diff options
-rw-r--r-- | .gitignore | 12 | ||||
-rw-r--r-- | SConstruct | 4 | ||||
-rw-r--r-- | editor/SCsub | 205 | ||||
-rw-r--r-- | editor/animation_editor.cpp | 4331 | ||||
-rw-r--r-- | editor/animation_editor.h (renamed from tools/editor/animation_editor.h) | 0 | ||||
-rw-r--r-- | editor/array_property_edit.cpp (renamed from tools/editor/array_property_edit.cpp) | 0 | ||||
-rw-r--r-- | editor/array_property_edit.h (renamed from tools/editor/array_property_edit.h) | 0 | ||||
-rw-r--r-- | editor/asset_library_editor_plugin.cpp (renamed from tools/editor/asset_library_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/asset_library_editor_plugin.h (renamed from tools/editor/asset_library_editor_plugin.h) | 0 | ||||
-rw-r--r-- | editor/call_dialog.cpp (renamed from tools/editor/call_dialog.cpp) | 0 | ||||
-rw-r--r-- | editor/call_dialog.h | 85 | ||||
-rw-r--r-- | editor/code_editor.cpp | 1323 | ||||
-rw-r--r-- | editor/code_editor.h | 261 | ||||
-rw-r--r-- | editor/collada/SCsub (renamed from tools/editor/collada/SCsub) | 0 | ||||
-rw-r--r-- | editor/collada/collada.cpp (renamed from tools/editor/collada/collada.cpp) | 0 | ||||
-rw-r--r-- | editor/collada/collada.h (renamed from tools/editor/collada/collada.h) | 0 | ||||
-rw-r--r-- | editor/connections_dialog.cpp (renamed from tools/editor/connections_dialog.cpp) | 0 | ||||
-rw-r--r-- | editor/connections_dialog.h | 134 | ||||
-rw-r--r-- | editor/create_dialog.cpp (renamed from tools/editor/create_dialog.cpp) | 0 | ||||
-rw-r--r-- | editor/create_dialog.h (renamed from tools/editor/create_dialog.h) | 0 | ||||
-rw-r--r-- | editor/dependency_editor.cpp (renamed from tools/editor/dependency_editor.cpp) | 0 | ||||
-rw-r--r-- | editor/dependency_editor.h (renamed from tools/editor/dependency_editor.h) | 0 | ||||
-rw-r--r-- | editor/doc/SCsub (renamed from tools/editor/doc/SCsub) | 0 | ||||
-rw-r--r-- | editor/doc/doc_data.cpp (renamed from tools/editor/doc/doc_data.cpp) | 0 | ||||
-rw-r--r-- | editor/doc/doc_data.h (renamed from tools/editor/doc/doc_data.h) | 0 | ||||
-rw-r--r-- | editor/doc/doc_dump.cpp (renamed from tools/editor/doc/doc_dump.cpp) | 0 | ||||
-rw-r--r-- | editor/doc/doc_dump.h (renamed from tools/editor/doc/doc_dump.h) | 0 | ||||
-rw-r--r-- | editor/doc_code_font.h (renamed from tools/editor/doc_code_font.h) | 0 | ||||
-rw-r--r-- | editor/doc_font.h (renamed from tools/editor/doc_font.h) | 0 | ||||
-rw-r--r-- | editor/doc_title_font.h (renamed from tools/editor/doc_title_font.h) | 0 | ||||
-rw-r--r-- | editor/editor_asset_installer.cpp (renamed from tools/editor/editor_asset_installer.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_asset_installer.h (renamed from tools/editor/editor_asset_installer.h) | 0 | ||||
-rw-r--r-- | editor/editor_audio_buses.cpp (renamed from tools/editor/editor_audio_buses.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_audio_buses.h | 186 | ||||
-rw-r--r-- | editor/editor_autoload_settings.cpp (renamed from tools/editor/editor_autoload_settings.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_autoload_settings.h (renamed from tools/editor/editor_autoload_settings.h) | 0 | ||||
-rw-r--r-- | editor/editor_data.cpp (renamed from tools/editor/editor_data.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_data.h | 269 | ||||
-rw-r--r-- | editor/editor_dir_dialog.cpp | 276 | ||||
-rw-r--r-- | editor/editor_dir_dialog.h (renamed from tools/editor/editor_dir_dialog.h) | 0 | ||||
-rw-r--r-- | editor/editor_export.cpp | 3231 | ||||
-rw-r--r-- | editor/editor_export.h (renamed from tools/editor/editor_export.h) | 0 | ||||
-rw-r--r-- | editor/editor_file_dialog.cpp (renamed from tools/editor/editor_file_dialog.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_file_dialog.h (renamed from tools/editor/editor_file_dialog.h) | 0 | ||||
-rw-r--r-- | editor/editor_file_system.cpp (renamed from tools/editor/editor_file_system.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_file_system.h (renamed from tools/editor/editor_file_system.h) | 0 | ||||
-rw-r--r-- | editor/editor_fonts.cpp (renamed from tools/editor/editor_fonts.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_fonts.h (renamed from tools/editor/editor_fonts.h) | 0 | ||||
-rw-r--r-- | editor/editor_help.cpp | 1929 | ||||
-rw-r--r-- | editor/editor_help.h | 222 | ||||
-rw-r--r-- | editor/editor_icons.h (renamed from tools/editor/editor_icons.h) | 0 | ||||
-rw-r--r-- | editor/editor_initialize_ssl.cpp (renamed from tools/editor/editor_initialize_ssl.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_initialize_ssl.h (renamed from tools/editor/editor_initialize_ssl.h) | 0 | ||||
-rw-r--r-- | editor/editor_log.cpp (renamed from tools/editor/editor_log.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_log.h (renamed from tools/editor/editor_log.h) | 0 | ||||
-rw-r--r-- | editor/editor_name_dialog.cpp (renamed from tools/editor/editor_name_dialog.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_name_dialog.h (renamed from tools/editor/editor_name_dialog.h) | 0 | ||||
-rw-r--r-- | editor/editor_node.cpp (renamed from tools/editor/editor_node.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_node.h | 833 | ||||
-rw-r--r-- | editor/editor_path.cpp (renamed from tools/editor/editor_path.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_path.h (renamed from tools/editor/editor_path.h) | 0 | ||||
-rw-r--r-- | editor/editor_plugin.cpp | 432 | ||||
-rw-r--r-- | editor/editor_plugin.h (renamed from tools/editor/editor_plugin.h) | 0 | ||||
-rw-r--r-- | editor/editor_plugin_settings.cpp (renamed from tools/editor/editor_plugin_settings.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_plugin_settings.h (renamed from tools/editor/editor_plugin_settings.h) | 0 | ||||
-rw-r--r-- | editor/editor_profiler.cpp (renamed from tools/editor/editor_profiler.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_profiler.h (renamed from tools/editor/editor_profiler.h) | 0 | ||||
-rw-r--r-- | editor/editor_reimport_dialog.cpp (renamed from tools/editor/editor_reimport_dialog.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_reimport_dialog.h (renamed from tools/editor/editor_reimport_dialog.h) | 0 | ||||
-rw-r--r-- | editor/editor_resource_preview.cpp (renamed from tools/editor/editor_resource_preview.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_resource_preview.h (renamed from tools/editor/editor_resource_preview.h) | 0 | ||||
-rw-r--r-- | editor/editor_run.cpp (renamed from tools/editor/editor_run.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_run.h (renamed from tools/editor/editor_run.h) | 0 | ||||
-rw-r--r-- | editor/editor_run_native.cpp (renamed from tools/editor/editor_run_native.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_run_native.h (renamed from tools/editor/editor_run_native.h) | 0 | ||||
-rw-r--r-- | editor/editor_run_script.cpp (renamed from tools/editor/editor_run_script.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_run_script.h (renamed from tools/editor/editor_run_script.h) | 0 | ||||
-rw-r--r-- | editor/editor_scale.cpp (renamed from tools/editor/editor_scale.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_scale.h (renamed from tools/editor/editor_scale.h) | 0 | ||||
-rw-r--r-- | editor/editor_settings.cpp (renamed from tools/editor/editor_settings.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_settings.h (renamed from tools/editor/editor_settings.h) | 0 | ||||
-rw-r--r-- | editor/editor_sub_scene.cpp (renamed from tools/editor/editor_sub_scene.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_sub_scene.h | 69 | ||||
-rw-r--r-- | editor/editor_themes.cpp (renamed from tools/editor/editor_themes.cpp) | 0 | ||||
-rw-r--r-- | editor/editor_themes.h (renamed from tools/editor/editor_themes.h) | 0 | ||||
-rw-r--r-- | editor/file_type_cache.cpp (renamed from tools/editor/file_type_cache.cpp) | 0 | ||||
-rw-r--r-- | editor/file_type_cache.h (renamed from tools/editor/file_type_cache.h) | 0 | ||||
-rw-r--r-- | editor/fileserver/SCsub (renamed from tools/editor/fileserver/SCsub) | 0 | ||||
-rw-r--r-- | editor/fileserver/editor_file_server.cpp (renamed from tools/editor/fileserver/editor_file_server.cpp) | 0 | ||||
-rw-r--r-- | editor/fileserver/editor_file_server.h (renamed from tools/editor/fileserver/editor_file_server.h) | 0 | ||||
-rw-r--r-- | editor/filesystem_dock.cpp (renamed from tools/editor/filesystem_dock.cpp) | 0 | ||||
-rw-r--r-- | editor/filesystem_dock.h (renamed from tools/editor/filesystem_dock.h) | 0 | ||||
-rw-r--r-- | editor/groups_editor.cpp (renamed from tools/editor/groups_editor.cpp) | 0 | ||||
-rw-r--r-- | editor/groups_editor.h (renamed from tools/editor/groups_editor.h) | 0 | ||||
-rw-r--r-- | editor/icons/2x/icon_accept_dialog.png (renamed from tools/editor/icons/2x/icon_accept_dialog.png) | bin | 581 -> 581 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_add.png (renamed from tools/editor/icons/2x/icon_add.png) | bin | 151 -> 151 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_add_track.png (renamed from tools/editor/icons/2x/icon_add_track.png) | bin | 151 -> 151 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_anchor.png (renamed from tools/editor/icons/2x/icon_anchor.png) | bin | 828 -> 828 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_animated_sprite.png (renamed from tools/editor/icons/2x/icon_animated_sprite.png) | bin | 1212 -> 1212 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_animated_sprite_3d.png (renamed from tools/editor/icons/2x/icon_animated_sprite_3d.png) | bin | 1125 -> 1125 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_animation.png (renamed from tools/editor/icons/2x/icon_animation.png) | bin | 912 -> 912 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_animation_player.png (renamed from tools/editor/icons/2x/icon_animation_player.png) | bin | 174 -> 174 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_animation_tree.png (renamed from tools/editor/icons/2x/icon_animation_tree.png) | bin | 471 -> 471 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_animation_tree_player.png (renamed from tools/editor/icons/2x/icon_animation_tree_player.png) | bin | 471 -> 471 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_area.png (renamed from tools/editor/icons/2x/icon_area.png) | bin | 209 -> 209 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_area_2d.png (renamed from tools/editor/icons/2x/icon_area_2d.png) | bin | 211 -> 211 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_arrow_left.png (renamed from tools/editor/icons/2x/icon_arrow_left.png) | bin | 333 -> 333 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_arrow_right.png (renamed from tools/editor/icons/2x/icon_arrow_right.png) | bin | 308 -> 308 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_arrow_up.png (renamed from tools/editor/icons/2x/icon_arrow_up.png) | bin | 293 -> 293 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_atlas_texture.png (renamed from tools/editor/icons/2x/icon_atlas_texture.png) | bin | 382 -> 382 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_audio_stream_gibberish.png (renamed from tools/editor/icons/2x/icon_audio_stream_gibberish.png) | bin | 437 -> 437 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_auto_play.png (renamed from tools/editor/icons/2x/icon_auto_play.png) | bin | 699 -> 699 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_back.png (renamed from tools/editor/icons/2x/icon_back.png) | bin | 323 -> 323 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_back_buffer_copy.png (renamed from tools/editor/icons/2x/icon_back_buffer_copy.png) | bin | 190 -> 190 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_bake.png (renamed from tools/editor/icons/2x/icon_bake.png) | bin | 267 -> 267 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_baked_light.png (renamed from tools/editor/icons/2x/icon_baked_light.png) | bin | 267 -> 267 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_baked_light_instance.png (renamed from tools/editor/icons/2x/icon_baked_light_instance.png) | bin | 264 -> 264 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_baked_light_sampler.png (renamed from tools/editor/icons/2x/icon_baked_light_sampler.png) | bin | 391 -> 391 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_bit_map.png (renamed from tools/editor/icons/2x/icon_bit_map.png) | bin | 148 -> 148 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_bitmap_font.png (renamed from tools/editor/icons/2x/icon_bitmap_font.png) | bin | 191 -> 191 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_blend.png (renamed from tools/editor/icons/2x/icon_blend.png) | bin | 1091 -> 1091 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_bone.png (renamed from tools/editor/icons/2x/icon_bone.png) | bin | 597 -> 597 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_bone_attachment.png (renamed from tools/editor/icons/2x/icon_bone_attachment.png) | bin | 576 -> 576 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_bone_track.png (renamed from tools/editor/icons/2x/icon_bone_track.png) | bin | 565 -> 565 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_bool.png (renamed from tools/editor/icons/2x/icon_bool.png) | bin | 171 -> 171 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_box_shape.png (renamed from tools/editor/icons/2x/icon_box_shape.png) | bin | 597 -> 597 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_button.png (renamed from tools/editor/icons/2x/icon_button.png) | bin | 186 -> 186 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_button_group.png (renamed from tools/editor/icons/2x/icon_button_group.png) | bin | 251 -> 251 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_camera.png (renamed from tools/editor/icons/2x/icon_camera.png) | bin | 352 -> 352 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_camera_2d.png (renamed from tools/editor/icons/2x/icon_camera_2d.png) | bin | 364 -> 364 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_canvas_item.png (renamed from tools/editor/icons/2x/icon_canvas_item.png) | bin | 709 -> 709 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_canvas_item_material.png (renamed from tools/editor/icons/2x/icon_canvas_item_material.png) | bin | 640 -> 640 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_canvas_item_shader.png (renamed from tools/editor/icons/2x/icon_canvas_item_shader.png) | bin | 716 -> 716 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_canvas_item_shader_graph.png (renamed from tools/editor/icons/2x/icon_canvas_item_shader_graph.png) | bin | 707 -> 707 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_canvas_layer.png (renamed from tools/editor/icons/2x/icon_canvas_layer.png) | bin | 860 -> 860 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_canvas_modulate.png (renamed from tools/editor/icons/2x/icon_canvas_modulate.png) | bin | 273 -> 273 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_capsule_shape.png (renamed from tools/editor/icons/2x/icon_capsule_shape.png) | bin | 372 -> 372 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_capsule_shape_2d.png (renamed from tools/editor/icons/2x/icon_capsule_shape_2d.png) | bin | 552 -> 552 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_center_container.png (renamed from tools/editor/icons/2x/icon_center_container.png) | bin | 478 -> 478 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_check_box.png (renamed from tools/editor/icons/2x/icon_check_box.png) | bin | 565 -> 565 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_check_button.png (renamed from tools/editor/icons/2x/icon_check_button.png) | bin | 528 -> 528 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_circle_shape_2d.png (renamed from tools/editor/icons/2x/icon_circle_shape_2d.png) | bin | 838 -> 838 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_class_list.png (renamed from tools/editor/icons/2x/icon_class_list.png) | bin | 192 -> 192 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_close.png (renamed from tools/editor/icons/2x/icon_close.png) | bin | 461 -> 461 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_collapse.png (renamed from tools/editor/icons/2x/icon_collapse.png) | bin | 383 -> 383 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_collision_2d.png (renamed from tools/editor/icons/2x/icon_collision_2d.png) | bin | 407 -> 407 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_collision_polygon.png (renamed from tools/editor/icons/2x/icon_collision_polygon.png) | bin | 397 -> 397 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_collision_polygon_2d.png (renamed from tools/editor/icons/2x/icon_collision_polygon_2d.png) | bin | 407 -> 407 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_collision_shape.png (renamed from tools/editor/icons/2x/icon_collision_shape.png) | bin | 439 -> 439 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_collision_shape_2d.png (renamed from tools/editor/icons/2x/icon_collision_shape_2d.png) | bin | 235 -> 235 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_color.png (renamed from tools/editor/icons/2x/icon_color.png) | bin | 1406 -> 1406 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_color_pick.png (renamed from tools/editor/icons/2x/icon_color_pick.png) | bin | 822 -> 822 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_color_picker.png (renamed from tools/editor/icons/2x/icon_color_picker.png) | bin | 837 -> 837 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_color_picker_button.png (renamed from tools/editor/icons/2x/icon_color_picker_button.png) | bin | 942 -> 942 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_color_ramp.png (renamed from tools/editor/icons/2x/icon_color_ramp.png) | bin | 342 -> 342 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_color_rect.png (renamed from tools/editor/icons/2x/icon_color_rect.png) | bin | 289 -> 289 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_concave_polygon_shape.png (renamed from tools/editor/icons/2x/icon_concave_polygon_shape.png) | bin | 709 -> 709 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_concave_polygon_shape_2d.png (renamed from tools/editor/icons/2x/icon_concave_polygon_shape_2d.png) | bin | 436 -> 436 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_cone_twist_joint.png (renamed from tools/editor/icons/2x/icon_cone_twist_joint.png) | bin | 906 -> 906 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_confirmation_dialog.png (renamed from tools/editor/icons/2x/icon_confirmation_dialog.png) | bin | 694 -> 694 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_connect.png (renamed from tools/editor/icons/2x/icon_connect.png) | bin | 251 -> 251 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_connection_and_groups.png (renamed from tools/editor/icons/2x/icon_connection_and_groups.png) | bin | 397 -> 397 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_container.png (renamed from tools/editor/icons/2x/icon_container.png) | bin | 319 -> 319 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control.png (renamed from tools/editor/icons/2x/icon_control.png) | bin | 825 -> 825 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_bottom_center.png (renamed from tools/editor/icons/2x/icon_control_align_bottom_center.png) | bin | 156 -> 156 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_bottom_left.png (renamed from tools/editor/icons/2x/icon_control_align_bottom_left.png) | bin | 154 -> 154 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_bottom_right.png (renamed from tools/editor/icons/2x/icon_control_align_bottom_right.png) | bin | 155 -> 155 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_bottom_wide.png (renamed from tools/editor/icons/2x/icon_control_align_bottom_wide.png) | bin | 160 -> 160 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_center.png (renamed from tools/editor/icons/2x/icon_control_align_center.png) | bin | 171 -> 171 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_center_left.png (renamed from tools/editor/icons/2x/icon_control_align_center_left.png) | bin | 130 -> 130 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_center_right.png (renamed from tools/editor/icons/2x/icon_control_align_center_right.png) | bin | 127 -> 127 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_left_center.png (renamed from tools/editor/icons/2x/icon_control_align_left_center.png) | bin | 169 -> 169 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_left_wide.png (renamed from tools/editor/icons/2x/icon_control_align_left_wide.png) | bin | 143 -> 143 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_right_center.png (renamed from tools/editor/icons/2x/icon_control_align_right_center.png) | bin | 171 -> 171 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_right_wide.png (renamed from tools/editor/icons/2x/icon_control_align_right_wide.png) | bin | 144 -> 144 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_top_center.png (renamed from tools/editor/icons/2x/icon_control_align_top_center.png) | bin | 165 -> 165 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_top_left.png (renamed from tools/editor/icons/2x/icon_control_align_top_left.png) | bin | 159 -> 159 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_top_right.png (renamed from tools/editor/icons/2x/icon_control_align_top_right.png) | bin | 167 -> 167 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_top_wide.png (renamed from tools/editor/icons/2x/icon_control_align_top_wide.png) | bin | 160 -> 160 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_align_wide.png (renamed from tools/editor/icons/2x/icon_control_align_wide.png) | bin | 145 -> 145 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_hcenter_wide.png (renamed from tools/editor/icons/2x/icon_control_hcenter_wide.png) | bin | 169 -> 169 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_control_vcenter_wide.png (renamed from tools/editor/icons/2x/icon_control_vcenter_wide.png) | bin | 148 -> 148 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_convex_polygon_shape.png (renamed from tools/editor/icons/2x/icon_convex_polygon_shape.png) | bin | 648 -> 648 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_convex_polygon_shape_2d.png (renamed from tools/editor/icons/2x/icon_convex_polygon_shape_2d.png) | bin | 373 -> 373 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_copy_node_path.png (renamed from tools/editor/icons/2x/icon_copy_node_path.png) | bin | 356 -> 356 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_create_new_scene_from.png (renamed from tools/editor/icons/2x/icon_create_new_scene_from.png) | bin | 639 -> 639 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_cube_map.png (renamed from tools/editor/icons/2x/icon_cube_map.png) | bin | 159 -> 159 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_curve_2d.png (renamed from tools/editor/icons/2x/icon_curve_2d.png) | bin | 591 -> 591 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_curve_3d.png (renamed from tools/editor/icons/2x/icon_curve_3d.png) | bin | 522 -> 522 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_curve_close.png (renamed from tools/editor/icons/2x/icon_curve_close.png) | bin | 610 -> 610 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_curve_constant.png (renamed from tools/editor/icons/2x/icon_curve_constant.png) | bin | 162 -> 162 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_curve_create.png (renamed from tools/editor/icons/2x/icon_curve_create.png) | bin | 698 -> 698 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_curve_curve.png (renamed from tools/editor/icons/2x/icon_curve_curve.png) | bin | 744 -> 744 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_curve_delete.png (renamed from tools/editor/icons/2x/icon_curve_delete.png) | bin | 926 -> 926 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_curve_edit.png (renamed from tools/editor/icons/2x/icon_curve_edit.png) | bin | 954 -> 954 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_curve_in.png (renamed from tools/editor/icons/2x/icon_curve_in.png) | bin | 449 -> 449 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_curve_in_out.png (renamed from tools/editor/icons/2x/icon_curve_in_out.png) | bin | 494 -> 494 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_curve_linear.png (renamed from tools/editor/icons/2x/icon_curve_linear.png) | bin | 283 -> 283 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_curve_out.png (renamed from tools/editor/icons/2x/icon_curve_out.png) | bin | 459 -> 459 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_curve_out_in.png (renamed from tools/editor/icons/2x/icon_curve_out_in.png) | bin | 489 -> 489 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_damped_spring_joint_2d.png (renamed from tools/editor/icons/2x/icon_damped_spring_joint_2d.png) | bin | 496 -> 496 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_debug_continue.png (renamed from tools/editor/icons/2x/icon_debug_continue.png) | bin | 525 -> 525 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_debug_next.png (renamed from tools/editor/icons/2x/icon_debug_next.png) | bin | 284 -> 284 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_debug_step.png (renamed from tools/editor/icons/2x/icon_debug_step.png) | bin | 317 -> 317 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_dependency_changed.png (renamed from tools/editor/icons/2x/icon_dependency_changed.png) | bin | 731 -> 731 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_dependency_changed_hl.png (renamed from tools/editor/icons/2x/icon_dependency_changed_hl.png) | bin | 601 -> 601 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_dependency_local_changed.png (renamed from tools/editor/icons/2x/icon_dependency_local_changed.png) | bin | 1104 -> 1104 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_dependency_local_changed_hl.png (renamed from tools/editor/icons/2x/icon_dependency_local_changed_hl.png) | bin | 926 -> 926 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_dependency_ok.png (renamed from tools/editor/icons/2x/icon_dependency_ok.png) | bin | 1015 -> 1015 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_dependency_ok_hl.png (renamed from tools/editor/icons/2x/icon_dependency_ok_hl.png) | bin | 836 -> 836 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_directional_light.png (renamed from tools/editor/icons/2x/icon_directional_light.png) | bin | 756 -> 756 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_distraction_free.png (renamed from tools/editor/icons/2x/icon_distraction_free.png) | bin | 575 -> 575 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_duplicate.png (renamed from tools/editor/icons/2x/icon_duplicate.png) | bin | 225 -> 225 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_dynamic_font.png (renamed from tools/editor/icons/2x/icon_dynamic_font.png) | bin | 383 -> 383 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_dynamic_font_data.png (renamed from tools/editor/icons/2x/icon_dynamic_font_data.png) | bin | 379 -> 379 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_edit.png (renamed from tools/editor/icons/2x/icon_edit.png) | bin | 525 -> 525 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_edit_key.png (renamed from tools/editor/icons/2x/icon_edit_key.png) | bin | 641 -> 641 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_edit_pivot.png (renamed from tools/editor/icons/2x/icon_edit_pivot.png) | bin | 595 -> 595 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_edit_resource.png (renamed from tools/editor/icons/2x/icon_edit_resource.png) | bin | 396 -> 396 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_editor_3d_handle.png (renamed from tools/editor/icons/2x/icon_editor_3d_handle.png) | bin | 705 -> 705 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_editor_handle.png (renamed from tools/editor/icons/2x/icon_editor_handle.png) | bin | 427 -> 427 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_editor_pivot.png (renamed from tools/editor/icons/2x/icon_editor_pivot.png) | bin | 198 -> 198 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_editor_plugin.png (renamed from tools/editor/icons/2x/icon_editor_plugin.png) | bin | 469 -> 469 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_enum.png (renamed from tools/editor/icons/2x/icon_enum.png) | bin | 137 -> 137 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_environment.png (renamed from tools/editor/icons/2x/icon_environment.png) | bin | 1270 -> 1270 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_error.png (renamed from tools/editor/icons/2x/icon_error.png) | bin | 155 -> 155 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_error_sign.png (renamed from tools/editor/icons/2x/icon_error_sign.png) | bin | 441 -> 441 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_event_player.png (renamed from tools/editor/icons/2x/icon_event_player.png) | bin | 167 -> 167 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_favorites.png (renamed from tools/editor/icons/2x/icon_favorites.png) | bin | 702 -> 702 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_file.png (renamed from tools/editor/icons/2x/icon_file.png) | bin | 196 -> 196 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_file_big.png (renamed from tools/editor/icons/2x/icon_file_big.png) | bin | 505 -> 505 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_file_dialog.png (renamed from tools/editor/icons/2x/icon_file_dialog.png) | bin | 342 -> 342 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_file_list.png (renamed from tools/editor/icons/2x/icon_file_list.png) | bin | 137 -> 137 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_file_server.png (renamed from tools/editor/icons/2x/icon_file_server.png) | bin | 172 -> 172 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_file_server_active.png (renamed from tools/editor/icons/2x/icon_file_server_active.png) | bin | 173 -> 173 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_file_thumbnail.png (renamed from tools/editor/icons/2x/icon_file_thumbnail.png) | bin | 137 -> 137 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_filesystem.png (renamed from tools/editor/icons/2x/icon_filesystem.png) | bin | 192 -> 192 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_fixed_material.png (renamed from tools/editor/icons/2x/icon_fixed_material.png) | bin | 736 -> 736 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_fixed_spatial_material.png (renamed from tools/editor/icons/2x/icon_fixed_spatial_material.png) | bin | 768 -> 768 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_folder.png (renamed from tools/editor/icons/2x/icon_folder.png) | bin | 228 -> 228 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_folder_big.png (renamed from tools/editor/icons/2x/icon_folder_big.png) | bin | 991 -> 991 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_font.png (renamed from tools/editor/icons/2x/icon_font.png) | bin | 369 -> 369 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_forward.png (renamed from tools/editor/icons/2x/icon_forward.png) | bin | 326 -> 326 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_g_d_script.png (renamed from tools/editor/icons/2x/icon_g_d_script.png) | bin | 759 -> 759 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_g_i_probe.png (renamed from tools/editor/icons/2x/icon_g_i_probe.png) | bin | 680 -> 680 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_g_i_probe_data.png (renamed from tools/editor/icons/2x/icon_g_i_probe_data.png) | bin | 662 -> 662 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_generic_6_d_o_f_joint.png (renamed from tools/editor/icons/2x/icon_generic_6_d_o_f_joint.png) | bin | 535 -> 535 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_gizmo_directional_light.png (renamed from tools/editor/icons/2x/icon_gizmo_directional_light.png) | bin | 8264 -> 8264 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_gizmo_light.png (renamed from tools/editor/icons/2x/icon_gizmo_light.png) | bin | 6282 -> 6282 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_gizmo_listener.png (renamed from tools/editor/icons/2x/icon_gizmo_listener.png) | bin | 7636 -> 7636 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_gizmo_spatial_sample_player.png (renamed from tools/editor/icons/2x/icon_gizmo_spatial_sample_player.png) | bin | 2831 -> 2831 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_gizmo_spatial_stream_player.png (renamed from tools/editor/icons/2x/icon_gizmo_spatial_stream_player.png) | bin | 3649 -> 3649 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_godot.png (renamed from tools/editor/icons/2x/icon_godot.png) | bin | 1842 -> 1842 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_color_ramp.png (renamed from tools/editor/icons/2x/icon_graph_color_ramp.png) | bin | 342 -> 342 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_comment.png (renamed from tools/editor/icons/2x/icon_graph_comment.png) | bin | 152 -> 152 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_cube_uniform.png (renamed from tools/editor/icons/2x/icon_graph_cube_uniform.png) | bin | 795 -> 795 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_curve_map.png (renamed from tools/editor/icons/2x/icon_graph_curve_map.png) | bin | 587 -> 587 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_default_texture.png (renamed from tools/editor/icons/2x/icon_graph_default_texture.png) | bin | 254 -> 254 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_edit.png (renamed from tools/editor/icons/2x/icon_graph_edit.png) | bin | 815 -> 815 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_input.png (renamed from tools/editor/icons/2x/icon_graph_input.png) | bin | 521 -> 521 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_node.png (renamed from tools/editor/icons/2x/icon_graph_node.png) | bin | 710 -> 710 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_rgb.png (renamed from tools/editor/icons/2x/icon_graph_rgb.png) | bin | 951 -> 951 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_rgb_op.png (renamed from tools/editor/icons/2x/icon_graph_rgb_op.png) | bin | 219 -> 219 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_rgb_uniform.png (renamed from tools/editor/icons/2x/icon_graph_rgb_uniform.png) | bin | 696 -> 696 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_scalar.png (renamed from tools/editor/icons/2x/icon_graph_scalar.png) | bin | 461 -> 461 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_scalar_interp.png (renamed from tools/editor/icons/2x/icon_graph_scalar_interp.png) | bin | 307 -> 307 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_scalar_op.png (renamed from tools/editor/icons/2x/icon_graph_scalar_op.png) | bin | 390 -> 390 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_scalar_uniform.png (renamed from tools/editor/icons/2x/icon_graph_scalar_uniform.png) | bin | 570 -> 570 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_scalars_to_vec.png (renamed from tools/editor/icons/2x/icon_graph_scalars_to_vec.png) | bin | 255 -> 255 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_texscreen.png (renamed from tools/editor/icons/2x/icon_graph_texscreen.png) | bin | 217 -> 217 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_texture_uniform.png (renamed from tools/editor/icons/2x/icon_graph_texture_uniform.png) | bin | 394 -> 394 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_time.png (renamed from tools/editor/icons/2x/icon_graph_time.png) | bin | 819 -> 819 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_vec_dp.png (renamed from tools/editor/icons/2x/icon_graph_vec_dp.png) | bin | 482 -> 482 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_vec_interp.png (renamed from tools/editor/icons/2x/icon_graph_vec_interp.png) | bin | 307 -> 307 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_vec_length.png (renamed from tools/editor/icons/2x/icon_graph_vec_length.png) | bin | 513 -> 513 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_vec_op.png (renamed from tools/editor/icons/2x/icon_graph_vec_op.png) | bin | 387 -> 387 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_vec_scalar_op.png (renamed from tools/editor/icons/2x/icon_graph_vec_scalar_op.png) | bin | 431 -> 431 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_vec_to_scalars.png (renamed from tools/editor/icons/2x/icon_graph_vec_to_scalars.png) | bin | 257 -> 257 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_vecs_to_xform.png (renamed from tools/editor/icons/2x/icon_graph_vecs_to_xform.png) | bin | 282 -> 282 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_vector.png (renamed from tools/editor/icons/2x/icon_graph_vector.png) | bin | 620 -> 620 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_vector_uniform.png (renamed from tools/editor/icons/2x/icon_graph_vector_uniform.png) | bin | 718 -> 718 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_xform.png (renamed from tools/editor/icons/2x/icon_graph_xform.png) | bin | 380 -> 380 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_xform_mult.png (renamed from tools/editor/icons/2x/icon_graph_xform_mult.png) | bin | 321 -> 321 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_xform_scalar_func.png (renamed from tools/editor/icons/2x/icon_graph_xform_scalar_func.png) | bin | 467 -> 467 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_xform_to_vecs.png (renamed from tools/editor/icons/2x/icon_graph_xform_to_vecs.png) | bin | 277 -> 277 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_xform_uniform.png (renamed from tools/editor/icons/2x/icon_graph_xform_uniform.png) | bin | 526 -> 526 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_xform_vec_func.png (renamed from tools/editor/icons/2x/icon_graph_xform_vec_func.png) | bin | 476 -> 476 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_xform_vec_imult.png (renamed from tools/editor/icons/2x/icon_graph_xform_vec_imult.png) | bin | 601 -> 601 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_graph_xform_vec_mult.png (renamed from tools/editor/icons/2x/icon_graph_xform_vec_mult.png) | bin | 600 -> 600 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_grid.png (renamed from tools/editor/icons/2x/icon_grid.png) | bin | 194 -> 194 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_grid_container.png (renamed from tools/editor/icons/2x/icon_grid_container.png) | bin | 329 -> 329 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_grid_map.png (renamed from tools/editor/icons/2x/icon_grid_map.png) | bin | 138 -> 138 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_groove_joint_2d.png (renamed from tools/editor/icons/2x/icon_groove_joint_2d.png) | bin | 179 -> 179 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_group.png (renamed from tools/editor/icons/2x/icon_group.png) | bin | 207 -> 207 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_groups.png (renamed from tools/editor/icons/2x/icon_groups.png) | bin | 353 -> 353 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_h_box_container.png (renamed from tools/editor/icons/2x/icon_h_box_container.png) | bin | 307 -> 307 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_h_button_array.png (renamed from tools/editor/icons/2x/icon_h_button_array.png) | bin | 224 -> 224 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_h_scroll_bar.png (renamed from tools/editor/icons/2x/icon_h_scroll_bar.png) | bin | 324 -> 324 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_h_separator.png (renamed from tools/editor/icons/2x/icon_h_separator.png) | bin | 148 -> 148 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_h_slider.png (renamed from tools/editor/icons/2x/icon_h_slider.png) | bin | 360 -> 360 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_h_split_container.png (renamed from tools/editor/icons/2x/icon_h_split_container.png) | bin | 399 -> 399 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_h_t_t_p_request.png (renamed from tools/editor/icons/2x/icon_h_t_t_p_request.png) | bin | 425 -> 425 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_headphones.png (renamed from tools/editor/icons/2x/icon_headphones.png) | bin | 620 -> 620 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_help.png (renamed from tools/editor/icons/2x/icon_help.png) | bin | 1126 -> 1126 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_hidden.png (renamed from tools/editor/icons/2x/icon_hidden.png) | bin | 640 -> 640 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_hinge_joint.png (renamed from tools/editor/icons/2x/icon_hinge_joint.png) | bin | 663 -> 663 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_history.png (renamed from tools/editor/icons/2x/icon_history.png) | bin | 814 -> 814 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_hsize.png (renamed from tools/editor/icons/2x/icon_hsize.png) | bin | 247 -> 247 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_image.png (renamed from tools/editor/icons/2x/icon_image.png) | bin | 404 -> 404 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_image_sky_box.png (renamed from tools/editor/icons/2x/icon_image_sky_box.png) | bin | 904 -> 904 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_image_texture.png (renamed from tools/editor/icons/2x/icon_image_texture.png) | bin | 262 -> 262 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_immediate_geometry.png (renamed from tools/editor/icons/2x/icon_immediate_geometry.png) | bin | 706 -> 706 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_import_check.png (renamed from tools/editor/icons/2x/icon_import_check.png) | bin | 386 -> 386 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_import_fail.png (renamed from tools/editor/icons/2x/icon_import_fail.png) | bin | 464 -> 464 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_instance.png (renamed from tools/editor/icons/2x/icon_instance.png) | bin | 817 -> 817 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_instance_options.png (renamed from tools/editor/icons/2x/icon_instance_options.png) | bin | 708 -> 708 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_integer.png (renamed from tools/editor/icons/2x/icon_integer.png) | bin | 147 -> 147 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_interp_cubic.png (renamed from tools/editor/icons/2x/icon_interp_cubic.png) | bin | 483 -> 483 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_interp_linear.png (renamed from tools/editor/icons/2x/icon_interp_linear.png) | bin | 398 -> 398 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_interp_raw.png (renamed from tools/editor/icons/2x/icon_interp_raw.png) | bin | 221 -> 221 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_interp_wrap_clamp.png (renamed from tools/editor/icons/2x/icon_interp_wrap_clamp.png) | bin | 348 -> 348 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_interp_wrap_loop.png (renamed from tools/editor/icons/2x/icon_interp_wrap_loop.png) | bin | 548 -> 548 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_interpolated_camera.png (renamed from tools/editor/icons/2x/icon_interpolated_camera.png) | bin | 454 -> 454 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_invalid_key.png (renamed from tools/editor/icons/2x/icon_invalid_key.png) | bin | 385 -> 385 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_inverse_kinematics.png (renamed from tools/editor/icons/2x/icon_inverse_kinematics.png) | bin | 459 -> 459 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_item_list.png (renamed from tools/editor/icons/2x/icon_item_list.png) | bin | 338 -> 338 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_joy_axis.png (renamed from tools/editor/icons/2x/icon_joy_axis.png) | bin | 425 -> 425 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_joy_button.png (renamed from tools/editor/icons/2x/icon_joy_button.png) | bin | 499 -> 499 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_joypad.png (renamed from tools/editor/icons/2x/icon_joypad.png) | bin | 380 -> 380 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_key.png (renamed from tools/editor/icons/2x/icon_key.png) | bin | 572 -> 572 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_key_hover.png (renamed from tools/editor/icons/2x/icon_key_hover.png) | bin | 376 -> 376 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_key_invalid.png (renamed from tools/editor/icons/2x/icon_key_invalid.png) | bin | 385 -> 385 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_key_next.png (renamed from tools/editor/icons/2x/icon_key_next.png) | bin | 579 -> 579 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_key_selected.png (renamed from tools/editor/icons/2x/icon_key_selected.png) | bin | 353 -> 353 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_key_value.png (renamed from tools/editor/icons/2x/icon_key_value.png) | bin | 380 -> 380 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_key_xform.png (renamed from tools/editor/icons/2x/icon_key_xform.png) | bin | 388 -> 388 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_keyboard.png (renamed from tools/editor/icons/2x/icon_keyboard.png) | bin | 486 -> 486 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_kinematic_body.png (renamed from tools/editor/icons/2x/icon_kinematic_body.png) | bin | 197 -> 197 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_kinematic_body_2d.png (renamed from tools/editor/icons/2x/icon_kinematic_body_2d.png) | bin | 204 -> 204 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_label.png (renamed from tools/editor/icons/2x/icon_label.png) | bin | 370 -> 370 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_large_texture.png (renamed from tools/editor/icons/2x/icon_large_texture.png) | bin | 211 -> 211 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_light_2d.png (renamed from tools/editor/icons/2x/icon_light_2d.png) | bin | 669 -> 669 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_light_occluder_2d.png (renamed from tools/editor/icons/2x/icon_light_occluder_2d.png) | bin | 175 -> 175 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_line_2d.png (renamed from tools/editor/icons/2x/icon_line_2d.png) | bin | 795 -> 795 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_line_edit.png (renamed from tools/editor/icons/2x/icon_line_edit.png) | bin | 323 -> 323 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_line_shape_2d.png (renamed from tools/editor/icons/2x/icon_line_shape_2d.png) | bin | 597 -> 597 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_link_button.png (renamed from tools/editor/icons/2x/icon_link_button.png) | bin | 774 -> 774 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_list_select.png (renamed from tools/editor/icons/2x/icon_list_select.png) | bin | 653 -> 653 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_listener.png (renamed from tools/editor/icons/2x/icon_listener.png) | bin | 885 -> 885 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_load.png (renamed from tools/editor/icons/2x/icon_load.png) | bin | 523 -> 523 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_lock.png (renamed from tools/editor/icons/2x/icon_lock.png) | bin | 441 -> 441 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_loop.png (renamed from tools/editor/icons/2x/icon_loop.png) | bin | 806 -> 806 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_loop_interpolation.png (renamed from tools/editor/icons/2x/icon_loop_interpolation.png) | bin | 709 -> 709 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_main_play.png (renamed from tools/editor/icons/2x/icon_main_play.png) | bin | 359 -> 359 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_main_stop.png (renamed from tools/editor/icons/2x/icon_main_stop.png) | bin | 197 -> 197 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_margin_container.png (renamed from tools/editor/icons/2x/icon_margin_container.png) | bin | 365 -> 365 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_material_preview_cube.png (renamed from tools/editor/icons/2x/icon_material_preview_cube.png) | bin | 562 -> 562 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_material_preview_cube_off.png (renamed from tools/editor/icons/2x/icon_material_preview_cube_off.png) | bin | 598 -> 598 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_material_preview_light_1.png (renamed from tools/editor/icons/2x/icon_material_preview_light_1.png) | bin | 724 -> 724 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_material_preview_light_1_off.png (renamed from tools/editor/icons/2x/icon_material_preview_light_1_off.png) | bin | 596 -> 596 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_material_preview_light_2.png (renamed from tools/editor/icons/2x/icon_material_preview_light_2.png) | bin | 740 -> 740 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_material_preview_light_2_off.png (renamed from tools/editor/icons/2x/icon_material_preview_light_2_off.png) | bin | 843 -> 843 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_material_preview_sphere.png (renamed from tools/editor/icons/2x/icon_material_preview_sphere.png) | bin | 704 -> 704 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_material_preview_sphere_off.png (renamed from tools/editor/icons/2x/icon_material_preview_sphere_off.png) | bin | 518 -> 518 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_material_shader.png (renamed from tools/editor/icons/2x/icon_material_shader.png) | bin | 342 -> 342 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_material_shader_graph.png (renamed from tools/editor/icons/2x/icon_material_shader_graph.png) | bin | 707 -> 707 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_matrix.png (renamed from tools/editor/icons/2x/icon_matrix.png) | bin | 185 -> 185 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_menu_button.png (renamed from tools/editor/icons/2x/icon_menu_button.png) | bin | 296 -> 296 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mesh.png (renamed from tools/editor/icons/2x/icon_mesh.png) | bin | 582 -> 582 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mesh_instance.png (renamed from tools/editor/icons/2x/icon_mesh_instance.png) | bin | 563 -> 563 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mesh_library.png (renamed from tools/editor/icons/2x/icon_mesh_library.png) | bin | 631 -> 631 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_aabb.png (renamed from tools/editor/icons/2x/icon_mini_aabb.png) | bin | 695 -> 695 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_array.png (renamed from tools/editor/icons/2x/icon_mini_array.png) | bin | 326 -> 326 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_boolean.png (renamed from tools/editor/icons/2x/icon_mini_boolean.png) | bin | 434 -> 434 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_color.png (renamed from tools/editor/icons/2x/icon_mini_color.png) | bin | 411 -> 411 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_color_array.png (renamed from tools/editor/icons/2x/icon_mini_color_array.png) | bin | 445 -> 445 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_dictionary.png (renamed from tools/editor/icons/2x/icon_mini_dictionary.png) | bin | 371 -> 371 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_float.png (renamed from tools/editor/icons/2x/icon_mini_float.png) | bin | 355 -> 355 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_float_array.png (renamed from tools/editor/icons/2x/icon_mini_float_array.png) | bin | 451 -> 451 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_image.png (renamed from tools/editor/icons/2x/icon_mini_image.png) | bin | 450 -> 450 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_input.png (renamed from tools/editor/icons/2x/icon_mini_input.png) | bin | 409 -> 409 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_int_array.png (renamed from tools/editor/icons/2x/icon_mini_int_array.png) | bin | 384 -> 384 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_integer.png (renamed from tools/editor/icons/2x/icon_mini_integer.png) | bin | 367 -> 367 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_matrix3.png (renamed from tools/editor/icons/2x/icon_mini_matrix3.png) | bin | 391 -> 391 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_matrix32.png (renamed from tools/editor/icons/2x/icon_mini_matrix32.png) | bin | 573 -> 573 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_object.png (renamed from tools/editor/icons/2x/icon_mini_object.png) | bin | 507 -> 507 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_path.png (renamed from tools/editor/icons/2x/icon_mini_path.png) | bin | 435 -> 435 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_plane.png (renamed from tools/editor/icons/2x/icon_mini_plane.png) | bin | 424 -> 424 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_quat.png (renamed from tools/editor/icons/2x/icon_mini_quat.png) | bin | 509 -> 509 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_raw_array.png (renamed from tools/editor/icons/2x/icon_mini_raw_array.png) | bin | 382 -> 382 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_rect2.png (renamed from tools/editor/icons/2x/icon_mini_rect2.png) | bin | 431 -> 431 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_rid.png (renamed from tools/editor/icons/2x/icon_mini_rid.png) | bin | 349 -> 349 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_string.png (renamed from tools/editor/icons/2x/icon_mini_string.png) | bin | 437 -> 437 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_string_array.png (renamed from tools/editor/icons/2x/icon_mini_string_array.png) | bin | 479 -> 479 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_transform.png (renamed from tools/editor/icons/2x/icon_mini_transform.png) | bin | 539 -> 539 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_variant.png (renamed from tools/editor/icons/2x/icon_mini_variant.png) | bin | 405 -> 405 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_vector2.png (renamed from tools/editor/icons/2x/icon_mini_vector2.png) | bin | 541 -> 541 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_vector2_array.png (renamed from tools/editor/icons/2x/icon_mini_vector2_array.png) | bin | 485 -> 485 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_vector3.png (renamed from tools/editor/icons/2x/icon_mini_vector3.png) | bin | 509 -> 509 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mini_vector3_array.png (renamed from tools/editor/icons/2x/icon_mini_vector3_array.png) | bin | 416 -> 416 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mirror_x.png (renamed from tools/editor/icons/2x/icon_mirror_x.png) | bin | 247 -> 247 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mirror_y.png (renamed from tools/editor/icons/2x/icon_mirror_y.png) | bin | 240 -> 240 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_mouse.png (renamed from tools/editor/icons/2x/icon_mouse.png) | bin | 476 -> 476 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_move_down.png (renamed from tools/editor/icons/2x/icon_move_down.png) | bin | 357 -> 357 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_move_point.png (renamed from tools/editor/icons/2x/icon_move_point.png) | bin | 1205 -> 1205 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_move_up.png (renamed from tools/editor/icons/2x/icon_move_up.png) | bin | 346 -> 346 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_multi_edit.png (renamed from tools/editor/icons/2x/icon_multi_edit.png) | bin | 558 -> 558 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_multi_line.png (renamed from tools/editor/icons/2x/icon_multi_line.png) | bin | 166 -> 166 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_multi_mesh.png (renamed from tools/editor/icons/2x/icon_multi_mesh.png) | bin | 591 -> 591 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_multi_mesh_instance.png (renamed from tools/editor/icons/2x/icon_multi_mesh_instance.png) | bin | 653 -> 653 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_multi_node_edit.png (renamed from tools/editor/icons/2x/icon_multi_node_edit.png) | bin | 558 -> 558 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_navigation.png (renamed from tools/editor/icons/2x/icon_navigation.png) | bin | 534 -> 534 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_navigation_2d.png (renamed from tools/editor/icons/2x/icon_navigation_2d.png) | bin | 558 -> 558 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_navigation_mesh.png (renamed from tools/editor/icons/2x/icon_navigation_mesh.png) | bin | 806 -> 806 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_navigation_mesh_instance.png (renamed from tools/editor/icons/2x/icon_navigation_mesh_instance.png) | bin | 867 -> 867 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_navigation_polygon.png (renamed from tools/editor/icons/2x/icon_navigation_polygon.png) | bin | 640 -> 640 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_navigation_polygon_instance.png (renamed from tools/editor/icons/2x/icon_navigation_polygon_instance.png) | bin | 712 -> 712 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_new.png (renamed from tools/editor/icons/2x/icon_new.png) | bin | 196 -> 196 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_nine_patch_rect.png (renamed from tools/editor/icons/2x/icon_nine_patch_rect.png) | bin | 162 -> 162 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_node.png (renamed from tools/editor/icons/2x/icon_node.png) | bin | 788 -> 788 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_node_2d.png (renamed from tools/editor/icons/2x/icon_node_2d.png) | bin | 864 -> 864 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_node_warning.png (renamed from tools/editor/icons/2x/icon_node_warning.png) | bin | 443 -> 443 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_non_favorite.png (renamed from tools/editor/icons/2x/icon_non_favorite.png) | bin | 946 -> 946 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_object.png (renamed from tools/editor/icons/2x/icon_object.png) | bin | 500 -> 500 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_occluder_polygon_2d.png (renamed from tools/editor/icons/2x/icon_occluder_polygon_2d.png) | bin | 384 -> 384 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_omni_light.png (renamed from tools/editor/icons/2x/icon_omni_light.png) | bin | 659 -> 659 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_open.png (renamed from tools/editor/icons/2x/icon_open.png) | bin | 228 -> 228 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_option_button.png (renamed from tools/editor/icons/2x/icon_option_button.png) | bin | 366 -> 366 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_override.png (renamed from tools/editor/icons/2x/icon_override.png) | bin | 488 -> 488 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_p_hash_translation.png (renamed from tools/editor/icons/2x/icon_p_hash_translation.png) | bin | 285 -> 285 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_packed_data_container.png (renamed from tools/editor/icons/2x/icon_packed_data_container.png) | bin | 253 -> 253 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_packed_scene.png (renamed from tools/editor/icons/2x/icon_packed_scene.png) | bin | 569 -> 569 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_panel.png (renamed from tools/editor/icons/2x/icon_panel.png) | bin | 277 -> 277 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_panel_container.png (renamed from tools/editor/icons/2x/icon_panel_container.png) | bin | 309 -> 309 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_panels_1.png (renamed from tools/editor/icons/2x/icon_panels_1.png) | bin | 117 -> 117 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_panels_2.png (renamed from tools/editor/icons/2x/icon_panels_2.png) | bin | 127 -> 127 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_panels_2_alt.png (renamed from tools/editor/icons/2x/icon_panels_2_alt.png) | bin | 134 -> 134 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_panels_3.png (renamed from tools/editor/icons/2x/icon_panels_3.png) | bin | 141 -> 141 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_panels_3_alt.png (renamed from tools/editor/icons/2x/icon_panels_3_alt.png) | bin | 152 -> 152 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_panels_4.png (renamed from tools/editor/icons/2x/icon_panels_4.png) | bin | 136 -> 136 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_parallax_background.png (renamed from tools/editor/icons/2x/icon_parallax_background.png) | bin | 335 -> 335 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_parallax_layer.png (renamed from tools/editor/icons/2x/icon_parallax_layer.png) | bin | 469 -> 469 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_particle_attractor_2d.png (renamed from tools/editor/icons/2x/icon_particle_attractor_2d.png) | bin | 1578 -> 1578 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_particles.png (renamed from tools/editor/icons/2x/icon_particles.png) | bin | 686 -> 686 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_particles_2d.png (renamed from tools/editor/icons/2x/icon_particles_2d.png) | bin | 728 -> 728 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_particles_shader.png (renamed from tools/editor/icons/2x/icon_particles_shader.png) | bin | 657 -> 657 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_patch_9_rect.png (renamed from tools/editor/icons/2x/icon_patch_9_rect.png) | bin | 162 -> 162 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_path.png (renamed from tools/editor/icons/2x/icon_path.png) | bin | 666 -> 666 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_path_2d.png (renamed from tools/editor/icons/2x/icon_path_2d.png) | bin | 687 -> 687 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_path_follow.png (renamed from tools/editor/icons/2x/icon_path_follow.png) | bin | 725 -> 725 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_path_follow_2d.png (renamed from tools/editor/icons/2x/icon_path_follow_2d.png) | bin | 725 -> 725 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_pause.png (renamed from tools/editor/icons/2x/icon_pause.png) | bin | 194 -> 194 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_pin.png (renamed from tools/editor/icons/2x/icon_pin.png) | bin | 322 -> 322 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_pin_joint.png (renamed from tools/editor/icons/2x/icon_pin_joint.png) | bin | 686 -> 686 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_pin_joint_2d.png (renamed from tools/editor/icons/2x/icon_pin_joint_2d.png) | bin | 719 -> 719 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_pin_pressed.png (renamed from tools/editor/icons/2x/icon_pin_pressed.png) | bin | 322 -> 322 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_plane.png (renamed from tools/editor/icons/2x/icon_plane.png) | bin | 306 -> 306 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_plane_shape.png (renamed from tools/editor/icons/2x/icon_plane_shape.png) | bin | 316 -> 316 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_play.png (renamed from tools/editor/icons/2x/icon_play.png) | bin | 395 -> 395 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_play_backwards.png (renamed from tools/editor/icons/2x/icon_play_backwards.png) | bin | 424 -> 424 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_play_custom.png (renamed from tools/editor/icons/2x/icon_play_custom.png) | bin | 572 -> 572 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_play_scene.png (renamed from tools/editor/icons/2x/icon_play_scene.png) | bin | 686 -> 686 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_play_start.png (renamed from tools/editor/icons/2x/icon_play_start.png) | bin | 463 -> 463 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_play_start_backwards.png (renamed from tools/editor/icons/2x/icon_play_start_backwards.png) | bin | 497 -> 497 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_polygon_2d.png (renamed from tools/editor/icons/2x/icon_polygon_2d.png) | bin | 407 -> 407 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_polygon_path_finder.png (renamed from tools/editor/icons/2x/icon_polygon_path_finder.png) | bin | 491 -> 491 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_popup.png (renamed from tools/editor/icons/2x/icon_popup.png) | bin | 329 -> 329 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_popup_dialog.png (renamed from tools/editor/icons/2x/icon_popup_dialog.png) | bin | 347 -> 347 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_popup_menu.png (renamed from tools/editor/icons/2x/icon_popup_menu.png) | bin | 301 -> 301 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_popup_panel.png (renamed from tools/editor/icons/2x/icon_popup_panel.png) | bin | 279 -> 279 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_portal.png (renamed from tools/editor/icons/2x/icon_portal.png) | bin | 855 -> 855 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_position_2d.png (renamed from tools/editor/icons/2x/icon_position_2d.png) | bin | 152 -> 152 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_position_3d.png (renamed from tools/editor/icons/2x/icon_position_3d.png) | bin | 151 -> 151 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_progress_1.png (renamed from tools/editor/icons/2x/icon_progress_1.png) | bin | 781 -> 781 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_progress_2.png (renamed from tools/editor/icons/2x/icon_progress_2.png) | bin | 785 -> 785 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_progress_3.png (renamed from tools/editor/icons/2x/icon_progress_3.png) | bin | 800 -> 800 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_progress_4.png (renamed from tools/editor/icons/2x/icon_progress_4.png) | bin | 808 -> 808 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_progress_5.png (renamed from tools/editor/icons/2x/icon_progress_5.png) | bin | 807 -> 807 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_progress_6.png (renamed from tools/editor/icons/2x/icon_progress_6.png) | bin | 793 -> 793 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_progress_7.png (renamed from tools/editor/icons/2x/icon_progress_7.png) | bin | 815 -> 815 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_progress_8.png (renamed from tools/editor/icons/2x/icon_progress_8.png) | bin | 791 -> 791 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_progress_bar.png (renamed from tools/editor/icons/2x/icon_progress_bar.png) | bin | 328 -> 328 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_proximity_group.png (renamed from tools/editor/icons/2x/icon_proximity_group.png) | bin | 326 -> 326 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_quad.png (renamed from tools/editor/icons/2x/icon_quad.png) | bin | 289 -> 289 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_quat.png (renamed from tools/editor/icons/2x/icon_quat.png) | bin | 668 -> 668 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_range.png (renamed from tools/editor/icons/2x/icon_range.png) | bin | 177 -> 177 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_rating_no_star.png (renamed from tools/editor/icons/2x/icon_rating_no_star.png) | bin | 1077 -> 1077 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_rating_star.png (renamed from tools/editor/icons/2x/icon_rating_star.png) | bin | 696 -> 696 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_ray_cast.png (renamed from tools/editor/icons/2x/icon_ray_cast.png) | bin | 308 -> 308 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_ray_cast_2d.png (renamed from tools/editor/icons/2x/icon_ray_cast_2d.png) | bin | 337 -> 337 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_ray_shape.png (renamed from tools/editor/icons/2x/icon_ray_shape.png) | bin | 541 -> 541 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_ray_shape_2d.png (renamed from tools/editor/icons/2x/icon_ray_shape_2d.png) | bin | 330 -> 330 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_rayito.png (renamed from tools/editor/icons/2x/icon_rayito.png) | bin | 449 -> 449 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_real.png (renamed from tools/editor/icons/2x/icon_real.png) | bin | 423 -> 423 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_rectangle_shape_2d.png (renamed from tools/editor/icons/2x/icon_rectangle_shape_2d.png) | bin | 213 -> 213 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_reference_rect.png (renamed from tools/editor/icons/2x/icon_reference_rect.png) | bin | 160 -> 160 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_reflection_probe.png (renamed from tools/editor/icons/2x/icon_reflection_probe.png) | bin | 533 -> 533 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_region_edit.png (renamed from tools/editor/icons/2x/icon_region_edit.png) | bin | 158 -> 158 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_reload.png (renamed from tools/editor/icons/2x/icon_reload.png) | bin | 786 -> 786 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_reload_small.png (renamed from tools/editor/icons/2x/icon_reload_small.png) | bin | 756 -> 756 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_remote.png (renamed from tools/editor/icons/2x/icon_remote.png) | bin | 824 -> 824 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_remote_transform.png (renamed from tools/editor/icons/2x/icon_remote_transform.png) | bin | 1140 -> 1140 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_remote_transform_2d.png (renamed from tools/editor/icons/2x/icon_remote_transform_2d.png) | bin | 1197 -> 1197 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_remove.png (renamed from tools/editor/icons/2x/icon_remove.png) | bin | 271 -> 271 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_rename.png (renamed from tools/editor/icons/2x/icon_rename.png) | bin | 215 -> 215 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_reparent.png (renamed from tools/editor/icons/2x/icon_reparent.png) | bin | 741 -> 741 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_resource_preloader.png (renamed from tools/editor/icons/2x/icon_resource_preloader.png) | bin | 609 -> 609 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_rich_text_label.png (renamed from tools/editor/icons/2x/icon_rich_text_label.png) | bin | 313 -> 313 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_rigid_body.png (renamed from tools/editor/icons/2x/icon_rigid_body.png) | bin | 1139 -> 1139 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_rigid_body_2d.png (renamed from tools/editor/icons/2x/icon_rigid_body_2d.png) | bin | 1206 -> 1206 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_room.png (renamed from tools/editor/icons/2x/icon_room.png) | bin | 567 -> 567 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_room_bounds.png (renamed from tools/editor/icons/2x/icon_room_bounds.png) | bin | 631 -> 631 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_rotate_0.png (renamed from tools/editor/icons/2x/icon_rotate_0.png) | bin | 878 -> 878 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_rotate_180.png (renamed from tools/editor/icons/2x/icon_rotate_180.png) | bin | 713 -> 713 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_rotate_270.png (renamed from tools/editor/icons/2x/icon_rotate_270.png) | bin | 666 -> 666 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_rotate_90.png (renamed from tools/editor/icons/2x/icon_rotate_90.png) | bin | 805 -> 805 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_sample.png (renamed from tools/editor/icons/2x/icon_sample.png) | bin | 197 -> 197 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_sample_library.png (renamed from tools/editor/icons/2x/icon_sample_library.png) | bin | 568 -> 568 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_sample_player.png (renamed from tools/editor/icons/2x/icon_sample_player.png) | bin | 345 -> 345 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_sample_player_2d.png (renamed from tools/editor/icons/2x/icon_sample_player_2d.png) | bin | 376 -> 376 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_save.png (renamed from tools/editor/icons/2x/icon_save.png) | bin | 466 -> 466 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_script.png (renamed from tools/editor/icons/2x/icon_script.png) | bin | 465 -> 465 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_script_create.png (renamed from tools/editor/icons/2x/icon_script_create.png) | bin | 491 -> 491 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_script_remove.png (renamed from tools/editor/icons/2x/icon_script_remove.png) | bin | 787 -> 787 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_scroll_bar.png (renamed from tools/editor/icons/2x/icon_scroll_bar.png) | bin | 324 -> 324 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_scroll_container.png (renamed from tools/editor/icons/2x/icon_scroll_container.png) | bin | 483 -> 483 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_segment_shape_2d.png (renamed from tools/editor/icons/2x/icon_segment_shape_2d.png) | bin | 320 -> 320 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_shader.png (renamed from tools/editor/icons/2x/icon_shader.png) | bin | 342 -> 342 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_shader_material.png (renamed from tools/editor/icons/2x/icon_shader_material.png) | bin | 342 -> 342 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_short_cut.png (renamed from tools/editor/icons/2x/icon_short_cut.png) | bin | 473 -> 473 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_signal.png (renamed from tools/editor/icons/2x/icon_signal.png) | bin | 327 -> 327 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_skeleton.png (renamed from tools/editor/icons/2x/icon_skeleton.png) | bin | 649 -> 649 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_slider_joint.png (renamed from tools/editor/icons/2x/icon_slider_joint.png) | bin | 180 -> 180 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_slot.png (renamed from tools/editor/icons/2x/icon_slot.png) | bin | 342 -> 342 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_snap.png (renamed from tools/editor/icons/2x/icon_snap.png) | bin | 424 -> 424 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_sound_room_params.png (renamed from tools/editor/icons/2x/icon_sound_room_params.png) | bin | 375 -> 375 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_spatial.png (renamed from tools/editor/icons/2x/icon_spatial.png) | bin | 835 -> 835 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_spatial_sample_player.png (renamed from tools/editor/icons/2x/icon_spatial_sample_player.png) | bin | 353 -> 353 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_spatial_shader.png (renamed from tools/editor/icons/2x/icon_spatial_shader.png) | bin | 704 -> 704 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_spatial_stream_player.png (renamed from tools/editor/icons/2x/icon_spatial_stream_player.png) | bin | 262 -> 262 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_sphere_shape.png (renamed from tools/editor/icons/2x/icon_sphere_shape.png) | bin | 712 -> 712 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_spin_box.png (renamed from tools/editor/icons/2x/icon_spin_box.png) | bin | 436 -> 436 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_spot_light.png (renamed from tools/editor/icons/2x/icon_spot_light.png) | bin | 669 -> 669 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_sprite.png (renamed from tools/editor/icons/2x/icon_sprite.png) | bin | 841 -> 841 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_sprite_3d.png (renamed from tools/editor/icons/2x/icon_sprite_3d.png) | bin | 838 -> 838 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_sprite_frames.png (renamed from tools/editor/icons/2x/icon_sprite_frames.png) | bin | 691 -> 691 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_static_body.png (renamed from tools/editor/icons/2x/icon_static_body.png) | bin | 397 -> 397 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_static_body_2d.png (renamed from tools/editor/icons/2x/icon_static_body_2d.png) | bin | 417 -> 417 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_stream_player.png (renamed from tools/editor/icons/2x/icon_stream_player.png) | bin | 263 -> 263 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_string.png (renamed from tools/editor/icons/2x/icon_string.png) | bin | 217 -> 217 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_style_box_empty.png (renamed from tools/editor/icons/2x/icon_style_box_empty.png) | bin | 555 -> 555 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_style_box_flat.png (renamed from tools/editor/icons/2x/icon_style_box_flat.png) | bin | 695 -> 695 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_style_box_texture.png (renamed from tools/editor/icons/2x/icon_style_box_texture.png) | bin | 693 -> 693 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_tab_container.png (renamed from tools/editor/icons/2x/icon_tab_container.png) | bin | 334 -> 334 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_tabs.png (renamed from tools/editor/icons/2x/icon_tabs.png) | bin | 222 -> 222 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_test_cube.png (renamed from tools/editor/icons/2x/icon_test_cube.png) | bin | 596 -> 596 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_text_edit.png (renamed from tools/editor/icons/2x/icon_text_edit.png) | bin | 329 -> 329 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_texture.png (renamed from tools/editor/icons/2x/icon_texture.png) | bin | 262 -> 262 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_texture_button.png (renamed from tools/editor/icons/2x/icon_texture_button.png) | bin | 190 -> 190 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_texture_progress.png (renamed from tools/editor/icons/2x/icon_texture_progress.png) | bin | 344 -> 344 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_texture_rect.png (renamed from tools/editor/icons/2x/icon_texture_rect.png) | bin | 201 -> 201 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_theme.png (renamed from tools/editor/icons/2x/icon_theme.png) | bin | 809 -> 809 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_tile_map.png (renamed from tools/editor/icons/2x/icon_tile_map.png) | bin | 139 -> 139 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_tile_set.png (renamed from tools/editor/icons/2x/icon_tile_set.png) | bin | 242 -> 242 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_timer.png (renamed from tools/editor/icons/2x/icon_timer.png) | bin | 909 -> 909 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_tool_button.png (renamed from tools/editor/icons/2x/icon_tool_button.png) | bin | 425 -> 425 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_tool_move.png (renamed from tools/editor/icons/2x/icon_tool_move.png) | bin | 353 -> 353 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_tool_pan.png (renamed from tools/editor/icons/2x/icon_tool_pan.png) | bin | 479 -> 479 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_tool_rotate.png (renamed from tools/editor/icons/2x/icon_tool_rotate.png) | bin | 786 -> 786 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_tool_scale.png (renamed from tools/editor/icons/2x/icon_tool_scale.png) | bin | 562 -> 562 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_tool_select.png (renamed from tools/editor/icons/2x/icon_tool_select.png) | bin | 659 -> 659 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_tools.png (renamed from tools/editor/icons/2x/icon_tools.png) | bin | 759 -> 759 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_touch_screen_button.png (renamed from tools/editor/icons/2x/icon_touch_screen_button.png) | bin | 511 -> 511 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_track_add_key.png (renamed from tools/editor/icons/2x/icon_track_add_key.png) | bin | 127 -> 127 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_track_add_key_hl.png (renamed from tools/editor/icons/2x/icon_track_add_key_hl.png) | bin | 128 -> 128 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_track_continuous.png (renamed from tools/editor/icons/2x/icon_track_continuous.png) | bin | 434 -> 434 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_track_discrete.png (renamed from tools/editor/icons/2x/icon_track_discrete.png) | bin | 196 -> 196 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_track_trigger.png (renamed from tools/editor/icons/2x/icon_track_trigger.png) | bin | 214 -> 214 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_translation.png (renamed from tools/editor/icons/2x/icon_translation.png) | bin | 285 -> 285 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_transparent.png (renamed from tools/editor/icons/2x/icon_transparent.png) | bin | 177 -> 177 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_transpose.png (renamed from tools/editor/icons/2x/icon_transpose.png) | bin | 210 -> 210 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_tree.png (renamed from tools/editor/icons/2x/icon_tree.png) | bin | 417 -> 417 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_tween.png (renamed from tools/editor/icons/2x/icon_tween.png) | bin | 315 -> 315 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_unbone.png (renamed from tools/editor/icons/2x/icon_unbone.png) | bin | 661 -> 661 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_ungroup.png (renamed from tools/editor/icons/2x/icon_ungroup.png) | bin | 202 -> 202 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_uninstance.png (renamed from tools/editor/icons/2x/icon_uninstance.png) | bin | 883 -> 883 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_unlock.png (renamed from tools/editor/icons/2x/icon_unlock.png) | bin | 388 -> 388 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_uv.png (renamed from tools/editor/icons/2x/icon_uv.png) | bin | 502 -> 502 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_v_box_container.png (renamed from tools/editor/icons/2x/icon_v_box_container.png) | bin | 327 -> 327 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_v_button_array.png (renamed from tools/editor/icons/2x/icon_v_button_array.png) | bin | 231 -> 231 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_v_scroll_bar.png (renamed from tools/editor/icons/2x/icon_v_scroll_bar.png) | bin | 328 -> 328 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_v_separator.png (renamed from tools/editor/icons/2x/icon_v_separator.png) | bin | 154 -> 154 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_v_slider.png (renamed from tools/editor/icons/2x/icon_v_slider.png) | bin | 391 -> 391 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_v_split_container.png (renamed from tools/editor/icons/2x/icon_v_split_container.png) | bin | 425 -> 425 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_vector.png (renamed from tools/editor/icons/2x/icon_vector.png) | bin | 270 -> 270 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_vector2.png (renamed from tools/editor/icons/2x/icon_vector2.png) | bin | 141 -> 141 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_vehicle_body.png (renamed from tools/editor/icons/2x/icon_vehicle_body.png) | bin | 410 -> 410 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_vehicle_wheel.png (renamed from tools/editor/icons/2x/icon_vehicle_wheel.png) | bin | 1269 -> 1269 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_video_player.png (renamed from tools/editor/icons/2x/icon_video_player.png) | bin | 501 -> 501 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_viewport.png (renamed from tools/editor/icons/2x/icon_viewport.png) | bin | 349 -> 349 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_viewport_container.png (renamed from tools/editor/icons/2x/icon_viewport_container.png) | bin | 528 -> 528 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_viewport_sprite.png (renamed from tools/editor/icons/2x/icon_viewport_sprite.png) | bin | 403 -> 403 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_viewport_texture.png (renamed from tools/editor/icons/2x/icon_viewport_texture.png) | bin | 404 -> 404 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_visibility_enabler.png (renamed from tools/editor/icons/2x/icon_visibility_enabler.png) | bin | 1106 -> 1106 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_visibility_enabler_2d.png (renamed from tools/editor/icons/2x/icon_visibility_enabler_2d.png) | bin | 1114 -> 1114 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_visibility_notifier.png (renamed from tools/editor/icons/2x/icon_visibility_notifier.png) | bin | 832 -> 832 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_visibility_notifier_2d.png (renamed from tools/editor/icons/2x/icon_visibility_notifier_2d.png) | bin | 844 -> 844 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_visible.png (renamed from tools/editor/icons/2x/icon_visible.png) | bin | 994 -> 994 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_visual_script.png (renamed from tools/editor/icons/2x/icon_visual_script.png) | bin | 707 -> 707 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_visual_shader_port.png (renamed from tools/editor/icons/2x/icon_visual_shader_port.png) | bin | 338 -> 338 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_vu_empty.png (renamed from tools/editor/icons/2x/icon_vu_empty.png) | bin | 452 -> 452 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_vu_full.png (renamed from tools/editor/icons/2x/icon_vu_full.png) | bin | 350 -> 350 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_warning.png (renamed from tools/editor/icons/2x/icon_warning.png) | bin | 154 -> 154 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_window_dialog.png (renamed from tools/editor/icons/2x/icon_window_dialog.png) | bin | 311 -> 311 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_world.png (renamed from tools/editor/icons/2x/icon_world.png) | bin | 502 -> 502 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_world_2d.png (renamed from tools/editor/icons/2x/icon_world_2d.png) | bin | 584 -> 584 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_world_environment.png (renamed from tools/editor/icons/2x/icon_world_environment.png) | bin | 1371 -> 1371 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_y_sort.png (renamed from tools/editor/icons/2x/icon_y_sort.png) | bin | 293 -> 293 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_zoom.png (renamed from tools/editor/icons/2x/icon_zoom.png) | bin | 762 -> 762 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_zoom_less.png (renamed from tools/editor/icons/2x/icon_zoom_less.png) | bin | 162 -> 162 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_zoom_more.png (renamed from tools/editor/icons/2x/icon_zoom_more.png) | bin | 290 -> 290 bytes | |||
-rw-r--r-- | editor/icons/2x/icon_zoom_reset.png (renamed from tools/editor/icons/2x/icon_zoom_reset.png) | bin | 689 -> 689 bytes | |||
-rw-r--r-- | editor/icons/SCsub | 96 | ||||
-rw-r--r-- | editor/icons/icon_accept_dialog.png (renamed from tools/editor/icons/icon_accept_dialog.png) | bin | 338 -> 338 bytes | |||
-rw-r--r-- | editor/icons/icon_add.png (renamed from tools/editor/icons/icon_add.png) | bin | 129 -> 129 bytes | |||
-rw-r--r-- | editor/icons/icon_add_track.png (renamed from tools/editor/icons/icon_add_track.png) | bin | 129 -> 129 bytes | |||
-rw-r--r-- | editor/icons/icon_anchor.png (renamed from tools/editor/icons/icon_anchor.png) | bin | 451 -> 451 bytes | |||
-rw-r--r-- | editor/icons/icon_anim_export.png (renamed from tools/editor/icons/icon_anim_export.png) | bin | 552 -> 552 bytes | |||
-rw-r--r-- | editor/icons/icon_anim_export_all.png (renamed from tools/editor/icons/icon_anim_export_all.png) | bin | 566 -> 566 bytes | |||
-rw-r--r-- | editor/icons/icon_anim_get.png (renamed from tools/editor/icons/icon_anim_get.png) | bin | 276 -> 276 bytes | |||
-rw-r--r-- | editor/icons/icon_anim_get_hl.png (renamed from tools/editor/icons/icon_anim_get_hl.png) | bin | 270 -> 270 bytes | |||
-rw-r--r-- | editor/icons/icon_anim_import.png (renamed from tools/editor/icons/icon_anim_import.png) | bin | 572 -> 572 bytes | |||
-rw-r--r-- | editor/icons/icon_anim_import_all.png (renamed from tools/editor/icons/icon_anim_import_all.png) | bin | 586 -> 586 bytes | |||
-rw-r--r-- | editor/icons/icon_anim_set.png (renamed from tools/editor/icons/icon_anim_set.png) | bin | 287 -> 287 bytes | |||
-rw-r--r-- | editor/icons/icon_anim_set_hl.png (renamed from tools/editor/icons/icon_anim_set_hl.png) | bin | 268 -> 268 bytes | |||
-rw-r--r-- | editor/icons/icon_animated_sprite.png (renamed from tools/editor/icons/icon_animated_sprite.png) | bin | 584 -> 584 bytes | |||
-rw-r--r-- | editor/icons/icon_animated_sprite_3d.png (renamed from tools/editor/icons/icon_animated_sprite_3d.png) | bin | 552 -> 552 bytes | |||
-rw-r--r-- | editor/icons/icon_animation.png (renamed from tools/editor/icons/icon_animation.png) | bin | 399 -> 399 bytes | |||
-rw-r--r-- | editor/icons/icon_animation_node.png (renamed from tools/editor/icons/icon_animation_node.png) | bin | 261 -> 261 bytes | |||
-rw-r--r-- | editor/icons/icon_animation_play.png (renamed from tools/editor/icons/icon_animation_play.png) | bin | 593 -> 593 bytes | |||
-rw-r--r-- | editor/icons/icon_animation_player.png (renamed from tools/editor/icons/icon_animation_player.png) | bin | 153 -> 153 bytes | |||
-rw-r--r-- | editor/icons/icon_animation_set.png (renamed from tools/editor/icons/icon_animation_set.png) | bin | 529 -> 529 bytes | |||
-rw-r--r-- | editor/icons/icon_animation_tree.png (renamed from tools/editor/icons/icon_animation_tree.png) | bin | 279 -> 279 bytes | |||
-rw-r--r-- | editor/icons/icon_animation_tree_player.png (renamed from tools/editor/icons/icon_animation_tree_player.png) | bin | 279 -> 279 bytes | |||
-rw-r--r-- | editor/icons/icon_area.png (renamed from tools/editor/icons/icon_area.png) | bin | 176 -> 176 bytes | |||
-rw-r--r-- | editor/icons/icon_area_2d.png (renamed from tools/editor/icons/icon_area_2d.png) | bin | 182 -> 182 bytes | |||
-rw-r--r-- | editor/icons/icon_array_data.png (renamed from tools/editor/icons/icon_array_data.png) | bin | 176 -> 176 bytes | |||
-rw-r--r-- | editor/icons/icon_array_float.png (renamed from tools/editor/icons/icon_array_float.png) | bin | 177 -> 177 bytes | |||
-rw-r--r-- | editor/icons/icon_array_int.png (renamed from tools/editor/icons/icon_array_int.png) | bin | 172 -> 172 bytes | |||
-rw-r--r-- | editor/icons/icon_array_string.png (renamed from tools/editor/icons/icon_array_string.png) | bin | 178 -> 178 bytes | |||
-rw-r--r-- | editor/icons/icon_array_variant.png (renamed from tools/editor/icons/icon_array_variant.png) | bin | 172 -> 172 bytes | |||
-rw-r--r-- | editor/icons/icon_arrow_left.png (renamed from tools/editor/icons/icon_arrow_left.png) | bin | 211 -> 211 bytes | |||
-rw-r--r-- | editor/icons/icon_arrow_left_disabled.png (renamed from tools/editor/icons/icon_arrow_left_disabled.png) | bin | 244 -> 244 bytes | |||
-rw-r--r-- | editor/icons/icon_arrow_right.png (renamed from tools/editor/icons/icon_arrow_right.png) | bin | 215 -> 215 bytes | |||
-rw-r--r-- | editor/icons/icon_arrow_right_disabled.png (renamed from tools/editor/icons/icon_arrow_right_disabled.png) | bin | 252 -> 252 bytes | |||
-rw-r--r-- | editor/icons/icon_arrow_up.png (renamed from tools/editor/icons/icon_arrow_up.png) | bin | 223 -> 223 bytes | |||
-rw-r--r-- | editor/icons/icon_arrow_up_disabled.png (renamed from tools/editor/icons/icon_arrow_up_disabled.png) | bin | 275 -> 275 bytes | |||
-rw-r--r-- | editor/icons/icon_atlas_texture.png (renamed from tools/editor/icons/icon_atlas_texture.png) | bin | 286 -> 286 bytes | |||
-rw-r--r-- | editor/icons/icon_audio_effect_amplify.png (renamed from tools/editor/icons/icon_audio_effect_amplify.png) | bin | 379 -> 379 bytes | |||
-rw-r--r-- | editor/icons/icon_audio_stream_gibberish.png (renamed from tools/editor/icons/icon_audio_stream_gibberish.png) | bin | 250 -> 250 bytes | |||
-rw-r--r-- | editor/icons/icon_audio_stream_m_p_c.png (renamed from tools/editor/icons/icon_audio_stream_m_p_c.png) | bin | 832 -> 832 bytes | |||
-rw-r--r-- | editor/icons/icon_audio_stream_o_g_g_vorbis.png (renamed from tools/editor/icons/icon_audio_stream_o_g_g_vorbis.png) | bin | 774 -> 774 bytes | |||
-rw-r--r-- | editor/icons/icon_audio_stream_opus.png (renamed from tools/editor/icons/icon_audio_stream_opus.png) | bin | 559 -> 559 bytes | |||
-rw-r--r-- | editor/icons/icon_audio_stream_speex.png (renamed from tools/editor/icons/icon_audio_stream_speex.png) | bin | 1080 -> 1080 bytes | |||
-rw-r--r-- | editor/icons/icon_auto_play.png (renamed from tools/editor/icons/icon_auto_play.png) | bin | 370 -> 370 bytes | |||
-rw-r--r-- | editor/icons/icon_b_c_s_f_x.png (renamed from tools/editor/icons/icon_b_c_s_f_x.png) | bin | 451 -> 451 bytes | |||
-rw-r--r-- | editor/icons/icon_b_g_color_f_x.png (renamed from tools/editor/icons/icon_b_g_color_f_x.png) | bin | 367 -> 367 bytes | |||
-rw-r--r-- | editor/icons/icon_b_g_image_f_x.png (renamed from tools/editor/icons/icon_b_g_image_f_x.png) | bin | 753 -> 753 bytes | |||
-rw-r--r-- | editor/icons/icon_back.png (renamed from tools/editor/icons/icon_back.png) | bin | 223 -> 223 bytes | |||
-rw-r--r-- | editor/icons/icon_back_buffer_copy.png (renamed from tools/editor/icons/icon_back_buffer_copy.png) | bin | 158 -> 158 bytes | |||
-rw-r--r-- | editor/icons/icon_back_disabled.png (renamed from tools/editor/icons/icon_back_disabled.png) | bin | 175 -> 175 bytes | |||
-rw-r--r-- | editor/icons/icon_back_no.png (renamed from tools/editor/icons/icon_back_no.png) | bin | 213 -> 213 bytes | |||
-rw-r--r-- | editor/icons/icon_bake.png (renamed from tools/editor/icons/icon_bake.png) | bin | 180 -> 180 bytes | |||
-rw-r--r-- | editor/icons/icon_baked_light.png (renamed from tools/editor/icons/icon_baked_light.png) | bin | 180 -> 180 bytes | |||
-rw-r--r-- | editor/icons/icon_baked_light_instance.png (renamed from tools/editor/icons/icon_baked_light_instance.png) | bin | 179 -> 179 bytes | |||
-rw-r--r-- | editor/icons/icon_baked_light_sampler.png (renamed from tools/editor/icons/icon_baked_light_sampler.png) | bin | 230 -> 230 bytes | |||
-rw-r--r-- | editor/icons/icon_bit_map.png (renamed from tools/editor/icons/icon_bit_map.png) | bin | 113 -> 113 bytes | |||
-rw-r--r-- | editor/icons/icon_bitmap_font.png (renamed from tools/editor/icons/icon_bitmap_font.png) | bin | 160 -> 160 bytes | |||
-rw-r--r-- | editor/icons/icon_blend.png (renamed from tools/editor/icons/icon_blend.png) | bin | 578 -> 578 bytes | |||
-rw-r--r-- | editor/icons/icon_bone.png (renamed from tools/editor/icons/icon_bone.png) | bin | 349 -> 349 bytes | |||
-rw-r--r-- | editor/icons/icon_bone_attachment.png (renamed from tools/editor/icons/icon_bone_attachment.png) | bin | 333 -> 333 bytes | |||
-rw-r--r-- | editor/icons/icon_bone_track.png (renamed from tools/editor/icons/icon_bone_track.png) | bin | 343 -> 343 bytes | |||
-rw-r--r-- | editor/icons/icon_bool.png (renamed from tools/editor/icons/icon_bool.png) | bin | 154 -> 154 bytes | |||
-rw-r--r-- | editor/icons/icon_box_shape.png (renamed from tools/editor/icons/icon_box_shape.png) | bin | 392 -> 392 bytes | |||
-rw-r--r-- | editor/icons/icon_bus_vu_db.png (renamed from tools/editor/icons/icon_bus_vu_db.png) | bin | 1136 -> 1136 bytes | |||
-rw-r--r-- | editor/icons/icon_bus_vu_empty.png (renamed from tools/editor/icons/icon_bus_vu_empty.png) | bin | 1631 -> 1631 bytes | |||
-rw-r--r-- | editor/icons/icon_bus_vu_frozen.png (renamed from tools/editor/icons/icon_bus_vu_frozen.png) | bin | 267 -> 267 bytes | |||
-rw-r--r-- | editor/icons/icon_bus_vu_full.png (renamed from tools/editor/icons/icon_bus_vu_full.png) | bin | 2463 -> 2463 bytes | |||
-rw-r--r-- | editor/icons/icon_button.png (renamed from tools/editor/icons/icon_button.png) | bin | 163 -> 163 bytes | |||
-rw-r--r-- | editor/icons/icon_button_group.png (renamed from tools/editor/icons/icon_button_group.png) | bin | 165 -> 165 bytes | |||
-rw-r--r-- | editor/icons/icon_camera.png (renamed from tools/editor/icons/icon_camera.png) | bin | 225 -> 225 bytes | |||
-rw-r--r-- | editor/icons/icon_camera_2d.png (renamed from tools/editor/icons/icon_camera_2d.png) | bin | 229 -> 229 bytes | |||
-rw-r--r-- | editor/icons/icon_canvas_item.png (renamed from tools/editor/icons/icon_canvas_item.png) | bin | 411 -> 411 bytes | |||
-rw-r--r-- | editor/icons/icon_canvas_item_material.png (renamed from tools/editor/icons/icon_canvas_item_material.png) | bin | 350 -> 350 bytes | |||
-rw-r--r-- | editor/icons/icon_canvas_item_shader.png (renamed from tools/editor/icons/icon_canvas_item_shader.png) | bin | 416 -> 416 bytes | |||
-rw-r--r-- | editor/icons/icon_canvas_item_shader_graph.png (renamed from tools/editor/icons/icon_canvas_item_shader_graph.png) | bin | 440 -> 440 bytes | |||
-rw-r--r-- | editor/icons/icon_canvas_layer.png (renamed from tools/editor/icons/icon_canvas_layer.png) | bin | 474 -> 474 bytes | |||
-rw-r--r-- | editor/icons/icon_canvas_modulate.png (renamed from tools/editor/icons/icon_canvas_modulate.png) | bin | 213 -> 213 bytes | |||
-rw-r--r-- | editor/icons/icon_capsule_shape.png (renamed from tools/editor/icons/icon_capsule_shape.png) | bin | 225 -> 225 bytes | |||
-rw-r--r-- | editor/icons/icon_capsule_shape_2d.png (renamed from tools/editor/icons/icon_capsule_shape_2d.png) | bin | 309 -> 309 bytes | |||
-rw-r--r-- | editor/icons/icon_center_container.png (renamed from tools/editor/icons/icon_center_container.png) | bin | 294 -> 294 bytes | |||
-rw-r--r-- | editor/icons/icon_character_body.png (renamed from tools/editor/icons/icon_character_body.png) | bin | 559 -> 559 bytes | |||
-rw-r--r-- | editor/icons/icon_character_camera.png (renamed from tools/editor/icons/icon_character_camera.png) | bin | 477 -> 477 bytes | |||
-rw-r--r-- | editor/icons/icon_check_box.png (renamed from tools/editor/icons/icon_check_box.png) | bin | 404 -> 404 bytes | |||
-rw-r--r-- | editor/icons/icon_check_button.png (renamed from tools/editor/icons/icon_check_button.png) | bin | 283 -> 283 bytes | |||
-rw-r--r-- | editor/icons/icon_checkerboard.png (renamed from tools/editor/icons/icon_checkerboard.png) | bin | 253 -> 253 bytes | |||
-rw-r--r-- | editor/icons/icon_circle_shape_2d.png (renamed from tools/editor/icons/icon_circle_shape_2d.png) | bin | 425 -> 425 bytes | |||
-rw-r--r-- | editor/icons/icon_class_list.png (renamed from tools/editor/icons/icon_class_list.png) | bin | 157 -> 157 bytes | |||
-rw-r--r-- | editor/icons/icon_click2edit.png (renamed from tools/editor/icons/icon_click2edit.png) | bin | 294 -> 294 bytes | |||
-rw-r--r-- | editor/icons/icon_close.png (renamed from tools/editor/icons/icon_close.png) | bin | 325 -> 325 bytes | |||
-rw-r--r-- | editor/icons/icon_close_hover.png (renamed from tools/editor/icons/icon_close_hover.png) | bin | 391 -> 391 bytes | |||
-rw-r--r-- | editor/icons/icon_collapse.png (renamed from tools/editor/icons/icon_collapse.png) | bin | 230 -> 230 bytes | |||
-rw-r--r-- | editor/icons/icon_collapse_hl.png (renamed from tools/editor/icons/icon_collapse_hl.png) | bin | 338 -> 338 bytes | |||
-rw-r--r-- | editor/icons/icon_collision.png (renamed from tools/editor/icons/icon_collision.png) | bin | 320 -> 320 bytes | |||
-rw-r--r-- | editor/icons/icon_collision_2d.png (renamed from tools/editor/icons/icon_collision_2d.png) | bin | 281 -> 281 bytes | |||
-rw-r--r-- | editor/icons/icon_collision_polygon.png (renamed from tools/editor/icons/icon_collision_polygon.png) | bin | 287 -> 287 bytes | |||
-rw-r--r-- | editor/icons/icon_collision_polygon_2d.png (renamed from tools/editor/icons/icon_collision_polygon_2d.png) | bin | 281 -> 281 bytes | |||
-rw-r--r-- | editor/icons/icon_collision_shape.png (renamed from tools/editor/icons/icon_collision_shape.png) | bin | 278 -> 278 bytes | |||
-rw-r--r-- | editor/icons/icon_collision_shape_2d.png (renamed from tools/editor/icons/icon_collision_shape_2d.png) | bin | 164 -> 164 bytes | |||
-rw-r--r-- | editor/icons/icon_color.png (renamed from tools/editor/icons/icon_color.png) | bin | 582 -> 582 bytes | |||
-rw-r--r-- | editor/icons/icon_color_pick.png (renamed from tools/editor/icons/icon_color_pick.png) | bin | 416 -> 416 bytes | |||
-rw-r--r-- | editor/icons/icon_color_picker.png (renamed from tools/editor/icons/icon_color_picker.png) | bin | 432 -> 432 bytes | |||
-rw-r--r-- | editor/icons/icon_color_picker_button.png (renamed from tools/editor/icons/icon_color_picker_button.png) | bin | 548 -> 548 bytes | |||
-rw-r--r-- | editor/icons/icon_color_ramp.png (renamed from tools/editor/icons/icon_color_ramp.png) | bin | 222 -> 222 bytes | |||
-rw-r--r-- | editor/icons/icon_color_rect.png (renamed from tools/editor/icons/icon_color_rect.png) | bin | 214 -> 214 bytes | |||
-rw-r--r-- | editor/icons/icon_concave_polygon_shape.png (renamed from tools/editor/icons/icon_concave_polygon_shape.png) | bin | 449 -> 449 bytes | |||
-rw-r--r-- | editor/icons/icon_concave_polygon_shape_2d.png (renamed from tools/editor/icons/icon_concave_polygon_shape_2d.png) | bin | 321 -> 321 bytes | |||
-rw-r--r-- | editor/icons/icon_cone_twist_joint.png (renamed from tools/editor/icons/icon_cone_twist_joint.png) | bin | 497 -> 497 bytes | |||
-rw-r--r-- | editor/icons/icon_confirmation_dialog.png (renamed from tools/editor/icons/icon_confirmation_dialog.png) | bin | 330 -> 330 bytes | |||
-rw-r--r-- | editor/icons/icon_connect.png (renamed from tools/editor/icons/icon_connect.png) | bin | 170 -> 170 bytes | |||
-rw-r--r-- | editor/icons/icon_connection_and_groups.png (renamed from tools/editor/icons/icon_connection_and_groups.png) | bin | 228 -> 228 bytes | |||
-rw-r--r-- | editor/icons/icon_console.png (renamed from tools/editor/icons/icon_console.png) | bin | 640 -> 640 bytes | |||
-rw-r--r-- | editor/icons/icon_container.png (renamed from tools/editor/icons/icon_container.png) | bin | 188 -> 188 bytes | |||
-rw-r--r-- | editor/icons/icon_control.png (renamed from tools/editor/icons/icon_control.png) | bin | 414 -> 414 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_bottom_center.png (renamed from tools/editor/icons/icon_control_align_bottom_center.png) | bin | 134 -> 134 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_bottom_left.png (renamed from tools/editor/icons/icon_control_align_bottom_left.png) | bin | 134 -> 134 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_bottom_right.png (renamed from tools/editor/icons/icon_control_align_bottom_right.png) | bin | 134 -> 134 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_bottom_wide.png (renamed from tools/editor/icons/icon_control_align_bottom_wide.png) | bin | 135 -> 135 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_center.png (renamed from tools/editor/icons/icon_control_align_center.png) | bin | 142 -> 142 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_center_left.png (renamed from tools/editor/icons/icon_control_align_center_left.png) | bin | 116 -> 116 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_center_right.png (renamed from tools/editor/icons/icon_control_align_center_right.png) | bin | 117 -> 117 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_left_center.png (renamed from tools/editor/icons/icon_control_align_left_center.png) | bin | 141 -> 141 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_left_wide.png (renamed from tools/editor/icons/icon_control_align_left_wide.png) | bin | 123 -> 123 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_right_center.png (renamed from tools/editor/icons/icon_control_align_right_center.png) | bin | 142 -> 142 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_right_wide.png (renamed from tools/editor/icons/icon_control_align_right_wide.png) | bin | 124 -> 124 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_top_center.png (renamed from tools/editor/icons/icon_control_align_top_center.png) | bin | 141 -> 141 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_top_left.png (renamed from tools/editor/icons/icon_control_align_top_left.png) | bin | 136 -> 136 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_top_right.png (renamed from tools/editor/icons/icon_control_align_top_right.png) | bin | 141 -> 141 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_top_wide.png (renamed from tools/editor/icons/icon_control_align_top_wide.png) | bin | 136 -> 136 bytes | |||
-rw-r--r-- | editor/icons/icon_control_align_wide.png (renamed from tools/editor/icons/icon_control_align_wide.png) | bin | 123 -> 123 bytes | |||
-rw-r--r-- | editor/icons/icon_control_hcenter_wide.png (renamed from tools/editor/icons/icon_control_hcenter_wide.png) | bin | 142 -> 142 bytes | |||
-rw-r--r-- | editor/icons/icon_control_vcenter_wide.png (renamed from tools/editor/icons/icon_control_vcenter_wide.png) | bin | 128 -> 128 bytes | |||
-rw-r--r-- | editor/icons/icon_convex_polygon_shape.png (renamed from tools/editor/icons/icon_convex_polygon_shape.png) | bin | 404 -> 404 bytes | |||
-rw-r--r-- | editor/icons/icon_convex_polygon_shape_2d.png (renamed from tools/editor/icons/icon_convex_polygon_shape_2d.png) | bin | 297 -> 297 bytes | |||
-rw-r--r-- | editor/icons/icon_copy_node_path.png (renamed from tools/editor/icons/icon_copy_node_path.png) | bin | 248 -> 248 bytes | |||
-rw-r--r-- | editor/icons/icon_create_new_scene_from.png (renamed from tools/editor/icons/icon_create_new_scene_from.png) | bin | 349 -> 349 bytes | |||
-rw-r--r-- | editor/icons/icon_cube_grid_map.png (renamed from tools/editor/icons/icon_cube_grid_map.png) | bin | 607 -> 607 bytes | |||
-rw-r--r-- | editor/icons/icon_cube_map.png (renamed from tools/editor/icons/icon_cube_map.png) | bin | 134 -> 134 bytes | |||
-rw-r--r-- | editor/icons/icon_curve.png (renamed from tools/editor/icons/icon_curve.png) | bin | 315 -> 315 bytes | |||
-rw-r--r-- | editor/icons/icon_curve_2d.png (renamed from tools/editor/icons/icon_curve_2d.png) | bin | 342 -> 342 bytes | |||
-rw-r--r-- | editor/icons/icon_curve_3d.png (renamed from tools/editor/icons/icon_curve_3d.png) | bin | 336 -> 336 bytes | |||
-rw-r--r-- | editor/icons/icon_curve_close.png (renamed from tools/editor/icons/icon_curve_close.png) | bin | 351 -> 351 bytes | |||
-rw-r--r-- | editor/icons/icon_curve_constant.png (renamed from tools/editor/icons/icon_curve_constant.png) | bin | 114 -> 114 bytes | |||
-rw-r--r-- | editor/icons/icon_curve_create.png (renamed from tools/editor/icons/icon_curve_create.png) | bin | 375 -> 375 bytes | |||
-rw-r--r-- | editor/icons/icon_curve_curve.png (renamed from tools/editor/icons/icon_curve_curve.png) | bin | 412 -> 412 bytes | |||
-rw-r--r-- | editor/icons/icon_curve_delete.png (renamed from tools/editor/icons/icon_curve_delete.png) | bin | 457 -> 457 bytes | |||
-rw-r--r-- | editor/icons/icon_curve_edit.png (renamed from tools/editor/icons/icon_curve_edit.png) | bin | 488 -> 488 bytes | |||
-rw-r--r-- | editor/icons/icon_curve_in.png (renamed from tools/editor/icons/icon_curve_in.png) | bin | 257 -> 257 bytes | |||
-rw-r--r-- | editor/icons/icon_curve_in_out.png (renamed from tools/editor/icons/icon_curve_in_out.png) | bin | 282 -> 282 bytes | |||
-rw-r--r-- | editor/icons/icon_curve_linear.png (renamed from tools/editor/icons/icon_curve_linear.png) | bin | 219 -> 219 bytes | |||
-rw-r--r-- | editor/icons/icon_curve_out.png (renamed from tools/editor/icons/icon_curve_out.png) | bin | 263 -> 263 bytes | |||
-rw-r--r-- | editor/icons/icon_curve_out_in.png (renamed from tools/editor/icons/icon_curve_out_in.png) | bin | 288 -> 288 bytes | |||
-rw-r--r-- | editor/icons/icon_cylinder_shape.png (renamed from tools/editor/icons/icon_cylinder_shape.png) | bin | 673 -> 673 bytes | |||
-rw-r--r-- | editor/icons/icon_d_o_f_blur_f_x.png (renamed from tools/editor/icons/icon_d_o_f_blur_f_x.png) | bin | 796 -> 796 bytes | |||
-rw-r--r-- | editor/icons/icon_damped_spring_joint_2d.png (renamed from tools/editor/icons/icon_damped_spring_joint_2d.png) | bin | 316 -> 316 bytes | |||
-rw-r--r-- | editor/icons/icon_debug.png (renamed from tools/editor/icons/icon_debug.png) | bin | 659 -> 659 bytes | |||
-rw-r--r-- | editor/icons/icon_debug_continue.png (renamed from tools/editor/icons/icon_debug_continue.png) | bin | 302 -> 302 bytes | |||
-rw-r--r-- | editor/icons/icon_debug_next.png (renamed from tools/editor/icons/icon_debug_next.png) | bin | 220 -> 220 bytes | |||
-rw-r--r-- | editor/icons/icon_debug_step.png (renamed from tools/editor/icons/icon_debug_step.png) | bin | 219 -> 219 bytes | |||
-rw-r--r-- | editor/icons/icon_default_project_icon.png (renamed from tools/editor/icons/icon_default_project_icon.png) | bin | 2713 -> 2713 bytes | |||
-rw-r--r-- | editor/icons/icon_del.png (renamed from tools/editor/icons/icon_del.png) | bin | 398 -> 398 bytes | |||
-rw-r--r-- | editor/icons/icon_dependency_changed.png (renamed from tools/editor/icons/icon_dependency_changed.png) | bin | 392 -> 392 bytes | |||
-rw-r--r-- | editor/icons/icon_dependency_changed_hl.png (renamed from tools/editor/icons/icon_dependency_changed_hl.png) | bin | 330 -> 330 bytes | |||
-rw-r--r-- | editor/icons/icon_dependency_local_changed.png (renamed from tools/editor/icons/icon_dependency_local_changed.png) | bin | 571 -> 571 bytes | |||
-rw-r--r-- | editor/icons/icon_dependency_local_changed_hl.png (renamed from tools/editor/icons/icon_dependency_local_changed_hl.png) | bin | 460 -> 460 bytes | |||
-rw-r--r-- | editor/icons/icon_dependency_ok.png (renamed from tools/editor/icons/icon_dependency_ok.png) | bin | 518 -> 518 bytes | |||
-rw-r--r-- | editor/icons/icon_dependency_ok_hl.png (renamed from tools/editor/icons/icon_dependency_ok_hl.png) | bin | 413 -> 413 bytes | |||
-rw-r--r-- | editor/icons/icon_directional_light.png (renamed from tools/editor/icons/icon_directional_light.png) | bin | 426 -> 426 bytes | |||
-rw-r--r-- | editor/icons/icon_distraction_free.png (renamed from tools/editor/icons/icon_distraction_free.png) | bin | 397 -> 397 bytes | |||
-rw-r--r-- | editor/icons/icon_doc_code_font.png (renamed from tools/editor/icons/icon_doc_code_font.png) | bin | 8123 -> 8123 bytes | |||
-rw-r--r-- | editor/icons/icon_doc_font.png (renamed from tools/editor/icons/icon_doc_font.png) | bin | 8213 -> 8213 bytes | |||
-rw-r--r-- | editor/icons/icon_doc_title_font.png (renamed from tools/editor/icons/icon_doc_title_font.png) | bin | 10222 -> 10222 bytes | |||
-rw-r--r-- | editor/icons/icon_down.png (renamed from tools/editor/icons/icon_down.png) | bin | 186 -> 186 bytes | |||
-rw-r--r-- | editor/icons/icon_dummy.png (renamed from tools/editor/icons/icon_dummy.png) | bin | 217 -> 217 bytes | |||
-rw-r--r-- | editor/icons/icon_duplicate.png (renamed from tools/editor/icons/icon_duplicate.png) | bin | 167 -> 167 bytes | |||
-rw-r--r-- | editor/icons/icon_dynamic_character_body.png (renamed from tools/editor/icons/icon_dynamic_character_body.png) | bin | 559 -> 559 bytes | |||
-rw-r--r-- | editor/icons/icon_dynamic_custom_body.png (renamed from tools/editor/icons/icon_dynamic_custom_body.png) | bin | 556 -> 556 bytes | |||
-rw-r--r-- | editor/icons/icon_dynamic_font.png (renamed from tools/editor/icons/icon_dynamic_font.png) | bin | 239 -> 239 bytes | |||
-rw-r--r-- | editor/icons/icon_dynamic_font_data.png (renamed from tools/editor/icons/icon_dynamic_font_data.png) | bin | 246 -> 246 bytes | |||
-rw-r--r-- | editor/icons/icon_dynamic_rigid_body.png (renamed from tools/editor/icons/icon_dynamic_rigid_body.png) | bin | 546 -> 546 bytes | |||
-rw-r--r-- | editor/icons/icon_edit.png (renamed from tools/editor/icons/icon_edit.png) | bin | 346 -> 346 bytes | |||
-rw-r--r-- | editor/icons/icon_edit_key.png (renamed from tools/editor/icons/icon_edit_key.png) | bin | 405 -> 405 bytes | |||
-rw-r--r-- | editor/icons/icon_edit_pivot.png (renamed from tools/editor/icons/icon_edit_pivot.png) | bin | 327 -> 327 bytes | |||
-rw-r--r-- | editor/icons/icon_edit_resource.png (renamed from tools/editor/icons/icon_edit_resource.png) | bin | 232 -> 232 bytes | |||
-rw-r--r-- | editor/icons/icon_edit_small.png (renamed from tools/editor/icons/icon_edit_small.png) | bin | 365 -> 365 bytes | |||
-rw-r--r-- | editor/icons/icon_editor_2d.png (renamed from tools/editor/icons/icon_editor_2d.png) | bin | 197 -> 197 bytes | |||
-rw-r--r-- | editor/icons/icon_editor_3d_handle.png (renamed from tools/editor/icons/icon_editor_3d_handle.png) | bin | 350 -> 350 bytes | |||
-rw-r--r-- | editor/icons/icon_editor_focus.png (renamed from tools/editor/icons/icon_editor_focus.png) | bin | 629 -> 629 bytes | |||
-rw-r--r-- | editor/icons/icon_editor_handle.png (renamed from tools/editor/icons/icon_editor_handle.png) | bin | 214 -> 214 bytes | |||
-rw-r--r-- | editor/icons/icon_editor_node.png (renamed from tools/editor/icons/icon_editor_node.png) | bin | 311 -> 311 bytes | |||
-rw-r--r-- | editor/icons/icon_editor_pivot.png (renamed from tools/editor/icons/icon_editor_pivot.png) | bin | 177 -> 177 bytes | |||
-rw-r--r-- | editor/icons/icon_editor_plugin.png (renamed from tools/editor/icons/icon_editor_plugin.png) | bin | 248 -> 248 bytes | |||
-rw-r--r-- | editor/icons/icon_editor_rect_2d.png (renamed from tools/editor/icons/icon_editor_rect_2d.png) | bin | 222 -> 222 bytes | |||
-rw-r--r-- | editor/icons/icon_empty_control.png (renamed from tools/editor/icons/icon_empty_control.png) | bin | 233 -> 233 bytes | |||
-rw-r--r-- | editor/icons/icon_enum.png (renamed from tools/editor/icons/icon_enum.png) | bin | 123 -> 123 bytes | |||
-rw-r--r-- | editor/icons/icon_environment.png (renamed from tools/editor/icons/icon_environment.png) | bin | 588 -> 588 bytes | |||
-rw-r--r-- | editor/icons/icon_error.png (renamed from tools/editor/icons/icon_error.png) | bin | 121 -> 121 bytes | |||
-rw-r--r-- | editor/icons/icon_error_sign.png (renamed from tools/editor/icons/icon_error_sign.png) | bin | 255 -> 255 bytes | |||
-rw-r--r-- | editor/icons/icon_event_player.png (renamed from tools/editor/icons/icon_event_player.png) | bin | 142 -> 142 bytes | |||
-rw-r--r-- | editor/icons/icon_expand.png (renamed from tools/editor/icons/icon_expand.png) | bin | 322 -> 322 bytes | |||
-rw-r--r-- | editor/icons/icon_expand_hl.png (renamed from tools/editor/icons/icon_expand_hl.png) | bin | 320 -> 320 bytes | |||
-rw-r--r-- | editor/icons/icon_favorites.png (renamed from tools/editor/icons/icon_favorites.png) | bin | 385 -> 385 bytes | |||
-rw-r--r-- | editor/icons/icon_file.png (renamed from tools/editor/icons/icon_file.png) | bin | 157 -> 157 bytes | |||
-rw-r--r-- | editor/icons/icon_file_big.png (renamed from tools/editor/icons/icon_file_big.png) | bin | 317 -> 317 bytes | |||
-rw-r--r-- | editor/icons/icon_file_dialog.png (renamed from tools/editor/icons/icon_file_dialog.png) | bin | 220 -> 220 bytes | |||
-rw-r--r-- | editor/icons/icon_file_list.png (renamed from tools/editor/icons/icon_file_list.png) | bin | 123 -> 123 bytes | |||
-rw-r--r-- | editor/icons/icon_file_server.png (renamed from tools/editor/icons/icon_file_server.png) | bin | 145 -> 145 bytes | |||
-rw-r--r-- | editor/icons/icon_file_server_active.png (renamed from tools/editor/icons/icon_file_server_active.png) | bin | 145 -> 145 bytes | |||
-rw-r--r-- | editor/icons/icon_file_thumbnail.png (renamed from tools/editor/icons/icon_file_thumbnail.png) | bin | 116 -> 116 bytes | |||
-rw-r--r-- | editor/icons/icon_filesystem.png (renamed from tools/editor/icons/icon_filesystem.png) | bin | 157 -> 157 bytes | |||
-rw-r--r-- | editor/icons/icon_fixed_material.png (renamed from tools/editor/icons/icon_fixed_material.png) | bin | 377 -> 377 bytes | |||
-rw-r--r-- | editor/icons/icon_fixed_spatial_material.png (renamed from tools/editor/icons/icon_fixed_spatial_material.png) | bin | 409 -> 409 bytes | |||
-rw-r--r-- | editor/icons/icon_fog_f_x.png (renamed from tools/editor/icons/icon_fog_f_x.png) | bin | 540 -> 540 bytes | |||
-rw-r--r-- | editor/icons/icon_folder.png (renamed from tools/editor/icons/icon_folder.png) | bin | 170 -> 170 bytes | |||
-rw-r--r-- | editor/icons/icon_folder_big.png (renamed from tools/editor/icons/icon_folder_big.png) | bin | 482 -> 482 bytes | |||
-rw-r--r-- | editor/icons/icon_folder_scene.png (renamed from tools/editor/icons/icon_folder_scene.png) | bin | 644 -> 644 bytes | |||
-rw-r--r-- | editor/icons/icon_font.png (renamed from tools/editor/icons/icon_font.png) | bin | 215 -> 215 bytes | |||
-rw-r--r-- | editor/icons/icon_forward.png (renamed from tools/editor/icons/icon_forward.png) | bin | 224 -> 224 bytes | |||
-rw-r--r-- | editor/icons/icon_forward_no.png (renamed from tools/editor/icons/icon_forward_no.png) | bin | 217 -> 217 bytes | |||
-rw-r--r-- | editor/icons/icon_func.png (renamed from tools/editor/icons/icon_func.png) | bin | 262 -> 262 bytes | |||
-rw-r--r-- | editor/icons/icon_g_d_script.png (renamed from tools/editor/icons/icon_g_d_script.png) | bin | 392 -> 392 bytes | |||
-rw-r--r-- | editor/icons/icon_g_i_probe.png (renamed from tools/editor/icons/icon_g_i_probe.png) | bin | 341 -> 341 bytes | |||
-rw-r--r-- | editor/icons/icon_g_i_probe_data.png (renamed from tools/editor/icons/icon_g_i_probe_data.png) | bin | 350 -> 350 bytes | |||
-rw-r--r-- | editor/icons/icon_gamma_f_x.png (renamed from tools/editor/icons/icon_gamma_f_x.png) | bin | 461 -> 461 bytes | |||
-rw-r--r-- | editor/icons/icon_generic_6_d_o_f_joint.png (renamed from tools/editor/icons/icon_generic_6_d_o_f_joint.png) | bin | 390 -> 390 bytes | |||
-rw-r--r-- | editor/icons/icon_gizmo_directional_light.png (renamed from tools/editor/icons/icon_gizmo_directional_light.png) | bin | 3628 -> 3628 bytes | |||
-rw-r--r-- | editor/icons/icon_gizmo_light.png (renamed from tools/editor/icons/icon_gizmo_light.png) | bin | 3064 -> 3064 bytes | |||
-rw-r--r-- | editor/icons/icon_gizmo_listener.png (renamed from tools/editor/icons/icon_gizmo_listener.png) | bin | 3613 -> 3613 bytes | |||
-rw-r--r-- | editor/icons/icon_gizmo_spatial_sample_player.png (renamed from tools/editor/icons/icon_gizmo_spatial_sample_player.png) | bin | 1297 -> 1297 bytes | |||
-rw-r--r-- | editor/icons/icon_gizmo_spatial_stream_player.png (renamed from tools/editor/icons/icon_gizmo_spatial_stream_player.png) | bin | 1720 -> 1720 bytes | |||
-rw-r--r-- | editor/icons/icon_glow_f_x.png (renamed from tools/editor/icons/icon_glow_f_x.png) | bin | 676 -> 676 bytes | |||
-rw-r--r-- | editor/icons/icon_godot.png (renamed from tools/editor/icons/icon_godot.png) | bin | 769 -> 769 bytes | |||
-rw-r--r-- | editor/icons/icon_godot_asset_default.png (renamed from tools/editor/icons/icon_godot_asset_default.png) | bin | 4167 -> 4167 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_color_ramp.png (renamed from tools/editor/icons/icon_graph_color_ramp.png) | bin | 222 -> 222 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_comment.png (renamed from tools/editor/icons/icon_graph_comment.png) | bin | 125 -> 125 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_cube_uniform.png (renamed from tools/editor/icons/icon_graph_cube_uniform.png) | bin | 445 -> 445 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_curve_map.png (renamed from tools/editor/icons/icon_graph_curve_map.png) | bin | 330 -> 330 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_default_texture.png (renamed from tools/editor/icons/icon_graph_default_texture.png) | bin | 196 -> 196 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_edit.png (renamed from tools/editor/icons/icon_graph_edit.png) | bin | 467 -> 467 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_input.png (renamed from tools/editor/icons/icon_graph_input.png) | bin | 268 -> 268 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_node.png (renamed from tools/editor/icons/icon_graph_node.png) | bin | 397 -> 397 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_rgb.png (renamed from tools/editor/icons/icon_graph_rgb.png) | bin | 443 -> 443 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_rgb_op.png (renamed from tools/editor/icons/icon_graph_rgb_op.png) | bin | 165 -> 165 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_rgb_uniform.png (renamed from tools/editor/icons/icon_graph_rgb_uniform.png) | bin | 346 -> 346 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_scalar.png (renamed from tools/editor/icons/icon_graph_scalar.png) | bin | 269 -> 269 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_scalar_interp.png (renamed from tools/editor/icons/icon_graph_scalar_interp.png) | bin | 236 -> 236 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_scalar_op.png (renamed from tools/editor/icons/icon_graph_scalar_op.png) | bin | 266 -> 266 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_scalar_uniform.png (renamed from tools/editor/icons/icon_graph_scalar_uniform.png) | bin | 307 -> 307 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_scalars_to_vec.png (renamed from tools/editor/icons/icon_graph_scalars_to_vec.png) | bin | 172 -> 172 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_texscreen.png (renamed from tools/editor/icons/icon_graph_texscreen.png) | bin | 151 -> 151 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_texture_uniform.png (renamed from tools/editor/icons/icon_graph_texture_uniform.png) | bin | 237 -> 237 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_time.png (renamed from tools/editor/icons/icon_graph_time.png) | bin | 398 -> 398 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_vec_dp.png (renamed from tools/editor/icons/icon_graph_vec_dp.png) | bin | 258 -> 258 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_vec_interp.png (renamed from tools/editor/icons/icon_graph_vec_interp.png) | bin | 229 -> 229 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_vec_length.png (renamed from tools/editor/icons/icon_graph_vec_length.png) | bin | 305 -> 305 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_vec_op.png (renamed from tools/editor/icons/icon_graph_vec_op.png) | bin | 266 -> 266 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_vec_scalar_op.png (renamed from tools/editor/icons/icon_graph_vec_scalar_op.png) | bin | 299 -> 299 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_vec_to_scalars.png (renamed from tools/editor/icons/icon_graph_vec_to_scalars.png) | bin | 181 -> 181 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_vecs_to_xform.png (renamed from tools/editor/icons/icon_graph_vecs_to_xform.png) | bin | 178 -> 178 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_vector.png (renamed from tools/editor/icons/icon_graph_vector.png) | bin | 345 -> 345 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_vector_uniform.png (renamed from tools/editor/icons/icon_graph_vector_uniform.png) | bin | 390 -> 390 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_xform.png (renamed from tools/editor/icons/icon_graph_xform.png) | bin | 241 -> 241 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_xform_mult.png (renamed from tools/editor/icons/icon_graph_xform_mult.png) | bin | 223 -> 223 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_xform_scalar_func.png (renamed from tools/editor/icons/icon_graph_xform_scalar_func.png) | bin | 275 -> 275 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_xform_to_vecs.png (renamed from tools/editor/icons/icon_graph_xform_to_vecs.png) | bin | 195 -> 195 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_xform_uniform.png (renamed from tools/editor/icons/icon_graph_xform_uniform.png) | bin | 310 -> 310 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_xform_vec_func.png (renamed from tools/editor/icons/icon_graph_xform_vec_func.png) | bin | 277 -> 277 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_xform_vec_imult.png (renamed from tools/editor/icons/icon_graph_xform_vec_imult.png) | bin | 327 -> 327 bytes | |||
-rw-r--r-- | editor/icons/icon_graph_xform_vec_mult.png (renamed from tools/editor/icons/icon_graph_xform_vec_mult.png) | bin | 336 -> 336 bytes | |||
-rw-r--r-- | editor/icons/icon_grid.png (renamed from tools/editor/icons/icon_grid.png) | bin | 165 -> 165 bytes | |||
-rw-r--r-- | editor/icons/icon_grid_container.png (renamed from tools/editor/icons/icon_grid_container.png) | bin | 216 -> 216 bytes | |||
-rw-r--r-- | editor/icons/icon_grid_map.png (renamed from tools/editor/icons/icon_grid_map.png) | bin | 122 -> 122 bytes | |||
-rw-r--r-- | editor/icons/icon_grid_map_floor.png (renamed from tools/editor/icons/icon_grid_map_floor.png) | bin | 169 -> 169 bytes | |||
-rw-r--r-- | editor/icons/icon_groove_joint_2d.png (renamed from tools/editor/icons/icon_groove_joint_2d.png) | bin | 150 -> 150 bytes | |||
-rw-r--r-- | editor/icons/icon_group.png (renamed from tools/editor/icons/icon_group.png) | bin | 177 -> 177 bytes | |||
-rw-r--r-- | editor/icons/icon_groups.png (renamed from tools/editor/icons/icon_groups.png) | bin | 194 -> 194 bytes | |||
-rw-r--r-- | editor/icons/icon_h_box_container.png (renamed from tools/editor/icons/icon_h_box_container.png) | bin | 201 -> 201 bytes | |||
-rw-r--r-- | editor/icons/icon_h_button_array.png (renamed from tools/editor/icons/icon_h_button_array.png) | bin | 163 -> 163 bytes | |||
-rw-r--r-- | editor/icons/icon_h_scroll_bar.png (renamed from tools/editor/icons/icon_h_scroll_bar.png) | bin | 205 -> 205 bytes | |||
-rw-r--r-- | editor/icons/icon_h_separator.png (renamed from tools/editor/icons/icon_h_separator.png) | bin | 131 -> 131 bytes | |||
-rw-r--r-- | editor/icons/icon_h_slider.png (renamed from tools/editor/icons/icon_h_slider.png) | bin | 204 -> 204 bytes | |||
-rw-r--r-- | editor/icons/icon_h_split_container.png (renamed from tools/editor/icons/icon_h_split_container.png) | bin | 259 -> 259 bytes | |||
-rw-r--r-- | editor/icons/icon_h_t_t_p_request.png (renamed from tools/editor/icons/icon_h_t_t_p_request.png) | bin | 301 -> 301 bytes | |||
-rw-r--r-- | editor/icons/icon_headphones.png (renamed from tools/editor/icons/icon_headphones.png) | bin | 350 -> 350 bytes | |||
-rw-r--r-- | editor/icons/icon_help.png (renamed from tools/editor/icons/icon_help.png) | bin | 578 -> 578 bytes | |||
-rw-r--r-- | editor/icons/icon_hidden.png (renamed from tools/editor/icons/icon_hidden.png) | bin | 345 -> 345 bytes | |||
-rw-r--r-- | editor/icons/icon_hinge_joint.png (renamed from tools/editor/icons/icon_hinge_joint.png) | bin | 353 -> 353 bytes | |||
-rw-r--r-- | editor/icons/icon_history.png (renamed from tools/editor/icons/icon_history.png) | bin | 437 -> 437 bytes | |||
-rw-r--r-- | editor/icons/icon_hsize.png (renamed from tools/editor/icons/icon_hsize.png) | bin | 166 -> 166 bytes | |||
-rw-r--r-- | editor/icons/icon_iapi.png (renamed from tools/editor/icons/icon_iapi.png) | bin | 277 -> 277 bytes | |||
-rw-r--r-- | editor/icons/icon_image.png (renamed from tools/editor/icons/icon_image.png) | bin | 263 -> 263 bytes | |||
-rw-r--r-- | editor/icons/icon_image_sky_box.png (renamed from tools/editor/icons/icon_image_sky_box.png) | bin | 434 -> 434 bytes | |||
-rw-r--r-- | editor/icons/icon_image_texture.png (renamed from tools/editor/icons/icon_image_texture.png) | bin | 200 -> 200 bytes | |||
-rw-r--r-- | editor/icons/icon_immediate_geometry.png (renamed from tools/editor/icons/icon_immediate_geometry.png) | bin | 411 -> 411 bytes | |||
-rw-r--r-- | editor/icons/icon_import_check.png (renamed from tools/editor/icons/icon_import_check.png) | bin | 266 -> 266 bytes | |||
-rw-r--r-- | editor/icons/icon_import_fail.png (renamed from tools/editor/icons/icon_import_fail.png) | bin | 346 -> 346 bytes | |||
-rw-r--r-- | editor/icons/icon_influence_zone.png (renamed from tools/editor/icons/icon_influence_zone.png) | bin | 303 -> 303 bytes | |||
-rw-r--r-- | editor/icons/icon_instance.png (renamed from tools/editor/icons/icon_instance.png) | bin | 442 -> 442 bytes | |||
-rw-r--r-- | editor/icons/icon_instance_options.png (renamed from tools/editor/icons/icon_instance_options.png) | bin | 365 -> 365 bytes | |||
-rw-r--r-- | editor/icons/icon_integer.png (renamed from tools/editor/icons/icon_integer.png) | bin | 126 -> 126 bytes | |||
-rw-r--r-- | editor/icons/icon_interp_cubic.png (renamed from tools/editor/icons/icon_interp_cubic.png) | bin | 281 -> 281 bytes | |||
-rw-r--r-- | editor/icons/icon_interp_linear.png (renamed from tools/editor/icons/icon_interp_linear.png) | bin | 271 -> 271 bytes | |||
-rw-r--r-- | editor/icons/icon_interp_raw.png (renamed from tools/editor/icons/icon_interp_raw.png) | bin | 156 -> 156 bytes | |||
-rw-r--r-- | editor/icons/icon_interp_wrap_clamp.png (renamed from tools/editor/icons/icon_interp_wrap_clamp.png) | bin | 233 -> 233 bytes | |||
-rw-r--r-- | editor/icons/icon_interp_wrap_loop.png (renamed from tools/editor/icons/icon_interp_wrap_loop.png) | bin | 309 -> 309 bytes | |||
-rw-r--r-- | editor/icons/icon_interpolated_camera.png (renamed from tools/editor/icons/icon_interpolated_camera.png) | bin | 279 -> 279 bytes | |||
-rw-r--r-- | editor/icons/icon_invalid_key.png (renamed from tools/editor/icons/icon_invalid_key.png) | bin | 205 -> 205 bytes | |||
-rw-r--r-- | editor/icons/icon_inverse_kinematics.png (renamed from tools/editor/icons/icon_inverse_kinematics.png) | bin | 262 -> 262 bytes | |||
-rw-r--r-- | editor/icons/icon_item_list.png (renamed from tools/editor/icons/icon_item_list.png) | bin | 216 -> 216 bytes | |||
-rw-r--r-- | editor/icons/icon_joy_axis.png (renamed from tools/editor/icons/icon_joy_axis.png) | bin | 260 -> 260 bytes | |||
-rw-r--r-- | editor/icons/icon_joy_button.png (renamed from tools/editor/icons/icon_joy_button.png) | bin | 272 -> 272 bytes | |||
-rw-r--r-- | editor/icons/icon_joypad.png (renamed from tools/editor/icons/icon_joypad.png) | bin | 239 -> 239 bytes | |||
-rw-r--r-- | editor/icons/icon_key.png (renamed from tools/editor/icons/icon_key.png) | bin | 285 -> 285 bytes | |||
-rw-r--r-- | editor/icons/icon_key_call.png (renamed from tools/editor/icons/icon_key_call.png) | bin | 265 -> 265 bytes | |||
-rw-r--r-- | editor/icons/icon_key_hover.png (renamed from tools/editor/icons/icon_key_hover.png) | bin | 206 -> 206 bytes | |||
-rw-r--r-- | editor/icons/icon_key_invalid.png (renamed from tools/editor/icons/icon_key_invalid.png) | bin | 205 -> 205 bytes | |||
-rw-r--r-- | editor/icons/icon_key_invalid_hover.png (renamed from tools/editor/icons/icon_key_invalid_hover.png) | bin | 239 -> 239 bytes | |||
-rw-r--r-- | editor/icons/icon_key_next.png (renamed from tools/editor/icons/icon_key_next.png) | bin | 321 -> 321 bytes | |||
-rw-r--r-- | editor/icons/icon_key_selected.png (renamed from tools/editor/icons/icon_key_selected.png) | bin | 203 -> 203 bytes | |||
-rw-r--r-- | editor/icons/icon_key_value.png (renamed from tools/editor/icons/icon_key_value.png) | bin | 210 -> 210 bytes | |||
-rw-r--r-- | editor/icons/icon_key_xform.png (renamed from tools/editor/icons/icon_key_xform.png) | bin | 213 -> 213 bytes | |||
-rw-r--r-- | editor/icons/icon_keyboard.png (renamed from tools/editor/icons/icon_keyboard.png) | bin | 299 -> 299 bytes | |||
-rw-r--r-- | editor/icons/icon_keying.png (renamed from tools/editor/icons/icon_keying.png) | bin | 1603 -> 1603 bytes | |||
-rw-r--r-- | editor/icons/icon_kinematic_body.png (renamed from tools/editor/icons/icon_kinematic_body.png) | bin | 145 -> 145 bytes | |||
-rw-r--r-- | editor/icons/icon_kinematic_body_2d.png (renamed from tools/editor/icons/icon_kinematic_body_2d.png) | bin | 147 -> 147 bytes | |||
-rw-r--r-- | editor/icons/icon_label.png (renamed from tools/editor/icons/icon_label.png) | bin | 240 -> 240 bytes | |||
-rw-r--r-- | editor/icons/icon_large_texture.png (renamed from tools/editor/icons/icon_large_texture.png) | bin | 156 -> 156 bytes | |||
-rw-r--r-- | editor/icons/icon_light_2d.png (renamed from tools/editor/icons/icon_light_2d.png) | bin | 362 -> 362 bytes | |||
-rw-r--r-- | editor/icons/icon_light_map.png (renamed from tools/editor/icons/icon_light_map.png) | bin | 406 -> 406 bytes | |||
-rw-r--r-- | editor/icons/icon_light_occluder_2d.png (renamed from tools/editor/icons/icon_light_occluder_2d.png) | bin | 146 -> 146 bytes | |||
-rw-r--r-- | editor/icons/icon_lightr.png (renamed from tools/editor/icons/icon_lightr.png) | bin | 272 -> 272 bytes | |||
-rw-r--r-- | editor/icons/icon_line_2d.png (renamed from tools/editor/icons/icon_line_2d.png) | bin | 474 -> 474 bytes | |||
-rw-r--r-- | editor/icons/icon_line_edit.png (renamed from tools/editor/icons/icon_line_edit.png) | bin | 201 -> 201 bytes | |||
-rw-r--r-- | editor/icons/icon_line_shape_2d.png (renamed from tools/editor/icons/icon_line_shape_2d.png) | bin | 379 -> 379 bytes | |||
-rw-r--r-- | editor/icons/icon_link_button.png (renamed from tools/editor/icons/icon_link_button.png) | bin | 409 -> 409 bytes | |||
-rw-r--r-- | editor/icons/icon_list_select.png (renamed from tools/editor/icons/icon_list_select.png) | bin | 349 -> 349 bytes | |||
-rw-r--r-- | editor/icons/icon_listener.png (renamed from tools/editor/icons/icon_listener.png) | bin | 448 -> 448 bytes | |||
-rw-r--r-- | editor/icons/icon_live_debug.png (renamed from tools/editor/icons/icon_live_debug.png) | bin | 583 -> 583 bytes | |||
-rw-r--r-- | editor/icons/icon_load.png (renamed from tools/editor/icons/icon_load.png) | bin | 271 -> 271 bytes | |||
-rw-r--r-- | editor/icons/icon_lock.png (renamed from tools/editor/icons/icon_lock.png) | bin | 271 -> 271 bytes | |||
-rw-r--r-- | editor/icons/icon_logo.png (renamed from tools/editor/icons/icon_logo.png) | bin | 6211 -> 6211 bytes | |||
-rw-r--r-- | editor/icons/icon_logo_small.png (renamed from tools/editor/icons/icon_logo_small.png) | bin | 1825 -> 1825 bytes | |||
-rw-r--r-- | editor/icons/icon_loop.png (renamed from tools/editor/icons/icon_loop.png) | bin | 412 -> 412 bytes | |||
-rw-r--r-- | editor/icons/icon_loop_interpolation.png (renamed from tools/editor/icons/icon_loop_interpolation.png) | bin | 374 -> 374 bytes | |||
-rw-r--r-- | editor/icons/icon_main_play.png (renamed from tools/editor/icons/icon_main_play.png) | bin | 234 -> 234 bytes | |||
-rw-r--r-- | editor/icons/icon_main_stop.png (renamed from tools/editor/icons/icon_main_stop.png) | bin | 144 -> 144 bytes | |||
-rw-r--r-- | editor/icons/icon_margin_container.png (renamed from tools/editor/icons/icon_margin_container.png) | bin | 233 -> 233 bytes | |||
-rw-r--r-- | editor/icons/icon_material_preview_cube.png (renamed from tools/editor/icons/icon_material_preview_cube.png) | bin | 374 -> 374 bytes | |||
-rw-r--r-- | editor/icons/icon_material_preview_cube_off.png (renamed from tools/editor/icons/icon_material_preview_cube_off.png) | bin | 401 -> 401 bytes | |||
-rw-r--r-- | editor/icons/icon_material_preview_light_1.png (renamed from tools/editor/icons/icon_material_preview_light_1.png) | bin | 359 -> 359 bytes | |||
-rw-r--r-- | editor/icons/icon_material_preview_light_1_off.png (renamed from tools/editor/icons/icon_material_preview_light_1_off.png) | bin | 305 -> 305 bytes | |||
-rw-r--r-- | editor/icons/icon_material_preview_light_2.png (renamed from tools/editor/icons/icon_material_preview_light_2.png) | bin | 354 -> 354 bytes | |||
-rw-r--r-- | editor/icons/icon_material_preview_light_2_off.png (renamed from tools/editor/icons/icon_material_preview_light_2_off.png) | bin | 443 -> 443 bytes | |||
-rw-r--r-- | editor/icons/icon_material_preview_sphere.png (renamed from tools/editor/icons/icon_material_preview_sphere.png) | bin | 359 -> 359 bytes | |||
-rw-r--r-- | editor/icons/icon_material_preview_sphere_off.png (renamed from tools/editor/icons/icon_material_preview_sphere_off.png) | bin | 283 -> 283 bytes | |||
-rw-r--r-- | editor/icons/icon_material_shader.png (renamed from tools/editor/icons/icon_material_shader.png) | bin | 254 -> 254 bytes | |||
-rw-r--r-- | editor/icons/icon_material_shader_graph.png (renamed from tools/editor/icons/icon_material_shader_graph.png) | bin | 440 -> 440 bytes | |||
-rw-r--r-- | editor/icons/icon_matrix.png (renamed from tools/editor/icons/icon_matrix.png) | bin | 138 -> 138 bytes | |||
-rw-r--r-- | editor/icons/icon_menu_button.png (renamed from tools/editor/icons/icon_menu_button.png) | bin | 213 -> 213 bytes | |||
-rw-r--r-- | editor/icons/icon_mesh.png (renamed from tools/editor/icons/icon_mesh.png) | bin | 343 -> 343 bytes | |||
-rw-r--r-- | editor/icons/icon_mesh_instance.png (renamed from tools/editor/icons/icon_mesh_instance.png) | bin | 314 -> 314 bytes | |||
-rw-r--r-- | editor/icons/icon_mesh_library.png (renamed from tools/editor/icons/icon_mesh_library.png) | bin | 349 -> 349 bytes | |||
-rw-r--r-- | editor/icons/icon_mesh_old.png (renamed from tools/editor/icons/icon_mesh_old.png) | bin | 615 -> 615 bytes | |||
-rw-r--r-- | editor/icons/icon_meshr.png (renamed from tools/editor/icons/icon_meshr.png) | bin | 744 -> 744 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_aabb.png (renamed from tools/editor/icons/icon_mini_aabb.png) | bin | 360 -> 360 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_array.png (renamed from tools/editor/icons/icon_mini_array.png) | bin | 210 -> 210 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_boolean.png (renamed from tools/editor/icons/icon_mini_boolean.png) | bin | 256 -> 256 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_color.png (renamed from tools/editor/icons/icon_mini_color.png) | bin | 253 -> 253 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_color_array.png (renamed from tools/editor/icons/icon_mini_color_array.png) | bin | 337 -> 337 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_dictionary.png (renamed from tools/editor/icons/icon_mini_dictionary.png) | bin | 230 -> 230 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_float.png (renamed from tools/editor/icons/icon_mini_float.png) | bin | 233 -> 233 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_float_array.png (renamed from tools/editor/icons/icon_mini_float_array.png) | bin | 275 -> 275 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_image.png (renamed from tools/editor/icons/icon_mini_image.png) | bin | 257 -> 257 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_input.png (renamed from tools/editor/icons/icon_mini_input.png) | bin | 236 -> 236 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_int_array.png (renamed from tools/editor/icons/icon_mini_int_array.png) | bin | 262 -> 262 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_integer.png (renamed from tools/editor/icons/icon_mini_integer.png) | bin | 228 -> 228 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_matrix3.png (renamed from tools/editor/icons/icon_mini_matrix3.png) | bin | 236 -> 236 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_matrix32.png (renamed from tools/editor/icons/icon_mini_matrix32.png) | bin | 320 -> 320 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_object.png (renamed from tools/editor/icons/icon_mini_object.png) | bin | 289 -> 289 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_path.png (renamed from tools/editor/icons/icon_mini_path.png) | bin | 254 -> 254 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_plane.png (renamed from tools/editor/icons/icon_mini_plane.png) | bin | 249 -> 249 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_quat.png (renamed from tools/editor/icons/icon_mini_quat.png) | bin | 309 -> 309 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_raw_array.png (renamed from tools/editor/icons/icon_mini_raw_array.png) | bin | 248 -> 248 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_rect2.png (renamed from tools/editor/icons/icon_mini_rect2.png) | bin | 267 -> 267 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_rid.png (renamed from tools/editor/icons/icon_mini_rid.png) | bin | 222 -> 222 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_string.png (renamed from tools/editor/icons/icon_mini_string.png) | bin | 258 -> 258 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_string_array.png (renamed from tools/editor/icons/icon_mini_string_array.png) | bin | 296 -> 296 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_transform.png (renamed from tools/editor/icons/icon_mini_transform.png) | bin | 321 -> 321 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_variant.png (renamed from tools/editor/icons/icon_mini_variant.png) | bin | 240 -> 240 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_vector2.png (renamed from tools/editor/icons/icon_mini_vector2.png) | bin | 301 -> 301 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_vector2_array.png (renamed from tools/editor/icons/icon_mini_vector2_array.png) | bin | 284 -> 284 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_vector3.png (renamed from tools/editor/icons/icon_mini_vector3.png) | bin | 285 -> 285 bytes | |||
-rw-r--r-- | editor/icons/icon_mini_vector3_array.png (renamed from tools/editor/icons/icon_mini_vector3_array.png) | bin | 264 -> 264 bytes | |||
-rw-r--r-- | editor/icons/icon_mirror_x.png (renamed from tools/editor/icons/icon_mirror_x.png) | bin | 166 -> 166 bytes | |||
-rw-r--r-- | editor/icons/icon_mirror_y.png (renamed from tools/editor/icons/icon_mirror_y.png) | bin | 168 -> 168 bytes | |||
-rw-r--r-- | editor/icons/icon_mouse.png (renamed from tools/editor/icons/icon_mouse.png) | bin | 256 -> 256 bytes | |||
-rw-r--r-- | editor/icons/icon_move_down.png (renamed from tools/editor/icons/icon_move_down.png) | bin | 268 -> 268 bytes | |||
-rw-r--r-- | editor/icons/icon_move_down_hl.png (renamed from tools/editor/icons/icon_move_down_hl.png) | bin | 234 -> 234 bytes | |||
-rw-r--r-- | editor/icons/icon_move_point.png (renamed from tools/editor/icons/icon_move_point.png) | bin | 542 -> 542 bytes | |||
-rw-r--r-- | editor/icons/icon_move_up.png (renamed from tools/editor/icons/icon_move_up.png) | bin | 269 -> 269 bytes | |||
-rw-r--r-- | editor/icons/icon_move_up_hl.png (renamed from tools/editor/icons/icon_move_up_hl.png) | bin | 224 -> 224 bytes | |||
-rw-r--r-- | editor/icons/icon_multi_edit.png (renamed from tools/editor/icons/icon_multi_edit.png) | bin | 358 -> 358 bytes | |||
-rw-r--r-- | editor/icons/icon_multi_line.png (renamed from tools/editor/icons/icon_multi_line.png) | bin | 140 -> 140 bytes | |||
-rw-r--r-- | editor/icons/icon_multi_mesh.png (renamed from tools/editor/icons/icon_multi_mesh.png) | bin | 347 -> 347 bytes | |||
-rw-r--r-- | editor/icons/icon_multi_mesh_instance.png (renamed from tools/editor/icons/icon_multi_mesh_instance.png) | bin | 376 -> 376 bytes | |||
-rw-r--r-- | editor/icons/icon_multi_node_edit.png (renamed from tools/editor/icons/icon_multi_node_edit.png) | bin | 358 -> 358 bytes | |||
-rw-r--r-- | editor/icons/icon_navigation.png (renamed from tools/editor/icons/icon_navigation.png) | bin | 344 -> 344 bytes | |||
-rw-r--r-- | editor/icons/icon_navigation_2d.png (renamed from tools/editor/icons/icon_navigation_2d.png) | bin | 363 -> 363 bytes | |||
-rw-r--r-- | editor/icons/icon_navigation_mesh.png (renamed from tools/editor/icons/icon_navigation_mesh.png) | bin | 450 -> 450 bytes | |||
-rw-r--r-- | editor/icons/icon_navigation_mesh_instance.png (renamed from tools/editor/icons/icon_navigation_mesh_instance.png) | bin | 480 -> 480 bytes | |||
-rw-r--r-- | editor/icons/icon_navigation_polygon.png (renamed from tools/editor/icons/icon_navigation_polygon.png) | bin | 384 -> 384 bytes | |||
-rw-r--r-- | editor/icons/icon_navigation_polygon_instance.png (renamed from tools/editor/icons/icon_navigation_polygon_instance.png) | bin | 409 -> 409 bytes | |||
-rw-r--r-- | editor/icons/icon_new.png (renamed from tools/editor/icons/icon_new.png) | bin | 157 -> 157 bytes | |||
-rw-r--r-- | editor/icons/icon_nine_patch_rect.png (renamed from tools/editor/icons/icon_nine_patch_rect.png) | bin | 128 -> 128 bytes | |||
-rw-r--r-- | editor/icons/icon_node.png (renamed from tools/editor/icons/icon_node.png) | bin | 403 -> 403 bytes | |||
-rw-r--r-- | editor/icons/icon_node_2d.png (renamed from tools/editor/icons/icon_node_2d.png) | bin | 427 -> 427 bytes | |||
-rw-r--r-- | editor/icons/icon_node_real_slot.png (renamed from tools/editor/icons/icon_node_real_slot.png) | bin | 239 -> 239 bytes | |||
-rw-r--r-- | editor/icons/icon_node_vec_slot.png (renamed from tools/editor/icons/icon_node_vec_slot.png) | bin | 240 -> 240 bytes | |||
-rw-r--r-- | editor/icons/icon_node_warning.png (renamed from tools/editor/icons/icon_node_warning.png) | bin | 320 -> 320 bytes | |||
-rw-r--r-- | editor/icons/icon_non_favorite.png (renamed from tools/editor/icons/icon_non_favorite.png) | bin | 475 -> 475 bytes | |||
-rw-r--r-- | editor/icons/icon_object.png (renamed from tools/editor/icons/icon_object.png) | bin | 354 -> 354 bytes | |||
-rw-r--r-- | editor/icons/icon_occluder_polygon_2d.png (renamed from tools/editor/icons/icon_occluder_polygon_2d.png) | bin | 274 -> 274 bytes | |||
-rw-r--r-- | editor/icons/icon_omni_light.png (renamed from tools/editor/icons/icon_omni_light.png) | bin | 347 -> 347 bytes | |||
-rw-r--r-- | editor/icons/icon_open.png (renamed from tools/editor/icons/icon_open.png) | bin | 170 -> 170 bytes | |||
-rw-r--r-- | editor/icons/icon_option_button.png (renamed from tools/editor/icons/icon_option_button.png) | bin | 218 -> 218 bytes | |||
-rw-r--r-- | editor/icons/icon_override.png (renamed from tools/editor/icons/icon_override.png) | bin | 281 -> 281 bytes | |||
-rw-r--r-- | editor/icons/icon_p_hash_translation.png (renamed from tools/editor/icons/icon_p_hash_translation.png) | bin | 194 -> 194 bytes | |||
-rw-r--r-- | editor/icons/icon_packed_data_container.png (renamed from tools/editor/icons/icon_packed_data_container.png) | bin | 176 -> 176 bytes | |||
-rw-r--r-- | editor/icons/icon_packed_scene.png (renamed from tools/editor/icons/icon_packed_scene.png) | bin | 289 -> 289 bytes | |||
-rw-r--r-- | editor/icons/icon_pane_drag.png (renamed from tools/editor/icons/icon_pane_drag.png) | bin | 620 -> 620 bytes | |||
-rw-r--r-- | editor/icons/icon_pane_drag_hover.png (renamed from tools/editor/icons/icon_pane_drag_hover.png) | bin | 637 -> 637 bytes | |||
-rw-r--r-- | editor/icons/icon_panel.png (renamed from tools/editor/icons/icon_panel.png) | bin | 175 -> 175 bytes | |||
-rw-r--r-- | editor/icons/icon_panel_container.png (renamed from tools/editor/icons/icon_panel_container.png) | bin | 198 -> 198 bytes | |||
-rw-r--r-- | editor/icons/icon_panel_top.png (renamed from tools/editor/icons/icon_panel_top.png) | bin | 195 -> 195 bytes | |||
-rw-r--r-- | editor/icons/icon_panels_1.png (renamed from tools/editor/icons/icon_panels_1.png) | bin | 100 -> 100 bytes | |||
-rw-r--r-- | editor/icons/icon_panels_2.png (renamed from tools/editor/icons/icon_panels_2.png) | bin | 108 -> 108 bytes | |||
-rw-r--r-- | editor/icons/icon_panels_2_alt.png (renamed from tools/editor/icons/icon_panels_2_alt.png) | bin | 116 -> 116 bytes | |||
-rw-r--r-- | editor/icons/icon_panels_3.png (renamed from tools/editor/icons/icon_panels_3.png) | bin | 123 -> 123 bytes | |||
-rw-r--r-- | editor/icons/icon_panels_3_alt.png (renamed from tools/editor/icons/icon_panels_3_alt.png) | bin | 130 -> 130 bytes | |||
-rw-r--r-- | editor/icons/icon_panels_4.png (renamed from tools/editor/icons/icon_panels_4.png) | bin | 120 -> 120 bytes | |||
-rw-r--r-- | editor/icons/icon_parallax_background.png (renamed from tools/editor/icons/icon_parallax_background.png) | bin | 218 -> 218 bytes | |||
-rw-r--r-- | editor/icons/icon_parallax_layer.png (renamed from tools/editor/icons/icon_parallax_layer.png) | bin | 282 -> 282 bytes | |||
-rw-r--r-- | editor/icons/icon_particle_attractor_2d.png (renamed from tools/editor/icons/icon_particle_attractor_2d.png) | bin | 629 -> 629 bytes | |||
-rw-r--r-- | editor/icons/icon_particles.png (renamed from tools/editor/icons/icon_particles.png) | bin | 370 -> 370 bytes | |||
-rw-r--r-- | editor/icons/icon_particles_2d.png (renamed from tools/editor/icons/icon_particles_2d.png) | bin | 391 -> 391 bytes | |||
-rw-r--r-- | editor/icons/icon_particles_frame.png (renamed from tools/editor/icons/icon_particles_frame.png) | bin | 254 -> 254 bytes | |||
-rw-r--r-- | editor/icons/icon_particles_shader.png (renamed from tools/editor/icons/icon_particles_shader.png) | bin | 367 -> 367 bytes | |||
-rw-r--r-- | editor/icons/icon_patch_9_rect.png (renamed from tools/editor/icons/icon_patch_9_rect.png) | bin | 128 -> 128 bytes | |||
-rw-r--r-- | editor/icons/icon_path.png (renamed from tools/editor/icons/icon_path.png) | bin | 353 -> 353 bytes | |||
-rw-r--r-- | editor/icons/icon_path_2d.png (renamed from tools/editor/icons/icon_path_2d.png) | bin | 359 -> 359 bytes | |||
-rw-r--r-- | editor/icons/icon_path_follow.png (renamed from tools/editor/icons/icon_path_follow.png) | bin | 387 -> 387 bytes | |||
-rw-r--r-- | editor/icons/icon_path_follow_2d.png (renamed from tools/editor/icons/icon_path_follow_2d.png) | bin | 392 -> 392 bytes | |||
-rw-r--r-- | editor/icons/icon_pause.png (renamed from tools/editor/icons/icon_pause.png) | bin | 147 -> 147 bytes | |||
-rw-r--r-- | editor/icons/icon_pe_edit.png (renamed from tools/editor/icons/icon_pe_edit.png) | bin | 403 -> 403 bytes | |||
-rw-r--r-- | editor/icons/icon_physics_joint_pin.png (renamed from tools/editor/icons/icon_physics_joint_pin.png) | bin | 454 -> 454 bytes | |||
-rw-r--r-- | editor/icons/icon_pin.png (renamed from tools/editor/icons/icon_pin.png) | bin | 227 -> 227 bytes | |||
-rw-r--r-- | editor/icons/icon_pin_joint.png (renamed from tools/editor/icons/icon_pin_joint.png) | bin | 418 -> 418 bytes | |||
-rw-r--r-- | editor/icons/icon_pin_joint_2d.png (renamed from tools/editor/icons/icon_pin_joint_2d.png) | bin | 428 -> 428 bytes | |||
-rw-r--r-- | editor/icons/icon_pin_pressed.png (renamed from tools/editor/icons/icon_pin_pressed.png) | bin | 227 -> 227 bytes | |||
-rw-r--r-- | editor/icons/icon_plane.png (renamed from tools/editor/icons/icon_plane.png) | bin | 235 -> 235 bytes | |||
-rw-r--r-- | editor/icons/icon_plane_shape.png (renamed from tools/editor/icons/icon_plane_shape.png) | bin | 229 -> 229 bytes | |||
-rw-r--r-- | editor/icons/icon_play.png (renamed from tools/editor/icons/icon_play.png) | bin | 237 -> 237 bytes | |||
-rw-r--r-- | editor/icons/icon_play_backwards.png (renamed from tools/editor/icons/icon_play_backwards.png) | bin | 245 -> 245 bytes | |||
-rw-r--r-- | editor/icons/icon_play_custom.png (renamed from tools/editor/icons/icon_play_custom.png) | bin | 282 -> 282 bytes | |||
-rw-r--r-- | editor/icons/icon_play_scene.png (renamed from tools/editor/icons/icon_play_scene.png) | bin | 350 -> 350 bytes | |||
-rw-r--r-- | editor/icons/icon_play_start.png (renamed from tools/editor/icons/icon_play_start.png) | bin | 269 -> 269 bytes | |||
-rw-r--r-- | editor/icons/icon_play_start_backwards.png (renamed from tools/editor/icons/icon_play_start_backwards.png) | bin | 279 -> 279 bytes | |||
-rw-r--r-- | editor/icons/icon_polygon_2d.png (renamed from tools/editor/icons/icon_polygon_2d.png) | bin | 281 -> 281 bytes | |||
-rw-r--r-- | editor/icons/icon_polygon_path_finder.png (renamed from tools/editor/icons/icon_polygon_path_finder.png) | bin | 307 -> 307 bytes | |||
-rw-r--r-- | editor/icons/icon_popup.png (renamed from tools/editor/icons/icon_popup.png) | bin | 210 -> 210 bytes | |||
-rw-r--r-- | editor/icons/icon_popup_dialog.png (renamed from tools/editor/icons/icon_popup_dialog.png) | bin | 221 -> 221 bytes | |||
-rw-r--r-- | editor/icons/icon_popup_menu.png (renamed from tools/editor/icons/icon_popup_menu.png) | bin | 216 -> 216 bytes | |||
-rw-r--r-- | editor/icons/icon_popup_panel.png (renamed from tools/editor/icons/icon_popup_panel.png) | bin | 198 -> 198 bytes | |||
-rw-r--r-- | editor/icons/icon_portal.png (renamed from tools/editor/icons/icon_portal.png) | bin | 452 -> 452 bytes | |||
-rw-r--r-- | editor/icons/icon_position_2d.png (renamed from tools/editor/icons/icon_position_2d.png) | bin | 132 -> 132 bytes | |||
-rw-r--r-- | editor/icons/icon_position_3d.png (renamed from tools/editor/icons/icon_position_3d.png) | bin | 131 -> 131 bytes | |||
-rw-r--r-- | editor/icons/icon_prev_scene.png (renamed from tools/editor/icons/icon_prev_scene.png) | bin | 229 -> 229 bytes | |||
-rw-r--r-- | editor/icons/icon_progress_1.png (renamed from tools/editor/icons/icon_progress_1.png) | bin | 468 -> 468 bytes | |||
-rw-r--r-- | editor/icons/icon_progress_2.png (renamed from tools/editor/icons/icon_progress_2.png) | bin | 455 -> 455 bytes | |||
-rw-r--r-- | editor/icons/icon_progress_3.png (renamed from tools/editor/icons/icon_progress_3.png) | bin | 462 -> 462 bytes | |||
-rw-r--r-- | editor/icons/icon_progress_4.png (renamed from tools/editor/icons/icon_progress_4.png) | bin | 475 -> 475 bytes | |||
-rw-r--r-- | editor/icons/icon_progress_5.png (renamed from tools/editor/icons/icon_progress_5.png) | bin | 454 -> 454 bytes | |||
-rw-r--r-- | editor/icons/icon_progress_6.png (renamed from tools/editor/icons/icon_progress_6.png) | bin | 465 -> 465 bytes | |||
-rw-r--r-- | editor/icons/icon_progress_7.png (renamed from tools/editor/icons/icon_progress_7.png) | bin | 461 -> 461 bytes | |||
-rw-r--r-- | editor/icons/icon_progress_8.png (renamed from tools/editor/icons/icon_progress_8.png) | bin | 463 -> 463 bytes | |||
-rw-r--r-- | editor/icons/icon_progress_bar.png (renamed from tools/editor/icons/icon_progress_bar.png) | bin | 208 -> 208 bytes | |||
-rw-r--r-- | editor/icons/icon_property_editor.png (renamed from tools/editor/icons/icon_property_editor.png) | bin | 248 -> 248 bytes | |||
-rw-r--r-- | editor/icons/icon_proximity_group.png (renamed from tools/editor/icons/icon_proximity_group.png) | bin | 223 -> 223 bytes | |||
-rw-r--r-- | editor/icons/icon_quad.png (renamed from tools/editor/icons/icon_quad.png) | bin | 251 -> 251 bytes | |||
-rw-r--r-- | editor/icons/icon_quat.png (renamed from tools/editor/icons/icon_quat.png) | bin | 341 -> 341 bytes | |||
-rw-r--r-- | editor/icons/icon_range.png (renamed from tools/editor/icons/icon_range.png) | bin | 151 -> 151 bytes | |||
-rw-r--r-- | editor/icons/icon_rating_no_star.png (renamed from tools/editor/icons/icon_rating_no_star.png) | bin | 515 -> 515 bytes | |||
-rw-r--r-- | editor/icons/icon_rating_star.png (renamed from tools/editor/icons/icon_rating_star.png) | bin | 383 -> 383 bytes | |||
-rw-r--r-- | editor/icons/icon_ray_cast.png (renamed from tools/editor/icons/icon_ray_cast.png) | bin | 216 -> 216 bytes | |||
-rw-r--r-- | editor/icons/icon_ray_cast_2d.png (renamed from tools/editor/icons/icon_ray_cast_2d.png) | bin | 214 -> 214 bytes | |||
-rw-r--r-- | editor/icons/icon_ray_shape.png (renamed from tools/editor/icons/icon_ray_shape.png) | bin | 363 -> 363 bytes | |||
-rw-r--r-- | editor/icons/icon_ray_shape_2d.png (renamed from tools/editor/icons/icon_ray_shape_2d.png) | bin | 233 -> 233 bytes | |||
-rw-r--r-- | editor/icons/icon_rayito.png (renamed from tools/editor/icons/icon_rayito.png) | bin | 300 -> 300 bytes | |||
-rw-r--r-- | editor/icons/icon_real.png (renamed from tools/editor/icons/icon_real.png) | bin | 265 -> 265 bytes | |||
-rw-r--r-- | editor/icons/icon_rect2.png (renamed from tools/editor/icons/icon_rect2.png) | bin | 193 -> 193 bytes | |||
-rw-r--r-- | editor/icons/icon_rect3.png (renamed from tools/editor/icons/icon_rect3.png) | bin | 202 -> 202 bytes | |||
-rw-r--r-- | editor/icons/icon_rectangle_shape_2d.png (renamed from tools/editor/icons/icon_rectangle_shape_2d.png) | bin | 159 -> 159 bytes | |||
-rw-r--r-- | editor/icons/icon_reference_rect.png (renamed from tools/editor/icons/icon_reference_rect.png) | bin | 128 -> 128 bytes | |||
-rw-r--r-- | editor/icons/icon_reflection_probe.png (renamed from tools/editor/icons/icon_reflection_probe.png) | bin | 370 -> 370 bytes | |||
-rw-r--r-- | editor/icons/icon_region_edit.png (renamed from tools/editor/icons/icon_region_edit.png) | bin | 141 -> 141 bytes | |||
-rw-r--r-- | editor/icons/icon_reload.png (renamed from tools/editor/icons/icon_reload.png) | bin | 420 -> 420 bytes | |||
-rw-r--r-- | editor/icons/icon_reload_empty.png (renamed from tools/editor/icons/icon_reload_empty.png) | bin | 251 -> 251 bytes | |||
-rw-r--r-- | editor/icons/icon_reload_small.png (renamed from tools/editor/icons/icon_reload_small.png) | bin | 409 -> 409 bytes | |||
-rw-r--r-- | editor/icons/icon_remote.png (renamed from tools/editor/icons/icon_remote.png) | bin | 394 -> 394 bytes | |||
-rw-r--r-- | editor/icons/icon_remote_transform.png (renamed from tools/editor/icons/icon_remote_transform.png) | bin | 530 -> 530 bytes | |||
-rw-r--r-- | editor/icons/icon_remote_transform_2d.png (renamed from tools/editor/icons/icon_remote_transform_2d.png) | bin | 552 -> 552 bytes | |||
-rw-r--r-- | editor/icons/icon_remove.png (renamed from tools/editor/icons/icon_remove.png) | bin | 184 -> 184 bytes | |||
-rw-r--r-- | editor/icons/icon_remove_hl.png (renamed from tools/editor/icons/icon_remove_hl.png) | bin | 385 -> 385 bytes | |||
-rw-r--r-- | editor/icons/icon_remove_small.png (renamed from tools/editor/icons/icon_remove_small.png) | bin | 297 -> 297 bytes | |||
-rw-r--r-- | editor/icons/icon_rename.png (renamed from tools/editor/icons/icon_rename.png) | bin | 160 -> 160 bytes | |||
-rw-r--r-- | editor/icons/icon_reparent.png (renamed from tools/editor/icons/icon_reparent.png) | bin | 390 -> 390 bytes | |||
-rw-r--r-- | editor/icons/icon_replace.png (renamed from tools/editor/icons/icon_replace.png) | bin | 435 -> 435 bytes | |||
-rw-r--r-- | editor/icons/icon_resource_preloader.png (renamed from tools/editor/icons/icon_resource_preloader.png) | bin | 391 -> 391 bytes | |||
-rw-r--r-- | editor/icons/icon_rich_text_label.png (renamed from tools/editor/icons/icon_rich_text_label.png) | bin | 236 -> 236 bytes | |||
-rw-r--r-- | editor/icons/icon_rid.png (renamed from tools/editor/icons/icon_rid.png) | bin | 468 -> 468 bytes | |||
-rw-r--r-- | editor/icons/icon_rigid_body.png (renamed from tools/editor/icons/icon_rigid_body.png) | bin | 531 -> 531 bytes | |||
-rw-r--r-- | editor/icons/icon_rigid_body_2_d.png (renamed from tools/editor/icons/icon_rigid_body_2_d.png) | bin | 501 -> 501 bytes | |||
-rw-r--r-- | editor/icons/icon_rigid_body_2d.png (renamed from tools/editor/icons/icon_rigid_body_2d.png) | bin | 559 -> 559 bytes | |||
-rw-r--r-- | editor/icons/icon_room.png (renamed from tools/editor/icons/icon_room.png) | bin | 375 -> 375 bytes | |||
-rw-r--r-- | editor/icons/icon_room_bounds.png (renamed from tools/editor/icons/icon_room_bounds.png) | bin | 363 -> 363 bytes | |||
-rw-r--r-- | editor/icons/icon_room_instance.png (renamed from tools/editor/icons/icon_room_instance.png) | bin | 392 -> 392 bytes | |||
-rw-r--r-- | editor/icons/icon_rotate_0.png (renamed from tools/editor/icons/icon_rotate_0.png) | bin | 436 -> 436 bytes | |||
-rw-r--r-- | editor/icons/icon_rotate_180.png (renamed from tools/editor/icons/icon_rotate_180.png) | bin | 376 -> 376 bytes | |||
-rw-r--r-- | editor/icons/icon_rotate_270.png (renamed from tools/editor/icons/icon_rotate_270.png) | bin | 357 -> 357 bytes | |||
-rw-r--r-- | editor/icons/icon_rotate_90.png (renamed from tools/editor/icons/icon_rotate_90.png) | bin | 412 -> 412 bytes | |||
-rw-r--r-- | editor/icons/icon_run.png (renamed from tools/editor/icons/icon_run.png) | bin | 800 -> 800 bytes | |||
-rw-r--r-- | editor/icons/icon_s_s_a_o_f_x.png (renamed from tools/editor/icons/icon_s_s_a_o_f_x.png) | bin | 564 -> 564 bytes | |||
-rw-r--r-- | editor/icons/icon_sample.png (renamed from tools/editor/icons/icon_sample.png) | bin | 152 -> 152 bytes | |||
-rw-r--r-- | editor/icons/icon_sample_library.png (renamed from tools/editor/icons/icon_sample_library.png) | bin | 333 -> 333 bytes | |||
-rw-r--r-- | editor/icons/icon_sample_player.png (renamed from tools/editor/icons/icon_sample_player.png) | bin | 234 -> 234 bytes | |||
-rw-r--r-- | editor/icons/icon_sample_player_2d.png (renamed from tools/editor/icons/icon_sample_player_2d.png) | bin | 252 -> 252 bytes | |||
-rw-r--r-- | editor/icons/icon_save.png (renamed from tools/editor/icons/icon_save.png) | bin | 252 -> 252 bytes | |||
-rw-r--r-- | editor/icons/icon_scene.png (renamed from tools/editor/icons/icon_scene.png) | bin | 476 -> 476 bytes | |||
-rw-r--r-- | editor/icons/icon_scene_instance.png (renamed from tools/editor/icons/icon_scene_instance.png) | bin | 488 -> 488 bytes | |||
-rw-r--r-- | editor/icons/icon_scene_tree_editor.png (renamed from tools/editor/icons/icon_scene_tree_editor.png) | bin | 294 -> 294 bytes | |||
-rw-r--r-- | editor/icons/icon_script.png (renamed from tools/editor/icons/icon_script.png) | bin | 262 -> 262 bytes | |||
-rw-r--r-- | editor/icons/icon_script_control.png (renamed from tools/editor/icons/icon_script_control.png) | bin | 452 -> 452 bytes | |||
-rw-r--r-- | editor/icons/icon_script_create.png (renamed from tools/editor/icons/icon_script_create.png) | bin | 288 -> 288 bytes | |||
-rw-r--r-- | editor/icons/icon_script_error.png (renamed from tools/editor/icons/icon_script_error.png) | bin | 220 -> 220 bytes | |||
-rw-r--r-- | editor/icons/icon_script_list.png (renamed from tools/editor/icons/icon_script_list.png) | bin | 213 -> 213 bytes | |||
-rw-r--r-- | editor/icons/icon_script_node.png (renamed from tools/editor/icons/icon_script_node.png) | bin | 455 -> 455 bytes | |||
-rw-r--r-- | editor/icons/icon_script_remove.png (renamed from tools/editor/icons/icon_script_remove.png) | bin | 411 -> 411 bytes | |||
-rw-r--r-- | editor/icons/icon_scroll_bar.png (renamed from tools/editor/icons/icon_scroll_bar.png) | bin | 205 -> 205 bytes | |||
-rw-r--r-- | editor/icons/icon_scroll_container.png (renamed from tools/editor/icons/icon_scroll_container.png) | bin | 304 -> 304 bytes | |||
-rw-r--r-- | editor/icons/icon_segment_shape_2d.png (renamed from tools/editor/icons/icon_segment_shape_2d.png) | bin | 241 -> 241 bytes | |||
-rw-r--r-- | editor/icons/icon_shader.png (renamed from tools/editor/icons/icon_shader.png) | bin | 254 -> 254 bytes | |||
-rw-r--r-- | editor/icons/icon_shader_material.png (renamed from tools/editor/icons/icon_shader_material.png) | bin | 254 -> 254 bytes | |||
-rw-r--r-- | editor/icons/icon_short_cut.png (renamed from tools/editor/icons/icon_short_cut.png) | bin | 272 -> 272 bytes | |||
-rw-r--r-- | editor/icons/icon_signal.png (renamed from tools/editor/icons/icon_signal.png) | bin | 246 -> 246 bytes | |||
-rw-r--r-- | editor/icons/icon_skeleton.png (renamed from tools/editor/icons/icon_skeleton.png) | bin | 346 -> 346 bytes | |||
-rw-r--r-- | editor/icons/icon_skeletonr.png (renamed from tools/editor/icons/icon_skeletonr.png) | bin | 362 -> 362 bytes | |||
-rw-r--r-- | editor/icons/icon_sky_box_f_x.png (renamed from tools/editor/icons/icon_sky_box_f_x.png) | bin | 740 -> 740 bytes | |||
-rw-r--r-- | editor/icons/icon_slider_joint.png (renamed from tools/editor/icons/icon_slider_joint.png) | bin | 150 -> 150 bytes | |||
-rw-r--r-- | editor/icons/icon_slot.png (renamed from tools/editor/icons/icon_slot.png) | bin | 246 -> 246 bytes | |||
-rw-r--r-- | editor/icons/icon_small_next.png (renamed from tools/editor/icons/icon_small_next.png) | bin | 191 -> 191 bytes | |||
-rw-r--r-- | editor/icons/icon_snap.png (renamed from tools/editor/icons/icon_snap.png) | bin | 269 -> 269 bytes | |||
-rw-r--r-- | editor/icons/icon_sound_room_params.png (renamed from tools/editor/icons/icon_sound_room_params.png) | bin | 248 -> 248 bytes | |||
-rw-r--r-- | editor/icons/icon_spatial.png (renamed from tools/editor/icons/icon_spatial.png) | bin | 419 -> 419 bytes | |||
-rw-r--r-- | editor/icons/icon_spatial_add.png (renamed from tools/editor/icons/icon_spatial_add.png) | bin | 429 -> 429 bytes | |||
-rw-r--r-- | editor/icons/icon_spatial_sample_player.png (renamed from tools/editor/icons/icon_spatial_sample_player.png) | bin | 239 -> 239 bytes | |||
-rw-r--r-- | editor/icons/icon_spatial_shader.png (renamed from tools/editor/icons/icon_spatial_shader.png) | bin | 483 -> 483 bytes | |||
-rw-r--r-- | editor/icons/icon_spatial_stream_player.png (renamed from tools/editor/icons/icon_spatial_stream_player.png) | bin | 183 -> 183 bytes | |||
-rw-r--r-- | editor/icons/icon_sphere_shape.png (renamed from tools/editor/icons/icon_sphere_shape.png) | bin | 362 -> 362 bytes | |||
-rw-r--r-- | editor/icons/icon_spin_box.png (renamed from tools/editor/icons/icon_spin_box.png) | bin | 289 -> 289 bytes | |||
-rw-r--r-- | editor/icons/icon_spline.png (renamed from tools/editor/icons/icon_spline.png) | bin | 244 -> 244 bytes | |||
-rw-r--r-- | editor/icons/icon_spot_light.png (renamed from tools/editor/icons/icon_spot_light.png) | bin | 341 -> 341 bytes | |||
-rw-r--r-- | editor/icons/icon_sprite.png (renamed from tools/editor/icons/icon_sprite.png) | bin | 419 -> 419 bytes | |||
-rw-r--r-- | editor/icons/icon_sprite_3d.png (renamed from tools/editor/icons/icon_sprite_3d.png) | bin | 408 -> 408 bytes | |||
-rw-r--r-- | editor/icons/icon_sprite_frames.png (renamed from tools/editor/icons/icon_sprite_frames.png) | bin | 332 -> 332 bytes | |||
-rw-r--r-- | editor/icons/icon_squirrel_script.png (renamed from tools/editor/icons/icon_squirrel_script.png) | bin | 283 -> 283 bytes | |||
-rw-r--r-- | editor/icons/icon_static_body.png (renamed from tools/editor/icons/icon_static_body.png) | bin | 229 -> 229 bytes | |||
-rw-r--r-- | editor/icons/icon_static_body_2_d.png (renamed from tools/editor/icons/icon_static_body_2_d.png) | bin | 368 -> 368 bytes | |||
-rw-r--r-- | editor/icons/icon_static_body_2d.png (renamed from tools/editor/icons/icon_static_body_2d.png) | bin | 237 -> 237 bytes | |||
-rw-r--r-- | editor/icons/icon_stop.png (renamed from tools/editor/icons/icon_stop.png) | bin | 236 -> 236 bytes | |||
-rw-r--r-- | editor/icons/icon_stream_player.png (renamed from tools/editor/icons/icon_stream_player.png) | bin | 183 -> 183 bytes | |||
-rw-r--r-- | editor/icons/icon_string.png (renamed from tools/editor/icons/icon_string.png) | bin | 160 -> 160 bytes | |||
-rw-r--r-- | editor/icons/icon_style_box_empty.png (renamed from tools/editor/icons/icon_style_box_empty.png) | bin | 333 -> 333 bytes | |||
-rw-r--r-- | editor/icons/icon_style_box_flat.png (renamed from tools/editor/icons/icon_style_box_flat.png) | bin | 398 -> 398 bytes | |||
-rw-r--r-- | editor/icons/icon_style_box_texture.png (renamed from tools/editor/icons/icon_style_box_texture.png) | bin | 411 -> 411 bytes | |||
-rw-r--r-- | editor/icons/icon_surface.png (renamed from tools/editor/icons/icon_surface.png) | bin | 212 -> 212 bytes | |||
-rw-r--r-- | editor/icons/icon_tab_container.png (renamed from tools/editor/icons/icon_tab_container.png) | bin | 214 -> 214 bytes | |||
-rw-r--r-- | editor/icons/icon_tab_menu.png (renamed from tools/editor/icons/icon_tab_menu.png) | bin | 251 -> 251 bytes | |||
-rw-r--r-- | editor/icons/icon_tabs.png (renamed from tools/editor/icons/icon_tabs.png) | bin | 146 -> 146 bytes | |||
-rw-r--r-- | editor/icons/icon_test_cube.png (renamed from tools/editor/icons/icon_test_cube.png) | bin | 435 -> 435 bytes | |||
-rw-r--r-- | editor/icons/icon_text_edit.png (renamed from tools/editor/icons/icon_text_edit.png) | bin | 207 -> 207 bytes | |||
-rw-r--r-- | editor/icons/icon_texture.png (renamed from tools/editor/icons/icon_texture.png) | bin | 200 -> 200 bytes | |||
-rw-r--r-- | editor/icons/icon_texture_button.png (renamed from tools/editor/icons/icon_texture_button.png) | bin | 159 -> 159 bytes | |||
-rw-r--r-- | editor/icons/icon_texture_progress.png (renamed from tools/editor/icons/icon_texture_progress.png) | bin | 213 -> 213 bytes | |||
-rw-r--r-- | editor/icons/icon_texture_rect.png (renamed from tools/editor/icons/icon_texture_rect.png) | bin | 158 -> 158 bytes | |||
-rw-r--r-- | editor/icons/icon_theme.png (renamed from tools/editor/icons/icon_theme.png) | bin | 451 -> 451 bytes | |||
-rw-r--r-- | editor/icons/icon_thumbnail_wait.png (renamed from tools/editor/icons/icon_thumbnail_wait.png) | bin | 2616 -> 2616 bytes | |||
-rw-r--r-- | editor/icons/icon_tile_map.png (renamed from tools/editor/icons/icon_tile_map.png) | bin | 113 -> 113 bytes | |||
-rw-r--r-- | editor/icons/icon_tile_set.png (renamed from tools/editor/icons/icon_tile_set.png) | bin | 174 -> 174 bytes | |||
-rw-r--r-- | editor/icons/icon_time.png (renamed from tools/editor/icons/icon_time.png) | bin | 557 -> 557 bytes | |||
-rw-r--r-- | editor/icons/icon_timer.png (renamed from tools/editor/icons/icon_timer.png) | bin | 447 -> 447 bytes | |||
-rw-r--r-- | editor/icons/icon_tool_button.png (renamed from tools/editor/icons/icon_tool_button.png) | bin | 263 -> 263 bytes | |||
-rw-r--r-- | editor/icons/icon_tool_move.png (renamed from tools/editor/icons/icon_tool_move.png) | bin | 217 -> 217 bytes | |||
-rw-r--r-- | editor/icons/icon_tool_pan.png (renamed from tools/editor/icons/icon_tool_pan.png) | bin | 281 -> 281 bytes | |||
-rw-r--r-- | editor/icons/icon_tool_rotate.png (renamed from tools/editor/icons/icon_tool_rotate.png) | bin | 420 -> 420 bytes | |||
-rw-r--r-- | editor/icons/icon_tool_scale.png (renamed from tools/editor/icons/icon_tool_scale.png) | bin | 349 -> 349 bytes | |||
-rw-r--r-- | editor/icons/icon_tool_select.png (renamed from tools/editor/icons/icon_tool_select.png) | bin | 376 -> 376 bytes | |||
-rw-r--r-- | editor/icons/icon_tools.png (renamed from tools/editor/icons/icon_tools.png) | bin | 392 -> 392 bytes | |||
-rw-r--r-- | editor/icons/icon_touch_screen_button.png (renamed from tools/editor/icons/icon_touch_screen_button.png) | bin | 313 -> 313 bytes | |||
-rw-r--r-- | editor/icons/icon_track_add_key.png (renamed from tools/editor/icons/icon_track_add_key.png) | bin | 113 -> 113 bytes | |||
-rw-r--r-- | editor/icons/icon_track_add_key_hl.png (renamed from tools/editor/icons/icon_track_add_key_hl.png) | bin | 113 -> 113 bytes | |||
-rw-r--r-- | editor/icons/icon_track_continuous.png (renamed from tools/editor/icons/icon_track_continuous.png) | bin | 265 -> 265 bytes | |||
-rw-r--r-- | editor/icons/icon_track_discrete.png (renamed from tools/editor/icons/icon_track_discrete.png) | bin | 125 -> 125 bytes | |||
-rw-r--r-- | editor/icons/icon_track_method.png (renamed from tools/editor/icons/icon_track_method.png) | bin | 283 -> 283 bytes | |||
-rw-r--r-- | editor/icons/icon_track_prop.png (renamed from tools/editor/icons/icon_track_prop.png) | bin | 285 -> 285 bytes | |||
-rw-r--r-- | editor/icons/icon_track_trigger.png (renamed from tools/editor/icons/icon_track_trigger.png) | bin | 158 -> 158 bytes | |||
-rw-r--r-- | editor/icons/icon_track_value.png (renamed from tools/editor/icons/icon_track_value.png) | bin | 300 -> 300 bytes | |||
-rw-r--r-- | editor/icons/icon_translation.png (renamed from tools/editor/icons/icon_translation.png) | bin | 194 -> 194 bytes | |||
-rw-r--r-- | editor/icons/icon_transparent.png (renamed from tools/editor/icons/icon_transparent.png) | bin | 158 -> 158 bytes | |||
-rw-r--r-- | editor/icons/icon_transpose.png (renamed from tools/editor/icons/icon_transpose.png) | bin | 165 -> 165 bytes | |||
-rw-r--r-- | editor/icons/icon_tree.png (renamed from tools/editor/icons/icon_tree.png) | bin | 243 -> 243 bytes | |||
-rw-r--r-- | editor/icons/icon_tween.png (renamed from tools/editor/icons/icon_tween.png) | bin | 248 -> 248 bytes | |||
-rw-r--r-- | editor/icons/icon_unbone.png (renamed from tools/editor/icons/icon_unbone.png) | bin | 383 -> 383 bytes | |||
-rw-r--r-- | editor/icons/icon_ungroup.png (renamed from tools/editor/icons/icon_ungroup.png) | bin | 170 -> 170 bytes | |||
-rw-r--r-- | editor/icons/icon_uninstance.png (renamed from tools/editor/icons/icon_uninstance.png) | bin | 525 -> 525 bytes | |||
-rw-r--r-- | editor/icons/icon_unlock.png (renamed from tools/editor/icons/icon_unlock.png) | bin | 262 -> 262 bytes | |||
-rw-r--r-- | editor/icons/icon_up.png (renamed from tools/editor/icons/icon_up.png) | bin | 185 -> 185 bytes | |||
-rw-r--r-- | editor/icons/icon_updown.png (renamed from tools/editor/icons/icon_updown.png) | bin | 180 -> 180 bytes | |||
-rw-r--r-- | editor/icons/icon_uv.png (renamed from tools/editor/icons/icon_uv.png) | bin | 282 -> 282 bytes | |||
-rw-r--r-- | editor/icons/icon_v_box_container.png (renamed from tools/editor/icons/icon_v_box_container.png) | bin | 207 -> 207 bytes | |||
-rw-r--r-- | editor/icons/icon_v_button_array.png (renamed from tools/editor/icons/icon_v_button_array.png) | bin | 147 -> 147 bytes | |||
-rw-r--r-- | editor/icons/icon_v_scroll_bar.png (renamed from tools/editor/icons/icon_v_scroll_bar.png) | bin | 218 -> 218 bytes | |||
-rw-r--r-- | editor/icons/icon_v_separator.png (renamed from tools/editor/icons/icon_v_separator.png) | bin | 130 -> 130 bytes | |||
-rw-r--r-- | editor/icons/icon_v_slider.png (renamed from tools/editor/icons/icon_v_slider.png) | bin | 231 -> 231 bytes | |||
-rw-r--r-- | editor/icons/icon_v_split_container.png (renamed from tools/editor/icons/icon_v_split_container.png) | bin | 277 -> 277 bytes | |||
-rw-r--r-- | editor/icons/icon_variant.png (renamed from tools/editor/icons/icon_variant.png) | bin | 240 -> 240 bytes | |||
-rw-r--r-- | editor/icons/icon_vector.png (renamed from tools/editor/icons/icon_vector.png) | bin | 208 -> 208 bytes | |||
-rw-r--r-- | editor/icons/icon_vector2.png (renamed from tools/editor/icons/icon_vector2.png) | bin | 122 -> 122 bytes | |||
-rw-r--r-- | editor/icons/icon_vehicle_body.png (renamed from tools/editor/icons/icon_vehicle_body.png) | bin | 236 -> 236 bytes | |||
-rw-r--r-- | editor/icons/icon_vehicle_wheel.png (renamed from tools/editor/icons/icon_vehicle_wheel.png) | bin | 537 -> 537 bytes | |||
-rw-r--r-- | editor/icons/icon_video_player.png (renamed from tools/editor/icons/icon_video_player.png) | bin | 302 -> 302 bytes | |||
-rw-r--r-- | editor/icons/icon_video_stream_theora.png (renamed from tools/editor/icons/icon_video_stream_theora.png) | bin | 925 -> 925 bytes | |||
-rw-r--r-- | editor/icons/icon_view.png (renamed from tools/editor/icons/icon_view.png) | bin | 386 -> 386 bytes | |||
-rw-r--r-- | editor/icons/icon_viewport.png (renamed from tools/editor/icons/icon_viewport.png) | bin | 198 -> 198 bytes | |||
-rw-r--r-- | editor/icons/icon_viewport_container.png (renamed from tools/editor/icons/icon_viewport_container.png) | bin | 284 -> 284 bytes | |||
-rw-r--r-- | editor/icons/icon_viewport_sprite.png (renamed from tools/editor/icons/icon_viewport_sprite.png) | bin | 239 -> 239 bytes | |||
-rw-r--r-- | editor/icons/icon_viewport_texture.png (renamed from tools/editor/icons/icon_viewport_texture.png) | bin | 227 -> 227 bytes | |||
-rw-r--r-- | editor/icons/icon_visibility_area.png (renamed from tools/editor/icons/icon_visibility_area.png) | bin | 422 -> 422 bytes | |||
-rw-r--r-- | editor/icons/icon_visibility_enabler.png (renamed from tools/editor/icons/icon_visibility_enabler.png) | bin | 549 -> 549 bytes | |||
-rw-r--r-- | editor/icons/icon_visibility_enabler_2d.png (renamed from tools/editor/icons/icon_visibility_enabler_2d.png) | bin | 550 -> 550 bytes | |||
-rw-r--r-- | editor/icons/icon_visibility_notifier.png (renamed from tools/editor/icons/icon_visibility_notifier.png) | bin | 427 -> 427 bytes | |||
-rw-r--r-- | editor/icons/icon_visibility_notifier_2d.png (renamed from tools/editor/icons/icon_visibility_notifier_2d.png) | bin | 431 -> 431 bytes | |||
-rw-r--r-- | editor/icons/icon_visible.png (renamed from tools/editor/icons/icon_visible.png) | bin | 497 -> 497 bytes | |||
-rw-r--r-- | editor/icons/icon_visual_script.png (renamed from tools/editor/icons/icon_visual_script.png) | bin | 388 -> 388 bytes | |||
-rw-r--r-- | editor/icons/icon_visual_shader_port.png (renamed from tools/editor/icons/icon_visual_shader_port.png) | bin | 255 -> 255 bytes | |||
-rw-r--r-- | editor/icons/icon_volume.png (renamed from tools/editor/icons/icon_volume.png) | bin | 295 -> 295 bytes | |||
-rw-r--r-- | editor/icons/icon_vu_db.png (renamed from tools/editor/icons/icon_vu_db.png) | bin | 1015 -> 1015 bytes | |||
-rw-r--r-- | editor/icons/icon_vu_empty.png (renamed from tools/editor/icons/icon_vu_empty.png) | bin | 283 -> 283 bytes | |||
-rw-r--r-- | editor/icons/icon_vu_full.png (renamed from tools/editor/icons/icon_vu_full.png) | bin | 224 -> 224 bytes | |||
-rw-r--r-- | editor/icons/icon_wait_no_preview.png (renamed from tools/editor/icons/icon_wait_no_preview.png) | bin | 1041 -> 1041 bytes | |||
-rw-r--r-- | editor/icons/icon_wait_preview_1.png (renamed from tools/editor/icons/icon_wait_preview_1.png) | bin | 1208 -> 1208 bytes | |||
-rw-r--r-- | editor/icons/icon_wait_preview_2.png (renamed from tools/editor/icons/icon_wait_preview_2.png) | bin | 1270 -> 1270 bytes | |||
-rw-r--r-- | editor/icons/icon_wait_preview_3.png (renamed from tools/editor/icons/icon_wait_preview_3.png) | bin | 1190 -> 1190 bytes | |||
-rw-r--r-- | editor/icons/icon_wait_preview_4.png (renamed from tools/editor/icons/icon_wait_preview_4.png) | bin | 1269 -> 1269 bytes | |||
-rw-r--r-- | editor/icons/icon_wait_preview_5.png (renamed from tools/editor/icons/icon_wait_preview_5.png) | bin | 1191 -> 1191 bytes | |||
-rw-r--r-- | editor/icons/icon_wait_preview_6.png (renamed from tools/editor/icons/icon_wait_preview_6.png) | bin | 1278 -> 1278 bytes | |||
-rw-r--r-- | editor/icons/icon_wait_preview_7.png (renamed from tools/editor/icons/icon_wait_preview_7.png) | bin | 1192 -> 1192 bytes | |||
-rw-r--r-- | editor/icons/icon_wait_preview_8.png (renamed from tools/editor/icons/icon_wait_preview_8.png) | bin | 1341 -> 1341 bytes | |||
-rw-r--r-- | editor/icons/icon_warning.png (renamed from tools/editor/icons/icon_warning.png) | bin | 120 -> 120 bytes | |||
-rw-r--r-- | editor/icons/icon_window_dialog.png (renamed from tools/editor/icons/icon_window_dialog.png) | bin | 200 -> 200 bytes | |||
-rw-r--r-- | editor/icons/icon_world.png (renamed from tools/editor/icons/icon_world.png) | bin | 254 -> 254 bytes | |||
-rw-r--r-- | editor/icons/icon_world_2d.png (renamed from tools/editor/icons/icon_world_2d.png) | bin | 328 -> 328 bytes | |||
-rw-r--r-- | editor/icons/icon_world_environment.png (renamed from tools/editor/icons/icon_world_environment.png) | bin | 578 -> 578 bytes | |||
-rw-r--r-- | editor/icons/icon_y_sort.png (renamed from tools/editor/icons/icon_y_sort.png) | bin | 230 -> 230 bytes | |||
-rw-r--r-- | editor/icons/icon_zoom.png (renamed from tools/editor/icons/icon_zoom.png) | bin | 404 -> 404 bytes | |||
-rw-r--r-- | editor/icons/icon_zoom_less.png (renamed from tools/editor/icons/icon_zoom_less.png) | bin | 149 -> 149 bytes | |||
-rw-r--r-- | editor/icons/icon_zoom_more.png (renamed from tools/editor/icons/icon_zoom_more.png) | bin | 232 -> 232 bytes | |||
-rw-r--r-- | editor/icons/icon_zoom_reset.png (renamed from tools/editor/icons/icon_zoom_reset.png) | bin | 430 -> 430 bytes | |||
-rw-r--r-- | editor/icons/source/icon_accept_dialog.svg (renamed from tools/editor/icons/source/icon_accept_dialog.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_add_track.svg (renamed from tools/editor/icons/source/icon_add_track.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_anchor.svg (renamed from tools/editor/icons/source/icon_anchor.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_animated_sprite.svg (renamed from tools/editor/icons/source/icon_animated_sprite.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_animated_sprite_3d.svg (renamed from tools/editor/icons/source/icon_animated_sprite_3d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_animation.svg (renamed from tools/editor/icons/source/icon_animation.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_animation_player.svg (renamed from tools/editor/icons/source/icon_animation_player.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_animation_tree_player.svg (renamed from tools/editor/icons/source/icon_animation_tree_player.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_area.svg (renamed from tools/editor/icons/source/icon_area.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_area_2d.svg (renamed from tools/editor/icons/source/icon_area_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_arrow_left.svg (renamed from tools/editor/icons/source/icon_arrow_left.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_arrow_right.svg (renamed from tools/editor/icons/source/icon_arrow_right.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_arrow_up.svg (renamed from tools/editor/icons/source/icon_arrow_up.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_atlas_texture.svg (renamed from tools/editor/icons/source/icon_atlas_texture.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_audio_stream_gibberish.svg (renamed from tools/editor/icons/source/icon_audio_stream_gibberish.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_auto_play.svg (renamed from tools/editor/icons/source/icon_auto_play.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_back.svg (renamed from tools/editor/icons/source/icon_back.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_back_buffer_copy.svg (renamed from tools/editor/icons/source/icon_back_buffer_copy.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_bake.svg (renamed from tools/editor/icons/source/icon_bake.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_baked_light.svg (renamed from tools/editor/icons/source/icon_baked_light.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_baked_light_instance.svg (renamed from tools/editor/icons/source/icon_baked_light_instance.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_baked_light_sampler.svg (renamed from tools/editor/icons/source/icon_baked_light_sampler.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_bit_map.svg (renamed from tools/editor/icons/source/icon_bit_map.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_bitmap_font.svg (renamed from tools/editor/icons/source/icon_bitmap_font.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_blend.svg (renamed from tools/editor/icons/source/icon_blend.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_bone.svg (renamed from tools/editor/icons/source/icon_bone.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_bone_attachment.svg (renamed from tools/editor/icons/source/icon_bone_attachment.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_bone_track.svg (renamed from tools/editor/icons/source/icon_bone_track.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_bool.svg (renamed from tools/editor/icons/source/icon_bool.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_box_shape.svg (renamed from tools/editor/icons/source/icon_box_shape.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_button.svg (renamed from tools/editor/icons/source/icon_button.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_button_group.svg (renamed from tools/editor/icons/source/icon_button_group.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_camera.svg (renamed from tools/editor/icons/source/icon_camera.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_camera_2d.svg (renamed from tools/editor/icons/source/icon_camera_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_canvas_item.svg (renamed from tools/editor/icons/source/icon_canvas_item.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_canvas_item_material.svg (renamed from tools/editor/icons/source/icon_canvas_item_material.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_canvas_item_shader.svg (renamed from tools/editor/icons/source/icon_canvas_item_shader.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_canvas_item_shader_graph.svg (renamed from tools/editor/icons/source/icon_canvas_item_shader_graph.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_canvas_layer.svg (renamed from tools/editor/icons/source/icon_canvas_layer.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_canvas_modulate.svg (renamed from tools/editor/icons/source/icon_canvas_modulate.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_capsule_shape.svg (renamed from tools/editor/icons/source/icon_capsule_shape.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_capsule_shape_2d.svg (renamed from tools/editor/icons/source/icon_capsule_shape_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_center_container.svg (renamed from tools/editor/icons/source/icon_center_container.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_check_box.svg (renamed from tools/editor/icons/source/icon_check_box.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_check_button.svg (renamed from tools/editor/icons/source/icon_check_button.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_circle_shape_2d.svg (renamed from tools/editor/icons/source/icon_circle_shape_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_class_list.svg (renamed from tools/editor/icons/source/icon_class_list.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_close.svg (renamed from tools/editor/icons/source/icon_close.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_collapse.svg (renamed from tools/editor/icons/source/icon_collapse.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_collision_2d.svg (renamed from tools/editor/icons/source/icon_collision_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_collision_polygon.svg (renamed from tools/editor/icons/source/icon_collision_polygon.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_collision_shape.svg (renamed from tools/editor/icons/source/icon_collision_shape.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_collision_shape_2d.svg (renamed from tools/editor/icons/source/icon_collision_shape_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_color.svg (renamed from tools/editor/icons/source/icon_color.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_color_pick.svg (renamed from tools/editor/icons/source/icon_color_pick.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_color_picker.svg (renamed from tools/editor/icons/source/icon_color_picker.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_color_picker_button.svg (renamed from tools/editor/icons/source/icon_color_picker_button.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_color_ramp.svg (renamed from tools/editor/icons/source/icon_color_ramp.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_color_rect.svg (renamed from tools/editor/icons/source/icon_color_rect.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_concave_polygon_shape.svg (renamed from tools/editor/icons/source/icon_concave_polygon_shape.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_concave_polygon_shape_2d.svg (renamed from tools/editor/icons/source/icon_concave_polygon_shape_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_cone_twist_joint.svg (renamed from tools/editor/icons/source/icon_cone_twist_joint.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_confirmation_dialog.svg (renamed from tools/editor/icons/source/icon_confirmation_dialog.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_connect.svg (renamed from tools/editor/icons/source/icon_connect.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_connection_and_groups.svg (renamed from tools/editor/icons/source/icon_connection_and_groups.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_container.svg (renamed from tools/editor/icons/source/icon_container.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control.svg (renamed from tools/editor/icons/source/icon_control.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_bottom_center.svg (renamed from tools/editor/icons/source/icon_control_align_bottom_center.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_bottom_left.svg (renamed from tools/editor/icons/source/icon_control_align_bottom_left.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_bottom_right.svg (renamed from tools/editor/icons/source/icon_control_align_bottom_right.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_bottom_wide.svg (renamed from tools/editor/icons/source/icon_control_align_bottom_wide.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_center.svg (renamed from tools/editor/icons/source/icon_control_align_center.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_center_left.svg (renamed from tools/editor/icons/source/icon_control_align_center_left.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_center_right.svg (renamed from tools/editor/icons/source/icon_control_align_center_right.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_left_center.svg (renamed from tools/editor/icons/source/icon_control_align_left_center.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_left_wide.svg (renamed from tools/editor/icons/source/icon_control_align_left_wide.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_right_center.svg (renamed from tools/editor/icons/source/icon_control_align_right_center.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_right_wide.svg (renamed from tools/editor/icons/source/icon_control_align_right_wide.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_top_center.svg (renamed from tools/editor/icons/source/icon_control_align_top_center.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_top_left.svg (renamed from tools/editor/icons/source/icon_control_align_top_left.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_top_right.svg (renamed from tools/editor/icons/source/icon_control_align_top_right.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_top_wide.svg (renamed from tools/editor/icons/source/icon_control_align_top_wide.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_align_wide.svg (renamed from tools/editor/icons/source/icon_control_align_wide.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_hcenter_wide.svg (renamed from tools/editor/icons/source/icon_control_hcenter_wide.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_control_vcenter_wide.svg (renamed from tools/editor/icons/source/icon_control_vcenter_wide.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_convex_polygon_shape.svg (renamed from tools/editor/icons/source/icon_convex_polygon_shape.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_convex_polygon_shape_2d.svg (renamed from tools/editor/icons/source/icon_convex_polygon_shape_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_copy_node_path.svg (renamed from tools/editor/icons/source/icon_copy_node_path.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_create_new_scene_from.svg (renamed from tools/editor/icons/source/icon_create_new_scene_from.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_cube_map.svg (renamed from tools/editor/icons/source/icon_cube_map.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_curve_2d.svg (renamed from tools/editor/icons/source/icon_curve_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_curve_3d.svg (renamed from tools/editor/icons/source/icon_curve_3d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_curve_close.svg (renamed from tools/editor/icons/source/icon_curve_close.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_curve_constant.svg (renamed from tools/editor/icons/source/icon_curve_constant.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_curve_create.svg (renamed from tools/editor/icons/source/icon_curve_create.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_curve_curve.svg (renamed from tools/editor/icons/source/icon_curve_curve.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_curve_delete.svg (renamed from tools/editor/icons/source/icon_curve_delete.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_curve_edit.svg (renamed from tools/editor/icons/source/icon_curve_edit.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_curve_in.svg (renamed from tools/editor/icons/source/icon_curve_in.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_curve_in_out.svg (renamed from tools/editor/icons/source/icon_curve_in_out.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_curve_linear.svg (renamed from tools/editor/icons/source/icon_curve_linear.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_curve_out.svg (renamed from tools/editor/icons/source/icon_curve_out.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_curve_out_in.svg (renamed from tools/editor/icons/source/icon_curve_out_in.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_damped_spring_joint_2d.svg (renamed from tools/editor/icons/source/icon_damped_spring_joint_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_debug_continue.svg (renamed from tools/editor/icons/source/icon_debug_continue.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_debug_next.svg (renamed from tools/editor/icons/source/icon_debug_next.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_debug_step.svg (renamed from tools/editor/icons/source/icon_debug_step.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_dependency_changed.svg (renamed from tools/editor/icons/source/icon_dependency_changed.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_dependency_changed_hl.svg (renamed from tools/editor/icons/source/icon_dependency_changed_hl.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_dependency_local_changed.svg (renamed from tools/editor/icons/source/icon_dependency_local_changed.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_dependency_local_changed_hl.svg (renamed from tools/editor/icons/source/icon_dependency_local_changed_hl.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_dependency_ok.svg (renamed from tools/editor/icons/source/icon_dependency_ok.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_dependency_ok_hl.svg (renamed from tools/editor/icons/source/icon_dependency_ok_hl.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_directional_light.svg (renamed from tools/editor/icons/source/icon_directional_light.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_distraction_free.svg (renamed from tools/editor/icons/source/icon_distraction_free.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_duplicate.svg (renamed from tools/editor/icons/source/icon_duplicate.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_dynamic_font.svg (renamed from tools/editor/icons/source/icon_dynamic_font.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_dynamic_font_data.svg (renamed from tools/editor/icons/source/icon_dynamic_font_data.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_edit.svg (renamed from tools/editor/icons/source/icon_edit.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_edit_key.svg (renamed from tools/editor/icons/source/icon_edit_key.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_edit_pivot.svg (renamed from tools/editor/icons/source/icon_edit_pivot.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_edit_resource.svg (renamed from tools/editor/icons/source/icon_edit_resource.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_editor_3d_handle.svg (renamed from tools/editor/icons/source/icon_editor_3d_handle.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_editor_handle.svg (renamed from tools/editor/icons/source/icon_editor_handle.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_editor_pivot.svg (renamed from tools/editor/icons/source/icon_editor_pivot.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_editor_plugin.svg (renamed from tools/editor/icons/source/icon_editor_plugin.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_environment.svg (renamed from tools/editor/icons/source/icon_environment.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_error.svg (renamed from tools/editor/icons/source/icon_error.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_error_sign.svg (renamed from tools/editor/icons/source/icon_error_sign.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_event_player.svg (renamed from tools/editor/icons/source/icon_event_player.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_favorites.svg (renamed from tools/editor/icons/source/icon_favorites.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_file_big.svg (renamed from tools/editor/icons/source/icon_file_big.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_file_dialog.svg (renamed from tools/editor/icons/source/icon_file_dialog.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_file_list.svg (renamed from tools/editor/icons/source/icon_file_list.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_file_server.svg (renamed from tools/editor/icons/source/icon_file_server.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_file_server_active.svg (renamed from tools/editor/icons/source/icon_file_server_active.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_file_thumbnail.svg (renamed from tools/editor/icons/source/icon_file_thumbnail.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_fixed_material.svg (renamed from tools/editor/icons/source/icon_fixed_material.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_fixed_spatial_material.svg (renamed from tools/editor/icons/source/icon_fixed_spatial_material.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_folder.svg (renamed from tools/editor/icons/source/icon_folder.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_folder_big.svg (renamed from tools/editor/icons/source/icon_folder_big.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_font.svg (renamed from tools/editor/icons/source/icon_font.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_forward.svg (renamed from tools/editor/icons/source/icon_forward.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_g_d_script.svg (renamed from tools/editor/icons/source/icon_g_d_script.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_g_i_probe.svg (renamed from tools/editor/icons/source/icon_g_i_probe.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_g_i_probe_data.svg (renamed from tools/editor/icons/source/icon_g_i_probe_data.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_generic_6_d_o_f_joint.svg (renamed from tools/editor/icons/source/icon_generic_6_d_o_f_joint.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_gizmo_directional_light.svg (renamed from tools/editor/icons/source/icon_gizmo_directional_light.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_gizmo_light.svg (renamed from tools/editor/icons/source/icon_gizmo_light.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_gizmo_listener.svg (renamed from tools/editor/icons/source/icon_gizmo_listener.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_gizmo_spatial_sample_player.svg (renamed from tools/editor/icons/source/icon_gizmo_spatial_sample_player.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_gizmo_spatial_stream_player.svg (renamed from tools/editor/icons/source/icon_gizmo_spatial_stream_player.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_godot.svg (renamed from tools/editor/icons/source/icon_godot.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_comment.svg (renamed from tools/editor/icons/source/icon_graph_comment.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_cube_uniform.svg (renamed from tools/editor/icons/source/icon_graph_cube_uniform.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_curve_map.svg (renamed from tools/editor/icons/source/icon_graph_curve_map.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_default_texture.svg (renamed from tools/editor/icons/source/icon_graph_default_texture.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_edit.svg (renamed from tools/editor/icons/source/icon_graph_edit.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_input.svg (renamed from tools/editor/icons/source/icon_graph_input.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_node.svg (renamed from tools/editor/icons/source/icon_graph_node.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_rgb.svg (renamed from tools/editor/icons/source/icon_graph_rgb.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_rgb_op.svg (renamed from tools/editor/icons/source/icon_graph_rgb_op.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_rgb_uniform.svg (renamed from tools/editor/icons/source/icon_graph_rgb_uniform.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_scalar.svg (renamed from tools/editor/icons/source/icon_graph_scalar.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_scalar_interp.svg (renamed from tools/editor/icons/source/icon_graph_scalar_interp.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_scalar_op.svg (renamed from tools/editor/icons/source/icon_graph_scalar_op.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_scalar_uniform.svg (renamed from tools/editor/icons/source/icon_graph_scalar_uniform.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_scalars_to_vec.svg (renamed from tools/editor/icons/source/icon_graph_scalars_to_vec.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_texscreen.svg (renamed from tools/editor/icons/source/icon_graph_texscreen.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_texture_uniform.svg (renamed from tools/editor/icons/source/icon_graph_texture_uniform.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_time.svg (renamed from tools/editor/icons/source/icon_graph_time.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_vec_dp.svg (renamed from tools/editor/icons/source/icon_graph_vec_dp.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_vec_interp.svg (renamed from tools/editor/icons/source/icon_graph_vec_interp.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_vec_length.svg (renamed from tools/editor/icons/source/icon_graph_vec_length.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_vec_op.svg (renamed from tools/editor/icons/source/icon_graph_vec_op.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_vec_scalar_op.svg (renamed from tools/editor/icons/source/icon_graph_vec_scalar_op.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_vec_to_scalars.svg (renamed from tools/editor/icons/source/icon_graph_vec_to_scalars.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_vecs_to_xform.svg (renamed from tools/editor/icons/source/icon_graph_vecs_to_xform.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_vector.svg (renamed from tools/editor/icons/source/icon_graph_vector.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_vector_uniform.svg (renamed from tools/editor/icons/source/icon_graph_vector_uniform.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_xform.svg (renamed from tools/editor/icons/source/icon_graph_xform.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_xform_mult.svg (renamed from tools/editor/icons/source/icon_graph_xform_mult.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_xform_scalar_func.svg (renamed from tools/editor/icons/source/icon_graph_xform_scalar_func.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_xform_to_vecs.svg (renamed from tools/editor/icons/source/icon_graph_xform_to_vecs.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_xform_uniform.svg (renamed from tools/editor/icons/source/icon_graph_xform_uniform.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_xform_vec_func.svg (renamed from tools/editor/icons/source/icon_graph_xform_vec_func.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_xform_vec_imult.svg (renamed from tools/editor/icons/source/icon_graph_xform_vec_imult.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_graph_xform_vec_mult.svg (renamed from tools/editor/icons/source/icon_graph_xform_vec_mult.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_grid.svg (renamed from tools/editor/icons/source/icon_grid.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_grid_container.svg (renamed from tools/editor/icons/source/icon_grid_container.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_grid_map.svg (renamed from tools/editor/icons/source/icon_grid_map.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_groove_joint_2d.svg (renamed from tools/editor/icons/source/icon_groove_joint_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_group.svg (renamed from tools/editor/icons/source/icon_group.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_groups.svg (renamed from tools/editor/icons/source/icon_groups.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_h_box_container.svg (renamed from tools/editor/icons/source/icon_h_box_container.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_h_button_array.svg (renamed from tools/editor/icons/source/icon_h_button_array.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_h_scroll_bar.svg (renamed from tools/editor/icons/source/icon_h_scroll_bar.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_h_separator.svg (renamed from tools/editor/icons/source/icon_h_separator.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_h_slider.svg (renamed from tools/editor/icons/source/icon_h_slider.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_h_split_container.svg (renamed from tools/editor/icons/source/icon_h_split_container.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_h_t_t_p_request.svg (renamed from tools/editor/icons/source/icon_h_t_t_p_request.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_headphones.svg (renamed from tools/editor/icons/source/icon_headphones.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_help.svg (renamed from tools/editor/icons/source/icon_help.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_hidden.svg (renamed from tools/editor/icons/source/icon_hidden.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_hinge_joint.svg (renamed from tools/editor/icons/source/icon_hinge_joint.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_history.svg (renamed from tools/editor/icons/source/icon_history.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_hsize.svg (renamed from tools/editor/icons/source/icon_hsize.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_image.svg (renamed from tools/editor/icons/source/icon_image.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_image_sky_box.svg (renamed from tools/editor/icons/source/icon_image_sky_box.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_image_texture.svg (renamed from tools/editor/icons/source/icon_image_texture.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_immediate_geometry.svg (renamed from tools/editor/icons/source/icon_immediate_geometry.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_import_check.svg (renamed from tools/editor/icons/source/icon_import_check.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_import_fail.svg (renamed from tools/editor/icons/source/icon_import_fail.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_instance.svg (renamed from tools/editor/icons/source/icon_instance.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_instance_options.svg (renamed from tools/editor/icons/source/icon_instance_options.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_integer.svg (renamed from tools/editor/icons/source/icon_integer.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_interp_cubic.svg (renamed from tools/editor/icons/source/icon_interp_cubic.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_interp_linear.svg (renamed from tools/editor/icons/source/icon_interp_linear.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_interp_raw.svg (renamed from tools/editor/icons/source/icon_interp_raw.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_interp_wrap_clamp.svg (renamed from tools/editor/icons/source/icon_interp_wrap_clamp.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_interp_wrap_loop.svg (renamed from tools/editor/icons/source/icon_interp_wrap_loop.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_interpolated_camera.svg (renamed from tools/editor/icons/source/icon_interpolated_camera.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_invalid_key.svg (renamed from tools/editor/icons/source/icon_invalid_key.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_inverse_kinematics.svg (renamed from tools/editor/icons/source/icon_inverse_kinematics.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_item_list.svg (renamed from tools/editor/icons/source/icon_item_list.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_joy_axis.svg (renamed from tools/editor/icons/source/icon_joy_axis.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_joy_button.svg (renamed from tools/editor/icons/source/icon_joy_button.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_joypad.svg (renamed from tools/editor/icons/source/icon_joypad.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_key.svg (renamed from tools/editor/icons/source/icon_key.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_key_hover.svg (renamed from tools/editor/icons/source/icon_key_hover.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_key_invalid.svg (renamed from tools/editor/icons/source/icon_key_invalid.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_key_next.svg (renamed from tools/editor/icons/source/icon_key_next.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_key_selected.svg (renamed from tools/editor/icons/source/icon_key_selected.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_key_value.svg (renamed from tools/editor/icons/source/icon_key_value.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_key_xform.svg (renamed from tools/editor/icons/source/icon_key_xform.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_keyboard.svg (renamed from tools/editor/icons/source/icon_keyboard.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_kinematic_body.svg (renamed from tools/editor/icons/source/icon_kinematic_body.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_kinematic_body_2d.svg (renamed from tools/editor/icons/source/icon_kinematic_body_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_label.svg (renamed from tools/editor/icons/source/icon_label.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_large_texture.svg (renamed from tools/editor/icons/source/icon_large_texture.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_light_2d.svg (renamed from tools/editor/icons/source/icon_light_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_light_occluder_2d.svg (renamed from tools/editor/icons/source/icon_light_occluder_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_line_2d.svg (renamed from tools/editor/icons/source/icon_line_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_line_edit.svg (renamed from tools/editor/icons/source/icon_line_edit.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_line_shape_2d.svg (renamed from tools/editor/icons/source/icon_line_shape_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_link_button.svg (renamed from tools/editor/icons/source/icon_link_button.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_list_select.svg (renamed from tools/editor/icons/source/icon_list_select.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_listener.svg (renamed from tools/editor/icons/source/icon_listener.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_load.svg (renamed from tools/editor/icons/source/icon_load.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_lock.svg (renamed from tools/editor/icons/source/icon_lock.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_loop.svg (renamed from tools/editor/icons/source/icon_loop.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_loop_interpolation.svg (renamed from tools/editor/icons/source/icon_loop_interpolation.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_main_play.svg (renamed from tools/editor/icons/source/icon_main_play.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_main_stop.svg (renamed from tools/editor/icons/source/icon_main_stop.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_margin_container.svg (renamed from tools/editor/icons/source/icon_margin_container.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_material_preview_cube.svg (renamed from tools/editor/icons/source/icon_material_preview_cube.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_material_preview_cube_off.svg (renamed from tools/editor/icons/source/icon_material_preview_cube_off.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_material_preview_light_1.svg (renamed from tools/editor/icons/source/icon_material_preview_light_1.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_material_preview_light_1_off.svg (renamed from tools/editor/icons/source/icon_material_preview_light_1_off.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_material_preview_light_2.svg (renamed from tools/editor/icons/source/icon_material_preview_light_2.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_material_preview_light_2_off.svg (renamed from tools/editor/icons/source/icon_material_preview_light_2_off.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_material_preview_sphere.svg (renamed from tools/editor/icons/source/icon_material_preview_sphere.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_material_preview_sphere_off.svg (renamed from tools/editor/icons/source/icon_material_preview_sphere_off.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_matrix.svg (renamed from tools/editor/icons/source/icon_matrix.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_menu_button.svg (renamed from tools/editor/icons/source/icon_menu_button.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mesh.svg (renamed from tools/editor/icons/source/icon_mesh.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mesh_instance.svg (renamed from tools/editor/icons/source/icon_mesh_instance.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mesh_library.svg (renamed from tools/editor/icons/source/icon_mesh_library.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_aabb.svg (renamed from tools/editor/icons/source/icon_mini_aabb.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_array.svg (renamed from tools/editor/icons/source/icon_mini_array.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_boolean.svg (renamed from tools/editor/icons/source/icon_mini_boolean.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_color.svg (renamed from tools/editor/icons/source/icon_mini_color.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_color_array.svg (renamed from tools/editor/icons/source/icon_mini_color_array.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_dictionary.svg (renamed from tools/editor/icons/source/icon_mini_dictionary.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_float.svg (renamed from tools/editor/icons/source/icon_mini_float.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_float_array.svg (renamed from tools/editor/icons/source/icon_mini_float_array.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_image.svg (renamed from tools/editor/icons/source/icon_mini_image.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_input.svg (renamed from tools/editor/icons/source/icon_mini_input.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_int_array.svg (renamed from tools/editor/icons/source/icon_mini_int_array.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_integer.svg (renamed from tools/editor/icons/source/icon_mini_integer.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_matrix3.svg (renamed from tools/editor/icons/source/icon_mini_matrix3.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_matrix32.svg (renamed from tools/editor/icons/source/icon_mini_matrix32.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_object.svg (renamed from tools/editor/icons/source/icon_mini_object.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_path.svg (renamed from tools/editor/icons/source/icon_mini_path.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_plane.svg (renamed from tools/editor/icons/source/icon_mini_plane.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_quat.svg (renamed from tools/editor/icons/source/icon_mini_quat.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_raw_array.svg (renamed from tools/editor/icons/source/icon_mini_raw_array.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_rect2.svg (renamed from tools/editor/icons/source/icon_mini_rect2.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_rid.svg (renamed from tools/editor/icons/source/icon_mini_rid.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_string.svg (renamed from tools/editor/icons/source/icon_mini_string.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_string_array.svg (renamed from tools/editor/icons/source/icon_mini_string_array.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_transform.svg (renamed from tools/editor/icons/source/icon_mini_transform.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_variant.svg (renamed from tools/editor/icons/source/icon_mini_variant.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_vector2.svg (renamed from tools/editor/icons/source/icon_mini_vector2.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_vector2_array.svg (renamed from tools/editor/icons/source/icon_mini_vector2_array.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_vector3.svg (renamed from tools/editor/icons/source/icon_mini_vector3.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mini_vector3_array.svg (renamed from tools/editor/icons/source/icon_mini_vector3_array.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mirror_x.svg (renamed from tools/editor/icons/source/icon_mirror_x.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mirror_y.svg (renamed from tools/editor/icons/source/icon_mirror_y.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_mouse.svg (renamed from tools/editor/icons/source/icon_mouse.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_move_down.svg (renamed from tools/editor/icons/source/icon_move_down.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_move_point.svg (renamed from tools/editor/icons/source/icon_move_point.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_move_up.svg (renamed from tools/editor/icons/source/icon_move_up.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_multi_edit.svg (renamed from tools/editor/icons/source/icon_multi_edit.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_multi_line.svg (renamed from tools/editor/icons/source/icon_multi_line.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_multi_mesh.svg (renamed from tools/editor/icons/source/icon_multi_mesh.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_multi_mesh_instance.svg (renamed from tools/editor/icons/source/icon_multi_mesh_instance.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_navigation.svg (renamed from tools/editor/icons/source/icon_navigation.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_navigation_2d.svg (renamed from tools/editor/icons/source/icon_navigation_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_navigation_mesh.svg (renamed from tools/editor/icons/source/icon_navigation_mesh.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_navigation_mesh_instance.svg (renamed from tools/editor/icons/source/icon_navigation_mesh_instance.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_navigation_polygon.svg (renamed from tools/editor/icons/source/icon_navigation_polygon.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_navigation_polygon_instance.svg (renamed from tools/editor/icons/source/icon_navigation_polygon_instance.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_new.svg (renamed from tools/editor/icons/source/icon_new.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_nine_patch_rect.svg (renamed from tools/editor/icons/source/icon_nine_patch_rect.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_node.svg (renamed from tools/editor/icons/source/icon_node.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_node_2d.svg (renamed from tools/editor/icons/source/icon_node_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_node_warning.svg (renamed from tools/editor/icons/source/icon_node_warning.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_non_favorite.svg (renamed from tools/editor/icons/source/icon_non_favorite.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_object.svg (renamed from tools/editor/icons/source/icon_object.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_occluder_polygon_2d.svg (renamed from tools/editor/icons/source/icon_occluder_polygon_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_omni_light.svg (renamed from tools/editor/icons/source/icon_omni_light.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_option_button.svg (renamed from tools/editor/icons/source/icon_option_button.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_override.svg (renamed from tools/editor/icons/source/icon_override.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_packed_data_container.svg (renamed from tools/editor/icons/source/icon_packed_data_container.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_packed_scene.svg (renamed from tools/editor/icons/source/icon_packed_scene.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_panel.svg (renamed from tools/editor/icons/source/icon_panel.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_panel_container.svg (renamed from tools/editor/icons/source/icon_panel_container.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_panels_1.svg (renamed from tools/editor/icons/source/icon_panels_1.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_panels_2.svg (renamed from tools/editor/icons/source/icon_panels_2.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_panels_2_alt.svg (renamed from tools/editor/icons/source/icon_panels_2_alt.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_panels_3.svg (renamed from tools/editor/icons/source/icon_panels_3.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_panels_3_alt.svg (renamed from tools/editor/icons/source/icon_panels_3_alt.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_panels_4.svg (renamed from tools/editor/icons/source/icon_panels_4.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_parallax_background.svg (renamed from tools/editor/icons/source/icon_parallax_background.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_parallax_layer.svg (renamed from tools/editor/icons/source/icon_parallax_layer.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_particle_attractor_2d.svg (renamed from tools/editor/icons/source/icon_particle_attractor_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_particles.svg (renamed from tools/editor/icons/source/icon_particles.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_particles_2d.svg (renamed from tools/editor/icons/source/icon_particles_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_particles_shader.svg (renamed from tools/editor/icons/source/icon_particles_shader.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_patch_9_rect.svg (renamed from tools/editor/icons/source/icon_patch_9_rect.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_path.svg (renamed from tools/editor/icons/source/icon_path.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_path_2d.svg (renamed from tools/editor/icons/source/icon_path_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_path_follow.svg (renamed from tools/editor/icons/source/icon_path_follow.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_path_follow_2d.svg (renamed from tools/editor/icons/source/icon_path_follow_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_pause.svg (renamed from tools/editor/icons/source/icon_pause.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_pin.svg (renamed from tools/editor/icons/source/icon_pin.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_pin_joint.svg (renamed from tools/editor/icons/source/icon_pin_joint.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_pin_joint_2d.svg (renamed from tools/editor/icons/source/icon_pin_joint_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_pin_pressed.svg (renamed from tools/editor/icons/source/icon_pin_pressed.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_plane.svg (renamed from tools/editor/icons/source/icon_plane.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_plane_shape.svg (renamed from tools/editor/icons/source/icon_plane_shape.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_play.svg (renamed from tools/editor/icons/source/icon_play.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_play_backwards.svg (renamed from tools/editor/icons/source/icon_play_backwards.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_play_custom.svg (renamed from tools/editor/icons/source/icon_play_custom.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_play_scene.svg (renamed from tools/editor/icons/source/icon_play_scene.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_play_start.svg (renamed from tools/editor/icons/source/icon_play_start.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_play_start_backwards.svg (renamed from tools/editor/icons/source/icon_play_start_backwards.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_polygon_path_finder.svg (renamed from tools/editor/icons/source/icon_polygon_path_finder.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_popup.svg (renamed from tools/editor/icons/source/icon_popup.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_popup_dialog.svg (renamed from tools/editor/icons/source/icon_popup_dialog.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_popup_menu.svg (renamed from tools/editor/icons/source/icon_popup_menu.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_popup_panel.svg (renamed from tools/editor/icons/source/icon_popup_panel.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_portal.svg (renamed from tools/editor/icons/source/icon_portal.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_position_2d.svg (renamed from tools/editor/icons/source/icon_position_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_position_3d.svg (renamed from tools/editor/icons/source/icon_position_3d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_progress_1.svg (renamed from tools/editor/icons/source/icon_progress_1.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_progress_2.svg (renamed from tools/editor/icons/source/icon_progress_2.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_progress_3.svg (renamed from tools/editor/icons/source/icon_progress_3.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_progress_4.svg (renamed from tools/editor/icons/source/icon_progress_4.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_progress_5.svg (renamed from tools/editor/icons/source/icon_progress_5.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_progress_6.svg (renamed from tools/editor/icons/source/icon_progress_6.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_progress_7.svg (renamed from tools/editor/icons/source/icon_progress_7.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_progress_8.svg (renamed from tools/editor/icons/source/icon_progress_8.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_progress_bar.svg (renamed from tools/editor/icons/source/icon_progress_bar.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_proximity_group.svg (renamed from tools/editor/icons/source/icon_proximity_group.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_quad.svg (renamed from tools/editor/icons/source/icon_quad.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_quat.svg (renamed from tools/editor/icons/source/icon_quat.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_range.svg (renamed from tools/editor/icons/source/icon_range.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_rating_no_star.svg (renamed from tools/editor/icons/source/icon_rating_no_star.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_rating_star.svg (renamed from tools/editor/icons/source/icon_rating_star.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_ray_cast.svg (renamed from tools/editor/icons/source/icon_ray_cast.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_ray_cast_2d.svg (renamed from tools/editor/icons/source/icon_ray_cast_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_ray_shape.svg (renamed from tools/editor/icons/source/icon_ray_shape.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_ray_shape_2d.svg (renamed from tools/editor/icons/source/icon_ray_shape_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_rayito.svg (renamed from tools/editor/icons/source/icon_rayito.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_real.svg (renamed from tools/editor/icons/source/icon_real.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_rectangle_shape_2d.svg (renamed from tools/editor/icons/source/icon_rectangle_shape_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_reference_rect.svg (renamed from tools/editor/icons/source/icon_reference_rect.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_reflection_probe.svg (renamed from tools/editor/icons/source/icon_reflection_probe.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_region_edit.svg (renamed from tools/editor/icons/source/icon_region_edit.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_reload_small.svg (renamed from tools/editor/icons/source/icon_reload_small.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_remote.svg (renamed from tools/editor/icons/source/icon_remote.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_remote_transform.svg (renamed from tools/editor/icons/source/icon_remote_transform.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_remote_transform_2d.svg (renamed from tools/editor/icons/source/icon_remote_transform_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_remove.svg (renamed from tools/editor/icons/source/icon_remove.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_rename.svg (renamed from tools/editor/icons/source/icon_rename.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_reparent.svg (renamed from tools/editor/icons/source/icon_reparent.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_resource_preloader.svg (renamed from tools/editor/icons/source/icon_resource_preloader.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_rich_text_label.svg (renamed from tools/editor/icons/source/icon_rich_text_label.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_rigid_body.svg (renamed from tools/editor/icons/source/icon_rigid_body.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_rigid_body_2d.svg (renamed from tools/editor/icons/source/icon_rigid_body_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_room.svg (renamed from tools/editor/icons/source/icon_room.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_room_bounds.svg (renamed from tools/editor/icons/source/icon_room_bounds.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_rotate_0.svg (renamed from tools/editor/icons/source/icon_rotate_0.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_rotate_180.svg (renamed from tools/editor/icons/source/icon_rotate_180.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_rotate_270.svg (renamed from tools/editor/icons/source/icon_rotate_270.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_rotate_90.svg (renamed from tools/editor/icons/source/icon_rotate_90.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_sample.svg (renamed from tools/editor/icons/source/icon_sample.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_sample_library.svg (renamed from tools/editor/icons/source/icon_sample_library.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_sample_player.svg (renamed from tools/editor/icons/source/icon_sample_player.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_sample_player_2d.svg (renamed from tools/editor/icons/source/icon_sample_player_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_save.svg (renamed from tools/editor/icons/source/icon_save.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_script.svg (renamed from tools/editor/icons/source/icon_script.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_script_create.svg (renamed from tools/editor/icons/source/icon_script_create.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_script_remove.svg (renamed from tools/editor/icons/source/icon_script_remove.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_scroll_bar.svg (renamed from tools/editor/icons/source/icon_scroll_bar.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_scroll_container.svg (renamed from tools/editor/icons/source/icon_scroll_container.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_segment_shape_2d.svg (renamed from tools/editor/icons/source/icon_segment_shape_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_shader.svg (renamed from tools/editor/icons/source/icon_shader.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_short_cut.svg (renamed from tools/editor/icons/source/icon_short_cut.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_signal.svg (renamed from tools/editor/icons/source/icon_signal.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_skeleton.svg (renamed from tools/editor/icons/source/icon_skeleton.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_slider_joint.svg (renamed from tools/editor/icons/source/icon_slider_joint.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_slot.svg (renamed from tools/editor/icons/source/icon_slot.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_snap.svg (renamed from tools/editor/icons/source/icon_snap.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_sound_room_params.svg (renamed from tools/editor/icons/source/icon_sound_room_params.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_spatial.svg (renamed from tools/editor/icons/source/icon_spatial.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_spatial_sample_player.svg (renamed from tools/editor/icons/source/icon_spatial_sample_player.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_spatial_shader.svg (renamed from tools/editor/icons/source/icon_spatial_shader.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_spatial_stream_player.svg (renamed from tools/editor/icons/source/icon_spatial_stream_player.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_sphere_shape.svg (renamed from tools/editor/icons/source/icon_sphere_shape.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_spin_box.svg (renamed from tools/editor/icons/source/icon_spin_box.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_spot_light.svg (renamed from tools/editor/icons/source/icon_spot_light.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_sprite.svg (renamed from tools/editor/icons/source/icon_sprite.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_sprite_3d.svg (renamed from tools/editor/icons/source/icon_sprite_3d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_sprite_frames.svg (renamed from tools/editor/icons/source/icon_sprite_frames.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_static_body.svg (renamed from tools/editor/icons/source/icon_static_body.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_static_body_2d.svg (renamed from tools/editor/icons/source/icon_static_body_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_stream_player.svg (renamed from tools/editor/icons/source/icon_stream_player.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_string.svg (renamed from tools/editor/icons/source/icon_string.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_style_box_empty.svg (renamed from tools/editor/icons/source/icon_style_box_empty.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_style_box_flat.svg (renamed from tools/editor/icons/source/icon_style_box_flat.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_style_box_texture.svg (renamed from tools/editor/icons/source/icon_style_box_texture.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_tab_container.svg (renamed from tools/editor/icons/source/icon_tab_container.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_tabs.svg (renamed from tools/editor/icons/source/icon_tabs.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_test_cube.svg (renamed from tools/editor/icons/source/icon_test_cube.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_text_edit.svg (renamed from tools/editor/icons/source/icon_text_edit.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_texture.svg (renamed from tools/editor/icons/source/icon_texture.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_texture_button.svg (renamed from tools/editor/icons/source/icon_texture_button.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_texture_progress.svg (renamed from tools/editor/icons/source/icon_texture_progress.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_texture_rect.svg (renamed from tools/editor/icons/source/icon_texture_rect.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_theme.svg (renamed from tools/editor/icons/source/icon_theme.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_tile_map.svg (renamed from tools/editor/icons/source/icon_tile_map.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_tile_set.svg (renamed from tools/editor/icons/source/icon_tile_set.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_timer.svg (renamed from tools/editor/icons/source/icon_timer.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_tool_button.svg (renamed from tools/editor/icons/source/icon_tool_button.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_tool_move.svg (renamed from tools/editor/icons/source/icon_tool_move.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_tool_pan.svg (renamed from tools/editor/icons/source/icon_tool_pan.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_tool_rotate.svg (renamed from tools/editor/icons/source/icon_tool_rotate.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_tool_scale.svg (renamed from tools/editor/icons/source/icon_tool_scale.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_tool_select.svg (renamed from tools/editor/icons/source/icon_tool_select.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_tools.svg (renamed from tools/editor/icons/source/icon_tools.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_touch_screen_button.svg (renamed from tools/editor/icons/source/icon_touch_screen_button.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_track_add_key.svg (renamed from tools/editor/icons/source/icon_track_add_key.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_track_add_key_hl.svg (renamed from tools/editor/icons/source/icon_track_add_key_hl.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_track_continuous.svg (renamed from tools/editor/icons/source/icon_track_continuous.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_track_discrete.svg (renamed from tools/editor/icons/source/icon_track_discrete.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_track_trigger.svg (renamed from tools/editor/icons/source/icon_track_trigger.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_translation.svg (renamed from tools/editor/icons/source/icon_translation.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_transpose.svg (renamed from tools/editor/icons/source/icon_transpose.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_tree.svg (renamed from tools/editor/icons/source/icon_tree.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_tween.svg (renamed from tools/editor/icons/source/icon_tween.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_unbone.svg (renamed from tools/editor/icons/source/icon_unbone.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_ungroup.svg (renamed from tools/editor/icons/source/icon_ungroup.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_unlock.svg (renamed from tools/editor/icons/source/icon_unlock.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_uv.svg (renamed from tools/editor/icons/source/icon_uv.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_v_box_container.svg (renamed from tools/editor/icons/source/icon_v_box_container.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_v_button_array.svg (renamed from tools/editor/icons/source/icon_v_button_array.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_v_scroll_bar.svg (renamed from tools/editor/icons/source/icon_v_scroll_bar.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_v_separator.svg (renamed from tools/editor/icons/source/icon_v_separator.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_v_slider.svg (renamed from tools/editor/icons/source/icon_v_slider.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_v_split_container.svg (renamed from tools/editor/icons/source/icon_v_split_container.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_vector.svg (renamed from tools/editor/icons/source/icon_vector.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_vector2.svg (renamed from tools/editor/icons/source/icon_vector2.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_vehicle_body.svg (renamed from tools/editor/icons/source/icon_vehicle_body.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_vehicle_wheel.svg (renamed from tools/editor/icons/source/icon_vehicle_wheel.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_video_player.svg (renamed from tools/editor/icons/source/icon_video_player.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_viewport.svg (renamed from tools/editor/icons/source/icon_viewport.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_viewport_container.svg (renamed from tools/editor/icons/source/icon_viewport_container.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_viewport_sprite.svg (renamed from tools/editor/icons/source/icon_viewport_sprite.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_viewport_texture.svg (renamed from tools/editor/icons/source/icon_viewport_texture.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_visibility_enabler.svg (renamed from tools/editor/icons/source/icon_visibility_enabler.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_visibility_enabler_2d.svg (renamed from tools/editor/icons/source/icon_visibility_enabler_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_visibility_notifier.svg (renamed from tools/editor/icons/source/icon_visibility_notifier.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_visibility_notifier_2d.svg (renamed from tools/editor/icons/source/icon_visibility_notifier_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_visible.svg (renamed from tools/editor/icons/source/icon_visible.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_visual_script.svg (renamed from tools/editor/icons/source/icon_visual_script.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_visual_shader_port.svg (renamed from tools/editor/icons/source/icon_visual_shader_port.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_vu_empty.svg (renamed from tools/editor/icons/source/icon_vu_empty.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_vu_full.svg (renamed from tools/editor/icons/source/icon_vu_full.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_warning.svg (renamed from tools/editor/icons/source/icon_warning.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_window_dialog.svg (renamed from tools/editor/icons/source/icon_window_dialog.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_world.svg (renamed from tools/editor/icons/source/icon_world.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_world_2d.svg (renamed from tools/editor/icons/source/icon_world_2d.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_world_environment.svg (renamed from tools/editor/icons/source/icon_world_environment.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_y_sort.svg (renamed from tools/editor/icons/source/icon_y_sort.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_zoom.svg (renamed from tools/editor/icons/source/icon_zoom.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_zoom_less.svg (renamed from tools/editor/icons/source/icon_zoom_less.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_zoom_more.svg (renamed from tools/editor/icons/source/icon_zoom_more.svg) | 0 | ||||
-rw-r--r-- | editor/icons/source/icon_zoom_reset.svg (renamed from tools/editor/icons/source/icon_zoom_reset.svg) | 0 | ||||
-rwxr-xr-x | editor/icons/xpmfix.sh (renamed from tools/editor/icons/xpmfix.sh) | 0 | ||||
-rw-r--r-- | editor/import/SCsub (renamed from tools/editor/import/SCsub) | 0 | ||||
-rw-r--r-- | editor/import/editor_import_collada.cpp | 2508 | ||||
-rw-r--r-- | editor/import/editor_import_collada.h | 51 | ||||
-rw-r--r-- | editor/import/resource_importer_csv_translation.cpp (renamed from tools/editor/import/resource_importer_csv_translation.cpp) | 0 | ||||
-rw-r--r-- | editor/import/resource_importer_csv_translation.h (renamed from tools/editor/import/resource_importer_csv_translation.h) | 0 | ||||
-rw-r--r-- | editor/import/resource_importer_obj.cpp (renamed from tools/editor/import/resource_importer_obj.cpp) | 0 | ||||
-rw-r--r-- | editor/import/resource_importer_obj.h (renamed from tools/editor/import/resource_importer_obj.h) | 0 | ||||
-rw-r--r-- | editor/import/resource_importer_scene.cpp | 1328 | ||||
-rw-r--r-- | editor/import/resource_importer_scene.h (renamed from tools/editor/import/resource_importer_scene.h) | 0 | ||||
-rw-r--r-- | editor/import/resource_importer_texture.cpp | 393 | ||||
-rw-r--r-- | editor/import/resource_importer_texture.h (renamed from tools/editor/import/resource_importer_texture.h) | 0 | ||||
-rw-r--r-- | editor/import/resource_importer_wav.cpp (renamed from tools/editor/import/resource_importer_wav.cpp) | 0 | ||||
-rw-r--r-- | editor/import/resource_importer_wav.h (renamed from tools/editor/import/resource_importer_wav.h) | 0 | ||||
-rw-r--r-- | editor/import_dock.cpp (renamed from tools/editor/import_dock.cpp) | 0 | ||||
-rw-r--r-- | editor/import_dock.h (renamed from tools/editor/import_dock.h) | 0 | ||||
-rw-r--r-- | editor/inspector_dock.cpp (renamed from tools/editor/inspector_dock.cpp) | 0 | ||||
-rw-r--r-- | editor/inspector_dock.h (renamed from tools/editor/inspector_dock.h) | 0 | ||||
-rw-r--r-- | editor/io_plugins/SCsub (renamed from tools/editor/io_plugins/SCsub) | 0 | ||||
-rw-r--r-- | editor/io_plugins/editor_atlas.cpp (renamed from tools/editor/io_plugins/editor_atlas.cpp) | 0 | ||||
-rw-r--r-- | editor/io_plugins/editor_atlas.h (renamed from tools/editor/io_plugins/editor_atlas.h) | 0 | ||||
-rw-r--r-- | editor/io_plugins/editor_bitmask_import_plugin.cpp | 387 | ||||
-rw-r--r-- | editor/io_plugins/editor_bitmask_import_plugin.h | 70 | ||||
-rw-r--r-- | editor/io_plugins/editor_export_scene.cpp | 142 | ||||
-rw-r--r-- | editor/io_plugins/editor_export_scene.h | 44 | ||||
-rw-r--r-- | editor/io_plugins/editor_font_import_plugin.cpp | 1704 | ||||
-rw-r--r-- | editor/io_plugins/editor_font_import_plugin.h | 58 | ||||
-rw-r--r-- | editor/io_plugins/editor_mesh_import_plugin.cpp | 593 | ||||
-rw-r--r-- | editor/io_plugins/editor_mesh_import_plugin.h | 59 | ||||
-rw-r--r-- | editor/io_plugins/editor_sample_import_plugin.cpp | 929 | ||||
-rw-r--r-- | editor/io_plugins/editor_sample_import_plugin.h | 74 | ||||
-rw-r--r-- | editor/io_plugins/editor_scene_import_plugin.cpp | 2992 | ||||
-rw-r--r-- | editor/io_plugins/editor_scene_import_plugin.h | 200 | ||||
-rw-r--r-- | editor/io_plugins/editor_scene_importer_fbxconv.cpp | 1136 | ||||
-rw-r--r-- | editor/io_plugins/editor_scene_importer_fbxconv.h | 111 | ||||
-rw-r--r-- | editor/io_plugins/editor_texture_import_plugin.cpp | 1893 | ||||
-rw-r--r-- | editor/io_plugins/editor_texture_import_plugin.h | 179 | ||||
-rw-r--r-- | editor/io_plugins/editor_translation_import_plugin.cpp | 479 | ||||
-rw-r--r-- | editor/io_plugins/editor_translation_import_plugin.h | 56 | ||||
-rw-r--r-- | editor/multi_node_edit.cpp (renamed from tools/editor/multi_node_edit.cpp) | 0 | ||||
-rw-r--r-- | editor/multi_node_edit.h (renamed from tools/editor/multi_node_edit.h) | 0 | ||||
-rw-r--r-- | editor/node_dock.cpp (renamed from tools/editor/node_dock.cpp) | 0 | ||||
-rw-r--r-- | editor/node_dock.h (renamed from tools/editor/node_dock.h) | 0 | ||||
-rw-r--r-- | editor/output_strings.cpp (renamed from tools/editor/output_strings.cpp) | 0 | ||||
-rw-r--r-- | editor/output_strings.h (renamed from tools/editor/output_strings.h) | 0 | ||||
-rw-r--r-- | editor/pane_drag.cpp (renamed from tools/editor/pane_drag.cpp) | 0 | ||||
-rw-r--r-- | editor/pane_drag.h (renamed from tools/editor/pane_drag.h) | 0 | ||||
-rw-r--r-- | editor/plugins/SCsub (renamed from tools/editor/plugins/SCsub) | 0 | ||||
-rw-r--r-- | editor/plugins/animation_player_editor_plugin.cpp | 1604 | ||||
-rw-r--r-- | editor/plugins/animation_player_editor_plugin.h | 219 | ||||
-rw-r--r-- | editor/plugins/animation_tree_editor_plugin.cpp (renamed from tools/editor/plugins/animation_tree_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/animation_tree_editor_plugin.h | 194 | ||||
-rw-r--r-- | editor/plugins/baked_light_baker.cpp | 2731 | ||||
-rw-r--r-- | editor/plugins/baked_light_baker.h (renamed from tools/editor/plugins/baked_light_baker.h) | 0 | ||||
-rw-r--r-- | editor/plugins/baked_light_baker_cmpxchg.cpp (renamed from tools/editor/plugins/baked_light_baker_cmpxchg.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/baked_light_editor_plugin.cpp (renamed from tools/editor/plugins/baked_light_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/baked_light_editor_plugin.h | 120 | ||||
-rw-r--r-- | editor/plugins/camera_editor_plugin.cpp (renamed from tools/editor/plugins/camera_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/camera_editor_plugin.h | 79 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 4063 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.h | 503 | ||||
-rw-r--r-- | editor/plugins/collision_polygon_2d_editor_plugin.cpp | 482 | ||||
-rw-r--r-- | editor/plugins/collision_polygon_2d_editor_plugin.h | 111 | ||||
-rw-r--r-- | editor/plugins/collision_polygon_editor_plugin.cpp | 648 | ||||
-rw-r--r-- | editor/plugins/collision_polygon_editor_plugin.h | 123 | ||||
-rw-r--r-- | editor/plugins/collision_shape_2d_editor_plugin.cpp (renamed from tools/editor/plugins/collision_shape_2d_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/collision_shape_2d_editor_plugin.h | 101 | ||||
-rw-r--r-- | editor/plugins/color_ramp_editor_plugin.cpp (renamed from tools/editor/plugins/color_ramp_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/color_ramp_editor_plugin.h | 62 | ||||
-rw-r--r-- | editor/plugins/cube_grid_theme_editor_plugin.cpp | 357 | ||||
-rw-r--r-- | editor/plugins/cube_grid_theme_editor_plugin.h | 96 | ||||
-rw-r--r-- | editor/plugins/editor_preview_plugins.cpp | 907 | ||||
-rw-r--r-- | editor/plugins/editor_preview_plugins.h | 128 | ||||
-rw-r--r-- | editor/plugins/gi_probe_editor_plugin.cpp (renamed from tools/editor/plugins/gi_probe_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/gi_probe_editor_plugin.h | 65 | ||||
-rw-r--r-- | editor/plugins/item_list_editor_plugin.cpp (renamed from tools/editor/plugins/item_list_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/item_list_editor_plugin.h | 230 | ||||
-rw-r--r-- | editor/plugins/light_occluder_2d_editor_plugin.cpp | 518 | ||||
-rw-r--r-- | editor/plugins/light_occluder_2d_editor_plugin.h | 115 | ||||
-rw-r--r-- | editor/plugins/line_2d_editor_plugin.cpp | 283 | ||||
-rw-r--r-- | editor/plugins/line_2d_editor_plugin.h | 90 | ||||
-rw-r--r-- | editor/plugins/material_editor_plugin.cpp (renamed from tools/editor/plugins/material_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/material_editor_plugin.h | 100 | ||||
-rw-r--r-- | editor/plugins/mesh_editor_plugin.cpp (renamed from tools/editor/plugins/mesh_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/mesh_editor_plugin.h | 98 | ||||
-rw-r--r-- | editor/plugins/mesh_instance_editor_plugin.cpp (renamed from tools/editor/plugins/mesh_instance_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/mesh_instance_editor_plugin.h | 97 | ||||
-rw-r--r-- | editor/plugins/multimesh_editor_plugin.cpp (renamed from tools/editor/plugins/multimesh_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/multimesh_editor_plugin.h | 107 | ||||
-rw-r--r-- | editor/plugins/navigation_polygon_editor_plugin.cpp | 566 | ||||
-rw-r--r-- | editor/plugins/navigation_polygon_editor_plugin.h | 118 | ||||
-rw-r--r-- | editor/plugins/particles_2d_editor_plugin.cpp (renamed from tools/editor/plugins/particles_2d_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/particles_2d_editor_plugin.h | 82 | ||||
-rw-r--r-- | editor/plugins/particles_editor_plugin.cpp | 461 | ||||
-rw-r--r-- | editor/plugins/particles_editor_plugin.h | 116 | ||||
-rw-r--r-- | editor/plugins/path_2d_editor_plugin.cpp | 718 | ||||
-rw-r--r-- | editor/plugins/path_2d_editor_plugin.h | 126 | ||||
-rw-r--r-- | editor/plugins/path_editor_plugin.cpp (renamed from tools/editor/plugins/path_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/path_editor_plugin.h | 100 | ||||
-rw-r--r-- | editor/plugins/polygon_2d_editor_plugin.cpp | 1028 | ||||
-rw-r--r-- | editor/plugins/polygon_2d_editor_plugin.h | 167 | ||||
-rw-r--r-- | editor/plugins/resource_preloader_editor_plugin.cpp | 507 | ||||
-rw-r--r-- | editor/plugins/resource_preloader_editor_plugin.h | 108 | ||||
-rw-r--r-- | editor/plugins/rich_text_editor_plugin.cpp (renamed from tools/editor/plugins/rich_text_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/rich_text_editor_plugin.h | 91 | ||||
-rw-r--r-- | editor/plugins/sample_editor_plugin.cpp | 451 | ||||
-rw-r--r-- | editor/plugins/sample_editor_plugin.h | 92 | ||||
-rw-r--r-- | editor/plugins/sample_library_editor_plugin.cpp | 546 | ||||
-rw-r--r-- | editor/plugins/sample_library_editor_plugin.h | 108 | ||||
-rw-r--r-- | editor/plugins/sample_player_editor_plugin.cpp (renamed from tools/editor/plugins/sample_player_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/sample_player_editor_plugin.h | 90 | ||||
-rw-r--r-- | editor/plugins/script_editor_plugin.cpp | 2491 | ||||
-rw-r--r-- | editor/plugins/script_editor_plugin.h | 394 | ||||
-rw-r--r-- | editor/plugins/script_text_editor.cpp | 1401 | ||||
-rw-r--r-- | editor/plugins/script_text_editor.h (renamed from tools/editor/plugins/script_text_editor.h) | 0 | ||||
-rw-r--r-- | editor/plugins/shader_editor_plugin.cpp | 584 | ||||
-rw-r--r-- | editor/plugins/shader_editor_plugin.h | 156 | ||||
-rw-r--r-- | editor/plugins/shader_graph_editor_plugin.cpp (renamed from tools/editor/plugins/shader_graph_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/shader_graph_editor_plugin.h | 242 | ||||
-rw-r--r-- | editor/plugins/spatial_editor_plugin.cpp | 4131 | ||||
-rw-r--r-- | editor/plugins/spatial_editor_plugin.h | 574 | ||||
-rw-r--r-- | editor/plugins/sprite_frames_editor_plugin.cpp | 969 | ||||
-rw-r--r-- | editor/plugins/sprite_frames_editor_plugin.h | 138 | ||||
-rw-r--r-- | editor/plugins/stream_editor_plugin.cpp (renamed from tools/editor/plugins/stream_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/stream_editor_plugin.h | 84 | ||||
-rw-r--r-- | editor/plugins/style_box_editor_plugin.cpp (renamed from tools/editor/plugins/style_box_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/style_box_editor_plugin.h | 83 | ||||
-rw-r--r-- | editor/plugins/texture_editor_plugin.cpp | 169 | ||||
-rw-r--r-- | editor/plugins/texture_editor_plugin.h | 77 | ||||
-rw-r--r-- | editor/plugins/texture_region_editor_plugin.cpp (renamed from tools/editor/plugins/texture_region_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/texture_region_editor_plugin.h | 153 | ||||
-rw-r--r-- | editor/plugins/theme_editor_plugin.cpp (renamed from tools/editor/plugins/theme_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/theme_editor_plugin.h | 125 | ||||
-rw-r--r-- | editor/plugins/tile_map_editor_plugin.cpp | 1593 | ||||
-rw-r--r-- | editor/plugins/tile_map_editor_plugin.h | 207 | ||||
-rw-r--r-- | editor/plugins/tile_set_editor_plugin.cpp (renamed from tools/editor/plugins/tile_set_editor_plugin.cpp) | 0 | ||||
-rw-r--r-- | editor/plugins/tile_set_editor_plugin.h | 101 | ||||
-rw-r--r-- | editor/progress_dialog.cpp (renamed from tools/editor/progress_dialog.cpp) | 0 | ||||
-rw-r--r-- | editor/progress_dialog.h (renamed from tools/editor/progress_dialog.h) | 0 | ||||
-rw-r--r-- | editor/project_export.cpp (renamed from tools/editor/project_export.cpp) | 0 | ||||
-rw-r--r-- | editor/project_export.h | 142 | ||||
-rw-r--r-- | editor/project_manager.cpp (renamed from tools/editor/project_manager.cpp) | 0 | ||||
-rw-r--r-- | editor/project_manager.h | 148 | ||||
-rw-r--r-- | editor/project_settings.cpp (renamed from tools/editor/project_settings.cpp) | 0 | ||||
-rw-r--r-- | editor/project_settings.h (renamed from tools/editor/project_settings.h) | 0 | ||||
-rw-r--r-- | editor/property_editor.cpp (renamed from tools/editor/property_editor.cpp) | 0 | ||||
-rw-r--r-- | editor/property_editor.h | 352 | ||||
-rw-r--r-- | editor/property_selector.cpp (renamed from tools/editor/property_selector.cpp) | 0 | ||||
-rw-r--r-- | editor/property_selector.h | 83 | ||||
-rw-r--r-- | editor/pvrtc_compress.cpp (renamed from tools/editor/pvrtc_compress.cpp) | 0 | ||||
-rw-r--r-- | editor/pvrtc_compress.h (renamed from tools/editor/pvrtc_compress.h) | 0 | ||||
-rw-r--r-- | editor/quick_open.cpp (renamed from tools/editor/quick_open.cpp) | 0 | ||||
-rw-r--r-- | editor/quick_open.h (renamed from tools/editor/quick_open.h) | 0 | ||||
-rw-r--r-- | editor/register_exporters.h (renamed from tools/editor/register_exporters.h) | 0 | ||||
-rw-r--r-- | editor/reparent_dialog.cpp (renamed from tools/editor/reparent_dialog.cpp) | 0 | ||||
-rw-r--r-- | editor/reparent_dialog.h | 68 | ||||
-rw-r--r-- | editor/resources_dock.cpp (renamed from tools/editor/resources_dock.cpp) | 0 | ||||
-rw-r--r-- | editor/resources_dock.h (renamed from tools/editor/resources_dock.h) | 0 | ||||
-rw-r--r-- | editor/run_settings_dialog.cpp (renamed from tools/editor/run_settings_dialog.cpp) | 0 | ||||
-rw-r--r-- | editor/run_settings_dialog.h (renamed from tools/editor/run_settings_dialog.h) | 0 | ||||
-rw-r--r-- | editor/scene_tree_dock.cpp | 2061 | ||||
-rw-r--r-- | editor/scene_tree_dock.h (renamed from tools/editor/scene_tree_dock.h) | 0 | ||||
-rw-r--r-- | editor/scene_tree_editor.cpp | 1316 | ||||
-rw-r--r-- | editor/scene_tree_editor.h (renamed from tools/editor/scene_tree_editor.h) | 0 | ||||
-rw-r--r-- | editor/script_create_dialog.cpp (renamed from tools/editor/script_create_dialog.cpp) | 0 | ||||
-rw-r--r-- | editor/script_create_dialog.h | 79 | ||||
-rw-r--r-- | editor/script_editor_debugger.cpp (renamed from tools/editor/script_editor_debugger.cpp) | 0 | ||||
-rw-r--r-- | editor/script_editor_debugger.h (renamed from tools/editor/script_editor_debugger.h) | 0 | ||||
-rw-r--r-- | editor/settings_config_dialog.cpp (renamed from tools/editor/settings_config_dialog.cpp) | 0 | ||||
-rw-r--r-- | editor/settings_config_dialog.h (renamed from tools/editor/settings_config_dialog.h) | 0 | ||||
-rw-r--r-- | editor/spatial_editor_gizmos.cpp (renamed from tools/editor/spatial_editor_gizmos.cpp) | 0 | ||||
-rw-r--r-- | editor/spatial_editor_gizmos.h | 521 | ||||
-rw-r--r-- | editor/translations/Makefile | 20 | ||||
-rw-r--r-- | editor/translations/README.md (renamed from tools/editor/translations/README.md) | 0 | ||||
-rw-r--r-- | editor/translations/ar.po (renamed from tools/editor/translations/ar.po) | 0 | ||||
-rw-r--r-- | editor/translations/bg.po (renamed from tools/editor/translations/bg.po) | 0 | ||||
-rw-r--r-- | editor/translations/bn.po (renamed from tools/editor/translations/bn.po) | 0 | ||||
-rw-r--r-- | editor/translations/ca.po (renamed from tools/editor/translations/ca.po) | 0 | ||||
-rw-r--r-- | editor/translations/cs.po (renamed from tools/editor/translations/cs.po) | 0 | ||||
-rw-r--r-- | editor/translations/da.po (renamed from tools/editor/translations/da.po) | 0 | ||||
-rw-r--r-- | editor/translations/de.po (renamed from tools/editor/translations/de.po) | 0 | ||||
-rw-r--r-- | editor/translations/de_CH.po (renamed from tools/editor/translations/de_CH.po) | 0 | ||||
-rw-r--r-- | editor/translations/editor.pot (renamed from tools/editor/translations/tools.pot) | 0 | ||||
-rw-r--r-- | editor/translations/es.po (renamed from tools/editor/translations/es.po) | 0 | ||||
-rw-r--r-- | editor/translations/es_AR.po (renamed from tools/editor/translations/es_AR.po) | 0 | ||||
-rwxr-xr-x | editor/translations/extract.py | 121 | ||||
-rw-r--r-- | editor/translations/fa.po (renamed from tools/editor/translations/fa.po) | 0 | ||||
-rw-r--r-- | editor/translations/fr.po (renamed from tools/editor/translations/fr.po) | 0 | ||||
-rw-r--r-- | editor/translations/hu.po (renamed from tools/editor/translations/hu.po) | 0 | ||||
-rw-r--r-- | editor/translations/id.po (renamed from tools/editor/translations/id.po) | 0 | ||||
-rw-r--r-- | editor/translations/it.po (renamed from tools/editor/translations/it.po) | 0 | ||||
-rw-r--r-- | editor/translations/ja.po (renamed from tools/editor/translations/ja.po) | 0 | ||||
-rw-r--r-- | editor/translations/ko.po (renamed from tools/editor/translations/ko.po) | 0 | ||||
-rw-r--r-- | editor/translations/nb.po (renamed from tools/editor/translations/nb.po) | 0 | ||||
-rw-r--r-- | editor/translations/pl.po (renamed from tools/editor/translations/pl.po) | 0 | ||||
-rw-r--r-- | editor/translations/pr.po (renamed from tools/editor/translations/pr.po) | 0 | ||||
-rw-r--r-- | editor/translations/pt_BR.po (renamed from tools/editor/translations/pt_BR.po) | 0 | ||||
-rw-r--r-- | editor/translations/pt_PT.po (renamed from tools/editor/translations/pt_PT.po) | 0 | ||||
-rw-r--r-- | editor/translations/ru.po (renamed from tools/editor/translations/ru.po) | 0 | ||||
-rw-r--r-- | editor/translations/sk.po (renamed from tools/editor/translations/sk.po) | 0 | ||||
-rw-r--r-- | editor/translations/sl.po (renamed from tools/editor/translations/sl.po) | 0 | ||||
-rw-r--r-- | editor/translations/tr.po (renamed from tools/editor/translations/tr.po) | 0 | ||||
-rw-r--r-- | editor/translations/ur_PK.po (renamed from tools/editor/translations/ur_PK.po) | 0 | ||||
-rw-r--r-- | editor/translations/zh_CN.po (renamed from tools/editor/translations/zh_CN.po) | 0 | ||||
-rw-r--r-- | editor/translations/zh_HK.po (renamed from tools/editor/translations/zh_HK.po) | 0 | ||||
-rw-r--r-- | editor/translations/zh_TW.po (renamed from tools/editor/translations/zh_TW.po) | 0 | ||||
-rw-r--r-- | main/main.cpp | 6 | ||||
-rw-r--r-- | modules/gdscript/register_types.cpp | 6 | ||||
-rw-r--r-- | modules/gridmap/grid_map_editor_plugin.cpp | 4 | ||||
-rw-r--r-- | modules/gridmap/grid_map_editor_plugin.h | 6 | ||||
-rw-r--r-- | modules/visual_script/visual_script_editor.cpp | 4 | ||||
-rw-r--r-- | modules/visual_script/visual_script_editor.h | 8 | ||||
-rw-r--r-- | platform/android/export/export.cpp | 6 | ||||
-rw-r--r-- | platform/bb10/export/export.cpp | 6 | ||||
-rw-r--r-- | platform/javascript/export/export.cpp | 6 | ||||
-rw-r--r-- | platform/osx/export/export.cpp | 6 | ||||
-rw-r--r-- | platform/uwp/export/export.cpp | 4 | ||||
-rw-r--r-- | platform/windows/export/export.cpp | 2 | ||||
-rw-r--r-- | platform/x11/export/export.cpp | 2 | ||||
-rw-r--r-- | scene/gui/control.cpp | 2 | ||||
-rw-r--r-- | scene/gui/line_edit.cpp | 2 | ||||
-rw-r--r-- | tools/editor/SCsub | 205 | ||||
-rw-r--r-- | tools/editor/animation_editor.cpp | 4331 | ||||
-rw-r--r-- | tools/editor/call_dialog.h | 85 | ||||
-rw-r--r-- | tools/editor/code_editor.cpp | 1323 | ||||
-rw-r--r-- | tools/editor/code_editor.h | 261 | ||||
-rw-r--r-- | tools/editor/connections_dialog.h | 134 | ||||
-rw-r--r-- | tools/editor/editor_audio_buses.h | 186 | ||||
-rw-r--r-- | tools/editor/editor_data.h | 269 | ||||
-rw-r--r-- | tools/editor/editor_dir_dialog.cpp | 276 | ||||
-rw-r--r-- | tools/editor/editor_export.cpp | 3231 | ||||
-rw-r--r-- | tools/editor/editor_help.cpp | 1929 | ||||
-rw-r--r-- | tools/editor/editor_help.h | 222 | ||||
-rw-r--r-- | tools/editor/editor_node.h | 833 | ||||
-rw-r--r-- | tools/editor/editor_plugin.cpp | 432 | ||||
-rw-r--r-- | tools/editor/editor_sub_scene.h | 69 | ||||
-rw-r--r-- | tools/editor/icons/SCsub | 96 | ||||
-rw-r--r-- | tools/editor/import/editor_import_collada.cpp | 2508 | ||||
-rw-r--r-- | tools/editor/import/editor_import_collada.h | 51 | ||||
-rw-r--r-- | tools/editor/import/resource_importer_scene.cpp | 1328 | ||||
-rw-r--r-- | tools/editor/import/resource_importer_texture.cpp | 393 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_bitmask_import_plugin.cpp | 387 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_bitmask_import_plugin.h | 70 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_export_scene.cpp | 142 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_export_scene.h | 44 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_font_import_plugin.cpp | 1704 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_font_import_plugin.h | 58 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_mesh_import_plugin.cpp | 593 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_mesh_import_plugin.h | 59 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_sample_import_plugin.cpp | 929 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_sample_import_plugin.h | 74 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_scene_import_plugin.cpp | 2992 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_scene_import_plugin.h | 200 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_scene_importer_fbxconv.cpp | 1136 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_scene_importer_fbxconv.h | 111 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_texture_import_plugin.cpp | 1893 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_texture_import_plugin.h | 179 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_translation_import_plugin.cpp | 479 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_translation_import_plugin.h | 56 | ||||
-rw-r--r-- | tools/editor/plugins/animation_player_editor_plugin.cpp | 1604 | ||||
-rw-r--r-- | tools/editor/plugins/animation_player_editor_plugin.h | 219 | ||||
-rw-r--r-- | tools/editor/plugins/animation_tree_editor_plugin.h | 194 | ||||
-rw-r--r-- | tools/editor/plugins/baked_light_baker.cpp | 2731 | ||||
-rw-r--r-- | tools/editor/plugins/baked_light_editor_plugin.h | 120 | ||||
-rw-r--r-- | tools/editor/plugins/camera_editor_plugin.h | 79 | ||||
-rw-r--r-- | tools/editor/plugins/canvas_item_editor_plugin.cpp | 4063 | ||||
-rw-r--r-- | tools/editor/plugins/canvas_item_editor_plugin.h | 503 | ||||
-rw-r--r-- | tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp | 482 | ||||
-rw-r--r-- | tools/editor/plugins/collision_polygon_2d_editor_plugin.h | 111 | ||||
-rw-r--r-- | tools/editor/plugins/collision_polygon_editor_plugin.cpp | 648 | ||||
-rw-r--r-- | tools/editor/plugins/collision_polygon_editor_plugin.h | 123 | ||||
-rw-r--r-- | tools/editor/plugins/collision_shape_2d_editor_plugin.h | 101 | ||||
-rw-r--r-- | tools/editor/plugins/color_ramp_editor_plugin.h | 62 | ||||
-rw-r--r-- | tools/editor/plugins/cube_grid_theme_editor_plugin.cpp | 357 | ||||
-rw-r--r-- | tools/editor/plugins/cube_grid_theme_editor_plugin.h | 96 | ||||
-rw-r--r-- | tools/editor/plugins/editor_preview_plugins.cpp | 907 | ||||
-rw-r--r-- | tools/editor/plugins/editor_preview_plugins.h | 128 | ||||
-rw-r--r-- | tools/editor/plugins/gi_probe_editor_plugin.h | 65 | ||||
-rw-r--r-- | tools/editor/plugins/item_list_editor_plugin.h | 230 | ||||
-rw-r--r-- | tools/editor/plugins/light_occluder_2d_editor_plugin.cpp | 518 | ||||
-rw-r--r-- | tools/editor/plugins/light_occluder_2d_editor_plugin.h | 115 | ||||
-rw-r--r-- | tools/editor/plugins/line_2d_editor_plugin.cpp | 283 | ||||
-rw-r--r-- | tools/editor/plugins/line_2d_editor_plugin.h | 90 | ||||
-rw-r--r-- | tools/editor/plugins/material_editor_plugin.h | 100 | ||||
-rw-r--r-- | tools/editor/plugins/mesh_editor_plugin.h | 98 | ||||
-rw-r--r-- | tools/editor/plugins/mesh_instance_editor_plugin.h | 97 | ||||
-rw-r--r-- | tools/editor/plugins/multimesh_editor_plugin.h | 107 | ||||
-rw-r--r-- | tools/editor/plugins/navigation_polygon_editor_plugin.cpp | 566 | ||||
-rw-r--r-- | tools/editor/plugins/navigation_polygon_editor_plugin.h | 118 | ||||
-rw-r--r-- | tools/editor/plugins/particles_2d_editor_plugin.h | 82 | ||||
-rw-r--r-- | tools/editor/plugins/particles_editor_plugin.cpp | 461 | ||||
-rw-r--r-- | tools/editor/plugins/particles_editor_plugin.h | 116 | ||||
-rw-r--r-- | tools/editor/plugins/path_2d_editor_plugin.cpp | 718 | ||||
-rw-r--r-- | tools/editor/plugins/path_2d_editor_plugin.h | 126 | ||||
-rw-r--r-- | tools/editor/plugins/path_editor_plugin.h | 100 | ||||
-rw-r--r-- | tools/editor/plugins/polygon_2d_editor_plugin.cpp | 1028 | ||||
-rw-r--r-- | tools/editor/plugins/polygon_2d_editor_plugin.h | 167 | ||||
-rw-r--r-- | tools/editor/plugins/resource_preloader_editor_plugin.cpp | 507 | ||||
-rw-r--r-- | tools/editor/plugins/resource_preloader_editor_plugin.h | 108 | ||||
-rw-r--r-- | tools/editor/plugins/rich_text_editor_plugin.h | 91 | ||||
-rw-r--r-- | tools/editor/plugins/sample_editor_plugin.cpp | 451 | ||||
-rw-r--r-- | tools/editor/plugins/sample_editor_plugin.h | 92 | ||||
-rw-r--r-- | tools/editor/plugins/sample_library_editor_plugin.cpp | 546 | ||||
-rw-r--r-- | tools/editor/plugins/sample_library_editor_plugin.h | 108 | ||||
-rw-r--r-- | tools/editor/plugins/sample_player_editor_plugin.h | 90 | ||||
-rw-r--r-- | tools/editor/plugins/script_editor_plugin.cpp | 2491 | ||||
-rw-r--r-- | tools/editor/plugins/script_editor_plugin.h | 394 | ||||
-rw-r--r-- | tools/editor/plugins/script_text_editor.cpp | 1401 | ||||
-rw-r--r-- | tools/editor/plugins/shader_editor_plugin.cpp | 584 | ||||
-rw-r--r-- | tools/editor/plugins/shader_editor_plugin.h | 156 | ||||
-rw-r--r-- | tools/editor/plugins/shader_graph_editor_plugin.h | 242 | ||||
-rw-r--r-- | tools/editor/plugins/spatial_editor_plugin.cpp | 4131 | ||||
-rw-r--r-- | tools/editor/plugins/spatial_editor_plugin.h | 574 | ||||
-rw-r--r-- | tools/editor/plugins/sprite_frames_editor_plugin.cpp | 969 | ||||
-rw-r--r-- | tools/editor/plugins/sprite_frames_editor_plugin.h | 138 | ||||
-rw-r--r-- | tools/editor/plugins/stream_editor_plugin.h | 84 | ||||
-rw-r--r-- | tools/editor/plugins/style_box_editor_plugin.h | 83 | ||||
-rw-r--r-- | tools/editor/plugins/texture_editor_plugin.cpp | 169 | ||||
-rw-r--r-- | tools/editor/plugins/texture_editor_plugin.h | 77 | ||||
-rw-r--r-- | tools/editor/plugins/texture_region_editor_plugin.h | 153 | ||||
-rw-r--r-- | tools/editor/plugins/theme_editor_plugin.h | 125 | ||||
-rw-r--r-- | tools/editor/plugins/tile_map_editor_plugin.cpp | 1593 | ||||
-rw-r--r-- | tools/editor/plugins/tile_map_editor_plugin.h | 207 | ||||
-rw-r--r-- | tools/editor/plugins/tile_set_editor_plugin.h | 101 | ||||
-rw-r--r-- | tools/editor/project_export.h | 142 | ||||
-rw-r--r-- | tools/editor/project_manager.h | 148 | ||||
-rw-r--r-- | tools/editor/property_editor.h | 352 | ||||
-rw-r--r-- | tools/editor/property_selector.h | 83 | ||||
-rw-r--r-- | tools/editor/reparent_dialog.h | 68 | ||||
-rw-r--r-- | tools/editor/scene_tree_dock.cpp | 2061 | ||||
-rw-r--r-- | tools/editor/scene_tree_editor.cpp | 1316 | ||||
-rw-r--r-- | tools/editor/script_create_dialog.h | 79 | ||||
-rw-r--r-- | tools/editor/spatial_editor_gizmos.h | 521 | ||||
-rw-r--r-- | tools/editor/translations/Makefile | 20 | ||||
-rwxr-xr-x | tools/editor/translations/extract.py | 121 |
2143 files changed, 67600 insertions, 67600 deletions
diff --git a/.gitignore b/.gitignore index 8ab969c9a4..cdf277dd71 100644 --- a/.gitignore +++ b/.gitignore @@ -16,12 +16,12 @@ core/method_bind_ext.inc core/script_encryption_key.cpp core/global_defaults.cpp drivers/unix/os_unix_global_settings_path.cpp -tools/editor/register_exporters.cpp -tools/editor/doc_data_compressed.h -tools/editor/certs_compressed.h -tools/editor/editor_icons.cpp -tools/editor/translations.h -tools/editor/builtin_fonts.h +editor/register_exporters.cpp +editor/doc_data_compressed.h +editor/certs_compressed.h +editor/editor_icons.cpp +editor/translations.h +editor/builtin_fonts.h .fscache make.bat log.txt diff --git a/SConstruct b/SConstruct index 4c79304ef2..2e7683d17a 100644 --- a/SConstruct +++ b/SConstruct @@ -179,7 +179,7 @@ Help(opts.GenerateHelpText(env_base)) # generate help # add default include paths -env_base.Append(CPPPATH=['#core', '#core/math', '#tools', '#drivers', '#']) +env_base.Append(CPPPATH=['#core', '#core/math', '#editor', '#drivers', '#']) # configure ENV for platform env_base.platform_exporters = platform_exporters @@ -358,7 +358,7 @@ if selected_platform in platform_list: SConscript("core/SCsub") SConscript("servers/SCsub") SConscript("scene/SCsub") - SConscript("tools/editor/SCsub") + SConscript("editor/SCsub") SConscript("drivers/SCsub") SConscript("modules/SCsub") diff --git a/editor/SCsub b/editor/SCsub new file mode 100644 index 0000000000..d7392f8249 --- /dev/null +++ b/editor/SCsub @@ -0,0 +1,205 @@ +#!/usr/bin/env python + +Import('env') +env.editor_sources = [] + +import os + + +def make_certs_header(target, source, env): + + src = source[0].srcnode().abspath + dst = target[0].srcnode().abspath + f = open(src, "rb") + g = open(dst, "wb") + buf = f.read() + decomp_size = len(buf) + import zlib + buf = zlib.compress(buf) + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _CERTS_RAW_H\n") + g.write("#define _CERTS_RAW_H\n") + g.write("static const int _certs_compressed_size=" + str(len(buf)) + ";\n") + g.write("static const int _certs_uncompressed_size=" + str(decomp_size) + ";\n") + g.write("static const unsigned char _certs_compressed[]={\n") + for i in range(len(buf)): + g.write(str(ord(buf[i])) + ",\n") + g.write("};\n") + g.write("#endif") + + +def make_doc_header(target, source, env): + + dst = target[0].srcnode().abspath + g = open(dst, "wb") + buf = "" + docbegin = "" + docend = "" + for s in source: + src = s.srcnode().abspath + f = open(src, "rb") + content = f.read() + buf += content[content.find("<class"): content.rfind("</doc>")] + if len(docbegin) == 0: + docbegin = content[0: content.find("<class")] + if len(docend) == 0: + docend = content[content.rfind("</doc>"): len(buf)] + buf = docbegin + buf + docend + decomp_size = len(buf) + import zlib + buf = zlib.compress(buf) + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _DOC_DATA_RAW_H\n") + g.write("#define _DOC_DATA_RAW_H\n") + g.write("static const int _doc_data_compressed_size=" + str(len(buf)) + ";\n") + g.write("static const int _doc_data_uncompressed_size=" + str(decomp_size) + ";\n") + g.write("static const unsigned char _doc_data_compressed[]={\n") + for i in range(len(buf)): + g.write(str(ord(buf[i])) + ",\n") + g.write("};\n") + g.write("#endif") + + +def make_fonts_header(target, source, env): + + dst = target[0].srcnode().abspath + + g = open(dst, "wb") + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _EDITOR_FONTS_H\n") + g.write("#define _EDITOR_FONTS_H\n") + + # saving uncompressed, since freetype will reference from memory pointer + xl_names = [] + for i in range(len(source)): + print("Appending font: " + source[i].srcnode().abspath) + f = open(source[i].srcnode().abspath, "rb") + buf = f.read() + import os.path + + name = os.path.splitext(os.path.basename(source[i].srcnode().abspath))[0] + + g.write("static const int _font_" + name + "_size=" + str(len(buf)) + ";\n") + g.write("static const unsigned char _font_" + name + "[]={\n") + for i in range(len(buf)): + g.write(str(ord(buf[i])) + ",\n") + + g.write("};\n") + + g.write("#endif") + + +def make_translations_header(target, source, env): + + dst = target[0].srcnode().abspath + + g = open(dst, "wb") + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _EDITOR_TRANSLATIONS_H\n") + g.write("#define _EDITOR_TRANSLATIONS_H\n") + + import zlib + import os.path + + paths = [node.srcnode().abspath for node in source] + sorted_paths = sorted(paths, key=lambda path: os.path.splitext(os.path.basename(path))[0]) + + xl_names = [] + for i in range(len(sorted_paths)): + print("Appending translation: " + sorted_paths[i]) + f = open(sorted_paths[i], "rb") + buf = f.read() + decomp_size = len(buf) + buf = zlib.compress(buf) + name = os.path.splitext(os.path.basename(sorted_paths[i]))[0] + + #g.write("static const int _translation_"+name+"_compressed_size="+str(len(buf))+";\n") + #g.write("static const int _translation_"+name+"_uncompressed_size="+str(decomp_size)+";\n") + g.write("static const unsigned char _translation_" + name + "_compressed[]={\n") + for i in range(len(buf)): + g.write(str(ord(buf[i])) + ",\n") + + g.write("};\n") + + xl_names.append([name, len(buf), str(decomp_size)]) + + g.write("struct EditorTranslationList {\n") + g.write("\tconst char* lang;\n") + g.write("\tint comp_size;\n") + g.write("\tint uncomp_size;\n") + g.write("\tconst unsigned char* data;\n") + g.write("};\n\n") + g.write("static EditorTranslationList _editor_translations[]={\n") + for x in xl_names: + g.write("\t{ \"" + x[0] + "\", " + str(x[1]) + ", " + str(x[2]) + ",_translation_" + x[0] + "_compressed},\n") + g.write("\t{NULL,0,0,NULL}\n") + g.write("};\n") + + g.write("#endif") + + +if (env["tools"] == "yes"): + + # Register exporters + reg_exporters_inc = '#include "register_exporters.h"\n' + reg_exporters = 'void register_exporters() {\n' + for e in env.platform_exporters: + env.editor_sources.append("#platform/" + e + "/export/export.cpp") + reg_exporters += '\tregister_' + e + '_exporter();\n' + reg_exporters_inc += '#include "platform/' + e + '/export/export.h"\n' + reg_exporters += '}\n' + f = open("register_exporters.cpp", "wb") + f.write(reg_exporters_inc) + f.write(reg_exporters) + f.close() + + # API documentation + docs = ["#doc/base/classes.xml"] + moduledir = os.path.join(os.getcwd(), "..", "modules") + for m in os.listdir(moduledir): + curmodle = os.path.join(moduledir, m) + docfile = os.path.join(curmodle, "classes.xml") + if os.path.isdir(curmodle) and os.path.isfile(docfile): + docs.append(docfile) + env.Depends("#editor/doc_data_compressed.h", docs) + env.Command("#editor/doc_data_compressed.h", docs, make_doc_header) + + # Certificates + env.Depends("#editor/certs_compressed.h", "#thirdparty/certs/ca-certificates.crt") + env.Command("#editor/certs_compressed.h", "#thirdparty/certs/ca-certificates.crt", make_certs_header) + + import glob + path = env.Dir('.').abspath + + # Translations + tlist = glob.glob(path + "/translations/*.po") + print("translations: ", tlist) + env.Depends('#editor/translations.h', tlist) + env.Command('#editor/translations.h', tlist, make_translations_header) + + # Fonts + flist = glob.glob(path + "/../thirdparty/fonts/*.ttf") + flist.append(glob.glob(path + "/../thirdparty/fonts/*.otf")) + print("fonts: ", flist) + env.Depends('#editor/builtin_fonts.h', flist) + env.Command('#editor/builtin_fonts.h', flist, make_fonts_header) + + + env.add_source_files(env.editor_sources, "*.cpp") + + SConscript('collada/SCsub') + SConscript('doc/SCsub') + SConscript('fileserver/SCsub') + SConscript('icons/SCsub') + SConscript('import/SCsub') + SConscript('io_plugins/SCsub') + SConscript('plugins/SCsub') + + lib = env.Library("editor", env.editor_sources) + env.Prepend(LIBS=[lib]) + + Export('env') diff --git a/editor/animation_editor.cpp b/editor/animation_editor.cpp new file mode 100644 index 0000000000..d65f229fca --- /dev/null +++ b/editor/animation_editor.cpp @@ -0,0 +1,4331 @@ +/*************************************************************************/ +/* animation_editor.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 "animation_editor.h" + +#include "editor_settings.h" +#include "os/keyboard.h" +#include "os/os.h" +#include "io/resource_saver.h" +#include "pair.h" +#include "scene/gui/separator.h" +#include "editor_node.h" +#include "editor/plugins/animation_player_editor_plugin.h" +#include "scene/main/viewport.h" +/* Missing to fix: + + *Set + *Find better source for hint for edited value keys + * + button on track to add a key + * when clicked for first time, erase selection of not selected at first + * automatically create discrete/continuous tracks!! + *when create track do undo/redo +*/ + + +class AnimationCurveEdit : public Control { + GDCLASS( AnimationCurveEdit, Control ); +public: + enum Mode { + MODE_DISABLED, + MODE_SINGLE, + MODE_MULTIPLE + }; +private: + + Set<float> multiples; + float transition; + Mode mode; + + void _notification(int p_what) { + + if (p_what==NOTIFICATION_DRAW) { + + + RID ci = get_canvas_item(); + + Size2 s = get_size(); + Rect2 r(Point2(),s); + + //r=r.grow(3); + Ref<StyleBox> sb = get_stylebox("normal","LineEdit"); + sb->draw(ci,r); + r.size-=sb->get_minimum_size(); + r.pos+=sb->get_offset(); + //VisualServer::get_singleton()->canvas_item_add + + Ref<Font> f = get_font("font","Label"); + r=r.grow(-2); + Color color = get_color("font_color","Label"); + + int points = 48; + if (mode==MODE_MULTIPLE) { + + Color mcolor=color; + mcolor.a*=0.3; + + Set<float>::Element *E=multiples.front(); + for(int j=0;j<16;j++) { + + if (!E) + break; + + float prev=1.0; + float exp=E->get(); + bool flip=false;//hint_text=="attenuation"; + + + for(int i=1;i<=points;i++) { + + float ifl = i/float(points); + float iflp = (i-1)/float(points); + + float h = 1.0-Math::ease(ifl,exp); + + if (flip) { + ifl=1.0-ifl; + iflp=1.0-iflp; + } + + VisualServer::get_singleton()->canvas_item_add_line(ci,r.pos+Point2(iflp*r.size.width,prev*r.size.height),r.pos+Point2(ifl*r.size.width,h*r.size.height),mcolor); + prev=h; + } + + E=E->next(); + } + } + + float exp=transition; + if (mode!=MODE_DISABLED) { + + + float prev=1.0; + + bool flip=false;//hint_text=="attenuation"; + + + for(int i=1;i<=points;i++) { + + float ifl = i/float(points); + float iflp = (i-1)/float(points); + + float h = 1.0-Math::ease(ifl,exp); + + if (flip) { + ifl=1.0-ifl; + iflp=1.0-iflp; + } + + VisualServer::get_singleton()->canvas_item_add_line(ci,r.pos+Point2(iflp*r.size.width,prev*r.size.height),r.pos+Point2(ifl*r.size.width,h*r.size.height),color); + prev=h; + } + } + + String txt=String::num(exp,2); + if (mode==MODE_DISABLED) { + txt=TTR("Disabled"); + } else if (mode==MODE_MULTIPLE) { + txt+=" - "+TTR("All Selection"); + } + + f->draw(ci,Point2(10,10+f->get_ascent()),txt,color); + + } + } + + void _gui_input(const InputEvent& p_ev) { + if (p_ev.type==InputEvent::MOUSE_MOTION && p_ev.mouse_motion.button_mask&BUTTON_MASK_LEFT) { + + if (mode==MODE_DISABLED) + return; + + float rel = p_ev.mouse_motion.relative_x; + if (rel==0) + return; + + bool flip=false; + + if (flip) + rel=-rel; + + float val = transition; + if (val==0) + return; + bool sg = val < 0; + val = Math::absf(val); + + val = Math::log(val)/Math::log((float)2.0); + //logspace + val+=rel*0.05; + // + + val = Math::pow((float)2.0,val); + if (sg) + val=-val; + + transition=val; + update(); + //emit_signal("variant_changed"); + emit_signal("transition_changed",transition); + } + } + +public: + + static void _bind_methods() { + + //ClassDB::bind_method("_update_obj",&AnimationKeyEdit::_update_obj); + ClassDB::bind_method("_gui_input",&AnimationCurveEdit::_gui_input); + ADD_SIGNAL(MethodInfo("transition_changed")); + } + + void set_mode(Mode p_mode) { + + mode=p_mode; + update(); + } + + void clear_multiples() { multiples.clear(); update();} + void set_multiple(float p_transition) { + + multiples.insert(p_transition); + } + + void set_transition(float p_transition) { + transition=p_transition; + update(); + } + + float get_transition() const { + return transition; + } + + void force_transition(float p_value) { + if (mode==MODE_DISABLED) + return; + transition=p_value; + emit_signal("transition_changed",p_value); + update(); + } + + AnimationCurveEdit() { + + transition=1.0; + set_default_cursor_shape(CURSOR_HSPLIT); + mode=MODE_DISABLED; + } + +}; + +class AnimationKeyEdit : public Object { + + GDCLASS(AnimationKeyEdit,Object); +public: + bool setting; + bool hidden; + + static void _bind_methods() { + + ClassDB::bind_method("_update_obj",&AnimationKeyEdit::_update_obj); + ClassDB::bind_method("_key_ofs_changed",&AnimationKeyEdit::_key_ofs_changed); + } + + //PopupDialog *ke_dialog; + + void _fix_node_path(Variant &value) { + + + NodePath np=value; + + if (np==NodePath()) + return; + + Node* root = EditorNode::get_singleton()->get_tree()->get_root(); + + Node* np_node = root->get_node(np); + ERR_FAIL_COND(!np_node); + + Node* edited_node = root->get_node(base); + ERR_FAIL_COND(!edited_node); + + + + value = edited_node->get_path_to(np_node); + } + + + void _update_obj(const Ref<Animation> &p_anim) { + if (setting) + return; + if (hidden) + return; + if (!(animation==p_anim)) + return; + notify_change(); + } + + void _key_ofs_changed(const Ref<Animation> &p_anim,float from, float to) { + if (hidden) + return; + if (!(animation==p_anim)) + return; + if (from!=key_ofs) + return; + key_ofs=to; + if (setting) + return; + notify_change(); + } + + bool _set(const StringName& p_name, const Variant& p_value) { + + int key = animation->track_find_key(track,key_ofs,true); + ERR_FAIL_COND_V(key==-1,false); + + String name=p_name; + if (name=="time") { + + float new_time = p_value; + if (new_time==key_ofs) + return true; + + int existing = animation->track_find_key(track,new_time,true); + + setting=true; + undo_redo->create_action(TTR("Move Add Key"),UndoRedo::MERGE_ENDS); + + Variant val = animation->track_get_key_value(track,key); + float trans = animation->track_get_key_transition(track,key); + + undo_redo->add_do_method(animation.ptr(),"track_remove_key",track,key); + undo_redo->add_do_method(animation.ptr(),"track_insert_key",track,new_time,val,trans); + undo_redo->add_do_method(this,"_key_ofs_changed",animation,key_ofs,new_time); + undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",track,new_time); + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",track,key_ofs,val,trans); + undo_redo->add_undo_method(this,"_key_ofs_changed",animation,new_time,key_ofs); + + + if (existing!=-1) { + Variant v = animation->track_get_key_value(track,existing); + float trans = animation->track_get_key_transition(track,existing); + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",track,new_time,v,trans); + } + + undo_redo->commit_action(); + setting=false; + + return true; + } else if (name=="easing") { + + float val = p_value; + float prev_val = animation->track_get_key_transition(track,key); + setting=true; + undo_redo->create_action(TTR("Anim Change Transition"),UndoRedo::MERGE_ENDS); + undo_redo->add_do_method(animation.ptr(),"track_set_key_transition",track,key,val); + undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",track,key,prev_val); + undo_redo->add_do_method(this,"_update_obj",animation); + undo_redo->add_undo_method(this,"_update_obj",animation); + undo_redo->commit_action(); + setting=false; + return true; + } + + + + switch(animation->track_get_type(track)) { + + + case Animation::TYPE_TRANSFORM: { + + Dictionary d_old = animation->track_get_key_value(track,key); + Dictionary d_new = d_old; + d_new[p_name]=p_value; + setting=true; + undo_redo->create_action(TTR("Anim Change Transform")); + undo_redo->add_do_method(animation.ptr(),"track_set_key_value",track,key,d_new); + undo_redo->add_undo_method(animation.ptr(),"track_set_key_value",track,key,d_old); + undo_redo->add_do_method(this,"_update_obj",animation); + undo_redo->add_undo_method(this,"_update_obj",animation); + undo_redo->commit_action(); + setting=false; + return true; + + } break; + case Animation::TYPE_VALUE: { + + if (name=="value") { + + Variant value = p_value; + + if (value.get_type()==Variant::NODE_PATH) { + + _fix_node_path(value); + } + + setting=true; + undo_redo->create_action(TTR("Anim Change Value"),UndoRedo::MERGE_ENDS); + Variant prev = animation->track_get_key_value(track,key); + undo_redo->add_do_method(animation.ptr(),"track_set_key_value",track,key,value); + undo_redo->add_undo_method(animation.ptr(),"track_set_key_value",track,key,prev); + undo_redo->add_do_method(this,"_update_obj",animation); + undo_redo->add_undo_method(this,"_update_obj",animation); + undo_redo->commit_action(); + setting=false; + return true; + } + + + + } break; + case Animation::TYPE_METHOD: { + + Dictionary d_old = animation->track_get_key_value(track,key); + Dictionary d_new = d_old; + + bool change_notify_deserved=false; + bool mergeable=false; + + if (name=="name") { + + d_new["method"]=p_value; + + } + + if (name=="arg_count") { + + Vector<Variant> args = d_old["args"]; + args.resize(p_value); + d_new["args"]=args; + change_notify_deserved=true; + } + + if (name.begins_with("args/")) { + + + Vector<Variant> args = d_old["args"]; + int idx = name.get_slice("/",1).to_int(); + ERR_FAIL_INDEX_V(idx,args.size(),false); + + String what = name.get_slice("/",2); + if (what=="type") { + Variant::Type t = Variant::Type(int(p_value)); + + if (t!=args[idx].get_type()) { + Variant::CallError err; + if (Variant::can_convert(args[idx].get_type(),t)) { + Variant old=args[idx]; + Variant *ptrs[1]={&old}; + args[idx]=Variant::construct(t,(const Variant**)ptrs,1,err); + } else { + + args[idx]=Variant::construct(t,NULL,0,err); + } + change_notify_deserved=true; + d_new["args"]=args; + } + + } + if (what=="value") { + + Variant value=p_value; + if (value.get_type()==Variant::NODE_PATH) { + + _fix_node_path(value); + } + + args[idx]=value; + d_new["args"]=args; + mergeable=true; + } + } + + if (mergeable) + undo_redo->create_action(TTR("Anim Change Call"),UndoRedo::MERGE_ENDS); + else + undo_redo->create_action(TTR("Anim Change Call")); + + Variant prev = animation->track_get_key_value(track,key); + setting=true; + undo_redo->add_do_method(animation.ptr(),"track_set_key_value",track,key,d_new); + undo_redo->add_undo_method(animation.ptr(),"track_set_key_value",track,key,d_old); + undo_redo->add_do_method(this,"_update_obj",animation); + undo_redo->add_undo_method(this,"_update_obj",animation); + undo_redo->commit_action(); + setting=false; + if (change_notify_deserved) + notify_change(); + return true; + } break; + } + + + + return false; + + } + + bool _get(const StringName& p_name,Variant &r_ret) const { + + int key = animation->track_find_key(track,key_ofs,true); + ERR_FAIL_COND_V(key==-1,false); + + String name=p_name; + if (name=="time") { + r_ret = key_ofs; + return true; + } else if (name=="easing") { + r_ret = animation->track_get_key_transition(track,key); + return true; + } + + + + switch(animation->track_get_type(track)) { + + + case Animation::TYPE_TRANSFORM: { + + Dictionary d = animation->track_get_key_value(track,key); + ERR_FAIL_COND_V(!d.has(name),false); + r_ret = d[p_name]; + return true; + + } break; + case Animation::TYPE_VALUE: { + + if (name=="value") { + r_ret = animation->track_get_key_value(track,key); + return true; + } + + + + } break; + case Animation::TYPE_METHOD: { + + Dictionary d = animation->track_get_key_value(track,key); + + if (name=="name") { + + ERR_FAIL_COND_V(!d.has("method"),false); + r_ret=d["method"]; + return true; + } + + ERR_FAIL_COND_V(!d.has("args"),false); + + Vector<Variant> args = d["args"]; + + + if (name=="arg_count") { + + r_ret=args.size(); + return true; + } + + + if (name.begins_with("args/")) { + + int idx = name.get_slice("/",1).to_int(); + ERR_FAIL_INDEX_V(idx,args.size(),false); + + String what = name.get_slice("/",2); + if (what=="type") { + r_ret=args[idx].get_type(); + return true; + } + if (what=="value") { + r_ret=args[idx]; + return true; + } + } + + } break; + } + + return false; + } + void _get_property_list( List<PropertyInfo> *p_list) const { + + if (animation.is_null()) + return; + + ERR_FAIL_INDEX(track,animation->get_track_count()); + int key = animation->track_find_key(track,key_ofs,true); + ERR_FAIL_COND(key==-1); + + p_list->push_back( PropertyInfo( Variant::REAL, "time", PROPERTY_HINT_RANGE,"0,"+rtos(animation->get_length())+",0.01") ); + + switch(animation->track_get_type(track)) { + + + case Animation::TYPE_TRANSFORM: { + + p_list->push_back( PropertyInfo( Variant::VECTOR3, "loc")); + p_list->push_back( PropertyInfo( Variant::QUAT, "rot")); + p_list->push_back( PropertyInfo( Variant::VECTOR3, "scale")); + + } break; + case Animation::TYPE_VALUE: { + + Variant v = animation->track_get_key_value(track,key); + + + + if (hint.type!=Variant::NIL) { + + PropertyInfo pi=hint; + pi.name="value"; + p_list->push_back( pi ); + } else { + + PropertyHint hint= PROPERTY_HINT_NONE; + String hint_string; + + if (v.get_type()==Variant::OBJECT) { + //could actually check the object property if exists..? yes i will! + Ref<Resource> res = v; + if (res.is_valid()) { + + hint=PROPERTY_HINT_RESOURCE_TYPE; + hint_string=res->get_class(); + } + } + + if (v.get_type()!=Variant::NIL) + p_list->push_back( PropertyInfo( v.get_type(), "value", hint,hint_string)); + } + + } break; + case Animation::TYPE_METHOD: { + + p_list->push_back( PropertyInfo( Variant::STRING, "name")); + p_list->push_back( PropertyInfo( Variant::INT, "arg_count",PROPERTY_HINT_RANGE,"0,5,1")); + + Dictionary d = animation->track_get_key_value(track,key); + ERR_FAIL_COND(!d.has("args")); + Vector<Variant> args=d["args"]; + String vtypes; + for(int i=0;i<Variant::VARIANT_MAX;i++) { + + if (i>0) + vtypes+=","; + vtypes+=Variant::get_type_name( Variant::Type(i) ); + } + + for(int i=0;i<args.size();i++) { + + p_list->push_back( PropertyInfo( Variant::INT, "args/"+itos(i)+"/type", PROPERTY_HINT_ENUM,vtypes)); + if (args[i].get_type()!=Variant::NIL) + p_list->push_back( PropertyInfo( args[i].get_type(), "args/"+itos(i)+"/value")); + } + + } break; + } + + /* + if (animation->track_get_type(track)!=Animation::TYPE_METHOD) + p_list->push_back( PropertyInfo( Variant::REAL, "easing", PROPERTY_HINT_EXP_EASING)); + */ + } + + UndoRedo *undo_redo; + Ref<Animation> animation; + int track; + float key_ofs; + + PropertyInfo hint; + NodePath base; + + + void notify_change() { + + _change_notify(); + } + + AnimationKeyEdit() { hidden=true; key_ofs=0; track=-1; setting=false; } + +}; + + +void AnimationKeyEditor::_menu_add_track(int p_type) { + + ERR_FAIL_COND(!animation.is_valid()); + + + switch(p_type) { + + case ADD_TRACK_MENU_ADD_CALL_TRACK: { + if (root) { + call_select->popup_centered_ratio(); + break; + } + } break; + case ADD_TRACK_MENU_ADD_VALUE_TRACK: + case ADD_TRACK_MENU_ADD_TRANSFORM_TRACK: { + + undo_redo->create_action(TTR("Anim Add Track")); + undo_redo->add_do_method(animation.ptr(),"add_track",p_type); + undo_redo->add_do_method(animation.ptr(),"track_set_path",animation->get_track_count(),"."); + undo_redo->add_undo_method(animation.ptr(),"remove_track",animation->get_track_count()); + undo_redo->commit_action(); + + + } break; + } +} + +void AnimationKeyEditor::_anim_duplicate_keys(bool transpose) { + //duplicait! + if (selection.size() && animation.is_valid() && selected_track>=0 && selected_track<animation->get_track_count()) { + + int top_track=0x7FFFFFFF; + float top_time = 1e10; + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + const SelectedKey &sk = E->key(); + + float t = animation->track_get_key_time(sk.track,sk.key); + if (t<top_time) + top_time=t; + if (sk.track<top_track) + top_track=sk.track; + + } + ERR_FAIL_COND( top_track == 0x7FFFFFFF || top_time==1e10 ); + + // + + int start_track = transpose ? selected_track : top_track; + + undo_redo->create_action(TTR("Anim Duplicate Keys")); + + List<Pair<int,float> > new_selection_values; + + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + const SelectedKey &sk = E->key(); + + float t = animation->track_get_key_time(sk.track,sk.key); + + float dst_time = t+(timeline_pos - top_time); + int dst_track = sk.track + (start_track - top_track); + + if (dst_track < 0 || dst_track>= animation->get_track_count()) + continue; + + if (animation->track_get_type(dst_track) != animation->track_get_type(sk.track)) + continue; + + int existing_idx = animation->track_find_key(dst_track,dst_time,true); + + undo_redo->add_do_method(animation.ptr(),"track_insert_key",dst_track,dst_time,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); + undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",dst_track,dst_time); + + Pair<int,float> p; + p.first=dst_track; + p.second=dst_time; + new_selection_values.push_back( p ); + + if (existing_idx!=-1) { + + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",dst_track,dst_time,animation->track_get_key_value(dst_track,existing_idx),animation->track_get_key_transition(dst_track,existing_idx)); + + } + + } + + undo_redo->commit_action(); + + //reselect duplicated + + Map<SelectedKey,KeyInfo> new_selection; + for (List<Pair<int,float> >::Element *E=new_selection_values.front();E;E=E->next()) { + + int track=E->get().first; + float time = E->get().second; + + int existing_idx = animation->track_find_key(track,time,true); + + if (existing_idx==-1) + continue; + SelectedKey sk2; + sk2.track=track; + sk2.key=existing_idx; + + KeyInfo ki; + ki.pos=time; + + new_selection[sk2]=ki; + + } + + + selection=new_selection; + track_editor->update(); + _edit_if_single_selection(); + + } +} + +void AnimationKeyEditor::_menu_track(int p_type) { + + ERR_FAIL_COND(!animation.is_valid()); + + last_menu_track_opt=p_type; + switch(p_type) { + + case TRACK_MENU_SCALE: + case TRACK_MENU_SCALE_PIVOT: { + + scale_dialog->popup_centered(Size2(200,100)); + } break; + case TRACK_MENU_MOVE_UP: { + + int idx=selected_track; + if (idx>0 && idx<animation->get_track_count()) { + undo_redo->create_action(TTR("Move Anim Track Up")); + undo_redo->add_do_method(animation.ptr(),"track_move_down",idx); + undo_redo->add_undo_method(animation.ptr(),"track_move_up",idx-1); + undo_redo->commit_action(); + selected_track=idx-1; + } + + } break; + case TRACK_MENU_MOVE_DOWN: { + + + int idx=selected_track; + if (idx>=0 && idx<animation->get_track_count()-1) { + undo_redo->create_action(TTR("Move Anim Track Down")); + undo_redo->add_do_method(animation.ptr(),"track_move_up",idx); + undo_redo->add_undo_method(animation.ptr(),"track_move_down",idx+1); + undo_redo->commit_action(); + selected_track=idx+1; + } + + } break; + case TRACK_MENU_REMOVE: { + + int idx=selected_track; + if (idx>=0 && idx<animation->get_track_count()) { + undo_redo->create_action(TTR("Remove Anim Track")); + undo_redo->add_do_method(animation.ptr(),"remove_track",idx); + undo_redo->add_undo_method(animation.ptr(),"add_track",animation->track_get_type(idx),idx); + undo_redo->add_undo_method(animation.ptr(),"track_set_path",idx,animation->track_get_path(idx)); + //todo interpolation + for(int i=0;i<animation->track_get_key_count(idx);i++) { + + Variant v = animation->track_get_key_value(idx,i); + float time = animation->track_get_key_time(idx,i); + float trans = animation->track_get_key_transition(idx,i); + + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",idx,time,v); + undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",idx,i,trans); + + } + + undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_type",idx,animation->track_get_interpolation_type(idx)); + if (animation->track_get_type(idx)==Animation::TYPE_VALUE) { + undo_redo->add_undo_method(animation.ptr(),"value_track_set_update_mode",idx,animation->value_track_get_update_mode(idx)); + + } + + undo_redo->commit_action(); + } + + + } break; + case TRACK_MENU_DUPLICATE: + case TRACK_MENU_DUPLICATE_TRANSPOSE: { + + _anim_duplicate_keys(p_type==TRACK_MENU_DUPLICATE_TRANSPOSE); + } break; + case TRACK_MENU_SET_ALL_TRANS_LINEAR: + case TRACK_MENU_SET_ALL_TRANS_CONSTANT: + case TRACK_MENU_SET_ALL_TRANS_OUT: + case TRACK_MENU_SET_ALL_TRANS_IN: + case TRACK_MENU_SET_ALL_TRANS_INOUT: + case TRACK_MENU_SET_ALL_TRANS_OUTIN: { + + if (!selection.size() || !animation.is_valid()) + break; + + float t=0; + switch(p_type) { + case TRACK_MENU_SET_ALL_TRANS_LINEAR: t=1.0; break; + case TRACK_MENU_SET_ALL_TRANS_CONSTANT: t=0.0; break; + case TRACK_MENU_SET_ALL_TRANS_OUT: t=0.5; break; + case TRACK_MENU_SET_ALL_TRANS_IN: t=2.0; break; + case TRACK_MENU_SET_ALL_TRANS_INOUT: t=-0.5; break; + case TRACK_MENU_SET_ALL_TRANS_OUTIN: t=-2.0; break; + } + + undo_redo->create_action(TTR("Set Transitions to:")+" "+rtos(t)); + + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + const SelectedKey &sk = E->key(); + + undo_redo->add_do_method(animation.ptr(),"track_set_key_transition",sk.track,sk.key,t); + undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",sk.track,sk.key,animation->track_get_key_transition(sk.track,sk.key)); + + } + + undo_redo->commit_action(); + + } break; + case TRACK_MENU_NEXT_STEP: { + + if (animation.is_null()) + break; + float step = animation->get_step(); + if (step==0) + step=1; + + float pos=timeline_pos; + + pos=Math::stepify(pos+step,step); + if (pos>animation->get_length()) + pos=animation->get_length(); + timeline_pos=pos; + track_pos->update(); + emit_signal("timeline_changed",pos,true); + + } break; + case TRACK_MENU_PREV_STEP: { + if (animation.is_null()) + break; + float step = animation->get_step(); + if (step==0) + step=1; + + float pos=timeline_pos; + pos=Math::stepify(pos-step,step); + if (pos<0) + pos=0; + timeline_pos=pos; + track_pos->update(); + emit_signal("timeline_changed",pos,true); + + + } break; + + case TRACK_MENU_OPTIMIZE: { + + optimize_dialog->popup_centered(Size2(250,180)); + } break; + case TRACK_MENU_CLEAN_UP: { + + cleanup_dialog->popup_centered_minsize(Size2(300,0)); + } break; + case TRACK_MENU_CLEAN_UP_CONFIRM: { + + if (cleanup_all->is_pressed()) { + List<StringName> names; + AnimationPlayerEditor::singleton->get_player()->get_animation_list(&names); + for (List<StringName>::Element *E=names.front();E;E=E->next()) { + _cleanup_animation(AnimationPlayerEditor::singleton->get_player()->get_animation(E->get())); + } + } else { + _cleanup_animation(animation); + + } + } break; + case CURVE_SET_LINEAR: { + curve_edit->force_transition(1.0); + + } break; + case CURVE_SET_IN: { + + curve_edit->force_transition(4.0); + + } break; + case CURVE_SET_OUT: { + + curve_edit->force_transition(0.25); + } break; + case CURVE_SET_INOUT: { + curve_edit->force_transition(-4); + + } break; + case CURVE_SET_OUTIN: { + + curve_edit->force_transition(-0.25); + } break; + case CURVE_SET_CONSTANT: { + + curve_edit->force_transition(0); + } break; + + } + +} + +void AnimationKeyEditor::_cleanup_animation(Ref<Animation> p_animation) { + + + for(int i=0;i<p_animation->get_track_count();i++) { + + bool prop_exists=false; + Variant::Type valid_type=Variant::NIL; + Object *obj=NULL; + + RES res; + Node *node = root->get_node_and_resource(p_animation->track_get_path(i),res); + + if (res.is_valid()) { + obj=res.ptr(); + } else if (node) { + obj=node; + } + + if (obj && p_animation->track_get_type(i)==Animation::TYPE_VALUE) { + valid_type=obj->get_static_property_type(p_animation->track_get_path(i).get_property(),&prop_exists); + } + + if (!obj && cleanup_tracks->is_pressed()) { + + p_animation->remove_track(i); + i--; + continue; + } + + if (!prop_exists || p_animation->track_get_type(i)!=Animation::TYPE_VALUE || cleanup_keys->is_pressed()==false) + continue; + + for(int j=0;j<p_animation->track_get_key_count(i);j++) { + + Variant v = p_animation->track_get_key_value(i,j); + + if (!Variant::can_convert(v.get_type(),valid_type)) { + p_animation->track_remove_key(i,j); + j--; + } + } + + if (p_animation->track_get_key_count(i)==0 && cleanup_tracks->is_pressed()) { + p_animation->remove_track(i); + i--; + } + } + + undo_redo->clear_history(); + _update_paths(); +} + +void AnimationKeyEditor::_animation_optimize() { + + + + animation->optimize(optimize_linear_error->get_value(),optimize_angular_error->get_value(),optimize_max_angle->get_value()); + track_editor->update(); + undo_redo->clear_history(); + +} + + +float AnimationKeyEditor::_get_zoom_scale() const { + + float zv = zoom->get_value(); + if (zv<1) { + zv = 1.0-zv; + return Math::pow(1.0f+zv,8.0f)*100; + } else { + return 1.0/Math::pow(zv,8.0f)*100; + } +} + +void AnimationKeyEditor::_track_pos_draw() { + + if (!animation.is_valid()) { + return; + } + + + Ref<StyleBox> style = get_stylebox("normal","TextEdit"); + Size2 size= track_editor->get_size() - style->get_minimum_size(); + Size2 ofs = style->get_offset(); + + int settings_limit = size.width - right_data_size_cache; + int name_limit = settings_limit * name_column_ratio; + + float keys_from= h_scroll->get_value(); + float zoom_scale = _get_zoom_scale(); + float keys_to=keys_from+(settings_limit-name_limit) / zoom_scale; + + + + //will move to separate control! (for speedup) + if (timeline_pos >= keys_from && timeline_pos<keys_to) { + //draw position + int pixel = (timeline_pos - h_scroll->get_value()) * zoom_scale; + pixel+=name_limit; + track_pos->draw_line(ofs+Point2(pixel,0),ofs+Point2(pixel,size.height),Color(1,0.3,0.3,0.8)); + + } +} + +void AnimationKeyEditor::_track_editor_draw() { + + + if (animation.is_valid() && animation->get_track_count()) { + if (selected_track < 0) + selected_track=0; + else if (selected_track>=animation->get_track_count()) + selected_track=animation->get_track_count()-1; + } + + track_pos->update(); + Control *te=track_editor; + Ref<StyleBox> style = get_stylebox("normal","TextEdit"); + te->draw_style_box(style,Rect2(Point2(),track_editor->get_size())); + + if (te->has_focus()) { + te->draw_style_box(get_stylebox("bg_focus","Tree"),Rect2(Point2(),track_editor->get_size())); + } + + if (!animation.is_valid()) { + v_scroll->hide(); + h_scroll->hide(); + menu_add_track->set_disabled(true); + menu_track->set_disabled(true); + edit_button->set_disabled(true); + key_editor_tab->hide(); + move_up_button->set_disabled(true); + move_down_button->set_disabled(true); + remove_button->set_disabled(true); + + return; + } + + menu_add_track->set_disabled(false); + menu_track->set_disabled(false); + edit_button->set_disabled(false); + move_up_button->set_disabled(false); + move_down_button->set_disabled(false); + remove_button->set_disabled(false); + if (edit_button->is_pressed()) + key_editor_tab->show(); + + te_drawing=true; + + Size2 size= te->get_size() - style->get_minimum_size(); + Size2 ofs = style->get_offset(); + + Ref<Font> font = te->get_font("font","Tree"); + int sep = get_constant("vseparation","Tree"); + int hsep = get_constant("hseparation","Tree"); + Color color = get_color("font_color","Tree"); + Color sepcolor = get_color("guide_color","Tree"); + Color timecolor = get_color("prop_subsection","Editor"); + timecolor = Color::html("ff4a414f"); + Color hover_color = Color(1,1,1,0.05); + Color select_color = Color(1,1,1,0.1); + Color invalid_path_color = Color(1,0.6,0.4,0.5); + Color track_select_color =Color::html("ffbd8e8e"); + + Ref<Texture> remove_icon = get_icon("Remove","EditorIcons"); + Ref<Texture> move_up_icon = get_icon("MoveUp","EditorIcons"); + Ref<Texture> move_down_icon = get_icon("MoveDown","EditorIcons"); + Ref<Texture> remove_icon_hl = get_icon("RemoveHl","EditorIcons"); + Ref<Texture> move_up_icon_hl = get_icon("MoveUpHl","EditorIcons"); + Ref<Texture> move_down_icon_hl = get_icon("MoveDownHl","EditorIcons"); + Ref<Texture> add_key_icon = get_icon("TrackAddKey","EditorIcons"); + Ref<Texture> add_key_icon_hl = get_icon("TrackAddKeyHl","EditorIcons"); + Ref<Texture> down_icon = get_icon("select_arrow","Tree"); + + Ref<Texture> wrap_icon[2]={ + get_icon("InterpWrapClamp","EditorIcons"), + get_icon("InterpWrapLoop","EditorIcons"), + }; + + Ref<Texture> interp_icon[3]={ + get_icon("InterpRaw","EditorIcons"), + get_icon("InterpLinear","EditorIcons"), + get_icon("InterpCubic","EditorIcons") + }; + Ref<Texture> cont_icon[3]={ + get_icon("TrackContinuous","EditorIcons"), + get_icon("TrackDiscrete","EditorIcons"), + get_icon("TrackTrigger","EditorIcons") + }; + Ref<Texture> type_icon[3]={ + get_icon("KeyValue","EditorIcons"), + get_icon("KeyXform","EditorIcons"), + get_icon("KeyCall","EditorIcons") + }; + + Ref<Texture> invalid_icon = get_icon("KeyInvalid","EditorIcons"); + Ref<Texture> invalid_icon_hover = get_icon("KeyInvalidHover","EditorIcons"); + + Ref<Texture> hsize_icon = get_icon("Hsize","EditorIcons"); + + Ref<Texture> type_hover=get_icon("KeyHover","EditorIcons"); + Ref<Texture> type_selected=get_icon("KeySelected","EditorIcons"); + + int right_separator_ofs = down_icon->get_width() *3 + add_key_icon->get_width() + interp_icon[0]->get_width() + wrap_icon[0]->get_width() + cont_icon[0]->get_width() + hsep*9; + + int h = font->get_height()+sep; + + + int fit = (size.height / h)-1; + int total = animation->get_track_count(); + if (total < fit) { + v_scroll->hide(); + v_scroll->set_max( total ); + v_scroll->set_page( fit ); + } else { + v_scroll->show(); + v_scroll->set_max( total ); + v_scroll->set_page( fit ); + } + + + int settings_limit = size.width - right_separator_ofs; + int name_limit = settings_limit * name_column_ratio; + + te->draw_line(ofs+Point2(name_limit,0),ofs+Point2(name_limit,size.height),color); + te->draw_line(ofs+Point2(settings_limit,0),ofs+Point2(settings_limit,size.height),color); + te->draw_texture(hsize_icon,ofs+Point2(name_limit-hsize_icon->get_width()-hsep,(h-hsize_icon->get_height())/2)); + + te->draw_line(ofs+Point2(0,h),ofs+Point2(size.width,h),color); + // draw time + + float keys_from; + float keys_to; + float zoom_scale; + + + { + + int zoomw = settings_limit-name_limit; + + + float scale = _get_zoom_scale(); + zoom_scale=scale; + + + float l = animation->get_length(); + if (l<=0) + l=0.001; //avoid crashor + + int end_px = (l - h_scroll->get_value()) * scale; + int begin_px = -h_scroll->get_value() * scale; + Color notimecol; + notimecol.r=timecolor.gray(); + notimecol.g=notimecol.r; + notimecol.b=notimecol.r; + notimecol.a=timecolor.a; + + { + + te->draw_rect(Rect2( ofs + Point2(name_limit,0), Point2(zoomw-1,h)), notimecol); + + + if (begin_px < zoomw && end_px >0) { + + if (begin_px<0) + begin_px=0; + if (end_px>zoomw) + end_px=zoomw; + + te->draw_rect(Rect2( ofs + Point2(name_limit+begin_px,0), Point2(end_px-begin_px-1,h)), timecolor); + } + + } + + + + keys_from= h_scroll->get_value(); + keys_to=keys_from+zoomw / scale; + + { + float time_min=0; + float time_max=animation->get_length(); + for(int i=0;i<animation->get_track_count();i++) { + + if (animation->track_get_key_count(i)>0) { + + float beg = animation->track_get_key_time(i,0); + if (beg<time_min) + time_min=beg; + float end = animation->track_get_key_time(i,animation->track_get_key_count(i)-1); + if (end>time_max) + time_max=end; + } + } + + + + + + float extra = (zoomw / scale)*0.5; + + if (time_min<-0.001) + time_min-=extra; + time_max+=extra; + h_scroll->set_min(time_min); + h_scroll->set_max(time_max); + + if (zoomw / scale < (time_max-time_min)) { + h_scroll->show(); + + } else { + + h_scroll->hide(); + } + + + } + + h_scroll->set_page(zoomw / scale); + + Color color_time_sec = color; + Color color_time_dec = color; + color_time_dec.a*=0.5; +#define SC_ADJ 100 + int min=30; + int dec=1; + int step=1; + int decimals=2; + bool step_found=false; + + while(!step_found) { + + static const int _multp[3]={1,2,5}; + for(int i=0;i<3;i++) { + + step = (_multp[i] * dec); + if (step*scale/SC_ADJ> min) { + step_found=true; + break; + } + + } + if (step_found) + break; + dec*=10; + decimals--; + if (decimals<0) + decimals=0; + } + + + for(int i=0;i<zoomw;i++) { + + float pos = h_scroll->get_value() + double(i)/scale; + float prev = h_scroll->get_value() + (double(i)-1.0)/scale; + + + int sc = int(Math::floor(pos*SC_ADJ)); + int prev_sc = int(Math::floor(prev*SC_ADJ)); + bool sub = (sc % SC_ADJ); + + if ((sc/step)!=(prev_sc/step) || (prev_sc<0 && sc>=0)) { + + int scd = sc < 0 ? prev_sc : sc; + te->draw_line( ofs + Point2(name_limit+i,0), ofs+Point2(name_limit+i,h), color); + te->draw_string( font,ofs + Point2(name_limit+i+3,(h-font->get_height())/2+font->get_ascent()).floor(),String::num((scd-(scd%step))/double(SC_ADJ),decimals),sub?color_time_dec:color_time_sec,zoomw-i); + } + + + } + } + + color.a*=0.5; + + for(int i=0;i<fit;i++) { + + //this code sucks, i always forget how it works + + int idx = v_scroll->get_value() + i; + if (idx>=animation->get_track_count()) + break; + int y = h+i*h+sep; + + bool prop_exists=false; + Variant::Type valid_type=Variant::NIL; + Object *obj=NULL; + + RES res; + Node *node = root->get_node_and_resource(animation->track_get_path(idx),res); + + if (res.is_valid()) { + obj=res.ptr(); + } else if (node) { + obj=node; + } + + if (obj && animation->track_get_type(idx)==Animation::TYPE_VALUE) { + valid_type=obj->get_static_property_type(animation->track_get_path(idx).get_property(),&prop_exists); + } + + + if (/*mouse_over.over!=MouseOver::OVER_NONE &&*/ idx==mouse_over.track) { + Color sepc=hover_color; + te->draw_rect(Rect2(ofs+Point2(0,y),Size2(size.width,h-1)),sepc); + } + + if (selected_track==idx) { + Color tc = select_color; + //tc.a*=0.7; + te->draw_rect(Rect2(ofs+Point2(0,y),Size2(size.width-1,h-1)),tc); + } + + te->draw_texture(type_icon[animation->track_get_type(idx)],ofs+Point2(0,y+(h-type_icon[0]->get_height())/2).floor()); + NodePath np = animation->track_get_path(idx); + Node *n = root->get_node(np); + Color ncol = color; + if (n && editor_selection->is_selected(n)) + ncol=track_select_color; + te->draw_string(font,Point2(ofs+Point2(type_icon[0]->get_width()+sep,y+font->get_ascent()+(sep/2))).floor(),np,ncol,name_limit-(type_icon[0]->get_width()+sep)-5); + + if (!obj) + te->draw_line(ofs+Point2(0,y+h/2),ofs+Point2(name_limit,y+h/2),invalid_path_color); + + te->draw_line(ofs+Point2(0,y+h),ofs+Point2(size.width,y+h),sepcolor); + + Point2 icon_ofs = ofs + Point2( size.width, y + (h - remove_icon->get_height() )/2).floor(); + icon_ofs.y+=4; + + +/* icon_ofs.x-=remove_icon->get_width(); + + te->draw_texture((mouse_over.over==MouseOver::OVER_REMOVE && mouse_over.track==idx)?remove_icon_hl:remove_icon,icon_ofs); + icon_ofs.x-=hsep; + icon_ofs.x-=move_down_icon->get_width(); + te->draw_texture((mouse_over.over==MouseOver::OVER_DOWN && mouse_over.track==idx)?move_down_icon_hl:move_down_icon,icon_ofs); + icon_ofs.x-=hsep; + icon_ofs.x-=move_up_icon->get_width(); + te->draw_texture((mouse_over.over==MouseOver::OVER_UP && mouse_over.track==idx)?move_up_icon_hl:move_up_icon,icon_ofs); + icon_ofs.x-=hsep; + te->draw_line(Point2(icon_ofs.x,ofs.y+y),Point2(icon_ofs.x,ofs.y+y+h),sepcolor); + + icon_ofs.x-=hsep; + */ + track_ofs[0]=size.width-icon_ofs.x; + icon_ofs.x-=down_icon->get_width(); + te->draw_texture(down_icon,icon_ofs); + + int wrap_type = animation->track_get_interpolation_loop_wrap(idx)?1:0; + icon_ofs.x-=hsep; + icon_ofs.x-=wrap_icon[wrap_type]->get_width(); + te->draw_texture(wrap_icon[wrap_type],icon_ofs); + + icon_ofs.x-=hsep; + te->draw_line(Point2(icon_ofs.x,ofs.y+y),Point2(icon_ofs.x,ofs.y+y+h),sepcolor); + + track_ofs[1]=size.width-icon_ofs.x; + + icon_ofs.x-=down_icon->get_width(); + te->draw_texture(down_icon,icon_ofs); + + int interp_type = animation->track_get_interpolation_type(idx); + ERR_CONTINUE(interp_type<0 || interp_type>=3); + icon_ofs.x-=hsep; + icon_ofs.x-=interp_icon[interp_type]->get_width(); + te->draw_texture(interp_icon[interp_type],icon_ofs); + + icon_ofs.x-=hsep; + te->draw_line(Point2(icon_ofs.x,ofs.y+y),Point2(icon_ofs.x,ofs.y+y+h),sepcolor); + + track_ofs[2]=size.width-icon_ofs.x; + + if (animation->track_get_type(idx)==Animation::TYPE_VALUE) { + + + int umode = animation->value_track_get_update_mode(idx); + + icon_ofs.x-=hsep; + icon_ofs.x-=down_icon->get_width(); + te->draw_texture(down_icon,icon_ofs); + + icon_ofs.x-=hsep; + icon_ofs.x-=cont_icon[umode]->get_width(); + te->draw_texture(cont_icon[umode],icon_ofs); + } else { + + icon_ofs.x -= hsep*2 + cont_icon[0]->get_width() + down_icon->get_width(); + } + + icon_ofs.x-=hsep; + te->draw_line(Point2(icon_ofs.x,ofs.y+y),Point2(icon_ofs.x,ofs.y+y+h),sepcolor); + + track_ofs[3]=size.width-icon_ofs.x; + + icon_ofs.x-=hsep; + icon_ofs.x-=add_key_icon->get_width(); + te->draw_texture((mouse_over.over==MouseOver::OVER_ADD_KEY && mouse_over.track==idx)?add_key_icon_hl:add_key_icon,icon_ofs); + + track_ofs[4]=size.width-icon_ofs.x; + + //draw the keys; + int tt = animation->track_get_type(idx); + float key_vofs = Math::floor((float)(h - type_icon[tt]->get_height())/2); + float key_hofs = -Math::floor((float)type_icon[tt]->get_height()/2); + + int kc=animation->track_get_key_count(idx); + bool first=true; + + + + for(int i=0;i<kc;i++) { + + + float time = animation->track_get_key_time(idx,i); + if (time<keys_from) + continue; + if (time>keys_to) { + + if (first && i>0 && animation->track_get_key_value(idx,i)==animation->track_get_key_value(idx,i-1)) { + //draw whole line + te->draw_line(ofs+Vector2(name_limit,y+h/2),ofs+Point2(settings_limit,y+h/2),color); + } + + break; + } + + float x = key_hofs + name_limit + (time-keys_from)*zoom_scale; + + Ref<Texture> tex = type_icon[tt]; + + SelectedKey sk; + sk.key=i; + sk.track=idx; + if (selection.has(sk)) { + + if (click.click==ClickOver::CLICK_MOVE_KEYS) + continue; + tex=type_selected; + } + + if (mouse_over.over==MouseOver::OVER_KEY && mouse_over.track==idx && mouse_over.over_key==i) + tex=type_hover; + + Variant value = animation->track_get_key_value(idx,i); + if (first && i>0 && value==animation->track_get_key_value(idx,i-1)) { + + te->draw_line(ofs+Vector2(name_limit,y+h/2),ofs+Point2(x,y+h/2),color); + } + + if (i<kc-1 && value==animation->track_get_key_value(idx,i+1)) { + float x_n = key_hofs + name_limit + (animation->track_get_key_time(idx,i+1)-keys_from)*zoom_scale; + + x_n = MIN( x_n, settings_limit); + te->draw_line(ofs+Point2(x_n,y+h/2),ofs+Point2(x,y+h/2),color); + + } + + if (prop_exists && !Variant::can_convert(value.get_type(),valid_type)) { + te->draw_texture(invalid_icon,ofs+Point2(x,y+key_vofs).floor()); + } + + if (prop_exists && !Variant::can_convert(value.get_type(),valid_type)) { + if (tex==type_hover) + te->draw_texture(invalid_icon_hover,ofs+Point2(x,y+key_vofs).floor()); + else + te->draw_texture(invalid_icon,ofs+Point2(x,y+key_vofs).floor()); + } else { + + te->draw_texture(tex,ofs+Point2(x,y+key_vofs).floor()); + } + + + first=false; + } + + } + + switch(click.click) { + case ClickOver::CLICK_SELECT_KEYS: { + + te->draw_rect(Rect2(click.at,click.to-click.at),Color(0.7,0.7,1.0,0.5)); + + } break; + case ClickOver::CLICK_MOVE_KEYS: { + + float from_t = 1e20; + + for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { + float t = animation->track_get_key_time(E->key().track,E->key().key); + if (t<from_t) + from_t=t; + + } + + float motion = from_t+(click.to.x - click.at.x)/zoom_scale; + if (step->get_value()) + motion = Math::stepify(motion,step->get_value()); + + for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { + + + int idx = E->key().track; + int i = idx-v_scroll->get_value(); + if (i<0 || i>=fit) + continue; + int y = h+i*h+sep; + + float key_vofs = Math::floor((float)(h - type_selected->get_height())/2); + float key_hofs = -Math::floor((float)type_selected->get_height()/2); + + float time = animation->track_get_key_time(idx,E->key().key); + float diff = time-from_t; + + float t = motion + diff; + + float x = (t-keys_from)*zoom_scale; + //x+=click.to.x - click.at.x; + if (x<0 || x>=(settings_limit-name_limit)) + continue; + + x+=name_limit; + + te->draw_texture(type_selected,ofs+Point2(x+key_hofs,y+key_vofs).floor()); + + } + } break; + default: {}; + } + + + te_drawing=false; +} + +void AnimationKeyEditor::_track_name_changed(const String& p_name) { + + ERR_FAIL_COND(!animation.is_valid()); + undo_redo->create_action(TTR("Anim Track Rename")); + undo_redo->add_do_method(animation.ptr(),"track_set_path",track_name_editing,p_name); + undo_redo->add_undo_method(animation.ptr(),"track_set_path",track_name_editing,animation->track_get_path(track_name_editing)); + undo_redo->commit_action(); + track_name->hide(); + +} + +void AnimationKeyEditor::_track_menu_selected(int p_idx) { + + + ERR_FAIL_COND(!animation.is_valid()); + + if (interp_editing!=-1) { + + ERR_FAIL_INDEX(interp_editing,animation->get_track_count()); + undo_redo->create_action(TTR("Anim Track Change Interpolation")); + undo_redo->add_do_method(animation.ptr(),"track_set_interpolation_type",interp_editing,p_idx); + undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_type",interp_editing,animation->track_get_interpolation_type(interp_editing)); + undo_redo->commit_action(); + } else if (cont_editing!=-1) { + + ERR_FAIL_INDEX(cont_editing,animation->get_track_count()); + + undo_redo->create_action(TTR("Anim Track Change Value Mode")); + undo_redo->add_do_method(animation.ptr(),"value_track_set_update_mode",cont_editing,p_idx); + undo_redo->add_undo_method(animation.ptr(),"value_track_set_update_mode",cont_editing,animation->value_track_get_update_mode(cont_editing)); + undo_redo->commit_action(); + } else if (wrap_editing!=-1) { + + ERR_FAIL_INDEX(wrap_editing,animation->get_track_count()); + + undo_redo->create_action(TTR("Anim Track Change Wrap Mode")); + undo_redo->add_do_method(animation.ptr(),"track_set_interpolation_loop_wrap",wrap_editing,p_idx?true:false); + undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_loop_wrap",wrap_editing,animation->track_get_interpolation_loop_wrap(wrap_editing)); + undo_redo->commit_action(); + } else { + switch (p_idx) { + + case RIGHT_MENU_DUPLICATE: + _anim_duplicate_keys(); break; + case RIGHT_MENU_DUPLICATE_TRANSPOSE: + _anim_duplicate_keys(true); break; + case RIGHT_MENU_REMOVE: + _anim_delete_keys(); break; + } + } + +} + +struct _AnimMoveRestore { + + int track; + float time; + Variant key; + float transition; +}; + +void AnimationKeyEditor::_clear_selection_for_anim(const Ref<Animation>& p_anim) { + + if (!(animation==p_anim)) + return; + //selection.clear(); + _clear_selection(); + +} + +void AnimationKeyEditor::_select_at_anim(const Ref<Animation>& p_anim,int p_track,float p_pos){ + + if (!(animation==p_anim)) + return; + + int idx = animation->track_find_key(p_track,p_pos,true); + ERR_FAIL_COND(idx<0); + + SelectedKey sk; + sk.track=p_track; + sk.key=idx; + KeyInfo ki; + ki.pos=p_pos; + + selection.insert(sk,ki); + +} + + +PropertyInfo AnimationKeyEditor::_find_hint_for_track(int p_idx,NodePath& r_base_path) { + + r_base_path=NodePath(); + ERR_FAIL_COND_V(!animation.is_valid(),PropertyInfo()); + ERR_FAIL_INDEX_V(p_idx,animation->get_track_count(),PropertyInfo()); + + if (!root) + return PropertyInfo(); + + NodePath path = animation->track_get_path(p_idx); + + + if (!root->has_node_and_resource(path)) + return PropertyInfo(); + + RES res; + Node *node = root->get_node_and_resource(path,res); + + + if (node) { + r_base_path=node->get_path(); + } + + String property = path.get_property(); + if (property=="") + return PropertyInfo(); + + List<PropertyInfo> pinfo; + if (res.is_valid()) + res->get_property_list(&pinfo); + else + node->get_property_list(&pinfo); + + for(List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) { + + if (E->get().name==property) + return E->get(); + } + + return PropertyInfo(); +} + + +void AnimationKeyEditor::_curve_transition_changed(float p_what) { + + if (selection.size()==0) + return; + if (selection.size()==1) + undo_redo->create_action(TTR("Edit Node Curve"),UndoRedo::MERGE_ENDS); + else + undo_redo->create_action(TTR("Edit Selection Curve"),UndoRedo::MERGE_ENDS); + + for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { + + int track = E->key().track; + int key = E->key().key; + float prev_val = animation->track_get_key_transition(track,key); + undo_redo->add_do_method(animation.ptr(),"track_set_key_transition",track,key,p_what); + undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",track,key,prev_val); + } + + undo_redo->commit_action(); + +} + +void AnimationKeyEditor::_toggle_edit_curves() { + + if (edit_button->is_pressed()) + key_editor_tab->show(); + else + key_editor_tab->hide(); +} + + +bool AnimationKeyEditor::_edit_if_single_selection() { + + if (selection.size()!=1) { + + if (selection.size()==0) { + curve_edit->set_mode(AnimationCurveEdit::MODE_DISABLED); + //print_line("disable"); + } else { + + curve_edit->set_mode(AnimationCurveEdit::MODE_MULTIPLE); + curve_edit->set_transition(1.0); + curve_edit->clear_multiples(); + //add all + for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { + + curve_edit->set_multiple(animation->track_get_key_transition(E->key().track,E->key().key)); + } + //print_line("multiple"); + + } + return false; + } + curve_edit->set_mode(AnimationCurveEdit::MODE_SINGLE); + //print_line("regular"); + + int idx = selection.front()->key().track; + int key = selection.front()->key().key; + { + + key_edit->animation=animation; + key_edit->track=idx; + key_edit->key_ofs=animation->track_get_key_time(idx,key); + key_edit->hint=_find_hint_for_track(idx,key_edit->base); + key_edit->notify_change(); + + curve_edit->set_transition(animation->track_get_key_transition(idx,key)); + + /*key_edit_dialog->set_size( Size2( 200,200) ); + key_edit_dialog->set_pos( track_editor->get_global_pos() + ofs + mpos +Point2(-100,20)); + key_edit_dialog->popup();*/ + + } + + return true; + +} + +void AnimationKeyEditor::_anim_delete_keys() { + if (selection.size()) { + undo_redo->create_action(TTR("Anim Delete Keys")); + + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + undo_redo->add_do_method(animation.ptr(),"track_remove_key",E->key().track,E->key().key); + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",E->key().track,E->get().pos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); + + } + undo_redo->add_do_method(this,"_clear_selection_for_anim",animation); + undo_redo->add_undo_method(this,"_clear_selection_for_anim",animation); + undo_redo->commit_action(); + //selection.clear(); + accept_event(); + _edit_if_single_selection(); + } +} + +void AnimationKeyEditor::_track_editor_gui_input(const InputEvent& p_input) { + + Control *te=track_editor; + Ref<StyleBox> style = get_stylebox("normal","TextEdit"); + + if (!animation.is_valid()) { + return; + } + + Size2 size= te->get_size() - style->get_minimum_size(); + Size2 ofs = style->get_offset(); + + Ref<Font> font = te->get_font("font","Tree"); + int sep = get_constant("vseparation","Tree"); + int hsep = get_constant("hseparation","Tree"); + Ref<Texture> remove_icon = get_icon("Remove","EditorIcons"); + Ref<Texture> move_up_icon = get_icon("MoveUp","EditorIcons"); + Ref<Texture> move_down_icon = get_icon("MoveDown","EditorIcons"); + Ref<Texture> down_icon = get_icon("select_arrow","Tree"); + Ref<Texture> hsize_icon = get_icon("Hsize","EditorIcons"); + Ref<Texture> add_key_icon = get_icon("TrackAddKey","EditorIcons"); + + Ref<Texture> wrap_icon[2]={ + get_icon("InterpWrapClamp","EditorIcons"), + get_icon("InterpWrapLoop","EditorIcons"), + }; + Ref<Texture> interp_icon[3]={ + get_icon("InterpRaw","EditorIcons"), + get_icon("InterpLinear","EditorIcons"), + get_icon("InterpCubic","EditorIcons") + }; + Ref<Texture> cont_icon[3]={ + get_icon("TrackContinuous","EditorIcons"), + get_icon("TrackDiscrete","EditorIcons"), + get_icon("TrackTrigger","EditorIcons") + }; + Ref<Texture> type_icon[3]={ + get_icon("KeyValue","EditorIcons"), + get_icon("KeyXform","EditorIcons"), + get_icon("KeyCall","EditorIcons") + }; + int right_separator_ofs = down_icon->get_width() *3 + add_key_icon->get_width() + interp_icon[0]->get_width() + wrap_icon[0]->get_width() + cont_icon[0]->get_width() + hsep*9; + + int h = font->get_height()+sep; + + int fit = (size.height / h)-1; + int total = animation->get_track_count(); + if (total < fit) { + v_scroll->hide(); + } else { + v_scroll->show(); + v_scroll->set_max( total ); + v_scroll->set_page( fit ); + } + + int settings_limit = size.width - right_separator_ofs; + int name_limit = settings_limit * name_column_ratio; + + + switch(p_input.type) { + + case InputEvent::KEY: { + + if (p_input.key.scancode==KEY_D && p_input.key.pressed && p_input.key.mod.command) { + + if (p_input.key.mod.shift) + _menu_track(TRACK_MENU_DUPLICATE_TRANSPOSE); + else + _menu_track(TRACK_MENU_DUPLICATE); + + accept_event(); + + } else if (p_input.key.scancode==KEY_DELETE && p_input.key.pressed && click.click==ClickOver::CLICK_NONE) { + + _anim_delete_keys(); + } else if (animation.is_valid() && animation->get_track_count()>0) { + + if (p_input.is_pressed() && (p_input.is_action("ui_up") || p_input.is_action("ui_page_up"))) { + + if (p_input.is_action("ui_up")) + selected_track--; + if (v_scroll->is_visible_in_tree() && p_input.is_action("ui_page_up")) + selected_track--; + + if (selected_track<0) + selected_track=0; + + + if (v_scroll->is_visible_in_tree()) { + if (v_scroll->get_value() > selected_track) + v_scroll->set_value(selected_track); + + } + + track_editor->update(); + accept_event(); + + } + + if (p_input.is_pressed() && (p_input.is_action("ui_down") || p_input.is_action("ui_page_down"))) { + + if (p_input.is_action("ui_down")) + selected_track++; + else if (v_scroll->is_visible_in_tree() && p_input.is_action("ui_page_down")) + selected_track+=v_scroll->get_page(); + + if (selected_track >= animation->get_track_count()) + selected_track=animation->get_track_count()-1; + + if (v_scroll->is_visible_in_tree() && v_scroll->get_page()+v_scroll->get_value() < selected_track+1) { + v_scroll->set_value(selected_track-v_scroll->get_page()+1); + } + + track_editor->update(); + accept_event(); + } + } + + + } break; + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &mb = p_input.mouse_button; + + if (mb.button_index==BUTTON_WHEEL_UP && mb.pressed) { + + if (mb.mod.command) { + zoom->set_value(zoom->get_value() + zoom->get_step()); + } else { + v_scroll->set_value( v_scroll->get_value() - v_scroll->get_page() / 8 ); + } + } + + if (mb.button_index==BUTTON_WHEEL_DOWN && mb.pressed) { + + if (mb.mod.command) { + zoom->set_value(zoom->get_value() - zoom->get_step()); + } else { + v_scroll->set_value( v_scroll->get_value() + v_scroll->get_page() / 8 ); + } + } + + if (mb.button_index==BUTTON_RIGHT && mb.pressed) { + + Point2 mpos = Point2(mb.x,mb.y)-ofs; + + if (selection.size() == 0) { + // Auto-select on right-click if nothing is selected + // Note: This code is pretty much duplicated from the left click code, + // both codes could be moved into a function to avoid the duplicated code. + Point2 mpos = Point2(mb.x,mb.y)-ofs; + + if (mpos.y < h ) { + return; + } + + mpos.y -= h; + + int idx = mpos.y / h; + idx+=v_scroll->get_value(); + if (idx <0 || idx>=animation->get_track_count()) + break; + + if (mpos.x < name_limit) { + } else if (mpos.x < settings_limit) { + float pos = mpos.x - name_limit; + pos/=_get_zoom_scale(); + pos+=h_scroll->get_value(); + float w_time = (type_icon[0]->get_width() / _get_zoom_scale())/2.0; + + int kidx = animation->track_find_key(idx,pos); + int kidx_n = kidx+1; + int key=-1; + + if (kidx>=0 && kidx<animation->track_get_key_count(idx)) { + + float kpos = animation->track_get_key_time(idx,kidx); + if (ABS(pos-kpos)<=w_time) { + + key=kidx; + } + } + + if (key==-1 && kidx_n>=0 && kidx_n<animation->track_get_key_count(idx)) { + + float kpos = animation->track_get_key_time(idx,kidx_n); + if (ABS(pos-kpos)<=w_time) { + + key=kidx_n; + } + } + + if (key==-1) { + + click.click=ClickOver::CLICK_SELECT_KEYS; + click.at=Point2(mb.x,mb.y); + click.to=click.at; + click.shift=mb.mod.shift; + selected_track=idx; + track_editor->update(); + //drag select region + return; + + } + + + + SelectedKey sk; + sk.track=idx; + sk.key=key; + KeyInfo ki; + ki.pos= animation->track_get_key_time(idx,key); + click.shift=mb.mod.shift; + click.selk=sk; + + + if (!mb.mod.shift && !selection.has(sk)) + _clear_selection(); + + selection.insert(sk,ki); + + click.click=ClickOver::CLICK_MOVE_KEYS; + click.at=Point2(mb.x,mb.y); + click.to=click.at; + update(); + selected_track=idx; + track_editor->update(); + + if (_edit_if_single_selection() && mb.mod.command) { + edit_button->set_pressed(true); + key_editor_tab->show(); + } + } + } + + if (selection.size()) { + // User has right clicked and we have a selection, show a popup menu with options + track_menu->clear(); + track_menu->set_size(Point2(1,1)); + track_menu->add_item(TTR("Duplicate Selection"), RIGHT_MENU_DUPLICATE); + track_menu->add_item(TTR("Duplicate Transposed"), RIGHT_MENU_DUPLICATE_TRANSPOSE); + track_menu->add_item(TTR("Remove Selection"), RIGHT_MENU_REMOVE); + + track_menu->set_pos(te->get_global_pos()+mpos); + + interp_editing=-1; + cont_editing=-1; + wrap_editing=-1; + + track_menu->popup(); + } + } + + if (mb.button_index==BUTTON_LEFT && !(mb.button_mask&~BUTTON_MASK_LEFT)) { + + + if (mb.pressed) { + + Point2 mpos = Point2(mb.x,mb.y)-ofs; + + if (mpos.y < h ) { + + + if (mpos.x<name_limit && mpos.x > (name_limit - hsep - hsize_icon->get_width())) { + + + click.click=ClickOver::CLICK_RESIZE_NAMES; + click.at=Point2(mb.x,mb.y); + click.to=click.at; + click.at.y=name_limit; + + } + + if (mpos.x>=name_limit && mpos.x<settings_limit) { + //seek + //int zoomw = settings_limit-name_limit; + float scale = _get_zoom_scale(); + float pos = h_scroll->get_value() + (mpos.x-name_limit) / scale; + if (animation->get_step()) + pos=Math::stepify(pos,animation->get_step()); + + if (pos<0 ) + pos=0; + if (pos>=animation->get_length()) + pos=animation->get_length(); + timeline_pos=pos; + click.click=ClickOver::CLICK_DRAG_TIMELINE; + click.at=Point2(mb.x,mb.y); + click.to=click.at; + emit_signal("timeline_changed",pos,false); + + } + + return; + } + + mpos.y -= h; + + int idx = mpos.y / h; + idx+=v_scroll->get_value(); + if (idx <0) + break; + + if (idx>=animation->get_track_count()) { + + if (mpos.x >= name_limit && mpos.x<settings_limit) { + + click.click=ClickOver::CLICK_SELECT_KEYS; + click.at=Point2(mb.x,mb.y); + click.to=click.at; + //drag select region + } + + break; + } + + if (mpos.x < name_limit) { + //name column + + // area + if (idx!=selected_track) { + + selected_track=idx; + track_editor->update(); + break; + } + + Rect2 area(ofs.x,ofs.y+((int(mpos.y)/h)+1)*h,name_limit, h ); + track_name->set_text(animation->track_get_path(idx)); + track_name->set_pos( te->get_global_pos() + area.pos); + track_name->set_size(area.size); + track_name->show_modal(); + track_name->grab_focus(); + track_name->select_all(); + track_name_editing=idx; + + } else if (mpos.x < settings_limit) { + + float pos = mpos.x - name_limit; + pos/=_get_zoom_scale(); + pos+=h_scroll->get_value(); + float w_time = (type_icon[0]->get_width() / _get_zoom_scale())/2.0; + + int kidx = animation->track_find_key(idx,pos); + int kidx_n = kidx+1; + int key=-1; + + if (kidx>=0 && kidx<animation->track_get_key_count(idx)) { + + float kpos = animation->track_get_key_time(idx,kidx); + if (ABS(pos-kpos)<=w_time) { + + key=kidx; + } + } + + if (key==-1 && kidx_n>=0 && kidx_n<animation->track_get_key_count(idx)) { + + float kpos = animation->track_get_key_time(idx,kidx_n); + if (ABS(pos-kpos)<=w_time) { + + key=kidx_n; + } + } + + if (key==-1) { + + click.click=ClickOver::CLICK_SELECT_KEYS; + click.at=Point2(mb.x,mb.y); + click.to=click.at; + click.shift=mb.mod.shift; + selected_track=idx; + track_editor->update(); + //drag select region + return; + + } + + + + SelectedKey sk; + sk.track=idx; + sk.key=key; + KeyInfo ki; + ki.pos= animation->track_get_key_time(idx,key); + click.shift=mb.mod.shift; + click.selk=sk; + + + if (!mb.mod.shift && !selection.has(sk)) + _clear_selection(); + + selection.insert(sk,ki); + + click.click=ClickOver::CLICK_MOVE_KEYS; + click.at=Point2(mb.x,mb.y); + click.to=click.at; + update(); + selected_track=idx; + track_editor->update(); + + if (_edit_if_single_selection() && mb.mod.command) { + edit_button->set_pressed(true); + key_editor_tab->show(); + } + } else { + //button column + int ofsx = size.width - mpos.x; + if (ofsx < 0) + break; +/* + if (ofsx < remove_icon->get_width()) { + + undo_redo->create_action("Remove Anim Track"); + undo_redo->add_do_method(animation.ptr(),"remove_track",idx); + undo_redo->add_undo_method(animation.ptr(),"add_track",animation->track_get_type(idx),idx); + undo_redo->add_undo_method(animation.ptr(),"track_set_path",idx,animation->track_get_path(idx)); + //todo interpolation + for(int i=0;i<animation->track_get_key_count(idx);i++) { + + Variant v = animation->track_get_key_value(idx,i); + float time = animation->track_get_key_time(idx,i); + float trans = animation->track_get_key_transition(idx,i); + + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",idx,time,v); + undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",idx,i,trans); + + } + + undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_type",idx,animation->track_get_interpolation_type(idx)); + if (animation->track_get_type(idx)==Animation::TYPE_VALUE) { + undo_redo->add_undo_method(animation.ptr(),"value_track_set_continuous",idx,animation->value_track_is_continuous(idx)); + + } + + undo_redo->commit_action(); + + + return; + } + + ofsx-=hsep+remove_icon->get_width(); + + if (ofsx < move_down_icon->get_width()) { + + if (idx < animation->get_track_count() -1) { + undo_redo->create_action("Move Anim Track Down"); + undo_redo->add_do_method(animation.ptr(),"track_move_up",idx); + undo_redo->add_undo_method(animation.ptr(),"track_move_down",idx+1); + undo_redo->commit_action(); + } + return; + } + + ofsx-=hsep+move_down_icon->get_width(); + + if (ofsx < move_up_icon->get_width()) { + + if (idx >0) { + undo_redo->create_action("Move Anim Track Up"); + undo_redo->add_do_method(animation.ptr(),"track_move_down",idx); + undo_redo->add_undo_method(animation.ptr(),"track_move_up",idx-1); + undo_redo->commit_action(); + } + return; + } + + + ofsx-=hsep*3+move_up_icon->get_width(); + */ + + + if (ofsx < track_ofs[1]) { + + track_menu->clear(); + track_menu->set_size(Point2(1,1)); + static const char *interp_name[2]={"Clamp Loop Interp","Wrap Loop Interp"}; + for(int i=0;i<2;i++) { + track_menu->add_icon_item(wrap_icon[i],interp_name[i]); + } + + int popup_y = ofs.y+((int(mpos.y)/h)+2)*h; + int popup_x = size.width-track_ofs[1]; + + track_menu->set_pos(te->get_global_pos()+Point2(popup_x,popup_y)); + + + wrap_editing=idx; + interp_editing=-1; + cont_editing=-1; + + track_menu->popup(); + + return; + } + + + if (ofsx < track_ofs[2]) { + + track_menu->clear(); + track_menu->set_size(Point2(1,1)); + static const char *interp_name[3]={"Nearest","Linear","Cubic"}; + for(int i=0;i<3;i++) { + track_menu->add_icon_item(interp_icon[i],interp_name[i]); + } + + int popup_y = ofs.y+((int(mpos.y)/h)+2)*h; + int popup_x = size.width-track_ofs[2]; + + track_menu->set_pos(te->get_global_pos()+Point2(popup_x,popup_y)); + + + interp_editing=idx; + cont_editing=-1; + wrap_editing=-1; + + track_menu->popup(); + + return; + } + + if (ofsx < track_ofs[3]) { + + track_menu->clear(); + track_menu->set_size(Point2(1,1)); + String cont_name[3]={TTR("Continuous"),TTR("Discrete"),TTR("Trigger")}; + for(int i=0;i<3;i++) { + track_menu->add_icon_item(cont_icon[i],cont_name[i]); + } + + + int popup_y = ofs.y+((int(mpos.y)/h)+2)*h; + int popup_x = size.width-track_ofs[3]; + + track_menu->set_pos(te->get_global_pos()+Point2(popup_x,popup_y)); + + interp_editing=-1; + wrap_editing=-1; + cont_editing=idx; + + track_menu->popup(); + + return; + } + + if (ofsx < track_ofs[4]) { + + Animation::TrackType tt = animation->track_get_type(idx); + + float pos = timeline_pos; + int existing = animation->track_find_key(idx,pos,true); + + + + Variant newval; + + if (tt==Animation::TYPE_TRANSFORM) { + Dictionary d; + d["loc"]=Vector3(); + d["rot"]=Quat(); + d["scale"]=Vector3(); + newval=d; + + } else if (tt==Animation::TYPE_METHOD) { + + Dictionary d; + d["method"]=""; + d["args"]=Vector<Variant>(); + + + newval=d; + } else if (tt==Animation::TYPE_VALUE) { + + NodePath np; + PropertyInfo inf = _find_hint_for_track(idx,np); + if (inf.type!=Variant::NIL) { + + Variant::CallError err; + newval=Variant::construct(inf.type,NULL,0,err); + + } + + if (newval.get_type()==Variant::NIL) { + //popup a new type + cvi_track=idx; + cvi_pos=pos; + + type_menu->set_pos( get_global_pos() + mpos +ofs ); + type_menu->popup(); + return; + } + + } + + undo_redo->create_action(TTR("Anim Add Key")); + + undo_redo->add_do_method(animation.ptr(),"track_insert_key",idx,pos,newval,1); + undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",idx,pos); + + if (existing!=-1) { + Variant v = animation->track_get_key_value(idx,existing); + float trans = animation->track_get_key_transition(idx,existing); + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",idx,pos,v,trans); + } + + undo_redo->commit_action(); + + + return; + } + + } + + } else { + + switch(click.click) { + case ClickOver::CLICK_SELECT_KEYS: { + + + float zoom_scale=_get_zoom_scale(); + float keys_from = h_scroll->get_value(); + float keys_to = keys_from + (settings_limit-name_limit) / zoom_scale; + + float from_time = keys_from + ( click.at.x - (name_limit+ofs.x)) / zoom_scale; + float to_time = keys_from + (click.to.x - (name_limit+ofs.x)) / zoom_scale; + + + if (to_time < from_time) + SWAP(from_time,to_time); + + if (from_time > keys_to || to_time < keys_from) + break; + + if (from_time < keys_from) + from_time = keys_from; + + if (to_time >= keys_to) + to_time = keys_to; + + + int from_track = int(click.at.y-ofs.y-h-sep) / h + v_scroll->get_value(); + int to_track = int(click.to.y-ofs.y-h-sep) / h + v_scroll->get_value(); + int from_mod = int(click.at.y-ofs.y-sep) % h; + int to_mod = int(click.to.y-ofs.y-sep) % h; + + if (to_track < from_track) { + + SWAP(from_track,to_track); + SWAP(from_mod,to_mod); + } + + + + + if ((from_mod > (h/2)) && ((click.at.y-ofs.y)>=(h+sep))) { + from_track++; + } + + if (to_mod < h/2) { + to_track--; + } + + if (from_track>to_track) { + if (!click.shift) + _clear_selection(); + _edit_if_single_selection(); + break; + } + + int tracks_from = v_scroll->get_value(); + int tracks_to = v_scroll->get_value()+fit-1; + if (tracks_to>=animation->get_track_count()) + tracks_to=animation->get_track_count()-1; + + tracks_from=0; + tracks_to=animation->get_track_count()-1; + if (to_track >tracks_to) + to_track = tracks_to; + if (from_track<tracks_from) + from_track=tracks_from; + + if (from_track > tracks_to || to_track < tracks_from) { + if (!click.shift) + _clear_selection(); + _edit_if_single_selection(); + break; + } + + if (!click.shift) + _clear_selection(); + + + int higher_track=0x7FFFFFFF; + for(int i=from_track;i<=to_track;i++) { + + int kc=animation->track_get_key_count(i); + for(int j=0;j<kc;j++) { + + float t = animation->track_get_key_time(i,j); + if (t<from_time) + continue; + if (t>to_time) + break; + + if (i<higher_track) + higher_track=i; + + SelectedKey sk; + sk.track=i; + sk.key=j; + KeyInfo ki; + ki.pos=t; + selection[sk]=ki; + } + } + + if (higher_track!=0x7FFFFFFF) { + selected_track=higher_track; + track_editor->update(); + } + + + _edit_if_single_selection(); + + + } break; + case ClickOver::CLICK_MOVE_KEYS: { + + if (selection.empty()) + break; + if (click.at==click.to) { + + if (!click.shift) { + + KeyInfo ki=selection[click.selk]; + _clear_selection(); + selection[click.selk]=ki; + _edit_if_single_selection(); + } + + break; + } + + float from_t = 1e20; + + for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { + float t = animation->track_get_key_time(E->key().track,E->key().key); + if (t<from_t) + from_t=t; + + } + + float motion = from_t+(click.to.x - click.at.x)/_get_zoom_scale(); + if (step->get_value()) + motion = Math::stepify(motion,step->get_value()); + + + + + undo_redo->create_action(TTR("Anim Move Keys")); + + List<_AnimMoveRestore> to_restore; + + // 1-remove the keys + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + undo_redo->add_do_method(animation.ptr(),"track_remove_key",E->key().track,E->key().key); + } + // 2- remove overlapped keys + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + float newtime = E->get().pos-from_t+motion; + int idx = animation->track_find_key(E->key().track,newtime,true); + if (idx==-1) + continue; + SelectedKey sk; + sk.key=idx; + sk.track=E->key().track; + if (selection.has(sk)) + continue; //already in selection, don't save + + undo_redo->add_do_method(animation.ptr(),"track_remove_key_at_pos",E->key().track,newtime); + _AnimMoveRestore amr; + + amr.key=animation->track_get_key_value(E->key().track,idx); + amr.track=E->key().track; + amr.time=newtime; + amr.transition=animation->track_get_key_transition(E->key().track,idx); + + to_restore.push_back(amr); + + } + + // 3-move the keys (re insert them) + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + float newpos=E->get().pos-from_t+motion; + /* + if (newpos<0) + continue; //no add at the begining + */ + undo_redo->add_do_method(animation.ptr(),"track_insert_key",E->key().track,newpos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); + + } + + // 4-(undo) remove inserted keys + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + float newpos=E->get().pos+-from_t+motion; + /* + if (newpos<0) + continue; //no remove what no inserted + */ + undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",E->key().track,newpos); + + } + + // 5-(undo) reinsert keys + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",E->key().track,E->get().pos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); + + } + + // 6-(undo) reinsert overlapped keys + for(List<_AnimMoveRestore>::Element *E=to_restore.front();E;E=E->next()) { + + _AnimMoveRestore &amr = E->get(); + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",amr.track,amr.time,amr.key,amr.transition); + + } + + // 6-(undo) reinsert overlapped keys + for(List<_AnimMoveRestore>::Element *E=to_restore.front();E;E=E->next()) { + + _AnimMoveRestore &amr = E->get(); + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",amr.track,amr.time,amr.key,amr.transition); + + } + + undo_redo->add_do_method(this,"_clear_selection_for_anim",animation); + undo_redo->add_undo_method(this,"_clear_selection_for_anim",animation); + + // 7-reselect + + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + float oldpos=E->get().pos; + float newpos=oldpos-from_t+motion; + //if (newpos>=0) + undo_redo->add_do_method(this,"_select_at_anim",animation,E->key().track,newpos); + undo_redo->add_undo_method(this,"_select_at_anim",animation,E->key().track,oldpos); + + } + + undo_redo->commit_action(); + _edit_if_single_selection(); + + } break; + default: {} + } + + //button released + click.click=ClickOver::CLICK_NONE; + track_editor->update(); + + + } + } + + } break; + + case InputEvent::MOUSE_MOTION: { + + const InputEventMouseMotion &mb = p_input.mouse_motion; + + mouse_over.over=MouseOver::OVER_NONE; + mouse_over.track=-1; + te->update(); + track_editor->set_tooltip(""); + + if (!track_editor->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) + track_editor->call_deferred("grab_focus"); + + + if (click.click!=ClickOver::CLICK_NONE) { + + switch(click.click) { + case ClickOver::CLICK_RESIZE_NAMES: { + + + float base = click.at.y; + float clickp = click.at.x-ofs.x; + float dif = base - clickp; + + float target = mb.x+dif-ofs.x; + + float ratio = target / settings_limit; + + if (ratio>0.9) + ratio=0.9; + else if (ratio<0.2) + ratio=0.2; + + name_column_ratio=ratio; + + + } break; + case ClickOver::CLICK_DRAG_TIMELINE: { + + Point2 mpos = Point2(mb.x,mb.y)-ofs; + /* + if (mpos.x<name_limit) + mpos.x=name_limit; + if (mpos.x>settings_limit) + mpos.x=settings_limit; + */ + + + //int zoomw = settings_limit-name_limit; + float scale = _get_zoom_scale(); + float pos = h_scroll->get_value() + (mpos.x-name_limit) / scale; + if (animation->get_step()) { + pos=Math::stepify(pos,animation->get_step()); + + } + if (pos<0) + pos=0; + if (pos>=animation->get_length()) + pos=animation->get_length(); + + if (pos < h_scroll->get_value()) { + h_scroll->set_value(pos); + } else if (pos > h_scroll->get_value() + (settings_limit - name_limit) / scale) { + h_scroll->set_value( pos - (settings_limit - name_limit) / scale ); + } + + timeline_pos=pos; + emit_signal("timeline_changed",pos,true); + + + + } break; + case ClickOver::CLICK_SELECT_KEYS: { + + click.to=Point2(mb.x,mb.y); + if (click.to.y<h && click.at.y>h && mb.relative_y<0) { + + float prev = v_scroll->get_value(); + v_scroll->set_value( v_scroll->get_value() -1 ); + if (prev!=v_scroll->get_value()) + click.at.y+=h; + + + } + if (click.to.y>size.height && click.at.y<size.height && mb.relative_y>0) { + + float prev = v_scroll->get_value(); + v_scroll->set_value( v_scroll->get_value() +1 ); + if (prev!=v_scroll->get_value()) + click.at.y-=h; + } + + } break; + case ClickOver::CLICK_MOVE_KEYS: { + + click.to=Point2(mb.x,mb.y); + } break; + default: {} + } + + return; + } else if (mb.button_mask&BUTTON_MASK_MIDDLE) { + + int rel = mb.relative_x; + float relf = rel / _get_zoom_scale(); + h_scroll->set_value( h_scroll->get_value() - relf ); + } + + if (mb.button_mask==0) { + + + Point2 mpos = Point2(mb.x,mb.y)-ofs; + + if (mpos.y < h ) { +#if 0 + //seek + //int zoomw = settings_limit-name_limit; + float scale = _get_zoom_scale(); + float pos = h_scroll->get_val() + (mpos.y-name_limit) / scale; + if (pos<0 ) + pos=0; + if (pos>=animation->get_length()) + pos=animation->get_length(); + timeline->set_val(pos); +#endif + return; + } + + mpos.y -= h; + + int idx = mpos.y / h; + idx+=v_scroll->get_value(); + if (idx <0 || idx>=animation->get_track_count()) + break; + + mouse_over.track=idx; + + if (mpos.x < name_limit) { + //name column + + + mouse_over.over=MouseOver::OVER_NAME; + + } else if (mpos.x < settings_limit) { + + float pos = mpos.x - name_limit; + pos/=_get_zoom_scale(); + pos+=h_scroll->get_value(); + float w_time = (type_icon[0]->get_width() / _get_zoom_scale())/2.0; + + int kidx = animation->track_find_key(idx,pos); + int kidx_n = kidx+1; + + bool found = false; + + if (kidx>=0 && kidx<animation->track_get_key_count(idx)) { + + float kpos = animation->track_get_key_time(idx,kidx); + if (ABS(pos-kpos)<=w_time) { + + mouse_over.over=MouseOver::OVER_KEY; + mouse_over.track=idx; + mouse_over.over_key=kidx; + found=true; + } + } + + if (!found && kidx_n>=0 && kidx_n<animation->track_get_key_count(idx)) { + + float kpos = animation->track_get_key_time(idx,kidx_n); + if (ABS(pos-kpos)<=w_time) { + + mouse_over.over=MouseOver::OVER_KEY; + mouse_over.track=idx; + mouse_over.over_key=kidx_n; + found=true; + } + } + + + if (found) { + + String text; + text="time: "+rtos(animation->track_get_key_time(idx,mouse_over.over_key))+"\n"; + + + switch(animation->track_get_type(idx)) { + + case Animation::TYPE_TRANSFORM: { + + Dictionary d = animation->track_get_key_value(idx,mouse_over.over_key); + if (d.has("loc")) + text+="loc: "+String(d["loc"])+"\n"; + if (d.has("rot")) + text+="rot: "+String(d["rot"])+"\n"; + if (d.has("scale")) + text+="scale: "+String(d["scale"])+"\n"; + } break; + case Animation::TYPE_VALUE: { + + Variant v = animation->track_get_key_value(idx,mouse_over.over_key); + //text+="value: "+String(v)+"\n"; + + bool prop_exists=false; + Variant::Type valid_type=Variant::NIL; + Object *obj=NULL; + + RES res; + Node *node = root->get_node_and_resource(animation->track_get_path(idx),res); + + if (res.is_valid()) { + obj=res.ptr(); + } else if (node) { + obj=node; + } + + if (obj) { + valid_type=obj->get_static_property_type(animation->track_get_path(idx).get_property(),&prop_exists); + } + + text+="type: "+Variant::get_type_name(v.get_type())+"\n"; + if (prop_exists && !Variant::can_convert(v.get_type(),valid_type)) { + text+="value: "+String(v)+" (Invalid, expected type: "+Variant::get_type_name(valid_type)+")\n"; + } else { + text+="value: "+String(v)+"\n"; + } + + } break; + case Animation::TYPE_METHOD: { + + + Dictionary d = animation->track_get_key_value(idx,mouse_over.over_key); + if (d.has("method")) + text+=String(d["method"]); + text+="("; + Vector<Variant> args; + if (d.has("args")) + args=d["args"]; + for(int i=0;i<args.size();i++) { + + if (i>0) + text+=", "; + text+=String(args[i]); + } + text+=")\n"; + + } break; + } + text+="easing: "+rtos(animation->track_get_key_transition(idx,mouse_over.over_key)); + + + + track_editor->set_tooltip(text); + return; + + } + + } else { + //button column + int ofsx = size.width - mpos.x; + if (ofsx < 0) + break; +/* + if (ofsx < remove_icon->get_width()) { + + mouse_over.over=MouseOver::OVER_REMOVE; + + return; + } + + ofsx-=hsep+remove_icon->get_width(); + + if (ofsx < move_down_icon->get_width()) { + + mouse_over.over=MouseOver::OVER_DOWN; + return; + } + + ofsx-=hsep+move_down_icon->get_width(); + + if (ofsx < move_up_icon->get_width()) { + + mouse_over.over=MouseOver::OVER_UP; + return; + } + + ofsx-=hsep*3+move_up_icon->get_width(); + + */ + + if (ofsx < down_icon->get_width() + wrap_icon[0]->get_width() + hsep*3) { + + mouse_over.over=MouseOver::OVER_WRAP; + return; + } + + ofsx-=hsep*3+wrap_icon[0]->get_width() + down_icon->get_width(); + + if (ofsx < down_icon->get_width() + interp_icon[0]->get_width() + hsep*3) { + + mouse_over.over=MouseOver::OVER_INTERP; + return; + } + + + ofsx-=hsep*2+interp_icon[0]->get_width() + down_icon->get_width(); + + if (ofsx < down_icon->get_width() + cont_icon[0]->get_width() +hsep*3) { + + mouse_over.over=MouseOver::OVER_VALUE; + return; + } + + ofsx-=hsep*3+cont_icon[0]->get_width() + down_icon->get_width(); + + if (ofsx < add_key_icon->get_width()) { + + mouse_over.over=MouseOver::OVER_ADD_KEY; + return; + } + + + } + + } + + } break; + + } +} + +void AnimationKeyEditor::_notification(int p_what) { + + + switch(p_what) { + case NOTIFICATION_VISIBILITY_CHANGED: { + + EditorNode::get_singleton()->update_keying(); + emit_signal("keying_changed"); + } break; + + case NOTIFICATION_ENTER_TREE: { + + key_editor->edit(key_edit); + + zoomicon->set_texture( get_icon("Zoom","EditorIcons") ); + + menu_add_track->set_icon(get_icon("AddTrack","EditorIcons")); + menu_add_track->get_popup()->add_icon_item(get_icon("KeyValue","EditorIcons"),"Add Normal Track",ADD_TRACK_MENU_ADD_VALUE_TRACK); + menu_add_track->get_popup()->add_icon_item(get_icon("KeyXform","EditorIcons"),"Add Transform Track",ADD_TRACK_MENU_ADD_TRANSFORM_TRACK); + menu_add_track->get_popup()->add_icon_item(get_icon("KeyCall","EditorIcons"),"Add Call Func Track",ADD_TRACK_MENU_ADD_CALL_TRACK); + + menu_track->set_icon(get_icon("Tools","EditorIcons")); + menu_track->get_popup()->add_item(TTR("Scale Selection"),TRACK_MENU_SCALE); + menu_track->get_popup()->add_item(TTR("Scale From Cursor"),TRACK_MENU_SCALE_PIVOT); + menu_track->get_popup()->add_separator(); + menu_track->get_popup()->add_item(TTR("Duplicate Selection"),TRACK_MENU_DUPLICATE); + menu_track->get_popup()->add_item(TTR("Duplicate Transposed"),TRACK_MENU_DUPLICATE_TRANSPOSE); + menu_track->get_popup()->add_separator(); + menu_track->get_popup()->add_item(TTR("Goto Next Step"),TRACK_MENU_NEXT_STEP,KEY_MASK_CMD|KEY_RIGHT); + menu_track->get_popup()->add_item(TTR("Goto Prev Step"),TRACK_MENU_PREV_STEP,KEY_MASK_CMD|KEY_LEFT); + menu_track->get_popup()->add_separator(); + PopupMenu *tpp = memnew( PopupMenu ); + tpp->add_item(TTR("Linear"),TRACK_MENU_SET_ALL_TRANS_LINEAR); + tpp->add_item(TTR("Constant"),TRACK_MENU_SET_ALL_TRANS_CONSTANT); + tpp->add_item(TTR("In"),TRACK_MENU_SET_ALL_TRANS_IN); + tpp->add_item(TTR("Out"),TRACK_MENU_SET_ALL_TRANS_OUT); + tpp->add_item(TTR("In-Out"),TRACK_MENU_SET_ALL_TRANS_INOUT); + tpp->add_item(TTR("Out-In"),TRACK_MENU_SET_ALL_TRANS_OUTIN); + tpp->set_name(TTR("Transitions")); + tpp->connect("id_pressed",this,"_menu_track"); + optimize_dialog->connect("confirmed",this,"_animation_optimize"); + + menu_track->get_popup()->add_child(tpp); + //menu_track->get_popup()->add_submenu_item("Set Transitions..","Transitions"); + //menu_track->get_popup()->add_separator(); + menu_track->get_popup()->add_item(TTR("Optimize Animation"),TRACK_MENU_OPTIMIZE); + menu_track->get_popup()->add_item(TTR("Clean-Up Animation"),TRACK_MENU_CLEAN_UP); + + curve_linear->set_icon(get_icon("CurveLinear","EditorIcons")); + curve_in->set_icon(get_icon("CurveIn","EditorIcons")); + curve_out->set_icon(get_icon("CurveOut","EditorIcons")); + curve_inout->set_icon(get_icon("CurveInOut","EditorIcons")); + curve_outin->set_icon(get_icon("CurveOutIn","EditorIcons")); + curve_constant->set_icon(get_icon("CurveConstant","EditorIcons")); + + curve_linear->connect("pressed",this,"_menu_track",varray(CURVE_SET_LINEAR)); + curve_in->connect("pressed",this,"_menu_track",varray(CURVE_SET_IN)); + curve_out->connect("pressed",this,"_menu_track",varray(CURVE_SET_OUT)); + curve_inout->connect("pressed",this,"_menu_track",varray(CURVE_SET_INOUT)); + curve_outin->connect("pressed",this,"_menu_track",varray(CURVE_SET_OUTIN)); + curve_constant->connect("pressed",this,"_menu_track",varray(CURVE_SET_CONSTANT)); + + + move_up_button->set_icon(get_icon("MoveUp","EditorIcons")); + move_down_button->set_icon(get_icon("MoveDown","EditorIcons")); + remove_button->set_icon(get_icon("Remove","EditorIcons")); + edit_button->set_icon(get_icon("EditKey","EditorIcons")); + edit_button->connect("pressed",this,"_toggle_edit_curves"); + + loop->set_icon(get_icon("Loop","EditorIcons")); + curve_edit->connect("transition_changed",this,"_curve_transition_changed"); + + //edit_button->add_color_override("font_color",get_color("font_color","Tree")); + //edit_button->add_color_override("font_color_hover",get_color("font_color","Tree")); + + { + + right_data_size_cache=0; + int hsep = get_constant("hseparation","Tree"); + Ref<Texture> remove_icon = get_icon("Remove","EditorIcons"); + Ref<Texture> move_up_icon = get_icon("MoveUp","EditorIcons"); + Ref<Texture> move_down_icon = get_icon("MoveDown","EditorIcons"); + Ref<Texture> down_icon = get_icon("select_arrow","Tree"); + Ref<Texture> add_key_icon = get_icon("TrackAddKey","EditorIcons"); + Ref<Texture> interp_icon[3]={ + get_icon("InterpRaw","EditorIcons"), + get_icon("InterpLinear","EditorIcons"), + get_icon("InterpCubic","EditorIcons") + }; + Ref<Texture> cont_icon[3]={ + get_icon("TrackContinuous","EditorIcons"), + get_icon("TrackDiscrete","EditorIcons"), + get_icon("TrackTrigger","EditorIcons") + }; + + Ref<Texture> wrap_icon[2]={ + get_icon("InterpWrapClamp","EditorIcons"), + get_icon("InterpWrapLoop","EditorIcons"), + }; + + //right_data_size_cache = remove_icon->get_width() + move_up_icon->get_width() + move_down_icon->get_width() + down_icon->get_width() *2 + interp_icon[0]->get_width() + cont_icon[0]->get_width() + add_key_icon->get_width() + hsep*11; + right_data_size_cache = down_icon->get_width() *3 + add_key_icon->get_width() + interp_icon[0]->get_width() + cont_icon[0]->get_width() + wrap_icon[0]->get_width() + hsep*8; + + + } + call_select->connect("selected",this,"_add_call_track"); + //rename_anim->set_icon( get_icon("Rename","EditorIcons") ); +/* + edit_anim->set_icon( get_icon("Edit","EditorIcons") ); + blend_anim->set_icon( get_icon("Blend","EditorIcons") ); + play->set_icon( get_icon("Play","EditorIcons") ); + stop->set_icon( get_icon("Stop","EditorIcons") ); + pause->set_icon( get_icon("Pause","EditorIcons") ); +*/ + //menu->set_icon(get_icon("Animation","EditorIcons")); + //play->set_icon(get_icon("AnimationPlay","EditorIcons")); + //menu->set_icon(get_icon("Animation","EditorIcons")); + _update_menu(); + + } break; + + + } + +} + + + +void AnimationKeyEditor::_scroll_changed(double) { + + if (te_drawing) + return; + + track_editor->update(); +} + + + +void AnimationKeyEditor::_update_paths() { + + if (animation.is_valid()) { + //timeline->set_max(animation->get_length()); + //timeline->set_step(0.01); + track_editor->update(); + length->set_value(animation->get_length()); + step->set_value(animation->get_step()); + } +} + + +void AnimationKeyEditor::_root_removed() { + + root=NULL; +} + +void AnimationKeyEditor::_update_menu() { + + + updating=true; + + if (animation.is_valid()) { + + length->set_value(animation->get_length()); + loop->set_pressed(animation->has_loop()); + step->set_value(animation->get_step()); + } + + track_editor->update(); + updating=false; + +} +void AnimationKeyEditor::_clear_selection() { + + selection.clear(); + key_edit->animation=Ref<Animation>(); + key_edit->track=0; + key_edit->key_ofs=0; + key_edit->hint=PropertyInfo(); + key_edit->base=NodePath(); + key_edit->notify_change(); + +} + + +void AnimationKeyEditor::set_animation(const Ref<Animation>& p_anim) { + + if (animation.is_valid()) + animation->disconnect("changed",this,"_update_paths"); + animation=p_anim; + if (animation.is_valid()) + animation->connect("changed",this,"_update_paths"); + + timeline_pos=0; + _clear_selection(); + _update_paths(); + + _update_menu(); + selected_track=-1; + _edit_if_single_selection(); + + EditorNode::get_singleton()->update_keying(); +} + +void AnimationKeyEditor::set_root(Node *p_root) { + + if (root) + root->disconnect("tree_exited",this,"_root_removed"); + + root=p_root; + + if (root) + root->connect("tree_exited",this,"_root_removed",make_binds(),CONNECT_ONESHOT); + + +} + +Node *AnimationKeyEditor::get_root() const { + + return root; +} + + + + + + +void AnimationKeyEditor::update_keying() { + + bool keying_enabled=is_visible_in_tree() && animation.is_valid(); + + if (keying_enabled==keying) + return; + + keying=keying_enabled; + _update_menu(); + emit_signal("keying_changed"); + +} + +bool AnimationKeyEditor::has_keying() const { + + return keying; +} + +void AnimationKeyEditor::_query_insert(const InsertData& p_id) { + + + if (insert_frame!=Engine::get_singleton()->get_frames_drawn()) { + //clear insert list for the frame if frame changed + if (insert_confirm->is_visible_in_tree()) + return; //do nothing + insert_data.clear(); + insert_query=false; + } + insert_frame=Engine::get_singleton()->get_frames_drawn(); + + for (List<InsertData>::Element *E=insert_data.front();E;E=E->next()) { + //prevent insertion of multiple tracks + if (E->get().path==p_id.path) + return; //already inserted a track for this on this frame + } + + insert_data.push_back(p_id); + + if (p_id.track_idx==-1) { + if (bool(EDITOR_DEF("editors/animation/confirm_insert_track",true))) { + //potential new key, does not exist + if (insert_data.size()==1) + insert_confirm->set_text(vformat(TTR("Create NEW track for %s and insert key?"),p_id.query)); + else + insert_confirm->set_text(vformat(TTR("Create %d NEW tracks and insert keys?"),insert_data.size())); + + insert_confirm->get_ok()->set_text(TTR("Create")); + insert_confirm->popup_centered_minsize(); + insert_query=true; + } else { + call_deferred("_insert_delay"); + insert_queue=true; + } + + } else { + if (!insert_query && !insert_queue) { + call_deferred("_insert_delay"); + insert_queue=true; + } + } + +} + +void AnimationKeyEditor::insert_transform_key(Spatial *p_node,const String& p_sub,const Transform& p_xform) { + + if (!keying) + return; + if (!animation.is_valid()) + return; + + + ERR_FAIL_COND(!root); + //let's build a node path + String path = root->get_path_to(p_node); + if (p_sub!="") + path+=":"+p_sub; + + NodePath np=path; + + int track_idx=-1; + + for(int i=0;i<animation->get_track_count();i++) { + + if (animation->track_get_type(i)!=Animation::TYPE_TRANSFORM) + continue; + if (animation->track_get_path(i)!=np) + continue; + + track_idx=i; + break; + } + + InsertData id; + Dictionary val; + + id.path=np; + id.track_idx=track_idx; + id.value=p_xform; + id.type=Animation::TYPE_TRANSFORM; + id.query="node '"+p_node->get_name()+"'"; + id.advance=false; + + //dialog insert + + _query_insert(id); + +} + + +void AnimationKeyEditor::insert_node_value_key(Node* p_node, const String& p_property,const Variant& p_value,bool p_only_if_exists) { + + ERR_FAIL_COND(!root); + //let's build a node path + + Node *node = p_node; + + String path = root->get_path_to(node); + + for(int i=1;i<history->get_path_size();i++) { + + String prop = history->get_path_property(i); + ERR_FAIL_COND(prop==""); + path+=":"+prop; + } + + + path+=":"+p_property; + + NodePath np = path; + + //locate track + + int track_idx=-1; + + for(int i=0;i<animation->get_track_count();i++) { + + if (animation->track_get_type(i)!=Animation::TYPE_VALUE) + continue; + if (animation->track_get_path(i)!=np) + continue; + + track_idx=i; + break; + } + + if (p_only_if_exists && track_idx==-1) + return; + InsertData id; + id.path=np; + id.track_idx=track_idx; + id.value=p_value; + id.type=Animation::TYPE_VALUE; + id.query="property '"+p_property+"'"; + id.advance=false; + //dialog insert + _query_insert(id); + + + +} + +void AnimationKeyEditor::insert_value_key(const String& p_property,const Variant& p_value,bool p_advance) { + + ERR_FAIL_COND(!root); + //let's build a node path + ERR_FAIL_COND(history->get_path_size()==0); + Object *obj = ObjectDB::get_instance(history->get_path_object(0)); + ERR_FAIL_COND(!obj || !obj->cast_to<Node>()); + + Node *node = obj->cast_to<Node>(); + + String path = root->get_path_to(node); + + for(int i=1;i<history->get_path_size();i++) { + + String prop = history->get_path_property(i); + ERR_FAIL_COND(prop==""); + path+=":"+prop; + } + + + + path+=":"+p_property; + + NodePath np = path; + + //locate track + + int track_idx=-1; + + for(int i=0;i<animation->get_track_count();i++) { + + if (animation->track_get_type(i)!=Animation::TYPE_VALUE) + continue; + if (animation->track_get_path(i)!=np) + continue; + + track_idx=i; + break; + } + + InsertData id; + id.path=np; + id.track_idx=track_idx; + id.value=p_value; + id.type=Animation::TYPE_VALUE; + id.query="property '"+p_property+"'"; + id.advance=p_advance; + //dialog insert + _query_insert(id); + + + +} + +void AnimationKeyEditor::_confirm_insert_list() { + + + undo_redo->create_action(TTR("Anim Create & Insert")); + + int last_track = animation->get_track_count(); + while(insert_data.size()) { + + last_track=_confirm_insert(insert_data.front()->get(),last_track); + insert_data.pop_front(); + } + + undo_redo->commit_action(); +} + +int AnimationKeyEditor::_confirm_insert(InsertData p_id,int p_last_track) { + + if (p_last_track==-1) + p_last_track=animation->get_track_count(); + + bool created=false; + if (p_id.track_idx<0) { + + created=true; + undo_redo->create_action(TTR("Anim Insert Track & Key")); + Animation::UpdateMode update_mode=Animation::UPDATE_DISCRETE; + + if (p_id.type==Animation::TYPE_VALUE) { + //wants a new tack + + { + //shitty hack + NodePath np; + animation->add_track(p_id.type); + animation->track_set_path(animation->get_track_count()-1,p_id.path); + PropertyInfo h = _find_hint_for_track(animation->get_track_count()-1,np); + animation->remove_track(animation->get_track_count()-1); //hack + + if ( h.type==Variant::REAL || + h.type==Variant::VECTOR2 || + h.type==Variant::RECT2 || + h.type==Variant::VECTOR3 || + h.type==Variant::RECT3 || + h.type==Variant::QUAT || + h.type==Variant::COLOR || + h.type==Variant::TRANSFORM ) { + + update_mode=Animation::UPDATE_CONTINUOUS; + } + + if (h.usage&PROPERTY_USAGE_ANIMATE_AS_TRIGGER) { + update_mode=Animation::UPDATE_TRIGGER; + } + } + } + + p_id.track_idx=p_last_track; + + undo_redo->add_do_method(animation.ptr(),"add_track",p_id.type); + undo_redo->add_do_method(animation.ptr(),"track_set_path",p_id.track_idx,p_id.path); + if (p_id.type==Animation::TYPE_VALUE) + undo_redo->add_do_method(animation.ptr(),"value_track_set_update_mode",p_id.track_idx,update_mode); + + } else { + undo_redo->create_action(TTR("Anim Insert Key")); + } + + float time = timeline_pos; + Variant value; + + + switch(p_id.type) { + + case Animation::TYPE_VALUE: { + + value = p_id.value; + + + } break; + case Animation::TYPE_TRANSFORM: { + + + Transform tr = p_id.value; + Dictionary d; + d["loc"]=tr.origin; + d["scale"]=tr.basis.get_scale(); + d["rot"]=Quat(tr.basis);//.orthonormalized(); + value=d; + } break; + default:{} + } + + + + undo_redo->add_do_method(animation.ptr(),"track_insert_key",p_id.track_idx,time,value); + + if (created) { + + //just remove the track + undo_redo->add_undo_method(animation.ptr(),"remove_track",p_last_track); + p_last_track++; + } else { + + undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",p_id.track_idx,time); + int existing = animation->track_find_key(p_id.track_idx,time,true); + if (existing!=-1) { + Variant v = animation->track_get_key_value(p_id.track_idx,existing); + float trans = animation->track_get_key_transition(p_id.track_idx,existing); + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",p_id.track_idx,time,v,trans); + } + } + + undo_redo->add_do_method(this,"update"); + undo_redo->add_undo_method(this,"update"); + undo_redo->add_do_method(track_editor,"update"); + undo_redo->add_undo_method(track_editor,"update"); + undo_redo->add_do_method(track_pos,"update"); + undo_redo->add_undo_method(track_pos,"update"); + + undo_redo->commit_action(); + + return p_last_track; + +} + + + + +Ref<Animation> AnimationKeyEditor::get_current_animation() const { + + return animation; +} + +void AnimationKeyEditor::_animation_len_changed(float p_len) { + + + if (updating) + return; + + if (!animation.is_null()) { + + undo_redo->create_action(TTR("Change Anim Len")); + undo_redo->add_do_method(animation.ptr(),"set_length",p_len); + undo_redo->add_undo_method(animation.ptr(),"set_length",animation->get_length()); + undo_redo->add_do_method(this,"_animation_len_update"); + undo_redo->add_undo_method(this,"_animation_len_update"); + undo_redo->commit_action(); + } +} + +void AnimationKeyEditor::_animation_len_update() { + + if (!animation.is_null()) + emit_signal(alc,animation->get_length()); +} + +void AnimationKeyEditor::_animation_changed() { + if (updating) + return; + _update_menu(); + +} + +void AnimationKeyEditor::_animation_loop_changed() { + + if (updating) + return; + + if (!animation.is_null()) { + + undo_redo->create_action(TTR("Change Anim Loop")); + undo_redo->add_do_method(animation.ptr(),"set_loop",loop->is_pressed()); + undo_redo->add_undo_method(animation.ptr(),"set_loop",!loop->is_pressed()); + undo_redo->commit_action(); + } + +} + + +void AnimationKeyEditor::_create_value_item(int p_type) { + + undo_redo->create_action(TTR("Anim Create Typed Value Key")); + + Variant::CallError ce; + Variant v = Variant::construct(Variant::Type(p_type),NULL,0,ce); + undo_redo->add_do_method(animation.ptr(),"track_insert_key",cvi_track,cvi_pos,v); + undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",cvi_track,cvi_pos); + + int existing = animation->track_find_key(cvi_track,cvi_pos,true); + + if (existing!=-1) { + Variant v = animation->track_get_key_value(cvi_track,existing); + float trans = animation->track_get_key_transition(cvi_track,existing); + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",cvi_track,cvi_pos,v,trans); + } + + undo_redo->commit_action(); + +} + + +void AnimationKeyEditor::set_anim_pos(float p_pos) { + + if (animation.is_null()) + return; + timeline_pos=p_pos; + update(); + track_pos->update(); + track_editor->update(); +} + +void AnimationKeyEditor::_pane_drag(const Point2& p_delta) { + + Size2 ecs = ec->get_custom_minimum_size(); + ecs.y-=p_delta.y; + if (ecs.y<100) + ecs.y=100; + ec->set_custom_minimum_size(ecs); + +} + +void AnimationKeyEditor::_insert_delay() { + + if (insert_query) { + //discard since it's entered into query mode + insert_queue=false; + return; + } + + undo_redo->create_action(TTR("Anim Insert")); + + int last_track = animation->get_track_count(); + bool advance=false; + while(insert_data.size()) { + + if (insert_data.front()->get().advance) + advance=true; + last_track=_confirm_insert(insert_data.front()->get(),last_track); + insert_data.pop_front(); + } + + undo_redo->commit_action(); + + if (advance) { + float step = animation->get_step(); + if (step==0) + step=1; + + float pos=timeline_pos; + + pos=Math::stepify(pos+step,step); + if (pos>animation->get_length()) + pos=animation->get_length(); + timeline_pos=pos; + track_pos->update(); + emit_signal("timeline_changed",pos,true); + } + insert_queue=false; +} + +void AnimationKeyEditor::_step_changed(float p_len) { + + updating=true; + if (!animation.is_null()) { + animation->set_step(p_len); + emit_signal("animation_step_changed",animation->get_step()); + } + updating=false; +} + +void AnimationKeyEditor::_scale() { + + + if (selection.empty()) + return; + + + float from_t = 1e20; + float to_t = -1e20; + float len = -1e20; + float pivot=0; + + for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { + float t = animation->track_get_key_time(E->key().track,E->key().key); + if (t<from_t) + from_t=t; + if (t>to_t) + to_t=t; + + } + + len=to_t-from_t; + if (last_menu_track_opt==TRACK_MENU_SCALE_PIVOT) { + pivot = timeline_pos; + + } else { + + pivot=from_t; + + } + + float s = scale->get_value(); + if (s==0) { + ERR_PRINT("Can't scale to 0"); + } + + + + undo_redo->create_action(TTR("Anim Scale Keys")); + + List<_AnimMoveRestore> to_restore; + + // 1-remove the keys + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + undo_redo->add_do_method(animation.ptr(),"track_remove_key",E->key().track,E->key().key); + } + // 2- remove overlapped keys + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + float newtime = (E->get().pos-from_t)*s+from_t; + int idx = animation->track_find_key(E->key().track,newtime,true); + if (idx==-1) + continue; + SelectedKey sk; + sk.key=idx; + sk.track=E->key().track; + if (selection.has(sk)) + continue; //already in selection, don't save + + undo_redo->add_do_method(animation.ptr(),"track_remove_key_at_pos",E->key().track,newtime); + _AnimMoveRestore amr; + + amr.key=animation->track_get_key_value(E->key().track,idx); + amr.track=E->key().track; + amr.time=newtime; + amr.transition=animation->track_get_key_transition(E->key().track,idx); + + to_restore.push_back(amr); + + } + +#define _NEW_POS(m_ofs) (((s>0)?m_ofs:from_t+(len-(m_ofs-from_t)))-pivot)*ABS(s)+from_t + // 3-move the keys (re insert them) + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + float newpos=_NEW_POS(E->get().pos); + undo_redo->add_do_method(animation.ptr(),"track_insert_key",E->key().track,newpos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); + + } + + // 4-(undo) remove inserted keys + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + float newpos=_NEW_POS(E->get().pos); + undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",E->key().track,newpos); + + } + + // 5-(undo) reinsert keys + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",E->key().track,E->get().pos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); + + } + + // 6-(undo) reinsert overlapped keys + for(List<_AnimMoveRestore>::Element *E=to_restore.front();E;E=E->next()) { + + _AnimMoveRestore &amr = E->get(); + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",amr.track,amr.time,amr.key,amr.transition); + + } + + // 6-(undo) reinsert overlapped keys + for(List<_AnimMoveRestore>::Element *E=to_restore.front();E;E=E->next()) { + + _AnimMoveRestore &amr = E->get(); + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",amr.track,amr.time,amr.key,amr.transition); + + } + + undo_redo->add_do_method(this,"_clear_selection_for_anim",animation); + undo_redo->add_undo_method(this,"_clear_selection_for_anim",animation); + + // 7-reselect + + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + float oldpos=E->get().pos; + float newpos=_NEW_POS(oldpos); + if (newpos>=0) + undo_redo->add_do_method(this,"_select_at_anim",animation,E->key().track,newpos); + undo_redo->add_undo_method(this,"_select_at_anim",animation,E->key().track,oldpos); + + } +#undef _NEW_POS + undo_redo->commit_action(); + +} + + +void AnimationKeyEditor::_add_call_track(const NodePath& p_base) { + + + Node* base = EditorNode::get_singleton()->get_edited_scene(); + if (!base) + return; + Node* from=base->get_node(p_base); + if (!from || !root) + return; + + NodePath path = root->get_path_to(from); + + //print_line("root: "+String(root->get_path())); + //print_line("path: "+String(path)); + + undo_redo->create_action(TTR("Anim Add Call Track")); + undo_redo->add_do_method(animation.ptr(),"add_track",Animation::TYPE_METHOD); + undo_redo->add_do_method(animation.ptr(),"track_set_path",animation->get_track_count(),path); + undo_redo->add_undo_method(animation.ptr(),"remove_track",animation->get_track_count()); + undo_redo->commit_action(); + +} + +void AnimationKeyEditor::cleanup() { + + set_animation(Ref<Animation>()); +} + +void AnimationKeyEditor::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_root_removed"),&AnimationKeyEditor::_root_removed); + ClassDB::bind_method(D_METHOD("_scale"),&AnimationKeyEditor::_scale); + ClassDB::bind_method(D_METHOD("set_root"),&AnimationKeyEditor::set_root); + + + //ClassDB::bind_method(D_METHOD("_confirm_insert"),&AnimationKeyEditor::_confirm_insert); + ClassDB::bind_method(D_METHOD("_confirm_insert_list"),&AnimationKeyEditor::_confirm_insert_list); + + + + ClassDB::bind_method(D_METHOD("_update_paths"),&AnimationKeyEditor::_update_paths); + ClassDB::bind_method(D_METHOD("_track_editor_draw"),&AnimationKeyEditor::_track_editor_draw); + + + + + ClassDB::bind_method(D_METHOD("_animation_changed"),&AnimationKeyEditor::_animation_changed); + ClassDB::bind_method(D_METHOD("_scroll_changed"),&AnimationKeyEditor::_scroll_changed); + ClassDB::bind_method(D_METHOD("_track_editor_gui_input"),&AnimationKeyEditor::_track_editor_gui_input); + ClassDB::bind_method(D_METHOD("_track_name_changed"),&AnimationKeyEditor::_track_name_changed); + ClassDB::bind_method(D_METHOD("_track_menu_selected"),&AnimationKeyEditor::_track_menu_selected); + ClassDB::bind_method(D_METHOD("_menu_add_track"),&AnimationKeyEditor::_menu_add_track); + ClassDB::bind_method(D_METHOD("_menu_track"),&AnimationKeyEditor::_menu_track); + ClassDB::bind_method(D_METHOD("_clear_selection_for_anim"),&AnimationKeyEditor::_clear_selection_for_anim); + ClassDB::bind_method(D_METHOD("_select_at_anim"),&AnimationKeyEditor::_select_at_anim); + ClassDB::bind_method(D_METHOD("_track_pos_draw"),&AnimationKeyEditor::_track_pos_draw); + ClassDB::bind_method(D_METHOD("_insert_delay"),&AnimationKeyEditor::_insert_delay); + ClassDB::bind_method(D_METHOD("_step_changed"),&AnimationKeyEditor::_step_changed); + + + ClassDB::bind_method(D_METHOD("_animation_loop_changed"),&AnimationKeyEditor::_animation_loop_changed); + ClassDB::bind_method(D_METHOD("_animation_len_changed"),&AnimationKeyEditor::_animation_len_changed); + ClassDB::bind_method(D_METHOD("_create_value_item"),&AnimationKeyEditor::_create_value_item); + ClassDB::bind_method(D_METHOD("_pane_drag"),&AnimationKeyEditor::_pane_drag); + + ClassDB::bind_method(D_METHOD("_animation_len_update"),&AnimationKeyEditor::_animation_len_update); + + ClassDB::bind_method(D_METHOD("set_animation"),&AnimationKeyEditor::set_animation); + ClassDB::bind_method(D_METHOD("_animation_optimize"),&AnimationKeyEditor::_animation_optimize); + ClassDB::bind_method(D_METHOD("_curve_transition_changed"),&AnimationKeyEditor::_curve_transition_changed); + ClassDB::bind_method(D_METHOD("_toggle_edit_curves"),&AnimationKeyEditor::_toggle_edit_curves); + ClassDB::bind_method(D_METHOD("_add_call_track"),&AnimationKeyEditor::_add_call_track); + + + ADD_SIGNAL( MethodInfo("resource_selected", PropertyInfo( Variant::OBJECT, "res"),PropertyInfo( Variant::STRING, "prop") ) ); + ADD_SIGNAL( MethodInfo("keying_changed" ) ); + ADD_SIGNAL( MethodInfo("timeline_changed", PropertyInfo(Variant::REAL,"pos"), PropertyInfo(Variant::BOOL,"drag") ) ); + ADD_SIGNAL( MethodInfo("animation_len_changed", PropertyInfo(Variant::REAL,"len") ) ); + ADD_SIGNAL( MethodInfo("animation_step_changed", PropertyInfo(Variant::REAL,"step") ) ); + ADD_SIGNAL( MethodInfo("key_edited", PropertyInfo(Variant::INT,"track"), PropertyInfo(Variant::INT,"key") ) ); + +} + + +AnimationKeyEditor::AnimationKeyEditor() { + + alc="animation_len_changed"; + editor_selection=EditorNode::get_singleton()->get_editor_selection(); + + selected_track=-1; + updating=false; + te_drawing=false; + undo_redo=EditorNode::get_singleton()->get_undo_redo(); + history=EditorNode::get_singleton()->get_editor_history(); + + ec = memnew (Control); + ec->set_custom_minimum_size(Size2(0,150)); + add_child(ec); + ec->set_v_size_flags(SIZE_EXPAND_FILL); + + h_scroll = memnew( HScrollBar ); + h_scroll->connect("value_changed",this,"_scroll_changed"); + add_child(h_scroll); + h_scroll->set_value(0); + + + HBoxContainer *hb = memnew( HBoxContainer ); + add_child(hb); + + + root=NULL; + //menu = memnew( MenuButton ); + //menu->set_flat(true); + //menu->set_pos(Point2()); + //add_child(menu); + + zoomicon = memnew( TextureRect ); + hb->add_child(zoomicon); + zoomicon->set_tooltip(TTR("Animation zoom.")); + + zoom = memnew( HSlider ); + //hb->add_child(zoom); + zoom->set_step(0.01); + zoom->set_min(0.0); + zoom->set_max(2.0); + zoom->set_value(1.0); + zoom->set_h_size_flags(SIZE_EXPAND_FILL); + zoom->set_stretch_ratio(2); + hb->add_child(zoom); + zoom->connect("value_changed",this,"_scroll_changed"); + zoom->set_tooltip(TTR("Animation zoom.")); + + hb->add_child( memnew( VSeparator ) ); + + Label *l = memnew( Label ); + l->set_text(TTR("Length (s):")); + hb->add_child(l); + + length = memnew( SpinBox ); + length->set_min(0.01); + length->set_max(10000); + length->set_step(0.01); + length->set_h_size_flags(SIZE_EXPAND_FILL); + length->set_stretch_ratio(1); + length->set_tooltip(TTR("Animation length (in seconds).")); + + hb->add_child(length); + length->connect("value_changed",this,"_animation_len_changed"); + + l = memnew( Label ); + l->set_text(TTR("Step (s):")); + hb->add_child(l); + + step = memnew( SpinBox ); + step->set_min(0.00); + step->set_max(128); + step->set_step(0.01); + step->set_value(0.0); + step->set_h_size_flags(SIZE_EXPAND_FILL); + step->set_stretch_ratio(1); + step->set_tooltip(TTR("Cursor step snap (in seconds).")); + + hb->add_child(step); + step->connect("value_changed",this,"_step_changed"); + + loop = memnew( ToolButton ); + loop->set_toggle_mode(true); + loop->connect("pressed",this,"_animation_loop_changed"); + hb->add_child(loop); + loop->set_tooltip(TTR("Enable/Disable looping in animation.")); + + hb->add_child( memnew( VSeparator ) ); + + menu_add_track = memnew( MenuButton ); + hb->add_child(menu_add_track); + menu_add_track->get_popup()->connect("id_pressed",this,"_menu_add_track"); + menu_add_track->set_tooltip(TTR("Add new tracks.")); + + move_up_button = memnew( ToolButton ); + hb->add_child(move_up_button); + move_up_button->connect("pressed",this,"_menu_track",make_binds(TRACK_MENU_MOVE_UP)); + move_up_button->set_focus_mode(FOCUS_NONE); + move_up_button->set_disabled(true); + move_up_button->set_tooltip(TTR("Move current track up.")); + + move_down_button = memnew( ToolButton ); + hb->add_child(move_down_button); + move_down_button->connect("pressed",this,"_menu_track",make_binds(TRACK_MENU_MOVE_DOWN)); + move_down_button->set_focus_mode(FOCUS_NONE); + move_down_button->set_disabled(true); + move_down_button->set_tooltip(TTR("Move current track down.")); + + remove_button = memnew( ToolButton ); + hb->add_child(remove_button); + remove_button->connect("pressed",this,"_menu_track",make_binds(TRACK_MENU_REMOVE)); + remove_button->set_focus_mode(FOCUS_NONE); + remove_button->set_disabled(true); + remove_button->set_tooltip(TTR("Remove selected track.")); + + hb->add_child(memnew( VSeparator )); + + menu_track = memnew( MenuButton ); + hb->add_child(menu_track); + menu_track->get_popup()->connect("id_pressed",this,"_menu_track"); + menu_track->set_tooltip(TTR("Track tools")); + + edit_button = memnew( ToolButton ); + edit_button->set_toggle_mode(true); + edit_button->set_focus_mode(FOCUS_NONE); + edit_button->set_disabled(true); + + hb->add_child(edit_button); + edit_button->set_tooltip(TTR("Enable editing of individual keys by clicking them.")); + + optimize_dialog = memnew( ConfirmationDialog ); + add_child(optimize_dialog); + optimize_dialog->set_title(TTR("Anim. Optimizer")); + VBoxContainer *optimize_vb = memnew( VBoxContainer ); + optimize_dialog->add_child(optimize_vb); + + optimize_linear_error = memnew( SpinBox ); + optimize_linear_error->set_max(1.0); + optimize_linear_error->set_min(0.001); + optimize_linear_error->set_step(0.001); + optimize_linear_error->set_value(0.05); + optimize_vb->add_margin_child(TTR("Max. Linear Error:"),optimize_linear_error); + optimize_angular_error = memnew( SpinBox ); + optimize_angular_error->set_max(1.0); + optimize_angular_error->set_min(0.001); + optimize_angular_error->set_step(0.001); + optimize_angular_error->set_value(0.01); + + optimize_vb->add_margin_child(TTR("Max. Angular Error:"),optimize_angular_error); + optimize_max_angle = memnew( SpinBox ); + optimize_vb->add_margin_child(TTR("Max Optimizable Angle:"),optimize_max_angle); + optimize_max_angle->set_max(360.0); + optimize_max_angle->set_min(0.0); + optimize_max_angle->set_step(0.1); + optimize_max_angle->set_value(22); + + optimize_dialog->get_ok()->set_text(TTR("Optimize")); + + + + /*keying = memnew( Button ); + keying->set_toggle_mode(true); + //keying->set_text("Keys"); + keying->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,60); + keying->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,10); + keying->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_BEGIN,55); + keying->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,10); + //add_child(keying); + keying->connect("pressed",this,"_keying_toggled"); + */ + +/* l = memnew( Label ); + l->set_text("Base: "); + l->set_pos(Point2(0,3)); + //dr_panel->add_child(l);*/ + + //menu->get_popup()->connect("id_pressed",this,"_menu_callback"); + + + hb = memnew( HBoxContainer); + hb->set_area_as_parent_rect(); + ec->add_child(hb); + hb->set_v_size_flags(SIZE_EXPAND_FILL); + + track_editor = memnew( Control ); + track_editor->connect("draw",this,"_track_editor_draw"); + hb->add_child(track_editor); + track_editor->connect("gui_input",this,"_track_editor_gui_input"); + track_editor->set_focus_mode(Control::FOCUS_ALL); + track_editor->set_h_size_flags(SIZE_EXPAND_FILL); + + + + track_pos = memnew( Control ); + track_pos->set_area_as_parent_rect(); + track_pos->set_mouse_filter(MOUSE_FILTER_IGNORE); + track_editor->add_child(track_pos); + track_pos->connect("draw",this,"_track_pos_draw"); + + select_anim_warning = memnew( Label ); + track_editor->add_child(select_anim_warning); + select_anim_warning->set_area_as_parent_rect(); + select_anim_warning->set_text(TTR("Select an AnimationPlayer from the Scene Tree to edit animations.")); + select_anim_warning->set_autowrap(true); + select_anim_warning->set_align(Label::ALIGN_CENTER); + select_anim_warning->set_valign(Label::VALIGN_CENTER); + + + + v_scroll = memnew( VScrollBar ); + hb->add_child(v_scroll); + v_scroll->connect("value_changed",this,"_scroll_changed"); + v_scroll->set_value(0); + + key_editor_tab = memnew(TabContainer); + hb->add_child(key_editor_tab); + key_editor_tab->set_custom_minimum_size(Size2(200,0)); + + key_editor = memnew( PropertyEditor ); + key_editor->set_area_as_parent_rect(); + key_editor->hide_top_label(); + key_editor->set_name(TTR("Key")); + key_editor_tab->add_child(key_editor); + + key_edit = memnew( AnimationKeyEdit ); + key_edit->undo_redo=undo_redo; + //key_edit->ke_dialog=key_edit_dialog; + + type_menu = memnew( PopupMenu ); + add_child(type_menu); + for(int i=0;i<Variant::VARIANT_MAX;i++) + type_menu->add_item(Variant::get_type_name(Variant::Type(i)),i); + type_menu->connect("id_pressed",this,"_create_value_item"); + + VBoxContainer *curve_vb = memnew( VBoxContainer ); + curve_vb->set_name(TTR("Transition")); + HBoxContainer *curve_hb = memnew( HBoxContainer ); + curve_vb->add_child(curve_hb); + + curve_linear = memnew( ToolButton ); + curve_linear->set_focus_mode(FOCUS_NONE); + curve_hb->add_child(curve_linear); + curve_in = memnew( ToolButton ); + curve_in->set_focus_mode(FOCUS_NONE); + curve_hb->add_child(curve_in); + curve_out = memnew( ToolButton ); + curve_out->set_focus_mode(FOCUS_NONE); + curve_hb->add_child(curve_out); + curve_inout = memnew( ToolButton ); + curve_inout->set_focus_mode(FOCUS_NONE); + curve_hb->add_child(curve_inout); + curve_outin = memnew( ToolButton ); + curve_outin->set_focus_mode(FOCUS_NONE); + curve_hb->add_child(curve_outin); + curve_constant = memnew( ToolButton ); + curve_constant->set_focus_mode(FOCUS_NONE); + curve_hb->add_child(curve_constant); + + + curve_edit = memnew( AnimationCurveEdit ); + curve_vb->add_child(curve_edit); + curve_edit->set_v_size_flags(SIZE_EXPAND_FILL); + key_editor_tab->add_child(curve_vb); + + track_name = memnew( LineEdit ); + track_name->set_as_toplevel(true); + track_name->hide(); + add_child(track_name); + track_name->connect("text_entered",this,"_track_name_changed"); + track_menu = memnew( PopupMenu ); + add_child(track_menu); + track_menu->connect("id_pressed",this,"_track_menu_selected"); + + key_editor_tab->hide(); + + last_idx =1; + + _update_menu(); + + + + insert_confirm = memnew( ConfirmationDialog ); + add_child(insert_confirm); + insert_confirm->connect("confirmed",this,"_confirm_insert_list"); + + click.click=ClickOver::CLICK_NONE; + + + name_column_ratio=0.3; + timeline_pos=0; + + + keying=false; + insert_frame=0; + insert_query=false; + insert_queue=false; + + editor_selection->connect("selection_changed",track_editor,"update"); + + + scale_dialog = memnew( ConfirmationDialog ); + VBoxContainer *vbc = memnew( VBoxContainer ); + scale_dialog->add_child(vbc); + + scale = memnew( SpinBox ); + scale->set_min(-99999); + scale->set_max(99999); + scale->set_step(0.001); + vbc->add_margin_child(TTR("Scale Ratio:"),scale); + scale_dialog->connect("confirmed",this,"_scale"); + add_child(scale_dialog); + + call_select = memnew( SceneTreeDialog ); + add_child(call_select); + call_select->set_title(TTR("Call Functions in Which Node?")); + + cleanup_dialog = memnew( ConfirmationDialog ); + add_child(cleanup_dialog); + VBoxContainer *cleanup_vb = memnew( VBoxContainer ); + cleanup_dialog->add_child(cleanup_vb); + + cleanup_keys = memnew( CheckButton ); + cleanup_keys->set_text(TTR("Remove invalid keys")); + cleanup_keys->set_pressed(true); + cleanup_vb->add_child(cleanup_keys); + + cleanup_tracks = memnew( CheckButton ); + cleanup_tracks->set_text(TTR("Remove unresolved and empty tracks")); + cleanup_tracks->set_pressed(true); + cleanup_vb->add_child(cleanup_tracks); + + cleanup_all = memnew( CheckButton ); + cleanup_all->set_text(TTR("Clean-up all animations")); + cleanup_vb->add_child(cleanup_all); + + cleanup_dialog->set_title(TTR("Clean-Up Animation(s) (NO UNDO!)")); + cleanup_dialog->get_ok()->set_text(TTR("Clean-Up")); + + cleanup_dialog->connect("confirmed",this,"_menu_track",varray(TRACK_MENU_CLEAN_UP_CONFIRM)); + + add_constant_override("separation",get_constant("separation","VBoxContainer")); + + track_editor->set_clip_contents(true); + +} + +AnimationKeyEditor::~AnimationKeyEditor() { + + + + memdelete( key_edit ); + +} diff --git a/tools/editor/animation_editor.h b/editor/animation_editor.h index c4539cd763..c4539cd763 100644 --- a/tools/editor/animation_editor.h +++ b/editor/animation_editor.h diff --git a/tools/editor/array_property_edit.cpp b/editor/array_property_edit.cpp index 7304d8dddf..7304d8dddf 100644 --- a/tools/editor/array_property_edit.cpp +++ b/editor/array_property_edit.cpp diff --git a/tools/editor/array_property_edit.h b/editor/array_property_edit.h index 6ca700bf80..6ca700bf80 100644 --- a/tools/editor/array_property_edit.h +++ b/editor/array_property_edit.h diff --git a/tools/editor/asset_library_editor_plugin.cpp b/editor/asset_library_editor_plugin.cpp index 1c1b6c91e3..1c1b6c91e3 100644 --- a/tools/editor/asset_library_editor_plugin.cpp +++ b/editor/asset_library_editor_plugin.cpp diff --git a/tools/editor/asset_library_editor_plugin.h b/editor/asset_library_editor_plugin.h index 0598ea90ea..0598ea90ea 100644 --- a/tools/editor/asset_library_editor_plugin.h +++ b/editor/asset_library_editor_plugin.h diff --git a/tools/editor/call_dialog.cpp b/editor/call_dialog.cpp index 6dfeb87dfd..6dfeb87dfd 100644 --- a/tools/editor/call_dialog.cpp +++ b/editor/call_dialog.cpp diff --git a/editor/call_dialog.h b/editor/call_dialog.h new file mode 100644 index 0000000000..56fc07c3df --- /dev/null +++ b/editor/call_dialog.h @@ -0,0 +1,85 @@ +/*************************************************************************/ +/* call_dialog.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef CALL_DIALOG_H +#define CALL_DIALOG_H + +#include "scene/gui/popup.h" +#include "scene/gui/button.h" +#include "scene/gui/tree.h" +#include "scene/gui/label.h" +#include "scene/gui/line_edit.h" +#include "editor/property_editor.h" +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +#if 0 + +class CallDialogParams; + +class CallDialog : public Popup { + + GDCLASS( CallDialog, Popup ); + + + Label* method_label; + Tree *tree; + Button *call; + Button *cancel; + + CallDialogParams *call_params; + PropertyEditor *property_editor; + + Label *return_label; + LineEdit *return_value; + Object *object; + StringName selected; + + Vector<MethodInfo> methods; + + + void _item_selected(); + void _update_method_list(); + void _call(); + void _cancel(); + +protected: + static void _bind_methods(); + void _notification(int p_what); +public: + + void set_object(Object *p_object,StringName p_selected=""); + + CallDialog(); + ~CallDialog(); + +}; + +#endif +#endif diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp new file mode 100644 index 0000000000..8e9925a0d3 --- /dev/null +++ b/editor/code_editor.cpp @@ -0,0 +1,1323 @@ +/*************************************************************************/ +/* code_editor.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 "code_editor.h" + +#include "editor_settings.h" +#include "scene/gui/margin_container.h" +#include "scene/gui/separator.h" +#include "scene/resources/dynamic_font.h" +#include "os/keyboard.h" +#include "editor/editor_scale.h" + +void GotoLineDialog::popup_find_line(TextEdit *p_edit) { + + text_editor=p_edit; + + line->set_text(itos(text_editor->cursor_get_line())); + line->select_all(); + popup_centered(Size2(180,80)); + line->grab_focus(); +} + + +int GotoLineDialog::get_line() const { + + return line->get_text().to_int(); +} + + +void GotoLineDialog::ok_pressed() { + + if (get_line()<1 || get_line()>text_editor->get_line_count()) + return; + text_editor->cursor_set_line(get_line()-1); + hide(); +} + +GotoLineDialog::GotoLineDialog() { + + set_title(TTR("Go to Line")); + Label *l = memnew(Label); + l->set_text(TTR("Line Number:")); + l->set_pos(Point2(5,5)); + add_child(l); + + line = memnew( LineEdit ); + line->set_anchor( MARGIN_RIGHT, ANCHOR_END ); + line->set_begin( Point2(15,22) ); + line->set_end( Point2(15,35) ); + add_child(line); + register_text_enter(line); + text_editor=NULL; + + set_hide_on_ok(false); +} + + +void FindReplaceBar::_notification(int p_what) { + + if (p_what == NOTIFICATION_READY) { + + find_prev->set_icon(get_icon("MoveUp", "EditorIcons")); + find_next->set_icon(get_icon("MoveDown", "EditorIcons")); + hide_button->set_normal_texture(get_icon("Close","EditorIcons")); + hide_button->set_hover_texture(get_icon("CloseHover","EditorIcons")); + hide_button->set_pressed_texture(get_icon("Close","EditorIcons")); + + } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { + + set_process_unhandled_input(is_visible_in_tree()); + } +} + +void FindReplaceBar::_unhandled_input(const InputEvent &p_event) { + + if (p_event.type == InputEvent::KEY) { + + const InputEventKey& k = p_event.key; + + if (k.pressed && (text_edit->has_focus() || text_vbc->is_a_parent_of(get_focus_owner()))) { + + bool accepted = true; + + switch (k.scancode) { + + case KEY_ESCAPE: { + + _hide_bar(); + } break; + default: { + + accepted = false; + } break; + } + + if (accepted) { + accept_event(); + } + } + } +} + +bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col) { + + int line, col; + String text=get_search_text(); + + bool found=text_edit->search(text,p_flags,p_from_line,p_from_col,line,col); + + if (found) { + if (!preserve_cursor) { + text_edit->cursor_set_line(line, false); + text_edit->cursor_set_column(col+text.length(), false); + text_edit->center_viewport_to_cursor(); + } + + text_edit->set_search_text(text); + text_edit->set_search_flags(p_flags); + text_edit->set_current_search_result(line,col); + + result_line=line; + result_col=col; + + set_error(""); + } else { + result_line=-1; + result_col=-1; + text_edit->set_search_text(""); + set_error(text.empty()?"":TTR("No Matches")); + } + + return found; +} + +void FindReplaceBar::_replace() { + + if (result_line!=-1 && result_col!=-1) { + text_edit->begin_complex_operation(); + + text_edit->select(result_line,result_col,result_line,result_col+get_search_text().length()); + text_edit->insert_text_at_cursor(get_replace_text()); + + text_edit->end_complex_operation(); + } + + search_current(); +} + +void FindReplaceBar::_replace_all() { + + // line as x so it gets priority in comparison, column as y + Point2i orig_cursor(text_edit->cursor_get_line(),text_edit->cursor_get_column()); + Point2i prev_match=Point2(-1,-1); + + bool selection_enabled = text_edit->is_selection_active(); + Point2i selection_begin,selection_end; + if (selection_enabled) { + selection_begin=Point2i(text_edit->get_selection_from_line(),text_edit->get_selection_from_column()); + selection_end=Point2i(text_edit->get_selection_to_line(),text_edit->get_selection_to_column()); + } + + int vsval = text_edit->get_v_scroll(); + + text_edit->cursor_set_line(0); + text_edit->cursor_set_column(0); + + String replace_text=get_replace_text(); + int search_text_len=get_search_text().length(); + + int rc=0; + + replace_all_mode = true; + + text_edit->begin_complex_operation(); + + while (search_next()) { + + // replace area + Point2i match_from(result_line,result_col); + Point2i match_to(result_line,result_col+search_text_len); + + if (match_from < prev_match) + break; // done + + prev_match=Point2i(result_line,result_col+replace_text.length()); + + text_edit->select(result_line,result_col,result_line,match_to.y); + + if (selection_enabled && is_selection_only()) { + + if (match_from<selection_begin || match_to>selection_end) + continue; + + // replace but adjust selection bounds + text_edit->insert_text_at_cursor(replace_text); + if (match_to.x==selection_end.x) + selection_end.y+=replace_text.length()-search_text_len; + } else { + // just replace + text_edit->insert_text_at_cursor(replace_text); + } + + rc++; + } + + text_edit->end_complex_operation(); + + replace_all_mode = false; + + // restore editor state (selection, cursor, scroll) + text_edit->cursor_set_line(orig_cursor.x); + text_edit->cursor_set_column(orig_cursor.y); + + if (selection_enabled && is_selection_only()) { + // reselect + text_edit->select(selection_begin.x,selection_begin.y,selection_end.x,selection_end.y); + } else { + text_edit->deselect(); + } + + text_edit->set_v_scroll(vsval); + set_error(vformat(TTR("Replaced %d Ocurrence(s)."), rc)); +} + +void FindReplaceBar::_get_search_from(int& r_line, int& r_col) { + + r_line=text_edit->cursor_get_line(); + r_col=text_edit->cursor_get_column(); + + if (text_edit->is_selection_active() && !replace_all_mode) { + + int selection_line=text_edit->get_selection_from_line(); + + if (text_edit->get_selection_text()==get_search_text() && r_line==selection_line) { + + int selection_from_col=text_edit->get_selection_from_column(); + + if (r_col>=selection_from_col && r_col<=text_edit->get_selection_to_column()) { + r_col=selection_line; + r_col=selection_from_col; + } + } + } + + if (r_line==result_line && r_col>=result_col && r_col<=result_col+get_search_text().length()) { + r_col=result_col; + } +} + +bool FindReplaceBar::search_current() { + + uint32_t flags=0; + + if (is_whole_words()) + flags|=TextEdit::SEARCH_WHOLE_WORDS; + if (is_case_sensitive()) + flags|=TextEdit::SEARCH_MATCH_CASE; + + int line, col; + _get_search_from(line, col); + + return _search(flags,line,col); +} + +bool FindReplaceBar::search_prev() { + + uint32_t flags=0; + String text = get_search_text(); + + if (is_whole_words()) + flags|=TextEdit::SEARCH_WHOLE_WORDS; + if (is_case_sensitive()) + flags|=TextEdit::SEARCH_MATCH_CASE; + + flags|=TextEdit::SEARCH_BACKWARDS; + + int line, col; + _get_search_from(line, col); + + col-=text.length(); + if (col<0) { + line-=1; + if (line<0) + line=text_edit->get_line_count()-1; + col=text_edit->get_line(line).length(); + } + + return _search(flags,line,col); +} + +bool FindReplaceBar::search_next() { + + uint32_t flags=0; + String text = get_search_text(); + + if (is_whole_words()) + flags|=TextEdit::SEARCH_WHOLE_WORDS; + if (is_case_sensitive()) + flags|=TextEdit::SEARCH_MATCH_CASE; + + int line, col; + _get_search_from(line, col); + + if (line==result_line && col==result_col) { + col+=text.length(); + if (col>text_edit->get_line(line).length()) { + line+=1; + if (line>=text_edit->get_line_count()) + line=0; + col=0; + } + } + + return _search(flags,line,col); +} + +void FindReplaceBar::_hide_bar() { + + if (replace_text->has_focus() || search_text->has_focus()) + text_edit->grab_focus(); + + text_edit->set_search_text(""); + result_line = -1; + result_col = -1; + replace_hbc->hide(); + replace_options_hbc->hide(); + hide(); +} + +void FindReplaceBar::_show_search() { + + show(); + search_text->grab_focus(); + + if (text_edit->is_selection_active() && !selection_only->is_pressed()) { + search_text->set_text(text_edit->get_selection_text()); + } + + if (!get_search_text().empty()) { + search_text->select_all(); + search_text->set_cursor_pos(search_text->get_text().length()); + search_current(); + } +} + +void FindReplaceBar::popup_search() { + + replace_hbc->hide(); + replace_options_hbc->hide(); + _show_search(); +} + +void FindReplaceBar::popup_replace() { + + + if (!replace_hbc->is_visible_in_tree() || !replace_options_hbc->is_visible_in_tree()) { + replace_text->clear(); + replace_hbc->show(); + replace_options_hbc->show(); + + } + + selection_only->set_pressed( (text_edit->is_selection_active() && text_edit->get_selection_from_line() < text_edit->get_selection_to_line()) ); + + _show_search(); +} + +void FindReplaceBar::_search_options_changed(bool p_pressed) { + + search_current(); +} + +void FindReplaceBar::_editor_text_changed() { + + if (is_visible_in_tree()) { + preserve_cursor=true; + search_current(); + preserve_cursor=false; + } +} + +void FindReplaceBar::_search_text_changed(const String& p_text) { + + search_current(); +} + +void FindReplaceBar::_search_text_entered(const String& p_text) { + + search_next(); +} + +void FindReplaceBar::_replace_text_entered(const String& p_text) { + + if (selection_only->is_pressed() && text_edit->is_selection_active()) { + _replace_all(); + _hide_bar(); + } +} + +String FindReplaceBar::get_search_text() const { + + return search_text->get_text(); +} + +String FindReplaceBar::get_replace_text() const { + + return replace_text->get_text(); +} + +bool FindReplaceBar::is_case_sensitive() const { + + return case_sensitive->is_pressed(); +} + +bool FindReplaceBar::is_whole_words() const { + + return whole_words->is_pressed(); +} + +bool FindReplaceBar::is_selection_only() const { + + return selection_only->is_pressed(); +} + +void FindReplaceBar::set_error(const String &p_label) { + + error_label->set_text(p_label); +} + +void FindReplaceBar::set_text_edit(TextEdit *p_text_edit) { + + text_edit = p_text_edit; + text_edit->connect("text_changed",this,"_editor_text_changed"); +} + +void FindReplaceBar::_bind_methods() { + + ClassDB::bind_method("_unhandled_input",&FindReplaceBar::_unhandled_input); + + ClassDB::bind_method("_editor_text_changed",&FindReplaceBar::_editor_text_changed); + ClassDB::bind_method("_search_text_changed",&FindReplaceBar::_search_text_changed); + ClassDB::bind_method("_search_text_entered",&FindReplaceBar::_search_text_entered); + ClassDB::bind_method("_replace_text_entered",&FindReplaceBar::_replace_text_entered); + ClassDB::bind_method("_search_current",&FindReplaceBar::search_current); + ClassDB::bind_method("_search_next",&FindReplaceBar::search_next); + ClassDB::bind_method("_search_prev",&FindReplaceBar::search_prev); + ClassDB::bind_method("_replace_pressed",&FindReplaceBar::_replace); + ClassDB::bind_method("_replace_all_pressed",&FindReplaceBar::_replace_all); + ClassDB::bind_method("_search_options_changed",&FindReplaceBar::_search_options_changed); + ClassDB::bind_method("_hide_pressed",&FindReplaceBar::_hide_bar); + + ADD_SIGNAL(MethodInfo("search")); +} + +FindReplaceBar::FindReplaceBar() { + + replace_all_mode=false; + preserve_cursor=false; + + text_vbc = memnew(VBoxContainer); + add_child(text_vbc); + + HBoxContainer *search_hbc = memnew(HBoxContainer); + text_vbc->add_child(search_hbc); + + search_text = memnew(LineEdit); + search_hbc->add_child(search_text); + search_text->set_custom_minimum_size(Size2(200, 0)); + search_text->connect("text_changed",this,"_search_text_changed"); + search_text->connect("text_entered",this,"_search_text_entered"); + + find_prev = memnew(ToolButton); + search_hbc->add_child(find_prev); + find_prev->set_focus_mode(FOCUS_NONE); + find_prev->connect("pressed",this,"_search_prev"); + + find_next = memnew(ToolButton); + search_hbc->add_child(find_next); + find_next->set_focus_mode(FOCUS_NONE); + find_next->connect("pressed",this,"_search_next"); + + replace_hbc = memnew(HBoxContainer); + text_vbc->add_child(replace_hbc); + replace_hbc->hide(); + + replace_text = memnew(LineEdit); + replace_hbc->add_child(replace_text); + replace_text->set_custom_minimum_size(Size2(200, 0)); + replace_text->connect("text_entered",this,"_replace_text_entered"); + + + replace = memnew(Button); + replace_hbc->add_child(replace); + replace->set_text(TTR("Replace")); + //replace->set_focus_mode(FOCUS_NONE); + replace->connect("pressed",this,"_replace_pressed"); + + replace_all = memnew(Button); + replace_hbc->add_child(replace_all); + replace_all->set_text(TTR("Replace All")); + //replace_all->set_focus_mode(FOCUS_NONE); + replace_all->connect("pressed",this,"_replace_all_pressed"); + + Control *spacer_split = memnew( Control ); + spacer_split->set_custom_minimum_size(Size2(0, 1)); + text_vbc->add_child(spacer_split); + + VBoxContainer *options_vbc = memnew(VBoxContainer); + add_child(options_vbc); + options_vbc->set_h_size_flags(SIZE_EXPAND_FILL); + + HBoxContainer *search_options = memnew(HBoxContainer); + options_vbc->add_child(search_options); + + case_sensitive = memnew(CheckBox); + search_options->add_child(case_sensitive); + case_sensitive->set_text(TTR("Match Case")); + case_sensitive->set_focus_mode(FOCUS_NONE); + case_sensitive->connect("toggled",this,"_search_options_changed"); + + whole_words = memnew(CheckBox); + search_options->add_child(whole_words); + whole_words->set_text(TTR("Whole Words")); + whole_words->set_focus_mode(FOCUS_NONE); + whole_words->connect("toggled",this,"_search_options_changed"); + + error_label = memnew(Label); + search_options->add_child(error_label); + error_label->add_color_override("font_color", Color(1,1,0,1)); + error_label->add_color_override("font_color_shadow", Color(0,0,0,1)); + error_label->add_constant_override("shadow_as_outline", 1); + + search_options->add_spacer(); + + hide_button = memnew(TextureButton); + search_options->add_child(hide_button); + hide_button->set_focus_mode(FOCUS_NONE); + hide_button->connect("pressed",this,"_hide_pressed"); + + replace_options_hbc = memnew(HBoxContainer); + options_vbc->add_child(replace_options_hbc); + replace_options_hbc->hide(); + + selection_only = memnew(CheckBox); + replace_options_hbc->add_child(selection_only); + selection_only->set_text(TTR("Selection Only")); + selection_only->set_focus_mode(FOCUS_NONE); + selection_only->connect("toggled",this,"_search_options_changed"); +} + + +void FindReplaceDialog::popup_search() { + + set_title(TTR("Search")); + replace_mc->hide(); + replace_label->hide(); + replace_vb->hide(); + skip->hide(); + popup_centered(Point2(300,190)); + get_ok()->set_text(TTR("Find")); + search_text->grab_focus(); + if (text_edit->is_selection_active() && ( text_edit->get_selection_from_line() == text_edit->get_selection_to_line())) { + + search_text->set_text( text_edit->get_selection_text() ); + } + search_text->select_all(); + + error_label->set_text(""); + +} + +void FindReplaceDialog::popup_replace() { + + + set_title(TTR("Replace")); + bool do_selection=(text_edit->is_selection_active() && text_edit->get_selection_from_line() < text_edit->get_selection_to_line()); + + set_replace_selection_only(do_selection); + + if (!do_selection && text_edit->is_selection_active()) { + search_text->set_text(text_edit->get_selection_text()); + } + + replace_mc->show(); + replace_label->show(); + replace_vb->show(); + popup_centered(Point2(300,300)); + if (search_text->get_text()!="" && replace_text->get_text()=="") { + search_text->select(0,0); + replace_text->grab_focus(); + } else { + search_text->grab_focus(); + search_text->select_all(); + } + error_label->set_text(""); + + if (prompt->is_pressed()) { + skip->show(); + get_ok()->set_text(TTR("Next")); + selection_only->set_disabled(true); + + } else { + skip->hide(); + get_ok()->set_text(TTR("Replace")); + selection_only->set_disabled(false); + } + +} + +void FindReplaceDialog::_search_callback() { + + if (is_replace_mode()) + _replace(); + else + _search(); + +} + +void FindReplaceDialog::_replace_skip_callback() { + + _search(); +} + +void FindReplaceDialog::_replace() { + + text_edit->begin_complex_operation(); + if (is_replace_all_mode()) { + + //line as x so it gets priority in comparison, column as y + Point2i orig_cursor(text_edit->cursor_get_line(),text_edit->cursor_get_column()); + Point2i prev_match=Point2(-1,-1); + + + bool selection_enabled = text_edit->is_selection_active(); + Point2i selection_begin,selection_end; + if (selection_enabled) { + selection_begin=Point2i(text_edit->get_selection_from_line(),text_edit->get_selection_from_column()); + selection_end=Point2i(text_edit->get_selection_to_line(),text_edit->get_selection_to_column()); + } + int vsval = text_edit->get_v_scroll(); + //int hsval = text_edit->get_h_scroll(); + + text_edit->cursor_set_line(0); + text_edit->cursor_set_column(0); + + int rc=0; + + while(_search()) { + + if (!text_edit->is_selection_active()) { + //search selects + break; + } + + //replace area + Point2i match_from(text_edit->get_selection_from_line(),text_edit->get_selection_from_column()); + Point2i match_to(text_edit->get_selection_to_line(),text_edit->get_selection_to_column()); + + if (match_from < prev_match) + break; //done + + prev_match=match_to; + + if (selection_enabled && is_replace_selection_only()) { + + if (match_from<selection_begin || match_to>selection_end) + continue; + + //replace but adjust selection bounds + + text_edit->insert_text_at_cursor(get_replace_text()); + if (match_to.x==selection_end.x) + selection_end.y+=get_replace_text().length() - get_search_text().length(); + } else { + //just replace + text_edit->insert_text_at_cursor(get_replace_text()); + } + rc++; + + } + //restore editor state (selection, cursor, scroll) + text_edit->cursor_set_line(orig_cursor.x); + text_edit->cursor_set_column(orig_cursor.y); + + if (selection_enabled && is_replace_selection_only()) { + //reselect + text_edit->select(selection_begin.x,selection_begin.y,selection_end.x,selection_end.y); + } else { + text_edit->deselect(); + } + + text_edit->set_v_scroll(vsval); + //text_edit->set_h_scroll(hsval); + error_label->set_text(vformat(TTR("Replaced %d ocurrence(s)."),rc)); + + + //hide(); + } else { + + if (text_edit->get_selection_text()==get_search_text()) { + + text_edit->insert_text_at_cursor(get_replace_text()); + } + + _search(); + } + text_edit->end_complex_operation(); +} + + + +bool FindReplaceDialog::_search() { + + + String text=get_search_text(); + uint32_t flags=0; + + if (is_whole_words()) + flags|=TextEdit::SEARCH_WHOLE_WORDS; + if (is_case_sensitive()) + flags|=TextEdit::SEARCH_MATCH_CASE; + if (is_backwards()) + flags|=TextEdit::SEARCH_BACKWARDS; + + int line=text_edit->cursor_get_line(),col=text_edit->cursor_get_column(); + + if (is_backwards()) { + col-=1; + if (col<0) { + line-=1; + if (line<0) { + line=text_edit->get_line_count()-1; + } + col=text_edit->get_line(line).length(); + } + } + bool found = text_edit->search(text,flags,line,col,line,col); + + + if (found) { + // print_line("found"); + text_edit->cursor_set_line(line); + if (is_backwards()) + text_edit->cursor_set_column(col); + else + text_edit->cursor_set_column(col+text.length()); + text_edit->select(line,col,line,col+text.length()); + set_error(""); + return true; + } else { + + set_error(TTR("Not found!")); + return false; + } + +} + +void FindReplaceDialog::_prompt_changed() { + + if (prompt->is_pressed()) { + skip->show(); + get_ok()->set_text(TTR("Next")); + selection_only->set_disabled(true); + + } else { + skip->hide(); + get_ok()->set_text(TTR("Replace")); + selection_only->set_disabled(false); + } +} + + +void FindReplaceDialog::_skip_pressed() { + + _replace_skip_callback(); +} + +bool FindReplaceDialog::is_replace_mode() const { + + return replace_text->is_visible_in_tree(); +} + +bool FindReplaceDialog::is_replace_all_mode() const { + + return !prompt->is_pressed(); +} + +bool FindReplaceDialog::is_replace_selection_only() const { + + return selection_only->is_pressed(); +} +void FindReplaceDialog::set_replace_selection_only(bool p_enable){ + + selection_only->set_pressed(p_enable); +} + + +void FindReplaceDialog::ok_pressed() { + + _search_callback(); +} + +void FindReplaceDialog::_search_text_entered(const String& p_text) { + + if (replace_text->is_visible_in_tree()) + return; + emit_signal("search"); + _search(); + +} + +void FindReplaceDialog::_replace_text_entered(const String& p_text) { + + if (!replace_text->is_visible_in_tree()) + return; + + emit_signal("search"); + _replace(); + +} + + +String FindReplaceDialog::get_search_text() const { + + return search_text->get_text(); +} +String FindReplaceDialog::get_replace_text() const { + + return replace_text->get_text(); +} +bool FindReplaceDialog::is_whole_words() const { + + return whole_words->is_pressed(); +} +bool FindReplaceDialog::is_case_sensitive() const { + + return case_sensitive->is_pressed(); + +} +bool FindReplaceDialog::is_backwards() const { + + return backwards->is_pressed(); + +} + +void FindReplaceDialog::set_error(const String& p_error) { + + error_label->set_text(p_error); +} + +void FindReplaceDialog::set_text_edit(TextEdit *p_text_edit) { + + text_edit=p_text_edit; +} + +void FindReplaceDialog::search_next() { + _search(); +} + + +void FindReplaceDialog::_bind_methods() { + + ClassDB::bind_method("_search_text_entered",&FindReplaceDialog::_search_text_entered); + ClassDB::bind_method("_replace_text_entered",&FindReplaceDialog::_replace_text_entered); + ClassDB::bind_method("_prompt_changed",&FindReplaceDialog::_prompt_changed); + ClassDB::bind_method("_skip_pressed",&FindReplaceDialog::_skip_pressed); + ADD_SIGNAL(MethodInfo("search")); + ADD_SIGNAL(MethodInfo("skip")); + +} + +FindReplaceDialog::FindReplaceDialog() { + + set_self_modulate(Color(1,1,1,0.8)); + + VBoxContainer *vb = memnew( VBoxContainer ); + add_child(vb); + + + + search_text = memnew( LineEdit ); + vb->add_margin_child(TTR("Search"),search_text); + search_text->connect("text_entered", this,"_search_text_entered"); + //search_text->set_self_opacity(0.7); + + + + replace_label = memnew( Label); + replace_label->set_text(TTR("Replace By")); + vb->add_child(replace_label); + replace_mc= memnew( MarginContainer); + vb->add_child(replace_mc); + + replace_text = memnew( LineEdit ); + replace_text->set_anchor( MARGIN_RIGHT, ANCHOR_END ); + replace_text->set_begin( Point2(15,132) ); + replace_text->set_end( Point2(15,135) ); + //replace_text->set_self_opacity(0.7); + replace_mc->add_child(replace_text); + + + replace_text->connect("text_entered", this,"_replace_text_entered"); + + + + MarginContainer *opt_mg = memnew( MarginContainer ); + vb->add_child(opt_mg); + VBoxContainer *svb = memnew( VBoxContainer); + opt_mg->add_child(svb); + + svb ->add_child(memnew(Label)); + + whole_words = memnew( CheckButton ); + whole_words->set_text(TTR("Whole Words")); + svb->add_child(whole_words); + + case_sensitive = memnew( CheckButton ); + case_sensitive->set_text(TTR("Case Sensitive")); + svb->add_child(case_sensitive); + + backwards = memnew( CheckButton ); + backwards->set_text(TTR("Backwards")); + svb->add_child(backwards); + + opt_mg = memnew( MarginContainer ); + vb->add_child(opt_mg); + VBoxContainer *rvb = memnew( VBoxContainer); + opt_mg->add_child(rvb); + replace_vb=rvb; + //rvb ->add_child(memnew(HSeparator)); + rvb ->add_child(memnew(Label)); + + prompt = memnew( CheckButton ); + prompt->set_text(TTR("Prompt On Replace")); + rvb->add_child(prompt); + prompt->connect("pressed", this,"_prompt_changed"); + + selection_only = memnew( CheckButton ); + selection_only->set_text(TTR("Selection Only")); + rvb->add_child(selection_only); + + + int margin = get_constant("margin","Dialogs"); + int button_margin = get_constant("button_margin","Dialogs"); + + skip = memnew( Button ); + skip->set_anchor( MARGIN_LEFT, ANCHOR_END ); + skip->set_anchor( MARGIN_TOP, ANCHOR_END ); + skip->set_anchor( MARGIN_RIGHT, ANCHOR_END ); + skip->set_anchor( MARGIN_BOTTOM, ANCHOR_END ); + skip->set_begin( Point2( 70, button_margin ) ); + skip->set_end( Point2( 10, margin ) ); + skip->set_text(TTR("Skip")); + add_child(skip); + skip->connect("pressed", this,"_skip_pressed"); + + + error_label = memnew( Label ); + error_label->set_align(Label::ALIGN_CENTER); + error_label->add_color_override("font_color",Color(1,0.4,0.3)); + error_label->add_color_override("font_color_shadow",Color(0,0,0,0.2)); + error_label->add_constant_override("shadow_as_outline",1); + + vb->add_child(error_label); + + + set_hide_on_ok(false); + +} + + +/*** CODE EDITOR ****/ + +void CodeTextEditor::_text_editor_gui_input(const InputEvent& p_event) { + + if (p_event.type==InputEvent::MOUSE_BUTTON) { + + const InputEventMouseButton& mb=p_event.mouse_button; + + if (mb.pressed && mb.mod.command) { + + if (mb.button_index==BUTTON_WHEEL_UP) { + _zoom_in(); + } else if (mb.button_index==BUTTON_WHEEL_DOWN) { + _zoom_out(); + } + } + } else if (p_event.type==InputEvent::KEY) { + + if (p_event.key.pressed) { + if (ED_IS_SHORTCUT("script_editor/zoom_in", p_event)) { + _zoom_in(); + } + if (ED_IS_SHORTCUT("script_editor/zoom_out", p_event)) { + _zoom_out(); + } + if (ED_IS_SHORTCUT("script_editor/reset_zoom", p_event)) { + _reset_zoom(); + } + } + } +} + +void CodeTextEditor::_zoom_in() { + font_resize_val+=1; + + if (font_resize_timer->get_time_left()==0) + font_resize_timer->start(); +} + +void CodeTextEditor::_zoom_out() { + font_resize_val-=1; + + if (font_resize_timer->get_time_left()==0) + font_resize_timer->start(); +} + +void CodeTextEditor::_reset_zoom() { + Ref<DynamicFont> font = text_editor->get_font("font"); // reset source font size to default + + if (font.is_valid()) { + EditorSettings::get_singleton()->set("interface/source_font_size",14); + font->set_size(14); + } +} + +void CodeTextEditor::_line_col_changed() { + + line_nb->set_text(itos(text_editor->cursor_get_line() + 1)); + col_nb->set_text(itos(text_editor->cursor_get_column() + 1)); +} + +void CodeTextEditor::_text_changed() { + + code_complete_timer->start(); + idle->start(); +} + +void CodeTextEditor::_code_complete_timer_timeout() { + if (!is_visible_in_tree()) + return; + if (enable_complete_timer) + text_editor->query_code_comple(); +} + +void CodeTextEditor::_complete_request() { + + List<String> entries; + String ctext = text_editor->get_text_for_completion(); + _code_complete_script(ctext,&entries); + if (code_complete_func) { + code_complete_func(code_complete_ud,ctext,&entries); + } + // print_line("COMPLETE: "+p_request); + if (entries.size()==0) + return; + Vector<String> strs; + strs.resize(entries.size()); + int i=0; + for(List<String>::Element *E=entries.front();E;E=E->next()) { + + strs[i++]=E->get(); + } + + text_editor->code_complete(strs); +} + +void CodeTextEditor::_font_resize_timeout() { + + Ref<DynamicFont> font = text_editor->get_font("font"); + + if (font.is_valid()) { + int size=font->get_size()+font_resize_val; + + if (size>=8 && size<=96) { + EditorSettings::get_singleton()->set("interface/source_font_size",size); + font->set_size(size); + } + + font_resize_val=0; + } +} + +void CodeTextEditor::update_editor_settings() { + + text_editor->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/completion/auto_brace_complete")); + text_editor->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file")); + text_editor->set_tab_size(EditorSettings::get_singleton()->get("text_editor/indent/tab_size")); + text_editor->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/indent/draw_tabs")); + text_editor->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_numbers")); + text_editor->set_line_numbers_zero_padded(EditorSettings::get_singleton()->get("text_editor/line_numbers/line_numbers_zero_padded")); + text_editor->set_show_line_length_guideline(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_length_guideline")); + text_editor->set_line_length_guideline_column(EditorSettings::get_singleton()->get("text_editor/line_numbers/line_length_guideline_column")); + text_editor->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/highlighting/syntax_highlighting")); + text_editor->set_highlight_all_occurrences(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_all_occurrences")); + text_editor->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink")); + text_editor->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed")); + text_editor->set_draw_breakpoint_gutter(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_breakpoint_gutter")); + text_editor->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret")); +} + +void CodeTextEditor::set_error(const String& p_error) { + + if (p_error!="") { + error->set_text(p_error); + error->show(); + } else { + error->hide(); + } + +} + +void CodeTextEditor::_update_font() { + + // FONTS + String editor_font = EDITOR_DEF("text_editor/theme/font", ""); + bool font_overridden = false; + if (editor_font!="") { + Ref<Font> fnt = ResourceLoader::load(editor_font); + if (fnt.is_valid()) { + text_editor->add_font_override("font",fnt); + font_overridden = true; + } + } + if(!font_overridden) { + + text_editor->add_font_override("font",get_font("source","EditorFonts")); + } +} + +void CodeTextEditor::_on_settings_change() { + + _update_font(); + + // AUTO BRACE COMPLETION + text_editor->set_auto_brace_completion( + EDITOR_DEF("text_editor/completion/auto_brace_complete", true) + ); + + code_complete_timer->set_wait_time( + EDITOR_DEF("text_editor/completion/code_complete_delay",.3f) + ); + + enable_complete_timer = EDITOR_DEF("text_editor/completion/enable_code_completion_delay",true); + + // call hint settings + text_editor->set_callhint_settings( + EDITOR_DEF("text_editor/completion/put_callhint_tooltip_below_current_line", true), + EDITOR_DEF("text_editor/completion/callhint_tooltip_offset", Vector2()) + ); +} + +void CodeTextEditor::_text_changed_idle_timeout() { + + + _validate_script(); + emit_signal("validate_script"); +} + +void CodeTextEditor::_notification(int p_what) { + + + if (p_what==EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { + _load_theme_settings(); + emit_signal("load_theme_settings"); + } + if (p_what==NOTIFICATION_THEME_CHANGED) { + _update_font(); + } +} + +void CodeTextEditor::_bind_methods() { + + ClassDB::bind_method("_text_editor_gui_input",&CodeTextEditor::_text_editor_gui_input); + ClassDB::bind_method("_line_col_changed",&CodeTextEditor::_line_col_changed); + ClassDB::bind_method("_text_changed",&CodeTextEditor::_text_changed); + ClassDB::bind_method("_on_settings_change",&CodeTextEditor::_on_settings_change); + ClassDB::bind_method("_text_changed_idle_timeout",&CodeTextEditor::_text_changed_idle_timeout); + ClassDB::bind_method("_code_complete_timer_timeout",&CodeTextEditor::_code_complete_timer_timeout); + ClassDB::bind_method("_complete_request",&CodeTextEditor::_complete_request); + ClassDB::bind_method("_font_resize_timeout",&CodeTextEditor::_font_resize_timeout); + + ADD_SIGNAL(MethodInfo("validate_script")); + ADD_SIGNAL(MethodInfo("load_theme_settings")); + +} + +void CodeTextEditor::set_code_complete_func(CodeTextEditorCodeCompleteFunc p_code_complete_func,void * p_ud) { + code_complete_func=p_code_complete_func; + code_complete_ud=p_ud; +} + + +CodeTextEditor::CodeTextEditor() { + + code_complete_func=NULL; + ED_SHORTCUT("script_editor/zoom_in", TTR("Zoom In"), KEY_MASK_CMD|KEY_EQUAL); + ED_SHORTCUT("script_editor/zoom_out", TTR("Zoom Out"), KEY_MASK_CMD|KEY_MINUS); + ED_SHORTCUT("script_editor/reset_zoom", TTR("Reset Zoom"), KEY_MASK_CMD|KEY_0); + + find_replace_bar = memnew( FindReplaceBar ); + add_child(find_replace_bar); + find_replace_bar->set_h_size_flags(SIZE_EXPAND_FILL); + find_replace_bar->hide(); + + text_editor = memnew( TextEdit ); + add_child(text_editor); + text_editor->set_v_size_flags(SIZE_EXPAND_FILL); + + find_replace_bar->set_text_edit(text_editor); + + text_editor->set_show_line_numbers(true); + text_editor->set_brace_matching(true); + text_editor->set_auto_indent(true); + + MarginContainer *status_mc = memnew( MarginContainer ); + add_child(status_mc); + status_mc->set("custom_constants/margin_left", 2); + status_mc->set("custom_constants/margin_top", 5); + status_mc->set("custom_constants/margin_right", 2); + status_mc->set("custom_constants/margin_bottom", 1); + + HBoxContainer *status_bar = memnew( HBoxContainer ); + status_mc->add_child(status_bar); + status_bar->set_h_size_flags(SIZE_EXPAND_FILL); + status_bar->add_child( memnew( Label ) ); //to keep the height if the other labels are not visible + + idle = memnew( Timer ); + add_child(idle); + idle->set_one_shot(true); + idle->set_wait_time(EDITOR_DEF("text_editor/completion/idle_parse_delay",2)); + + code_complete_timer = memnew(Timer); + add_child(code_complete_timer); + code_complete_timer->set_one_shot(true); + enable_complete_timer = EDITOR_DEF("text_editor/completion/enable_code_completion_delay",true); + + code_complete_timer->set_wait_time(EDITOR_DEF("text_editor/completion/code_complete_delay",.3f)); + + error = memnew( Label ); + status_bar->add_child(error); + error->hide(); + error->set_valign(Label::VALIGN_CENTER); + error->add_color_override("font_color",Color(1,0.7,0.6,0.9)); + + status_bar->add_spacer(); + + Label *line_txt = memnew( Label ); + status_bar->add_child(line_txt); + line_txt->set_align(Label::ALIGN_RIGHT); + line_txt->set_valign(Label::VALIGN_CENTER); + line_txt->set_v_size_flags(SIZE_FILL); + line_txt->set_text(TTR("Line:")); + + line_nb = memnew( Label ); + status_bar->add_child(line_nb); + line_nb->set_valign(Label::VALIGN_CENTER); + line_nb->set_v_size_flags(SIZE_FILL); + line_nb->set_autowrap(true); // workaround to prevent resizing the label on each change + line_nb->set_custom_minimum_size(Size2(40,1)*EDSCALE); + + Label *col_txt = memnew( Label ); + status_bar->add_child(col_txt); + col_txt->set_align(Label::ALIGN_RIGHT); + col_txt->set_valign(Label::VALIGN_CENTER); + col_txt->set_v_size_flags(SIZE_FILL); + col_txt->set_text(TTR("Col:")); + + col_nb = memnew( Label ); + status_bar->add_child(col_nb); + col_nb->set_valign(Label::VALIGN_CENTER); + col_nb->set_v_size_flags(SIZE_FILL); + col_nb->set_autowrap(true); // workaround to prevent resizing the label on each change + col_nb->set_custom_minimum_size(Size2(40,1)*EDSCALE); + + text_editor->connect("gui_input", this,"_text_editor_gui_input"); + text_editor->connect("cursor_changed", this,"_line_col_changed"); + text_editor->connect("text_changed", this,"_text_changed"); + text_editor->connect("request_completion", this,"_complete_request"); + Vector<String> cs; + cs.push_back("."); + cs.push_back(","); + cs.push_back("("); + cs.push_back("$"); + text_editor->set_completion(true,cs); + idle->connect("timeout", this,"_text_changed_idle_timeout"); + + code_complete_timer->connect("timeout", this,"_code_complete_timer_timeout"); + + font_resize_val=0; + font_resize_timer = memnew(Timer); + add_child(font_resize_timer); + font_resize_timer->set_one_shot(true); + font_resize_timer->set_wait_time(0.07); + font_resize_timer->connect("timeout", this, "_font_resize_timeout"); + + EditorSettings::get_singleton()->connect("settings_changed",this,"_on_settings_change"); +} diff --git a/editor/code_editor.h b/editor/code_editor.h new file mode 100644 index 0000000000..7582985d4c --- /dev/null +++ b/editor/code_editor.h @@ -0,0 +1,261 @@ +/*************************************************************************/ +/* code_editor.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef CODE_EDITOR_H +#define CODE_EDITOR_H + +#include "editor/editor_plugin.h" +#include "scene/gui/text_edit.h" +#include "scene/gui/dialogs.h" +#include "scene/main/timer.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/check_button.h" +#include "scene/gui/check_box.h" +#include "scene/gui/line_edit.h" + + + +class GotoLineDialog : public ConfirmationDialog { + + GDCLASS(GotoLineDialog,ConfirmationDialog); + + Label *line_label; + LineEdit *line; + + TextEdit *text_editor; + + virtual void ok_pressed(); +public: + + void popup_find_line(TextEdit *p_edit); + int get_line() const; + + + void set_text_editor(TextEdit *p_text_editor); + GotoLineDialog(); +}; + +class FindReplaceBar : public HBoxContainer { + + GDCLASS(FindReplaceBar,HBoxContainer); + + LineEdit *search_text; + ToolButton *find_prev; + ToolButton *find_next; + CheckBox *case_sensitive; + CheckBox *whole_words; + Label *error_label; + TextureButton *hide_button; + + LineEdit *replace_text; + Button *replace; + Button *replace_all; + CheckBox *selection_only; + + VBoxContainer *text_vbc; + HBoxContainer *replace_hbc; + HBoxContainer *replace_options_hbc; + + TextEdit *text_edit; + + int result_line; + int result_col; + + bool replace_all_mode; + bool preserve_cursor; + + void _get_search_from(int& r_line, int& r_col); + + void _show_search(); + void _hide_bar(); + + void _editor_text_changed(); + void _search_options_changed(bool p_pressed); + void _search_text_changed(const String& p_text); + void _search_text_entered(const String& p_text); + void _replace_text_entered(const String& p_text); + +protected: + void _notification(int p_what); + void _unhandled_input(const InputEvent &p_event); + + bool _search(uint32_t p_flags, int p_from_line, int p_from_col); + + void _replace(); + void _replace_all(); + + static void _bind_methods(); + +public: + String get_search_text() const; + String get_replace_text() const; + + bool is_case_sensitive() const; + bool is_whole_words() const; + bool is_selection_only() const; + void set_error(const String& p_label); + + void set_text_edit(TextEdit *p_text_edit); + + void popup_search(); + void popup_replace(); + + bool search_current(); + bool search_prev(); + bool search_next(); + + FindReplaceBar(); +}; + +class FindReplaceDialog : public ConfirmationDialog { + + GDCLASS(FindReplaceDialog,ConfirmationDialog); + + LineEdit *search_text; + LineEdit *replace_text; + CheckButton *whole_words; + CheckButton *case_sensitive; + CheckButton *backwards; + CheckButton *prompt; + CheckButton *selection_only; + Button *skip; + Label *error_label; + MarginContainer *replace_mc; + Label *replace_label; + VBoxContainer *replace_vb; + + void _search_text_entered(const String& p_text); + void _replace_text_entered(const String& p_text); + void _prompt_changed(); + void _skip_pressed(); + + + TextEdit *text_edit; +protected: + + void _search_callback(); + void _replace_skip_callback(); + + bool _search(); + void _replace(); + + virtual void ok_pressed(); + static void _bind_methods(); +public: + + String get_search_text() const; + String get_replace_text() const; + bool is_whole_words() const; + bool is_case_sensitive() const; + bool is_backwards() const; + bool is_replace_mode() const; + bool is_replace_all_mode() const; + bool is_replace_selection_only() const; + void set_replace_selection_only(bool p_enable); + + void set_error(const String& p_error); + + void popup_search(); + void popup_replace(); + + void set_text_edit(TextEdit *p_text_edit); + + void search_next(); + FindReplaceDialog(); +}; + + +typedef void (*CodeTextEditorCodeCompleteFunc)(void* p_ud,const String& p_code, List<String>* r_options); + +class CodeTextEditor : public VBoxContainer { + + GDCLASS(CodeTextEditor,VBoxContainer); + + TextEdit *text_editor; + FindReplaceBar *find_replace_bar; + + Label *line_nb; + Label *col_nb; + Label *info; + Timer *idle; + Timer *code_complete_timer; + bool enable_complete_timer; + + Timer *font_resize_timer; + int font_resize_val; + + Label *error; + + void _on_settings_change(); + + void _update_font(); + void _complete_request(); + void _font_resize_timeout(); + + void _text_editor_gui_input(const InputEvent& p_event); + void _zoom_in(); + void _zoom_out(); + void _reset_zoom(); + + + CodeTextEditorCodeCompleteFunc code_complete_func; + void *code_complete_ud; + +protected: + + + virtual void _load_theme_settings() {} + virtual void _validate_script() {} + virtual void _code_complete_script(const String& p_code, List<String>* r_options) {} + + void _text_changed_idle_timeout(); + void _code_complete_timer_timeout(); + void _text_changed(); + void _line_col_changed(); + void _notification(int); + static void _bind_methods(); + +public: + + void update_editor_settings(); + void set_error(const String& p_error); + void update_line_and_column() { _line_col_changed(); } + TextEdit *get_text_edit() { return text_editor; } + FindReplaceBar *get_find_replace_bar() { return find_replace_bar; } + virtual void apply_code() {} + + + void set_code_complete_func(CodeTextEditorCodeCompleteFunc p_code_complete_func, void * p_ud); + + + CodeTextEditor(); +}; + + + +#endif // CODE_EDITOR_H diff --git a/tools/editor/collada/SCsub b/editor/collada/SCsub index 04c9a827ef..04c9a827ef 100644 --- a/tools/editor/collada/SCsub +++ b/editor/collada/SCsub diff --git a/tools/editor/collada/collada.cpp b/editor/collada/collada.cpp index 2ba4f648a3..2ba4f648a3 100644 --- a/tools/editor/collada/collada.cpp +++ b/editor/collada/collada.cpp diff --git a/tools/editor/collada/collada.h b/editor/collada/collada.h index 2de2d22935..2de2d22935 100644 --- a/tools/editor/collada/collada.h +++ b/editor/collada/collada.h diff --git a/tools/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 91ba419c97..91ba419c97 100644 --- a/tools/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h new file mode 100644 index 0000000000..6407b83f6e --- /dev/null +++ b/editor/connections_dialog.h @@ -0,0 +1,134 @@ +/*************************************************************************/ +/* connections_dialog.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef CONNECTIONS_DIALOG_H +#define CONNECTIONS_DIALOG_H + +#include "scene/gui/popup.h" +#include "scene/gui/button.h" +#include "scene/gui/check_button.h" +#include "scene/gui/tree.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/line_edit.h" +#include "editor/scene_tree_editor.h" +#include "editor/property_editor.h" +#include "undo_redo.h" + +/** +@author Juan Linietsky <reduzio@gmail.com> +*/ + +class ConnectDialogBinds; + +class ConnectDialog : public ConfirmationDialog { + + GDCLASS( ConnectDialog, ConfirmationDialog ); + + + ConfirmationDialog *error; + LineEdit *dst_path; + LineEdit *dst_method; + SceneTreeEditor *tree; + //MenuButton *dst_method_list; + OptionButton *type_list; + CheckButton *deferred; + CheckButton *oneshot; + CheckButton *make_callback; + PropertyEditor *bind_editor; + Node *node; + ConnectDialogBinds *cdbinds; + void ok_pressed(); + void _cancel_pressed(); + void _tree_node_selected(); + void _dst_method_list_selected(int p_idx); + void _add_bind(); + void _remove_bind(); + +protected: + + void _notification(int p_what); + static void _bind_methods(); +public: + + + bool get_make_callback() { return make_callback->is_visible() && make_callback->is_pressed(); } + NodePath get_dst_path() const; + StringName get_dst_method() const; + bool get_deferred() const; + bool get_oneshot() const; + Vector<Variant> get_binds() const; + void set_dst_method(const StringName& p_method); + void set_dst_node(Node* p_node); + + //Button *get_ok() { return ok; } + //Button *get_cancel() { return cancel; } + void edit(Node *p_node); + + ConnectDialog(); + ~ConnectDialog(); + +}; + +class ConnectionsDock : public VBoxContainer { + + GDCLASS( ConnectionsDock , VBoxContainer ); + + Button *connect_button; + EditorNode *editor; + Node *node; + Tree *tree; + ConfirmationDialog *remove_confirm; + ConnectDialog *connect_dialog; + + void update_tree(); + + void _close(); + void _connect(); + void _something_selected(); + void _something_activated(); + UndoRedo *undo_redo; + +protected: + + void _connect_pressed(); + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_undoredo(UndoRedo *p_undo_redo) { undo_redo=p_undo_redo; } + + void set_node(Node* p_node); + String get_selected_type(); + + ConnectionsDock(EditorNode *p_editor=NULL); + ~ConnectionsDock(); + +}; + +#endif diff --git a/tools/editor/create_dialog.cpp b/editor/create_dialog.cpp index 58bb148ce1..58bb148ce1 100644 --- a/tools/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp diff --git a/tools/editor/create_dialog.h b/editor/create_dialog.h index 5ecb4db2c3..5ecb4db2c3 100644 --- a/tools/editor/create_dialog.h +++ b/editor/create_dialog.h diff --git a/tools/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index d7e04db86e..d7e04db86e 100644 --- a/tools/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp diff --git a/tools/editor/dependency_editor.h b/editor/dependency_editor.h index a96ffe5fcf..a96ffe5fcf 100644 --- a/tools/editor/dependency_editor.h +++ b/editor/dependency_editor.h diff --git a/tools/editor/doc/SCsub b/editor/doc/SCsub index 04c9a827ef..04c9a827ef 100644 --- a/tools/editor/doc/SCsub +++ b/editor/doc/SCsub diff --git a/tools/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp index 47b8edfa04..47b8edfa04 100644 --- a/tools/editor/doc/doc_data.cpp +++ b/editor/doc/doc_data.cpp diff --git a/tools/editor/doc/doc_data.h b/editor/doc/doc_data.h index 7601013979..7601013979 100644 --- a/tools/editor/doc/doc_data.h +++ b/editor/doc/doc_data.h diff --git a/tools/editor/doc/doc_dump.cpp b/editor/doc/doc_dump.cpp index 5ebba596e9..5ebba596e9 100644 --- a/tools/editor/doc/doc_dump.cpp +++ b/editor/doc/doc_dump.cpp diff --git a/tools/editor/doc/doc_dump.h b/editor/doc/doc_dump.h index 84629b89c8..84629b89c8 100644 --- a/tools/editor/doc/doc_dump.h +++ b/editor/doc/doc_dump.h diff --git a/tools/editor/doc_code_font.h b/editor/doc_code_font.h index 55f335ab78..55f335ab78 100644 --- a/tools/editor/doc_code_font.h +++ b/editor/doc_code_font.h diff --git a/tools/editor/doc_font.h b/editor/doc_font.h index b598ee26f8..b598ee26f8 100644 --- a/tools/editor/doc_font.h +++ b/editor/doc_font.h diff --git a/tools/editor/doc_title_font.h b/editor/doc_title_font.h index afa0f61eda..afa0f61eda 100644 --- a/tools/editor/doc_title_font.h +++ b/editor/doc_title_font.h diff --git a/tools/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp index 8af01012a4..8af01012a4 100644 --- a/tools/editor/editor_asset_installer.cpp +++ b/editor/editor_asset_installer.cpp diff --git a/tools/editor/editor_asset_installer.h b/editor/editor_asset_installer.h index 2d0486a6f6..2d0486a6f6 100644 --- a/tools/editor/editor_asset_installer.h +++ b/editor/editor_asset_installer.h diff --git a/tools/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 6ee18f08d8..6ee18f08d8 100644 --- a/tools/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h new file mode 100644 index 0000000000..4ac8b27004 --- /dev/null +++ b/editor/editor_audio_buses.h @@ -0,0 +1,186 @@ +#ifndef EDITORAUDIOBUSES_H +#define EDITORAUDIOBUSES_H + + +#include "scene/gui/box_container.h" +#include "scene/gui/button.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/scroll_container.h" +#include "scene/gui/panel_container.h" +#include "scene/gui/slider.h" +#include "scene/gui/texture_progress.h" +#include "scene/gui/texture_rect.h" +#include "scene/gui/line_edit.h" +#include "scene/gui/tree.h" +#include "scene/gui/option_button.h" +#include "scene/gui/panel.h" +#include "editor/editor_file_dialog.h" +#include "editor_plugin.h" + +class EditorAudioBuses; + +class EditorAudioBus : public PanelContainer { + + GDCLASS( EditorAudioBus, PanelContainer ) + + bool prev_active; + float peak_l; + float peak_r; + + Ref<Texture> disabled_vu; + LineEdit *track_name; + VSlider *slider; + TextureProgress *vu_l; + TextureProgress *vu_r; + TextureRect *scale; + OptionButton *send; + + PopupMenu *effect_options; + PopupMenu *delete_popup; + PopupMenu *delete_effect_popup; + + Button *solo; + Button *mute; + Button *bypass; + + Tree *effects; + + bool updating_bus; + + void _gui_input(const InputEvent& p_event); + void _delete_pressed(int p_option); + + void _name_changed(const String& p_new_name); + void _name_focus_exit() { _name_changed(track_name->get_text()); } + void _volume_db_changed(float p_db); + void _solo_toggled(); + void _mute_toggled(); + void _bypass_toggled(); + void _send_selected(int p_which); + void _effect_edited(); + void _effect_add(int p_which); + void _effect_selected(); + void _delete_effect_pressed(int p_option); + void _effect_rmb(const Vector2& p_pos); + + + virtual Variant get_drag_data(const Point2& p_point); + virtual bool can_drop_data(const Point2& p_point,const Variant& p_data) const; + virtual void drop_data(const Point2& p_point,const Variant& p_data); + + + Variant get_drag_data_fw(const Point2& p_point,Control* p_from); + bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; + void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); + +friend class EditorAudioBuses; + + EditorAudioBuses *buses; + +protected: + + static void _bind_methods(); + void _notification(int p_what); +public: + + void update_bus(); + void update_send(); + + EditorAudioBus(EditorAudioBuses *p_buses=NULL); +}; + + +class EditorAudioBusDrop : public Panel { + + GDCLASS(EditorAudioBusDrop,Panel); + + virtual bool can_drop_data(const Point2& p_point,const Variant& p_data) const; + virtual void drop_data(const Point2& p_point,const Variant& p_data); +protected: + + static void _bind_methods(); +public: + + EditorAudioBusDrop(); +}; + +class EditorAudioBuses : public VBoxContainer { + + GDCLASS(EditorAudioBuses,VBoxContainer) + + HBoxContainer *top_hb; + + Button *add; + ScrollContainer *bus_scroll; + HBoxContainer *bus_hb; + + EditorAudioBusDrop *drop_end; + + Button *file; + Button *load; + Button *save_as; + Button *_default; + Button *_new; + + Timer *save_timer; + String edited_path; + + void _add_bus(); + void _update_buses(); + void _update_bus(int p_index); + void _update_sends(); + + void _delete_bus(Object* p_which); + void _duplicate_bus(int p_which); + + + void _request_drop_end(); + void _drop_at_index(int p_bus,int p_index); + + void _server_save(); + + void _select_layout(); + void _load_layout(); + void _save_as_layout(); + void _load_default_layout(); + void _new_layout(); + + EditorFileDialog *file_dialog; + bool new_layout; + + void _file_dialog_callback(const String& p_string); + +protected: + + static void _bind_methods(); + void _notification(int p_what); +public: + + void open_layout(const String& p_path); + + static EditorAudioBuses* register_editor(); + + EditorAudioBuses(); +}; + + + +class AudioBusesEditorPlugin : public EditorPlugin { + + GDCLASS( AudioBusesEditorPlugin, EditorPlugin ); + + EditorAudioBuses *audio_bus_editor; +public: + + virtual String get_name() const { return "SampleLibrary"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + AudioBusesEditorPlugin(EditorAudioBuses *p_node); + ~AudioBusesEditorPlugin(); + +}; + +#endif // EDITORAUDIOBUSES_H diff --git a/tools/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index 3e3362f515..3e3362f515 100644 --- a/tools/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp diff --git a/tools/editor/editor_autoload_settings.h b/editor/editor_autoload_settings.h index 2afe239000..2afe239000 100644 --- a/tools/editor/editor_autoload_settings.h +++ b/editor/editor_autoload_settings.h diff --git a/tools/editor/editor_data.cpp b/editor/editor_data.cpp index d2fa40e08c..d2fa40e08c 100644 --- a/tools/editor/editor_data.cpp +++ b/editor/editor_data.cpp diff --git a/editor/editor_data.h b/editor/editor_data.h new file mode 100644 index 0000000000..4622791653 --- /dev/null +++ b/editor/editor_data.h @@ -0,0 +1,269 @@ +/*************************************************************************/ +/* editor_data.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITOR_DATA_H +#define EDITOR_DATA_H + +#include "editor/editor_plugin.h" +#include "scene/resources/texture.h" +#include "list.h" +#include "undo_redo.h" +#include "pair.h" + +class EditorHistory { + + enum { + + HISTORY_MAX=64 + }; + + struct Obj { + + REF ref; + ObjectID object; + String property; + }; + + struct History { + + Vector<Obj> path; + int level; + }; +friend class EditorData; + + Vector<History> history; + int current; + + //Vector<EditorPlugin*> editor_plugins; + + struct PropertyData { + + String name; + Variant value; + }; + + + void _cleanup_history(); + + void _add_object(ObjectID p_object,const String& p_property,int p_level_change); + +public: + + bool is_at_begining() const; + bool is_at_end() const; + + void add_object(ObjectID p_object); + void add_object(ObjectID p_object,const String& p_subprop); + void add_object(ObjectID p_object,int p_relevel); + + int get_history_len(); + int get_history_pos(); + ObjectID get_history_obj(int p_obj) const; + + bool next(); + bool previous(); + ObjectID get_current(); + + int get_path_size() const; + ObjectID get_path_object(int p_index) const; + String get_path_property(int p_index) const; + + void clear(); + + EditorHistory(); +}; + +class EditorSelection; + +class EditorData { + +public: + struct CustomType { + + String name; + Ref<Script> script; + Ref<Texture> icon; + }; +private: + + Vector<EditorPlugin*> editor_plugins; + + struct PropertyData { + + String name; + Variant value; + }; + Map<String,Vector<CustomType> > custom_types; + + List<PropertyData> clipboard; + UndoRedo undo_redo; + + + void _cleanup_history(); + + struct EditedScene { + Node* root; + Dictionary editor_states; + List<Node*> selection; + Vector<EditorHistory::History> history_stored; + int history_current; + Dictionary custom_state; + uint64_t version; + NodePath live_edit_root; + + + }; + + Vector<EditedScene> edited_scene; + int current_edited_scene; + + bool _find_updated_instances(Node* p_root,Node *p_node,Set<String> &checked_paths); + +public: + + EditorPlugin* get_editor(Object *p_object); + EditorPlugin* get_subeditor(Object *p_object); + Vector<EditorPlugin*> get_subeditors(Object *p_object); + EditorPlugin* get_editor(String p_name); + + void copy_object_params(Object *p_object); + void paste_object_params(Object *p_object); + + Dictionary get_editor_states() const; + Dictionary get_scene_editor_states(int p_idx) const; + void set_editor_states(const Dictionary& p_states); + void get_editor_breakpoints(List<String> *p_breakpoints); + void clear_editor_states(); + void save_editor_external_data(); + void apply_changes_in_editors(); + + void add_editor_plugin(EditorPlugin *p_plugin); + void remove_editor_plugin(EditorPlugin *p_plugin); + + int get_editor_plugin_count() const; + EditorPlugin *get_editor_plugin(int p_idx); + + UndoRedo &get_undo_redo(); + + void save_editor_global_states(); + void restore_editor_global_states(); + + void add_custom_type(const String& p_type, const String& p_inherits,const Ref<Script>& p_script,const Ref<Texture>& p_icon ); + void remove_custom_type(const String& p_type); + const Map<String,Vector<CustomType> >& get_custom_types() const { return custom_types; } + + + int add_edited_scene(int p_at_pos); + void move_edited_scene_index(int p_idx,int p_to_idx); + void remove_scene(int p_idx); + void set_edited_scene(int p_idx); + void set_edited_scene_root(Node* p_root); + int get_edited_scene() const; + Node* get_edited_scene_root(int p_idx = -1); + int get_edited_scene_count() const; + String get_scene_title(int p_idx) const; + String get_scene_path(int p_idx) const; + String get_scene_type(int p_idx) const; + Ref<Script> get_scene_root_script(int p_idx) const; + void set_edited_scene_version(uint64_t version, int p_scene_idx = -1); + uint64_t get_edited_scene_version() const; + uint64_t get_scene_version(int p_idx) const; + void clear_edited_scenes(); + void set_edited_scene_live_edit_root(const NodePath& p_root); + NodePath get_edited_scene_live_edit_root(); + bool check_and_update_scene(int p_idx); + void move_edited_scene_to_index(int p_idx); + + + void set_plugin_window_layout(Ref<ConfigFile> p_layout); + void get_plugin_window_layout(Ref<ConfigFile> p_layout); + + void save_edited_scene_state(EditorSelection *p_selection,EditorHistory *p_history,const Dictionary& p_custom); + Dictionary restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history); + void notify_edited_scene_changed(); + + + EditorData(); +}; + + + +class EditorSelection : public Object { + + GDCLASS(EditorSelection,Object); +public: + + Map<Node*,Object*> selection; + + bool changed; + bool nl_changed; + + void _node_removed(Node *p_node); + + List<Object*> editor_plugins; + List<Node*> selected_node_list; + + void _update_nl(); + Array _get_selected_nodes(); + Array _get_transformable_selected_nodes(); + +protected: + + static void _bind_methods(); +public: + + void add_node(Node *p_node); + void remove_node(Node *p_node); + bool is_selected(Node *) const; + + template<class T> + T* get_node_editor_data(Node *p_node) { + if (!selection.has(p_node)) + return NULL; + Object *obj = selection[p_node]; + if (!obj) + return NULL; + return obj->cast_to<T>(); + } + + void add_editor_plugin(Object *p_object); + + void update(); + void clear(); + + + List<Node*>& get_selected_node_list(); + Map<Node*,Object*>& get_selection() { return selection; } + + + EditorSelection(); + ~EditorSelection(); +}; + + +#endif // EDITOR_DATA_H diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp new file mode 100644 index 0000000000..235d1f06ba --- /dev/null +++ b/editor/editor_dir_dialog.cpp @@ -0,0 +1,276 @@ +/*************************************************************************/ +/* editor_dir_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 "editor_dir_dialog.h" + +#include "os/os.h" +#include "os/keyboard.h" +#include "editor/editor_settings.h" +#include "editor/editor_file_system.h" + + +void EditorDirDialog::_update_dir(TreeItem* p_item) { + + updating=true; + p_item->clear_children(); + DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + String cdir = p_item->get_metadata(0); + + da->change_dir(cdir); + da->list_dir_begin(); + String p=da->get_next(); + + List<String> dirs; + bool ishidden; + bool show_hidden = EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"); + + while(p!="") { + + ishidden = da->current_is_hidden(); + + if (show_hidden || !ishidden) { + if (da->current_is_dir() && !p.begins_with(".")) { + dirs.push_back(p); + } + } + p=da->get_next(); + } + + dirs.sort(); + + for(List<String>::Element *E=dirs.front();E;E=E->next()) { + TreeItem *ti = tree->create_item(p_item); + ti->set_text(0,E->get()); + ti->set_icon(0,get_icon("Folder","EditorIcons")); + ti->set_collapsed(true); + + } + + memdelete(da); + updating=false; + +} + + +void EditorDirDialog::reload() { + + if (!is_visible_in_tree()) { + must_reload=true; + return; + } + + tree->clear(); + TreeItem *root = tree->create_item(); + root->set_metadata(0,"res://"); + root->set_icon(0,get_icon("Folder","EditorIcons")); + root->set_text(0,"/"); + _update_dir(root); + _item_collapsed(root); + must_reload=false; + +} + + +void EditorDirDialog::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + reload(); + + if (!tree->is_connected("item_collapsed",this,"_item_collapsed")) { + tree->connect("item_collapsed",this,"_item_collapsed",varray(),CONNECT_DEFERRED); + } + + if (!EditorFileSystem::get_singleton()->is_connected("filesystem_changed",this,"reload")) { + EditorFileSystem::get_singleton()->connect("filesystem_changed",this,"reload"); + } + + } + + if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { + if (must_reload && is_visible_in_tree()) { + reload(); + } + } +} + +void EditorDirDialog::_item_collapsed(Object* _p_item){ + + TreeItem *p_item=_p_item->cast_to<TreeItem>(); + + if (updating || p_item->is_collapsed()) + return; + + TreeItem *ci = p_item->get_children(); + while(ci) { + + String p =ci->get_metadata(0); + if (p=="") { + String pp = p_item->get_metadata(0); + ci->set_metadata(0,pp.plus_file(ci->get_text(0))); + _update_dir(ci); + } + ci=ci->get_next(); + } + +} + +void EditorDirDialog::set_current_path(const String& p_path) { + + reload(); + String p = p_path; + if (p.begins_with("res://")) + p = p.replace_first("res://",""); + + Vector<String> dirs = p.split("/",false); + + TreeItem *r=tree->get_root(); + for(int i=0;i<dirs.size();i++) { + + String d = dirs[i]; + TreeItem *p = r->get_children(); + while(p) { + + if (p->get_text(0)==d) + break; + p=p->get_next(); + } + + ERR_FAIL_COND(!p); + String pp = p->get_metadata(0); + if (pp=="") { + p->set_metadata(0,String(r->get_metadata(0)).plus_file(d)); + _update_dir(p); + } + updating=true; + p->set_collapsed(false); + updating=false; + _item_collapsed(p); + r=p; + } + + r->select(0); + +} + +void EditorDirDialog::ok_pressed() { + + TreeItem *ti=tree->get_selected(); + if (!ti) + return; + + String dir = ti->get_metadata(0); + emit_signal("dir_selected",dir); + hide(); +} + + +void EditorDirDialog::_make_dir() { + + TreeItem *ti=tree->get_selected(); + if (!ti) { + mkdirerr->set_text("Please select a base directory first"); + mkdirerr->popup_centered_minsize(); + return; + } + + makedialog->popup_centered_minsize(Size2(250,80)); + makedirname->grab_focus(); +} + +void EditorDirDialog::_make_dir_confirm() { + + TreeItem *ti=tree->get_selected(); + if (!ti) + return; + + String dir = ti->get_metadata(0); + + DirAccess *d = DirAccess::open(dir); + ERR_FAIL_COND(!d); + Error err = d->make_dir(makedirname->get_text()); + + if (err!=OK) { + mkdirerr->popup_centered_minsize(Size2(250,80)); + } else { + set_current_path(dir.plus_file(makedirname->get_text())); + } + makedirname->set_text(""); // reset label +} + + +void EditorDirDialog::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_item_collapsed"),&EditorDirDialog::_item_collapsed); + ClassDB::bind_method(D_METHOD("_make_dir"),&EditorDirDialog::_make_dir); + ClassDB::bind_method(D_METHOD("_make_dir_confirm"),&EditorDirDialog::_make_dir_confirm); + ClassDB::bind_method(D_METHOD("reload"),&EditorDirDialog::reload); + + ADD_SIGNAL(MethodInfo("dir_selected",PropertyInfo(Variant::STRING,"dir"))); +} + + + +EditorDirDialog::EditorDirDialog() { + + updating=false; + + set_title(TTR("Choose a Directory")); + set_hide_on_ok(false); + + tree = memnew( Tree ); + add_child(tree); + + tree->connect("item_activated",this,"_ok"); + + makedir = add_button(TTR("Create Folder"),OS::get_singleton()->get_swap_ok_cancel()?true:false,"makedir"); + makedir->connect("pressed",this,"_make_dir"); + + makedialog = memnew( ConfirmationDialog ); + makedialog->set_title(TTR("Create Folder")); + add_child(makedialog); + + VBoxContainer *makevb= memnew( VBoxContainer ); + makedialog->add_child(makevb); + //makedialog->set_child_rect(makevb); + + makedirname = memnew( LineEdit ); + makevb->add_margin_child(TTR("Name:"),makedirname); + makedialog->register_text_enter(makedirname); + makedialog->connect("confirmed",this,"_make_dir_confirm"); + + mkdirerr = memnew( AcceptDialog ); + mkdirerr->set_text(TTR("Could not create folder.")); + add_child(mkdirerr); + + get_ok()->set_text(TTR("Choose")); + + must_reload=false; + + + +} diff --git a/tools/editor/editor_dir_dialog.h b/editor/editor_dir_dialog.h index 0577ff0442..0577ff0442 100644 --- a/tools/editor/editor_dir_dialog.h +++ b/editor/editor_dir_dialog.h diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp new file mode 100644 index 0000000000..f5840d00fb --- /dev/null +++ b/editor/editor_export.cpp @@ -0,0 +1,3231 @@ +/*************************************************************************/ +/* editor_import_export.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 "editor_export.h" +#include "version.h" +#include "script_language.h" +#include "global_config.h" +#include "os/file_access.h" +#include "os/dir_access.h" +#include "editor/editor_file_system.h" +#include "io/resource_loader.h" +#include "editor_node.h" +#include "editor_settings.h" +#include "io/config_file.h" +#include "io/resource_saver.h" +#include "io/md5.h" +#include "editor/plugins/script_editor_plugin.h" +#include "io/zip_io.h" + +static int _get_pad(int p_alignment, int p_n) { + + int rest = p_n % p_alignment; + int pad = 0; + if (rest > 0) { + pad = p_alignment - rest; + }; + + return pad; +}; + +#define PCK_PADDING 16 + +bool EditorExportPreset::_set(const StringName& p_name, const Variant& p_value) { + + if (values.has(p_name)) { + values[p_name]=p_value; + EditorExport::singleton->save_presets(); + return true; + } + + return false; +} + +bool EditorExportPreset::_get(const StringName& p_name,Variant &r_ret) const{ + + if (values.has(p_name)) { + r_ret=values[p_name]; + return true; + } + + return false; +} +void EditorExportPreset::_get_property_list( List<PropertyInfo> *p_list) const{ + + for (const List<PropertyInfo>::Element *E=properties.front();E;E=E->next()) { + + p_list->push_back(E->get()); + } +} + +Ref<EditorExportPlatform> EditorExportPreset::get_platform() const { + + return platform; +} + +Vector<String> EditorExportPreset::get_files_to_export() const { + + Vector<String> files; + for(Set<String>::Element *E=selected_files.front();E;E=E->next()) { + files.push_back(E->get()); + } + return files; +} + +void EditorExportPreset::set_name(const String& p_name) { + name=p_name; + EditorExport::singleton->save_presets(); + +} + +String EditorExportPreset::get_name() const { + return name; + +} + +void EditorExportPreset::set_runnable(bool p_enable) { + + runnable=p_enable; + EditorExport::singleton->save_presets(); +} + +bool EditorExportPreset::is_runnable() const { + + return runnable; +} + +void EditorExportPreset::set_export_filter(ExportFilter p_filter) { + + export_filter=p_filter; + EditorExport::singleton->save_presets(); + +} + +EditorExportPreset::ExportFilter EditorExportPreset::get_export_filter() const { + return export_filter; +} + +void EditorExportPreset::set_include_filter(const String& p_include) { + + include_filter=p_include; + EditorExport::singleton->save_presets(); + +} + +String EditorExportPreset::get_include_filter() const { + + return include_filter; +} + +void EditorExportPreset::set_exclude_filter(const String& p_exclude) { + + exclude_filter=p_exclude; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_exclude_filter() const { + + return exclude_filter; +} + +void EditorExportPreset::add_export_file(const String& p_path) { + + selected_files.insert(p_path); + EditorExport::singleton->save_presets(); +} + +void EditorExportPreset::remove_export_file(const String& p_path) { + selected_files.erase(p_path); + EditorExport::singleton->save_presets(); +} + +bool EditorExportPreset::has_export_file(const String& p_path) { + + return selected_files.has(p_path); +} + +void EditorExportPreset::add_patch(const String& p_path,int p_at_pos) { + + if (p_at_pos<0) + patches.push_back(p_path); + else + patches.insert(p_at_pos,p_path); + EditorExport::singleton->save_presets(); +} + +void EditorExportPreset::remove_patch(int p_idx) { + patches.remove(p_idx); + EditorExport::singleton->save_presets(); +} + +void EditorExportPreset::set_patch(int p_index,const String& p_path) { + ERR_FAIL_INDEX(p_index,patches.size()); + patches[p_index]=p_path; + EditorExport::singleton->save_presets(); +} +String EditorExportPreset::get_patch(int p_index) { + + ERR_FAIL_INDEX_V(p_index,patches.size(),String()); + return patches[p_index]; +} + +Vector<String> EditorExportPreset::get_patches() const { + return patches; +} + +EditorExportPreset::EditorExportPreset() { + + export_filter=EXPORT_ALL_RESOURCES; + runnable=false; +} + + +/////////////////////////////////// + +void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags) { + + String host = EditorSettings::get_singleton()->get("network/debug_host"); + + if (p_flags&DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST) + host="localhost"; + + if (p_flags&DEBUG_FLAG_DUMB_CLIENT) { + int port = EditorSettings::get_singleton()->get("filesystem/file_server/port"); + String passwd = EditorSettings::get_singleton()->get("filesystem/file_server/password"); + r_flags.push_back("-rfs"); + r_flags.push_back(host+":"+itos(port)); + if (passwd!="") { + r_flags.push_back("-rfs_pass"); + r_flags.push_back(passwd); + } + } + + if (p_flags&DEBUG_FLAG_REMOTE_DEBUG) { + + r_flags.push_back("-rdebug"); + + r_flags.push_back(host+":"+String::num(GLOBAL_DEF("network/debug/remote_port", 6007))); + + List<String> breakpoints; + ScriptEditor::get_singleton()->get_breakpoints(&breakpoints); + + + if (breakpoints.size()) { + + r_flags.push_back("-bp"); + String bpoints; + for(const List<String>::Element *E=breakpoints.front();E;E=E->next()) { + + bpoints+=E->get().replace(" ","%20"); + if (E->next()) + bpoints+=","; + } + + r_flags.push_back(bpoints); + } + + } + + if (p_flags&DEBUG_FLAG_VIEW_COLLISONS) { + + r_flags.push_back("-debugcol"); + } + + if (p_flags&DEBUG_FLAG_VIEW_NAVIGATION) { + + r_flags.push_back("-debugnav"); + } +} + +Error EditorExportPlatform::_save_pack_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total) { + + PackData *pd = (PackData*)p_userdata; + + SavedData sd; + sd.path_utf8=p_path.utf8(); + sd.ofs = pd->f->get_pos(); + sd.size = p_data.size(); + + pd->f->store_buffer(p_data.ptr(),p_data.size()); + int pad = _get_pad(PCK_PADDING,sd.size); + for(int i=0;i<pad;i++) { + pd->f->store_8(0); + } + + { + MD5_CTX ctx; + MD5Init(&ctx); + MD5Update(&ctx,(unsigned char*)p_data.ptr(),p_data.size()); + MD5Final(&ctx); + sd.md5.resize(16); + for(int i=0;i<16;i++) { + sd.md5[i]=ctx.digest[i]; + } + } + + pd->file_ofs.push_back(sd); + + pd->ep->step(TTR("Storing File:")+" "+p_path,2+p_file*100/p_total,false); + + return OK; +} + +Error EditorExportPlatform::_save_zip_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total) { + + + String path=p_path.replace_first("res://",""); + + ZipData *zd = (ZipData*)p_userdata; + + zipFile zip=(zipFile)zd->zip; + + zipOpenNewFileInZip(zip, + path.utf8().get_data(), + NULL, + NULL, + 0, + NULL, + 0, + NULL, + Z_DEFLATED, + Z_DEFAULT_COMPRESSION); + + zipWriteInFileInZip(zip,p_data.ptr(),p_data.size()); + zipCloseFileInZip(zip); + + zd->ep->step(TTR("Storing File:")+" "+p_path,2+p_file*100/p_total,false); + + return OK; +} + +String EditorExportPlatform::find_export_template(String template_file_name, String *err) const { + + String user_file = EditorSettings::get_singleton()->get_settings_path() + +"/templates/"+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"."+_MKSTR(VERSION_STATUS)+"/"+template_file_name; + String system_file=OS::get_singleton()->get_installed_templates_path(); + bool has_system_path=(system_file!=""); + system_file+=template_file_name; + + // Prefer user file + if (FileAccess::exists(user_file)) { + return user_file; + } + + // Now check system file + if (has_system_path) { + if (FileAccess::exists(system_file)) { + return system_file; + } + } + + // Not found + if (err) { + *err+="No export template found at \""+user_file+"\""; + if (has_system_path) + *err+="\n or \""+system_file+"\"."; + else + *err+="."; + } + return ""; +} + +Ref<EditorExportPreset> EditorExportPlatform::create_preset() { + + Ref<EditorExportPreset> preset; + preset.instance(); + preset->platform=Ref<EditorExportPlatform>(this); + + List<ExportOption> options; + get_export_options(&options); + + for (List<ExportOption>::Element *E=options.front();E;E=E->next()) { + + preset->properties.push_back(E->get().option); + preset->values[E->get().option.name]=E->get().default_value; + } + + return preset; + +} + +void EditorExportPlatform::_export_find_resources(EditorFileSystemDirectory *p_dir,Set<String>& p_paths) { + + for(int i=0;i<p_dir->get_subdir_count();i++) { + _export_find_resources(p_dir->get_subdir(i),p_paths); + } + + for(int i=0;i<p_dir->get_file_count();i++) { + p_paths.insert(p_dir->get_file_path(i)); + } +} + + +void EditorExportPlatform::_export_find_dependencies(const String& p_path,Set<String>& p_paths) { + + if (p_paths.has(p_path)) + return; + + p_paths.insert(p_path); + + EditorFileSystemDirectory *dir; + int file_idx; + dir = EditorFileSystem::get_singleton()->find_file(p_path,&file_idx); + if (!dir) + return; + + Vector<String> deps = dir->get_file_deps(file_idx); + + for(int i=0;i<deps.size();i++) { + + _export_find_dependencies(deps[i],p_paths); + } +} + + +Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset>& p_preset,EditorExportSaveFunction p_func, void* p_udata) { + + Ref<EditorExportPlatform> platform = p_preset->get_platform(); + List<String> feature_list; + platform->get_preset_features(p_preset,&feature_list); + //figure out features + Set<String> features; + for (List<String>::Element *E=feature_list.front();E;E=E->next()) { + features.insert(E->get()); + } + + //figure out paths of files that will be exported + Set<String> paths; + + if (p_preset->get_export_filter()==EditorExportPreset::EXPORT_ALL_RESOURCES) { + //find stuff + _export_find_resources(EditorFileSystem::get_singleton()->get_filesystem(),paths); + } else { + bool scenes_only = p_preset->get_export_filter()==EditorExportPreset::EXPORT_SELECTED_SCENES; + + Vector<String> files = p_preset->get_files_to_export(); + for(int i=0;i<files.size();i++) { + if (scenes_only && ResourceLoader::get_resource_type(files[i])!="PackedScene") + continue; + + _export_find_dependencies(files[i],paths); + } + } + + //store everything in the export medium + int idx = 0; + int total=paths.size(); + + for(Set<String>::Element *E=paths.front();E;E=E->next()) { + + String path = E->get(); + + if (FileAccess::exists(path+".import")) { + //file is imported, replace by what it imports + Ref<ConfigFile> config; + config.instance(); + Error err = config->load(path+".import"); + if (err!=OK) { + ERR_PRINTS("Could not parse: '"+path+"', not exported."); + continue; + } + + List<String> remaps; + config->get_section_keys("remap",&remaps); + + for(List<String>::Element *F=remaps.front();F;F=F->next()) { + + String remap=F->get(); + if (remap=="path") { + String remapped_path=config->get_value("remap",remap); + Vector<uint8_t> array = FileAccess::get_file_as_array(remapped_path); + p_func(p_udata,remapped_path,array,idx,total); + } else if (remap.begins_with("path.")) { + String feature = remap.get_slice(".",1); + if (features.has(feature)) { + String remapped_path=config->get_value("remap",remap); + Vector<uint8_t> array = FileAccess::get_file_as_array(remapped_path); + p_func(p_udata,remapped_path,array,idx,total); + } + } + } + + //also save the .import file + Vector<uint8_t> array = FileAccess::get_file_as_array(path+".import"); + p_func(p_udata,path+".import",array,idx,total); + + } else { + //just store it as it comes + Vector<uint8_t> array = FileAccess::get_file_as_array(path); + p_func(p_udata,path,array,idx,total); + } + + idx++; + } + + //save config! + + String config_file="godot.cfb"; + String engine_cfb =EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmp"+config_file; + GlobalConfig::get_singleton()->save_custom(engine_cfb); + Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb); + + p_func(p_udata,"res://"+config_file,data,idx,total); + + return OK; +} + +Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset>& p_preset,const String& p_path) { + + EditorProgress ep("savepack",TTR("Packing"),102); + + String tmppath = EditorSettings::get_singleton()->get_settings_path()+"/tmp/packtmp"; + FileAccess *ftmp = FileAccess::open(tmppath,FileAccess::WRITE); + ERR_FAIL_COND_V(!ftmp,ERR_CANT_CREATE) + + PackData pd; + pd.ep=&ep; + pd.f=ftmp; + + Error err = export_project_files(p_preset,_save_pack_file,&pd); + + memdelete(ftmp); //close tmp file + + if (err) + return err; + + pd.file_ofs.sort(); //do sort, so we can do binary search later + + + FileAccess *f = FileAccess::open(p_path,FileAccess::WRITE); + ERR_FAIL_COND_V(!f,ERR_CANT_CREATE) + f->store_32(0x43504447); //GDPK + f->store_32(1); //pack version + f->store_32(VERSION_MAJOR); + f->store_32(VERSION_MINOR); + f->store_32(0); //hmph + for(int i=0;i<16;i++) { + //reserved + f->store_32(0); + } + + f->store_32(pd.file_ofs.size()); //amount of files + + size_t header_size = f->get_pos(); + + //precalculate header size + + for(int i=0;i<pd.file_ofs.size();i++) { + header_size += 4; // size of path string (32 bits is enough) + uint32_t string_len = pd.file_ofs[i].path_utf8.length(); + header_size += string_len + _get_pad(4,string_len); ///size of path string + header_size += 8; // offset to file _with_ header size included + header_size += 8; // size of file + header_size +=16; // md5 + + } + + size_t header_padding = _get_pad(PCK_PADDING,header_size); + + + for(int i=0;i<pd.file_ofs.size();i++) { + + uint32_t string_len = pd.file_ofs[i].path_utf8.length(); + uint32_t pad = _get_pad(4,string_len);; + f->store_32(string_len+pad); + f->store_buffer((const uint8_t*)pd.file_ofs[i].path_utf8.get_data(),string_len); + for(uint32_t j=0;j<pad;j++) { + f->store_8(0); + } + + f->store_64(pd.file_ofs[i].ofs + header_padding + header_size); + f->store_64(pd.file_ofs[i].size); // pay attention here, this is where file is + f->store_buffer(pd.file_ofs[i].md5.ptr(),16); //also save md5 for file + } + + for(uint32_t j=0;j<header_padding;j++) { + f->store_8(0); + } + + //save the rest of the data + + ftmp = FileAccess::open(tmppath,FileAccess::READ); + if (!ftmp) { + memdelete(f); + ERR_FAIL_COND_V(!ftmp,ERR_CANT_CREATE) + } + + const int bufsize=16384; + uint8_t buf[bufsize]; + + while(true) { + + int got = ftmp->get_buffer(buf,bufsize); + if (got<=0) + break; + f->store_buffer(buf,got); + } + + memdelete(ftmp); + + f->store_32(0x43504447); //GDPK + memdelete(f); + + return OK; +} + +Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset>& p_preset,const String& p_path) { + + EditorProgress ep("savezip",TTR("Packing"),102); + + //FileAccess *tmp = FileAccess::open(tmppath,FileAccess::WRITE); + + FileAccess *src_f; + zlib_filefunc_def io = zipio_create_io_from_file(&src_f); + zipFile zip=zipOpen2(p_path.utf8().get_data(),APPEND_STATUS_CREATE,NULL,&io); + + ZipData zd; + zd.ep=&ep; + zd.zip=zip; + + + Error err = export_project_files(p_preset,_save_zip_file,&zd); + + zipClose(zip,NULL); + + return OK; +} + +EditorExportPlatform::EditorExportPlatform() { + + +} + + +//// + +EditorExport *EditorExport::singleton=NULL; + + +void EditorExport::_save() { + + + Ref<ConfigFile> config; + config.instance(); + for(int i=0;i<export_presets.size();i++) { + + Ref<EditorExportPreset> preset = export_presets[i]; + String section="preset."+itos(i); + + config->set_value(section,"name",preset->get_name()); + config->set_value(section,"platform",preset->get_platform()->get_name()); + config->set_value(section,"runnable",preset->is_runnable()); + bool save_files=false; + switch(preset->get_export_filter()) { + case EditorExportPreset::EXPORT_ALL_RESOURCES: { + config->set_value(section,"export_filter","all_resources"); + } break; + case EditorExportPreset::EXPORT_SELECTED_SCENES: { + config->set_value(section,"export_filter","scenes"); + save_files=true; + } break; + case EditorExportPreset::EXPORT_SELECTED_RESOURCES: { + config->set_value(section,"export_filter","resources"); + save_files=true; + } break; + + + } + + if (save_files) { + Vector<String> export_files = preset->get_files_to_export(); + config->set_value(section,"export_files",export_files); + } + config->set_value(section,"include_filter",preset->get_include_filter()); + config->set_value(section,"exclude_filter",preset->get_exclude_filter()); + config->set_value(section,"patch_list",preset->get_patches()); + + String option_section="preset."+itos(i)+".options"; + + for (const List<PropertyInfo>::Element *E=preset->get_properties().front();E;E=E->next()) { + config->set_value(option_section,E->get().name,preset->get(E->get().name)); + } + } + + config->save("res://export_presets.cfg"); + + print_line("saved ok"); + +} + + +void EditorExport::save_presets() { + + print_line("save presets"); + if (block_save) + return; + save_timer->start(); +} + +void EditorExport::_bind_methods() { + + ClassDB::bind_method("_save",&EditorExport::_save); +} + +void EditorExport::add_export_platform(const Ref<EditorExportPlatform>& p_platform) { + + export_platforms.push_back(p_platform); +} + +int EditorExport::get_export_platform_count() { + + return export_platforms.size(); +} + +Ref<EditorExportPlatform> EditorExport::get_export_platform(int p_idx) { + + ERR_FAIL_INDEX_V(p_idx,export_platforms.size(),Ref<EditorExportPlatform>()); + + return export_platforms[p_idx]; +} + + +void EditorExport::add_export_preset(const Ref<EditorExportPreset>& p_preset,int p_at_pos) { + + if (p_at_pos<0) + export_presets.push_back(p_preset); + else + export_presets.insert(p_at_pos,p_preset); + + +} + +int EditorExport::get_export_preset_count() const { + + return export_presets.size(); +} + +Ref<EditorExportPreset> EditorExport::get_export_preset(int p_idx) { + + ERR_FAIL_INDEX_V( p_idx, export_presets.size(),Ref<EditorExportPreset>() ); + return export_presets[p_idx]; +} + +void EditorExport::remove_export_preset(int p_idx) { + + export_presets.remove(p_idx); +} + +void EditorExport::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + load_config(); + } +} + +void EditorExport::load_config() { + + Ref<ConfigFile> config; + config.instance(); + Error err = config->load("res://export_presets.cfg"); + if (err!=OK) + return; + + block_save=true; + + int index=0; + while(true) { + + String section = "preset."+itos(index); + if (!config->has_section(section)) + break; + + String platform=config->get_value(section,"platform"); + + Ref<EditorExportPreset> preset; + + for(int i=0;i<export_platforms.size();i++) { + if (export_platforms[i]->get_name()==platform) { + preset = export_platforms[i]->create_preset(); + break; + } + } + + if (!preset.is_valid()) { + index++; + ERR_CONTINUE(!preset.is_valid()); + } + + preset->set_name( config->get_value(section,"name") ); + preset->set_runnable( config->get_value(section,"runnable") ); + + String export_filter = config->get_value(section,"export_filter"); + + bool get_files=false; + + if (export_filter=="all_resources") { + preset->set_export_filter(EditorExportPreset::EXPORT_ALL_RESOURCES); + } else if (export_filter=="scenes") { + preset->set_export_filter(EditorExportPreset::EXPORT_SELECTED_SCENES); + get_files=true; + } else if (export_filter=="resources") { + preset->set_export_filter(EditorExportPreset::EXPORT_SELECTED_RESOURCES); + get_files=true; + } + + if (get_files) { + + Vector<String> files = config->get_value(section,"export_files"); + + for(int i=0;i<files.size();i++) { + preset->add_export_file(files[i]); + } + } + + preset->set_include_filter( config->get_value(section,"include_filter") ); + preset->set_exclude_filter( config->get_value(section,"exclude_filter") ); + + + Vector<String> patch_list = config->get_value(section,"patch_list"); + + for(int i=0;i<patch_list.size();i++) { + preset->add_patch(patch_list[i]); + } + + String option_section="preset."+itos(index)+".options"; + + List<String> options; + + config->get_section_keys(option_section,&options); + + for (List<String>::Element *E=options.front();E;E=E->next()) { + + Variant value = config->get_value(option_section,E->get()); + + preset->set(E->get(),value); + } + + add_export_preset(preset); + index++; + } + + block_save=false; + +} + + + +EditorExport::EditorExport() { + + save_timer = memnew( Timer ); + add_child(save_timer); + save_timer->set_wait_time(0.8); + save_timer->set_one_shot(true); + save_timer->connect("timeout",this,"_save"); + block_save=false; + + singleton=this; +} + +EditorExport::~EditorExport() { + + +} + + +////////// + +void EditorExportPlatformPC::get_preset_features(const Ref<EditorExportPreset>& p_preset,List<String>* r_features) { + + if (p_preset->get("texture_format/s3tc")) { + r_features->push_back("s3tc"); + } + if (p_preset->get("texture_format/etc")) { + r_features->push_back("etc"); + } + if (p_preset->get("texture_format/etc2")) { + r_features->push_back("etc2"); + } +} + +void EditorExportPlatformPC::get_export_options(List<ExportOption> *r_options) { + + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL,"texture_format/s3tc"),true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL,"texture_format/etc"),false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL,"texture_format/etc2"),false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL,"binary_format/64_bits"),true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING,"custom_template/release",PROPERTY_HINT_GLOBAL_FILE),"")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING,"custom_template/debug",PROPERTY_HINT_GLOBAL_FILE),"")); +} + +String EditorExportPlatformPC::get_name() const { + + return name; +} +Ref<Texture> EditorExportPlatformPC::get_logo() const { + + return logo; +} + +bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset>& p_preset,String &r_error, bool &r_missing_templates) const { + + r_missing_templates=false; + + if (find_export_template(release_file_32)==String()) { + r_missing_templates=true; + } else if (find_export_template(debug_file_32)==String()) { + r_missing_templates=true; + } else if (find_export_template(release_file_64)==String()) { + r_missing_templates=true; + } else if (find_export_template(debug_file_64)==String()) { + r_missing_templates=true; + } + return !r_missing_templates; +} + +String EditorExportPlatformPC::get_binary_extension() const { + return extension; +} + +Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset>& p_preset, bool p_debug, const String& p_path, int p_flags) { + + return OK; +} + +void EditorExportPlatformPC::set_extension(const String& p_extension) { + extension=p_extension; +} + +void EditorExportPlatformPC::set_name(const String& p_name) { + name=p_name; +} + +void EditorExportPlatformPC::set_logo(const Ref<Texture>& p_logo) { + logo=p_logo; +} + +void EditorExportPlatformPC::set_release_64(const String& p_file) { + + release_file_64=p_file; +} + +void EditorExportPlatformPC::set_release_32(const String& p_file){ + + release_file_32=p_file; +} +void EditorExportPlatformPC::set_debug_64(const String& p_file){ + + debug_file_64=p_file; +} +void EditorExportPlatformPC::set_debug_32(const String& p_file){ + + debug_file_32=p_file; + +} + +EditorExportPlatformPC::EditorExportPlatformPC() { + +} + +//////// + +#if 0 +#include "version.h" +#include "script_language.h" +#include "global_config.h" +#include "os/file_access.h" +#include "os/dir_access.h" +#include "editor/editor_file_system.h" +#include "io/resource_loader.h" +#include "editor_node.h" +#include "editor_settings.h" +#include "io/config_file.h" +#include "io/resource_saver.h" +#include "io/md5.h" +#include "io_plugins/editor_texture_import_plugin.h" +#include "editor/plugins/script_editor_plugin.h" +#include "io/zip_io.h" + + +String EditorImportPlugin::validate_source_path(const String& p_path) { + + String gp = GlobalConfig::get_singleton()->globalize_path(p_path); + String rp = GlobalConfig::get_singleton()->get_resource_path(); + if (!rp.ends_with("/")) + rp+="/"; + + return rp.path_to_file(gp); +} + +String EditorImportPlugin::expand_source_path(const String& p_path) { + + if (p_path.is_rel_path()) { + return GlobalConfig::get_singleton()->get_resource_path().plus_file(p_path).simplify_path(); + } else { + return p_path; + } +} + + +String EditorImportPlugin::_validate_source_path(const String& p_path) { + + return validate_source_path(p_path); +} + +String EditorImportPlugin::_expand_source_path(const String& p_path) { + + return expand_source_path(p_path); +} + +void EditorImportPlugin::_bind_methods() { + + + ClassDB::bind_method(D_METHOD("validate_source_path","path"),&EditorImportPlugin::_validate_source_path); + ClassDB::bind_method(D_METHOD("expand_source_path","path"),&EditorImportPlugin::_expand_source_path); + + ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::STRING,"get_name")); + ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::STRING,"get_visible_name")); + ClassDB::add_virtual_method(get_class_static(),MethodInfo("import_dialog",PropertyInfo(Variant::STRING,"from"))); + ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::INT,"import",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"from",PROPERTY_HINT_RESOURCE_TYPE,"ResourceImportMetadata"))); + ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::POOL_BYTE_ARRAY,"custom_export",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"platform",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatform"))); + ClassDB::add_virtual_method(get_class_static(),MethodInfo("import_from_drop",PropertyInfo(Variant::POOL_STRING_ARRAY,"files"),PropertyInfo(Variant::STRING,"dest_path"))); + ClassDB::add_virtual_method(get_class_static(),MethodInfo("reimport_multiple_files",PropertyInfo(Variant::POOL_STRING_ARRAY,"files"))); + ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::BOOL,"can_reimport_multiple_files")); + + //BIND_VMETHOD( mi ); +} + +String EditorImportPlugin::get_name() const { + + if (get_script_instance() && get_script_instance()->has_method("get_name")) { + return get_script_instance()->call("get_name"); + } + + ERR_FAIL_V(""); +} + +String EditorImportPlugin::get_visible_name() const { + + if (get_script_instance() && get_script_instance()->has_method("get_visible_name")) { + return get_script_instance()->call("get_visible_name"); + } + + ERR_FAIL_V(""); +} + + +void EditorImportPlugin::import_dialog(const String& p_from) { + + if (get_script_instance() && get_script_instance()->has_method("import_dialog")) { + get_script_instance()->call("import_dialog",p_from); + return; + } + + ERR_FAIL(); + +} + +Error EditorImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from) { + + if (get_script_instance() && get_script_instance()->has_method("import")) { + return Error(get_script_instance()->call("import",p_path,p_from).operator int()); + } + + ERR_FAIL_V(ERR_UNAVAILABLE); +} + +Vector<uint8_t> EditorImportPlugin::custom_export(const String& p_path, const Ref<EditorExportPlatform> &p_platform) { + + if (get_script_instance() && get_script_instance()->has_method("custom_export")) { + get_script_instance()->call("custom_export",p_path,p_platform); + } + + return Vector<uint8_t>(); +} + +bool EditorImportPlugin::can_reimport_multiple_files() const { + + if (get_script_instance() && get_script_instance()->has_method("can_reimport_multiple_files")) { + return get_script_instance()->call("can_reimport_multiple_files"); + } + + return false; +} +void EditorImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { + + if (get_script_instance() && get_script_instance()->has_method("reimport_multiple_files")) { + get_script_instance()->call("reimport_multiple_files",p_list); + } + +} + +void EditorImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + if (get_script_instance() && get_script_instance()->has_method("import_from_drop")) { + get_script_instance()->call("import_from_drop",p_drop,p_dest_path); + } + +} + +EditorImportPlugin::EditorImportPlugin() { + + +} + +///////////////////////////////////////////////////////////////////////////////////////////////////// + + +void EditorExportPlugin::_bind_methods() { + + MethodInfo mi = MethodInfo("custom_export:Variant",PropertyInfo(Variant::STRING,"name"),PropertyInfo(Variant::OBJECT,"platform",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatform")); + mi.return_val.type=Variant::POOL_BYTE_ARRAY; + + BIND_VMETHOD( mi ); +} + + +Vector<uint8_t> EditorExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) { + + if (get_script_instance()) { + + Variant d = get_script_instance()->call("custom_export",p_path,p_platform); + if (d.get_type()==Variant::NIL) + return Vector<uint8_t>(); + if (d.get_type()==Variant::POOL_BYTE_ARRAY) + return d; + + ERR_FAIL_COND_V(d.get_type()!=Variant::DICTIONARY,Vector<uint8_t>()); + Dictionary dict=d; + ERR_FAIL_COND_V(!dict.has("name"),Vector<uint8_t>()); + ERR_FAIL_COND_V(!dict.has("data"),Vector<uint8_t>()); + p_path=dict["name"]; + return dict["data"]; + } + + return Vector<uint8_t>(); + +} + + +EditorExportPlugin::EditorExportPlugin() { + + +} + +///////////////////////////////////////////////////////////////////////////////////////////////////// + + + +static void _add_to_list(EditorFileSystemDirectory *p_efsd,Set<StringName>& r_list) { + + for(int i=0;i<p_efsd->get_subdir_count();i++) { + + _add_to_list(p_efsd->get_subdir(i),r_list); + } + + for(int i=0;i<p_efsd->get_file_count();i++) { + r_list.insert(p_efsd->get_file_path(i)); + } +} + + +struct __EESortDepCmp { + + _FORCE_INLINE_ bool operator()(const StringName& p_l,const StringName& p_r) const { + return p_l.operator String() < p_r.operator String(); + } +}; + + + + +static void _edit_files_with_filter(DirAccess *da,const List<String>& p_filters,Set<StringName>& r_list,bool exclude) { + + + List<String> files; + List<String> dirs; + + da->list_dir_begin(); + + String f = da->get_next(); + while(f!="") { + + print_line("HOHO: "+f); + if (da->current_is_dir()) + dirs.push_back(f); + else + files.push_back(f); + + f=da->get_next(); + } + + String r = da->get_current_dir().replace("\\","/"); + if (!r.ends_with("/")) + r+="/"; + + print_line("AT: "+r); + + for(List<String>::Element *E=files.front();E;E=E->next()) { + String fullpath=r+E->get(); + for(const List<String>::Element *F=p_filters.front();F;F=F->next()) { + + if (fullpath.matchn(F->get())) { + String act = TTR("Added:")+" "; + + if (!exclude) { + r_list.insert(fullpath); + } else { + act = TTR("Removed:")+" "; + r_list.erase(fullpath); + } + + + print_line(act+fullpath); + } + } + } + + da->list_dir_end(); + + for(List<String>::Element *E=dirs.front();E;E=E->next()) { + if (E->get().begins_with(".")) + continue; + da->change_dir(E->get()); + _edit_files_with_filter(da,p_filters,r_list,exclude); + da->change_dir(".."); + } + +} + +static void _edit_filter_list(Set<StringName>& r_list,const String& p_filter,bool exclude) { + + if (p_filter=="") + return; + Vector<String> split = p_filter.split(","); + List<String> filters; + for(int i=0;i<split.size();i++) { + String f = split[i].strip_edges(); + if (f.empty()) + continue; + filters.push_back(f); + } + + DirAccess *da = DirAccess::open("res://"); + ERR_FAIL_NULL(da); + _edit_files_with_filter(da,filters,r_list,exclude); + memdelete(da); +} + +static void _add_filter_to_list(Set<StringName>& r_list,const String& p_filter) { + _edit_filter_list(r_list,p_filter,false); +} + +static void _remove_filter_from_list(Set<StringName>& r_list,const String& p_filter) { + _edit_filter_list(r_list,p_filter,true); +} + +bool EditorExportPlatform::_set(const StringName& p_name, const Variant& p_value) { + + String n = p_name; + + if (n=="debug/debugging_enabled") { + set_debugging_enabled(p_value); + } else { + return false; + } + + return true; + +} + +bool EditorExportPlatform::_get(const StringName& p_name,Variant &r_ret) const { + + String n = p_name; + + if (n=="debug/debugging_enabled") { + r_ret=is_debugging_enabled(); + } else { + return false; + } + + return true; + +} + +void EditorExportPlatform::_get_property_list( List<PropertyInfo> *p_list) const { + + p_list->push_front( PropertyInfo( Variant::BOOL, "debug/debugging_enabled")); +} + +Vector<uint8_t> EditorExportPlatform::get_exported_file_default(String& p_fname) const { + + FileAccess *f = FileAccess::open(p_fname,FileAccess::READ); + ERR_FAIL_COND_V(!f,Vector<uint8_t>()); + Vector<uint8_t> ret; + ret.resize(f->get_len()); + int rbs = f->get_buffer(ret.ptr(),ret.size()); + memdelete(f); + return ret; +} + +Vector<uint8_t> EditorExportPlatform::get_exported_file(String& p_fname) const { + + Ref<EditorExportPlatform> ep=EditorImportExport::get_singleton()->get_export_platform(get_name()); + + for(int i=0;i<EditorImportExport::get_singleton()->get_export_plugin_count();i++) { + + Vector<uint8_t> data = EditorImportExport::get_singleton()->get_export_plugin(i)->custom_export(p_fname,ep); + if (data.size()) + return data; + + } + + + return get_exported_file_default(p_fname); + + +} + +Vector<StringName> EditorExportPlatform::get_dependencies(bool p_bundles) const { + + + Set<StringName> exported; + + if (FileAccess::exists("res://godot.cfg")) + exported.insert("res://godot.cfg"); + + if (EditorImportExport::get_singleton()->get_export_filter()!=EditorImportExport::EXPORT_SELECTED) { + + String filter; + if (EditorImportExport::get_singleton()->get_export_filter()==EditorImportExport::EXPORT_ALL) { + _add_filter_to_list(exported,"*"); + } else { + _add_to_list(EditorFileSystem::get_singleton()->get_filesystem(),exported); + String cf = EditorImportExport::get_singleton()->get_export_custom_filter(); + if (cf!="") + cf+=","; + cf+="*.flags"; + _add_filter_to_list(exported,cf); + + cf = EditorImportExport::get_singleton()->get_export_custom_filter_exclude(); + _remove_filter_from_list(exported,cf); + } + + + } else { + + + Map<String,Map<String,String> > remapped_paths; + + Set<String> scene_extensions; + Set<String> resource_extensions; + + { + + List<String> l; + /* + SceneLoader::get_recognized_extensions(&l); + for(List<String>::Element *E=l.front();E;E=E->next()) { + scene_extensions.insert(E->get()); + } + */ + ResourceLoader::get_recognized_extensions_for_type("",&l); + for(List<String>::Element *E=l.front();E;E=E->next()) { + + resource_extensions.insert(E->get()); + } + } + + + List<StringName> toexport; + + EditorImportExport::get_singleton()->get_export_file_list(&toexport); + + print_line("TO EXPORT: "+itos(toexport.size())); + + + for (List<StringName>::Element *E=toexport.front();E;E=E->next()) { + + print_line("DEP: "+String(E->get())); + exported.insert(E->get()); + if (p_bundles && EditorImportExport::get_singleton()->get_export_file_action(E->get())==EditorImportExport::ACTION_BUNDLE) { + print_line("NO BECAUSE OF BUNDLE!"); + continue; //no dependencies needed to be copied + } + + List<String> testsubs; + testsubs.push_back(E->get()); + + while(testsubs.size()) { + //recursive subdep search! + List<String> deplist; + ResourceLoader::get_dependencies(testsubs.front()->get(),&deplist); + testsubs.pop_front(); + + List<String> subdeps; + + for (List<String>::Element *F=deplist.front();F;F=F->next()) { + + StringName dep = F->get(); + + if (exported.has(dep) || EditorImportExport::get_singleton()->get_export_file_action(dep)!=EditorImportExport::ACTION_NONE) + continue; //dependency added or to be added + print_line(" SUBDEP: "+String(dep)); + + exported.insert(dep); + testsubs.push_back(dep); + } + } + } + String cf = EditorImportExport::get_singleton()->get_export_custom_filter(); + if (cf!="") + cf+=","; + cf+="*.flags"; + _add_filter_to_list(exported,cf); + + cf = EditorImportExport::get_singleton()->get_export_custom_filter_exclude(); + _remove_filter_from_list(exported,cf); + + + } + + Vector<StringName> ret; + ret.resize(exported.size()); + + + int idx=0; + for(Set<StringName>::Element *E=exported.front();E;E=E->next()) { + + ret[idx++]=E->get(); + + } + + SortArray<StringName,__EESortDepCmp> sort; //some platforms work better if this is sorted + sort.sort(ret.ptr(),ret.size()); + + return ret; + +} + +String EditorExportPlatform::find_export_template(String template_file_name, String *err) const { + String user_file = EditorSettings::get_singleton()->get_settings_path() + +"/templates/"+template_file_name; + String system_file=OS::get_singleton()->get_installed_templates_path(); + bool has_system_path=(system_file!=""); + system_file+=template_file_name; + + // Prefer user file + if (FileAccess::exists(user_file)) { + return user_file; + } + + // Now check system file + if (has_system_path) { + if (FileAccess::exists(system_file)) { + return system_file; + } + } + + // Not found + if (err) { + *err+="No export template found at \""+user_file+"\""; + if (has_system_path) + *err+="\n or \""+system_file+"\"."; + else + *err+="."; + } + return ""; +} + +bool EditorExportPlatform::exists_export_template(String template_file_name, String *err) const { + return find_export_template(template_file_name,err)!=""; +} + +/////////////////////////////////////// + + + +bool EditorExportPlatform::is_debugging_enabled() const { + + return debugging_enabled; +} + +void EditorExportPlatform::set_debugging_enabled(bool p_enabled) { + + debugging_enabled = p_enabled; +} + +bool EditorExportPlatformPC::_set(const StringName& p_name, const Variant& p_value) { + + String n = p_name; + + if (n=="custom_binary/release") { + + custom_release_binary=p_value; + } else if (n=="custom_binary/debug") { + + custom_debug_binary=p_value; + } else if (n=="resources/pack_mode") { + + export_mode=ExportMode(int(p_value)); + } else if (n=="resources/bundle_dependencies_(for_optical_disc)") { + + bundle=p_value; + } else if (n=="binary/64_bits") { + + use64=p_value; + } else + return false; + + return true; + +} + +bool EditorExportPlatformPC::_get(const StringName& p_name,Variant &r_ret) const { + + String n = p_name; + + if (n=="custom_binary/release") { + + r_ret=custom_release_binary; + } else if (n=="custom_binary/debug") { + + r_ret=custom_debug_binary; + } else if (n=="resources/pack_mode") { + + r_ret=export_mode; + } else if (n=="resources/bundle_dependencies_(for_optical_disc)") { + + r_ret=bundle; + } else if (n=="binary/64_bits") { + + r_ret=use64; + } else + return false; + + return true; + +} + +void EditorExportPlatformPC::_get_property_list( List<PropertyInfo> *p_list) const { + + p_list->push_back( PropertyInfo( Variant::STRING, "custom_binary/debug", PROPERTY_HINT_GLOBAL_FILE,binary_extension)); + p_list->push_back( PropertyInfo( Variant::STRING, "custom_binary/release", PROPERTY_HINT_GLOBAL_FILE,binary_extension)); + p_list->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Pack into executable,Pack into binary file (.pck),Pack into archive file (.zip)")); + p_list->push_back( PropertyInfo( Variant::BOOL, "resources/bundle_dependencies_(for_optical_disc)")); + p_list->push_back( PropertyInfo( Variant::BOOL, "binary/64_bits")); +} + + + +static void _exp_add_dep(Map<StringName,List<StringName> > &deps,const StringName& p_path) { + + + if (deps.has(p_path)) + return; //already done + + deps.insert(p_path,List<StringName>()); + + List<StringName> &deplist=deps[p_path]; + Set<StringName> depset; + + List<String> dl; + ResourceLoader::get_dependencies(p_path,&dl); + + //added in order so child dependencies are always added bfore parent dependencies + for (List<String>::Element *E=dl.front();E;E=E->next()) { + + + if (!deps.has(E->get())) + _exp_add_dep(deps,E->get()); + + for(List<StringName>::Element *F=deps[E->get()].front();F;F=F->next()) { + + + if (!depset.has(F->get())) { + depset.insert(F->get()); + deplist.push_back(F->get()); + } + } + + if (!depset.has(E->get())) { + depset.insert(E->get()); + deplist.push_back(E->get()); + } + + } +} + + + +Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func, void* p_udata,bool p_make_bundles) { + +/* ALL FILES AND DEPENDENCIES */ + + Vector<StringName> files=get_dependencies(p_make_bundles); + + Map<StringName,List<StringName> > deps; + + if (false) { + for(int i=0;i<files.size();i++) { + + _exp_add_dep(deps,files[i]); + + } + } + + + +/* GROUP ATLAS */ + + + List<StringName> groups; + + EditorImportExport::get_singleton()->image_export_get_groups(&groups); + + Map<StringName,StringName> remap_files; + Set<StringName> saved; + + int counter=0; + + for(List<StringName>::Element *E=groups.front();E;E=E->next()) { + + if (!EditorImportExport::get_singleton()->image_export_group_get_make_atlas(E->get())) + continue; //uninterested, only process for atlas! + + List<StringName> atlas_images; + EditorImportExport::get_singleton()->image_export_get_images_in_group(E->get(),&atlas_images); + atlas_images.sort_custom<StringName::AlphCompare>(); + + for (List<StringName>::Element *F=atlas_images.front();F;) { + + List<StringName>::Element *N=F->next(); + + if (!FileAccess::exists(F->get())) { + atlas_images.erase(F); + } + + F=N; + + } + + if (atlas_images.size()<=1) + continue; + + int group_format=0; + float group_lossy_quality=EditorImportExport::get_singleton()->image_export_group_get_lossy_quality(E->get()); + int group_shrink=EditorImportExport::get_singleton()->image_export_group_get_shrink(E->get()); + group_shrink*=EditorImportExport::get_singleton()->get_export_image_shrink(); + + switch(EditorImportExport::get_singleton()->image_export_group_get_image_action(E->get())) { + case EditorImportExport::IMAGE_ACTION_KEEP: + case EditorImportExport::IMAGE_ACTION_NONE: { + + switch(EditorImportExport::get_singleton()->get_export_image_action()) { + case EditorImportExport::IMAGE_ACTION_NONE: { + + group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS; //? + + } break; //use default + case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: { + group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY; + } break; //use default + case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: { + group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM; + } break; //use default + } + + group_lossy_quality=EditorImportExport::get_singleton()->get_export_image_quality(); + + } break; //use default + case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: { + group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY; + } break; //use default + case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: { + group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM; + } break; //use default + } + + String image_listD_METHOD5; + + { + MD5_CTX ctx; + MD5Init(&ctx); + for (List<StringName>::Element *F=atlas_images.front();F;F=F->next()) { + + String p = F->get(); + MD5Update(&ctx,(unsigned char*)p.utf8().get_data(),p.utf8().length()); + + } + + MD5Final(&ctx); + image_listD_METHOD5=String::md5(ctx.digest); + } + //ok see if cached + String md5; + bool atlas_valid=true; + String atlas_name; + + { + MD5_CTX ctx; + MD5Init(&ctx); + String path = GlobalConfig::get_singleton()->get_resource_path()+"::"+String(E->get())+"::"+get_name(); + MD5Update(&ctx,(unsigned char*)path.utf8().get_data(),path.utf8().length()); + MD5Final(&ctx); + md5 = String::md5(ctx.digest); + } + + FileAccess *f=NULL; + + if (!FileAccess::exists(EditorSettings::get_singleton()->get_settings_path()+"/tmp/atlas-"+md5)) { + print_line("NO MD5 INVALID"); + atlas_valid=false; + } + + if (atlas_valid) + f=FileAccess::open(EditorSettings::get_singleton()->get_settings_path()+"/tmp/atlas-"+md5,FileAccess::READ); + + if (atlas_valid) { + //compare options + /*Dictionary options; + options.parse_json(f->get_line()); + if (!options.has("lossy_quality") || float(options["lossy_quality"])!=group_lossy_quality) + atlas_valid=false; + else if (!options.has("shrink") || int(options["shrink"])!=group_shrink) + atlas_valid=false; + else if (!options.has("image_format") || int(options["image_format"])!=group_format) + atlas_valid=false; + + if (!atlas_valid) + print_line("JSON INVALID"); +*/ + } + + + if (atlas_valid) { + //check md5 of list of image /names/ + if (f->get_line().strip_edges()!=image_listD_METHOD5) { + atlas_valid=false; + print_line("IMAGE MD5 INVALID!"); + } + + } + + Vector<Rect2> rects; + bool resave_deps=false; + + if (atlas_valid) { + + //check if images were not modified + for (List<StringName>::Element *F=atlas_images.front();F;F=F->next()) { + + Vector<String> slices = f->get_line().strip_edges().split("::"); + + if (slices.size()!=10) { + atlas_valid=false; + print_line("CANT SLICE IN 10"); + break; + } + uint64_t mod_time = slices[0].to_int64(); + uint64_t file_mod_time = FileAccess::get_modified_time(F->get()); + if (mod_time!=file_mod_time) { + + String imageD_METHOD5 = slices[1]; + String fileD_METHOD5 = FileAccess::getD_METHOD5(F->get()); + + if (imageD_METHOD5!=fileD_METHOD5) { + atlas_valid=false; + print_line("IMAGE INVALID "+slices[0]); + break; + } else { + resave_deps=true; + } + } + + if (atlas_valid) { + //push back region and margin + rects.push_back(Rect2(slices[2].to_float(),slices[3].to_float(),slices[4].to_float(),slices[5].to_float())); + rects.push_back(Rect2(slices[6].to_float(),slices[7].to_float(),slices[8].to_float(),slices[9].to_float())); + } + } + + } + + if (f) { + memdelete(f); + f=NULL; + } + + print_line("ATLAS VALID? "+itos(atlas_valid)+" RESAVE DEPS? "+itos(resave_deps)); + if (!atlas_valid) { + rects.clear(); + //oh well, atlas is not valid. need to make new one.... + + String dst_file = EditorSettings::get_singleton()->get_settings_path()+"/tmp/atlas-"+md5+".tex"; + Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); + //imd->set_editor(); + + + for (List<StringName>::Element *F=atlas_images.front();F;F=F->next()) { + + imd->add_source(EditorImportPlugin::validate_source_path(F->get()),FileAccess::getD_METHOD5(F->get())); + + } + + + imd->set_option("format",group_format); + + + int flags=0; + + if (GlobalConfig::get_singleton()->get("image_loader/filter")) + flags|=EditorTextureImportPlugin::IMAGE_FLAG_FILTER; + if (!GlobalConfig::get_singleton()->get("image_loader/gen_mipmaps")) + flags|=EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS; + if (!GlobalConfig::get_singleton()->get("image_loader/repeat")) + flags|=EditorTextureImportPlugin::IMAGE_FLAG_REPEAT; + + flags|=EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA; + + imd->set_option("flags",flags); + imd->set_option("quality",group_lossy_quality); + imd->set_option("atlas",true); + imd->set_option("crop",true); + imd->set_option("shrink",group_shrink); + + + + Ref<EditorTextureImportPlugin> plugin = EditorImportExport::get_singleton()->get_import_plugin_by_name("texture"); + Error err = plugin->import2(dst_file,imd,get_image_compression(),true); + if (err) { + + EditorNode::add_io_error(TTR("Error saving atlas:")+" "+dst_file.get_file()); + return ERR_CANT_CREATE; + } + + ERR_FAIL_COND_V(imd->get_option("rects")==Variant(),ERR_BUG); + + Array r_rects=imd->get_option("rects"); + rects.resize(r_rects.size()); + for(int i=0;i<r_rects.size();i++) { + //get back region and margins + rects[i]=r_rects[i]; + } + + + resave_deps=true; + } + + + //atlas is valid (or it was just saved i guess), create the atex files and save them + + if (resave_deps) { + f=FileAccess::open(EditorSettings::get_singleton()->get_settings_path()+"/tmp/atlas-"+md5,FileAccess::WRITE); + Dictionary options; + options["lossy_quality"]=group_lossy_quality; + options["shrink"]=EditorImportExport::get_singleton()->image_export_group_get_shrink(E->get()); + options["image_format"]=group_format; + //f->store_line(options.to_json()); + f->store_line(image_listD_METHOD5); + } + + //go through all ATEX files + + { + Ref<ImageTexture> atlas = memnew( ImageTexture ); //fake atlas! + String atlas_path="res://atlas-"+md5+".tex"; + atlas->set_path(atlas_path); + int idx=0; + for (List<StringName>::Element *F=atlas_images.front();F;F=F->next()) { + + String p = F->get(); + Ref<AtlasTexture> atex = memnew(AtlasTexture); + atex->set_atlas(atlas); + Rect2 region=rects[idx++]; + Rect2 margin=rects[idx++]; + atex->set_region(region); + atex->set_margin(margin); + + String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmpatlas.atex"; + Error err = ResourceSaver::save(path,atex); + if (err!=OK) { + EditorNode::add_io_error(TTR("Could not save atlas subtexture:")+" "+path); + return ERR_CANT_CREATE; + } + Vector<uint8_t> data = FileAccess::get_file_as_array(path); + String dst_path = F->get().operator String().get_basename()+".atex"; + err = p_func(p_udata,dst_path,data,counter++,files.size()); + saved.insert(dst_path); + if (err) + return err; + + if (f) { + //recreating deps.. + String depline; + //depline=String(F->get())+"::"+itos(FileAccess::get_modified_time(F->get()))+"::"+FileAccess::getD_METHOD5(F->get()); name unneccesary by top md5 + depline=itos(FileAccess::get_modified_time(F->get()))+"::"+FileAccess::getD_METHOD5(F->get()); + depline+="::"+itos(region.pos.x)+"::"+itos(region.pos.y)+"::"+itos(region.size.x)+"::"+itos(region.size.y); + depline+="::"+itos(margin.pos.x)+"::"+itos(margin.pos.y)+"::"+itos(margin.size.x)+"::"+itos(margin.size.y); + f->store_line(depline); + } + + remap_files[F->get()]=dst_path; + } + + Vector<uint8_t> atlas_data = FileAccess::get_file_as_array(EditorSettings::get_singleton()->get_settings_path()+"/tmp/atlas-"+md5+".tex"); + Error err = p_func(p_udata,atlas_path,atlas_data,counter,files.size()); + saved.insert(atlas_path); + if (err) + return err; + + } + + + if (f) { + memdelete(f); + } + + } + + + StringName engine_cfg="res://godot.cfg"; + StringName boot_splash; + { + String splash=GlobalConfig::get_singleton()->get("application/boot_splash"); //avoid splash from being converted + splash=splash.strip_edges(); + if (splash!=String()) { + if (!splash.begins_with("res://")) + splash="res://"+splash; + splash=splash.simplify_path(); + boot_splash=splash; + } + } + StringName custom_cursor; + { + String splash=GlobalConfig::get_singleton()->get("display/custom_mouse_cursor"); //avoid splash from being converted + splash=splash.strip_edges(); + if (splash!=String()) { + if (!splash.begins_with("res://")) + splash="res://"+splash; + splash=splash.simplify_path(); + custom_cursor=splash; + } + } + + + + + for(int i=0;i<files.size();i++) { + + if (remap_files.has(files[i]) || files[i]==engine_cfg) //gonna be remapped (happened before!) + continue; //from atlas? + String src=files[i]; + Vector<uint8_t> buf; + + if (src==boot_splash || src==custom_cursor) + buf = get_exported_file_default(src); //bootsplash must be kept if used + else + buf = get_exported_file(src); + + ERR_CONTINUE( saved.has(src) ); + + Error err = p_func(p_udata,src,buf,counter++,files.size()); + if (err) + return err; + + saved.insert(src); + if (src!=String(files[i])) + remap_files[files[i]]=src; + + } + + + { + + //make binary godot.cfg config + Map<String,Variant> custom; + + + if (remap_files.size()) { + Vector<String> remapsprop; + for(Map<StringName,StringName>::Element *E=remap_files.front();E;E=E->next()) { + print_line("REMAP: "+String(E->key())+" -> "+E->get()); + remapsprop.push_back(E->key()); + remapsprop.push_back(E->get()); + } + + custom["remap/all"]=remapsprop; + } + + //add presaved dependencies + for(Map<StringName,List<StringName> >::Element *E=deps.front();E;E=E->next()) { + + if (E->get().size()==0) + continue; //no deps + String key; + Vector<StringName> deps; + //if bundle continue (when bundles supported obviously) + + if (remap_files.has(E->key())) { + key=remap_files[E->key()]; + } else { + key=E->key(); + } + + deps.resize(E->get().size()); + int i=0; + + for(List<StringName>::Element *F=E->get().front();F;F=F->next()) { + deps[i++]=F->get(); + print_line(" -"+String(F->get())); + } + + NodePath prop(deps,true,String()); //seems best to use this for performance + + custom["deps/"+key.md5_text()]=prop; + + } + + String remap_file="godot.cfb"; + String engine_cfb =EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmp"+remap_file; + GlobalConfig::get_singleton()->save_custom(engine_cfb,custom); + Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb); + + Error err = p_func(p_udata,"res://"+remap_file,data,counter,files.size()); + if (err) + return err; + + } + + return OK; +} + +static int _get_pad(int p_alignment, int p_n) { + + int rest = p_n % p_alignment; + int pad = 0; + if (rest > 0) { + pad = p_alignment - rest; + }; + + return pad; +}; + +void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags) { + + String host = EditorSettings::get_singleton()->get("network/debug_host"); + + if (p_flags&EXPORT_REMOTE_DEBUG_LOCALHOST) + host="localhost"; + + if (p_flags&EXPORT_DUMB_CLIENT) { + int port = EditorSettings::get_singleton()->get("filesystem/file_server/port"); + String passwd = EditorSettings::get_singleton()->get("filesystem/file_server/password"); + r_flags.push_back("-rfs"); + r_flags.push_back(host+":"+itos(port)); + if (passwd!="") { + r_flags.push_back("-rfs_pass"); + r_flags.push_back(passwd); + } + } + + if (p_flags&EXPORT_REMOTE_DEBUG) { + + r_flags.push_back("-rdebug"); + + r_flags.push_back(host+":"+String::num(GLOBAL_DEF("network/debug/remote_port", 6007))); + + List<String> breakpoints; + ScriptEditor::get_singleton()->get_breakpoints(&breakpoints); + + + if (breakpoints.size()) { + + r_flags.push_back("-bp"); + String bpoints; + for(const List<String>::Element *E=breakpoints.front();E;E=E->next()) { + + bpoints+=E->get().replace(" ","%20"); + if (E->next()) + bpoints+=","; + } + + r_flags.push_back(bpoints); + } + + } + + if (p_flags&EXPORT_VIEW_COLLISONS) { + + r_flags.push_back("-debugcol"); + } + + if (p_flags&EXPORT_VIEW_NAVIGATION) { + + r_flags.push_back("-debugnav"); + } + + +} + +Error EditorExportPlatform::save_pack_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total) { + + + PackData *pd = (PackData*)p_userdata; + + CharString cs=p_path.utf8(); + pd->f->store_32(cs.length()); + pd->f->store_buffer((uint8_t*)cs.get_data(),cs.length()); + TempData td; + td.pos=pd->f->get_pos(); + td.ofs=pd->ftmp->get_pos(); + td.size=p_data.size(); + pd->file_ofs.push_back(td); + pd->f->store_64(0); //ofs + pd->f->store_64(0); //size + { + MD5_CTX ctx; + MD5Init(&ctx); + MD5Update(&ctx,(unsigned char*)p_data.ptr(),p_data.size()); + MD5Final(&ctx); + pd->f->store_buffer(ctx.digest,16); + } + pd->ep->step(TTR("Storing File:")+" "+p_path,2+p_file*100/p_total,false); + pd->count++; + pd->ftmp->store_buffer(p_data.ptr(),p_data.size()); + if (pd->alignment > 1) { + + int pad = _get_pad(pd->alignment, pd->ftmp->get_pos()); + for (int i=0; i<pad; i++) { + + pd->ftmp->store_8(0); + }; + }; + return OK; + +} + +Error EditorExportPlatform::save_zip_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total) { + + + String path=p_path.replace_first("res://",""); + + ZipData *zd = (ZipData*)p_userdata; + + zipFile zip=(zipFile)zd->zip; + + zipOpenNewFileInZip(zip, + path.utf8().get_data(), + NULL, + NULL, + 0, + NULL, + 0, + NULL, + Z_DEFLATED, + Z_DEFAULT_COMPRESSION); + + zipWriteInFileInZip(zip,p_data.ptr(),p_data.size()); + zipCloseFileInZip(zip); + + zd->ep->step(TTR("Storing File:")+" "+p_path,2+p_file*100/p_total,false); + zd->count++; + return OK; + +} + +Error EditorExportPlatform::save_zip(const String& p_path, bool p_make_bundles) { + + EditorProgress ep("savezip",TTR("Packing"),102); + + //FileAccess *tmp = FileAccess::open(tmppath,FileAccess::WRITE); + + FileAccess *src_f; + zlib_filefunc_def io = zipio_create_io_from_file(&src_f); + zipFile zip=zipOpen2(p_path.utf8().get_data(),APPEND_STATUS_CREATE,NULL,&io); + + ZipData zd; + zd.count=0; + zd.ep=&ep; + zd.zip=zip; + + + Error err = export_project_files(save_zip_file,&zd,p_make_bundles); + + zipClose(zip,NULL); + + return err; +} + +Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles, int p_alignment) { + + EditorProgress ep("savepack",TTR("Packing"),102); + + String tmppath = EditorSettings::get_singleton()->get_settings_path()+"/tmp/packtmp"; + FileAccess *tmp = FileAccess::open(tmppath,FileAccess::WRITE); + uint64_t ofs_begin = dst->get_pos(); + + dst->store_32(0x43504447); //GDPK + dst->store_32(0); //pack version + dst->store_32(VERSION_MAJOR); + dst->store_32(VERSION_MINOR); + dst->store_32(0); //hmph + for(int i=0;i<16;i++) { + //reserved + dst->store_32(0); + } + + size_t fcountpos = dst->get_pos(); + dst->store_32(0); + + PackData pd; + pd.ep=&ep; + pd.f=dst; + pd.ftmp=tmp; + pd.count=0; + pd.alignment = p_alignment; + Error err = export_project_files(save_pack_file,&pd,p_make_bundles); + memdelete(tmp); + if (err) + return err; + + if (p_alignment > 1) { + int pad = _get_pad(p_alignment, dst->get_pos()); + for (int i=0; i<pad; i++) { + + dst->store_8(0); + }; + }; + + size_t ofsplus = dst->get_pos(); + //append file + + tmp = FileAccess::open(tmppath,FileAccess::READ); + + ERR_FAIL_COND_V(!tmp,ERR_CANT_OPEN;) + const int bufsize=16384; + uint8_t buf[bufsize]; + + while(true) { + + int got = tmp->get_buffer(buf,bufsize); + if (got<=0) + break; + dst->store_buffer(buf,got); + } + + memdelete(tmp); + + dst->store_64(dst->get_pos()-ofs_begin); + dst->store_32(0x43504447); //GDPK + + //fix offsets + + dst->seek(fcountpos); + dst->store_32(pd.count); + for(int i=0;i<pd.file_ofs.size();i++) { + + dst->seek(pd.file_ofs[i].pos); + dst->store_64(pd.file_ofs[i].ofs+ofsplus); + dst->store_64(pd.file_ofs[i].size); + } + + return OK; +} + +EditorExportPlatform::EditorExportPlatform() { + + debugging_enabled = true; +} + +Error EditorExportPlatformPC::export_project(const String& p_path, bool p_debug, int p_flags) { + + + + EditorProgress ep("export",vformat(TTR("Exporting for %s"),get_name()),102); + + const int BUFSIZE = 32768; + + + + ep.step(TTR("Setting Up.."),0); + + String exe_path=""; + + if (p_debug) + exe_path=custom_debug_binary; + else + exe_path=custom_release_binary; + + if (exe_path=="") { + String fname; + if (use64) { + if (p_debug) + fname=debug_binary64; + else + fname=release_binary64; + } else { + if (p_debug) + fname=debug_binary32; + else + fname=release_binary32; + } + String err=""; + exe_path=find_export_template(fname,&err); + if (exe_path=="") { + EditorNode::add_io_error(err); + return ERR_FILE_CANT_READ; + } + } + + FileAccess *src_exe=FileAccess::open(exe_path,FileAccess::READ); + if (!src_exe) { + + EditorNode::add_io_error("Couldn't read source executable at:\n "+exe_path); + return ERR_FILE_CANT_READ; + } + + FileAccess *dst=FileAccess::open(p_path,FileAccess::WRITE); + if (!dst) { + + EditorNode::add_io_error("Can't copy executable file to:\n "+p_path); + return ERR_FILE_CANT_WRITE; + } + + uint8_t buff[32768]; + + while(true) { + + int c = src_exe->get_buffer(buff,BUFSIZE); + if (c>0) { + + dst->store_buffer(buff,c); + } else { + break; + } + } + + String dstfile = p_path.replace_first("res://","").replace("\\","/"); + if (export_mode!=EXPORT_EXE) { + + String dstfile_extension=export_mode==EXPORT_ZIP?".zip":".pck"; + if (dstfile.find("/")!=-1) + dstfile=dstfile.get_base_dir()+"/data"+dstfile_extension; + else + dstfile="data"+dstfile_extension; + if (export_mode==EXPORT_PACK) { + + memdelete(dst); + + dst=FileAccess::open(dstfile,FileAccess::WRITE); + if (!dst) { + + EditorNode::add_io_error("Can't write data pack to:\n "+p_path); + return ERR_FILE_CANT_WRITE; + } + } + } + + + + memdelete(src_exe); + + Error err = export_mode==EXPORT_ZIP?save_zip(dstfile,bundle):save_pack(dst,bundle); + memdelete(dst); + return err; +} + +void EditorExportPlatformPC::set_binary_extension(const String& p_extension) { + + binary_extension=p_extension; +} + +bool EditorExportPlatformPC::can_export(String *r_error) const { + + String err; + bool valid=true; + + if (use64 && (!exists_export_template(debug_binary64) || !exists_export_template(release_binary64))) { + valid=false; + err="No 64 bits export templates found.\nDownload and install export templates.\n"; + } + + if (!use64 && (!exists_export_template(debug_binary32) || !exists_export_template(release_binary32))) { + valid=false; + err="No 32 bits export templates found.\nDownload and install export templates.\n"; + } + + if(custom_debug_binary=="" && custom_release_binary=="") { + if (r_error) *r_error=err; + return valid; + } + + bool dvalid = true; + bool rvalid = true; + + if(!FileAccess::exists(custom_debug_binary)) { + dvalid = false; + err = "Custom debug binary not found.\n"; + } + + if(!FileAccess::exists(custom_release_binary)) { + rvalid = false; + err = "Custom release binary not found.\n"; + } + + if (dvalid || rvalid) + valid = true; + else + valid = false; + + if (r_error) + *r_error=err; + return valid; +} + + +EditorExportPlatformPC::EditorExportPlatformPC() { + + export_mode=EXPORT_PACK; + use64=true; +} + + + + + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// + + +EditorImportExport* EditorImportExport::singleton=NULL; + +void EditorImportExport::add_import_plugin(const Ref<EditorImportPlugin>& p_plugin) { + + // Need to make sure the name is unique if we are going to lookup by it + ERR_FAIL_COND(by_idx.has(p_plugin->get_name())); + + by_idx[ p_plugin->get_name() ]=plugins.size(); + plugins.push_back(p_plugin); +} + +void EditorImportExport::remove_import_plugin(const Ref<EditorImportPlugin>& p_plugin) { + + String plugin_name = p_plugin->get_name(); + + // Keep the indices the same + // Find the index of the target plugin + ERR_FAIL_COND(!by_idx.has(plugin_name)); + int idx = by_idx[plugin_name]; + int last_idx = plugins.size() - 1; + + // Swap the last plugin and the target one + SWAP(plugins[idx], plugins[last_idx]); + + // Update the index of the old last one + by_idx[plugins[idx]->get_name()] = idx; + + // Remove the target plugin's by_idx entry + by_idx.erase(plugin_name); + + // Erase the plugin + plugins.remove(last_idx); +} + +int EditorImportExport::get_import_plugin_count() const{ + + return plugins.size(); +} +Ref<EditorImportPlugin> EditorImportExport::get_import_plugin(int p_idx) const{ + + ERR_FAIL_INDEX_V(p_idx,plugins.size(),Ref<EditorImportPlugin>()); + return plugins[p_idx]; + +} + + + +Ref<EditorImportPlugin> EditorImportExport::get_import_plugin_by_name(const String& p_string) const{ + + ERR_FAIL_COND_V( !by_idx.has(p_string), Ref<EditorImportPlugin>()); + return plugins[ by_idx[p_string] ]; +} + +void EditorImportExport::add_export_plugin(const Ref<EditorExportPlugin>& p_plugin) { + + ERR_FAIL_COND( p_plugin.is_null() ); + + export_plugins.push_back(p_plugin); +} + +void EditorImportExport::remove_export_plugin(const Ref<EditorExportPlugin>& p_plugin) { + + ERR_FAIL_COND( p_plugin.is_null() ); + export_plugins.erase(p_plugin); +} + +int EditorImportExport::get_export_plugin_count() const{ + + return export_plugins.size(); +} +Ref<EditorExportPlugin> EditorImportExport::get_export_plugin(int p_idx) const{ + + ERR_FAIL_INDEX_V(p_idx,export_plugins.size(),Ref<EditorExportPlugin>()); + return export_plugins[p_idx]; +} + +void EditorImportExport::set_export_file_action(const StringName& p_file, FileAction p_action) { + + if (p_action==ACTION_NONE) { + + files.erase(p_file); + } else { + + files[p_file]=p_action; + } + +} + +EditorImportExport::FileAction EditorImportExport::get_export_file_action(const StringName& p_file) const{ + + + if (files.has(p_file)) + return files[p_file]; + + + return ACTION_NONE; +} + +void EditorImportExport::get_export_file_list(List<StringName> *p_files){ + + + for (Map<StringName,FileAction>::Element *E=files.front();E;E=E->next()) { + + p_files->push_back(E->key()); + } + +} + +void EditorImportExport::add_export_platform(const Ref<EditorExportPlatform>& p_export) { + + exporters[p_export->get_name()]=p_export; +} + + +void EditorImportExport::get_export_platforms(List<StringName> *r_platforms) { + + for (Map<StringName,Ref<EditorExportPlatform> >::Element *E=exporters.front();E;E=E->next()) { + + r_platforms->push_back(E->key()); + } +} + +Ref<EditorExportPlatform> EditorImportExport::get_export_platform(const StringName& p_platform) { + + if (exporters.has(p_platform)) { + return exporters[p_platform]; + } else { + return Ref<EditorExportPlatform>(); + } +} + + +bool EditorImportExport::poll_export_platforms() { + + bool changed=false; + for (Map<StringName,Ref<EditorExportPlatform> >::Element *E=exporters.front();E;E=E->next()) { + + if (E->get()->poll_devices()) + changed=true; + } + + return changed; + +} + +void EditorImportExport::set_export_filter(ExportFilter p_enable) { + + export_filter=p_enable; +} + +EditorImportExport::ExportFilter EditorImportExport::get_export_filter() const{ + + return export_filter; +} + +void EditorImportExport::set_export_custom_filter(const String& p_custom_filter){ + export_custom_filter=p_custom_filter; +} +void EditorImportExport::set_export_custom_filter_exclude(const String& p_custom_filter){ + export_custom_filter_exclude=p_custom_filter; +} +String EditorImportExport::get_export_custom_filter() const{ + return export_custom_filter; +} +String EditorImportExport::get_export_custom_filter_exclude() const{ + return export_custom_filter_exclude; +} + +void EditorImportExport::set_export_image_action(ImageAction p_action) { + + image_action=p_action; +} + +EditorImportExport::ImageAction EditorImportExport::get_export_image_action() const{ + + return image_action; +} + +void EditorImportExport::set_export_image_shrink(float p_shrink) { + + image_shrink=p_shrink; +} + +float EditorImportExport::get_export_image_shrink() const{ + + return image_shrink; +} + + +void EditorImportExport::set_export_image_quality(float p_quality){ + + image_action_compress_quality=p_quality; +} + +float EditorImportExport::get_export_image_quality() const{ + + return image_action_compress_quality; +} + +void EditorImportExport::image_export_group_create(const StringName& p_name) { + + ERR_FAIL_COND(image_groups.has(p_name)); + ImageGroup ig; + ig.action=IMAGE_ACTION_NONE; //default + ig.make_atlas=false; + ig.shrink=1; + ig.lossy_quality=0.7; + image_groups[p_name]=ig; + + +} + + +bool EditorImportExport::image_export_has_group(const StringName& p_name) const { + + return image_groups.has(p_name); +} +void EditorImportExport::image_export_get_groups(List<StringName> *r_name) const { + + for (Map<StringName,ImageGroup>::Element *E=image_groups.front();E;E=E->next()) { + + r_name->push_back(E->key()); + } +} + +void EditorImportExport::image_export_group_remove(const StringName& p_name){ + + ERR_FAIL_COND(!image_groups.has(p_name)); + image_groups.erase(p_name); +} +void EditorImportExport::image_export_group_set_image_action(const StringName& p_export_group,ImageAction p_action){ + + ERR_FAIL_COND(!image_groups.has(p_export_group)); + image_groups[p_export_group].action=p_action; + +} +EditorImportExport::ImageAction EditorImportExport::image_export_group_get_image_action(const StringName& p_export_group) const{ + + ERR_FAIL_COND_V(!image_groups.has(p_export_group),IMAGE_ACTION_NONE); + return image_groups[p_export_group].action; + +} +void EditorImportExport::image_export_group_set_make_atlas(const StringName& p_export_group,bool p_make){ + + ERR_FAIL_COND(!image_groups.has(p_export_group)); + image_groups[p_export_group].make_atlas=p_make; + +} +bool EditorImportExport::image_export_group_get_make_atlas(const StringName& p_export_group) const{ + + ERR_FAIL_COND_V(!image_groups.has(p_export_group),false); + return image_groups[p_export_group].make_atlas; + +} +void EditorImportExport::image_export_group_set_shrink(const StringName& p_export_group,float p_amount){ + ERR_FAIL_COND(!image_groups.has(p_export_group)); + image_groups[p_export_group].shrink=p_amount; + +} +float EditorImportExport::image_export_group_get_shrink(const StringName& p_export_group) const{ + + ERR_FAIL_COND_V(!image_groups.has(p_export_group),1); + return image_groups[p_export_group].shrink; + +} + +void EditorImportExport::image_export_group_set_lossy_quality(const StringName& p_export_group,float p_amount){ + ERR_FAIL_COND(!image_groups.has(p_export_group)); + image_groups[p_export_group].lossy_quality=p_amount; + +} +float EditorImportExport::image_export_group_get_lossy_quality(const StringName& p_export_group) const{ + + ERR_FAIL_COND_V(!image_groups.has(p_export_group),1); + return image_groups[p_export_group].lossy_quality; + +} + +StringName EditorImportExport::image_get_export_group(const StringName& p_image) const { + + if (image_group_files.has(p_image)) + return image_group_files[p_image]; + else + return StringName(); + +} + +void EditorImportExport::image_add_to_export_group(const StringName& p_image,const StringName& p_export_group) { + + + bool emptygroup = String(p_export_group)==String(); + ERR_FAIL_COND(!emptygroup && !image_groups.has(p_export_group)); + + if (emptygroup) + image_group_files.erase(p_image); + else + image_group_files[p_image]=p_export_group; +} + +void EditorImportExport::image_export_get_images_in_group(const StringName& p_group,List<StringName> *r_images) const { + + for (Map<StringName,StringName>::Element *E=image_group_files.front();E;E=E->next()) { + + if (p_group==E->get()) + r_images->push_back(E->key()); + } +} + +void EditorImportExport::set_convert_text_scenes(bool p_convert) { + + convert_text_scenes=p_convert; +} + +bool EditorImportExport::get_convert_text_scenes() const{ + + return convert_text_scenes; +} + + +void EditorImportExport::load_config() { + + Ref<ConfigFile> cf = memnew( ConfigFile ); + + Error err = cf->load("res://export.cfg"); + if (err!=OK) + return; //no export config to be loaded! + + + export_custom_filter=cf->get_value("export_filter","filter"); + export_custom_filter_exclude=cf->get_value("export_filter","filter_exclude"); + String t=cf->get_value("export_filter","type"); + if (t=="selected") + export_filter=EXPORT_SELECTED; + else if (t=="resources") + export_filter=EXPORT_RESOURCES; + else if (t=="all") + export_filter=EXPORT_ALL; + + if (cf->has_section("convert_images")) { + + String ci = "convert_images"; + String action = cf->get_value(ci,"action"); + if (action=="none") + image_action=IMAGE_ACTION_NONE; + else if (action=="compress_ram") + image_action=IMAGE_ACTION_COMPRESS_RAM; + else if (action=="compress_disk") + image_action=IMAGE_ACTION_COMPRESS_DISK; + + image_action_compress_quality = cf->get_value(ci,"compress_quality"); + if (cf->has_section_key(ci,"shrink")) + image_shrink = cf->get_value(ci,"shrink"); + else + image_shrink=1; + String formats=cf->get_value(ci,"formats"); + Vector<String> f = formats.split(","); + image_formats.clear(); + for(int i=0;i<f.size();i++) { + image_formats.insert(f[i].strip_edges()); + } + } + + if (cf->has_section("convert_scenes")) { + + convert_text_scenes = cf->get_value("convert_scenes","convert_text_scenes"); + } + + + if (cf->has_section("export_filter_files")) { + + + String eff = "export_filter_files"; + List<String> k; + cf->get_section_keys(eff,&k); + for(List<String>::Element *E=k.front();E;E=E->next()) { + + String val = cf->get_value(eff,E->get()); + if (val=="copy") { + files[E->get()]=ACTION_COPY; + } else if (val=="bundle") { + files[E->get()]=ACTION_BUNDLE; + } + } + } + + List<String> sect; + + cf->get_sections(§); + + for(List<String>::Element *E=sect.front();E;E=E->next()) { + + String s = E->get(); + if (!s.begins_with("platform:")) + continue; + String p = s.substr(s.find(":")+1,s.length()); + + if (!exporters.has(p)) + continue; + + Ref<EditorExportPlatform> ep = exporters[p]; + if (!ep.is_valid()) { + continue; + } + List<String> keys; + cf->get_section_keys(s,&keys); + for(List<String>::Element *F=keys.front();F;F=F->next()) { + ep->set(F->get(),cf->get_value(s,F->get())); + } + } + + //save image groups + + if (cf->has_section("image_groups")) { + + sect.clear(); + cf->get_section_keys("image_groups",§); + for(List<String>::Element *E=sect.front();E;E=E->next()) { + + Dictionary d = cf->get_value("image_groups",E->get()); + ImageGroup g; + g.action=IMAGE_ACTION_NONE; + g.make_atlas=false; + g.lossy_quality=0.7; + g.shrink=1; + + if (d.has("action")) { + String action=d["action"]; + if (action=="compress_ram") + g.action=IMAGE_ACTION_COMPRESS_RAM; + else if (action=="compress_disk") + g.action=IMAGE_ACTION_COMPRESS_DISK; + else if (action=="keep") + g.action=IMAGE_ACTION_KEEP; + } + + if (d.has("atlas")) + g.make_atlas=d["atlas"]; + if (d.has("lossy_quality")) + g.lossy_quality=d["lossy_quality"]; + if (d.has("shrink")) { + + g.shrink=d["shrink"]; + g.shrink=CLAMP(g.shrink,1,8); + } + + image_groups[E->get()]=g; + + } + + if (cf->has_section_key("image_group_files","files")) { + + Vector<String> sa=cf->get_value("image_group_files","files"); + if (sa.size()%2==0) { + for(int i=0;i<sa.size();i+=2) { + image_group_files[sa[i]]=sa[i+1]; + } + } + } + + } + + + if (cf->has_section("script")) { + + if (cf->has_section_key("script","action")) { + + String action = cf->get_value("script","action"); + if (action=="compile") + script_action=SCRIPT_ACTION_COMPILE; + else if (action=="encrypt") + script_action=SCRIPT_ACTION_ENCRYPT; + else + script_action=SCRIPT_ACTION_NONE; + + } + + if (cf->has_section_key("script","encrypt_key")) { + + script_key = cf->get_value("script","encrypt_key"); + } + } + + if (cf->has_section("convert_samples")) { + + if (cf->has_section_key("convert_samples","action")) { + String action = cf->get_value("convert_samples","action"); + if (action=="none") { + sample_action=SAMPLE_ACTION_NONE; + } else if (action=="compress_ram") { + sample_action=SAMPLE_ACTION_COMPRESS_RAM; + } + } + + if (cf->has_section_key("convert_samples","max_hz")) + sample_action_max_hz=cf->get_value("convert_samples","max_hz"); + + if (cf->has_section_key("convert_samples","trim")) + sample_action_trim=cf->get_value("convert_samples","trim"); + } + + + +} + + + + + +void EditorImportExport::save_config() { + + Ref<ConfigFile> cf = memnew( ConfigFile ); + + switch(export_filter) { + case EXPORT_SELECTED: cf->set_value("export_filter","type","selected"); break; + case EXPORT_RESOURCES: cf->set_value("export_filter","type","resources"); break; + case EXPORT_ALL: cf->set_value("export_filter","type","all"); break; + } + + cf->set_value("export_filter","filter",export_custom_filter); + cf->set_value("export_filter", "filter_exclude",export_custom_filter_exclude); + + String file_action_section = "export_filter_files"; + + for (Map<StringName,FileAction>::Element *E=files.front();E;E=E->next()) { + + String f=E->key(); + String a; + switch (E->get()) { + case ACTION_NONE: {} + case ACTION_COPY: a="copy"; break; + case ACTION_BUNDLE: a="bundle"; break; + } + + cf->set_value(file_action_section,f,a); + } + + + for (Map<StringName,Ref<EditorExportPlatform> >::Element *E=exporters.front();E;E=E->next()) { + + String pname = "platform:"+String(E->key()); + + Ref<EditorExportPlatform> ep = E->get(); + + List<PropertyInfo> pl; + ep->get_property_list(&pl); + + for (List<PropertyInfo>::Element *F=pl.front();F;F=F->next()) { + + cf->set_value(pname,F->get().name,ep->get(F->get().name)); + } + + } + + switch(image_action) { + case IMAGE_ACTION_NONE: cf->set_value("convert_images","action","none"); break; + case IMAGE_ACTION_COMPRESS_RAM: cf->set_value("convert_images","action","compress_ram"); break; + case IMAGE_ACTION_COMPRESS_DISK: cf->set_value("convert_images","action","compress_disk"); break; + } + + cf->set_value("convert_images","shrink",image_shrink); + cf->set_value("convert_images","compress_quality",image_action_compress_quality); + + String formats; + for(Set<String>::Element *E=image_formats.front();E;E=E->next()) { + + if (E!=image_formats.front()) + formats+=","; + formats+=E->get(); + } + + cf->set_value("convert_images","formats",formats); + + //save image groups + + for(Map<StringName,ImageGroup>::Element *E=image_groups.front();E;E=E->next()) { + + Dictionary d; + switch(E->get().action) { + case IMAGE_ACTION_NONE: d["action"]="default"; break; + case IMAGE_ACTION_COMPRESS_RAM: d["action"]="compress_ram"; break; + case IMAGE_ACTION_COMPRESS_DISK: d["action"]="compress_disk"; break; + case IMAGE_ACTION_KEEP: d["action"]="keep"; break; + } + + + d["atlas"]=E->get().make_atlas; + d["shrink"]=E->get().shrink; + d["lossy_quality"]=E->get().lossy_quality; + cf->set_value("image_groups",E->key(),d); + + } + + if (image_groups.size() && image_group_files.size()){ + + Vector<String> igfkeys; + igfkeys.resize(image_group_files.size()); + int idx=0; + for (Map<StringName,StringName>::Element *E=image_group_files.front();E;E=E->next()) { + igfkeys[idx++]=E->key(); + } + igfkeys.sort(); + + Vector<String> igfsave; + igfsave.resize(image_group_files.size()*2); + idx=0; + for (int i=0;i<igfkeys.size();++i) { + + igfsave[idx++]=igfkeys[i]; + igfsave[idx++]=image_group_files[igfkeys[i]]; + } + cf->set_value("image_group_files","files",igfsave); + } + + switch(script_action) { + case SCRIPT_ACTION_NONE: cf->set_value("script","action","none"); break; + case SCRIPT_ACTION_COMPILE: cf->set_value("script","action","compile"); break; + case SCRIPT_ACTION_ENCRYPT: cf->set_value("script","action","encrypt"); break; + } + + cf->set_value("convert_scenes","convert_text_scenes",convert_text_scenes); + + cf->set_value("script","encrypt_key",script_key); + + switch(sample_action) { + case SAMPLE_ACTION_NONE: cf->set_value("convert_samples","action","none"); break; + case SAMPLE_ACTION_COMPRESS_RAM: cf->set_value("convert_samples","action","compress_ram"); break; + } + + cf->set_value("convert_samples","max_hz",sample_action_max_hz); + cf->set_value("convert_samples","trim",sample_action_trim); + + cf->save("res://export.cfg"); + +} + + +void EditorImportExport::script_set_action(ScriptAction p_action) { + + script_action=p_action; +} + +EditorImportExport::ScriptAction EditorImportExport::script_get_action() const{ + + return script_action; +} + +void EditorImportExport::script_set_encryption_key(const String& p_key){ + + script_key=p_key; +} +String EditorImportExport::script_get_encryption_key() const{ + + return script_key; +} + + +void EditorImportExport::sample_set_action(SampleAction p_action) { + + sample_action=p_action; +} + +EditorImportExport::SampleAction EditorImportExport::sample_get_action() const{ + + return sample_action; +} + +void EditorImportExport::sample_set_max_hz(int p_hz){ + + sample_action_max_hz=p_hz; +} +int EditorImportExport::sample_get_max_hz() const{ + + return sample_action_max_hz; +} + +void EditorImportExport::sample_set_trim(bool p_trim){ + + sample_action_trim=p_trim; +} +bool EditorImportExport::sample_get_trim() const{ + + return sample_action_trim; +} + +PoolVector<String> EditorImportExport::_get_export_file_list() { + + PoolVector<String> fl; + for (Map<StringName,FileAction>::Element *E=files.front();E;E=E->next()) { + + fl.push_back(E->key()); + } + + return fl; +} + +PoolVector<String> EditorImportExport::_get_export_platforms() { + + PoolVector<String> ep; + for (Map<StringName,Ref<EditorExportPlatform> >::Element *E=exporters.front();E;E=E->next()) { + + ep.push_back(E->key()); + } + + return ep; + +} + +void EditorImportExport::_bind_methods() { + + ClassDB::bind_method(D_METHOD("add_import_plugin","plugin:EditorImportPlugin"),&EditorImportExport::add_import_plugin); + ClassDB::bind_method(D_METHOD("remove_import_plugin","plugin:EditorImportPlugin"),&EditorImportExport::remove_import_plugin); + ClassDB::bind_method(D_METHOD("get_import_plugin_count"),&EditorImportExport::get_import_plugin_count); + ClassDB::bind_method(D_METHOD("get_import_plugin:EditorImportPlugin","idx"),&EditorImportExport::get_import_plugin); + ClassDB::bind_method(D_METHOD("get_import_plugin_by_name:EditorImportPlugin","name"),&EditorImportExport::get_import_plugin_by_name); + + ClassDB::bind_method(D_METHOD("add_export_plugin","plugin:EditorExportPlugin"),&EditorImportExport::add_export_plugin); + ClassDB::bind_method(D_METHOD("remove_export_plugin","plugin:EditorExportPlugin"),&EditorImportExport::remove_export_plugin); + ClassDB::bind_method(D_METHOD("get_export_plugin_count"),&EditorImportExport::get_export_plugin_count); + ClassDB::bind_method(D_METHOD("get_export_plugin:EditorExportPlugin","idx"),&EditorImportExport::get_export_plugin); + + ClassDB::bind_method(D_METHOD("set_export_file_action","file","action"),&EditorImportExport::set_export_file_action); + ClassDB::bind_method(D_METHOD("get_export_file_action","file"),&EditorImportExport::get_export_file_action); + ClassDB::bind_method(D_METHOD("get_export_file_list"),&EditorImportExport::_get_export_file_list); + + ClassDB::bind_method(D_METHOD("add_export_platform","platform:EditorExportplatform"),&EditorImportExport::add_export_platform); + //ClassDB::bind_method(D_METHOD("remove_export_platform","platform:EditorExportplatform"),&EditorImportExport::add_export_platform); + ClassDB::bind_method(D_METHOD("get_export_platform:EditorExportPlatform","name"),&EditorImportExport::get_export_platform); + ClassDB::bind_method(D_METHOD("get_export_platforms"),&EditorImportExport::_get_export_platforms); + + ClassDB::bind_method(D_METHOD("set_export_filter","filter"),&EditorImportExport::set_export_filter); + ClassDB::bind_method(D_METHOD("get_export_filter"),&EditorImportExport::get_export_filter); + + ClassDB::bind_method(D_METHOD("set_export_custom_filter","filter"),&EditorImportExport::set_export_custom_filter); + ClassDB::bind_method(D_METHOD("get_export_custom_filter"),&EditorImportExport::get_export_custom_filter); + + ClassDB::bind_method(D_METHOD("set_export_custom_filter_exclude","filter_exclude"),&EditorImportExport::set_export_custom_filter_exclude); + ClassDB::bind_method(D_METHOD("get_export_custom_filter_exclude"),&EditorImportExport::get_export_custom_filter_exclude); + + + ClassDB::bind_method(D_METHOD("image_export_group_create"),&EditorImportExport::image_export_group_create); + ClassDB::bind_method(D_METHOD("image_export_group_remove"),&EditorImportExport::image_export_group_remove); + ClassDB::bind_method(D_METHOD("image_export_group_set_image_action"),&EditorImportExport::image_export_group_set_image_action); + ClassDB::bind_method(D_METHOD("image_export_group_set_make_atlas"),&EditorImportExport::image_export_group_set_make_atlas); + ClassDB::bind_method(D_METHOD("image_export_group_set_shrink"),&EditorImportExport::image_export_group_set_shrink); + ClassDB::bind_method(D_METHOD("image_export_group_get_image_action"),&EditorImportExport::image_export_group_get_image_action); + ClassDB::bind_method(D_METHOD("image_export_group_get_make_atlas"),&EditorImportExport::image_export_group_get_make_atlas); + ClassDB::bind_method(D_METHOD("image_export_group_get_shrink"),&EditorImportExport::image_export_group_get_shrink); + ClassDB::bind_method(D_METHOD("image_add_to_export_group"),&EditorImportExport::image_add_to_export_group); + ClassDB::bind_method(D_METHOD("script_set_action"),&EditorImportExport::script_set_action); + ClassDB::bind_method(D_METHOD("script_set_encryption_key"),&EditorImportExport::script_set_encryption_key); + ClassDB::bind_method(D_METHOD("script_get_action"),&EditorImportExport::script_get_action); + ClassDB::bind_method(D_METHOD("script_get_encryption_key"),&EditorImportExport::script_get_encryption_key); + + + + BIND_CONSTANT( ACTION_NONE ); + BIND_CONSTANT( ACTION_COPY ); + BIND_CONSTANT( ACTION_BUNDLE ); + + BIND_CONSTANT( EXPORT_SELECTED ); + BIND_CONSTANT( EXPORT_RESOURCES ); + BIND_CONSTANT( EXPORT_ALL ); + + BIND_CONSTANT( IMAGE_ACTION_NONE ); + BIND_CONSTANT( IMAGE_ACTION_COMPRESS_DISK ); + BIND_CONSTANT( IMAGE_ACTION_COMPRESS_RAM ); + BIND_CONSTANT( IMAGE_ACTION_KEEP ); + + BIND_CONSTANT( SCRIPT_ACTION_NONE ); + BIND_CONSTANT( SCRIPT_ACTION_COMPILE ); + BIND_CONSTANT( SCRIPT_ACTION_ENCRYPT ); +}; + + + +EditorImportExport::EditorImportExport() { + + export_filter=EXPORT_RESOURCES; + singleton=this; + image_action=IMAGE_ACTION_NONE; + image_action_compress_quality=0.7; + image_formats.insert("png"); + image_shrink=1; + + + script_action=SCRIPT_ACTION_COMPILE; + + sample_action=SAMPLE_ACTION_NONE; + sample_action_max_hz=44100; + sample_action_trim=false; + + convert_text_scenes=true; + +} + + + +EditorImportExport::~EditorImportExport() { + + + +} +#endif diff --git a/tools/editor/editor_export.h b/editor/editor_export.h index 8a9dc965e5..8a9dc965e5 100644 --- a/tools/editor/editor_export.h +++ b/editor/editor_export.h diff --git a/tools/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index bfaf1906d8..bfaf1906d8 100644 --- a/tools/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp diff --git a/tools/editor/editor_file_dialog.h b/editor/editor_file_dialog.h index 193cbc513c..193cbc513c 100644 --- a/tools/editor/editor_file_dialog.h +++ b/editor/editor_file_dialog.h diff --git a/tools/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index cd151cd90b..cd151cd90b 100644 --- a/tools/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp diff --git a/tools/editor/editor_file_system.h b/editor/editor_file_system.h index 10d9b919fc..10d9b919fc 100644 --- a/tools/editor/editor_file_system.h +++ b/editor/editor_file_system.h diff --git a/tools/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index 3652a59978..3652a59978 100644 --- a/tools/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp diff --git a/tools/editor/editor_fonts.h b/editor/editor_fonts.h index 0e8ce20609..0e8ce20609 100644 --- a/tools/editor/editor_fonts.h +++ b/editor/editor_fonts.h diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp new file mode 100644 index 0000000000..7ef7658132 --- /dev/null +++ b/editor/editor_help.cpp @@ -0,0 +1,1929 @@ +/*************************************************************************/ +/* editor_help.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 "editor_help.h" + +#include "editor_node.h" +#include "editor_settings.h" +#include "os/keyboard.h" +#include "doc_data_compressed.h" +#include "editor/plugins/script_editor_plugin.h" + +void EditorHelpSearch::popup() { + popup_centered_ratio(0.6); + if (search_box->get_text()!="") { + search_box->select_all(); + _update_search(); + } + search_box->grab_focus(); +} + +void EditorHelpSearch::popup(const String& p_term) { + + popup_centered_ratio(0.6); + if (p_term!="") { + search_box->set_text(p_term); + search_box->select_all(); + _update_search(); + } else + search_box->clear(); + search_box->grab_focus(); +} + + +void EditorHelpSearch::_text_changed(const String& p_newtext) { + + _update_search(); +} + +void EditorHelpSearch::_sbox_input(const InputEvent& p_ie) { + + if (p_ie.type==InputEvent::KEY && ( + p_ie.key.scancode == KEY_UP || + p_ie.key.scancode == KEY_DOWN || + p_ie.key.scancode == KEY_PAGEUP || + p_ie.key.scancode == KEY_PAGEDOWN ) ) { + + search_options->call("_gui_input",p_ie); + search_box->accept_event(); + } + +} + +void EditorHelpSearch::_update_search() { + + search_options->clear(); + search_options->set_hide_root(true); + + /* + TreeItem *root = search_options->create_item(); + _parse_fs(EditorFileSystem::get_singleton()->get_filesystem()); +*/ + + List<StringName> type_list; + ClassDB::get_class_list(&type_list); + + DocData *doc=EditorHelp::get_doc_data(); + String term = search_box->get_text(); + if (term.length()<2) + return; + + TreeItem *root = search_options->create_item(); + + + + Ref<Texture> def_icon = get_icon("Node","EditorIcons"); + //classes first + for (Map<String,DocData::ClassDoc>::Element *E=doc->class_list.front();E;E=E->next()) { + + if (E->key().findn(term)!=-1) { + + TreeItem *item = search_options->create_item(root); + item->set_metadata(0,"class_name:"+E->key()); + item->set_text(0,E->key()+" (Class)"); + if (has_icon(E->key(),"EditorIcons")) + item->set_icon(0,get_icon(E->key(),"EditorIcons")); + else + item->set_icon(0,def_icon); + + + } + + } + + //class methods, etc second + for (Map<String,DocData::ClassDoc>::Element *E=doc->class_list.front();E;E=E->next()) { + + + DocData::ClassDoc & c = E->get(); + + Ref<Texture> cicon; + if (has_icon(E->key(),"EditorIcons")) + cicon=get_icon(E->key(),"EditorIcons"); + else + cicon=def_icon; + + + for(int i=0;i<c.methods.size();i++) { + if( (term.begins_with(".") && c.methods[i].name.begins_with(term.right(1))) + || (term.ends_with("(") && c.methods[i].name.ends_with(term.left(term.length()-1).strip_edges())) + || (term.begins_with(".") && term.ends_with("(") && c.methods[i].name==term.substr(1,term.length()-2).strip_edges()) + || c.methods[i].name.findn(term)!=-1) { + + TreeItem *item = search_options->create_item(root); + item->set_metadata(0,"class_method:"+E->key()+":"+c.methods[i].name); + item->set_text(0,E->key()+"."+c.methods[i].name+" (Method)"); + item->set_icon(0,cicon); + } + } + + for(int i=0;i<c.signals.size();i++) { + + if (c.signals[i].name.findn(term)!=-1) { + + TreeItem *item = search_options->create_item(root); + item->set_metadata(0,"class_signal:"+E->key()+":"+c.signals[i].name); + item->set_text(0,E->key()+"."+c.signals[i].name+" (Signal)"); + item->set_icon(0,cicon); + } + } + + for(int i=0;i<c.constants.size();i++) { + + if (c.constants[i].name.findn(term)!=-1) { + + TreeItem *item = search_options->create_item(root); + item->set_metadata(0,"class_constant:"+E->key()+":"+c.constants[i].name); + item->set_text(0,E->key()+"."+c.constants[i].name+" (Constant)"); + item->set_icon(0,cicon); + } + } + + for(int i=0;i<c.properties.size();i++) { + + if (c.properties[i].name.findn(term)!=-1) { + + TreeItem *item = search_options->create_item(root); + item->set_metadata(0,"class_property:"+E->key()+":"+c.properties[i].name); + item->set_text(0,E->key()+"."+c.properties[i].name+" (Property)"); + item->set_icon(0,cicon); + } + } + + for(int i=0;i<c.theme_properties.size();i++) { + + if (c.theme_properties[i].name.findn(term)!=-1) { + + TreeItem *item = search_options->create_item(root); + item->set_metadata(0,"class_theme_item:"+E->key()+":"+c.theme_properties[i].name); + item->set_text(0,E->key()+"."+c.theme_properties[i].name+" (Theme Item)"); + item->set_icon(0,cicon); + } + } + + + } + + //same but descriptions + + for (Map<String,DocData::ClassDoc>::Element *E=doc->class_list.front();E;E=E->next()) { + + + DocData::ClassDoc & c = E->get(); + + Ref<Texture> cicon; + if (has_icon(E->key(),"EditorIcons")) + cicon=get_icon(E->key(),"EditorIcons"); + else + cicon=def_icon; + + if (c.description.findn(term)!=-1) { + + + TreeItem *item = search_options->create_item(root); + item->set_metadata(0,"class_desc:"+E->key()); + item->set_text(0,E->key()+" (Class Description)"); + item->set_icon(0,cicon); + + } + + for(int i=0;i<c.methods.size();i++) { + + if (c.methods[i].description.findn(term)!=-1) { + + TreeItem *item = search_options->create_item(root); + item->set_metadata(0,"class_method_desc:"+E->key()+":"+c.methods[i].name); + item->set_text(0,E->key()+"."+c.methods[i].name+" (Method Description)"); + item->set_icon(0,cicon); + } + } + + for(int i=0;i<c.signals.size();i++) { + + if (c.signals[i].description.findn(term)!=-1) { + + TreeItem *item = search_options->create_item(root); + item->set_metadata(0,"class_signal:"+E->key()+":"+c.signals[i].name); + item->set_text(0,E->key()+"."+c.signals[i].name+" (Signal Description)"); + item->set_icon(0,cicon); + } + } + + for(int i=0;i<c.constants.size();i++) { + + if (c.constants[i].description.findn(term)!=-1) { + + TreeItem *item = search_options->create_item(root); + item->set_metadata(0,"class_constant:"+E->key()+":"+c.constants[i].name); + item->set_text(0,E->key()+"."+c.constants[i].name+" (Constant Description)"); + item->set_icon(0,cicon); + } + } + + for(int i=0;i<c.properties.size();i++) { + + if (c.properties[i].description.findn(term)!=-1) { + + TreeItem *item = search_options->create_item(root); + item->set_metadata(0,"class_property_desc:"+E->key()+":"+c.properties[i].name); + item->set_text(0,E->key()+"."+c.properties[i].name+" (Property Description)"); + item->set_icon(0,cicon); + } + } + + } + + get_ok()->set_disabled(root->get_children()==NULL); + +} + +void EditorHelpSearch::_confirmed() { + + TreeItem *ti = search_options->get_selected(); + if (!ti) + return; + + String mdata=ti->get_metadata(0); + emit_signal("go_to_help",mdata); + editor->call("_editor_select",EditorNode::EDITOR_SCRIPT); // in case EditorHelpSearch beeen invoked on top of other editor window + // go to that + hide(); +} + +void EditorHelpSearch::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + + connect("confirmed",this,"_confirmed"); + _update_search(); + } + + if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { + + if (is_visible_in_tree()) { + + search_box->call_deferred("grab_focus"); // still not visible + search_box->select_all(); + } + } + +} + + +void EditorHelpSearch::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_text_changed"),&EditorHelpSearch::_text_changed); + ClassDB::bind_method(D_METHOD("_confirmed"),&EditorHelpSearch::_confirmed); + ClassDB::bind_method(D_METHOD("_sbox_input"),&EditorHelpSearch::_sbox_input); + ClassDB::bind_method(D_METHOD("_update_search"),&EditorHelpSearch::_update_search); + + ADD_SIGNAL(MethodInfo("go_to_help")); + +} + + +EditorHelpSearch::EditorHelpSearch() { + + editor=EditorNode::get_singleton(); + VBoxContainer *vbc = memnew( VBoxContainer ); + add_child(vbc); + + HBoxContainer *sb_hb = memnew( HBoxContainer); + search_box = memnew( LineEdit ); + sb_hb->add_child(search_box); + search_box->set_h_size_flags(SIZE_EXPAND_FILL); + Button *sb = memnew( Button(TTR("Search"))); + sb->connect("pressed",this,"_update_search"); + sb_hb->add_child(sb); + vbc->add_margin_child(TTR("Search:"),sb_hb); + search_box->connect("text_changed",this,"_text_changed"); + search_box->connect("gui_input",this,"_sbox_input"); + search_options = memnew( Tree ); + vbc->add_margin_child(TTR("Matches:"),search_options,true); + get_ok()->set_text(TTR("Open")); + get_ok()->set_disabled(true); + register_text_enter(search_box); + set_hide_on_ok(false); + search_options->connect("item_activated",this,"_confirmed"); + set_title(TTR("Search Help")); + + //search_options->set_hide_root(true); + +} + +///////////////////////////////// + +//////////////////////////////////// +/// ///////////////////////////////// + + + +void EditorHelpIndex::add_type(const String& p_type,HashMap<String,TreeItem*>& p_types,TreeItem *p_root) { + + if (p_types.has(p_type)) + return; + /* + if (!ClassDB::is_type(p_type,base) || p_type==base) + return; + */ + + String inherits=EditorHelp::get_doc_data()->class_list[p_type].inherits; + + TreeItem *parent=p_root; + + + if (inherits.length()) { + + if (!p_types.has(inherits)) { + + add_type(inherits,p_types,p_root); + } + + if (p_types.has(inherits) ) + parent=p_types[inherits]; + } + + TreeItem *item = class_list->create_item(parent); + item->set_metadata(0,p_type); + item->set_tooltip(0,EditorHelp::get_doc_data()->class_list[p_type].brief_description); + item->set_text(0,p_type); + + + if (has_icon(p_type,"EditorIcons")) { + + item->set_icon(0, get_icon(p_type,"EditorIcons")); + } + + p_types[p_type]=item; +} + + +void EditorHelpIndex::_tree_item_selected() { + + + TreeItem *s=class_list->get_selected(); + if (!s) + return; + + emit_signal("open_class",s->get_text(0)); + + hide(); + + //_goto_desc(s->get_text(0)); + +} + +void EditorHelpIndex::select_class(const String& p_class) { + + if (!tree_item_map.has(p_class)) + return; + tree_item_map[p_class]->select(0); + class_list->ensure_cursor_is_visible(); +} + +void EditorHelpIndex::popup() { + + popup_centered_ratio(0.6); + + search_box->set_text(""); + _update_class_list(); +} + +void EditorHelpIndex::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + + _update_class_list(); + + connect("confirmed",this,"_tree_item_selected"); + + } else if (p_what==NOTIFICATION_POST_POPUP) { + + search_box->call_deferred("grab_focus"); + } +} + +void EditorHelpIndex::_text_changed(const String& p_text) { + + _update_class_list(); +} + +void EditorHelpIndex::_update_class_list() { + + class_list->clear(); + tree_item_map.clear(); + TreeItem *root = class_list->create_item(); + class_list->set_hide_root(true); + + String filter = search_box->get_text().strip_edges(); + String to_select = ""; + + for(Map<String,DocData::ClassDoc>::Element *E=EditorHelp::get_doc_data()->class_list.front();E;E=E->next()) { + + if (filter == "") { + add_type(E->key(),tree_item_map,root); + } else { + + bool found = false; + String type = E->key(); + + while(type != "") { + if (filter.is_subsequence_ofi(type)) { + + if (to_select.empty()) { + to_select = type; + } + + found=true; + break; + } + + type = EditorHelp::get_doc_data()->class_list[type].inherits; + } + + if (found) { + add_type(E->key(),tree_item_map,root); + } + } + } + + if (tree_item_map.has(filter)) { + select_class(filter); + } else if (to_select != "") { + select_class(to_select); + } +} + + +void EditorHelpIndex::_sbox_input(const InputEvent& p_ie) { + + if (p_ie.type==InputEvent::KEY && ( + p_ie.key.scancode == KEY_UP || + p_ie.key.scancode == KEY_DOWN || + p_ie.key.scancode == KEY_PAGEUP || + p_ie.key.scancode == KEY_PAGEDOWN ) ) { + + class_list->call("_gui_input",p_ie); + search_box->accept_event(); + } +} + +void EditorHelpIndex::_bind_methods() { + + ClassDB::bind_method("_tree_item_selected",&EditorHelpIndex::_tree_item_selected); + ClassDB::bind_method("_text_changed",&EditorHelpIndex::_text_changed); + ClassDB::bind_method("_sbox_input",&EditorHelpIndex::_sbox_input); + ClassDB::bind_method("select_class",&EditorHelpIndex::select_class); + ADD_SIGNAL( MethodInfo("open_class")); +} + + + +EditorHelpIndex::EditorHelpIndex() { + + VBoxContainer *vbc = memnew( VBoxContainer ); + add_child(vbc); + + search_box = memnew( LineEdit ); + vbc->add_margin_child(TTR("Search:"), search_box); + search_box->set_h_size_flags(SIZE_EXPAND_FILL); + + register_text_enter(search_box); + + search_box->connect("text_changed", this, "_text_changed"); + search_box->connect("gui_input", this, "_sbox_input"); + + class_list = memnew( Tree ); + vbc->add_margin_child(TTR("Class List:")+" ", class_list, true); + class_list->set_v_size_flags(SIZE_EXPAND_FILL); + + class_list->connect("item_activated",this,"_tree_item_selected"); + + get_ok()->set_text(TTR("Open")); + set_title(TTR("Search Classes")); +} + + + +///////////////////////////////// + +//////////////////////////////////// +/// ///////////////////////////////// +DocData *EditorHelp::doc=NULL; + +void EditorHelp::_unhandled_key_input(const InputEvent& p_ev) { + + if (!is_visible_in_tree()) + return; + if ( p_ev.key.mod.control && p_ev.key.scancode==KEY_F) { + + search->grab_focus(); + search->select_all(); + } +} + +void EditorHelp::_search(const String&) { + + if (search->get_text()=="") + return; + + + String stext=search->get_text(); + bool keep = prev_search==stext; + + bool ret = class_desc->search(stext, keep); + if (!ret) { + class_desc->search(stext, false); + } + + prev_search=stext; + + +} + +#if 0 +void EditorHelp::_button_pressed(int p_idx) { + + if (p_idx==PAGE_CLASS_LIST) { + + //edited_class->set_pressed(false); + //class_list_button->set_pressed(true); + //tabs->set_current_tab(PAGE_CLASS_LIST); + + } else if (p_idx==PAGE_CLASS_DESC) { + + //edited_class->set_pressed(true); + //class_list_button->set_pressed(false); + //tabs->set_current_tab(PAGE_CLASS_DESC); + + } else if (p_idx==PAGE_CLASS_PREV) { + + if (history_pos<2) + return; + history_pos--; + ERR_FAIL_INDEX(history_pos-1,history.size()); + _goto_desc(history[history_pos-1].c,false,history[history_pos-1].scroll); + _update_history_buttons(); + + + } else if (p_idx==PAGE_CLASS_NEXT) { + + if (history_pos>=history.size()) + return; + + history_pos++; + ERR_FAIL_INDEX(history_pos-1,history.size()); + _goto_desc(history[history_pos-1].c,false,history[history_pos-1].scroll); + _update_history_buttons(); + + } else if (p_idx==PAGE_SEARCH) { + + _search(""); + } +} + + +#endif + +void EditorHelp::_class_list_select(const String& p_select) { + + _goto_desc(p_select); +} + +void EditorHelp::_class_desc_select(const String& p_select) { + + + + //print_line("LINK: "+p_select); + if (p_select.begins_with("#")) { + //_goto_desc(p_select.substr(1,p_select.length())); + emit_signal("go_to_help","class_name:"+p_select.substr(1,p_select.length())); + return; + } else if (p_select.begins_with("@")) { + + String m = p_select.substr(1,p_select.length()); + + if (m.find(".")!=-1) { + //must go somewhere else + + emit_signal("go_to_help","class_method:"+m.get_slice(".",0)+":"+m.get_slice(".",0)); + } else { + + if (!method_line.has(m)) + return; + class_desc->scroll_to_line(method_line[m]); + } + + } + + +} + +void EditorHelp::_class_desc_input(const InputEvent& p_input) { + if (p_input.type==InputEvent::MOUSE_BUTTON && p_input.mouse_button.pressed && p_input.mouse_button.button_index==1) { + class_desc->set_selection_enabled(false); + class_desc->set_selection_enabled(true); + } + set_focused(); +} + +void EditorHelp::_add_type(const String& p_type) { + + String t = p_type; + if (t=="") + t="void"; + bool can_ref = (t!="int" && t!="real" && t!="bool" && t!="void"); + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color")); + if (can_ref) + class_desc->push_meta("#"+t); //class + class_desc->add_text(t); + if (can_ref) + class_desc->pop(); + class_desc->pop(); + +} + +void EditorHelp::_scroll_changed(double p_scroll) { + + if (scroll_locked) + return; + + if (!class_desc->get_v_scroll()->is_visible()) + p_scroll=0; + + //history[p].scroll=p_scroll; +} + +Error EditorHelp::_goto_desc(const String& p_class,int p_vscr) { + + //ERR_FAIL_COND(!doc->class_list.has(p_class)); + if (!doc->class_list.has(p_class)) + return ERR_DOES_NOT_EXIST; + + + //if (tree_item_map.has(p_class)) { + select_locked = true; + //} + + class_desc->show(); + //tabs->set_current_tab(PAGE_CLASS_DESC); + description_line=0; + + if (p_class==edited_class) + return OK; //already there + + scroll_locked=true; + + class_desc->clear(); + method_line.clear(); + edited_class=p_class; + //edited_class->show(); + + + DocData::ClassDoc cd=doc->class_list[p_class]; //make a copy, so we can sort without worrying + + Color h_color; + + Ref<Font> doc_font = get_font("doc","EditorFonts"); + Ref<Font> doc_title_font = get_font("doc_title","EditorFonts"); + Ref<Font> doc_code_font = get_font("doc_source","EditorFonts"); + + + h_color=Color(1,1,1,1); + + class_desc->push_font(doc_title_font); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->add_text(TTR("Class:")+" "); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color")); + _add_text(p_class); + class_desc->pop(); + class_desc->pop(); + class_desc->pop(); + class_desc->add_newline(); + + if (cd.inherits!="") { + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->push_font(doc_title_font); + class_desc->add_text(TTR("Inherits:")+" "); + class_desc->pop(); + class_desc->pop(); + + String inherits = cd.inherits; + + class_desc->push_font(doc_font); + + while (inherits != "") { + _add_type(inherits); + + inherits = doc->class_list[inherits].inherits; + + if (inherits != "") { + class_desc->add_text(" , "); + } + } + + class_desc->pop(); + class_desc->add_newline(); + } + + if (ClassDB::class_exists(cd.name)) { + + bool found = false; + bool prev = false; + + for (Map<String,DocData::ClassDoc>::Element *E=doc->class_list.front();E;E=E->next()) { + + if (E->get().inherits == cd.name) { + + if (!found) { + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->push_font(doc_title_font); + class_desc->add_text(TTR("Inherited by:")+" "); + class_desc->pop(); + class_desc->pop(); + + found = true; + class_desc->push_font(doc_font); + } + + if (prev) { + + class_desc->add_text(" , "); + prev = false; + } + + _add_type(E->get().name); + prev = true; + } + } + + if (found) + class_desc->pop(); + + class_desc->add_newline(); + } + + class_desc->add_newline(); + + if (cd.brief_description!="") { + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->push_font(doc_title_font); + class_desc->add_text(TTR("Brief Description:")); + class_desc->pop(); + class_desc->pop(); + + //class_desc->add_newline(); + class_desc->add_newline(); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + class_desc->push_font( doc_font ); + class_desc->push_indent(1); + _add_text(cd.brief_description); + class_desc->pop(); + class_desc->pop(); + class_desc->pop(); + class_desc->add_newline(); + class_desc->add_newline(); + } + + Set<String> skip_methods; + bool property_descr=false; + + if (cd.properties.size()) { + + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->push_font(doc_title_font); + class_desc->add_text(TTR("Members:")); + class_desc->pop(); + class_desc->pop(); + //class_desc->add_newline(); + + class_desc->push_indent(1); + class_desc->push_table(2); + class_desc->set_table_column_expand(1,1); + + for(int i=0;i<cd.properties.size();i++) { + property_line[cd.properties[i].name]=class_desc->get_line_count()-2; //gets overriden if description + + class_desc->push_cell(); + class_desc->push_align(RichTextLabel::ALIGN_RIGHT); + class_desc->push_font(doc_code_font); + _add_type(cd.properties[i].type); + class_desc->add_text(" "); + class_desc->pop(); + class_desc->pop(); + class_desc->pop(); + + bool describe=false; + + if (cd.properties[i].setter!="") { + skip_methods.insert(cd.properties[i].setter); + describe=true; + + } + if (cd.properties[i].getter!="") { + skip_methods.insert(cd.properties[i].getter); + describe=true; + } + + if (cd.properties[i].description!="") { + describe=true; + + } + class_desc->push_cell(); + if (describe) { + class_desc->push_meta("@"+cd.properties[i].name); + } + + class_desc->push_font(doc_code_font); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + _add_text(cd.properties[i].name); + + if (describe) { + class_desc->pop(); + } + + + if (cd.properties[i].brief_description!="") { + class_desc->push_font(doc_font); + class_desc->add_text(" "); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color")); + _add_text(cd.properties[i].description); + class_desc->pop(); + class_desc->pop(); + + } + + if (describe) { + property_descr=true; + } + + + class_desc->pop(); + class_desc->pop(); + class_desc->pop(); + + } + + + class_desc->pop(); //table + class_desc->pop(); + class_desc->add_newline(); + class_desc->add_newline(); + } + + + bool method_descr=false; + bool sort_methods = EditorSettings::get_singleton()->get("text_editor/help/sort_functions_alphabetically"); + + Vector<DocData::MethodDoc> methods; + + for(int i=0;i<cd.methods.size();i++) { + if (skip_methods.has(cd.methods[i].name)) + continue; + methods.push_back(cd.methods[i]); + } + + if (methods.size()) { + + if (sort_methods) + methods.sort(); + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->push_font(doc_title_font); + class_desc->add_text(TTR("Public Methods:")); + class_desc->pop(); + class_desc->pop(); + + //class_desc->add_newline(); + //class_desc->add_newline(); + + class_desc->push_indent(1); + class_desc->push_table(2); + class_desc->set_table_column_expand(1,1); + + for(int i=0;i<methods.size();i++) { + + class_desc->push_cell(); + + + method_line[methods[i].name]=class_desc->get_line_count()-2; //gets overriden if description + class_desc->push_align(RichTextLabel::ALIGN_RIGHT); + class_desc->push_font(doc_code_font); + _add_type(methods[i].return_type); + //class_desc->add_text(" "); + class_desc->pop(); //align + class_desc->pop(); //font + class_desc->pop(); //cell + class_desc->push_cell(); + class_desc->push_font(doc_code_font); + + if (methods[i].description!="") { + method_descr=true; + class_desc->push_meta("@"+methods[i].name); + } + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + _add_text(methods[i].name); + class_desc->pop(); + if (methods[i].description!="") + class_desc->pop(); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); + class_desc->add_text(methods[i].arguments.size()?"( ":"("); + class_desc->pop(); + for(int j=0;j<methods[i].arguments.size();j++) { + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + if (j>0) + class_desc->add_text(", "); + _add_type(methods[i].arguments[j].type); + class_desc->add_text(" "); + _add_text(methods[i].arguments[j].name); + if (methods[i].arguments[j].default_value!="") { + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); + class_desc->add_text("="); + class_desc->pop(); + _add_text(methods[i].arguments[j].default_value); + } + + class_desc->pop(); + } + + if (methods[i].qualifiers.find("vararg")!=-1) { + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + class_desc->add_text(","); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); + class_desc->add_text(" ... "); + class_desc->pop(); + class_desc->pop(); + } + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); + class_desc->add_text(methods[i].arguments.size()?" )":")"); + class_desc->pop(); + if (methods[i].qualifiers!="") { + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->add_text(" "); + _add_text(methods[i].qualifiers); + class_desc->pop(); + + } + class_desc->pop();//monofont + //class_desc->add_newline(); + class_desc->pop(); //cell + + } + class_desc->pop(); //table + class_desc->pop(); + class_desc->add_newline(); + class_desc->add_newline(); + + } + + + if (cd.theme_properties.size()) { + + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->push_font(doc_title_font); + class_desc->add_text(TTR("GUI Theme Items:")); + class_desc->pop(); + class_desc->pop(); + class_desc->add_newline(); + + class_desc->push_indent(1); + + //class_desc->add_newline(); + + for(int i=0;i<cd.theme_properties.size();i++) { + + theme_property_line[cd.theme_properties[i].name]=class_desc->get_line_count()-2; //gets overriden if description + class_desc->push_font(doc_code_font); + _add_type(cd.theme_properties[i].type); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + class_desc->add_text(" "); + _add_text(cd.theme_properties[i].name); + class_desc->pop(); + class_desc->pop(); + + if (cd.theme_properties[i].description!="") { + class_desc->push_font(doc_font); + class_desc->add_text(" "); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color")); + _add_text(cd.theme_properties[i].description); + class_desc->pop(); + class_desc->pop(); + + } + + class_desc->add_newline(); + } + + class_desc->pop(); + class_desc->add_newline(); + } + + if (cd.signals.size()) { + + if (sort_methods) { + cd.signals.sort(); + } + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->push_font(doc_title_font); + class_desc->add_text(TTR("Signals:")); + class_desc->pop(); + class_desc->pop(); + + class_desc->add_newline(); + //class_desc->add_newline(); + + class_desc->push_indent(1); + + for(int i=0;i<cd.signals.size();i++) { + + signal_line[cd.signals[i].name]=class_desc->get_line_count()-2; //gets overriden if description + class_desc->push_font(doc_code_font); // monofont + //_add_type("void"); + //class_desc->add_text(" "); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + _add_text(cd.signals[i].name); + class_desc->pop(); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); + class_desc->add_text(cd.signals[i].arguments.size()?"( ":"("); + class_desc->pop(); + for(int j=0;j<cd.signals[i].arguments.size();j++) { + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + if (j>0) + class_desc->add_text(", "); + _add_type(cd.signals[i].arguments[j].type); + class_desc->add_text(" "); + _add_text(cd.signals[i].arguments[j].name); + if (cd.signals[i].arguments[j].default_value!="") { + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); + class_desc->add_text("="); + class_desc->pop(); + _add_text(cd.signals[i].arguments[j].default_value); + } + + class_desc->pop(); + } + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); + class_desc->add_text(cd.signals[i].arguments.size()?" )":")"); + class_desc->pop(); + class_desc->pop(); // end monofont + if (cd.signals[i].description!="") { + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color")); + class_desc->add_text(" "); + _add_text(cd.signals[i].description); + class_desc->pop(); + + } + class_desc->add_newline(); + + } + + class_desc->pop(); + class_desc->add_newline(); + + } + + if (cd.constants.size()) { + + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->push_font(doc_title_font); + class_desc->add_text(TTR("Constants:")); + class_desc->pop(); + class_desc->pop(); + class_desc->push_indent(1); + + class_desc->add_newline(); + //class_desc->add_newline(); + + for(int i=0;i<cd.constants.size();i++) { + + constant_line[cd.constants[i].name]=class_desc->get_line_count()-2; + class_desc->push_font(doc_code_font); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color")); + _add_text(cd.constants[i].name); + class_desc->pop(); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); + class_desc->add_text(" = "); + class_desc->pop(); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + _add_text(cd.constants[i].value); + class_desc->pop(); + class_desc->pop(); + if (cd.constants[i].description!="") { + class_desc->push_font(doc_font); + class_desc->add_text(" "); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color")); + _add_text(cd.constants[i].description); + class_desc->pop(); + class_desc->pop(); + } + + class_desc->add_newline(); + } + + class_desc->pop(); + class_desc->add_newline(); + + + } + + if (cd.description!="") { + + description_line=class_desc->get_line_count()-2; + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->push_font(doc_title_font); + class_desc->add_text(TTR("Description:")); + class_desc->pop(); + class_desc->pop(); + + class_desc->add_newline(); + class_desc->add_newline(); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + class_desc->push_font( doc_font ); + class_desc->push_indent(1); + _add_text(cd.description); + class_desc->pop(); + class_desc->pop(); + class_desc->pop(); + class_desc->add_newline(); + class_desc->add_newline(); + } + + if (property_descr) { + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->push_font(doc_title_font); + class_desc->add_text(TTR("Property Description:")); + class_desc->pop(); + class_desc->pop(); + + class_desc->add_newline(); + class_desc->add_newline(); + + + for(int i=0;i<cd.properties.size();i++) { + + method_line[cd.properties[i].name]=class_desc->get_line_count()-2; + + class_desc->push_font(doc_code_font); + _add_type(cd.properties[i].type); + + class_desc->add_text(" "); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + _add_text(cd.properties[i].name); + class_desc->pop(); //color + + class_desc->add_text(" "); + + class_desc->pop(); //font + + if (cd.properties[i].setter!="") { + + class_desc->push_font( doc_font ); + + class_desc->push_indent(2); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->add_text("Setter: "); + class_desc->pop(); + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + class_desc->add_text(cd.properties[i].setter+"(value)"); + class_desc->pop(); //color + + class_desc->pop(); //indent + + class_desc->pop(); //font + + } + + if (cd.properties[i].getter!="") { + + class_desc->push_font( doc_font ); + + class_desc->push_indent(2); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->add_text("Getter: "); + class_desc->pop(); + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + class_desc->add_text(cd.properties[i].getter+"()"); + class_desc->pop(); //color + + class_desc->pop(); //indent + + class_desc->pop(); //font + + } + + class_desc->add_newline(); + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + class_desc->push_font( doc_font ); + class_desc->push_indent(1); + _add_text(cd.properties[i].description); + class_desc->pop(); + class_desc->pop(); + class_desc->pop(); + class_desc->add_newline(); + class_desc->add_newline(); + class_desc->add_newline(); + + } + + } + + if (method_descr) { + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->push_font(doc_title_font); + class_desc->add_text(TTR("Method Description:")); + class_desc->pop(); + class_desc->pop(); + + class_desc->add_newline(); + class_desc->add_newline(); + + + for(int i=0;i<methods.size();i++) { + + method_line[methods[i].name]=class_desc->get_line_count()-2; + + class_desc->push_font(doc_code_font); + _add_type(methods[i].return_type); + + class_desc->add_text(" "); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + _add_text(methods[i].name); + class_desc->pop(); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); + class_desc->add_text(methods[i].arguments.size()?"( ":"("); + class_desc->pop(); + for(int j=0;j<methods[i].arguments.size();j++) { + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + if (j>0) + class_desc->add_text(", "); + _add_type(methods[i].arguments[j].type); + class_desc->add_text(" "); + _add_text(methods[i].arguments[j].name); + if (methods[i].arguments[j].default_value!="") { + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); + class_desc->add_text("="); + class_desc->pop(); + _add_text(methods[i].arguments[j].default_value); + } + + class_desc->pop(); + } + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); + class_desc->add_text(methods[i].arguments.size()?" )":")"); + class_desc->pop(); + if (methods[i].qualifiers!="") { + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + class_desc->add_text(" "); + _add_text(methods[i].qualifiers); + class_desc->pop(); + + } + + class_desc->pop(); + + class_desc->add_newline(); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + class_desc->push_font( doc_font ); + class_desc->push_indent(1); + _add_text(methods[i].description); + class_desc->pop(); + class_desc->pop(); + class_desc->pop(); + class_desc->add_newline(); + class_desc->add_newline(); + class_desc->add_newline(); + + } + + + + + + } + + + + scroll_locked=false; + + return OK; +} + +void EditorHelp::_request_help(const String& p_string) { + Error err = _goto_desc(p_string); + if (err==OK) { + editor->call("_editor_select",EditorNode::EDITOR_SCRIPT); + } + //100 palabras +} + + +void EditorHelp::_help_callback(const String& p_topic) { + + String what = p_topic.get_slice(":",0); + String clss = p_topic.get_slice(":",1); + String name; + if (p_topic.get_slice_count(":")==3) + name=p_topic.get_slice(":",2); + + _request_help(clss); //first go to class + + int line=0; + + if (what=="class_desc") { + line=description_line; + } else if (what=="class_signal") { + if (signal_line.has(name)) + line=signal_line[name]; + } else if (what=="class_method" || what=="class_method_desc") { + if (method_line.has(name)) + line=method_line[name]; + } else if (what=="class_property") { + + if (property_line.has(name)) + line=property_line[name]; + } else if (what=="class_theme_item") { + + if (theme_property_line.has(name)) + line=theme_property_line[name]; + } else if (what=="class_constant") { + + if (constant_line.has(name)) + line=constant_line[name]; + } + + class_desc->call_deferred("scroll_to_line", line); + +} + + + +static void _add_text_to_rt(const String& p_bbcode,RichTextLabel *p_rt) { + + DocData *doc = EditorHelp::get_doc_data(); + String base_path; + + /*p_rt->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); + p_rt->push_font( get_font("normal","Fonts") ); + p_rt->push_indent(1);*/ + int pos = 0; + + Ref<Font> doc_font = p_rt->get_font("doc","EditorFonts"); + Ref<Font> doc_code_font = p_rt->get_font("doc_source","EditorFonts"); + + String bbcode=p_bbcode.replace("\t"," ").replace("\r"," ").strip_edges(); + + //change newlines for double newlines + for(int i=0;i<bbcode.length();i++) { + + //find valid newlines (double) + if (bbcode[i]=='\n') { + bool dnl=false; + int j=i+1; + for(;j<p_bbcode.length();j++) { + if (bbcode[j]==' ') + continue; + if (bbcode[j]=='\n') { + dnl=true; + break; + } + break; + } + + if (dnl) { + bbcode[i]=0xFFFF; + //keep + i=j; + } else { + bbcode=bbcode.insert(i,"\n"); + i++; + //bbcode[i]=' '; + //i=j-1; + } + } + } + + //remove double spaces or spaces after newlines + for(int i=0;i<bbcode.length();i++) { + + if (bbcode[i]==' ' || bbcode[i]=='\n' || bbcode[i]==0xFFFF) { + + for(int j=i+1;j<p_bbcode.length();j++) { + if (bbcode[j]==' ') { + bbcode.remove(j); + j--; + continue; + } else { + break; + } + } + } + } + + //change newlines to double newlines + + CharType dnls[2]={0xFFFF,0}; + bbcode=bbcode.replace(dnls,"\n"); + + + List<String> tag_stack; + + while(pos < bbcode.length()) { + + + int brk_pos = bbcode.find("[",pos); + + if (brk_pos<0) + brk_pos=bbcode.length(); + + if (brk_pos > pos) { + p_rt->add_text(bbcode.substr(pos,brk_pos-pos)); + + } + + if (brk_pos==bbcode.length()) + break; //nothing else o add + + int brk_end = bbcode.find("]",brk_pos+1); + + if (brk_end==-1) { + //no close, add the rest + p_rt->add_text(bbcode.substr(brk_pos,bbcode.length()-brk_pos)); + + break; + } + + + String tag = bbcode.substr(brk_pos+1,brk_end-brk_pos-1); + + + if (tag.begins_with("/")) { + bool tag_ok = tag_stack.size() && tag_stack.front()->get()==tag.substr(1,tag.length()); + if (tag_stack.size()) { + + + + } + if (!tag_ok) { + + p_rt->add_text("["); + pos++; + continue; + } + + tag_stack.pop_front(); + pos=brk_end+1; + if (tag!="/img") + p_rt->pop(); + + } else if (tag.begins_with("method ")) { + + String m = tag.substr(7,tag.length()); + p_rt->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + p_rt->push_meta("@"+m); + p_rt->add_text(m+"()"); + p_rt->pop(); + p_rt->pop(); + pos=brk_end+1; + + } else if (doc->class_list.has(tag)) { + + + p_rt->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); + p_rt->push_meta("#"+tag); + p_rt->add_text(tag); + p_rt->pop(); + p_rt->pop(); + pos=brk_end+1; + + } else if (tag=="b") { + + //use bold font + p_rt->push_font(doc_code_font); + pos=brk_end+1; + tag_stack.push_front(tag); + } else if (tag=="i") { + + //use italics font + Color text_color = EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"); + //no italics so emphasize with color + text_color.r*=1.1; + text_color.g*=1.1; + text_color.b*=1.1; + p_rt->push_color(text_color); + //p_rt->push_font(get_font("italic","Fonts")); + pos=brk_end+1; + tag_stack.push_front(tag); + } else if (tag=="code" || tag=="codeblock") { + + //use monospace font + p_rt->push_font(doc_code_font); + pos=brk_end+1; + tag_stack.push_front(tag); + } else if (tag=="center") { + + //use monospace font + p_rt->push_align(RichTextLabel::ALIGN_CENTER); + pos=brk_end+1; + tag_stack.push_front(tag); + } else if (tag=="br") { + + //use monospace font + p_rt->add_newline(); + pos=brk_end+1; + } else if (tag=="u") { + + //use underline + p_rt->push_underline(); + pos=brk_end+1; + tag_stack.push_front(tag); + } else if (tag=="s") { + + //use strikethrough (not supported underline instead) + p_rt->push_underline(); + pos=brk_end+1; + tag_stack.push_front(tag); + + } else if (tag=="url") { + + //use strikethrough (not supported underline instead) + int end=bbcode.find("[",brk_end); + if (end==-1) + end=bbcode.length(); + String url = bbcode.substr(brk_end+1,end-brk_end-1); + p_rt->push_meta(url); + + pos=brk_end+1; + tag_stack.push_front(tag); + } else if (tag.begins_with("url=")) { + + String url = tag.substr(4,tag.length()); + p_rt->push_meta(url); + pos=brk_end+1; + tag_stack.push_front("url"); + } else if (tag=="img") { + + //use strikethrough (not supported underline instead) + int end=bbcode.find("[",brk_end); + if (end==-1) + end=bbcode.length(); + String image = bbcode.substr(brk_end+1,end-brk_end-1); + + Ref<Texture> texture = ResourceLoader::load(base_path+"/"+image,"Texture"); + if (texture.is_valid()) + p_rt->add_image(texture); + + pos=end; + tag_stack.push_front(tag); + } else if (tag.begins_with("color=")) { + + String col = tag.substr(6,tag.length()); + Color color; + + if (col.begins_with("#")) + color=Color::html(col); + else if (col=="aqua") + color=Color::html("#00FFFF"); + else if (col=="black") + color=Color::html("#000000"); + else if (col=="blue") + color=Color::html("#0000FF"); + else if (col=="fuchsia") + color=Color::html("#FF00FF"); + else if (col=="gray" || col=="grey") + color=Color::html("#808080"); + else if (col=="green") + color=Color::html("#008000"); + else if (col=="lime") + color=Color::html("#00FF00"); + else if (col=="maroon") + color=Color::html("#800000"); + else if (col=="navy") + color=Color::html("#000080"); + else if (col=="olive") + color=Color::html("#808000"); + else if (col=="purple") + color=Color::html("#800080"); + else if (col=="red") + color=Color::html("#FF0000"); + else if (col=="silver") + color=Color::html("#C0C0C0"); + else if (col=="teal") + color=Color::html("#008008"); + else if (col=="white") + color=Color::html("#FFFFFF"); + else if (col=="yellow") + color=Color::html("#FFFF00"); + else + color=Color(0,0,0,1); //base_color; + + + + p_rt->push_color(color); + pos=brk_end+1; + tag_stack.push_front("color"); + + } else if (tag.begins_with("font=")) { + + String fnt = tag.substr(5,tag.length()); + + + Ref<Font> font = ResourceLoader::load(base_path+"/"+fnt,"Font"); + if (font.is_valid()) + p_rt->push_font(font); + else { + p_rt->push_font(doc_font); + } + + pos=brk_end+1; + tag_stack.push_front("font"); + + + } else { + + p_rt->add_text("["); //ignore + pos=brk_pos+1; + + } + } + + /*p_rt->pop(); + p_rt->pop(); + p_rt->pop();*/ + +} + + +void EditorHelp::_add_text(const String& p_bbcode) { + + + _add_text_to_rt(p_bbcode,class_desc); + +} + + + + +void EditorHelp::_update_doc() { + + + +} + + +void EditorHelp::generate_doc() { + + doc = memnew( DocData ); + doc->generate(true); + DocData compdoc; + compdoc.load_compressed(_doc_data_compressed,_doc_data_compressed_size,_doc_data_uncompressed_size); + doc->merge_from(compdoc); //ensure all is up to date + + +} + +void EditorHelp::_notification(int p_what) { + + + switch(p_what) { + + case NOTIFICATION_READY: { + + + //forward->set_icon(get_icon("Forward","EditorIcons")); + //back->set_icon(get_icon("Back","EditorIcons")); + _update_doc(); + + } break; + } +} + +void EditorHelp::go_to_help(const String& p_help) { + + _help_callback(p_help); +} + +void EditorHelp::go_to_class(const String& p_class,int p_scroll) { + + _goto_desc(p_class,p_scroll); +} + +void EditorHelp::popup_search() { + + + search_dialog->popup_centered(Size2(250,80)); + search->grab_focus(); +} + +void EditorHelp::_search_cbk() { + + _search(search->get_text()); +} + +String EditorHelp::get_class() { + + return edited_class; +} + +void EditorHelp::search_again() { + _search(prev_search); +} + +int EditorHelp::get_scroll() const { + + return class_desc->get_v_scroll()->get_value(); +} +void EditorHelp::set_scroll(int p_scroll) { + + + class_desc->get_v_scroll()->set_value(p_scroll); + +} + +void EditorHelp::_bind_methods() { + + ClassDB::bind_method("_class_list_select",&EditorHelp::_class_list_select); + ClassDB::bind_method("_class_desc_select",&EditorHelp::_class_desc_select); + ClassDB::bind_method("_class_desc_input",&EditorHelp::_class_desc_input); + //ClassDB::bind_method("_button_pressed",&EditorHelp::_button_pressed); + ClassDB::bind_method("_scroll_changed",&EditorHelp::_scroll_changed); + ClassDB::bind_method("_request_help",&EditorHelp::_request_help); + ClassDB::bind_method("_unhandled_key_input",&EditorHelp::_unhandled_key_input); + ClassDB::bind_method("_search",&EditorHelp::_search); + ClassDB::bind_method("_search_cbk",&EditorHelp::_search_cbk); + ClassDB::bind_method("_help_callback",&EditorHelp::_help_callback); + + ADD_SIGNAL(MethodInfo("go_to_help")); + +} + +EditorHelp::EditorHelp() { + + editor=EditorNode::get_singleton(); + + VBoxContainer *vbc = this; + + EDITOR_DEF("text_editor/help/sort_functions_alphabetically",true); + + //class_list->connect("meta_clicked",this,"_class_list_select"); + //class_list->set_selection_enabled(true); + + { + Panel *pc = memnew( Panel ); + Ref<StyleBoxFlat> style( memnew( StyleBoxFlat ) ); + style->set_bg_color( EditorSettings::get_singleton()->get("text_editor/highlighting/background_color") ); + pc->set_v_size_flags(SIZE_EXPAND_FILL); + pc->add_style_override("panel", style); //get_stylebox("normal","TextEdit")); + vbc->add_child(pc); + class_desc = memnew( RichTextLabel ); + pc->add_child(class_desc); + class_desc->set_area_as_parent_rect(8); + class_desc->connect("meta_clicked",this,"_class_desc_select"); + class_desc->connect("gui_input",this,"_class_desc_input"); + } + + class_desc->get_v_scroll()->connect("value_changed",this,"_scroll_changed"); + class_desc->set_selection_enabled(true); + + scroll_locked=false; + select_locked=false; + set_process_unhandled_key_input(true); + class_desc->hide(); + + search_dialog = memnew( ConfirmationDialog ); + add_child(search_dialog); + VBoxContainer *search_vb = memnew( VBoxContainer ); + search_dialog->add_child(search_vb); + + search = memnew( LineEdit ); + search_dialog->register_text_enter(search); + search_vb->add_margin_child(TTR("Search Text"),search); + search_dialog->get_ok()->set_text(TTR("Find")); + search_dialog->connect("confirmed",this,"_search_cbk"); + search_dialog->set_hide_on_ok(false); + search_dialog->set_self_modulate(Color(1,1,1,0.8)); + + + /*class_search = memnew( EditorHelpSearch(editor) ); + editor->get_gui_base()->add_child(class_search); + class_search->connect("go_to_help",this,"_help_callback");*/ + + //prev_search_page=-1; +} + +EditorHelp::~EditorHelp() { + +} + +///////////// + + + +void EditorHelpBit::_go_to_help(String p_what) { + + EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT); + ScriptEditor::get_singleton()->goto_help(p_what); + emit_signal("request_hide"); +} + +void EditorHelpBit::_meta_clicked(String p_select) { + + //print_line("LINK: "+p_select); + if (p_select.begins_with("#")) { + //_goto_desc(p_select.substr(1,p_select.length())); + _go_to_help("class_name:"+p_select.substr(1,p_select.length())); + return; + } else if (p_select.begins_with("@")) { + + String m = p_select.substr(1,p_select.length()); + + if (m.find(".")!=-1) { + //must go somewhere else + + _go_to_help("class_method:"+m.get_slice(".",0)+":"+m.get_slice(".",0)); + } else { + /* + if (!method_line.has(m)) + return; + class_desc->scroll_to_line(method_line[m]); + */ + } + + } + + +} + +void EditorHelpBit::_bind_methods() { + + ClassDB::bind_method("_meta_clicked",&EditorHelpBit::_meta_clicked); + ADD_SIGNAL(MethodInfo("request_hide")); +} + +void EditorHelpBit::_notification(int p_what){ + + if (p_what==NOTIFICATION_ENTER_TREE) { + add_style_override("panel",get_stylebox("normal","TextEdit")); + } +} + + +void EditorHelpBit::set_text(const String& p_text) { + + rich_text->clear(); + _add_text_to_rt(p_text,rich_text); +} + +EditorHelpBit::EditorHelpBit() { + + rich_text = memnew( RichTextLabel ); + add_child(rich_text); + rich_text->set_area_as_parent_rect(8*EDSCALE); + rich_text->connect("meta_clicked",this,"_meta_clicked"); + set_custom_minimum_size(Size2(0,70*EDSCALE)); + +} diff --git a/editor/editor_help.h b/editor/editor_help.h new file mode 100644 index 0000000000..909226f403 --- /dev/null +++ b/editor/editor_help.h @@ -0,0 +1,222 @@ +/*************************************************************************/ +/* editor_help.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITOR_HELP_H +#define EDITOR_HELP_H + +#include "editor/editor_plugin.h" +#include "scene/gui/tab_container.h" +#include "scene/gui/text_edit.h" +#include "scene/gui/split_container.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/rich_text_label.h" +#include "scene/gui/panel_container.h" +#include "scene/gui/tree.h" + +#include "scene/main/timer.h" +#include "editor/code_editor.h" +#include "editor/doc/doc_data.h" + + +class EditorNode; + +class EditorHelpSearch : public ConfirmationDialog { + + GDCLASS(EditorHelpSearch,ConfirmationDialog ) + + EditorNode *editor; + LineEdit *search_box; + Tree *search_options; + String base_type; + + void _update_search(); + + void _sbox_input(const InputEvent& p_ie); + + void _confirmed(); + void _text_changed(const String& p_newtext); + + +protected: + + void _notification(int p_what); + static void _bind_methods(); +public: + + void popup(); + void popup(const String& p_term); + + EditorHelpSearch(); +}; + +class EditorHelpIndex : public ConfirmationDialog { + GDCLASS( EditorHelpIndex, ConfirmationDialog ); + + LineEdit *search_box; + Tree *class_list; + HashMap<String,TreeItem*> tree_item_map; + + void _tree_item_selected(); + void _text_changed(const String& p_text); + void _sbox_input(const InputEvent& p_ie); + + void _update_class_list(); + + void add_type(const String& p_type,HashMap<String,TreeItem*>& p_types,TreeItem *p_root); +protected: + + void _notification(int p_what); + static void _bind_methods(); + +public: + + void select_class(const String& p_class); + + void popup(); + + EditorHelpIndex(); +}; + + +class EditorHelp : public VBoxContainer { + GDCLASS( EditorHelp, VBoxContainer ); + + + enum Page { + + PAGE_CLASS_LIST, + PAGE_CLASS_DESC, + PAGE_CLASS_PREV, + PAGE_CLASS_NEXT, + PAGE_SEARCH, + CLASS_SEARCH, + + }; + + + bool select_locked; + + String prev_search; + + String edited_class; + + EditorNode *editor; + Map<String,int> method_line; + Map<String,int> signal_line; + Map<String,int> property_line; + Map<String,int> theme_property_line; + Map<String,int> constant_line; + int description_line; + + + RichTextLabel *class_desc; + HSplitContainer *h_split; + static DocData *doc; + + + ConfirmationDialog *search_dialog; + LineEdit *search; + + + String base_path; + + + void _help_callback(const String& p_topic); + + void _add_text(const String& p_text); + bool scroll_locked; + + //void _button_pressed(int p_idx); + void _add_type(const String& p_type); + + void _scroll_changed(double p_scroll); + void _class_list_select(const String& p_select); + void _class_desc_select(const String& p_select); + void _class_desc_input(const InputEvent& p_input); + + Error _goto_desc(const String& p_class, int p_vscr=-1); + //void _update_history_buttons(); + void _update_doc(); + + void _request_help(const String& p_string); + void _search(const String& p_str); + void _search_cbk(); + + void _unhandled_key_input(const InputEvent& p_ev); + + + +protected: + + + void _notification(int p_what); + static void _bind_methods(); +public: + + static void generate_doc(); + static DocData *get_doc_data() { return doc; } + + void go_to_help(const String& p_help); + void go_to_class(const String& p_class,int p_scroll=0); + + void popup_search(); + void search_again(); + + String get_class(); + + void set_focused() { class_desc->grab_focus(); } + + int get_scroll() const; + void set_scroll(int p_scroll); + + EditorHelp(); + ~EditorHelp(); +}; + + + +class EditorHelpBit : public Panel { + + GDCLASS( EditorHelpBit, Panel); + + RichTextLabel *rich_text; + void _go_to_help(String p_what); + void _meta_clicked(String p_what); + + +protected: + + static void _bind_methods(); + void _notification(int p_what); +public: + + void set_text(const String& p_text); + EditorHelpBit(); +}; + +#endif // EDITOR_HELP_H diff --git a/tools/editor/editor_icons.h b/editor/editor_icons.h index 7e8d8c0828..7e8d8c0828 100644 --- a/tools/editor/editor_icons.h +++ b/editor/editor_icons.h diff --git a/tools/editor/editor_initialize_ssl.cpp b/editor/editor_initialize_ssl.cpp index c08dcc6656..c08dcc6656 100644 --- a/tools/editor/editor_initialize_ssl.cpp +++ b/editor/editor_initialize_ssl.cpp diff --git a/tools/editor/editor_initialize_ssl.h b/editor/editor_initialize_ssl.h index 0b34ac1d7e..0b34ac1d7e 100644 --- a/tools/editor/editor_initialize_ssl.h +++ b/editor/editor_initialize_ssl.h diff --git a/tools/editor/editor_log.cpp b/editor/editor_log.cpp index 850d9273f8..850d9273f8 100644 --- a/tools/editor/editor_log.cpp +++ b/editor/editor_log.cpp diff --git a/tools/editor/editor_log.h b/editor/editor_log.h index 965d8d6420..965d8d6420 100644 --- a/tools/editor/editor_log.h +++ b/editor/editor_log.h diff --git a/tools/editor/editor_name_dialog.cpp b/editor/editor_name_dialog.cpp index da9f25f1e3..da9f25f1e3 100644 --- a/tools/editor/editor_name_dialog.cpp +++ b/editor/editor_name_dialog.cpp diff --git a/tools/editor/editor_name_dialog.h b/editor/editor_name_dialog.h index d6bc7eca94..d6bc7eca94 100644 --- a/tools/editor/editor_name_dialog.h +++ b/editor/editor_name_dialog.h diff --git a/tools/editor/editor_node.cpp b/editor/editor_node.cpp index 7a85941b0d..7a85941b0d 100644 --- a/tools/editor/editor_node.cpp +++ b/editor/editor_node.cpp diff --git a/editor/editor_node.h b/editor/editor_node.h new file mode 100644 index 0000000000..fb0b5c4c25 --- /dev/null +++ b/editor/editor_node.h @@ -0,0 +1,833 @@ +/*************************************************************************/ +/* editor_node.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITOR_NODE_H +#define EDITOR_NODE_H + +#include "scene/gui/control.h" +#include "scene/gui/panel.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/tree.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/separator.h" +#include "scene/gui/tab_container.h" +#include "scene/gui/panel_container.h" +#include "scene/gui/file_dialog.h" +#include "scene/gui/split_container.h" +#include "scene/gui/center_container.h" +#include "scene/gui/texture_progress.h" +#include "editor/filesystem_dock.h" +#include "editor/scene_tree_editor.h" +#include "editor/property_editor.h" +#include "editor/create_dialog.h" +#include "editor/call_dialog.h" +#include "editor/reparent_dialog.h" +#include "editor/connections_dialog.h" +#include "editor/node_dock.h" +#include "editor/import_dock.h" +#include "editor/settings_config_dialog.h" +#include "editor/groups_editor.h" +#include "editor/editor_data.h" +#include "editor/editor_path.h" +#include "editor/editor_run.h" + +#include "editor/pane_drag.h" + +#include "editor/script_create_dialog.h" +#include "editor/run_settings_dialog.h" +#include "editor/project_settings.h" +#include "editor/project_export.h" +#include "editor/editor_log.h" +#include "editor/scene_tree_dock.h" +#include "editor/resources_dock.h" +#include "editor/editor_run_script.h" + +#include "editor/editor_run_native.h" +#include "scene/gui/tabs.h" +#include "editor/quick_open.h" +#include "editor/project_export.h" +#include "editor/editor_sub_scene.h" +#include "editor_export.h" +#include "editor_reimport_dialog.h" +#include "editor/editor_plugin.h" +#include "editor/editor_name_dialog.h" + +#include "fileserver/editor_file_server.h" +#include "editor_resource_preview.h" +#include "scene/gui/viewport_container.h" + + +#include "progress_dialog.h" + +#include "editor_scale.h" +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + + + + + +typedef void (*EditorNodeInitCallback)(); +typedef void (*EditorPluginInitializeCallback)(); +typedef void (*EditorBuildCallback)(); + +class EditorPluginList; + +class EditorNode : public Node { + + GDCLASS( EditorNode, Node ); + +public: + enum DockSlot { + DOCK_SLOT_LEFT_UL, + DOCK_SLOT_LEFT_BL, + DOCK_SLOT_LEFT_UR, + DOCK_SLOT_LEFT_BR, + DOCK_SLOT_RIGHT_UL, + DOCK_SLOT_RIGHT_BL, + DOCK_SLOT_RIGHT_UR, + DOCK_SLOT_RIGHT_BR, + DOCK_SLOT_MAX + }; +private: + enum { + HISTORY_SIZE=64 + }; + + enum MenuOptions { + FILE_NEW_SCENE, + FILE_NEW_INHERITED_SCENE, + FILE_OPEN_SCENE, + FILE_SAVE_SCENE, + FILE_SAVE_AS_SCENE, + FILE_SAVE_ALL_SCENES, + FILE_SAVE_BEFORE_RUN, + FILE_SAVE_AND_RUN, + FILE_IMPORT_SUBSCENE, + FILE_EXPORT_PROJECT, + FILE_EXPORT_MESH_LIBRARY, + FILE_EXPORT_TILESET, + FILE_SAVE_OPTIMIZED, + FILE_OPEN_RECENT, + FILE_OPEN_OLD_SCENE, + FILE_QUICK_OPEN_SCENE, + FILE_QUICK_OPEN_SCRIPT, + FILE_RUN_SCRIPT, + FILE_OPEN_PREV, + FILE_CLOSE, + FILE_QUIT, + FILE_EXTERNAL_OPEN_SCENE, + EDIT_UNDO, + EDIT_REDO, + EDIT_REVERT, + TOOLS_ORPHAN_RESOURCES, + RESOURCE_NEW, + RESOURCE_LOAD, + RESOURCE_SAVE, + RESOURCE_SAVE_AS, + RESOURCE_UNREF, + RESOURCE_COPY, + RESOURCE_PASTE, + OBJECT_COPY_PARAMS, + OBJECT_PASTE_PARAMS, + OBJECT_UNIQUE_RESOURCES, + OBJECT_REQUEST_HELP, + RUN_PLAY, + + RUN_STOP, + RUN_PLAY_SCENE, + RUN_PLAY_NATIVE, + RUN_PLAY_CUSTOM_SCENE, + RUN_SCENE_SETTINGS, + RUN_SETTINGS, + RUN_PROJECT_MANAGER, + RUN_FILE_SERVER, + //RUN_DEPLOY_DUMB_CLIENTS, + RUN_LIVE_DEBUG, + RUN_DEBUG_COLLISONS, + RUN_DEBUG_NAVIGATION, + RUN_DEPLOY_REMOTE_DEBUG, + RUN_RELOAD_SCRIPTS, + SETTINGS_UPDATE_ALWAYS, + SETTINGS_UPDATE_CHANGES, + SETTINGS_UPDATE_SPINNER_HIDE, + SETTINGS_EXPORT_PREFERENCES, + SETTINGS_PREFERENCES, + SETTINGS_OPTIMIZED_PRESETS, + SETTINGS_LAYOUT_SAVE, + SETTINGS_LAYOUT_DELETE, + SETTINGS_LAYOUT_DEFAULT, + SETTINGS_LOAD_EXPORT_TEMPLATES, + SETTINGS_PICK_MAIN_SCENE, + SETTINGS_TOGGLE_FULLSCREN, + SETTINGS_HELP, + SETTINGS_ABOUT, + SOURCES_REIMPORT, + DEPENDENCY_LOAD_CHANGED_IMAGES, + DEPENDENCY_UPDATE_IMPORTED, + SCENE_TAB_CLOSE, + + IMPORT_PLUGIN_BASE=100, + + OBJECT_METHOD_BASE=500, + + TOOL_MENU_BASE=1000 + }; + + + + //Node *edited_scene; //scene being edited + Viewport *scene_root; //root of the scene being edited + + //Ref<ResourceImportMetadata> scene_import_metadata; + + PanelContainer* scene_root_parent; + Control *gui_base; + VBoxContainer *main_vbox; + + //split + + HSplitContainer *left_l_hsplit; + VSplitContainer *left_l_vsplit; + HSplitContainer *left_r_hsplit; + VSplitContainer *left_r_vsplit; + HSplitContainer *main_hsplit; + HSplitContainer *right_hsplit; + VSplitContainer *right_l_vsplit; + VSplitContainer *right_r_vsplit; + + VSplitContainer *center_split; + + //main tabs + + Tabs *scene_tabs; + int tab_closing; + + bool exiting; + + int old_split_ofs; + VSplitContainer *top_split; + HBoxContainer *bottom_hb; + Control *vp_base; + PaneDrag *pd; + //PaneDrag *pd_anim; + Panel *menu_panel; + + + //HSplitContainer *editor_hsplit; + //VSplitContainer *editor_vsplit; + CenterContainer *play_cc; + HBoxContainer *menu_hb; + Control *viewport; + MenuButton *file_menu; + MenuButton *import_menu; + MenuButton *tool_menu; + ToolButton *export_button; + ToolButton *prev_scene; + MenuButton *object_menu; + MenuButton *settings_menu; + ToolButton *play_button; + MenuButton *native_play_button; + ToolButton *pause_button; + ToolButton *stop_button; + ToolButton *run_settings_button; + ToolButton *play_scene_button; + ToolButton *play_custom_scene_button; + MenuButton *debug_button; + ToolButton *search_button; + TextureProgress *audio_vu; + //MenuButton *fileserver_menu; + + RichTextLabel *load_errors; + AcceptDialog *load_error_dialog; + + //Control *scene_root_base; + Ref<Theme> theme; + + PopupMenu *recent_scenes; + Button *property_back; + Button *property_forward; + SceneTreeDock *scene_tree_dock; + //ResourcesDock *resources_dock; + PropertyEditor *property_editor; + NodeDock *node_dock; + ImportDock *import_dock; + VBoxContainer *prop_editor_vb; + FileSystemDock *filesystem_dock; + EditorRunNative *run_native; + + HBoxContainer *search_bar; + LineEdit *search_box; + + CreateDialog *create_dialog; + + //CallDialog *call_dialog; + ConfirmationDialog *confirmation; + ConfirmationDialog *import_confirmation; + ConfirmationDialog *open_recent_confirmation; + ConfirmationDialog *pick_main_scene; + AcceptDialog *accept; + AcceptDialog *about; + AcceptDialog *warning; + + int overridden_default_layout; + Ref<ConfigFile> default_layout; + PopupMenu *editor_layouts; + EditorNameDialog *layout_dialog; + + //OptimizedPresetsDialog *optimized_presets; + EditorSettingsDialog *settings_config_dialog; + RunSettingsDialog *run_settings_dialog; + ProjectSettings *project_settings; + EditorFileDialog *file; + FileDialog *file_templates; + FileDialog *file_export; + FileDialog *file_export_lib; + FileDialog *file_script; + CheckButton *file_export_lib_merge; + LineEdit *file_export_password; + String current_path; + MenuButton *update_menu; + ToolButton *sources_button; + //TabContainer *prop_pallete; + //TabContainer *top_pallete; + String defer_load_scene; + String defer_export; + String defer_export_platform; + bool defer_export_debug; + Node *_last_instanced_scene; + EditorPath *editor_path; + ToolButton *resource_new_button; + ToolButton *resource_load_button; + MenuButton *resource_save_button; + MenuButton *editor_history_menu; + + EditorLog *log; + CenterContainer *tabs_center; + EditorQuickOpen *quick_open; + EditorQuickOpen *quick_run; + + HBoxContainer *main_editor_button_vb; + Vector<ToolButton*> main_editor_buttons; + Vector<EditorPlugin*> editor_table; + +// EditorReImportDialog *reimport_dialog; + + ProgressDialog *progress_dialog; + BackgroundProgress *progress_hb; + + DependencyErrorDialog *dependency_error; + DependencyEditor *dependency_fixer; + OrphanResourcesDialog *orphan_resources; + ConfirmationDialog *open_imported; + Button *new_inherited_button; + String open_import_request; + + + TabContainer *dock_slot[DOCK_SLOT_MAX]; + Rect2 dock_select_rect[DOCK_SLOT_MAX]; + int dock_select_rect_over; + PopupPanel *dock_select_popoup; + Control *dock_select; + ToolButton *dock_tab_move_left; + ToolButton *dock_tab_move_right; + int dock_popup_selected; + Timer *dock_drag_timer; + bool docks_visible; + ToolButton *distraction_free; + + String _tmp_import_path; + + EditorExport *editor_export; + + Object *current; + + bool _playing_edited; + String run_custom_filename; + bool reference_resource_mem; + bool save_external_resources_mem; + uint64_t saved_version; + uint64_t last_checked_version; + bool unsaved_cache; + String open_navigate; + bool changing_scene; + bool waiting_for_first_scan; + + bool waiting_for_sources_changed; + + uint32_t circle_step_msec; + uint64_t circle_step_frame; + int circle_step; + + Vector<EditorPlugin*> editor_plugins; + EditorPlugin *editor_plugin_screen; + EditorPluginList *editor_plugins_over; + + EditorHistory editor_history; + EditorData editor_data; + EditorRun editor_run; + EditorSelection *editor_selection; +// ProjectExport *project_export; + ProjectExportDialog *project_export; + EditorResourcePreview *resource_preview; + + EditorFileServer *file_server; + + + struct BottomPanelItem { + String name; + Control *control; + ToolButton *button; + }; + + Vector<BottomPanelItem> bottom_panel_items; + + PanelContainer *bottom_panel; + HBoxContainer *bottom_panel_hb; + VBoxContainer *bottom_panel_vb; + + void _bottom_panel_switch(bool p_enable, int p_idx); + + String external_file; + List<String> previous_scenes; + bool opening_prev; + + void _dialog_action(String p_file); + + + void _edit_current(); + void _dialog_display_file_error(String p_file,Error p_error); + + int current_option; + //void _animation_visibility_toggle(); + void _resource_created(); + void _resource_selected(const RES& p_res,const String& p_property=""); + void _menu_option(int p_option); + void _menu_confirm_current(); + void _menu_option_confirm(int p_option,bool p_confirmed); + void _update_debug_options(); + + void _property_editor_forward(); + void _property_editor_back(); + + void _select_history(int p_idx); + void _prepare_history(); + + + void _fs_changed(); + void _sources_changed(bool p_exist); + void _imported(Node *p_node); + + void _node_renamed(); + void _editor_select(int p_which); + void _set_scene_metadata(const String &p_file, int p_idx=-1); + void _get_scene_metadata(const String& p_file); + void _update_title(); + void _update_scene_tabs(); + void _close_messages(); + void _show_messages(); + void _vp_resized(); + + void _rebuild_import_menu(); + + void _save_scene(String p_file, int idx = -1); + + + void _instance_request(const Vector<String>& p_files); + + void _property_keyed(const String& p_keyed, const Variant& p_value, bool p_advance); + void _transform_keyed(Object *sp,const String& p_sub,const Transform& p_key); + + void _hide_top_editors(); + void _display_top_editors(bool p_display); + void _set_top_editors(Vector<EditorPlugin*> p_editor_plugins_over); + void _set_editing_top_editors(Object * p_current_object); + + void _quick_opened(); + void _quick_run(); + + void _run(bool p_current=false, const String &p_custom=""); + + void _save_optimized(); + void _import_action(const String& p_action); + void _import(const String &p_file); + void _add_to_recent_scenes(const String& p_scene); + void _update_recent_scenes(); + void _open_recent_scene(int p_idx); + void _dropped_files(const Vector<String>& p_files,int p_screen); + //void _open_recent_scene_confirm(); + String _recent_scene; + + bool convert_old; + + void _unhandled_input(const InputEvent& p_event); + + static void _load_error_notify(void* p_ud,const String& p_text); + + bool has_main_screen() const { return true; } + + bool _find_editing_changed_scene(Node *p_from); + + String import_reload_fn; + + Set<FileDialog*> file_dialogs; + Set<EditorFileDialog*> editor_file_dialogs; + + Map<String,Ref<Texture> > icon_type_cache; + + bool _initializing_addons; + Map<String,EditorPlugin*> plugin_addons; + + + static Ref<Texture> _file_dialog_get_icon(const String& p_path); + static void _file_dialog_register(FileDialog *p_dialog); + static void _file_dialog_unregister(FileDialog *p_dialog); + static void _editor_file_dialog_register(EditorFileDialog *p_dialog); + static void _editor_file_dialog_unregister(EditorFileDialog *p_dialog); + + + void _cleanup_scene(); + void _remove_edited_scene(); + void _remove_scene(int index); + bool _find_and_save_resource(RES p_res,Map<RES,bool>& processed,int32_t flags); + bool _find_and_save_edited_subresources(Object *obj,Map<RES,bool>& processed,int32_t flags); + void _save_edited_subresources(Node* scene,Map<RES,bool>& processed,int32_t flags); + + void _find_node_types(Node* p_node, int&count_2d, int&count_3d); + void _save_scene_with_preview(String p_file); + + + Map<String,Set<String> > dependency_errors; + + static void _dependency_error_report(void *ud,const String& p_path,const String& p_dep,const String& p_type) { + EditorNode*en=(EditorNode*)ud; + if (!en->dependency_errors.has(p_path)) + en->dependency_errors[p_path]=Set<String>(); + en->dependency_errors[p_path].insert(p_dep+"::"+p_type); + + } + + struct ExportDefer { + String platform; + String path; + bool debug; + String password; + + } export_defer; + + static EditorNode *singleton; + + static Vector<EditorNodeInitCallback> _init_callbacks; + + bool _find_scene_in_use(Node* p_node,const String& p_path) const; + + void _dock_select_input(const InputEvent& p_input); + void _dock_move_left(); + void _dock_move_right(); + void _dock_select_draw(); + void _dock_pre_popup(int p_which); + void _dock_split_dragged(int ofs); + void _dock_popup_exit(); + void _scene_tab_changed(int p_tab); + void _scene_tab_closed(int p_tab); + void _scene_tab_script_edited(int p_tab); + + Dictionary _get_main_scene_state(); + void _set_main_scene_state(Dictionary p_state,Node* p_for_scene); + + int _get_current_main_editor(); + + void _save_docks(); + void _load_docks(); + void _save_docks_to_config(Ref<ConfigFile> p_layout, const String& p_section); + void _load_docks_from_config(Ref<ConfigFile> p_layout, const String& p_section); + void _update_dock_slots_visibility(); + void _update_top_menu_visibility(); + + void _update_layouts_menu(); + void _layout_menu_option(int p_idx); + + void _toggle_search_bar(bool p_pressed); + void _clear_search_box(); + void _clear_undo_history(); + + void _update_addon_config(); + + static void _file_access_close_error_notify(const String& p_str); + + void _toggle_distraction_free_mode(); + + enum { + MAX_INIT_CALLBACKS=128, + MAX_BUILD_CALLBACKS=128 + }; + + void _inherit_imported(const String &p_action); + void _open_imported(); + + + static int plugin_init_callback_count; + static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS]; + + void _call_build(); + static int build_callback_count; + static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS]; + + bool _initializing_tool_menu; + + struct ToolMenuItem { + String name; + String submenu; + Variant ud; + ObjectID handler; + String callback; + }; + + Vector<ToolMenuItem> tool_menu_items; + + void _tool_menu_insert_item(const ToolMenuItem& p_item); + void _rebuild_tool_menu() const; + +protected: + void _notification(int p_what); + static void _bind_methods(); +public: + + static void add_plugin_init_callback(EditorPluginInitializeCallback p_callback); + + enum EditorTable { + EDITOR_2D = 0, + EDITOR_3D, + EDITOR_SCRIPT + }; + + void set_visible_editor(EditorTable p_table) { _editor_select(p_table); } + static EditorNode* get_singleton() { return singleton; } + + + EditorPlugin *get_editor_plugin_screen() { return editor_plugin_screen; } + EditorPluginList *get_editor_plugins_over() { return editor_plugins_over; } + PropertyEditor *get_property_editor() { return property_editor; } + VBoxContainer *get_property_editor_vb() { return prop_editor_vb; } + + static void add_editor_plugin(EditorPlugin *p_editor); + static void remove_editor_plugin(EditorPlugin *p_editor); + + void new_inherited_scene() { _menu_option_confirm(FILE_NEW_INHERITED_SCENE,false); } + + + void set_docks_visible(bool p_show); + bool get_docks_visible() const; + + void set_distraction_free_mode(bool p_enter); + bool get_distraction_free_mode() const; + + void add_control_to_dock(DockSlot p_slot,Control* p_control); + void remove_control_from_dock(Control* p_control); + + void set_addon_plugin_enabled(const String& p_addon,bool p_enabled); + bool is_addon_plugin_enabled(const String &p_addon) const; + + void edit_node(Node *p_node); + void edit_resource(const Ref<Resource>& p_resource); + void open_resource(const String& p_type=""); + + void save_resource_in_path(const Ref<Resource>& p_resource,const String& p_path); + void save_resource(const Ref<Resource>& p_resource); + void save_resource_as(const Ref<Resource>& p_resource, const String &p_at_path=String()); + + void merge_from_scene() { _menu_option_confirm(FILE_IMPORT_SUBSCENE,false); } + + static bool has_unsaved_changes() { return singleton->unsaved_cache; } + + static HBoxContainer *get_menu_hb() { return singleton->menu_hb; } + + void push_item(Object *p_object,const String& p_property=""); + + void open_request(const String& p_path); + + bool is_changing_scene() const; + + + static EditorLog *get_log() { return singleton->log; } + Control* get_viewport(); + + //void animation_editor_make_visible(bool p_visible); + //void hide_animation_player_editors(); + //void animation_panel_make_visible(bool p_visible); + + void set_edited_scene(Node *p_scene); + + Node *get_edited_scene() { return editor_data.get_edited_scene_root(); } + + Viewport *get_scene_root() { return scene_root; } //root of the scene being edited + + void fix_dependencies(const String& p_for_file); + void clear_scene() { _cleanup_scene(); } + Error load_scene(const String& p_scene, bool p_ignore_broken_deps=false, bool p_set_inherited=false, bool p_clear_errors=true,bool p_force_open_imported=false); + Error load_resource(const String& p_scene); + + bool is_scene_open(const String& p_path); + + void set_current_version(uint64_t p_version); + void set_current_scene(int p_idx); + + static EditorData& get_editor_data() { return singleton->editor_data; } + EditorHistory * get_editor_history() { return &editor_history; } + + static VSplitContainer *get_top_split() { return singleton->top_split; } + + void request_instance_scene(const String &p_path); + void request_instance_scenes(const Vector<String>& p_files); + FileSystemDock *get_filesystem_dock(); + ImportDock *get_import_dock(); + SceneTreeDock *get_scene_tree_dock(); + static UndoRedo* get_undo_redo() { return &singleton->editor_data.get_undo_redo(); } + + EditorSelection *get_editor_selection() { return editor_selection; } + + void set_convert_old_scene(bool p_old) { convert_old=p_old; } + + void notify_child_process_exited(); + + OS::ProcessID get_child_process_id() const { return editor_run.get_pid(); } + void stop_child_process(); + + Ref<Theme> get_editor_theme() const { return theme; } + + + void show_warning(const String& p_text,const String& p_title="Warning!"); + + + Error export_platform(const String& p_platform, const String& p_path, bool p_debug,const String& p_password,bool p_quit_after=false); + + static void register_editor_types(); + static void unregister_editor_types(); + + Control *get_gui_base() { return gui_base; } + Control *get_theme_base() { return gui_base->get_parent_control(); } + + static void add_io_error(const String& p_error); + + static void progress_add_task(const String& p_task,const String& p_label, int p_steps); + static void progress_task_step(const String& p_task,const String& p_state, int p_step=-1,bool p_force_refresh=true); + static void progress_end_task(const String& p_task); + + static void progress_add_task_bg(const String& p_task,const String& p_label, int p_steps); + static void progress_task_step_bg(const String& p_task,int p_step=-1); + static void progress_end_task_bg(const String& p_task); + + void save_scene(String p_file) { _save_scene(p_file); } + + bool is_scene_in_use(const String& p_path); + + void scan_import_changes(); + + void save_layout(); + + void update_keying(); + + void reload_scene(const String& p_path); + + bool is_exiting() const { return exiting; } + + ToolButton *get_pause_button() { return pause_button; } + + + ToolButton* add_bottom_panel_item(String p_text,Control *p_item); + bool are_bottom_panels_hidden() const; + void make_bottom_panel_item_visible(Control *p_item); + void raise_bottom_panel_item(Control *p_item); + void hide_bottom_panel(); + void remove_bottom_panel_item(Control *p_item); + + Variant drag_resource(const Ref<Resource>& p_res,Control* p_from); + Variant drag_files(const Vector<String>& p_files,Control* p_from); + Variant drag_files_and_dirs(const Vector<String>& p_files,Control* p_from); + + void add_tool_menu_item(const String& p_name, Object *p_handler, const String& p_callback, const Variant& p_ud = Variant()); + void add_tool_submenu_item(const String& p_name, PopupMenu *p_submenu); + void remove_tool_menu_item(const String& p_name); + + EditorNode(); + ~EditorNode(); + void get_singleton(const char* arg1, bool arg2); + + static void add_init_callback(EditorNodeInitCallback p_callback) { _init_callbacks.push_back(p_callback); } + static void add_build_callback(EditorBuildCallback p_callback); + + + +}; + +struct EditorProgress { + + String task; + void step(const String& p_state, int p_step=-1,bool p_force_refresh=true) { EditorNode::progress_task_step(task,p_state,p_step,p_force_refresh); } + EditorProgress(const String& p_task,const String& p_label,int p_amount) { EditorNode::progress_add_task(p_task,p_label,p_amount); task=p_task; } + ~EditorProgress() { EditorNode::progress_end_task(task); } +}; + +class EditorPluginList : public Object { +private: + Vector<EditorPlugin*> plugins_list; + +public: + + void set_plugins_list(Vector<EditorPlugin*> p_plugins_list) { + plugins_list = p_plugins_list; + } + + Vector<EditorPlugin*>& get_plugins_list() { + return plugins_list; + } + + void make_visible(bool p_visible); + void edit(Object *p_object); + bool forward_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event); + bool forward_spatial_gui_input(Camera* p_camera, const InputEvent& p_event); + void forward_draw_over_canvas(const Transform2D& p_canvas_xform,Control* p_canvas); + void clear(); + bool empty(); + + EditorPluginList(); + ~EditorPluginList(); + +} ; + +struct EditorProgressBG { + + String task; + void step(int p_step=-1) { EditorNode::progress_task_step_bg(task,p_step); } + EditorProgressBG(const String& p_task,const String& p_label,int p_amount) { EditorNode::progress_add_task_bg(p_task,p_label,p_amount); task=p_task; } + ~EditorProgressBG() { EditorNode::progress_end_task_bg(task); } +}; + +#endif diff --git a/tools/editor/editor_path.cpp b/editor/editor_path.cpp index 8cd31c4bcc..8cd31c4bcc 100644 --- a/tools/editor/editor_path.cpp +++ b/editor/editor_path.cpp diff --git a/tools/editor/editor_path.h b/editor/editor_path.h index fd5b469d07..fd5b469d07 100644 --- a/tools/editor/editor_path.h +++ b/editor/editor_path.h diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp new file mode 100644 index 0000000000..85ef96fcc3 --- /dev/null +++ b/editor/editor_plugin.cpp @@ -0,0 +1,432 @@ +/*************************************************************************/ +/* editor_plugin.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 "editor_plugin.h" + +#include "scene/gui/popup_menu.h" +#include "scene/3d/camera.h" +#include "plugins/canvas_item_editor_plugin.h" +#include "plugins/spatial_editor_plugin.h" +#include "editor/editor_node.h" +#include "editor/editor_settings.h" +#include "editor_resource_preview.h" + +void EditorPlugin::add_custom_type(const String& p_type, const String& p_base,const Ref<Script>& p_script, const Ref<Texture>& p_icon) { + + EditorNode::get_editor_data().add_custom_type(p_type,p_base,p_script,p_icon); +} + +void EditorPlugin::remove_custom_type(const String& p_type){ + + EditorNode::get_editor_data().remove_custom_type(p_type); +} + + +ToolButton * EditorPlugin::add_control_to_bottom_panel(Control *p_control, const String &p_title) { + + return EditorNode::get_singleton()->add_bottom_panel_item(p_title,p_control); +} + +void EditorPlugin::add_control_to_dock(DockSlot p_slot,Control *p_control) { + + ERR_FAIL_NULL(p_control); + EditorNode::get_singleton()->add_control_to_dock(EditorNode::DockSlot(p_slot),p_control); + +} + +void EditorPlugin::remove_control_from_docks(Control *p_control) { + + ERR_FAIL_NULL(p_control); + EditorNode::get_singleton()->remove_control_from_dock(p_control); + +} + +void EditorPlugin::remove_control_from_bottom_panel(Control *p_control) { + + ERR_FAIL_NULL(p_control); + EditorNode::get_singleton()->remove_bottom_panel_item(p_control); + +} + +Control * EditorPlugin::get_editor_viewport() { + + return EditorNode::get_singleton()->get_viewport(); +} + +void EditorPlugin::edit_resource(const Ref<Resource>& p_resource){ + + EditorNode::get_singleton()->edit_resource(p_resource); +} + +void EditorPlugin::add_control_to_container(CustomControlContainer p_location,Control *p_control) { + + switch(p_location) { + + case CONTAINER_TOOLBAR: { + + EditorNode::get_menu_hb()->add_child(p_control); + } break; + + case CONTAINER_SPATIAL_EDITOR_MENU: { + + SpatialEditor::get_singleton()->add_control_to_menu_panel(p_control); + + } break; + case CONTAINER_SPATIAL_EDITOR_SIDE: { + + SpatialEditor::get_singleton()->get_palette_split()->add_child(p_control); + SpatialEditor::get_singleton()->get_palette_split()->move_child(p_control,0); + + } break; + case CONTAINER_SPATIAL_EDITOR_BOTTOM: { + + SpatialEditor::get_singleton()->get_shader_split()->add_child(p_control); + + } break; + case CONTAINER_CANVAS_EDITOR_MENU: { + + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(p_control); + + } break; + case CONTAINER_CANVAS_EDITOR_SIDE: { + + CanvasItemEditor::get_singleton()->get_palette_split()->add_child(p_control); + CanvasItemEditor::get_singleton()->get_palette_split()->move_child(p_control,0); + + } break; + case CONTAINER_CANVAS_EDITOR_BOTTOM: { + + CanvasItemEditor::get_singleton()->get_bottom_split()->add_child(p_control); + + } break; + case CONTAINER_PROPERTY_EDITOR_BOTTOM: { + + EditorNode::get_singleton()->get_property_editor_vb()->add_child(p_control); + + } break; + + + } +} + +void EditorPlugin::add_tool_menu_item(const String& p_name, Object *p_handler, const String& p_callback, const Variant& p_ud) { + + //EditorNode::get_singleton()->add_tool_menu_item(p_name, p_handler, p_callback, p_ud); +} + +void EditorPlugin::add_tool_submenu_item(const String& p_name, Object *p_submenu) { + + ERR_FAIL_NULL(p_submenu); + PopupMenu *submenu = p_submenu->cast_to<PopupMenu>(); + ERR_FAIL_NULL(submenu); + //EditorNode::get_singleton()->add_tool_submenu_item(p_name, submenu); +} + +void EditorPlugin::remove_tool_menu_item(const String& p_name) { + + //EditorNode::get_singleton()->remove_tool_menu_item(p_name); +} + +Ref<SpatialEditorGizmo> EditorPlugin::create_spatial_gizmo(Spatial* p_spatial) { + //?? + if (get_script_instance() && get_script_instance()->has_method("create_spatial_gizmo")) { + return get_script_instance()->call("create_spatial_gizmo",p_spatial); + } + + return Ref<SpatialEditorGizmo>(); +} + +bool EditorPlugin::forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { + + if (get_script_instance() && get_script_instance()->has_method("forward_canvas_gui_input")) { + return get_script_instance()->call("forward_canvas_gui_input",p_canvas_xform,p_event); + } + return false; +} + +void EditorPlugin::forward_draw_over_canvas(const Transform2D& p_canvas_xform,Control *p_canvas) { + + if (get_script_instance() && get_script_instance()->has_method("forward_draw_over_canvas")) { + get_script_instance()->call("forward_draw_over_canvas",p_canvas_xform,p_canvas); + } +} + +void EditorPlugin::update_canvas() { + CanvasItemEditor::get_singleton()->get_viewport_control()->update(); +} + +bool EditorPlugin::forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event) { + + if (get_script_instance() && get_script_instance()->has_method("forward_spatial_gui_input")) { + return get_script_instance()->call("forward_spatial_gui_input",p_camera,p_event); + } + + return false; +} +String EditorPlugin::get_name() const { + + if (get_script_instance() && get_script_instance()->has_method("get_name")) { + return get_script_instance()->call("get_name"); + } + + return String(); + +} +bool EditorPlugin::has_main_screen() const { + + if (get_script_instance() && get_script_instance()->has_method("has_main_screen")) { + return get_script_instance()->call("has_main_screen"); + } + + return false; + +} +void EditorPlugin::make_visible(bool p_visible) { + + if (get_script_instance() && get_script_instance()->has_method("make_visible")) { + get_script_instance()->call("make_visible",p_visible); + } +} + + +void EditorPlugin::edit(Object *p_object) { + + if (get_script_instance() && get_script_instance()->has_method("edit")) { + get_script_instance()->call("edit",p_object); + } + +} + +bool EditorPlugin::handles(Object *p_object) const { + + if (get_script_instance() && get_script_instance()->has_method("handles")) { + return get_script_instance()->call("handles",p_object); + } + + return false; +} +Dictionary EditorPlugin::get_state() const { + + if (get_script_instance() && get_script_instance()->has_method("get_state")) { + return get_script_instance()->call("get_state"); + } + + return Dictionary(); +} + +void EditorPlugin::set_state(const Dictionary& p_state) { + + if (get_script_instance() && get_script_instance()->has_method("set_state")) { + get_script_instance()->call("set_state",p_state); + } +} + +void EditorPlugin::clear() { + + if (get_script_instance() && get_script_instance()->has_method("clear")) { + get_script_instance()->call("clear"); + } + +} + +// if editor references external resources/scenes, save them +void EditorPlugin::save_external_data() { + + if (get_script_instance() && get_script_instance()->has_method("save_external_data")) { + get_script_instance()->call("save_external_data"); + } +} + +// if changes are pending in editor, apply them +void EditorPlugin::apply_changes() { + + if (get_script_instance() && get_script_instance()->has_method("apply_changes")) { + get_script_instance()->call("apply_changes"); + } +} + +void EditorPlugin::get_breakpoints(List<String> *p_breakpoints) { + + if (get_script_instance() && get_script_instance()->has_method("get_breakpoints")) { + PoolStringArray arr = get_script_instance()->call("get_breakpoints"); + for(int i=0;i<arr.size();i++) + p_breakpoints->push_back(arr[i]); + } + +} +bool EditorPlugin::get_remove_list(List<Node*> *p_list) { + + return false; +} + +void EditorPlugin::restore_global_state() {} +void EditorPlugin::save_global_state() {} + +void EditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) { + + if (get_script_instance() && get_script_instance()->has_method("set_window_layout")) { + get_script_instance()->call("set_window_layout", p_layout); + } +} + +void EditorPlugin::get_window_layout(Ref<ConfigFile> p_layout){ + + if (get_script_instance() && get_script_instance()->has_method("get_window_layout")) { + get_script_instance()->call("get_window_layout", p_layout); + } +} + +void EditorPlugin::queue_save_layout() const { + + EditorNode::get_singleton()->save_layout(); +} + +EditorSelection* EditorPlugin::get_selection() { + return EditorNode::get_singleton()->get_editor_selection(); +} + + +EditorSettings *EditorPlugin::get_editor_settings() { + return EditorSettings::get_singleton(); +} + +EditorResourcePreview *EditorPlugin::get_resource_previewer() { + return EditorResourcePreview::get_singleton(); +} + +Control *EditorPlugin::get_base_control() { + + return EditorNode::get_singleton()->get_gui_base(); +} + +void EditorPlugin::make_bottom_panel_item_visible(Control * p_item) { + + EditorNode::get_singleton()->make_bottom_panel_item_visible(p_item); +} + +void EditorPlugin::hide_bottom_panel() { + + EditorNode::get_singleton()->hide_bottom_panel(); +} + +void EditorPlugin::inspect_object(Object *p_obj,const String& p_for_property) { + + EditorNode::get_singleton()->push_item(p_obj,p_for_property); +} + +EditorFileSystem *EditorPlugin::get_resource_file_system() { + return EditorFileSystem::get_singleton(); +} + +void EditorPlugin::_bind_methods() { + + ClassDB::bind_method(D_METHOD("add_control_to_container","container","control:Control"),&EditorPlugin::add_control_to_container); + ClassDB::bind_method(D_METHOD("add_control_to_bottom_panel:ToolButton","control:Control","title"),&EditorPlugin::add_control_to_bottom_panel); + ClassDB::bind_method(D_METHOD("add_control_to_dock","slot","control:Control"),&EditorPlugin::add_control_to_dock); + ClassDB::bind_method(D_METHOD("remove_control_from_docks","control:Control"),&EditorPlugin::remove_control_from_docks); + ClassDB::bind_method(D_METHOD("remove_control_from_bottom_panel","control:Control"),&EditorPlugin::remove_control_from_bottom_panel); + //ClassDB::bind_method(D_METHOD("add_tool_menu_item", "name", "handler", "callback", "ud"),&EditorPlugin::add_tool_menu_item,DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("add_tool_submenu_item", "name", "submenu:PopupMenu"),&EditorPlugin::add_tool_submenu_item); + //ClassDB::bind_method(D_METHOD("remove_tool_menu_item", "name"),&EditorPlugin::remove_tool_menu_item); + ClassDB::bind_method(D_METHOD("add_custom_type","type","base","script:Script","icon:Texture"),&EditorPlugin::add_custom_type); + ClassDB::bind_method(D_METHOD("remove_custom_type","type"),&EditorPlugin::remove_custom_type); + ClassDB::bind_method(D_METHOD("get_editor_viewport:Control"), &EditorPlugin::get_editor_viewport); + + ClassDB::bind_method(D_METHOD("get_resource_previewer:EditorResourcePreview"),&EditorPlugin::get_resource_previewer); + ClassDB::bind_method(D_METHOD("get_resource_filesystem:EditorFileSystem"),&EditorPlugin::get_resource_file_system); + + ClassDB::bind_method(D_METHOD("inspect_object","object","for_property"),&EditorPlugin::inspect_object,DEFVAL(String())); + ClassDB::bind_method(D_METHOD("update_canvas"),&EditorPlugin::update_canvas); + + ClassDB::bind_method(D_METHOD("make_bottom_panel_item_visible","item:Control"), &EditorPlugin::make_bottom_panel_item_visible); + ClassDB::bind_method(D_METHOD("hide_bottom_panel"), &EditorPlugin::hide_bottom_panel); + + ClassDB::bind_method(D_METHOD("get_base_control:Control"),&EditorPlugin::get_base_control); + ClassDB::bind_method(D_METHOD("get_undo_redo:UndoRedo"),&EditorPlugin::_get_undo_redo); + ClassDB::bind_method(D_METHOD("get_selection:EditorSelection"),&EditorPlugin::get_selection); + ClassDB::bind_method(D_METHOD("get_editor_settings:EditorSettings"),&EditorPlugin::get_editor_settings); + ClassDB::bind_method(D_METHOD("queue_save_layout"),&EditorPlugin::queue_save_layout); + ClassDB::bind_method(D_METHOD("edit_resource"),&EditorPlugin::edit_resource); + + ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::BOOL,"forward_canvas_gui_input",PropertyInfo(Variant::TRANSFORM2D,"canvas_xform"),PropertyInfo(Variant::INPUT_EVENT,"event"))); + ClassDB::add_virtual_method(get_class_static(),MethodInfo("forward_draw_over_canvas",PropertyInfo(Variant::TRANSFORM2D,"canvas_xform"),PropertyInfo(Variant::OBJECT,"canvas:Control"))); + ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::BOOL,"forward_spatial_gui_input",PropertyInfo(Variant::OBJECT,"camera",PROPERTY_HINT_RESOURCE_TYPE,"Camera"),PropertyInfo(Variant::INPUT_EVENT,"event"))); + MethodInfo gizmo = MethodInfo(Variant::OBJECT,"create_spatial_gizmo",PropertyInfo(Variant::OBJECT,"for_spatial:Spatial")); + gizmo.return_val.hint=PROPERTY_HINT_RESOURCE_TYPE; + gizmo.return_val.hint_string="EditorSpatialGizmo"; + ClassDB::add_virtual_method(get_class_static(),gizmo); + ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::STRING,"get_name")); + ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::BOOL,"has_main_screen")); + ClassDB::add_virtual_method(get_class_static(),MethodInfo("make_visible",PropertyInfo(Variant::BOOL,"visible"))); + ClassDB::add_virtual_method(get_class_static(),MethodInfo("edit",PropertyInfo(Variant::OBJECT,"object"))); + ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::BOOL,"handles",PropertyInfo(Variant::OBJECT,"object"))); + ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::DICTIONARY,"get_state")); + ClassDB::add_virtual_method(get_class_static(),MethodInfo("set_state",PropertyInfo(Variant::DICTIONARY,"state"))); + ClassDB::add_virtual_method(get_class_static(),MethodInfo("clear")); + ClassDB::add_virtual_method(get_class_static(),MethodInfo("save_external_data")); + ClassDB::add_virtual_method(get_class_static(),MethodInfo("apply_changes")); + ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::POOL_STRING_ARRAY,"get_breakpoints")); + ClassDB::add_virtual_method(get_class_static(),MethodInfo("set_window_layout",PropertyInfo(Variant::OBJECT,"layout",PROPERTY_HINT_RESOURCE_TYPE,"ConfigFile"))); + ClassDB::add_virtual_method(get_class_static(),MethodInfo("get_window_layout",PropertyInfo(Variant::OBJECT,"layout",PROPERTY_HINT_RESOURCE_TYPE,"ConfigFile"))); + + BIND_CONSTANT( CONTAINER_TOOLBAR ); + BIND_CONSTANT( CONTAINER_SPATIAL_EDITOR_MENU ); + BIND_CONSTANT( CONTAINER_SPATIAL_EDITOR_SIDE ); + BIND_CONSTANT( CONTAINER_SPATIAL_EDITOR_BOTTOM ); + BIND_CONSTANT( CONTAINER_CANVAS_EDITOR_MENU ); + BIND_CONSTANT( CONTAINER_CANVAS_EDITOR_SIDE ); + BIND_CONSTANT( CONTAINER_PROPERTY_EDITOR_BOTTOM ); + + + BIND_CONSTANT( DOCK_SLOT_LEFT_UL ); + BIND_CONSTANT( DOCK_SLOT_LEFT_BL ); + BIND_CONSTANT( DOCK_SLOT_LEFT_UR ); + BIND_CONSTANT( DOCK_SLOT_LEFT_BR ); + BIND_CONSTANT( DOCK_SLOT_RIGHT_UL ); + BIND_CONSTANT( DOCK_SLOT_RIGHT_BL ); + BIND_CONSTANT( DOCK_SLOT_RIGHT_UR ); + BIND_CONSTANT( DOCK_SLOT_RIGHT_BR ); + BIND_CONSTANT( DOCK_SLOT_MAX ); + +} + +EditorPlugin::EditorPlugin() +{ + undo_redo=NULL; +} + + +EditorPlugin::~EditorPlugin() +{ +} + + + +EditorPluginCreateFunc EditorPlugins::creation_funcs[MAX_CREATE_FUNCS]; + +int EditorPlugins::creation_func_count=0; diff --git a/tools/editor/editor_plugin.h b/editor/editor_plugin.h index 13d8ab0343..13d8ab0343 100644 --- a/tools/editor/editor_plugin.h +++ b/editor/editor_plugin.h diff --git a/tools/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp index 2d879e38cf..2d879e38cf 100644 --- a/tools/editor/editor_plugin_settings.cpp +++ b/editor/editor_plugin_settings.cpp diff --git a/tools/editor/editor_plugin_settings.h b/editor/editor_plugin_settings.h index e24880a21d..e24880a21d 100644 --- a/tools/editor/editor_plugin_settings.h +++ b/editor/editor_plugin_settings.h diff --git a/tools/editor/editor_profiler.cpp b/editor/editor_profiler.cpp index d9a4174246..d9a4174246 100644 --- a/tools/editor/editor_profiler.cpp +++ b/editor/editor_profiler.cpp diff --git a/tools/editor/editor_profiler.h b/editor/editor_profiler.h index bf89e3939c..bf89e3939c 100644 --- a/tools/editor/editor_profiler.h +++ b/editor/editor_profiler.h diff --git a/tools/editor/editor_reimport_dialog.cpp b/editor/editor_reimport_dialog.cpp index 5904070230..5904070230 100644 --- a/tools/editor/editor_reimport_dialog.cpp +++ b/editor/editor_reimport_dialog.cpp diff --git a/tools/editor/editor_reimport_dialog.h b/editor/editor_reimport_dialog.h index 7379c70c5e..7379c70c5e 100644 --- a/tools/editor/editor_reimport_dialog.h +++ b/editor/editor_reimport_dialog.h diff --git a/tools/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index ab2226e79a..ab2226e79a 100644 --- a/tools/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp diff --git a/tools/editor/editor_resource_preview.h b/editor/editor_resource_preview.h index e4a593330d..e4a593330d 100644 --- a/tools/editor/editor_resource_preview.h +++ b/editor/editor_resource_preview.h diff --git a/tools/editor/editor_run.cpp b/editor/editor_run.cpp index 46e400ae7f..46e400ae7f 100644 --- a/tools/editor/editor_run.cpp +++ b/editor/editor_run.cpp diff --git a/tools/editor/editor_run.h b/editor/editor_run.h index 46c5dc7521..46c5dc7521 100644 --- a/tools/editor/editor_run.h +++ b/editor/editor_run.h diff --git a/tools/editor/editor_run_native.cpp b/editor/editor_run_native.cpp index 60a9f53b94..60a9f53b94 100644 --- a/tools/editor/editor_run_native.cpp +++ b/editor/editor_run_native.cpp diff --git a/tools/editor/editor_run_native.h b/editor/editor_run_native.h index c62021148b..c62021148b 100644 --- a/tools/editor/editor_run_native.h +++ b/editor/editor_run_native.h diff --git a/tools/editor/editor_run_script.cpp b/editor/editor_run_script.cpp index 77dc7bd4bf..77dc7bd4bf 100644 --- a/tools/editor/editor_run_script.cpp +++ b/editor/editor_run_script.cpp diff --git a/tools/editor/editor_run_script.h b/editor/editor_run_script.h index 3ab8525cc6..3ab8525cc6 100644 --- a/tools/editor/editor_run_script.h +++ b/editor/editor_run_script.h diff --git a/tools/editor/editor_scale.cpp b/editor/editor_scale.cpp index 5687f97b22..5687f97b22 100644 --- a/tools/editor/editor_scale.cpp +++ b/editor/editor_scale.cpp diff --git a/tools/editor/editor_scale.h b/editor/editor_scale.h index 035a5056c1..035a5056c1 100644 --- a/tools/editor/editor_scale.h +++ b/editor/editor_scale.h diff --git a/tools/editor/editor_settings.cpp b/editor/editor_settings.cpp index f977a40243..f977a40243 100644 --- a/tools/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp diff --git a/tools/editor/editor_settings.h b/editor/editor_settings.h index 809389eb40..809389eb40 100644 --- a/tools/editor/editor_settings.h +++ b/editor/editor_settings.h diff --git a/tools/editor/editor_sub_scene.cpp b/editor/editor_sub_scene.cpp index 917560b540..917560b540 100644 --- a/tools/editor/editor_sub_scene.cpp +++ b/editor/editor_sub_scene.cpp diff --git a/editor/editor_sub_scene.h b/editor/editor_sub_scene.h new file mode 100644 index 0000000000..46cdceafa5 --- /dev/null +++ b/editor/editor_sub_scene.h @@ -0,0 +1,69 @@ +/*************************************************************************/ +/* editor_sub_scene.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITOR_SUB_SCENE_H +#define EDITOR_SUB_SCENE_H + +#include "scene/gui/dialogs.h" +#include "scene/gui/tree.h" +#include "editor/editor_file_dialog.h" + +class EditorSubScene : public ConfirmationDialog { + + GDCLASS(EditorSubScene,ConfirmationDialog); + + + LineEdit *path; + Tree *tree; + Node *scene; + + EditorFileDialog *file_dialog; + + void _fill_tree(Node* p_node,TreeItem *p_parent); + void _reown(Node* p_node,List<Node*> *p_to_reown); + + void ok_pressed(); + + +protected: + + + void _notification(int p_what); + static void _bind_methods(); + void _path_browse(); + void _path_selected(const String& p_path); + void _path_changed(const String& p_path); + +public: + + void move(Node* p_new_parent, Node* p_new_owner); + void clear(); + EditorSubScene(); +}; + +#endif // EDITOR_SUB_SCENE_H diff --git a/tools/editor/editor_themes.cpp b/editor/editor_themes.cpp index 7657996b81..7657996b81 100644 --- a/tools/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp diff --git a/tools/editor/editor_themes.h b/editor/editor_themes.h index bf15420917..bf15420917 100644 --- a/tools/editor/editor_themes.h +++ b/editor/editor_themes.h diff --git a/tools/editor/file_type_cache.cpp b/editor/file_type_cache.cpp index 891669db13..891669db13 100644 --- a/tools/editor/file_type_cache.cpp +++ b/editor/file_type_cache.cpp diff --git a/tools/editor/file_type_cache.h b/editor/file_type_cache.h index 25755f168c..25755f168c 100644 --- a/tools/editor/file_type_cache.h +++ b/editor/file_type_cache.h diff --git a/tools/editor/fileserver/SCsub b/editor/fileserver/SCsub index f1fa50148f..f1fa50148f 100644 --- a/tools/editor/fileserver/SCsub +++ b/editor/fileserver/SCsub diff --git a/tools/editor/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp index 2e5dbf6248..2e5dbf6248 100644 --- a/tools/editor/fileserver/editor_file_server.cpp +++ b/editor/fileserver/editor_file_server.cpp diff --git a/tools/editor/fileserver/editor_file_server.h b/editor/fileserver/editor_file_server.h index 31f8ae84b8..31f8ae84b8 100644 --- a/tools/editor/fileserver/editor_file_server.h +++ b/editor/fileserver/editor_file_server.h diff --git a/tools/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index bce0e9148a..bce0e9148a 100644 --- a/tools/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp diff --git a/tools/editor/filesystem_dock.h b/editor/filesystem_dock.h index 916321d8fd..916321d8fd 100644 --- a/tools/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h diff --git a/tools/editor/groups_editor.cpp b/editor/groups_editor.cpp index 90f0bab6dd..90f0bab6dd 100644 --- a/tools/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp diff --git a/tools/editor/groups_editor.h b/editor/groups_editor.h index 9ab75c6cfd..9ab75c6cfd 100644 --- a/tools/editor/groups_editor.h +++ b/editor/groups_editor.h diff --git a/tools/editor/icons/2x/icon_accept_dialog.png b/editor/icons/2x/icon_accept_dialog.png Binary files differindex fca344aefc..fca344aefc 100644 --- a/tools/editor/icons/2x/icon_accept_dialog.png +++ b/editor/icons/2x/icon_accept_dialog.png diff --git a/tools/editor/icons/2x/icon_add.png b/editor/icons/2x/icon_add.png Binary files differindex a46c521f2a..a46c521f2a 100644 --- a/tools/editor/icons/2x/icon_add.png +++ b/editor/icons/2x/icon_add.png diff --git a/tools/editor/icons/2x/icon_add_track.png b/editor/icons/2x/icon_add_track.png Binary files differindex a46c521f2a..a46c521f2a 100644 --- a/tools/editor/icons/2x/icon_add_track.png +++ b/editor/icons/2x/icon_add_track.png diff --git a/tools/editor/icons/2x/icon_anchor.png b/editor/icons/2x/icon_anchor.png Binary files differindex 7e9e259c13..7e9e259c13 100644 --- a/tools/editor/icons/2x/icon_anchor.png +++ b/editor/icons/2x/icon_anchor.png diff --git a/tools/editor/icons/2x/icon_animated_sprite.png b/editor/icons/2x/icon_animated_sprite.png Binary files differindex 461dac8f13..461dac8f13 100644 --- a/tools/editor/icons/2x/icon_animated_sprite.png +++ b/editor/icons/2x/icon_animated_sprite.png diff --git a/tools/editor/icons/2x/icon_animated_sprite_3d.png b/editor/icons/2x/icon_animated_sprite_3d.png Binary files differindex 6c79c38875..6c79c38875 100644 --- a/tools/editor/icons/2x/icon_animated_sprite_3d.png +++ b/editor/icons/2x/icon_animated_sprite_3d.png diff --git a/tools/editor/icons/2x/icon_animation.png b/editor/icons/2x/icon_animation.png Binary files differindex ef18959a74..ef18959a74 100644 --- a/tools/editor/icons/2x/icon_animation.png +++ b/editor/icons/2x/icon_animation.png diff --git a/tools/editor/icons/2x/icon_animation_player.png b/editor/icons/2x/icon_animation_player.png Binary files differindex 4a3209ab70..4a3209ab70 100644 --- a/tools/editor/icons/2x/icon_animation_player.png +++ b/editor/icons/2x/icon_animation_player.png diff --git a/tools/editor/icons/2x/icon_animation_tree.png b/editor/icons/2x/icon_animation_tree.png Binary files differindex a213ab6e5e..a213ab6e5e 100644 --- a/tools/editor/icons/2x/icon_animation_tree.png +++ b/editor/icons/2x/icon_animation_tree.png diff --git a/tools/editor/icons/2x/icon_animation_tree_player.png b/editor/icons/2x/icon_animation_tree_player.png Binary files differindex a213ab6e5e..a213ab6e5e 100644 --- a/tools/editor/icons/2x/icon_animation_tree_player.png +++ b/editor/icons/2x/icon_animation_tree_player.png diff --git a/tools/editor/icons/2x/icon_area.png b/editor/icons/2x/icon_area.png Binary files differindex d9cefe8fc4..d9cefe8fc4 100644 --- a/tools/editor/icons/2x/icon_area.png +++ b/editor/icons/2x/icon_area.png diff --git a/tools/editor/icons/2x/icon_area_2d.png b/editor/icons/2x/icon_area_2d.png Binary files differindex 22616cc754..22616cc754 100644 --- a/tools/editor/icons/2x/icon_area_2d.png +++ b/editor/icons/2x/icon_area_2d.png diff --git a/tools/editor/icons/2x/icon_arrow_left.png b/editor/icons/2x/icon_arrow_left.png Binary files differindex bc3995f70b..bc3995f70b 100644 --- a/tools/editor/icons/2x/icon_arrow_left.png +++ b/editor/icons/2x/icon_arrow_left.png diff --git a/tools/editor/icons/2x/icon_arrow_right.png b/editor/icons/2x/icon_arrow_right.png Binary files differindex 045b390e0d..045b390e0d 100644 --- a/tools/editor/icons/2x/icon_arrow_right.png +++ b/editor/icons/2x/icon_arrow_right.png diff --git a/tools/editor/icons/2x/icon_arrow_up.png b/editor/icons/2x/icon_arrow_up.png Binary files differindex 524ab934e2..524ab934e2 100644 --- a/tools/editor/icons/2x/icon_arrow_up.png +++ b/editor/icons/2x/icon_arrow_up.png diff --git a/tools/editor/icons/2x/icon_atlas_texture.png b/editor/icons/2x/icon_atlas_texture.png Binary files differindex bd5bdc3148..bd5bdc3148 100644 --- a/tools/editor/icons/2x/icon_atlas_texture.png +++ b/editor/icons/2x/icon_atlas_texture.png diff --git a/tools/editor/icons/2x/icon_audio_stream_gibberish.png b/editor/icons/2x/icon_audio_stream_gibberish.png Binary files differindex da200740a4..da200740a4 100644 --- a/tools/editor/icons/2x/icon_audio_stream_gibberish.png +++ b/editor/icons/2x/icon_audio_stream_gibberish.png diff --git a/tools/editor/icons/2x/icon_auto_play.png b/editor/icons/2x/icon_auto_play.png Binary files differindex ec31dee958..ec31dee958 100644 --- a/tools/editor/icons/2x/icon_auto_play.png +++ b/editor/icons/2x/icon_auto_play.png diff --git a/tools/editor/icons/2x/icon_back.png b/editor/icons/2x/icon_back.png Binary files differindex 648c440928..648c440928 100644 --- a/tools/editor/icons/2x/icon_back.png +++ b/editor/icons/2x/icon_back.png diff --git a/tools/editor/icons/2x/icon_back_buffer_copy.png b/editor/icons/2x/icon_back_buffer_copy.png Binary files differindex 8b5c37b7e5..8b5c37b7e5 100644 --- a/tools/editor/icons/2x/icon_back_buffer_copy.png +++ b/editor/icons/2x/icon_back_buffer_copy.png diff --git a/tools/editor/icons/2x/icon_bake.png b/editor/icons/2x/icon_bake.png Binary files differindex 3c1cba5586..3c1cba5586 100644 --- a/tools/editor/icons/2x/icon_bake.png +++ b/editor/icons/2x/icon_bake.png diff --git a/tools/editor/icons/2x/icon_baked_light.png b/editor/icons/2x/icon_baked_light.png Binary files differindex 3c1cba5586..3c1cba5586 100644 --- a/tools/editor/icons/2x/icon_baked_light.png +++ b/editor/icons/2x/icon_baked_light.png diff --git a/tools/editor/icons/2x/icon_baked_light_instance.png b/editor/icons/2x/icon_baked_light_instance.png Binary files differindex 9b13ed8ff1..9b13ed8ff1 100644 --- a/tools/editor/icons/2x/icon_baked_light_instance.png +++ b/editor/icons/2x/icon_baked_light_instance.png diff --git a/tools/editor/icons/2x/icon_baked_light_sampler.png b/editor/icons/2x/icon_baked_light_sampler.png Binary files differindex 8dfc1793f1..8dfc1793f1 100644 --- a/tools/editor/icons/2x/icon_baked_light_sampler.png +++ b/editor/icons/2x/icon_baked_light_sampler.png diff --git a/tools/editor/icons/2x/icon_bit_map.png b/editor/icons/2x/icon_bit_map.png Binary files differindex 7372b85944..7372b85944 100644 --- a/tools/editor/icons/2x/icon_bit_map.png +++ b/editor/icons/2x/icon_bit_map.png diff --git a/tools/editor/icons/2x/icon_bitmap_font.png b/editor/icons/2x/icon_bitmap_font.png Binary files differindex c533b5f40e..c533b5f40e 100644 --- a/tools/editor/icons/2x/icon_bitmap_font.png +++ b/editor/icons/2x/icon_bitmap_font.png diff --git a/tools/editor/icons/2x/icon_blend.png b/editor/icons/2x/icon_blend.png Binary files differindex 8dd30d1a04..8dd30d1a04 100644 --- a/tools/editor/icons/2x/icon_blend.png +++ b/editor/icons/2x/icon_blend.png diff --git a/tools/editor/icons/2x/icon_bone.png b/editor/icons/2x/icon_bone.png Binary files differindex 0a8ceb4ce1..0a8ceb4ce1 100644 --- a/tools/editor/icons/2x/icon_bone.png +++ b/editor/icons/2x/icon_bone.png diff --git a/tools/editor/icons/2x/icon_bone_attachment.png b/editor/icons/2x/icon_bone_attachment.png Binary files differindex 4e9333d3d1..4e9333d3d1 100644 --- a/tools/editor/icons/2x/icon_bone_attachment.png +++ b/editor/icons/2x/icon_bone_attachment.png diff --git a/tools/editor/icons/2x/icon_bone_track.png b/editor/icons/2x/icon_bone_track.png Binary files differindex a956923a07..a956923a07 100644 --- a/tools/editor/icons/2x/icon_bone_track.png +++ b/editor/icons/2x/icon_bone_track.png diff --git a/tools/editor/icons/2x/icon_bool.png b/editor/icons/2x/icon_bool.png Binary files differindex 47103538bd..47103538bd 100644 --- a/tools/editor/icons/2x/icon_bool.png +++ b/editor/icons/2x/icon_bool.png diff --git a/tools/editor/icons/2x/icon_box_shape.png b/editor/icons/2x/icon_box_shape.png Binary files differindex 7d5356ad94..7d5356ad94 100644 --- a/tools/editor/icons/2x/icon_box_shape.png +++ b/editor/icons/2x/icon_box_shape.png diff --git a/tools/editor/icons/2x/icon_button.png b/editor/icons/2x/icon_button.png Binary files differindex 210b0da486..210b0da486 100644 --- a/tools/editor/icons/2x/icon_button.png +++ b/editor/icons/2x/icon_button.png diff --git a/tools/editor/icons/2x/icon_button_group.png b/editor/icons/2x/icon_button_group.png Binary files differindex 47f62005b9..47f62005b9 100644 --- a/tools/editor/icons/2x/icon_button_group.png +++ b/editor/icons/2x/icon_button_group.png diff --git a/tools/editor/icons/2x/icon_camera.png b/editor/icons/2x/icon_camera.png Binary files differindex ea17779784..ea17779784 100644 --- a/tools/editor/icons/2x/icon_camera.png +++ b/editor/icons/2x/icon_camera.png diff --git a/tools/editor/icons/2x/icon_camera_2d.png b/editor/icons/2x/icon_camera_2d.png Binary files differindex c5c881c435..c5c881c435 100644 --- a/tools/editor/icons/2x/icon_camera_2d.png +++ b/editor/icons/2x/icon_camera_2d.png diff --git a/tools/editor/icons/2x/icon_canvas_item.png b/editor/icons/2x/icon_canvas_item.png Binary files differindex 42863020f0..42863020f0 100644 --- a/tools/editor/icons/2x/icon_canvas_item.png +++ b/editor/icons/2x/icon_canvas_item.png diff --git a/tools/editor/icons/2x/icon_canvas_item_material.png b/editor/icons/2x/icon_canvas_item_material.png Binary files differindex a9f7948060..a9f7948060 100644 --- a/tools/editor/icons/2x/icon_canvas_item_material.png +++ b/editor/icons/2x/icon_canvas_item_material.png diff --git a/tools/editor/icons/2x/icon_canvas_item_shader.png b/editor/icons/2x/icon_canvas_item_shader.png Binary files differindex 5091a947c0..5091a947c0 100644 --- a/tools/editor/icons/2x/icon_canvas_item_shader.png +++ b/editor/icons/2x/icon_canvas_item_shader.png diff --git a/tools/editor/icons/2x/icon_canvas_item_shader_graph.png b/editor/icons/2x/icon_canvas_item_shader_graph.png Binary files differindex a26a9754fe..a26a9754fe 100644 --- a/tools/editor/icons/2x/icon_canvas_item_shader_graph.png +++ b/editor/icons/2x/icon_canvas_item_shader_graph.png diff --git a/tools/editor/icons/2x/icon_canvas_layer.png b/editor/icons/2x/icon_canvas_layer.png Binary files differindex 8a4b31cd7d..8a4b31cd7d 100644 --- a/tools/editor/icons/2x/icon_canvas_layer.png +++ b/editor/icons/2x/icon_canvas_layer.png diff --git a/tools/editor/icons/2x/icon_canvas_modulate.png b/editor/icons/2x/icon_canvas_modulate.png Binary files differindex 6cc15e2655..6cc15e2655 100644 --- a/tools/editor/icons/2x/icon_canvas_modulate.png +++ b/editor/icons/2x/icon_canvas_modulate.png diff --git a/tools/editor/icons/2x/icon_capsule_shape.png b/editor/icons/2x/icon_capsule_shape.png Binary files differindex f8844ecef4..f8844ecef4 100644 --- a/tools/editor/icons/2x/icon_capsule_shape.png +++ b/editor/icons/2x/icon_capsule_shape.png diff --git a/tools/editor/icons/2x/icon_capsule_shape_2d.png b/editor/icons/2x/icon_capsule_shape_2d.png Binary files differindex e449ce4985..e449ce4985 100644 --- a/tools/editor/icons/2x/icon_capsule_shape_2d.png +++ b/editor/icons/2x/icon_capsule_shape_2d.png diff --git a/tools/editor/icons/2x/icon_center_container.png b/editor/icons/2x/icon_center_container.png Binary files differindex c715f0959e..c715f0959e 100644 --- a/tools/editor/icons/2x/icon_center_container.png +++ b/editor/icons/2x/icon_center_container.png diff --git a/tools/editor/icons/2x/icon_check_box.png b/editor/icons/2x/icon_check_box.png Binary files differindex bade572304..bade572304 100644 --- a/tools/editor/icons/2x/icon_check_box.png +++ b/editor/icons/2x/icon_check_box.png diff --git a/tools/editor/icons/2x/icon_check_button.png b/editor/icons/2x/icon_check_button.png Binary files differindex 4f498bb9ad..4f498bb9ad 100644 --- a/tools/editor/icons/2x/icon_check_button.png +++ b/editor/icons/2x/icon_check_button.png diff --git a/tools/editor/icons/2x/icon_circle_shape_2d.png b/editor/icons/2x/icon_circle_shape_2d.png Binary files differindex feb84d2f1c..feb84d2f1c 100644 --- a/tools/editor/icons/2x/icon_circle_shape_2d.png +++ b/editor/icons/2x/icon_circle_shape_2d.png diff --git a/tools/editor/icons/2x/icon_class_list.png b/editor/icons/2x/icon_class_list.png Binary files differindex 4ae0b3edab..4ae0b3edab 100644 --- a/tools/editor/icons/2x/icon_class_list.png +++ b/editor/icons/2x/icon_class_list.png diff --git a/tools/editor/icons/2x/icon_close.png b/editor/icons/2x/icon_close.png Binary files differindex 62ab763fec..62ab763fec 100644 --- a/tools/editor/icons/2x/icon_close.png +++ b/editor/icons/2x/icon_close.png diff --git a/tools/editor/icons/2x/icon_collapse.png b/editor/icons/2x/icon_collapse.png Binary files differindex 18486c03f5..18486c03f5 100644 --- a/tools/editor/icons/2x/icon_collapse.png +++ b/editor/icons/2x/icon_collapse.png diff --git a/tools/editor/icons/2x/icon_collision_2d.png b/editor/icons/2x/icon_collision_2d.png Binary files differindex 491ebfaa78..491ebfaa78 100644 --- a/tools/editor/icons/2x/icon_collision_2d.png +++ b/editor/icons/2x/icon_collision_2d.png diff --git a/tools/editor/icons/2x/icon_collision_polygon.png b/editor/icons/2x/icon_collision_polygon.png Binary files differindex ef786f6a3d..ef786f6a3d 100644 --- a/tools/editor/icons/2x/icon_collision_polygon.png +++ b/editor/icons/2x/icon_collision_polygon.png diff --git a/tools/editor/icons/2x/icon_collision_polygon_2d.png b/editor/icons/2x/icon_collision_polygon_2d.png Binary files differindex 491ebfaa78..491ebfaa78 100644 --- a/tools/editor/icons/2x/icon_collision_polygon_2d.png +++ b/editor/icons/2x/icon_collision_polygon_2d.png diff --git a/tools/editor/icons/2x/icon_collision_shape.png b/editor/icons/2x/icon_collision_shape.png Binary files differindex 23bec8cdd9..23bec8cdd9 100644 --- a/tools/editor/icons/2x/icon_collision_shape.png +++ b/editor/icons/2x/icon_collision_shape.png diff --git a/tools/editor/icons/2x/icon_collision_shape_2d.png b/editor/icons/2x/icon_collision_shape_2d.png Binary files differindex c91456b58e..c91456b58e 100644 --- a/tools/editor/icons/2x/icon_collision_shape_2d.png +++ b/editor/icons/2x/icon_collision_shape_2d.png diff --git a/tools/editor/icons/2x/icon_color.png b/editor/icons/2x/icon_color.png Binary files differindex 125dd86ec0..125dd86ec0 100644 --- a/tools/editor/icons/2x/icon_color.png +++ b/editor/icons/2x/icon_color.png diff --git a/tools/editor/icons/2x/icon_color_pick.png b/editor/icons/2x/icon_color_pick.png Binary files differindex c61f2d4174..c61f2d4174 100644 --- a/tools/editor/icons/2x/icon_color_pick.png +++ b/editor/icons/2x/icon_color_pick.png diff --git a/tools/editor/icons/2x/icon_color_picker.png b/editor/icons/2x/icon_color_picker.png Binary files differindex 2b683c75ea..2b683c75ea 100644 --- a/tools/editor/icons/2x/icon_color_picker.png +++ b/editor/icons/2x/icon_color_picker.png diff --git a/tools/editor/icons/2x/icon_color_picker_button.png b/editor/icons/2x/icon_color_picker_button.png Binary files differindex 8d9bd17ccc..8d9bd17ccc 100644 --- a/tools/editor/icons/2x/icon_color_picker_button.png +++ b/editor/icons/2x/icon_color_picker_button.png diff --git a/tools/editor/icons/2x/icon_color_ramp.png b/editor/icons/2x/icon_color_ramp.png Binary files differindex d0056f0c7d..d0056f0c7d 100644 --- a/tools/editor/icons/2x/icon_color_ramp.png +++ b/editor/icons/2x/icon_color_ramp.png diff --git a/tools/editor/icons/2x/icon_color_rect.png b/editor/icons/2x/icon_color_rect.png Binary files differindex 153029ac20..153029ac20 100644 --- a/tools/editor/icons/2x/icon_color_rect.png +++ b/editor/icons/2x/icon_color_rect.png diff --git a/tools/editor/icons/2x/icon_concave_polygon_shape.png b/editor/icons/2x/icon_concave_polygon_shape.png Binary files differindex 82a67ca4d0..82a67ca4d0 100644 --- a/tools/editor/icons/2x/icon_concave_polygon_shape.png +++ b/editor/icons/2x/icon_concave_polygon_shape.png diff --git a/tools/editor/icons/2x/icon_concave_polygon_shape_2d.png b/editor/icons/2x/icon_concave_polygon_shape_2d.png Binary files differindex 1ad3f30950..1ad3f30950 100644 --- a/tools/editor/icons/2x/icon_concave_polygon_shape_2d.png +++ b/editor/icons/2x/icon_concave_polygon_shape_2d.png diff --git a/tools/editor/icons/2x/icon_cone_twist_joint.png b/editor/icons/2x/icon_cone_twist_joint.png Binary files differindex 3aeba5855d..3aeba5855d 100644 --- a/tools/editor/icons/2x/icon_cone_twist_joint.png +++ b/editor/icons/2x/icon_cone_twist_joint.png diff --git a/tools/editor/icons/2x/icon_confirmation_dialog.png b/editor/icons/2x/icon_confirmation_dialog.png Binary files differindex a0df7fcd1e..a0df7fcd1e 100644 --- a/tools/editor/icons/2x/icon_confirmation_dialog.png +++ b/editor/icons/2x/icon_confirmation_dialog.png diff --git a/tools/editor/icons/2x/icon_connect.png b/editor/icons/2x/icon_connect.png Binary files differindex e3f4b8fd12..e3f4b8fd12 100644 --- a/tools/editor/icons/2x/icon_connect.png +++ b/editor/icons/2x/icon_connect.png diff --git a/tools/editor/icons/2x/icon_connection_and_groups.png b/editor/icons/2x/icon_connection_and_groups.png Binary files differindex e7619327f6..e7619327f6 100644 --- a/tools/editor/icons/2x/icon_connection_and_groups.png +++ b/editor/icons/2x/icon_connection_and_groups.png diff --git a/tools/editor/icons/2x/icon_container.png b/editor/icons/2x/icon_container.png Binary files differindex baa09bbea9..baa09bbea9 100644 --- a/tools/editor/icons/2x/icon_container.png +++ b/editor/icons/2x/icon_container.png diff --git a/tools/editor/icons/2x/icon_control.png b/editor/icons/2x/icon_control.png Binary files differindex 82d7457f3b..82d7457f3b 100644 --- a/tools/editor/icons/2x/icon_control.png +++ b/editor/icons/2x/icon_control.png diff --git a/tools/editor/icons/2x/icon_control_align_bottom_center.png b/editor/icons/2x/icon_control_align_bottom_center.png Binary files differindex 9dc738c746..9dc738c746 100644 --- a/tools/editor/icons/2x/icon_control_align_bottom_center.png +++ b/editor/icons/2x/icon_control_align_bottom_center.png diff --git a/tools/editor/icons/2x/icon_control_align_bottom_left.png b/editor/icons/2x/icon_control_align_bottom_left.png Binary files differindex a11a13528d..a11a13528d 100644 --- a/tools/editor/icons/2x/icon_control_align_bottom_left.png +++ b/editor/icons/2x/icon_control_align_bottom_left.png diff --git a/tools/editor/icons/2x/icon_control_align_bottom_right.png b/editor/icons/2x/icon_control_align_bottom_right.png Binary files differindex 7fee3f0752..7fee3f0752 100644 --- a/tools/editor/icons/2x/icon_control_align_bottom_right.png +++ b/editor/icons/2x/icon_control_align_bottom_right.png diff --git a/tools/editor/icons/2x/icon_control_align_bottom_wide.png b/editor/icons/2x/icon_control_align_bottom_wide.png Binary files differindex 573619ccbb..573619ccbb 100644 --- a/tools/editor/icons/2x/icon_control_align_bottom_wide.png +++ b/editor/icons/2x/icon_control_align_bottom_wide.png diff --git a/tools/editor/icons/2x/icon_control_align_center.png b/editor/icons/2x/icon_control_align_center.png Binary files differindex 9850ecd775..9850ecd775 100644 --- a/tools/editor/icons/2x/icon_control_align_center.png +++ b/editor/icons/2x/icon_control_align_center.png diff --git a/tools/editor/icons/2x/icon_control_align_center_left.png b/editor/icons/2x/icon_control_align_center_left.png Binary files differindex 2c48b889ad..2c48b889ad 100644 --- a/tools/editor/icons/2x/icon_control_align_center_left.png +++ b/editor/icons/2x/icon_control_align_center_left.png diff --git a/tools/editor/icons/2x/icon_control_align_center_right.png b/editor/icons/2x/icon_control_align_center_right.png Binary files differindex 4f87a68ad3..4f87a68ad3 100644 --- a/tools/editor/icons/2x/icon_control_align_center_right.png +++ b/editor/icons/2x/icon_control_align_center_right.png diff --git a/tools/editor/icons/2x/icon_control_align_left_center.png b/editor/icons/2x/icon_control_align_left_center.png Binary files differindex c4250dcb37..c4250dcb37 100644 --- a/tools/editor/icons/2x/icon_control_align_left_center.png +++ b/editor/icons/2x/icon_control_align_left_center.png diff --git a/tools/editor/icons/2x/icon_control_align_left_wide.png b/editor/icons/2x/icon_control_align_left_wide.png Binary files differindex 5436397189..5436397189 100644 --- a/tools/editor/icons/2x/icon_control_align_left_wide.png +++ b/editor/icons/2x/icon_control_align_left_wide.png diff --git a/tools/editor/icons/2x/icon_control_align_right_center.png b/editor/icons/2x/icon_control_align_right_center.png Binary files differindex b1fd9a075d..b1fd9a075d 100644 --- a/tools/editor/icons/2x/icon_control_align_right_center.png +++ b/editor/icons/2x/icon_control_align_right_center.png diff --git a/tools/editor/icons/2x/icon_control_align_right_wide.png b/editor/icons/2x/icon_control_align_right_wide.png Binary files differindex 0ce81d3a50..0ce81d3a50 100644 --- a/tools/editor/icons/2x/icon_control_align_right_wide.png +++ b/editor/icons/2x/icon_control_align_right_wide.png diff --git a/tools/editor/icons/2x/icon_control_align_top_center.png b/editor/icons/2x/icon_control_align_top_center.png Binary files differindex baa2601531..baa2601531 100644 --- a/tools/editor/icons/2x/icon_control_align_top_center.png +++ b/editor/icons/2x/icon_control_align_top_center.png diff --git a/tools/editor/icons/2x/icon_control_align_top_left.png b/editor/icons/2x/icon_control_align_top_left.png Binary files differindex 90f3cb6105..90f3cb6105 100644 --- a/tools/editor/icons/2x/icon_control_align_top_left.png +++ b/editor/icons/2x/icon_control_align_top_left.png diff --git a/tools/editor/icons/2x/icon_control_align_top_right.png b/editor/icons/2x/icon_control_align_top_right.png Binary files differindex 040b7b27ee..040b7b27ee 100644 --- a/tools/editor/icons/2x/icon_control_align_top_right.png +++ b/editor/icons/2x/icon_control_align_top_right.png diff --git a/tools/editor/icons/2x/icon_control_align_top_wide.png b/editor/icons/2x/icon_control_align_top_wide.png Binary files differindex 5c14782fc2..5c14782fc2 100644 --- a/tools/editor/icons/2x/icon_control_align_top_wide.png +++ b/editor/icons/2x/icon_control_align_top_wide.png diff --git a/tools/editor/icons/2x/icon_control_align_wide.png b/editor/icons/2x/icon_control_align_wide.png Binary files differindex 383b63d069..383b63d069 100644 --- a/tools/editor/icons/2x/icon_control_align_wide.png +++ b/editor/icons/2x/icon_control_align_wide.png diff --git a/tools/editor/icons/2x/icon_control_hcenter_wide.png b/editor/icons/2x/icon_control_hcenter_wide.png Binary files differindex 840ac557f5..840ac557f5 100644 --- a/tools/editor/icons/2x/icon_control_hcenter_wide.png +++ b/editor/icons/2x/icon_control_hcenter_wide.png diff --git a/tools/editor/icons/2x/icon_control_vcenter_wide.png b/editor/icons/2x/icon_control_vcenter_wide.png Binary files differindex a9e406d4b5..a9e406d4b5 100644 --- a/tools/editor/icons/2x/icon_control_vcenter_wide.png +++ b/editor/icons/2x/icon_control_vcenter_wide.png diff --git a/tools/editor/icons/2x/icon_convex_polygon_shape.png b/editor/icons/2x/icon_convex_polygon_shape.png Binary files differindex 40dd40f299..40dd40f299 100644 --- a/tools/editor/icons/2x/icon_convex_polygon_shape.png +++ b/editor/icons/2x/icon_convex_polygon_shape.png diff --git a/tools/editor/icons/2x/icon_convex_polygon_shape_2d.png b/editor/icons/2x/icon_convex_polygon_shape_2d.png Binary files differindex 6d46a96f9d..6d46a96f9d 100644 --- a/tools/editor/icons/2x/icon_convex_polygon_shape_2d.png +++ b/editor/icons/2x/icon_convex_polygon_shape_2d.png diff --git a/tools/editor/icons/2x/icon_copy_node_path.png b/editor/icons/2x/icon_copy_node_path.png Binary files differindex 056748d20b..056748d20b 100644 --- a/tools/editor/icons/2x/icon_copy_node_path.png +++ b/editor/icons/2x/icon_copy_node_path.png diff --git a/tools/editor/icons/2x/icon_create_new_scene_from.png b/editor/icons/2x/icon_create_new_scene_from.png Binary files differindex cc3be48033..cc3be48033 100644 --- a/tools/editor/icons/2x/icon_create_new_scene_from.png +++ b/editor/icons/2x/icon_create_new_scene_from.png diff --git a/tools/editor/icons/2x/icon_cube_map.png b/editor/icons/2x/icon_cube_map.png Binary files differindex 0edf82a88e..0edf82a88e 100644 --- a/tools/editor/icons/2x/icon_cube_map.png +++ b/editor/icons/2x/icon_cube_map.png diff --git a/tools/editor/icons/2x/icon_curve_2d.png b/editor/icons/2x/icon_curve_2d.png Binary files differindex 69a6f9a9dc..69a6f9a9dc 100644 --- a/tools/editor/icons/2x/icon_curve_2d.png +++ b/editor/icons/2x/icon_curve_2d.png diff --git a/tools/editor/icons/2x/icon_curve_3d.png b/editor/icons/2x/icon_curve_3d.png Binary files differindex e989df4769..e989df4769 100644 --- a/tools/editor/icons/2x/icon_curve_3d.png +++ b/editor/icons/2x/icon_curve_3d.png diff --git a/tools/editor/icons/2x/icon_curve_close.png b/editor/icons/2x/icon_curve_close.png Binary files differindex bd2de0edc8..bd2de0edc8 100644 --- a/tools/editor/icons/2x/icon_curve_close.png +++ b/editor/icons/2x/icon_curve_close.png diff --git a/tools/editor/icons/2x/icon_curve_constant.png b/editor/icons/2x/icon_curve_constant.png Binary files differindex a6e32e0467..a6e32e0467 100644 --- a/tools/editor/icons/2x/icon_curve_constant.png +++ b/editor/icons/2x/icon_curve_constant.png diff --git a/tools/editor/icons/2x/icon_curve_create.png b/editor/icons/2x/icon_curve_create.png Binary files differindex 39f10fd8db..39f10fd8db 100644 --- a/tools/editor/icons/2x/icon_curve_create.png +++ b/editor/icons/2x/icon_curve_create.png diff --git a/tools/editor/icons/2x/icon_curve_curve.png b/editor/icons/2x/icon_curve_curve.png Binary files differindex 6476579a64..6476579a64 100644 --- a/tools/editor/icons/2x/icon_curve_curve.png +++ b/editor/icons/2x/icon_curve_curve.png diff --git a/tools/editor/icons/2x/icon_curve_delete.png b/editor/icons/2x/icon_curve_delete.png Binary files differindex 60c081bbd0..60c081bbd0 100644 --- a/tools/editor/icons/2x/icon_curve_delete.png +++ b/editor/icons/2x/icon_curve_delete.png diff --git a/tools/editor/icons/2x/icon_curve_edit.png b/editor/icons/2x/icon_curve_edit.png Binary files differindex f9701e05cb..f9701e05cb 100644 --- a/tools/editor/icons/2x/icon_curve_edit.png +++ b/editor/icons/2x/icon_curve_edit.png diff --git a/tools/editor/icons/2x/icon_curve_in.png b/editor/icons/2x/icon_curve_in.png Binary files differindex a018d28035..a018d28035 100644 --- a/tools/editor/icons/2x/icon_curve_in.png +++ b/editor/icons/2x/icon_curve_in.png diff --git a/tools/editor/icons/2x/icon_curve_in_out.png b/editor/icons/2x/icon_curve_in_out.png Binary files differindex 8b8b8d7d8a..8b8b8d7d8a 100644 --- a/tools/editor/icons/2x/icon_curve_in_out.png +++ b/editor/icons/2x/icon_curve_in_out.png diff --git a/tools/editor/icons/2x/icon_curve_linear.png b/editor/icons/2x/icon_curve_linear.png Binary files differindex 9733ec6f49..9733ec6f49 100644 --- a/tools/editor/icons/2x/icon_curve_linear.png +++ b/editor/icons/2x/icon_curve_linear.png diff --git a/tools/editor/icons/2x/icon_curve_out.png b/editor/icons/2x/icon_curve_out.png Binary files differindex 49e62ef471..49e62ef471 100644 --- a/tools/editor/icons/2x/icon_curve_out.png +++ b/editor/icons/2x/icon_curve_out.png diff --git a/tools/editor/icons/2x/icon_curve_out_in.png b/editor/icons/2x/icon_curve_out_in.png Binary files differindex cc716cdbe8..cc716cdbe8 100644 --- a/tools/editor/icons/2x/icon_curve_out_in.png +++ b/editor/icons/2x/icon_curve_out_in.png diff --git a/tools/editor/icons/2x/icon_damped_spring_joint_2d.png b/editor/icons/2x/icon_damped_spring_joint_2d.png Binary files differindex a51081efca..a51081efca 100644 --- a/tools/editor/icons/2x/icon_damped_spring_joint_2d.png +++ b/editor/icons/2x/icon_damped_spring_joint_2d.png diff --git a/tools/editor/icons/2x/icon_debug_continue.png b/editor/icons/2x/icon_debug_continue.png Binary files differindex be460bd61d..be460bd61d 100644 --- a/tools/editor/icons/2x/icon_debug_continue.png +++ b/editor/icons/2x/icon_debug_continue.png diff --git a/tools/editor/icons/2x/icon_debug_next.png b/editor/icons/2x/icon_debug_next.png Binary files differindex b52e276f36..b52e276f36 100644 --- a/tools/editor/icons/2x/icon_debug_next.png +++ b/editor/icons/2x/icon_debug_next.png diff --git a/tools/editor/icons/2x/icon_debug_step.png b/editor/icons/2x/icon_debug_step.png Binary files differindex e06a1ad56b..e06a1ad56b 100644 --- a/tools/editor/icons/2x/icon_debug_step.png +++ b/editor/icons/2x/icon_debug_step.png diff --git a/tools/editor/icons/2x/icon_dependency_changed.png b/editor/icons/2x/icon_dependency_changed.png Binary files differindex 3ec13e0e3b..3ec13e0e3b 100644 --- a/tools/editor/icons/2x/icon_dependency_changed.png +++ b/editor/icons/2x/icon_dependency_changed.png diff --git a/tools/editor/icons/2x/icon_dependency_changed_hl.png b/editor/icons/2x/icon_dependency_changed_hl.png Binary files differindex 630ea40554..630ea40554 100644 --- a/tools/editor/icons/2x/icon_dependency_changed_hl.png +++ b/editor/icons/2x/icon_dependency_changed_hl.png diff --git a/tools/editor/icons/2x/icon_dependency_local_changed.png b/editor/icons/2x/icon_dependency_local_changed.png Binary files differindex 9bc2545439..9bc2545439 100644 --- a/tools/editor/icons/2x/icon_dependency_local_changed.png +++ b/editor/icons/2x/icon_dependency_local_changed.png diff --git a/tools/editor/icons/2x/icon_dependency_local_changed_hl.png b/editor/icons/2x/icon_dependency_local_changed_hl.png Binary files differindex 385371df9f..385371df9f 100644 --- a/tools/editor/icons/2x/icon_dependency_local_changed_hl.png +++ b/editor/icons/2x/icon_dependency_local_changed_hl.png diff --git a/tools/editor/icons/2x/icon_dependency_ok.png b/editor/icons/2x/icon_dependency_ok.png Binary files differindex 80fe7f573a..80fe7f573a 100644 --- a/tools/editor/icons/2x/icon_dependency_ok.png +++ b/editor/icons/2x/icon_dependency_ok.png diff --git a/tools/editor/icons/2x/icon_dependency_ok_hl.png b/editor/icons/2x/icon_dependency_ok_hl.png Binary files differindex 9d496688cc..9d496688cc 100644 --- a/tools/editor/icons/2x/icon_dependency_ok_hl.png +++ b/editor/icons/2x/icon_dependency_ok_hl.png diff --git a/tools/editor/icons/2x/icon_directional_light.png b/editor/icons/2x/icon_directional_light.png Binary files differindex 9a35325aec..9a35325aec 100644 --- a/tools/editor/icons/2x/icon_directional_light.png +++ b/editor/icons/2x/icon_directional_light.png diff --git a/tools/editor/icons/2x/icon_distraction_free.png b/editor/icons/2x/icon_distraction_free.png Binary files differindex 034239a4e7..034239a4e7 100644 --- a/tools/editor/icons/2x/icon_distraction_free.png +++ b/editor/icons/2x/icon_distraction_free.png diff --git a/tools/editor/icons/2x/icon_duplicate.png b/editor/icons/2x/icon_duplicate.png Binary files differindex 37996482ae..37996482ae 100644 --- a/tools/editor/icons/2x/icon_duplicate.png +++ b/editor/icons/2x/icon_duplicate.png diff --git a/tools/editor/icons/2x/icon_dynamic_font.png b/editor/icons/2x/icon_dynamic_font.png Binary files differindex 1f1dc52dfb..1f1dc52dfb 100644 --- a/tools/editor/icons/2x/icon_dynamic_font.png +++ b/editor/icons/2x/icon_dynamic_font.png diff --git a/tools/editor/icons/2x/icon_dynamic_font_data.png b/editor/icons/2x/icon_dynamic_font_data.png Binary files differindex 6d76303c81..6d76303c81 100644 --- a/tools/editor/icons/2x/icon_dynamic_font_data.png +++ b/editor/icons/2x/icon_dynamic_font_data.png diff --git a/tools/editor/icons/2x/icon_edit.png b/editor/icons/2x/icon_edit.png Binary files differindex b9ed2c3e58..b9ed2c3e58 100644 --- a/tools/editor/icons/2x/icon_edit.png +++ b/editor/icons/2x/icon_edit.png diff --git a/tools/editor/icons/2x/icon_edit_key.png b/editor/icons/2x/icon_edit_key.png Binary files differindex 58b9a6e749..58b9a6e749 100644 --- a/tools/editor/icons/2x/icon_edit_key.png +++ b/editor/icons/2x/icon_edit_key.png diff --git a/tools/editor/icons/2x/icon_edit_pivot.png b/editor/icons/2x/icon_edit_pivot.png Binary files differindex ac5a2cafb9..ac5a2cafb9 100644 --- a/tools/editor/icons/2x/icon_edit_pivot.png +++ b/editor/icons/2x/icon_edit_pivot.png diff --git a/tools/editor/icons/2x/icon_edit_resource.png b/editor/icons/2x/icon_edit_resource.png Binary files differindex 5ba9b36b0a..5ba9b36b0a 100644 --- a/tools/editor/icons/2x/icon_edit_resource.png +++ b/editor/icons/2x/icon_edit_resource.png diff --git a/tools/editor/icons/2x/icon_editor_3d_handle.png b/editor/icons/2x/icon_editor_3d_handle.png Binary files differindex f76af85cc1..f76af85cc1 100644 --- a/tools/editor/icons/2x/icon_editor_3d_handle.png +++ b/editor/icons/2x/icon_editor_3d_handle.png diff --git a/tools/editor/icons/2x/icon_editor_handle.png b/editor/icons/2x/icon_editor_handle.png Binary files differindex 355d8fe155..355d8fe155 100644 --- a/tools/editor/icons/2x/icon_editor_handle.png +++ b/editor/icons/2x/icon_editor_handle.png diff --git a/tools/editor/icons/2x/icon_editor_pivot.png b/editor/icons/2x/icon_editor_pivot.png Binary files differindex e1666e38de..e1666e38de 100644 --- a/tools/editor/icons/2x/icon_editor_pivot.png +++ b/editor/icons/2x/icon_editor_pivot.png diff --git a/tools/editor/icons/2x/icon_editor_plugin.png b/editor/icons/2x/icon_editor_plugin.png Binary files differindex f6411bb323..f6411bb323 100644 --- a/tools/editor/icons/2x/icon_editor_plugin.png +++ b/editor/icons/2x/icon_editor_plugin.png diff --git a/tools/editor/icons/2x/icon_enum.png b/editor/icons/2x/icon_enum.png Binary files differindex d9df3a3ec3..d9df3a3ec3 100644 --- a/tools/editor/icons/2x/icon_enum.png +++ b/editor/icons/2x/icon_enum.png diff --git a/tools/editor/icons/2x/icon_environment.png b/editor/icons/2x/icon_environment.png Binary files differindex 4c4c30b0e5..4c4c30b0e5 100644 --- a/tools/editor/icons/2x/icon_environment.png +++ b/editor/icons/2x/icon_environment.png diff --git a/tools/editor/icons/2x/icon_error.png b/editor/icons/2x/icon_error.png Binary files differindex a6d79ab41b..a6d79ab41b 100644 --- a/tools/editor/icons/2x/icon_error.png +++ b/editor/icons/2x/icon_error.png diff --git a/tools/editor/icons/2x/icon_error_sign.png b/editor/icons/2x/icon_error_sign.png Binary files differindex f1d16ea669..f1d16ea669 100644 --- a/tools/editor/icons/2x/icon_error_sign.png +++ b/editor/icons/2x/icon_error_sign.png diff --git a/tools/editor/icons/2x/icon_event_player.png b/editor/icons/2x/icon_event_player.png Binary files differindex 2482c576db..2482c576db 100644 --- a/tools/editor/icons/2x/icon_event_player.png +++ b/editor/icons/2x/icon_event_player.png diff --git a/tools/editor/icons/2x/icon_favorites.png b/editor/icons/2x/icon_favorites.png Binary files differindex 7a63835b3d..7a63835b3d 100644 --- a/tools/editor/icons/2x/icon_favorites.png +++ b/editor/icons/2x/icon_favorites.png diff --git a/tools/editor/icons/2x/icon_file.png b/editor/icons/2x/icon_file.png Binary files differindex 683f1141fd..683f1141fd 100644 --- a/tools/editor/icons/2x/icon_file.png +++ b/editor/icons/2x/icon_file.png diff --git a/tools/editor/icons/2x/icon_file_big.png b/editor/icons/2x/icon_file_big.png Binary files differindex 8c86c6b958..8c86c6b958 100644 --- a/tools/editor/icons/2x/icon_file_big.png +++ b/editor/icons/2x/icon_file_big.png diff --git a/tools/editor/icons/2x/icon_file_dialog.png b/editor/icons/2x/icon_file_dialog.png Binary files differindex f19b4d7507..f19b4d7507 100644 --- a/tools/editor/icons/2x/icon_file_dialog.png +++ b/editor/icons/2x/icon_file_dialog.png diff --git a/tools/editor/icons/2x/icon_file_list.png b/editor/icons/2x/icon_file_list.png Binary files differindex d9df3a3ec3..d9df3a3ec3 100644 --- a/tools/editor/icons/2x/icon_file_list.png +++ b/editor/icons/2x/icon_file_list.png diff --git a/tools/editor/icons/2x/icon_file_server.png b/editor/icons/2x/icon_file_server.png Binary files differindex d8021a4067..d8021a4067 100644 --- a/tools/editor/icons/2x/icon_file_server.png +++ b/editor/icons/2x/icon_file_server.png diff --git a/tools/editor/icons/2x/icon_file_server_active.png b/editor/icons/2x/icon_file_server_active.png Binary files differindex f503fe406b..f503fe406b 100644 --- a/tools/editor/icons/2x/icon_file_server_active.png +++ b/editor/icons/2x/icon_file_server_active.png diff --git a/tools/editor/icons/2x/icon_file_thumbnail.png b/editor/icons/2x/icon_file_thumbnail.png Binary files differindex 5a8d282fe1..5a8d282fe1 100644 --- a/tools/editor/icons/2x/icon_file_thumbnail.png +++ b/editor/icons/2x/icon_file_thumbnail.png diff --git a/tools/editor/icons/2x/icon_filesystem.png b/editor/icons/2x/icon_filesystem.png Binary files differindex 4ae0b3edab..4ae0b3edab 100644 --- a/tools/editor/icons/2x/icon_filesystem.png +++ b/editor/icons/2x/icon_filesystem.png diff --git a/tools/editor/icons/2x/icon_fixed_material.png b/editor/icons/2x/icon_fixed_material.png Binary files differindex 21bfb15838..21bfb15838 100644 --- a/tools/editor/icons/2x/icon_fixed_material.png +++ b/editor/icons/2x/icon_fixed_material.png diff --git a/tools/editor/icons/2x/icon_fixed_spatial_material.png b/editor/icons/2x/icon_fixed_spatial_material.png Binary files differindex 65509a590e..65509a590e 100644 --- a/tools/editor/icons/2x/icon_fixed_spatial_material.png +++ b/editor/icons/2x/icon_fixed_spatial_material.png diff --git a/tools/editor/icons/2x/icon_folder.png b/editor/icons/2x/icon_folder.png Binary files differindex 2e797c448b..2e797c448b 100644 --- a/tools/editor/icons/2x/icon_folder.png +++ b/editor/icons/2x/icon_folder.png diff --git a/tools/editor/icons/2x/icon_folder_big.png b/editor/icons/2x/icon_folder_big.png Binary files differindex b89600619a..b89600619a 100644 --- a/tools/editor/icons/2x/icon_folder_big.png +++ b/editor/icons/2x/icon_folder_big.png diff --git a/tools/editor/icons/2x/icon_font.png b/editor/icons/2x/icon_font.png Binary files differindex b78c95a827..b78c95a827 100644 --- a/tools/editor/icons/2x/icon_font.png +++ b/editor/icons/2x/icon_font.png diff --git a/tools/editor/icons/2x/icon_forward.png b/editor/icons/2x/icon_forward.png Binary files differindex 11fd444a04..11fd444a04 100644 --- a/tools/editor/icons/2x/icon_forward.png +++ b/editor/icons/2x/icon_forward.png diff --git a/tools/editor/icons/2x/icon_g_d_script.png b/editor/icons/2x/icon_g_d_script.png Binary files differindex 6143191fc7..6143191fc7 100644 --- a/tools/editor/icons/2x/icon_g_d_script.png +++ b/editor/icons/2x/icon_g_d_script.png diff --git a/tools/editor/icons/2x/icon_g_i_probe.png b/editor/icons/2x/icon_g_i_probe.png Binary files differindex 921f1cca42..921f1cca42 100644 --- a/tools/editor/icons/2x/icon_g_i_probe.png +++ b/editor/icons/2x/icon_g_i_probe.png diff --git a/tools/editor/icons/2x/icon_g_i_probe_data.png b/editor/icons/2x/icon_g_i_probe_data.png Binary files differindex 69c4ed7184..69c4ed7184 100644 --- a/tools/editor/icons/2x/icon_g_i_probe_data.png +++ b/editor/icons/2x/icon_g_i_probe_data.png diff --git a/tools/editor/icons/2x/icon_generic_6_d_o_f_joint.png b/editor/icons/2x/icon_generic_6_d_o_f_joint.png Binary files differindex 506c873376..506c873376 100644 --- a/tools/editor/icons/2x/icon_generic_6_d_o_f_joint.png +++ b/editor/icons/2x/icon_generic_6_d_o_f_joint.png diff --git a/tools/editor/icons/2x/icon_gizmo_directional_light.png b/editor/icons/2x/icon_gizmo_directional_light.png Binary files differindex 0d02788040..0d02788040 100644 --- a/tools/editor/icons/2x/icon_gizmo_directional_light.png +++ b/editor/icons/2x/icon_gizmo_directional_light.png diff --git a/tools/editor/icons/2x/icon_gizmo_light.png b/editor/icons/2x/icon_gizmo_light.png Binary files differindex 2ba9689107..2ba9689107 100644 --- a/tools/editor/icons/2x/icon_gizmo_light.png +++ b/editor/icons/2x/icon_gizmo_light.png diff --git a/tools/editor/icons/2x/icon_gizmo_listener.png b/editor/icons/2x/icon_gizmo_listener.png Binary files differindex bc2908824d..bc2908824d 100644 --- a/tools/editor/icons/2x/icon_gizmo_listener.png +++ b/editor/icons/2x/icon_gizmo_listener.png diff --git a/tools/editor/icons/2x/icon_gizmo_spatial_sample_player.png b/editor/icons/2x/icon_gizmo_spatial_sample_player.png Binary files differindex 78a88c55c1..78a88c55c1 100644 --- a/tools/editor/icons/2x/icon_gizmo_spatial_sample_player.png +++ b/editor/icons/2x/icon_gizmo_spatial_sample_player.png diff --git a/tools/editor/icons/2x/icon_gizmo_spatial_stream_player.png b/editor/icons/2x/icon_gizmo_spatial_stream_player.png Binary files differindex 631f03e874..631f03e874 100644 --- a/tools/editor/icons/2x/icon_gizmo_spatial_stream_player.png +++ b/editor/icons/2x/icon_gizmo_spatial_stream_player.png diff --git a/tools/editor/icons/2x/icon_godot.png b/editor/icons/2x/icon_godot.png Binary files differindex 94d87e23cc..94d87e23cc 100644 --- a/tools/editor/icons/2x/icon_godot.png +++ b/editor/icons/2x/icon_godot.png diff --git a/tools/editor/icons/2x/icon_graph_color_ramp.png b/editor/icons/2x/icon_graph_color_ramp.png Binary files differindex d0056f0c7d..d0056f0c7d 100644 --- a/tools/editor/icons/2x/icon_graph_color_ramp.png +++ b/editor/icons/2x/icon_graph_color_ramp.png diff --git a/tools/editor/icons/2x/icon_graph_comment.png b/editor/icons/2x/icon_graph_comment.png Binary files differindex 3dedbfab52..3dedbfab52 100644 --- a/tools/editor/icons/2x/icon_graph_comment.png +++ b/editor/icons/2x/icon_graph_comment.png diff --git a/tools/editor/icons/2x/icon_graph_cube_uniform.png b/editor/icons/2x/icon_graph_cube_uniform.png Binary files differindex 43ec1fa6d6..43ec1fa6d6 100644 --- a/tools/editor/icons/2x/icon_graph_cube_uniform.png +++ b/editor/icons/2x/icon_graph_cube_uniform.png diff --git a/tools/editor/icons/2x/icon_graph_curve_map.png b/editor/icons/2x/icon_graph_curve_map.png Binary files differindex f29086e503..f29086e503 100644 --- a/tools/editor/icons/2x/icon_graph_curve_map.png +++ b/editor/icons/2x/icon_graph_curve_map.png diff --git a/tools/editor/icons/2x/icon_graph_default_texture.png b/editor/icons/2x/icon_graph_default_texture.png Binary files differindex 45e4470502..45e4470502 100644 --- a/tools/editor/icons/2x/icon_graph_default_texture.png +++ b/editor/icons/2x/icon_graph_default_texture.png diff --git a/tools/editor/icons/2x/icon_graph_edit.png b/editor/icons/2x/icon_graph_edit.png Binary files differindex bd4386839d..bd4386839d 100644 --- a/tools/editor/icons/2x/icon_graph_edit.png +++ b/editor/icons/2x/icon_graph_edit.png diff --git a/tools/editor/icons/2x/icon_graph_input.png b/editor/icons/2x/icon_graph_input.png Binary files differindex 3eeb29a3e7..3eeb29a3e7 100644 --- a/tools/editor/icons/2x/icon_graph_input.png +++ b/editor/icons/2x/icon_graph_input.png diff --git a/tools/editor/icons/2x/icon_graph_node.png b/editor/icons/2x/icon_graph_node.png Binary files differindex 7ce633af4d..7ce633af4d 100644 --- a/tools/editor/icons/2x/icon_graph_node.png +++ b/editor/icons/2x/icon_graph_node.png diff --git a/tools/editor/icons/2x/icon_graph_rgb.png b/editor/icons/2x/icon_graph_rgb.png Binary files differindex a9c39f0222..a9c39f0222 100644 --- a/tools/editor/icons/2x/icon_graph_rgb.png +++ b/editor/icons/2x/icon_graph_rgb.png diff --git a/tools/editor/icons/2x/icon_graph_rgb_op.png b/editor/icons/2x/icon_graph_rgb_op.png Binary files differindex 44812d8dd8..44812d8dd8 100644 --- a/tools/editor/icons/2x/icon_graph_rgb_op.png +++ b/editor/icons/2x/icon_graph_rgb_op.png diff --git a/tools/editor/icons/2x/icon_graph_rgb_uniform.png b/editor/icons/2x/icon_graph_rgb_uniform.png Binary files differindex b06f1d4d8d..b06f1d4d8d 100644 --- a/tools/editor/icons/2x/icon_graph_rgb_uniform.png +++ b/editor/icons/2x/icon_graph_rgb_uniform.png diff --git a/tools/editor/icons/2x/icon_graph_scalar.png b/editor/icons/2x/icon_graph_scalar.png Binary files differindex 382c429d35..382c429d35 100644 --- a/tools/editor/icons/2x/icon_graph_scalar.png +++ b/editor/icons/2x/icon_graph_scalar.png diff --git a/tools/editor/icons/2x/icon_graph_scalar_interp.png b/editor/icons/2x/icon_graph_scalar_interp.png Binary files differindex 430e35470f..430e35470f 100644 --- a/tools/editor/icons/2x/icon_graph_scalar_interp.png +++ b/editor/icons/2x/icon_graph_scalar_interp.png diff --git a/tools/editor/icons/2x/icon_graph_scalar_op.png b/editor/icons/2x/icon_graph_scalar_op.png Binary files differindex b90b6a6190..b90b6a6190 100644 --- a/tools/editor/icons/2x/icon_graph_scalar_op.png +++ b/editor/icons/2x/icon_graph_scalar_op.png diff --git a/tools/editor/icons/2x/icon_graph_scalar_uniform.png b/editor/icons/2x/icon_graph_scalar_uniform.png Binary files differindex dff850df03..dff850df03 100644 --- a/tools/editor/icons/2x/icon_graph_scalar_uniform.png +++ b/editor/icons/2x/icon_graph_scalar_uniform.png diff --git a/tools/editor/icons/2x/icon_graph_scalars_to_vec.png b/editor/icons/2x/icon_graph_scalars_to_vec.png Binary files differindex 266c84e5ae..266c84e5ae 100644 --- a/tools/editor/icons/2x/icon_graph_scalars_to_vec.png +++ b/editor/icons/2x/icon_graph_scalars_to_vec.png diff --git a/tools/editor/icons/2x/icon_graph_texscreen.png b/editor/icons/2x/icon_graph_texscreen.png Binary files differindex 8b1d250129..8b1d250129 100644 --- a/tools/editor/icons/2x/icon_graph_texscreen.png +++ b/editor/icons/2x/icon_graph_texscreen.png diff --git a/tools/editor/icons/2x/icon_graph_texture_uniform.png b/editor/icons/2x/icon_graph_texture_uniform.png Binary files differindex ee211b6c03..ee211b6c03 100644 --- a/tools/editor/icons/2x/icon_graph_texture_uniform.png +++ b/editor/icons/2x/icon_graph_texture_uniform.png diff --git a/tools/editor/icons/2x/icon_graph_time.png b/editor/icons/2x/icon_graph_time.png Binary files differindex 3cf9bf2035..3cf9bf2035 100644 --- a/tools/editor/icons/2x/icon_graph_time.png +++ b/editor/icons/2x/icon_graph_time.png diff --git a/tools/editor/icons/2x/icon_graph_vec_dp.png b/editor/icons/2x/icon_graph_vec_dp.png Binary files differindex e339f6a1e8..e339f6a1e8 100644 --- a/tools/editor/icons/2x/icon_graph_vec_dp.png +++ b/editor/icons/2x/icon_graph_vec_dp.png diff --git a/tools/editor/icons/2x/icon_graph_vec_interp.png b/editor/icons/2x/icon_graph_vec_interp.png Binary files differindex 02e7915748..02e7915748 100644 --- a/tools/editor/icons/2x/icon_graph_vec_interp.png +++ b/editor/icons/2x/icon_graph_vec_interp.png diff --git a/tools/editor/icons/2x/icon_graph_vec_length.png b/editor/icons/2x/icon_graph_vec_length.png Binary files differindex 857e006b6e..857e006b6e 100644 --- a/tools/editor/icons/2x/icon_graph_vec_length.png +++ b/editor/icons/2x/icon_graph_vec_length.png diff --git a/tools/editor/icons/2x/icon_graph_vec_op.png b/editor/icons/2x/icon_graph_vec_op.png Binary files differindex 282336f9d0..282336f9d0 100644 --- a/tools/editor/icons/2x/icon_graph_vec_op.png +++ b/editor/icons/2x/icon_graph_vec_op.png diff --git a/tools/editor/icons/2x/icon_graph_vec_scalar_op.png b/editor/icons/2x/icon_graph_vec_scalar_op.png Binary files differindex 38d355ef06..38d355ef06 100644 --- a/tools/editor/icons/2x/icon_graph_vec_scalar_op.png +++ b/editor/icons/2x/icon_graph_vec_scalar_op.png diff --git a/tools/editor/icons/2x/icon_graph_vec_to_scalars.png b/editor/icons/2x/icon_graph_vec_to_scalars.png Binary files differindex 1b8254b3c6..1b8254b3c6 100644 --- a/tools/editor/icons/2x/icon_graph_vec_to_scalars.png +++ b/editor/icons/2x/icon_graph_vec_to_scalars.png diff --git a/tools/editor/icons/2x/icon_graph_vecs_to_xform.png b/editor/icons/2x/icon_graph_vecs_to_xform.png Binary files differindex a9ed5052be..a9ed5052be 100644 --- a/tools/editor/icons/2x/icon_graph_vecs_to_xform.png +++ b/editor/icons/2x/icon_graph_vecs_to_xform.png diff --git a/tools/editor/icons/2x/icon_graph_vector.png b/editor/icons/2x/icon_graph_vector.png Binary files differindex eb4e94acee..eb4e94acee 100644 --- a/tools/editor/icons/2x/icon_graph_vector.png +++ b/editor/icons/2x/icon_graph_vector.png diff --git a/tools/editor/icons/2x/icon_graph_vector_uniform.png b/editor/icons/2x/icon_graph_vector_uniform.png Binary files differindex 94cde72904..94cde72904 100644 --- a/tools/editor/icons/2x/icon_graph_vector_uniform.png +++ b/editor/icons/2x/icon_graph_vector_uniform.png diff --git a/tools/editor/icons/2x/icon_graph_xform.png b/editor/icons/2x/icon_graph_xform.png Binary files differindex 4d823e2aa9..4d823e2aa9 100644 --- a/tools/editor/icons/2x/icon_graph_xform.png +++ b/editor/icons/2x/icon_graph_xform.png diff --git a/tools/editor/icons/2x/icon_graph_xform_mult.png b/editor/icons/2x/icon_graph_xform_mult.png Binary files differindex a6d41e43a4..a6d41e43a4 100644 --- a/tools/editor/icons/2x/icon_graph_xform_mult.png +++ b/editor/icons/2x/icon_graph_xform_mult.png diff --git a/tools/editor/icons/2x/icon_graph_xform_scalar_func.png b/editor/icons/2x/icon_graph_xform_scalar_func.png Binary files differindex 06826a1ca2..06826a1ca2 100644 --- a/tools/editor/icons/2x/icon_graph_xform_scalar_func.png +++ b/editor/icons/2x/icon_graph_xform_scalar_func.png diff --git a/tools/editor/icons/2x/icon_graph_xform_to_vecs.png b/editor/icons/2x/icon_graph_xform_to_vecs.png Binary files differindex 22125df573..22125df573 100644 --- a/tools/editor/icons/2x/icon_graph_xform_to_vecs.png +++ b/editor/icons/2x/icon_graph_xform_to_vecs.png diff --git a/tools/editor/icons/2x/icon_graph_xform_uniform.png b/editor/icons/2x/icon_graph_xform_uniform.png Binary files differindex b87f9936b8..b87f9936b8 100644 --- a/tools/editor/icons/2x/icon_graph_xform_uniform.png +++ b/editor/icons/2x/icon_graph_xform_uniform.png diff --git a/tools/editor/icons/2x/icon_graph_xform_vec_func.png b/editor/icons/2x/icon_graph_xform_vec_func.png Binary files differindex 007555ff7b..007555ff7b 100644 --- a/tools/editor/icons/2x/icon_graph_xform_vec_func.png +++ b/editor/icons/2x/icon_graph_xform_vec_func.png diff --git a/tools/editor/icons/2x/icon_graph_xform_vec_imult.png b/editor/icons/2x/icon_graph_xform_vec_imult.png Binary files differindex 39e25ef9b3..39e25ef9b3 100644 --- a/tools/editor/icons/2x/icon_graph_xform_vec_imult.png +++ b/editor/icons/2x/icon_graph_xform_vec_imult.png diff --git a/tools/editor/icons/2x/icon_graph_xform_vec_mult.png b/editor/icons/2x/icon_graph_xform_vec_mult.png Binary files differindex 32802fa1ed..32802fa1ed 100644 --- a/tools/editor/icons/2x/icon_graph_xform_vec_mult.png +++ b/editor/icons/2x/icon_graph_xform_vec_mult.png diff --git a/tools/editor/icons/2x/icon_grid.png b/editor/icons/2x/icon_grid.png Binary files differindex 99d896c012..99d896c012 100644 --- a/tools/editor/icons/2x/icon_grid.png +++ b/editor/icons/2x/icon_grid.png diff --git a/tools/editor/icons/2x/icon_grid_container.png b/editor/icons/2x/icon_grid_container.png Binary files differindex b83b1f4347..b83b1f4347 100644 --- a/tools/editor/icons/2x/icon_grid_container.png +++ b/editor/icons/2x/icon_grid_container.png diff --git a/tools/editor/icons/2x/icon_grid_map.png b/editor/icons/2x/icon_grid_map.png Binary files differindex 5bbd16d3df..5bbd16d3df 100644 --- a/tools/editor/icons/2x/icon_grid_map.png +++ b/editor/icons/2x/icon_grid_map.png diff --git a/tools/editor/icons/2x/icon_groove_joint_2d.png b/editor/icons/2x/icon_groove_joint_2d.png Binary files differindex ab9cd4f3eb..ab9cd4f3eb 100644 --- a/tools/editor/icons/2x/icon_groove_joint_2d.png +++ b/editor/icons/2x/icon_groove_joint_2d.png diff --git a/tools/editor/icons/2x/icon_group.png b/editor/icons/2x/icon_group.png Binary files differindex 158efa5fe4..158efa5fe4 100644 --- a/tools/editor/icons/2x/icon_group.png +++ b/editor/icons/2x/icon_group.png diff --git a/tools/editor/icons/2x/icon_groups.png b/editor/icons/2x/icon_groups.png Binary files differindex 203d36071b..203d36071b 100644 --- a/tools/editor/icons/2x/icon_groups.png +++ b/editor/icons/2x/icon_groups.png diff --git a/tools/editor/icons/2x/icon_h_box_container.png b/editor/icons/2x/icon_h_box_container.png Binary files differindex 3767cab1cf..3767cab1cf 100644 --- a/tools/editor/icons/2x/icon_h_box_container.png +++ b/editor/icons/2x/icon_h_box_container.png diff --git a/tools/editor/icons/2x/icon_h_button_array.png b/editor/icons/2x/icon_h_button_array.png Binary files differindex 750eef8267..750eef8267 100644 --- a/tools/editor/icons/2x/icon_h_button_array.png +++ b/editor/icons/2x/icon_h_button_array.png diff --git a/tools/editor/icons/2x/icon_h_scroll_bar.png b/editor/icons/2x/icon_h_scroll_bar.png Binary files differindex d15a36bb16..d15a36bb16 100644 --- a/tools/editor/icons/2x/icon_h_scroll_bar.png +++ b/editor/icons/2x/icon_h_scroll_bar.png diff --git a/tools/editor/icons/2x/icon_h_separator.png b/editor/icons/2x/icon_h_separator.png Binary files differindex 7dd7e1e314..7dd7e1e314 100644 --- a/tools/editor/icons/2x/icon_h_separator.png +++ b/editor/icons/2x/icon_h_separator.png diff --git a/tools/editor/icons/2x/icon_h_slider.png b/editor/icons/2x/icon_h_slider.png Binary files differindex 50bad1cc18..50bad1cc18 100644 --- a/tools/editor/icons/2x/icon_h_slider.png +++ b/editor/icons/2x/icon_h_slider.png diff --git a/tools/editor/icons/2x/icon_h_split_container.png b/editor/icons/2x/icon_h_split_container.png Binary files differindex 33e18946c1..33e18946c1 100644 --- a/tools/editor/icons/2x/icon_h_split_container.png +++ b/editor/icons/2x/icon_h_split_container.png diff --git a/tools/editor/icons/2x/icon_h_t_t_p_request.png b/editor/icons/2x/icon_h_t_t_p_request.png Binary files differindex a334dea4e2..a334dea4e2 100644 --- a/tools/editor/icons/2x/icon_h_t_t_p_request.png +++ b/editor/icons/2x/icon_h_t_t_p_request.png diff --git a/tools/editor/icons/2x/icon_headphones.png b/editor/icons/2x/icon_headphones.png Binary files differindex eca62b9372..eca62b9372 100644 --- a/tools/editor/icons/2x/icon_headphones.png +++ b/editor/icons/2x/icon_headphones.png diff --git a/tools/editor/icons/2x/icon_help.png b/editor/icons/2x/icon_help.png Binary files differindex f16a34c918..f16a34c918 100644 --- a/tools/editor/icons/2x/icon_help.png +++ b/editor/icons/2x/icon_help.png diff --git a/tools/editor/icons/2x/icon_hidden.png b/editor/icons/2x/icon_hidden.png Binary files differindex 09d38c5bef..09d38c5bef 100644 --- a/tools/editor/icons/2x/icon_hidden.png +++ b/editor/icons/2x/icon_hidden.png diff --git a/tools/editor/icons/2x/icon_hinge_joint.png b/editor/icons/2x/icon_hinge_joint.png Binary files differindex b888102573..b888102573 100644 --- a/tools/editor/icons/2x/icon_hinge_joint.png +++ b/editor/icons/2x/icon_hinge_joint.png diff --git a/tools/editor/icons/2x/icon_history.png b/editor/icons/2x/icon_history.png Binary files differindex 153a2b4edf..153a2b4edf 100644 --- a/tools/editor/icons/2x/icon_history.png +++ b/editor/icons/2x/icon_history.png diff --git a/tools/editor/icons/2x/icon_hsize.png b/editor/icons/2x/icon_hsize.png Binary files differindex 3b096dce88..3b096dce88 100644 --- a/tools/editor/icons/2x/icon_hsize.png +++ b/editor/icons/2x/icon_hsize.png diff --git a/tools/editor/icons/2x/icon_image.png b/editor/icons/2x/icon_image.png Binary files differindex 951b2242f1..951b2242f1 100644 --- a/tools/editor/icons/2x/icon_image.png +++ b/editor/icons/2x/icon_image.png diff --git a/tools/editor/icons/2x/icon_image_sky_box.png b/editor/icons/2x/icon_image_sky_box.png Binary files differindex 487178afab..487178afab 100644 --- a/tools/editor/icons/2x/icon_image_sky_box.png +++ b/editor/icons/2x/icon_image_sky_box.png diff --git a/tools/editor/icons/2x/icon_image_texture.png b/editor/icons/2x/icon_image_texture.png Binary files differindex ad5d04dfee..ad5d04dfee 100644 --- a/tools/editor/icons/2x/icon_image_texture.png +++ b/editor/icons/2x/icon_image_texture.png diff --git a/tools/editor/icons/2x/icon_immediate_geometry.png b/editor/icons/2x/icon_immediate_geometry.png Binary files differindex 5fafecadc3..5fafecadc3 100644 --- a/tools/editor/icons/2x/icon_immediate_geometry.png +++ b/editor/icons/2x/icon_immediate_geometry.png diff --git a/tools/editor/icons/2x/icon_import_check.png b/editor/icons/2x/icon_import_check.png Binary files differindex 98e76e2640..98e76e2640 100644 --- a/tools/editor/icons/2x/icon_import_check.png +++ b/editor/icons/2x/icon_import_check.png diff --git a/tools/editor/icons/2x/icon_import_fail.png b/editor/icons/2x/icon_import_fail.png Binary files differindex f89c2f5c75..f89c2f5c75 100644 --- a/tools/editor/icons/2x/icon_import_fail.png +++ b/editor/icons/2x/icon_import_fail.png diff --git a/tools/editor/icons/2x/icon_instance.png b/editor/icons/2x/icon_instance.png Binary files differindex 9b4731de03..9b4731de03 100644 --- a/tools/editor/icons/2x/icon_instance.png +++ b/editor/icons/2x/icon_instance.png diff --git a/tools/editor/icons/2x/icon_instance_options.png b/editor/icons/2x/icon_instance_options.png Binary files differindex 28e2db25f2..28e2db25f2 100644 --- a/tools/editor/icons/2x/icon_instance_options.png +++ b/editor/icons/2x/icon_instance_options.png diff --git a/tools/editor/icons/2x/icon_integer.png b/editor/icons/2x/icon_integer.png Binary files differindex 7ad2f62458..7ad2f62458 100644 --- a/tools/editor/icons/2x/icon_integer.png +++ b/editor/icons/2x/icon_integer.png diff --git a/tools/editor/icons/2x/icon_interp_cubic.png b/editor/icons/2x/icon_interp_cubic.png Binary files differindex e33bb65577..e33bb65577 100644 --- a/tools/editor/icons/2x/icon_interp_cubic.png +++ b/editor/icons/2x/icon_interp_cubic.png diff --git a/tools/editor/icons/2x/icon_interp_linear.png b/editor/icons/2x/icon_interp_linear.png Binary files differindex 205f7febd5..205f7febd5 100644 --- a/tools/editor/icons/2x/icon_interp_linear.png +++ b/editor/icons/2x/icon_interp_linear.png diff --git a/tools/editor/icons/2x/icon_interp_raw.png b/editor/icons/2x/icon_interp_raw.png Binary files differindex 848ef07be6..848ef07be6 100644 --- a/tools/editor/icons/2x/icon_interp_raw.png +++ b/editor/icons/2x/icon_interp_raw.png diff --git a/tools/editor/icons/2x/icon_interp_wrap_clamp.png b/editor/icons/2x/icon_interp_wrap_clamp.png Binary files differindex 93a5bc56ee..93a5bc56ee 100644 --- a/tools/editor/icons/2x/icon_interp_wrap_clamp.png +++ b/editor/icons/2x/icon_interp_wrap_clamp.png diff --git a/tools/editor/icons/2x/icon_interp_wrap_loop.png b/editor/icons/2x/icon_interp_wrap_loop.png Binary files differindex 3e656f7b07..3e656f7b07 100644 --- a/tools/editor/icons/2x/icon_interp_wrap_loop.png +++ b/editor/icons/2x/icon_interp_wrap_loop.png diff --git a/tools/editor/icons/2x/icon_interpolated_camera.png b/editor/icons/2x/icon_interpolated_camera.png Binary files differindex e4551a84ce..e4551a84ce 100644 --- a/tools/editor/icons/2x/icon_interpolated_camera.png +++ b/editor/icons/2x/icon_interpolated_camera.png diff --git a/tools/editor/icons/2x/icon_invalid_key.png b/editor/icons/2x/icon_invalid_key.png Binary files differindex c34f2bc276..c34f2bc276 100644 --- a/tools/editor/icons/2x/icon_invalid_key.png +++ b/editor/icons/2x/icon_invalid_key.png diff --git a/tools/editor/icons/2x/icon_inverse_kinematics.png b/editor/icons/2x/icon_inverse_kinematics.png Binary files differindex 3b10c9590c..3b10c9590c 100644 --- a/tools/editor/icons/2x/icon_inverse_kinematics.png +++ b/editor/icons/2x/icon_inverse_kinematics.png diff --git a/tools/editor/icons/2x/icon_item_list.png b/editor/icons/2x/icon_item_list.png Binary files differindex 11a375caac..11a375caac 100644 --- a/tools/editor/icons/2x/icon_item_list.png +++ b/editor/icons/2x/icon_item_list.png diff --git a/tools/editor/icons/2x/icon_joy_axis.png b/editor/icons/2x/icon_joy_axis.png Binary files differindex 90f3d7a444..90f3d7a444 100644 --- a/tools/editor/icons/2x/icon_joy_axis.png +++ b/editor/icons/2x/icon_joy_axis.png diff --git a/tools/editor/icons/2x/icon_joy_button.png b/editor/icons/2x/icon_joy_button.png Binary files differindex a6b911ba1b..a6b911ba1b 100644 --- a/tools/editor/icons/2x/icon_joy_button.png +++ b/editor/icons/2x/icon_joy_button.png diff --git a/tools/editor/icons/2x/icon_joypad.png b/editor/icons/2x/icon_joypad.png Binary files differindex 285d048544..285d048544 100644 --- a/tools/editor/icons/2x/icon_joypad.png +++ b/editor/icons/2x/icon_joypad.png diff --git a/tools/editor/icons/2x/icon_key.png b/editor/icons/2x/icon_key.png Binary files differindex d0c07bb1ea..d0c07bb1ea 100644 --- a/tools/editor/icons/2x/icon_key.png +++ b/editor/icons/2x/icon_key.png diff --git a/tools/editor/icons/2x/icon_key_hover.png b/editor/icons/2x/icon_key_hover.png Binary files differindex c9894ad8bf..c9894ad8bf 100644 --- a/tools/editor/icons/2x/icon_key_hover.png +++ b/editor/icons/2x/icon_key_hover.png diff --git a/tools/editor/icons/2x/icon_key_invalid.png b/editor/icons/2x/icon_key_invalid.png Binary files differindex c34f2bc276..c34f2bc276 100644 --- a/tools/editor/icons/2x/icon_key_invalid.png +++ b/editor/icons/2x/icon_key_invalid.png diff --git a/tools/editor/icons/2x/icon_key_next.png b/editor/icons/2x/icon_key_next.png Binary files differindex d35b52d3c7..d35b52d3c7 100644 --- a/tools/editor/icons/2x/icon_key_next.png +++ b/editor/icons/2x/icon_key_next.png diff --git a/tools/editor/icons/2x/icon_key_selected.png b/editor/icons/2x/icon_key_selected.png Binary files differindex 243dacb604..243dacb604 100644 --- a/tools/editor/icons/2x/icon_key_selected.png +++ b/editor/icons/2x/icon_key_selected.png diff --git a/tools/editor/icons/2x/icon_key_value.png b/editor/icons/2x/icon_key_value.png Binary files differindex 3863403706..3863403706 100644 --- a/tools/editor/icons/2x/icon_key_value.png +++ b/editor/icons/2x/icon_key_value.png diff --git a/tools/editor/icons/2x/icon_key_xform.png b/editor/icons/2x/icon_key_xform.png Binary files differindex 70c49b5b5f..70c49b5b5f 100644 --- a/tools/editor/icons/2x/icon_key_xform.png +++ b/editor/icons/2x/icon_key_xform.png diff --git a/tools/editor/icons/2x/icon_keyboard.png b/editor/icons/2x/icon_keyboard.png Binary files differindex a7daa06cc2..a7daa06cc2 100644 --- a/tools/editor/icons/2x/icon_keyboard.png +++ b/editor/icons/2x/icon_keyboard.png diff --git a/tools/editor/icons/2x/icon_kinematic_body.png b/editor/icons/2x/icon_kinematic_body.png Binary files differindex 59298dfa72..59298dfa72 100644 --- a/tools/editor/icons/2x/icon_kinematic_body.png +++ b/editor/icons/2x/icon_kinematic_body.png diff --git a/tools/editor/icons/2x/icon_kinematic_body_2d.png b/editor/icons/2x/icon_kinematic_body_2d.png Binary files differindex 5fd3b319ac..5fd3b319ac 100644 --- a/tools/editor/icons/2x/icon_kinematic_body_2d.png +++ b/editor/icons/2x/icon_kinematic_body_2d.png diff --git a/tools/editor/icons/2x/icon_label.png b/editor/icons/2x/icon_label.png Binary files differindex c5e3bc844d..c5e3bc844d 100644 --- a/tools/editor/icons/2x/icon_label.png +++ b/editor/icons/2x/icon_label.png diff --git a/tools/editor/icons/2x/icon_large_texture.png b/editor/icons/2x/icon_large_texture.png Binary files differindex dd1ec86d39..dd1ec86d39 100644 --- a/tools/editor/icons/2x/icon_large_texture.png +++ b/editor/icons/2x/icon_large_texture.png diff --git a/tools/editor/icons/2x/icon_light_2d.png b/editor/icons/2x/icon_light_2d.png Binary files differindex d441659354..d441659354 100644 --- a/tools/editor/icons/2x/icon_light_2d.png +++ b/editor/icons/2x/icon_light_2d.png diff --git a/tools/editor/icons/2x/icon_light_occluder_2d.png b/editor/icons/2x/icon_light_occluder_2d.png Binary files differindex 90e4387297..90e4387297 100644 --- a/tools/editor/icons/2x/icon_light_occluder_2d.png +++ b/editor/icons/2x/icon_light_occluder_2d.png diff --git a/tools/editor/icons/2x/icon_line_2d.png b/editor/icons/2x/icon_line_2d.png Binary files differindex 27299a2b69..27299a2b69 100644 --- a/tools/editor/icons/2x/icon_line_2d.png +++ b/editor/icons/2x/icon_line_2d.png diff --git a/tools/editor/icons/2x/icon_line_edit.png b/editor/icons/2x/icon_line_edit.png Binary files differindex d0c987388f..d0c987388f 100644 --- a/tools/editor/icons/2x/icon_line_edit.png +++ b/editor/icons/2x/icon_line_edit.png diff --git a/tools/editor/icons/2x/icon_line_shape_2d.png b/editor/icons/2x/icon_line_shape_2d.png Binary files differindex 490db5ca5b..490db5ca5b 100644 --- a/tools/editor/icons/2x/icon_line_shape_2d.png +++ b/editor/icons/2x/icon_line_shape_2d.png diff --git a/tools/editor/icons/2x/icon_link_button.png b/editor/icons/2x/icon_link_button.png Binary files differindex 20f300a553..20f300a553 100644 --- a/tools/editor/icons/2x/icon_link_button.png +++ b/editor/icons/2x/icon_link_button.png diff --git a/tools/editor/icons/2x/icon_list_select.png b/editor/icons/2x/icon_list_select.png Binary files differindex 9f7fa5b865..9f7fa5b865 100644 --- a/tools/editor/icons/2x/icon_list_select.png +++ b/editor/icons/2x/icon_list_select.png diff --git a/tools/editor/icons/2x/icon_listener.png b/editor/icons/2x/icon_listener.png Binary files differindex 1441a81bdd..1441a81bdd 100644 --- a/tools/editor/icons/2x/icon_listener.png +++ b/editor/icons/2x/icon_listener.png diff --git a/tools/editor/icons/2x/icon_load.png b/editor/icons/2x/icon_load.png Binary files differindex 759381d636..759381d636 100644 --- a/tools/editor/icons/2x/icon_load.png +++ b/editor/icons/2x/icon_load.png diff --git a/tools/editor/icons/2x/icon_lock.png b/editor/icons/2x/icon_lock.png Binary files differindex 912eaf9eb9..912eaf9eb9 100644 --- a/tools/editor/icons/2x/icon_lock.png +++ b/editor/icons/2x/icon_lock.png diff --git a/tools/editor/icons/2x/icon_loop.png b/editor/icons/2x/icon_loop.png Binary files differindex bd1322ae00..bd1322ae00 100644 --- a/tools/editor/icons/2x/icon_loop.png +++ b/editor/icons/2x/icon_loop.png diff --git a/tools/editor/icons/2x/icon_loop_interpolation.png b/editor/icons/2x/icon_loop_interpolation.png Binary files differindex 6009b50300..6009b50300 100644 --- a/tools/editor/icons/2x/icon_loop_interpolation.png +++ b/editor/icons/2x/icon_loop_interpolation.png diff --git a/tools/editor/icons/2x/icon_main_play.png b/editor/icons/2x/icon_main_play.png Binary files differindex 1f69ce6f17..1f69ce6f17 100644 --- a/tools/editor/icons/2x/icon_main_play.png +++ b/editor/icons/2x/icon_main_play.png diff --git a/tools/editor/icons/2x/icon_main_stop.png b/editor/icons/2x/icon_main_stop.png Binary files differindex 5048141485..5048141485 100644 --- a/tools/editor/icons/2x/icon_main_stop.png +++ b/editor/icons/2x/icon_main_stop.png diff --git a/tools/editor/icons/2x/icon_margin_container.png b/editor/icons/2x/icon_margin_container.png Binary files differindex 10eda265e0..10eda265e0 100644 --- a/tools/editor/icons/2x/icon_margin_container.png +++ b/editor/icons/2x/icon_margin_container.png diff --git a/tools/editor/icons/2x/icon_material_preview_cube.png b/editor/icons/2x/icon_material_preview_cube.png Binary files differindex 2507c969c3..2507c969c3 100644 --- a/tools/editor/icons/2x/icon_material_preview_cube.png +++ b/editor/icons/2x/icon_material_preview_cube.png diff --git a/tools/editor/icons/2x/icon_material_preview_cube_off.png b/editor/icons/2x/icon_material_preview_cube_off.png Binary files differindex 079b3a6645..079b3a6645 100644 --- a/tools/editor/icons/2x/icon_material_preview_cube_off.png +++ b/editor/icons/2x/icon_material_preview_cube_off.png diff --git a/tools/editor/icons/2x/icon_material_preview_light_1.png b/editor/icons/2x/icon_material_preview_light_1.png Binary files differindex f1d0ccdaca..f1d0ccdaca 100644 --- a/tools/editor/icons/2x/icon_material_preview_light_1.png +++ b/editor/icons/2x/icon_material_preview_light_1.png diff --git a/tools/editor/icons/2x/icon_material_preview_light_1_off.png b/editor/icons/2x/icon_material_preview_light_1_off.png Binary files differindex 5a42b7f2a1..5a42b7f2a1 100644 --- a/tools/editor/icons/2x/icon_material_preview_light_1_off.png +++ b/editor/icons/2x/icon_material_preview_light_1_off.png diff --git a/tools/editor/icons/2x/icon_material_preview_light_2.png b/editor/icons/2x/icon_material_preview_light_2.png Binary files differindex 934e696b51..934e696b51 100644 --- a/tools/editor/icons/2x/icon_material_preview_light_2.png +++ b/editor/icons/2x/icon_material_preview_light_2.png diff --git a/tools/editor/icons/2x/icon_material_preview_light_2_off.png b/editor/icons/2x/icon_material_preview_light_2_off.png Binary files differindex 1aa4c0bb79..1aa4c0bb79 100644 --- a/tools/editor/icons/2x/icon_material_preview_light_2_off.png +++ b/editor/icons/2x/icon_material_preview_light_2_off.png diff --git a/tools/editor/icons/2x/icon_material_preview_sphere.png b/editor/icons/2x/icon_material_preview_sphere.png Binary files differindex f5cc7f7819..f5cc7f7819 100644 --- a/tools/editor/icons/2x/icon_material_preview_sphere.png +++ b/editor/icons/2x/icon_material_preview_sphere.png diff --git a/tools/editor/icons/2x/icon_material_preview_sphere_off.png b/editor/icons/2x/icon_material_preview_sphere_off.png Binary files differindex 7ccef62553..7ccef62553 100644 --- a/tools/editor/icons/2x/icon_material_preview_sphere_off.png +++ b/editor/icons/2x/icon_material_preview_sphere_off.png diff --git a/tools/editor/icons/2x/icon_material_shader.png b/editor/icons/2x/icon_material_shader.png Binary files differindex f8c2e15fcb..f8c2e15fcb 100644 --- a/tools/editor/icons/2x/icon_material_shader.png +++ b/editor/icons/2x/icon_material_shader.png diff --git a/tools/editor/icons/2x/icon_material_shader_graph.png b/editor/icons/2x/icon_material_shader_graph.png Binary files differindex a26a9754fe..a26a9754fe 100644 --- a/tools/editor/icons/2x/icon_material_shader_graph.png +++ b/editor/icons/2x/icon_material_shader_graph.png diff --git a/tools/editor/icons/2x/icon_matrix.png b/editor/icons/2x/icon_matrix.png Binary files differindex 0ac4ae170b..0ac4ae170b 100644 --- a/tools/editor/icons/2x/icon_matrix.png +++ b/editor/icons/2x/icon_matrix.png diff --git a/tools/editor/icons/2x/icon_menu_button.png b/editor/icons/2x/icon_menu_button.png Binary files differindex abf9b490e3..abf9b490e3 100644 --- a/tools/editor/icons/2x/icon_menu_button.png +++ b/editor/icons/2x/icon_menu_button.png diff --git a/tools/editor/icons/2x/icon_mesh.png b/editor/icons/2x/icon_mesh.png Binary files differindex 19b9095619..19b9095619 100644 --- a/tools/editor/icons/2x/icon_mesh.png +++ b/editor/icons/2x/icon_mesh.png diff --git a/tools/editor/icons/2x/icon_mesh_instance.png b/editor/icons/2x/icon_mesh_instance.png Binary files differindex 02f3f5ffaa..02f3f5ffaa 100644 --- a/tools/editor/icons/2x/icon_mesh_instance.png +++ b/editor/icons/2x/icon_mesh_instance.png diff --git a/tools/editor/icons/2x/icon_mesh_library.png b/editor/icons/2x/icon_mesh_library.png Binary files differindex 2495e4a037..2495e4a037 100644 --- a/tools/editor/icons/2x/icon_mesh_library.png +++ b/editor/icons/2x/icon_mesh_library.png diff --git a/tools/editor/icons/2x/icon_mini_aabb.png b/editor/icons/2x/icon_mini_aabb.png Binary files differindex 25603eec49..25603eec49 100644 --- a/tools/editor/icons/2x/icon_mini_aabb.png +++ b/editor/icons/2x/icon_mini_aabb.png diff --git a/tools/editor/icons/2x/icon_mini_array.png b/editor/icons/2x/icon_mini_array.png Binary files differindex 5c7bde2639..5c7bde2639 100644 --- a/tools/editor/icons/2x/icon_mini_array.png +++ b/editor/icons/2x/icon_mini_array.png diff --git a/tools/editor/icons/2x/icon_mini_boolean.png b/editor/icons/2x/icon_mini_boolean.png Binary files differindex a7d00056bb..a7d00056bb 100644 --- a/tools/editor/icons/2x/icon_mini_boolean.png +++ b/editor/icons/2x/icon_mini_boolean.png diff --git a/tools/editor/icons/2x/icon_mini_color.png b/editor/icons/2x/icon_mini_color.png Binary files differindex f4059bfb91..f4059bfb91 100644 --- a/tools/editor/icons/2x/icon_mini_color.png +++ b/editor/icons/2x/icon_mini_color.png diff --git a/tools/editor/icons/2x/icon_mini_color_array.png b/editor/icons/2x/icon_mini_color_array.png Binary files differindex 26f1d9fce4..26f1d9fce4 100644 --- a/tools/editor/icons/2x/icon_mini_color_array.png +++ b/editor/icons/2x/icon_mini_color_array.png diff --git a/tools/editor/icons/2x/icon_mini_dictionary.png b/editor/icons/2x/icon_mini_dictionary.png Binary files differindex 241e0587b4..241e0587b4 100644 --- a/tools/editor/icons/2x/icon_mini_dictionary.png +++ b/editor/icons/2x/icon_mini_dictionary.png diff --git a/tools/editor/icons/2x/icon_mini_float.png b/editor/icons/2x/icon_mini_float.png Binary files differindex 6edf76ece1..6edf76ece1 100644 --- a/tools/editor/icons/2x/icon_mini_float.png +++ b/editor/icons/2x/icon_mini_float.png diff --git a/tools/editor/icons/2x/icon_mini_float_array.png b/editor/icons/2x/icon_mini_float_array.png Binary files differindex 5a79fab721..5a79fab721 100644 --- a/tools/editor/icons/2x/icon_mini_float_array.png +++ b/editor/icons/2x/icon_mini_float_array.png diff --git a/tools/editor/icons/2x/icon_mini_image.png b/editor/icons/2x/icon_mini_image.png Binary files differindex 98faebeef2..98faebeef2 100644 --- a/tools/editor/icons/2x/icon_mini_image.png +++ b/editor/icons/2x/icon_mini_image.png diff --git a/tools/editor/icons/2x/icon_mini_input.png b/editor/icons/2x/icon_mini_input.png Binary files differindex 48536e156c..48536e156c 100644 --- a/tools/editor/icons/2x/icon_mini_input.png +++ b/editor/icons/2x/icon_mini_input.png diff --git a/tools/editor/icons/2x/icon_mini_int_array.png b/editor/icons/2x/icon_mini_int_array.png Binary files differindex 790ed44c30..790ed44c30 100644 --- a/tools/editor/icons/2x/icon_mini_int_array.png +++ b/editor/icons/2x/icon_mini_int_array.png diff --git a/tools/editor/icons/2x/icon_mini_integer.png b/editor/icons/2x/icon_mini_integer.png Binary files differindex cd9118f024..cd9118f024 100644 --- a/tools/editor/icons/2x/icon_mini_integer.png +++ b/editor/icons/2x/icon_mini_integer.png diff --git a/tools/editor/icons/2x/icon_mini_matrix3.png b/editor/icons/2x/icon_mini_matrix3.png Binary files differindex 93783177e1..93783177e1 100644 --- a/tools/editor/icons/2x/icon_mini_matrix3.png +++ b/editor/icons/2x/icon_mini_matrix3.png diff --git a/tools/editor/icons/2x/icon_mini_matrix32.png b/editor/icons/2x/icon_mini_matrix32.png Binary files differindex c2f7ea3817..c2f7ea3817 100644 --- a/tools/editor/icons/2x/icon_mini_matrix32.png +++ b/editor/icons/2x/icon_mini_matrix32.png diff --git a/tools/editor/icons/2x/icon_mini_object.png b/editor/icons/2x/icon_mini_object.png Binary files differindex 7987f750ff..7987f750ff 100644 --- a/tools/editor/icons/2x/icon_mini_object.png +++ b/editor/icons/2x/icon_mini_object.png diff --git a/tools/editor/icons/2x/icon_mini_path.png b/editor/icons/2x/icon_mini_path.png Binary files differindex 2e60a46086..2e60a46086 100644 --- a/tools/editor/icons/2x/icon_mini_path.png +++ b/editor/icons/2x/icon_mini_path.png diff --git a/tools/editor/icons/2x/icon_mini_plane.png b/editor/icons/2x/icon_mini_plane.png Binary files differindex 12b5cd26cc..12b5cd26cc 100644 --- a/tools/editor/icons/2x/icon_mini_plane.png +++ b/editor/icons/2x/icon_mini_plane.png diff --git a/tools/editor/icons/2x/icon_mini_quat.png b/editor/icons/2x/icon_mini_quat.png Binary files differindex 9a33902e59..9a33902e59 100644 --- a/tools/editor/icons/2x/icon_mini_quat.png +++ b/editor/icons/2x/icon_mini_quat.png diff --git a/tools/editor/icons/2x/icon_mini_raw_array.png b/editor/icons/2x/icon_mini_raw_array.png Binary files differindex 629b01e72a..629b01e72a 100644 --- a/tools/editor/icons/2x/icon_mini_raw_array.png +++ b/editor/icons/2x/icon_mini_raw_array.png diff --git a/tools/editor/icons/2x/icon_mini_rect2.png b/editor/icons/2x/icon_mini_rect2.png Binary files differindex 88b12e3a3a..88b12e3a3a 100644 --- a/tools/editor/icons/2x/icon_mini_rect2.png +++ b/editor/icons/2x/icon_mini_rect2.png diff --git a/tools/editor/icons/2x/icon_mini_rid.png b/editor/icons/2x/icon_mini_rid.png Binary files differindex 5388c19817..5388c19817 100644 --- a/tools/editor/icons/2x/icon_mini_rid.png +++ b/editor/icons/2x/icon_mini_rid.png diff --git a/tools/editor/icons/2x/icon_mini_string.png b/editor/icons/2x/icon_mini_string.png Binary files differindex 2264451c73..2264451c73 100644 --- a/tools/editor/icons/2x/icon_mini_string.png +++ b/editor/icons/2x/icon_mini_string.png diff --git a/tools/editor/icons/2x/icon_mini_string_array.png b/editor/icons/2x/icon_mini_string_array.png Binary files differindex fa8109b88a..fa8109b88a 100644 --- a/tools/editor/icons/2x/icon_mini_string_array.png +++ b/editor/icons/2x/icon_mini_string_array.png diff --git a/tools/editor/icons/2x/icon_mini_transform.png b/editor/icons/2x/icon_mini_transform.png Binary files differindex 5144871c5c..5144871c5c 100644 --- a/tools/editor/icons/2x/icon_mini_transform.png +++ b/editor/icons/2x/icon_mini_transform.png diff --git a/tools/editor/icons/2x/icon_mini_variant.png b/editor/icons/2x/icon_mini_variant.png Binary files differindex ae0aad16cf..ae0aad16cf 100644 --- a/tools/editor/icons/2x/icon_mini_variant.png +++ b/editor/icons/2x/icon_mini_variant.png diff --git a/tools/editor/icons/2x/icon_mini_vector2.png b/editor/icons/2x/icon_mini_vector2.png Binary files differindex 9e608e61c1..9e608e61c1 100644 --- a/tools/editor/icons/2x/icon_mini_vector2.png +++ b/editor/icons/2x/icon_mini_vector2.png diff --git a/tools/editor/icons/2x/icon_mini_vector2_array.png b/editor/icons/2x/icon_mini_vector2_array.png Binary files differindex 247c0e2592..247c0e2592 100644 --- a/tools/editor/icons/2x/icon_mini_vector2_array.png +++ b/editor/icons/2x/icon_mini_vector2_array.png diff --git a/tools/editor/icons/2x/icon_mini_vector3.png b/editor/icons/2x/icon_mini_vector3.png Binary files differindex 0b84b4628f..0b84b4628f 100644 --- a/tools/editor/icons/2x/icon_mini_vector3.png +++ b/editor/icons/2x/icon_mini_vector3.png diff --git a/tools/editor/icons/2x/icon_mini_vector3_array.png b/editor/icons/2x/icon_mini_vector3_array.png Binary files differindex 68058e4232..68058e4232 100644 --- a/tools/editor/icons/2x/icon_mini_vector3_array.png +++ b/editor/icons/2x/icon_mini_vector3_array.png diff --git a/tools/editor/icons/2x/icon_mirror_x.png b/editor/icons/2x/icon_mirror_x.png Binary files differindex 3b096dce88..3b096dce88 100644 --- a/tools/editor/icons/2x/icon_mirror_x.png +++ b/editor/icons/2x/icon_mirror_x.png diff --git a/tools/editor/icons/2x/icon_mirror_y.png b/editor/icons/2x/icon_mirror_y.png Binary files differindex 4c89b167b5..4c89b167b5 100644 --- a/tools/editor/icons/2x/icon_mirror_y.png +++ b/editor/icons/2x/icon_mirror_y.png diff --git a/tools/editor/icons/2x/icon_mouse.png b/editor/icons/2x/icon_mouse.png Binary files differindex 9c4a76bd4f..9c4a76bd4f 100644 --- a/tools/editor/icons/2x/icon_mouse.png +++ b/editor/icons/2x/icon_mouse.png diff --git a/tools/editor/icons/2x/icon_move_down.png b/editor/icons/2x/icon_move_down.png Binary files differindex 97bbeea631..97bbeea631 100644 --- a/tools/editor/icons/2x/icon_move_down.png +++ b/editor/icons/2x/icon_move_down.png diff --git a/tools/editor/icons/2x/icon_move_point.png b/editor/icons/2x/icon_move_point.png Binary files differindex 5d135ae294..5d135ae294 100644 --- a/tools/editor/icons/2x/icon_move_point.png +++ b/editor/icons/2x/icon_move_point.png diff --git a/tools/editor/icons/2x/icon_move_up.png b/editor/icons/2x/icon_move_up.png Binary files differindex f8f31baeb1..f8f31baeb1 100644 --- a/tools/editor/icons/2x/icon_move_up.png +++ b/editor/icons/2x/icon_move_up.png diff --git a/tools/editor/icons/2x/icon_multi_edit.png b/editor/icons/2x/icon_multi_edit.png Binary files differindex 93360b93f7..93360b93f7 100644 --- a/tools/editor/icons/2x/icon_multi_edit.png +++ b/editor/icons/2x/icon_multi_edit.png diff --git a/tools/editor/icons/2x/icon_multi_line.png b/editor/icons/2x/icon_multi_line.png Binary files differindex 5d43b79e8a..5d43b79e8a 100644 --- a/tools/editor/icons/2x/icon_multi_line.png +++ b/editor/icons/2x/icon_multi_line.png diff --git a/tools/editor/icons/2x/icon_multi_mesh.png b/editor/icons/2x/icon_multi_mesh.png Binary files differindex 35b99d6698..35b99d6698 100644 --- a/tools/editor/icons/2x/icon_multi_mesh.png +++ b/editor/icons/2x/icon_multi_mesh.png diff --git a/tools/editor/icons/2x/icon_multi_mesh_instance.png b/editor/icons/2x/icon_multi_mesh_instance.png Binary files differindex f69768c6e3..f69768c6e3 100644 --- a/tools/editor/icons/2x/icon_multi_mesh_instance.png +++ b/editor/icons/2x/icon_multi_mesh_instance.png diff --git a/tools/editor/icons/2x/icon_multi_node_edit.png b/editor/icons/2x/icon_multi_node_edit.png Binary files differindex 93360b93f7..93360b93f7 100644 --- a/tools/editor/icons/2x/icon_multi_node_edit.png +++ b/editor/icons/2x/icon_multi_node_edit.png diff --git a/tools/editor/icons/2x/icon_navigation.png b/editor/icons/2x/icon_navigation.png Binary files differindex 3cd838d2fc..3cd838d2fc 100644 --- a/tools/editor/icons/2x/icon_navigation.png +++ b/editor/icons/2x/icon_navigation.png diff --git a/tools/editor/icons/2x/icon_navigation_2d.png b/editor/icons/2x/icon_navigation_2d.png Binary files differindex 9efbeaaef0..9efbeaaef0 100644 --- a/tools/editor/icons/2x/icon_navigation_2d.png +++ b/editor/icons/2x/icon_navigation_2d.png diff --git a/tools/editor/icons/2x/icon_navigation_mesh.png b/editor/icons/2x/icon_navigation_mesh.png Binary files differindex 35b893c3bb..35b893c3bb 100644 --- a/tools/editor/icons/2x/icon_navigation_mesh.png +++ b/editor/icons/2x/icon_navigation_mesh.png diff --git a/tools/editor/icons/2x/icon_navigation_mesh_instance.png b/editor/icons/2x/icon_navigation_mesh_instance.png Binary files differindex 404fad2d31..404fad2d31 100644 --- a/tools/editor/icons/2x/icon_navigation_mesh_instance.png +++ b/editor/icons/2x/icon_navigation_mesh_instance.png diff --git a/tools/editor/icons/2x/icon_navigation_polygon.png b/editor/icons/2x/icon_navigation_polygon.png Binary files differindex 3f4845e206..3f4845e206 100644 --- a/tools/editor/icons/2x/icon_navigation_polygon.png +++ b/editor/icons/2x/icon_navigation_polygon.png diff --git a/tools/editor/icons/2x/icon_navigation_polygon_instance.png b/editor/icons/2x/icon_navigation_polygon_instance.png Binary files differindex 5556835d76..5556835d76 100644 --- a/tools/editor/icons/2x/icon_navigation_polygon_instance.png +++ b/editor/icons/2x/icon_navigation_polygon_instance.png diff --git a/tools/editor/icons/2x/icon_new.png b/editor/icons/2x/icon_new.png Binary files differindex 683f1141fd..683f1141fd 100644 --- a/tools/editor/icons/2x/icon_new.png +++ b/editor/icons/2x/icon_new.png diff --git a/tools/editor/icons/2x/icon_nine_patch_rect.png b/editor/icons/2x/icon_nine_patch_rect.png Binary files differindex 5762a0392e..5762a0392e 100644 --- a/tools/editor/icons/2x/icon_nine_patch_rect.png +++ b/editor/icons/2x/icon_nine_patch_rect.png diff --git a/tools/editor/icons/2x/icon_node.png b/editor/icons/2x/icon_node.png Binary files differindex e487f988a2..e487f988a2 100644 --- a/tools/editor/icons/2x/icon_node.png +++ b/editor/icons/2x/icon_node.png diff --git a/tools/editor/icons/2x/icon_node_2d.png b/editor/icons/2x/icon_node_2d.png Binary files differindex 967d4b7da6..967d4b7da6 100644 --- a/tools/editor/icons/2x/icon_node_2d.png +++ b/editor/icons/2x/icon_node_2d.png diff --git a/tools/editor/icons/2x/icon_node_warning.png b/editor/icons/2x/icon_node_warning.png Binary files differindex 397a57bf1f..397a57bf1f 100644 --- a/tools/editor/icons/2x/icon_node_warning.png +++ b/editor/icons/2x/icon_node_warning.png diff --git a/tools/editor/icons/2x/icon_non_favorite.png b/editor/icons/2x/icon_non_favorite.png Binary files differindex 18aa94e6b9..18aa94e6b9 100644 --- a/tools/editor/icons/2x/icon_non_favorite.png +++ b/editor/icons/2x/icon_non_favorite.png diff --git a/tools/editor/icons/2x/icon_object.png b/editor/icons/2x/icon_object.png Binary files differindex dc0a94aacd..dc0a94aacd 100644 --- a/tools/editor/icons/2x/icon_object.png +++ b/editor/icons/2x/icon_object.png diff --git a/tools/editor/icons/2x/icon_occluder_polygon_2d.png b/editor/icons/2x/icon_occluder_polygon_2d.png Binary files differindex e5e27dda32..e5e27dda32 100644 --- a/tools/editor/icons/2x/icon_occluder_polygon_2d.png +++ b/editor/icons/2x/icon_occluder_polygon_2d.png diff --git a/tools/editor/icons/2x/icon_omni_light.png b/editor/icons/2x/icon_omni_light.png Binary files differindex 2c44252b9c..2c44252b9c 100644 --- a/tools/editor/icons/2x/icon_omni_light.png +++ b/editor/icons/2x/icon_omni_light.png diff --git a/tools/editor/icons/2x/icon_open.png b/editor/icons/2x/icon_open.png Binary files differindex 2e797c448b..2e797c448b 100644 --- a/tools/editor/icons/2x/icon_open.png +++ b/editor/icons/2x/icon_open.png diff --git a/tools/editor/icons/2x/icon_option_button.png b/editor/icons/2x/icon_option_button.png Binary files differindex f4438f9efd..f4438f9efd 100644 --- a/tools/editor/icons/2x/icon_option_button.png +++ b/editor/icons/2x/icon_option_button.png diff --git a/tools/editor/icons/2x/icon_override.png b/editor/icons/2x/icon_override.png Binary files differindex d735a1c734..d735a1c734 100644 --- a/tools/editor/icons/2x/icon_override.png +++ b/editor/icons/2x/icon_override.png diff --git a/tools/editor/icons/2x/icon_p_hash_translation.png b/editor/icons/2x/icon_p_hash_translation.png Binary files differindex 0ddc1da282..0ddc1da282 100644 --- a/tools/editor/icons/2x/icon_p_hash_translation.png +++ b/editor/icons/2x/icon_p_hash_translation.png diff --git a/tools/editor/icons/2x/icon_packed_data_container.png b/editor/icons/2x/icon_packed_data_container.png Binary files differindex 958e41ede2..958e41ede2 100644 --- a/tools/editor/icons/2x/icon_packed_data_container.png +++ b/editor/icons/2x/icon_packed_data_container.png diff --git a/tools/editor/icons/2x/icon_packed_scene.png b/editor/icons/2x/icon_packed_scene.png Binary files differindex 00778e8c0a..00778e8c0a 100644 --- a/tools/editor/icons/2x/icon_packed_scene.png +++ b/editor/icons/2x/icon_packed_scene.png diff --git a/tools/editor/icons/2x/icon_panel.png b/editor/icons/2x/icon_panel.png Binary files differindex 23491a7358..23491a7358 100644 --- a/tools/editor/icons/2x/icon_panel.png +++ b/editor/icons/2x/icon_panel.png diff --git a/tools/editor/icons/2x/icon_panel_container.png b/editor/icons/2x/icon_panel_container.png Binary files differindex fb2980ee8b..fb2980ee8b 100644 --- a/tools/editor/icons/2x/icon_panel_container.png +++ b/editor/icons/2x/icon_panel_container.png diff --git a/tools/editor/icons/2x/icon_panels_1.png b/editor/icons/2x/icon_panels_1.png Binary files differindex b8386daa2e..b8386daa2e 100644 --- a/tools/editor/icons/2x/icon_panels_1.png +++ b/editor/icons/2x/icon_panels_1.png diff --git a/tools/editor/icons/2x/icon_panels_2.png b/editor/icons/2x/icon_panels_2.png Binary files differindex 4d9f3ef724..4d9f3ef724 100644 --- a/tools/editor/icons/2x/icon_panels_2.png +++ b/editor/icons/2x/icon_panels_2.png diff --git a/tools/editor/icons/2x/icon_panels_2_alt.png b/editor/icons/2x/icon_panels_2_alt.png Binary files differindex 69aeecce34..69aeecce34 100644 --- a/tools/editor/icons/2x/icon_panels_2_alt.png +++ b/editor/icons/2x/icon_panels_2_alt.png diff --git a/tools/editor/icons/2x/icon_panels_3.png b/editor/icons/2x/icon_panels_3.png Binary files differindex e889504f15..e889504f15 100644 --- a/tools/editor/icons/2x/icon_panels_3.png +++ b/editor/icons/2x/icon_panels_3.png diff --git a/tools/editor/icons/2x/icon_panels_3_alt.png b/editor/icons/2x/icon_panels_3_alt.png Binary files differindex 1e9a17ca75..1e9a17ca75 100644 --- a/tools/editor/icons/2x/icon_panels_3_alt.png +++ b/editor/icons/2x/icon_panels_3_alt.png diff --git a/tools/editor/icons/2x/icon_panels_4.png b/editor/icons/2x/icon_panels_4.png Binary files differindex 62e77e417a..62e77e417a 100644 --- a/tools/editor/icons/2x/icon_panels_4.png +++ b/editor/icons/2x/icon_panels_4.png diff --git a/tools/editor/icons/2x/icon_parallax_background.png b/editor/icons/2x/icon_parallax_background.png Binary files differindex a81046e805..a81046e805 100644 --- a/tools/editor/icons/2x/icon_parallax_background.png +++ b/editor/icons/2x/icon_parallax_background.png diff --git a/tools/editor/icons/2x/icon_parallax_layer.png b/editor/icons/2x/icon_parallax_layer.png Binary files differindex 285999df61..285999df61 100644 --- a/tools/editor/icons/2x/icon_parallax_layer.png +++ b/editor/icons/2x/icon_parallax_layer.png diff --git a/tools/editor/icons/2x/icon_particle_attractor_2d.png b/editor/icons/2x/icon_particle_attractor_2d.png Binary files differindex b985a0ba57..b985a0ba57 100644 --- a/tools/editor/icons/2x/icon_particle_attractor_2d.png +++ b/editor/icons/2x/icon_particle_attractor_2d.png diff --git a/tools/editor/icons/2x/icon_particles.png b/editor/icons/2x/icon_particles.png Binary files differindex 68f30b4213..68f30b4213 100644 --- a/tools/editor/icons/2x/icon_particles.png +++ b/editor/icons/2x/icon_particles.png diff --git a/tools/editor/icons/2x/icon_particles_2d.png b/editor/icons/2x/icon_particles_2d.png Binary files differindex 13fc8a35e6..13fc8a35e6 100644 --- a/tools/editor/icons/2x/icon_particles_2d.png +++ b/editor/icons/2x/icon_particles_2d.png diff --git a/tools/editor/icons/2x/icon_particles_shader.png b/editor/icons/2x/icon_particles_shader.png Binary files differindex 26ce8f6809..26ce8f6809 100644 --- a/tools/editor/icons/2x/icon_particles_shader.png +++ b/editor/icons/2x/icon_particles_shader.png diff --git a/tools/editor/icons/2x/icon_patch_9_rect.png b/editor/icons/2x/icon_patch_9_rect.png Binary files differindex 5762a0392e..5762a0392e 100644 --- a/tools/editor/icons/2x/icon_patch_9_rect.png +++ b/editor/icons/2x/icon_patch_9_rect.png diff --git a/tools/editor/icons/2x/icon_path.png b/editor/icons/2x/icon_path.png Binary files differindex d10cb37bcd..d10cb37bcd 100644 --- a/tools/editor/icons/2x/icon_path.png +++ b/editor/icons/2x/icon_path.png diff --git a/tools/editor/icons/2x/icon_path_2d.png b/editor/icons/2x/icon_path_2d.png Binary files differindex dabf5ccc49..dabf5ccc49 100644 --- a/tools/editor/icons/2x/icon_path_2d.png +++ b/editor/icons/2x/icon_path_2d.png diff --git a/tools/editor/icons/2x/icon_path_follow.png b/editor/icons/2x/icon_path_follow.png Binary files differindex 8538b1f3b9..8538b1f3b9 100644 --- a/tools/editor/icons/2x/icon_path_follow.png +++ b/editor/icons/2x/icon_path_follow.png diff --git a/tools/editor/icons/2x/icon_path_follow_2d.png b/editor/icons/2x/icon_path_follow_2d.png Binary files differindex a83ed837ba..a83ed837ba 100644 --- a/tools/editor/icons/2x/icon_path_follow_2d.png +++ b/editor/icons/2x/icon_path_follow_2d.png diff --git a/tools/editor/icons/2x/icon_pause.png b/editor/icons/2x/icon_pause.png Binary files differindex 35e6b25294..35e6b25294 100644 --- a/tools/editor/icons/2x/icon_pause.png +++ b/editor/icons/2x/icon_pause.png diff --git a/tools/editor/icons/2x/icon_pin.png b/editor/icons/2x/icon_pin.png Binary files differindex d19fe7afef..d19fe7afef 100644 --- a/tools/editor/icons/2x/icon_pin.png +++ b/editor/icons/2x/icon_pin.png diff --git a/tools/editor/icons/2x/icon_pin_joint.png b/editor/icons/2x/icon_pin_joint.png Binary files differindex 304cb39724..304cb39724 100644 --- a/tools/editor/icons/2x/icon_pin_joint.png +++ b/editor/icons/2x/icon_pin_joint.png diff --git a/tools/editor/icons/2x/icon_pin_joint_2d.png b/editor/icons/2x/icon_pin_joint_2d.png Binary files differindex a2302c4756..a2302c4756 100644 --- a/tools/editor/icons/2x/icon_pin_joint_2d.png +++ b/editor/icons/2x/icon_pin_joint_2d.png diff --git a/tools/editor/icons/2x/icon_pin_pressed.png b/editor/icons/2x/icon_pin_pressed.png Binary files differindex d19fe7afef..d19fe7afef 100644 --- a/tools/editor/icons/2x/icon_pin_pressed.png +++ b/editor/icons/2x/icon_pin_pressed.png diff --git a/tools/editor/icons/2x/icon_plane.png b/editor/icons/2x/icon_plane.png Binary files differindex a096e30065..a096e30065 100644 --- a/tools/editor/icons/2x/icon_plane.png +++ b/editor/icons/2x/icon_plane.png diff --git a/tools/editor/icons/2x/icon_plane_shape.png b/editor/icons/2x/icon_plane_shape.png Binary files differindex 8ebd38fe83..8ebd38fe83 100644 --- a/tools/editor/icons/2x/icon_plane_shape.png +++ b/editor/icons/2x/icon_plane_shape.png diff --git a/tools/editor/icons/2x/icon_play.png b/editor/icons/2x/icon_play.png Binary files differindex b84ed23091..b84ed23091 100644 --- a/tools/editor/icons/2x/icon_play.png +++ b/editor/icons/2x/icon_play.png diff --git a/tools/editor/icons/2x/icon_play_backwards.png b/editor/icons/2x/icon_play_backwards.png Binary files differindex 42aeca74e5..42aeca74e5 100644 --- a/tools/editor/icons/2x/icon_play_backwards.png +++ b/editor/icons/2x/icon_play_backwards.png diff --git a/tools/editor/icons/2x/icon_play_custom.png b/editor/icons/2x/icon_play_custom.png Binary files differindex 299ac3ffbc..299ac3ffbc 100644 --- a/tools/editor/icons/2x/icon_play_custom.png +++ b/editor/icons/2x/icon_play_custom.png diff --git a/tools/editor/icons/2x/icon_play_scene.png b/editor/icons/2x/icon_play_scene.png Binary files differindex 948a2e9ba5..948a2e9ba5 100644 --- a/tools/editor/icons/2x/icon_play_scene.png +++ b/editor/icons/2x/icon_play_scene.png diff --git a/tools/editor/icons/2x/icon_play_start.png b/editor/icons/2x/icon_play_start.png Binary files differindex 227e1b6f19..227e1b6f19 100644 --- a/tools/editor/icons/2x/icon_play_start.png +++ b/editor/icons/2x/icon_play_start.png diff --git a/tools/editor/icons/2x/icon_play_start_backwards.png b/editor/icons/2x/icon_play_start_backwards.png Binary files differindex e9a46325f6..e9a46325f6 100644 --- a/tools/editor/icons/2x/icon_play_start_backwards.png +++ b/editor/icons/2x/icon_play_start_backwards.png diff --git a/tools/editor/icons/2x/icon_polygon_2d.png b/editor/icons/2x/icon_polygon_2d.png Binary files differindex 491ebfaa78..491ebfaa78 100644 --- a/tools/editor/icons/2x/icon_polygon_2d.png +++ b/editor/icons/2x/icon_polygon_2d.png diff --git a/tools/editor/icons/2x/icon_polygon_path_finder.png b/editor/icons/2x/icon_polygon_path_finder.png Binary files differindex ee6423c265..ee6423c265 100644 --- a/tools/editor/icons/2x/icon_polygon_path_finder.png +++ b/editor/icons/2x/icon_polygon_path_finder.png diff --git a/tools/editor/icons/2x/icon_popup.png b/editor/icons/2x/icon_popup.png Binary files differindex 7bcfb114da..7bcfb114da 100644 --- a/tools/editor/icons/2x/icon_popup.png +++ b/editor/icons/2x/icon_popup.png diff --git a/tools/editor/icons/2x/icon_popup_dialog.png b/editor/icons/2x/icon_popup_dialog.png Binary files differindex 6920fa27bf..6920fa27bf 100644 --- a/tools/editor/icons/2x/icon_popup_dialog.png +++ b/editor/icons/2x/icon_popup_dialog.png diff --git a/tools/editor/icons/2x/icon_popup_menu.png b/editor/icons/2x/icon_popup_menu.png Binary files differindex 4e0246879b..4e0246879b 100644 --- a/tools/editor/icons/2x/icon_popup_menu.png +++ b/editor/icons/2x/icon_popup_menu.png diff --git a/tools/editor/icons/2x/icon_popup_panel.png b/editor/icons/2x/icon_popup_panel.png Binary files differindex 15d977cc81..15d977cc81 100644 --- a/tools/editor/icons/2x/icon_popup_panel.png +++ b/editor/icons/2x/icon_popup_panel.png diff --git a/tools/editor/icons/2x/icon_portal.png b/editor/icons/2x/icon_portal.png Binary files differindex c934e65fc4..c934e65fc4 100644 --- a/tools/editor/icons/2x/icon_portal.png +++ b/editor/icons/2x/icon_portal.png diff --git a/tools/editor/icons/2x/icon_position_2d.png b/editor/icons/2x/icon_position_2d.png Binary files differindex 176a2300ef..176a2300ef 100644 --- a/tools/editor/icons/2x/icon_position_2d.png +++ b/editor/icons/2x/icon_position_2d.png diff --git a/tools/editor/icons/2x/icon_position_3d.png b/editor/icons/2x/icon_position_3d.png Binary files differindex ed19f011b0..ed19f011b0 100644 --- a/tools/editor/icons/2x/icon_position_3d.png +++ b/editor/icons/2x/icon_position_3d.png diff --git a/tools/editor/icons/2x/icon_progress_1.png b/editor/icons/2x/icon_progress_1.png Binary files differindex b73dded521..b73dded521 100644 --- a/tools/editor/icons/2x/icon_progress_1.png +++ b/editor/icons/2x/icon_progress_1.png diff --git a/tools/editor/icons/2x/icon_progress_2.png b/editor/icons/2x/icon_progress_2.png Binary files differindex 19d89bd369..19d89bd369 100644 --- a/tools/editor/icons/2x/icon_progress_2.png +++ b/editor/icons/2x/icon_progress_2.png diff --git a/tools/editor/icons/2x/icon_progress_3.png b/editor/icons/2x/icon_progress_3.png Binary files differindex ca6b270ef7..ca6b270ef7 100644 --- a/tools/editor/icons/2x/icon_progress_3.png +++ b/editor/icons/2x/icon_progress_3.png diff --git a/tools/editor/icons/2x/icon_progress_4.png b/editor/icons/2x/icon_progress_4.png Binary files differindex 3afa1f845e..3afa1f845e 100644 --- a/tools/editor/icons/2x/icon_progress_4.png +++ b/editor/icons/2x/icon_progress_4.png diff --git a/tools/editor/icons/2x/icon_progress_5.png b/editor/icons/2x/icon_progress_5.png Binary files differindex 8230048771..8230048771 100644 --- a/tools/editor/icons/2x/icon_progress_5.png +++ b/editor/icons/2x/icon_progress_5.png diff --git a/tools/editor/icons/2x/icon_progress_6.png b/editor/icons/2x/icon_progress_6.png Binary files differindex 6c21a5d053..6c21a5d053 100644 --- a/tools/editor/icons/2x/icon_progress_6.png +++ b/editor/icons/2x/icon_progress_6.png diff --git a/tools/editor/icons/2x/icon_progress_7.png b/editor/icons/2x/icon_progress_7.png Binary files differindex 96316b54ca..96316b54ca 100644 --- a/tools/editor/icons/2x/icon_progress_7.png +++ b/editor/icons/2x/icon_progress_7.png diff --git a/tools/editor/icons/2x/icon_progress_8.png b/editor/icons/2x/icon_progress_8.png Binary files differindex 95133b380d..95133b380d 100644 --- a/tools/editor/icons/2x/icon_progress_8.png +++ b/editor/icons/2x/icon_progress_8.png diff --git a/tools/editor/icons/2x/icon_progress_bar.png b/editor/icons/2x/icon_progress_bar.png Binary files differindex f9a243032e..f9a243032e 100644 --- a/tools/editor/icons/2x/icon_progress_bar.png +++ b/editor/icons/2x/icon_progress_bar.png diff --git a/tools/editor/icons/2x/icon_proximity_group.png b/editor/icons/2x/icon_proximity_group.png Binary files differindex 6602afa7ce..6602afa7ce 100644 --- a/tools/editor/icons/2x/icon_proximity_group.png +++ b/editor/icons/2x/icon_proximity_group.png diff --git a/tools/editor/icons/2x/icon_quad.png b/editor/icons/2x/icon_quad.png Binary files differindex a4074cd5b6..a4074cd5b6 100644 --- a/tools/editor/icons/2x/icon_quad.png +++ b/editor/icons/2x/icon_quad.png diff --git a/tools/editor/icons/2x/icon_quat.png b/editor/icons/2x/icon_quat.png Binary files differindex f909e134f4..f909e134f4 100644 --- a/tools/editor/icons/2x/icon_quat.png +++ b/editor/icons/2x/icon_quat.png diff --git a/tools/editor/icons/2x/icon_range.png b/editor/icons/2x/icon_range.png Binary files differindex 92c0934df6..92c0934df6 100644 --- a/tools/editor/icons/2x/icon_range.png +++ b/editor/icons/2x/icon_range.png diff --git a/tools/editor/icons/2x/icon_rating_no_star.png b/editor/icons/2x/icon_rating_no_star.png Binary files differindex f855fd8b56..f855fd8b56 100644 --- a/tools/editor/icons/2x/icon_rating_no_star.png +++ b/editor/icons/2x/icon_rating_no_star.png diff --git a/tools/editor/icons/2x/icon_rating_star.png b/editor/icons/2x/icon_rating_star.png Binary files differindex bfe082d330..bfe082d330 100644 --- a/tools/editor/icons/2x/icon_rating_star.png +++ b/editor/icons/2x/icon_rating_star.png diff --git a/tools/editor/icons/2x/icon_ray_cast.png b/editor/icons/2x/icon_ray_cast.png Binary files differindex 26d958ac2b..26d958ac2b 100644 --- a/tools/editor/icons/2x/icon_ray_cast.png +++ b/editor/icons/2x/icon_ray_cast.png diff --git a/tools/editor/icons/2x/icon_ray_cast_2d.png b/editor/icons/2x/icon_ray_cast_2d.png Binary files differindex e496cdcc2b..e496cdcc2b 100644 --- a/tools/editor/icons/2x/icon_ray_cast_2d.png +++ b/editor/icons/2x/icon_ray_cast_2d.png diff --git a/tools/editor/icons/2x/icon_ray_shape.png b/editor/icons/2x/icon_ray_shape.png Binary files differindex 54a1cf8fe9..54a1cf8fe9 100644 --- a/tools/editor/icons/2x/icon_ray_shape.png +++ b/editor/icons/2x/icon_ray_shape.png diff --git a/tools/editor/icons/2x/icon_ray_shape_2d.png b/editor/icons/2x/icon_ray_shape_2d.png Binary files differindex 2dc7041a93..2dc7041a93 100644 --- a/tools/editor/icons/2x/icon_ray_shape_2d.png +++ b/editor/icons/2x/icon_ray_shape_2d.png diff --git a/tools/editor/icons/2x/icon_rayito.png b/editor/icons/2x/icon_rayito.png Binary files differindex 1959b8bf00..1959b8bf00 100644 --- a/tools/editor/icons/2x/icon_rayito.png +++ b/editor/icons/2x/icon_rayito.png diff --git a/tools/editor/icons/2x/icon_real.png b/editor/icons/2x/icon_real.png Binary files differindex 5ec56ebcac..5ec56ebcac 100644 --- a/tools/editor/icons/2x/icon_real.png +++ b/editor/icons/2x/icon_real.png diff --git a/tools/editor/icons/2x/icon_rectangle_shape_2d.png b/editor/icons/2x/icon_rectangle_shape_2d.png Binary files differindex 51a93cdb1d..51a93cdb1d 100644 --- a/tools/editor/icons/2x/icon_rectangle_shape_2d.png +++ b/editor/icons/2x/icon_rectangle_shape_2d.png diff --git a/tools/editor/icons/2x/icon_reference_rect.png b/editor/icons/2x/icon_reference_rect.png Binary files differindex 63fe559fa7..63fe559fa7 100644 --- a/tools/editor/icons/2x/icon_reference_rect.png +++ b/editor/icons/2x/icon_reference_rect.png diff --git a/tools/editor/icons/2x/icon_reflection_probe.png b/editor/icons/2x/icon_reflection_probe.png Binary files differindex 5604b403df..5604b403df 100644 --- a/tools/editor/icons/2x/icon_reflection_probe.png +++ b/editor/icons/2x/icon_reflection_probe.png diff --git a/tools/editor/icons/2x/icon_region_edit.png b/editor/icons/2x/icon_region_edit.png Binary files differindex bcaba769d4..bcaba769d4 100644 --- a/tools/editor/icons/2x/icon_region_edit.png +++ b/editor/icons/2x/icon_region_edit.png diff --git a/tools/editor/icons/2x/icon_reload.png b/editor/icons/2x/icon_reload.png Binary files differindex b13c858124..b13c858124 100644 --- a/tools/editor/icons/2x/icon_reload.png +++ b/editor/icons/2x/icon_reload.png diff --git a/tools/editor/icons/2x/icon_reload_small.png b/editor/icons/2x/icon_reload_small.png Binary files differindex a278c34e4c..a278c34e4c 100644 --- a/tools/editor/icons/2x/icon_reload_small.png +++ b/editor/icons/2x/icon_reload_small.png diff --git a/tools/editor/icons/2x/icon_remote.png b/editor/icons/2x/icon_remote.png Binary files differindex 87883ed7e1..87883ed7e1 100644 --- a/tools/editor/icons/2x/icon_remote.png +++ b/editor/icons/2x/icon_remote.png diff --git a/tools/editor/icons/2x/icon_remote_transform.png b/editor/icons/2x/icon_remote_transform.png Binary files differindex dad528615a..dad528615a 100644 --- a/tools/editor/icons/2x/icon_remote_transform.png +++ b/editor/icons/2x/icon_remote_transform.png diff --git a/tools/editor/icons/2x/icon_remote_transform_2d.png b/editor/icons/2x/icon_remote_transform_2d.png Binary files differindex 7ef3e06f81..7ef3e06f81 100644 --- a/tools/editor/icons/2x/icon_remote_transform_2d.png +++ b/editor/icons/2x/icon_remote_transform_2d.png diff --git a/tools/editor/icons/2x/icon_remove.png b/editor/icons/2x/icon_remove.png Binary files differindex dbed177745..dbed177745 100644 --- a/tools/editor/icons/2x/icon_remove.png +++ b/editor/icons/2x/icon_remove.png diff --git a/tools/editor/icons/2x/icon_rename.png b/editor/icons/2x/icon_rename.png Binary files differindex a306a7b8c8..a306a7b8c8 100644 --- a/tools/editor/icons/2x/icon_rename.png +++ b/editor/icons/2x/icon_rename.png diff --git a/tools/editor/icons/2x/icon_reparent.png b/editor/icons/2x/icon_reparent.png Binary files differindex 3063da4b43..3063da4b43 100644 --- a/tools/editor/icons/2x/icon_reparent.png +++ b/editor/icons/2x/icon_reparent.png diff --git a/tools/editor/icons/2x/icon_resource_preloader.png b/editor/icons/2x/icon_resource_preloader.png Binary files differindex d48f37d21f..d48f37d21f 100644 --- a/tools/editor/icons/2x/icon_resource_preloader.png +++ b/editor/icons/2x/icon_resource_preloader.png diff --git a/tools/editor/icons/2x/icon_rich_text_label.png b/editor/icons/2x/icon_rich_text_label.png Binary files differindex 598913d896..598913d896 100644 --- a/tools/editor/icons/2x/icon_rich_text_label.png +++ b/editor/icons/2x/icon_rich_text_label.png diff --git a/tools/editor/icons/2x/icon_rigid_body.png b/editor/icons/2x/icon_rigid_body.png Binary files differindex 3b682f0033..3b682f0033 100644 --- a/tools/editor/icons/2x/icon_rigid_body.png +++ b/editor/icons/2x/icon_rigid_body.png diff --git a/tools/editor/icons/2x/icon_rigid_body_2d.png b/editor/icons/2x/icon_rigid_body_2d.png Binary files differindex bd45d2f01a..bd45d2f01a 100644 --- a/tools/editor/icons/2x/icon_rigid_body_2d.png +++ b/editor/icons/2x/icon_rigid_body_2d.png diff --git a/tools/editor/icons/2x/icon_room.png b/editor/icons/2x/icon_room.png Binary files differindex 946f95e955..946f95e955 100644 --- a/tools/editor/icons/2x/icon_room.png +++ b/editor/icons/2x/icon_room.png diff --git a/tools/editor/icons/2x/icon_room_bounds.png b/editor/icons/2x/icon_room_bounds.png Binary files differindex 94da9c437d..94da9c437d 100644 --- a/tools/editor/icons/2x/icon_room_bounds.png +++ b/editor/icons/2x/icon_room_bounds.png diff --git a/tools/editor/icons/2x/icon_rotate_0.png b/editor/icons/2x/icon_rotate_0.png Binary files differindex a4524b7856..a4524b7856 100644 --- a/tools/editor/icons/2x/icon_rotate_0.png +++ b/editor/icons/2x/icon_rotate_0.png diff --git a/tools/editor/icons/2x/icon_rotate_180.png b/editor/icons/2x/icon_rotate_180.png Binary files differindex a00e1b727c..a00e1b727c 100644 --- a/tools/editor/icons/2x/icon_rotate_180.png +++ b/editor/icons/2x/icon_rotate_180.png diff --git a/tools/editor/icons/2x/icon_rotate_270.png b/editor/icons/2x/icon_rotate_270.png Binary files differindex be56f080a9..be56f080a9 100644 --- a/tools/editor/icons/2x/icon_rotate_270.png +++ b/editor/icons/2x/icon_rotate_270.png diff --git a/tools/editor/icons/2x/icon_rotate_90.png b/editor/icons/2x/icon_rotate_90.png Binary files differindex a3a937892d..a3a937892d 100644 --- a/tools/editor/icons/2x/icon_rotate_90.png +++ b/editor/icons/2x/icon_rotate_90.png diff --git a/tools/editor/icons/2x/icon_sample.png b/editor/icons/2x/icon_sample.png Binary files differindex b01674f923..b01674f923 100644 --- a/tools/editor/icons/2x/icon_sample.png +++ b/editor/icons/2x/icon_sample.png diff --git a/tools/editor/icons/2x/icon_sample_library.png b/editor/icons/2x/icon_sample_library.png Binary files differindex 3f76a78aca..3f76a78aca 100644 --- a/tools/editor/icons/2x/icon_sample_library.png +++ b/editor/icons/2x/icon_sample_library.png diff --git a/tools/editor/icons/2x/icon_sample_player.png b/editor/icons/2x/icon_sample_player.png Binary files differindex aac4c1bbed..aac4c1bbed 100644 --- a/tools/editor/icons/2x/icon_sample_player.png +++ b/editor/icons/2x/icon_sample_player.png diff --git a/tools/editor/icons/2x/icon_sample_player_2d.png b/editor/icons/2x/icon_sample_player_2d.png Binary files differindex 9308d43128..9308d43128 100644 --- a/tools/editor/icons/2x/icon_sample_player_2d.png +++ b/editor/icons/2x/icon_sample_player_2d.png diff --git a/tools/editor/icons/2x/icon_save.png b/editor/icons/2x/icon_save.png Binary files differindex 0a643f2c88..0a643f2c88 100644 --- a/tools/editor/icons/2x/icon_save.png +++ b/editor/icons/2x/icon_save.png diff --git a/tools/editor/icons/2x/icon_script.png b/editor/icons/2x/icon_script.png Binary files differindex 6f54c20442..6f54c20442 100644 --- a/tools/editor/icons/2x/icon_script.png +++ b/editor/icons/2x/icon_script.png diff --git a/tools/editor/icons/2x/icon_script_create.png b/editor/icons/2x/icon_script_create.png Binary files differindex f1e25efe1c..f1e25efe1c 100644 --- a/tools/editor/icons/2x/icon_script_create.png +++ b/editor/icons/2x/icon_script_create.png diff --git a/tools/editor/icons/2x/icon_script_remove.png b/editor/icons/2x/icon_script_remove.png Binary files differindex f9a1bb19a4..f9a1bb19a4 100644 --- a/tools/editor/icons/2x/icon_script_remove.png +++ b/editor/icons/2x/icon_script_remove.png diff --git a/tools/editor/icons/2x/icon_scroll_bar.png b/editor/icons/2x/icon_scroll_bar.png Binary files differindex d15a36bb16..d15a36bb16 100644 --- a/tools/editor/icons/2x/icon_scroll_bar.png +++ b/editor/icons/2x/icon_scroll_bar.png diff --git a/tools/editor/icons/2x/icon_scroll_container.png b/editor/icons/2x/icon_scroll_container.png Binary files differindex 4ffe2f78f5..4ffe2f78f5 100644 --- a/tools/editor/icons/2x/icon_scroll_container.png +++ b/editor/icons/2x/icon_scroll_container.png diff --git a/tools/editor/icons/2x/icon_segment_shape_2d.png b/editor/icons/2x/icon_segment_shape_2d.png Binary files differindex 43d5d837cc..43d5d837cc 100644 --- a/tools/editor/icons/2x/icon_segment_shape_2d.png +++ b/editor/icons/2x/icon_segment_shape_2d.png diff --git a/tools/editor/icons/2x/icon_shader.png b/editor/icons/2x/icon_shader.png Binary files differindex f8c2e15fcb..f8c2e15fcb 100644 --- a/tools/editor/icons/2x/icon_shader.png +++ b/editor/icons/2x/icon_shader.png diff --git a/tools/editor/icons/2x/icon_shader_material.png b/editor/icons/2x/icon_shader_material.png Binary files differindex f8c2e15fcb..f8c2e15fcb 100644 --- a/tools/editor/icons/2x/icon_shader_material.png +++ b/editor/icons/2x/icon_shader_material.png diff --git a/tools/editor/icons/2x/icon_short_cut.png b/editor/icons/2x/icon_short_cut.png Binary files differindex 58c3e08ca4..58c3e08ca4 100644 --- a/tools/editor/icons/2x/icon_short_cut.png +++ b/editor/icons/2x/icon_short_cut.png diff --git a/tools/editor/icons/2x/icon_signal.png b/editor/icons/2x/icon_signal.png Binary files differindex 22b6da361e..22b6da361e 100644 --- a/tools/editor/icons/2x/icon_signal.png +++ b/editor/icons/2x/icon_signal.png diff --git a/tools/editor/icons/2x/icon_skeleton.png b/editor/icons/2x/icon_skeleton.png Binary files differindex 5345dfbd5c..5345dfbd5c 100644 --- a/tools/editor/icons/2x/icon_skeleton.png +++ b/editor/icons/2x/icon_skeleton.png diff --git a/tools/editor/icons/2x/icon_slider_joint.png b/editor/icons/2x/icon_slider_joint.png Binary files differindex 626479152f..626479152f 100644 --- a/tools/editor/icons/2x/icon_slider_joint.png +++ b/editor/icons/2x/icon_slider_joint.png diff --git a/tools/editor/icons/2x/icon_slot.png b/editor/icons/2x/icon_slot.png Binary files differindex 2176544c79..2176544c79 100644 --- a/tools/editor/icons/2x/icon_slot.png +++ b/editor/icons/2x/icon_slot.png diff --git a/tools/editor/icons/2x/icon_snap.png b/editor/icons/2x/icon_snap.png Binary files differindex 509b1c73f3..509b1c73f3 100644 --- a/tools/editor/icons/2x/icon_snap.png +++ b/editor/icons/2x/icon_snap.png diff --git a/tools/editor/icons/2x/icon_sound_room_params.png b/editor/icons/2x/icon_sound_room_params.png Binary files differindex 32927eaabc..32927eaabc 100644 --- a/tools/editor/icons/2x/icon_sound_room_params.png +++ b/editor/icons/2x/icon_sound_room_params.png diff --git a/tools/editor/icons/2x/icon_spatial.png b/editor/icons/2x/icon_spatial.png Binary files differindex 999771a7fe..999771a7fe 100644 --- a/tools/editor/icons/2x/icon_spatial.png +++ b/editor/icons/2x/icon_spatial.png diff --git a/tools/editor/icons/2x/icon_spatial_sample_player.png b/editor/icons/2x/icon_spatial_sample_player.png Binary files differindex f1926c446e..f1926c446e 100644 --- a/tools/editor/icons/2x/icon_spatial_sample_player.png +++ b/editor/icons/2x/icon_spatial_sample_player.png diff --git a/tools/editor/icons/2x/icon_spatial_shader.png b/editor/icons/2x/icon_spatial_shader.png Binary files differindex 68f6cf8dac..68f6cf8dac 100644 --- a/tools/editor/icons/2x/icon_spatial_shader.png +++ b/editor/icons/2x/icon_spatial_shader.png diff --git a/tools/editor/icons/2x/icon_spatial_stream_player.png b/editor/icons/2x/icon_spatial_stream_player.png Binary files differindex 835c5c0bbc..835c5c0bbc 100644 --- a/tools/editor/icons/2x/icon_spatial_stream_player.png +++ b/editor/icons/2x/icon_spatial_stream_player.png diff --git a/tools/editor/icons/2x/icon_sphere_shape.png b/editor/icons/2x/icon_sphere_shape.png Binary files differindex bdb7881e70..bdb7881e70 100644 --- a/tools/editor/icons/2x/icon_sphere_shape.png +++ b/editor/icons/2x/icon_sphere_shape.png diff --git a/tools/editor/icons/2x/icon_spin_box.png b/editor/icons/2x/icon_spin_box.png Binary files differindex 3d12664b86..3d12664b86 100644 --- a/tools/editor/icons/2x/icon_spin_box.png +++ b/editor/icons/2x/icon_spin_box.png diff --git a/tools/editor/icons/2x/icon_spot_light.png b/editor/icons/2x/icon_spot_light.png Binary files differindex e7aa35cbbf..e7aa35cbbf 100644 --- a/tools/editor/icons/2x/icon_spot_light.png +++ b/editor/icons/2x/icon_spot_light.png diff --git a/tools/editor/icons/2x/icon_sprite.png b/editor/icons/2x/icon_sprite.png Binary files differindex 3f18d313e7..3f18d313e7 100644 --- a/tools/editor/icons/2x/icon_sprite.png +++ b/editor/icons/2x/icon_sprite.png diff --git a/tools/editor/icons/2x/icon_sprite_3d.png b/editor/icons/2x/icon_sprite_3d.png Binary files differindex d3a491b9ee..d3a491b9ee 100644 --- a/tools/editor/icons/2x/icon_sprite_3d.png +++ b/editor/icons/2x/icon_sprite_3d.png diff --git a/tools/editor/icons/2x/icon_sprite_frames.png b/editor/icons/2x/icon_sprite_frames.png Binary files differindex 263f5c4aad..263f5c4aad 100644 --- a/tools/editor/icons/2x/icon_sprite_frames.png +++ b/editor/icons/2x/icon_sprite_frames.png diff --git a/tools/editor/icons/2x/icon_static_body.png b/editor/icons/2x/icon_static_body.png Binary files differindex 74f65ef490..74f65ef490 100644 --- a/tools/editor/icons/2x/icon_static_body.png +++ b/editor/icons/2x/icon_static_body.png diff --git a/tools/editor/icons/2x/icon_static_body_2d.png b/editor/icons/2x/icon_static_body_2d.png Binary files differindex 220c829edd..220c829edd 100644 --- a/tools/editor/icons/2x/icon_static_body_2d.png +++ b/editor/icons/2x/icon_static_body_2d.png diff --git a/tools/editor/icons/2x/icon_stream_player.png b/editor/icons/2x/icon_stream_player.png Binary files differindex 8ff471cb8a..8ff471cb8a 100644 --- a/tools/editor/icons/2x/icon_stream_player.png +++ b/editor/icons/2x/icon_stream_player.png diff --git a/tools/editor/icons/2x/icon_string.png b/editor/icons/2x/icon_string.png Binary files differindex e25a81f24e..e25a81f24e 100644 --- a/tools/editor/icons/2x/icon_string.png +++ b/editor/icons/2x/icon_string.png diff --git a/tools/editor/icons/2x/icon_style_box_empty.png b/editor/icons/2x/icon_style_box_empty.png Binary files differindex e790af4de4..e790af4de4 100644 --- a/tools/editor/icons/2x/icon_style_box_empty.png +++ b/editor/icons/2x/icon_style_box_empty.png diff --git a/tools/editor/icons/2x/icon_style_box_flat.png b/editor/icons/2x/icon_style_box_flat.png Binary files differindex 1cd5c7f69a..1cd5c7f69a 100644 --- a/tools/editor/icons/2x/icon_style_box_flat.png +++ b/editor/icons/2x/icon_style_box_flat.png diff --git a/tools/editor/icons/2x/icon_style_box_texture.png b/editor/icons/2x/icon_style_box_texture.png Binary files differindex a93e0228bd..a93e0228bd 100644 --- a/tools/editor/icons/2x/icon_style_box_texture.png +++ b/editor/icons/2x/icon_style_box_texture.png diff --git a/tools/editor/icons/2x/icon_tab_container.png b/editor/icons/2x/icon_tab_container.png Binary files differindex 93b7161a69..93b7161a69 100644 --- a/tools/editor/icons/2x/icon_tab_container.png +++ b/editor/icons/2x/icon_tab_container.png diff --git a/tools/editor/icons/2x/icon_tabs.png b/editor/icons/2x/icon_tabs.png Binary files differindex 6c317010c8..6c317010c8 100644 --- a/tools/editor/icons/2x/icon_tabs.png +++ b/editor/icons/2x/icon_tabs.png diff --git a/tools/editor/icons/2x/icon_test_cube.png b/editor/icons/2x/icon_test_cube.png Binary files differindex f2e523be3f..f2e523be3f 100644 --- a/tools/editor/icons/2x/icon_test_cube.png +++ b/editor/icons/2x/icon_test_cube.png diff --git a/tools/editor/icons/2x/icon_text_edit.png b/editor/icons/2x/icon_text_edit.png Binary files differindex 4fd92e518e..4fd92e518e 100644 --- a/tools/editor/icons/2x/icon_text_edit.png +++ b/editor/icons/2x/icon_text_edit.png diff --git a/tools/editor/icons/2x/icon_texture.png b/editor/icons/2x/icon_texture.png Binary files differindex ad5d04dfee..ad5d04dfee 100644 --- a/tools/editor/icons/2x/icon_texture.png +++ b/editor/icons/2x/icon_texture.png diff --git a/tools/editor/icons/2x/icon_texture_button.png b/editor/icons/2x/icon_texture_button.png Binary files differindex 84494209d7..84494209d7 100644 --- a/tools/editor/icons/2x/icon_texture_button.png +++ b/editor/icons/2x/icon_texture_button.png diff --git a/tools/editor/icons/2x/icon_texture_progress.png b/editor/icons/2x/icon_texture_progress.png Binary files differindex c11c1bbe4b..c11c1bbe4b 100644 --- a/tools/editor/icons/2x/icon_texture_progress.png +++ b/editor/icons/2x/icon_texture_progress.png diff --git a/tools/editor/icons/2x/icon_texture_rect.png b/editor/icons/2x/icon_texture_rect.png Binary files differindex 50d715dd09..50d715dd09 100644 --- a/tools/editor/icons/2x/icon_texture_rect.png +++ b/editor/icons/2x/icon_texture_rect.png diff --git a/tools/editor/icons/2x/icon_theme.png b/editor/icons/2x/icon_theme.png Binary files differindex 55b51428dd..55b51428dd 100644 --- a/tools/editor/icons/2x/icon_theme.png +++ b/editor/icons/2x/icon_theme.png diff --git a/tools/editor/icons/2x/icon_tile_map.png b/editor/icons/2x/icon_tile_map.png Binary files differindex fd98fb6a39..fd98fb6a39 100644 --- a/tools/editor/icons/2x/icon_tile_map.png +++ b/editor/icons/2x/icon_tile_map.png diff --git a/tools/editor/icons/2x/icon_tile_set.png b/editor/icons/2x/icon_tile_set.png Binary files differindex 9fbd0b4719..9fbd0b4719 100644 --- a/tools/editor/icons/2x/icon_tile_set.png +++ b/editor/icons/2x/icon_tile_set.png diff --git a/tools/editor/icons/2x/icon_timer.png b/editor/icons/2x/icon_timer.png Binary files differindex b0df31d803..b0df31d803 100644 --- a/tools/editor/icons/2x/icon_timer.png +++ b/editor/icons/2x/icon_timer.png diff --git a/tools/editor/icons/2x/icon_tool_button.png b/editor/icons/2x/icon_tool_button.png Binary files differindex 091fa8334f..091fa8334f 100644 --- a/tools/editor/icons/2x/icon_tool_button.png +++ b/editor/icons/2x/icon_tool_button.png diff --git a/tools/editor/icons/2x/icon_tool_move.png b/editor/icons/2x/icon_tool_move.png Binary files differindex 86419cb6a9..86419cb6a9 100644 --- a/tools/editor/icons/2x/icon_tool_move.png +++ b/editor/icons/2x/icon_tool_move.png diff --git a/tools/editor/icons/2x/icon_tool_pan.png b/editor/icons/2x/icon_tool_pan.png Binary files differindex b7a6c3566f..b7a6c3566f 100644 --- a/tools/editor/icons/2x/icon_tool_pan.png +++ b/editor/icons/2x/icon_tool_pan.png diff --git a/tools/editor/icons/2x/icon_tool_rotate.png b/editor/icons/2x/icon_tool_rotate.png Binary files differindex b13c858124..b13c858124 100644 --- a/tools/editor/icons/2x/icon_tool_rotate.png +++ b/editor/icons/2x/icon_tool_rotate.png diff --git a/tools/editor/icons/2x/icon_tool_scale.png b/editor/icons/2x/icon_tool_scale.png Binary files differindex 1bc29f4acc..1bc29f4acc 100644 --- a/tools/editor/icons/2x/icon_tool_scale.png +++ b/editor/icons/2x/icon_tool_scale.png diff --git a/tools/editor/icons/2x/icon_tool_select.png b/editor/icons/2x/icon_tool_select.png Binary files differindex 7421b98ef6..7421b98ef6 100644 --- a/tools/editor/icons/2x/icon_tool_select.png +++ b/editor/icons/2x/icon_tool_select.png diff --git a/tools/editor/icons/2x/icon_tools.png b/editor/icons/2x/icon_tools.png Binary files differindex 6143191fc7..6143191fc7 100644 --- a/tools/editor/icons/2x/icon_tools.png +++ b/editor/icons/2x/icon_tools.png diff --git a/tools/editor/icons/2x/icon_touch_screen_button.png b/editor/icons/2x/icon_touch_screen_button.png Binary files differindex b1af644e42..b1af644e42 100644 --- a/tools/editor/icons/2x/icon_touch_screen_button.png +++ b/editor/icons/2x/icon_touch_screen_button.png diff --git a/tools/editor/icons/2x/icon_track_add_key.png b/editor/icons/2x/icon_track_add_key.png Binary files differindex 9b7bd14fb4..9b7bd14fb4 100644 --- a/tools/editor/icons/2x/icon_track_add_key.png +++ b/editor/icons/2x/icon_track_add_key.png diff --git a/tools/editor/icons/2x/icon_track_add_key_hl.png b/editor/icons/2x/icon_track_add_key_hl.png Binary files differindex 0763836c3a..0763836c3a 100644 --- a/tools/editor/icons/2x/icon_track_add_key_hl.png +++ b/editor/icons/2x/icon_track_add_key_hl.png diff --git a/tools/editor/icons/2x/icon_track_continuous.png b/editor/icons/2x/icon_track_continuous.png Binary files differindex 5b4515f642..5b4515f642 100644 --- a/tools/editor/icons/2x/icon_track_continuous.png +++ b/editor/icons/2x/icon_track_continuous.png diff --git a/tools/editor/icons/2x/icon_track_discrete.png b/editor/icons/2x/icon_track_discrete.png Binary files differindex 19f479657b..19f479657b 100644 --- a/tools/editor/icons/2x/icon_track_discrete.png +++ b/editor/icons/2x/icon_track_discrete.png diff --git a/tools/editor/icons/2x/icon_track_trigger.png b/editor/icons/2x/icon_track_trigger.png Binary files differindex c04d47f9a4..c04d47f9a4 100644 --- a/tools/editor/icons/2x/icon_track_trigger.png +++ b/editor/icons/2x/icon_track_trigger.png diff --git a/tools/editor/icons/2x/icon_translation.png b/editor/icons/2x/icon_translation.png Binary files differindex 0ddc1da282..0ddc1da282 100644 --- a/tools/editor/icons/2x/icon_translation.png +++ b/editor/icons/2x/icon_translation.png diff --git a/tools/editor/icons/2x/icon_transparent.png b/editor/icons/2x/icon_transparent.png Binary files differindex 627607039b..627607039b 100644 --- a/tools/editor/icons/2x/icon_transparent.png +++ b/editor/icons/2x/icon_transparent.png diff --git a/tools/editor/icons/2x/icon_transpose.png b/editor/icons/2x/icon_transpose.png Binary files differindex 589dc54919..589dc54919 100644 --- a/tools/editor/icons/2x/icon_transpose.png +++ b/editor/icons/2x/icon_transpose.png diff --git a/tools/editor/icons/2x/icon_tree.png b/editor/icons/2x/icon_tree.png Binary files differindex 3f470cc0f3..3f470cc0f3 100644 --- a/tools/editor/icons/2x/icon_tree.png +++ b/editor/icons/2x/icon_tree.png diff --git a/tools/editor/icons/2x/icon_tween.png b/editor/icons/2x/icon_tween.png Binary files differindex a13d955eb0..a13d955eb0 100644 --- a/tools/editor/icons/2x/icon_tween.png +++ b/editor/icons/2x/icon_tween.png diff --git a/tools/editor/icons/2x/icon_unbone.png b/editor/icons/2x/icon_unbone.png Binary files differindex c20d6d9b2c..c20d6d9b2c 100644 --- a/tools/editor/icons/2x/icon_unbone.png +++ b/editor/icons/2x/icon_unbone.png diff --git a/tools/editor/icons/2x/icon_ungroup.png b/editor/icons/2x/icon_ungroup.png Binary files differindex bb46185370..bb46185370 100644 --- a/tools/editor/icons/2x/icon_ungroup.png +++ b/editor/icons/2x/icon_ungroup.png diff --git a/tools/editor/icons/2x/icon_uninstance.png b/editor/icons/2x/icon_uninstance.png Binary files differindex bf3dc00368..bf3dc00368 100644 --- a/tools/editor/icons/2x/icon_uninstance.png +++ b/editor/icons/2x/icon_uninstance.png diff --git a/tools/editor/icons/2x/icon_unlock.png b/editor/icons/2x/icon_unlock.png Binary files differindex 40ff3f25a0..40ff3f25a0 100644 --- a/tools/editor/icons/2x/icon_unlock.png +++ b/editor/icons/2x/icon_unlock.png diff --git a/tools/editor/icons/2x/icon_uv.png b/editor/icons/2x/icon_uv.png Binary files differindex e06be54edd..e06be54edd 100644 --- a/tools/editor/icons/2x/icon_uv.png +++ b/editor/icons/2x/icon_uv.png diff --git a/tools/editor/icons/2x/icon_v_box_container.png b/editor/icons/2x/icon_v_box_container.png Binary files differindex 97eb18c528..97eb18c528 100644 --- a/tools/editor/icons/2x/icon_v_box_container.png +++ b/editor/icons/2x/icon_v_box_container.png diff --git a/tools/editor/icons/2x/icon_v_button_array.png b/editor/icons/2x/icon_v_button_array.png Binary files differindex 93fd1fed04..93fd1fed04 100644 --- a/tools/editor/icons/2x/icon_v_button_array.png +++ b/editor/icons/2x/icon_v_button_array.png diff --git a/tools/editor/icons/2x/icon_v_scroll_bar.png b/editor/icons/2x/icon_v_scroll_bar.png Binary files differindex 5e4f83197f..5e4f83197f 100644 --- a/tools/editor/icons/2x/icon_v_scroll_bar.png +++ b/editor/icons/2x/icon_v_scroll_bar.png diff --git a/tools/editor/icons/2x/icon_v_separator.png b/editor/icons/2x/icon_v_separator.png Binary files differindex 58cdc3e8de..58cdc3e8de 100644 --- a/tools/editor/icons/2x/icon_v_separator.png +++ b/editor/icons/2x/icon_v_separator.png diff --git a/tools/editor/icons/2x/icon_v_slider.png b/editor/icons/2x/icon_v_slider.png Binary files differindex afc88cf510..afc88cf510 100644 --- a/tools/editor/icons/2x/icon_v_slider.png +++ b/editor/icons/2x/icon_v_slider.png diff --git a/tools/editor/icons/2x/icon_v_split_container.png b/editor/icons/2x/icon_v_split_container.png Binary files differindex b0f68381fc..b0f68381fc 100644 --- a/tools/editor/icons/2x/icon_v_split_container.png +++ b/editor/icons/2x/icon_v_split_container.png diff --git a/tools/editor/icons/2x/icon_vector.png b/editor/icons/2x/icon_vector.png Binary files differindex 9950d950ac..9950d950ac 100644 --- a/tools/editor/icons/2x/icon_vector.png +++ b/editor/icons/2x/icon_vector.png diff --git a/tools/editor/icons/2x/icon_vector2.png b/editor/icons/2x/icon_vector2.png Binary files differindex 73c1ca007f..73c1ca007f 100644 --- a/tools/editor/icons/2x/icon_vector2.png +++ b/editor/icons/2x/icon_vector2.png diff --git a/tools/editor/icons/2x/icon_vehicle_body.png b/editor/icons/2x/icon_vehicle_body.png Binary files differindex 215f7ac021..215f7ac021 100644 --- a/tools/editor/icons/2x/icon_vehicle_body.png +++ b/editor/icons/2x/icon_vehicle_body.png diff --git a/tools/editor/icons/2x/icon_vehicle_wheel.png b/editor/icons/2x/icon_vehicle_wheel.png Binary files differindex 6f7fecac4a..6f7fecac4a 100644 --- a/tools/editor/icons/2x/icon_vehicle_wheel.png +++ b/editor/icons/2x/icon_vehicle_wheel.png diff --git a/tools/editor/icons/2x/icon_video_player.png b/editor/icons/2x/icon_video_player.png Binary files differindex 588e17aa4e..588e17aa4e 100644 --- a/tools/editor/icons/2x/icon_video_player.png +++ b/editor/icons/2x/icon_video_player.png diff --git a/tools/editor/icons/2x/icon_viewport.png b/editor/icons/2x/icon_viewport.png Binary files differindex 7e588333fb..7e588333fb 100644 --- a/tools/editor/icons/2x/icon_viewport.png +++ b/editor/icons/2x/icon_viewport.png diff --git a/tools/editor/icons/2x/icon_viewport_container.png b/editor/icons/2x/icon_viewport_container.png Binary files differindex c43e53c34e..c43e53c34e 100644 --- a/tools/editor/icons/2x/icon_viewport_container.png +++ b/editor/icons/2x/icon_viewport_container.png diff --git a/tools/editor/icons/2x/icon_viewport_sprite.png b/editor/icons/2x/icon_viewport_sprite.png Binary files differindex adb336103f..adb336103f 100644 --- a/tools/editor/icons/2x/icon_viewport_sprite.png +++ b/editor/icons/2x/icon_viewport_sprite.png diff --git a/tools/editor/icons/2x/icon_viewport_texture.png b/editor/icons/2x/icon_viewport_texture.png Binary files differindex f798f1d221..f798f1d221 100644 --- a/tools/editor/icons/2x/icon_viewport_texture.png +++ b/editor/icons/2x/icon_viewport_texture.png diff --git a/tools/editor/icons/2x/icon_visibility_enabler.png b/editor/icons/2x/icon_visibility_enabler.png Binary files differindex 4be06a5123..4be06a5123 100644 --- a/tools/editor/icons/2x/icon_visibility_enabler.png +++ b/editor/icons/2x/icon_visibility_enabler.png diff --git a/tools/editor/icons/2x/icon_visibility_enabler_2d.png b/editor/icons/2x/icon_visibility_enabler_2d.png Binary files differindex 3d592e8983..3d592e8983 100644 --- a/tools/editor/icons/2x/icon_visibility_enabler_2d.png +++ b/editor/icons/2x/icon_visibility_enabler_2d.png diff --git a/tools/editor/icons/2x/icon_visibility_notifier.png b/editor/icons/2x/icon_visibility_notifier.png Binary files differindex aa73402d8e..aa73402d8e 100644 --- a/tools/editor/icons/2x/icon_visibility_notifier.png +++ b/editor/icons/2x/icon_visibility_notifier.png diff --git a/tools/editor/icons/2x/icon_visibility_notifier_2d.png b/editor/icons/2x/icon_visibility_notifier_2d.png Binary files differindex 5f3b7ecf42..5f3b7ecf42 100644 --- a/tools/editor/icons/2x/icon_visibility_notifier_2d.png +++ b/editor/icons/2x/icon_visibility_notifier_2d.png diff --git a/tools/editor/icons/2x/icon_visible.png b/editor/icons/2x/icon_visible.png Binary files differindex 761ff12c66..761ff12c66 100644 --- a/tools/editor/icons/2x/icon_visible.png +++ b/editor/icons/2x/icon_visible.png diff --git a/tools/editor/icons/2x/icon_visual_script.png b/editor/icons/2x/icon_visual_script.png Binary files differindex 78a3a0c318..78a3a0c318 100644 --- a/tools/editor/icons/2x/icon_visual_script.png +++ b/editor/icons/2x/icon_visual_script.png diff --git a/tools/editor/icons/2x/icon_visual_shader_port.png b/editor/icons/2x/icon_visual_shader_port.png Binary files differindex 3f9bf96b01..3f9bf96b01 100644 --- a/tools/editor/icons/2x/icon_visual_shader_port.png +++ b/editor/icons/2x/icon_visual_shader_port.png diff --git a/tools/editor/icons/2x/icon_vu_empty.png b/editor/icons/2x/icon_vu_empty.png Binary files differindex 7ecf215933..7ecf215933 100644 --- a/tools/editor/icons/2x/icon_vu_empty.png +++ b/editor/icons/2x/icon_vu_empty.png diff --git a/tools/editor/icons/2x/icon_vu_full.png b/editor/icons/2x/icon_vu_full.png Binary files differindex cfd29fa833..cfd29fa833 100644 --- a/tools/editor/icons/2x/icon_vu_full.png +++ b/editor/icons/2x/icon_vu_full.png diff --git a/tools/editor/icons/2x/icon_warning.png b/editor/icons/2x/icon_warning.png Binary files differindex 5d807065e7..5d807065e7 100644 --- a/tools/editor/icons/2x/icon_warning.png +++ b/editor/icons/2x/icon_warning.png diff --git a/tools/editor/icons/2x/icon_window_dialog.png b/editor/icons/2x/icon_window_dialog.png Binary files differindex 995381ed5f..995381ed5f 100644 --- a/tools/editor/icons/2x/icon_window_dialog.png +++ b/editor/icons/2x/icon_window_dialog.png diff --git a/tools/editor/icons/2x/icon_world.png b/editor/icons/2x/icon_world.png Binary files differindex 51b587c01e..51b587c01e 100644 --- a/tools/editor/icons/2x/icon_world.png +++ b/editor/icons/2x/icon_world.png diff --git a/tools/editor/icons/2x/icon_world_2d.png b/editor/icons/2x/icon_world_2d.png Binary files differindex e9cfa10461..e9cfa10461 100644 --- a/tools/editor/icons/2x/icon_world_2d.png +++ b/editor/icons/2x/icon_world_2d.png diff --git a/tools/editor/icons/2x/icon_world_environment.png b/editor/icons/2x/icon_world_environment.png Binary files differindex 9ca558fcba..9ca558fcba 100644 --- a/tools/editor/icons/2x/icon_world_environment.png +++ b/editor/icons/2x/icon_world_environment.png diff --git a/tools/editor/icons/2x/icon_y_sort.png b/editor/icons/2x/icon_y_sort.png Binary files differindex a38cbbe863..a38cbbe863 100644 --- a/tools/editor/icons/2x/icon_y_sort.png +++ b/editor/icons/2x/icon_y_sort.png diff --git a/tools/editor/icons/2x/icon_zoom.png b/editor/icons/2x/icon_zoom.png Binary files differindex 0c4a6a8c84..0c4a6a8c84 100644 --- a/tools/editor/icons/2x/icon_zoom.png +++ b/editor/icons/2x/icon_zoom.png diff --git a/tools/editor/icons/2x/icon_zoom_less.png b/editor/icons/2x/icon_zoom_less.png Binary files differindex d483db55ce..d483db55ce 100644 --- a/tools/editor/icons/2x/icon_zoom_less.png +++ b/editor/icons/2x/icon_zoom_less.png diff --git a/tools/editor/icons/2x/icon_zoom_more.png b/editor/icons/2x/icon_zoom_more.png Binary files differindex 8f9ef77849..8f9ef77849 100644 --- a/tools/editor/icons/2x/icon_zoom_more.png +++ b/editor/icons/2x/icon_zoom_more.png diff --git a/tools/editor/icons/2x/icon_zoom_reset.png b/editor/icons/2x/icon_zoom_reset.png Binary files differindex 092215b3e2..092215b3e2 100644 --- a/tools/editor/icons/2x/icon_zoom_reset.png +++ b/editor/icons/2x/icon_zoom_reset.png diff --git a/editor/icons/SCsub b/editor/icons/SCsub new file mode 100644 index 0000000000..3fc8e5461f --- /dev/null +++ b/editor/icons/SCsub @@ -0,0 +1,96 @@ +#!/usr/bin/env python + +Import('env') + + +def make_editor_icons_action(target, source, env): + + import os + import cStringIO + + dst = target[0].srcnode().abspath + pixmaps = source + + s = cStringIO.StringIO() + + s.write("#include \"editor_icons.h\"\n\n") + s.write("#include \"editor_scale.h\"\n\n") + s.write("#include \"scene/resources/theme.h\"\n\n") + + hidpi_list = [] + + for x in pixmaps: + + x = str(x) + var_str = os.path.basename(x)[:-4] + "_png" + # print(var_str) + + s.write("static const unsigned char " + var_str + "[]={\n") + + pngf = open(x, "rb") + + b = pngf.read(1) + while(len(b) == 1): + s.write(hex(ord(b))) + b = pngf.read(1) + if (len(b) == 1): + s.write(",") + + s.write("\n};\n\n") + + pngf.close() + var_str = os.path.basename(x)[:-4] + "_hidpi_png" + try: + + pngf = open(os.path.dirname(x) + "/2x/" + os.path.basename(x), "rb") + + s.write("static const unsigned char " + var_str + "[]={\n") + + b = pngf.read(1) + while(len(b) == 1): + s.write(hex(ord(b))) + b = pngf.read(1) + if (len(b) == 1): + s.write(",") + + s.write("\n};\n\n\n") + hidpi_list.append(x) + + except: + s.write("static const unsigned char* " + var_str + "=NULL;\n\n\n") + + s.write("static Ref<ImageTexture> make_icon(const uint8_t* p_png,const uint8_t* p_hidpi_png) {\n") + s.write("\tRef<ImageTexture> texture( memnew( ImageTexture ) );\n") + s.write("\tbool use_hidpi_image=(editor_get_scale()>1.0&&p_hidpi_png);\n") + s.write("\tImage img(use_hidpi_image?p_hidpi_png:p_png);\n") + s.write("\tif (editor_get_scale()>1.0 && !p_hidpi_png) { img.convert(Image::FORMAT_RGBA8); img.expand_x2_hq2x(); use_hidpi_image=true;}\n") + s.write("\timg.resize(img.get_width()*EDSCALE/(use_hidpi_image?2:1),img.get_height()*EDSCALE/(use_hidpi_image?2:1));\n") + s.write("\ttexture->create_from_image( img,ImageTexture::FLAG_FILTER );\n") + s.write("\treturn texture;\n") + s.write("}\n\n") + + s.write("void editor_register_icons(Ref<Theme> p_theme) {\n\n") + + for x in pixmaps: + + x = os.path.basename(str(x)) + type = x[5:-4].title().replace("_", "") + var_str = x[:-4] + "_png" + var_str_hidpi = x[:-4] + "_hidpi_png" + s.write("\tp_theme->set_icon(\"" + type + "\",\"EditorIcons\",make_icon(" + var_str + "," + var_str_hidpi + "));\n") + + s.write("\n\n}\n\n") + + f = open(dst, "wb") + f.write(s.getvalue()) + f.close() + s.close() + +make_editor_icons_builder = Builder(action=make_editor_icons_action, + suffix='.cpp', + src_suffix='.png') +env['BUILDERS']['MakeEditorIconsBuilder'] = make_editor_icons_builder +env.Alias('editor_icons', [env.MakeEditorIconsBuilder('#editor/editor_icons.cpp', Glob("*.png"))]) + +env.editor_sources.append("#editor/editor_icons.cpp") +Export('env') diff --git a/tools/editor/icons/icon_accept_dialog.png b/editor/icons/icon_accept_dialog.png Binary files differindex 7530127f82..7530127f82 100644 --- a/tools/editor/icons/icon_accept_dialog.png +++ b/editor/icons/icon_accept_dialog.png diff --git a/tools/editor/icons/icon_add.png b/editor/icons/icon_add.png Binary files differindex fa675045bc..fa675045bc 100644 --- a/tools/editor/icons/icon_add.png +++ b/editor/icons/icon_add.png diff --git a/tools/editor/icons/icon_add_track.png b/editor/icons/icon_add_track.png Binary files differindex fa675045bc..fa675045bc 100644 --- a/tools/editor/icons/icon_add_track.png +++ b/editor/icons/icon_add_track.png diff --git a/tools/editor/icons/icon_anchor.png b/editor/icons/icon_anchor.png Binary files differindex 7b02eb448e..7b02eb448e 100644 --- a/tools/editor/icons/icon_anchor.png +++ b/editor/icons/icon_anchor.png diff --git a/tools/editor/icons/icon_anim_export.png b/editor/icons/icon_anim_export.png Binary files differindex b17ecdeb22..b17ecdeb22 100644 --- a/tools/editor/icons/icon_anim_export.png +++ b/editor/icons/icon_anim_export.png diff --git a/tools/editor/icons/icon_anim_export_all.png b/editor/icons/icon_anim_export_all.png Binary files differindex 65a3cf5745..65a3cf5745 100644 --- a/tools/editor/icons/icon_anim_export_all.png +++ b/editor/icons/icon_anim_export_all.png diff --git a/tools/editor/icons/icon_anim_get.png b/editor/icons/icon_anim_get.png Binary files differindex 7edd883f02..7edd883f02 100644 --- a/tools/editor/icons/icon_anim_get.png +++ b/editor/icons/icon_anim_get.png diff --git a/tools/editor/icons/icon_anim_get_hl.png b/editor/icons/icon_anim_get_hl.png Binary files differindex fa6e94545b..fa6e94545b 100644 --- a/tools/editor/icons/icon_anim_get_hl.png +++ b/editor/icons/icon_anim_get_hl.png diff --git a/tools/editor/icons/icon_anim_import.png b/editor/icons/icon_anim_import.png Binary files differindex 166e3fecd7..166e3fecd7 100644 --- a/tools/editor/icons/icon_anim_import.png +++ b/editor/icons/icon_anim_import.png diff --git a/tools/editor/icons/icon_anim_import_all.png b/editor/icons/icon_anim_import_all.png Binary files differindex c99893d59d..c99893d59d 100644 --- a/tools/editor/icons/icon_anim_import_all.png +++ b/editor/icons/icon_anim_import_all.png diff --git a/tools/editor/icons/icon_anim_set.png b/editor/icons/icon_anim_set.png Binary files differindex c52334c72f..c52334c72f 100644 --- a/tools/editor/icons/icon_anim_set.png +++ b/editor/icons/icon_anim_set.png diff --git a/tools/editor/icons/icon_anim_set_hl.png b/editor/icons/icon_anim_set_hl.png Binary files differindex aefaf7f738..aefaf7f738 100644 --- a/tools/editor/icons/icon_anim_set_hl.png +++ b/editor/icons/icon_anim_set_hl.png diff --git a/tools/editor/icons/icon_animated_sprite.png b/editor/icons/icon_animated_sprite.png Binary files differindex 6b6cb2fbfa..6b6cb2fbfa 100644 --- a/tools/editor/icons/icon_animated_sprite.png +++ b/editor/icons/icon_animated_sprite.png diff --git a/tools/editor/icons/icon_animated_sprite_3d.png b/editor/icons/icon_animated_sprite_3d.png Binary files differindex e04d687bfb..e04d687bfb 100644 --- a/tools/editor/icons/icon_animated_sprite_3d.png +++ b/editor/icons/icon_animated_sprite_3d.png diff --git a/tools/editor/icons/icon_animation.png b/editor/icons/icon_animation.png Binary files differindex b333f82711..b333f82711 100644 --- a/tools/editor/icons/icon_animation.png +++ b/editor/icons/icon_animation.png diff --git a/tools/editor/icons/icon_animation_node.png b/editor/icons/icon_animation_node.png Binary files differindex 81026b3a98..81026b3a98 100644 --- a/tools/editor/icons/icon_animation_node.png +++ b/editor/icons/icon_animation_node.png diff --git a/tools/editor/icons/icon_animation_play.png b/editor/icons/icon_animation_play.png Binary files differindex b405bf98f4..b405bf98f4 100644 --- a/tools/editor/icons/icon_animation_play.png +++ b/editor/icons/icon_animation_play.png diff --git a/tools/editor/icons/icon_animation_player.png b/editor/icons/icon_animation_player.png Binary files differindex 8a6f446e4e..8a6f446e4e 100644 --- a/tools/editor/icons/icon_animation_player.png +++ b/editor/icons/icon_animation_player.png diff --git a/tools/editor/icons/icon_animation_set.png b/editor/icons/icon_animation_set.png Binary files differindex b603382b0c..b603382b0c 100644 --- a/tools/editor/icons/icon_animation_set.png +++ b/editor/icons/icon_animation_set.png diff --git a/tools/editor/icons/icon_animation_tree.png b/editor/icons/icon_animation_tree.png Binary files differindex 684edb876b..684edb876b 100644 --- a/tools/editor/icons/icon_animation_tree.png +++ b/editor/icons/icon_animation_tree.png diff --git a/tools/editor/icons/icon_animation_tree_player.png b/editor/icons/icon_animation_tree_player.png Binary files differindex 684edb876b..684edb876b 100644 --- a/tools/editor/icons/icon_animation_tree_player.png +++ b/editor/icons/icon_animation_tree_player.png diff --git a/tools/editor/icons/icon_area.png b/editor/icons/icon_area.png Binary files differindex 31b4473d17..31b4473d17 100644 --- a/tools/editor/icons/icon_area.png +++ b/editor/icons/icon_area.png diff --git a/tools/editor/icons/icon_area_2d.png b/editor/icons/icon_area_2d.png Binary files differindex 2f9c6bb8d4..2f9c6bb8d4 100644 --- a/tools/editor/icons/icon_area_2d.png +++ b/editor/icons/icon_area_2d.png diff --git a/tools/editor/icons/icon_array_data.png b/editor/icons/icon_array_data.png Binary files differindex 447acaab2b..447acaab2b 100644 --- a/tools/editor/icons/icon_array_data.png +++ b/editor/icons/icon_array_data.png diff --git a/tools/editor/icons/icon_array_float.png b/editor/icons/icon_array_float.png Binary files differindex d1b78b4c3e..d1b78b4c3e 100644 --- a/tools/editor/icons/icon_array_float.png +++ b/editor/icons/icon_array_float.png diff --git a/tools/editor/icons/icon_array_int.png b/editor/icons/icon_array_int.png Binary files differindex 2c4ec5bafb..2c4ec5bafb 100644 --- a/tools/editor/icons/icon_array_int.png +++ b/editor/icons/icon_array_int.png diff --git a/tools/editor/icons/icon_array_string.png b/editor/icons/icon_array_string.png Binary files differindex a2e3f11c35..a2e3f11c35 100644 --- a/tools/editor/icons/icon_array_string.png +++ b/editor/icons/icon_array_string.png diff --git a/tools/editor/icons/icon_array_variant.png b/editor/icons/icon_array_variant.png Binary files differindex ab294898ad..ab294898ad 100644 --- a/tools/editor/icons/icon_array_variant.png +++ b/editor/icons/icon_array_variant.png diff --git a/tools/editor/icons/icon_arrow_left.png b/editor/icons/icon_arrow_left.png Binary files differindex 1e0d38b4b6..1e0d38b4b6 100644 --- a/tools/editor/icons/icon_arrow_left.png +++ b/editor/icons/icon_arrow_left.png diff --git a/tools/editor/icons/icon_arrow_left_disabled.png b/editor/icons/icon_arrow_left_disabled.png Binary files differindex f1f9d0f988..f1f9d0f988 100644 --- a/tools/editor/icons/icon_arrow_left_disabled.png +++ b/editor/icons/icon_arrow_left_disabled.png diff --git a/tools/editor/icons/icon_arrow_right.png b/editor/icons/icon_arrow_right.png Binary files differindex 09907755e1..09907755e1 100644 --- a/tools/editor/icons/icon_arrow_right.png +++ b/editor/icons/icon_arrow_right.png diff --git a/tools/editor/icons/icon_arrow_right_disabled.png b/editor/icons/icon_arrow_right_disabled.png Binary files differindex 840cd0da0a..840cd0da0a 100644 --- a/tools/editor/icons/icon_arrow_right_disabled.png +++ b/editor/icons/icon_arrow_right_disabled.png diff --git a/tools/editor/icons/icon_arrow_up.png b/editor/icons/icon_arrow_up.png Binary files differindex f7ec666f69..f7ec666f69 100644 --- a/tools/editor/icons/icon_arrow_up.png +++ b/editor/icons/icon_arrow_up.png diff --git a/tools/editor/icons/icon_arrow_up_disabled.png b/editor/icons/icon_arrow_up_disabled.png Binary files differindex fb46aa1373..fb46aa1373 100644 --- a/tools/editor/icons/icon_arrow_up_disabled.png +++ b/editor/icons/icon_arrow_up_disabled.png diff --git a/tools/editor/icons/icon_atlas_texture.png b/editor/icons/icon_atlas_texture.png Binary files differindex 438ac8bfb5..438ac8bfb5 100644 --- a/tools/editor/icons/icon_atlas_texture.png +++ b/editor/icons/icon_atlas_texture.png diff --git a/tools/editor/icons/icon_audio_effect_amplify.png b/editor/icons/icon_audio_effect_amplify.png Binary files differindex 9af3227d40..9af3227d40 100644 --- a/tools/editor/icons/icon_audio_effect_amplify.png +++ b/editor/icons/icon_audio_effect_amplify.png diff --git a/tools/editor/icons/icon_audio_stream_gibberish.png b/editor/icons/icon_audio_stream_gibberish.png Binary files differindex 60c85fa5b4..60c85fa5b4 100644 --- a/tools/editor/icons/icon_audio_stream_gibberish.png +++ b/editor/icons/icon_audio_stream_gibberish.png diff --git a/tools/editor/icons/icon_audio_stream_m_p_c.png b/editor/icons/icon_audio_stream_m_p_c.png Binary files differindex 665d7b56a1..665d7b56a1 100644 --- a/tools/editor/icons/icon_audio_stream_m_p_c.png +++ b/editor/icons/icon_audio_stream_m_p_c.png diff --git a/tools/editor/icons/icon_audio_stream_o_g_g_vorbis.png b/editor/icons/icon_audio_stream_o_g_g_vorbis.png Binary files differindex 7860e111d0..7860e111d0 100644 --- a/tools/editor/icons/icon_audio_stream_o_g_g_vorbis.png +++ b/editor/icons/icon_audio_stream_o_g_g_vorbis.png diff --git a/tools/editor/icons/icon_audio_stream_opus.png b/editor/icons/icon_audio_stream_opus.png Binary files differindex 69b0c83b4d..69b0c83b4d 100644 --- a/tools/editor/icons/icon_audio_stream_opus.png +++ b/editor/icons/icon_audio_stream_opus.png diff --git a/tools/editor/icons/icon_audio_stream_speex.png b/editor/icons/icon_audio_stream_speex.png Binary files differindex 6fefe47284..6fefe47284 100644 --- a/tools/editor/icons/icon_audio_stream_speex.png +++ b/editor/icons/icon_audio_stream_speex.png diff --git a/tools/editor/icons/icon_auto_play.png b/editor/icons/icon_auto_play.png Binary files differindex a6be64a1d1..a6be64a1d1 100644 --- a/tools/editor/icons/icon_auto_play.png +++ b/editor/icons/icon_auto_play.png diff --git a/tools/editor/icons/icon_b_c_s_f_x.png b/editor/icons/icon_b_c_s_f_x.png Binary files differindex 2100aea6a0..2100aea6a0 100644 --- a/tools/editor/icons/icon_b_c_s_f_x.png +++ b/editor/icons/icon_b_c_s_f_x.png diff --git a/tools/editor/icons/icon_b_g_color_f_x.png b/editor/icons/icon_b_g_color_f_x.png Binary files differindex 5b7552f6d5..5b7552f6d5 100644 --- a/tools/editor/icons/icon_b_g_color_f_x.png +++ b/editor/icons/icon_b_g_color_f_x.png diff --git a/tools/editor/icons/icon_b_g_image_f_x.png b/editor/icons/icon_b_g_image_f_x.png Binary files differindex 7e8ec86eec..7e8ec86eec 100644 --- a/tools/editor/icons/icon_b_g_image_f_x.png +++ b/editor/icons/icon_b_g_image_f_x.png diff --git a/tools/editor/icons/icon_back.png b/editor/icons/icon_back.png Binary files differindex 52fbc8117a..52fbc8117a 100644 --- a/tools/editor/icons/icon_back.png +++ b/editor/icons/icon_back.png diff --git a/tools/editor/icons/icon_back_buffer_copy.png b/editor/icons/icon_back_buffer_copy.png Binary files differindex 35f04ddac8..35f04ddac8 100644 --- a/tools/editor/icons/icon_back_buffer_copy.png +++ b/editor/icons/icon_back_buffer_copy.png diff --git a/tools/editor/icons/icon_back_disabled.png b/editor/icons/icon_back_disabled.png Binary files differindex 31aab496e2..31aab496e2 100644 --- a/tools/editor/icons/icon_back_disabled.png +++ b/editor/icons/icon_back_disabled.png diff --git a/tools/editor/icons/icon_back_no.png b/editor/icons/icon_back_no.png Binary files differindex 539ce4124a..539ce4124a 100644 --- a/tools/editor/icons/icon_back_no.png +++ b/editor/icons/icon_back_no.png diff --git a/tools/editor/icons/icon_bake.png b/editor/icons/icon_bake.png Binary files differindex 3b7fce5c9f..3b7fce5c9f 100644 --- a/tools/editor/icons/icon_bake.png +++ b/editor/icons/icon_bake.png diff --git a/tools/editor/icons/icon_baked_light.png b/editor/icons/icon_baked_light.png Binary files differindex 3b7fce5c9f..3b7fce5c9f 100644 --- a/tools/editor/icons/icon_baked_light.png +++ b/editor/icons/icon_baked_light.png diff --git a/tools/editor/icons/icon_baked_light_instance.png b/editor/icons/icon_baked_light_instance.png Binary files differindex c667b542c1..c667b542c1 100644 --- a/tools/editor/icons/icon_baked_light_instance.png +++ b/editor/icons/icon_baked_light_instance.png diff --git a/tools/editor/icons/icon_baked_light_sampler.png b/editor/icons/icon_baked_light_sampler.png Binary files differindex 15ff7b98b9..15ff7b98b9 100644 --- a/tools/editor/icons/icon_baked_light_sampler.png +++ b/editor/icons/icon_baked_light_sampler.png diff --git a/tools/editor/icons/icon_bit_map.png b/editor/icons/icon_bit_map.png Binary files differindex 50dd8157d1..50dd8157d1 100644 --- a/tools/editor/icons/icon_bit_map.png +++ b/editor/icons/icon_bit_map.png diff --git a/tools/editor/icons/icon_bitmap_font.png b/editor/icons/icon_bitmap_font.png Binary files differindex 5334c335dc..5334c335dc 100644 --- a/tools/editor/icons/icon_bitmap_font.png +++ b/editor/icons/icon_bitmap_font.png diff --git a/tools/editor/icons/icon_blend.png b/editor/icons/icon_blend.png Binary files differindex 1676c650c2..1676c650c2 100644 --- a/tools/editor/icons/icon_blend.png +++ b/editor/icons/icon_blend.png diff --git a/tools/editor/icons/icon_bone.png b/editor/icons/icon_bone.png Binary files differindex 2d9a7b47f3..2d9a7b47f3 100644 --- a/tools/editor/icons/icon_bone.png +++ b/editor/icons/icon_bone.png diff --git a/tools/editor/icons/icon_bone_attachment.png b/editor/icons/icon_bone_attachment.png Binary files differindex 882bb55f44..882bb55f44 100644 --- a/tools/editor/icons/icon_bone_attachment.png +++ b/editor/icons/icon_bone_attachment.png diff --git a/tools/editor/icons/icon_bone_track.png b/editor/icons/icon_bone_track.png Binary files differindex 1e55e53d6b..1e55e53d6b 100644 --- a/tools/editor/icons/icon_bone_track.png +++ b/editor/icons/icon_bone_track.png diff --git a/tools/editor/icons/icon_bool.png b/editor/icons/icon_bool.png Binary files differindex 822b5dd688..822b5dd688 100644 --- a/tools/editor/icons/icon_bool.png +++ b/editor/icons/icon_bool.png diff --git a/tools/editor/icons/icon_box_shape.png b/editor/icons/icon_box_shape.png Binary files differindex 68ec6088c9..68ec6088c9 100644 --- a/tools/editor/icons/icon_box_shape.png +++ b/editor/icons/icon_box_shape.png diff --git a/tools/editor/icons/icon_bus_vu_db.png b/editor/icons/icon_bus_vu_db.png Binary files differindex 52507cae52..52507cae52 100644 --- a/tools/editor/icons/icon_bus_vu_db.png +++ b/editor/icons/icon_bus_vu_db.png diff --git a/tools/editor/icons/icon_bus_vu_empty.png b/editor/icons/icon_bus_vu_empty.png Binary files differindex 6fc3143a55..6fc3143a55 100644 --- a/tools/editor/icons/icon_bus_vu_empty.png +++ b/editor/icons/icon_bus_vu_empty.png diff --git a/tools/editor/icons/icon_bus_vu_frozen.png b/editor/icons/icon_bus_vu_frozen.png Binary files differindex cf128afa91..cf128afa91 100644 --- a/tools/editor/icons/icon_bus_vu_frozen.png +++ b/editor/icons/icon_bus_vu_frozen.png diff --git a/tools/editor/icons/icon_bus_vu_full.png b/editor/icons/icon_bus_vu_full.png Binary files differindex 9e3d7a93e3..9e3d7a93e3 100644 --- a/tools/editor/icons/icon_bus_vu_full.png +++ b/editor/icons/icon_bus_vu_full.png diff --git a/tools/editor/icons/icon_button.png b/editor/icons/icon_button.png Binary files differindex da02831da2..da02831da2 100644 --- a/tools/editor/icons/icon_button.png +++ b/editor/icons/icon_button.png diff --git a/tools/editor/icons/icon_button_group.png b/editor/icons/icon_button_group.png Binary files differindex c105234598..c105234598 100644 --- a/tools/editor/icons/icon_button_group.png +++ b/editor/icons/icon_button_group.png diff --git a/tools/editor/icons/icon_camera.png b/editor/icons/icon_camera.png Binary files differindex 4dff1791ad..4dff1791ad 100644 --- a/tools/editor/icons/icon_camera.png +++ b/editor/icons/icon_camera.png diff --git a/tools/editor/icons/icon_camera_2d.png b/editor/icons/icon_camera_2d.png Binary files differindex 6497997afe..6497997afe 100644 --- a/tools/editor/icons/icon_camera_2d.png +++ b/editor/icons/icon_camera_2d.png diff --git a/tools/editor/icons/icon_canvas_item.png b/editor/icons/icon_canvas_item.png Binary files differindex 64f5d8abdf..64f5d8abdf 100644 --- a/tools/editor/icons/icon_canvas_item.png +++ b/editor/icons/icon_canvas_item.png diff --git a/tools/editor/icons/icon_canvas_item_material.png b/editor/icons/icon_canvas_item_material.png Binary files differindex a04f6e8f5f..a04f6e8f5f 100644 --- a/tools/editor/icons/icon_canvas_item_material.png +++ b/editor/icons/icon_canvas_item_material.png diff --git a/tools/editor/icons/icon_canvas_item_shader.png b/editor/icons/icon_canvas_item_shader.png Binary files differindex 8392f889d1..8392f889d1 100644 --- a/tools/editor/icons/icon_canvas_item_shader.png +++ b/editor/icons/icon_canvas_item_shader.png diff --git a/tools/editor/icons/icon_canvas_item_shader_graph.png b/editor/icons/icon_canvas_item_shader_graph.png Binary files differindex f40e3755af..f40e3755af 100644 --- a/tools/editor/icons/icon_canvas_item_shader_graph.png +++ b/editor/icons/icon_canvas_item_shader_graph.png diff --git a/tools/editor/icons/icon_canvas_layer.png b/editor/icons/icon_canvas_layer.png Binary files differindex bb32d6d3ad..bb32d6d3ad 100644 --- a/tools/editor/icons/icon_canvas_layer.png +++ b/editor/icons/icon_canvas_layer.png diff --git a/tools/editor/icons/icon_canvas_modulate.png b/editor/icons/icon_canvas_modulate.png Binary files differindex b76e532268..b76e532268 100644 --- a/tools/editor/icons/icon_canvas_modulate.png +++ b/editor/icons/icon_canvas_modulate.png diff --git a/tools/editor/icons/icon_capsule_shape.png b/editor/icons/icon_capsule_shape.png Binary files differindex bc00e491d3..bc00e491d3 100644 --- a/tools/editor/icons/icon_capsule_shape.png +++ b/editor/icons/icon_capsule_shape.png diff --git a/tools/editor/icons/icon_capsule_shape_2d.png b/editor/icons/icon_capsule_shape_2d.png Binary files differindex 6f6554fbc7..6f6554fbc7 100644 --- a/tools/editor/icons/icon_capsule_shape_2d.png +++ b/editor/icons/icon_capsule_shape_2d.png diff --git a/tools/editor/icons/icon_center_container.png b/editor/icons/icon_center_container.png Binary files differindex 61904e7b00..61904e7b00 100644 --- a/tools/editor/icons/icon_center_container.png +++ b/editor/icons/icon_center_container.png diff --git a/tools/editor/icons/icon_character_body.png b/editor/icons/icon_character_body.png Binary files differindex b859a271d5..b859a271d5 100644 --- a/tools/editor/icons/icon_character_body.png +++ b/editor/icons/icon_character_body.png diff --git a/tools/editor/icons/icon_character_camera.png b/editor/icons/icon_character_camera.png Binary files differindex c238487942..c238487942 100644 --- a/tools/editor/icons/icon_character_camera.png +++ b/editor/icons/icon_character_camera.png diff --git a/tools/editor/icons/icon_check_box.png b/editor/icons/icon_check_box.png Binary files differindex f0e614d0e7..f0e614d0e7 100644 --- a/tools/editor/icons/icon_check_box.png +++ b/editor/icons/icon_check_box.png diff --git a/tools/editor/icons/icon_check_button.png b/editor/icons/icon_check_button.png Binary files differindex 968188f43d..968188f43d 100644 --- a/tools/editor/icons/icon_check_button.png +++ b/editor/icons/icon_check_button.png diff --git a/tools/editor/icons/icon_checkerboard.png b/editor/icons/icon_checkerboard.png Binary files differindex 5f658c765e..5f658c765e 100644 --- a/tools/editor/icons/icon_checkerboard.png +++ b/editor/icons/icon_checkerboard.png diff --git a/tools/editor/icons/icon_circle_shape_2d.png b/editor/icons/icon_circle_shape_2d.png Binary files differindex 7865ed3dbe..7865ed3dbe 100644 --- a/tools/editor/icons/icon_circle_shape_2d.png +++ b/editor/icons/icon_circle_shape_2d.png diff --git a/tools/editor/icons/icon_class_list.png b/editor/icons/icon_class_list.png Binary files differindex 5faff250d7..5faff250d7 100644 --- a/tools/editor/icons/icon_class_list.png +++ b/editor/icons/icon_class_list.png diff --git a/tools/editor/icons/icon_click2edit.png b/editor/icons/icon_click2edit.png Binary files differindex 795756dff0..795756dff0 100644 --- a/tools/editor/icons/icon_click2edit.png +++ b/editor/icons/icon_click2edit.png diff --git a/tools/editor/icons/icon_close.png b/editor/icons/icon_close.png Binary files differindex 20d9b5c810..20d9b5c810 100644 --- a/tools/editor/icons/icon_close.png +++ b/editor/icons/icon_close.png diff --git a/tools/editor/icons/icon_close_hover.png b/editor/icons/icon_close_hover.png Binary files differindex cb519691e5..cb519691e5 100644 --- a/tools/editor/icons/icon_close_hover.png +++ b/editor/icons/icon_close_hover.png diff --git a/tools/editor/icons/icon_collapse.png b/editor/icons/icon_collapse.png Binary files differindex ad2442183d..ad2442183d 100644 --- a/tools/editor/icons/icon_collapse.png +++ b/editor/icons/icon_collapse.png diff --git a/tools/editor/icons/icon_collapse_hl.png b/editor/icons/icon_collapse_hl.png Binary files differindex 0dfbc8b175..0dfbc8b175 100644 --- a/tools/editor/icons/icon_collapse_hl.png +++ b/editor/icons/icon_collapse_hl.png diff --git a/tools/editor/icons/icon_collision.png b/editor/icons/icon_collision.png Binary files differindex ccda8b6a25..ccda8b6a25 100644 --- a/tools/editor/icons/icon_collision.png +++ b/editor/icons/icon_collision.png diff --git a/tools/editor/icons/icon_collision_2d.png b/editor/icons/icon_collision_2d.png Binary files differindex b372749cb0..b372749cb0 100644 --- a/tools/editor/icons/icon_collision_2d.png +++ b/editor/icons/icon_collision_2d.png diff --git a/tools/editor/icons/icon_collision_polygon.png b/editor/icons/icon_collision_polygon.png Binary files differindex 738f80c3f3..738f80c3f3 100644 --- a/tools/editor/icons/icon_collision_polygon.png +++ b/editor/icons/icon_collision_polygon.png diff --git a/tools/editor/icons/icon_collision_polygon_2d.png b/editor/icons/icon_collision_polygon_2d.png Binary files differindex b372749cb0..b372749cb0 100644 --- a/tools/editor/icons/icon_collision_polygon_2d.png +++ b/editor/icons/icon_collision_polygon_2d.png diff --git a/tools/editor/icons/icon_collision_shape.png b/editor/icons/icon_collision_shape.png Binary files differindex 7bcd61c719..7bcd61c719 100644 --- a/tools/editor/icons/icon_collision_shape.png +++ b/editor/icons/icon_collision_shape.png diff --git a/tools/editor/icons/icon_collision_shape_2d.png b/editor/icons/icon_collision_shape_2d.png Binary files differindex afc1326959..afc1326959 100644 --- a/tools/editor/icons/icon_collision_shape_2d.png +++ b/editor/icons/icon_collision_shape_2d.png diff --git a/tools/editor/icons/icon_color.png b/editor/icons/icon_color.png Binary files differindex 589a6d3ffa..589a6d3ffa 100644 --- a/tools/editor/icons/icon_color.png +++ b/editor/icons/icon_color.png diff --git a/tools/editor/icons/icon_color_pick.png b/editor/icons/icon_color_pick.png Binary files differindex 15679a9558..15679a9558 100644 --- a/tools/editor/icons/icon_color_pick.png +++ b/editor/icons/icon_color_pick.png diff --git a/tools/editor/icons/icon_color_picker.png b/editor/icons/icon_color_picker.png Binary files differindex 6d1114054a..6d1114054a 100644 --- a/tools/editor/icons/icon_color_picker.png +++ b/editor/icons/icon_color_picker.png diff --git a/tools/editor/icons/icon_color_picker_button.png b/editor/icons/icon_color_picker_button.png Binary files differindex a399128773..a399128773 100644 --- a/tools/editor/icons/icon_color_picker_button.png +++ b/editor/icons/icon_color_picker_button.png diff --git a/tools/editor/icons/icon_color_ramp.png b/editor/icons/icon_color_ramp.png Binary files differindex 03d19a56bb..03d19a56bb 100644 --- a/tools/editor/icons/icon_color_ramp.png +++ b/editor/icons/icon_color_ramp.png diff --git a/tools/editor/icons/icon_color_rect.png b/editor/icons/icon_color_rect.png Binary files differindex 40b9dab605..40b9dab605 100644 --- a/tools/editor/icons/icon_color_rect.png +++ b/editor/icons/icon_color_rect.png diff --git a/tools/editor/icons/icon_concave_polygon_shape.png b/editor/icons/icon_concave_polygon_shape.png Binary files differindex dc1ff1d388..dc1ff1d388 100644 --- a/tools/editor/icons/icon_concave_polygon_shape.png +++ b/editor/icons/icon_concave_polygon_shape.png diff --git a/tools/editor/icons/icon_concave_polygon_shape_2d.png b/editor/icons/icon_concave_polygon_shape_2d.png Binary files differindex 2e87eea5aa..2e87eea5aa 100644 --- a/tools/editor/icons/icon_concave_polygon_shape_2d.png +++ b/editor/icons/icon_concave_polygon_shape_2d.png diff --git a/tools/editor/icons/icon_cone_twist_joint.png b/editor/icons/icon_cone_twist_joint.png Binary files differindex bbf93f2f71..bbf93f2f71 100644 --- a/tools/editor/icons/icon_cone_twist_joint.png +++ b/editor/icons/icon_cone_twist_joint.png diff --git a/tools/editor/icons/icon_confirmation_dialog.png b/editor/icons/icon_confirmation_dialog.png Binary files differindex 2dd4cd00fb..2dd4cd00fb 100644 --- a/tools/editor/icons/icon_confirmation_dialog.png +++ b/editor/icons/icon_confirmation_dialog.png diff --git a/tools/editor/icons/icon_connect.png b/editor/icons/icon_connect.png Binary files differindex 51615838a9..51615838a9 100644 --- a/tools/editor/icons/icon_connect.png +++ b/editor/icons/icon_connect.png diff --git a/tools/editor/icons/icon_connection_and_groups.png b/editor/icons/icon_connection_and_groups.png Binary files differindex 76e036e5bb..76e036e5bb 100644 --- a/tools/editor/icons/icon_connection_and_groups.png +++ b/editor/icons/icon_connection_and_groups.png diff --git a/tools/editor/icons/icon_console.png b/editor/icons/icon_console.png Binary files differindex 7dc7407ef7..7dc7407ef7 100644 --- a/tools/editor/icons/icon_console.png +++ b/editor/icons/icon_console.png diff --git a/tools/editor/icons/icon_container.png b/editor/icons/icon_container.png Binary files differindex ae0d76072b..ae0d76072b 100644 --- a/tools/editor/icons/icon_container.png +++ b/editor/icons/icon_container.png diff --git a/tools/editor/icons/icon_control.png b/editor/icons/icon_control.png Binary files differindex 0d2a82ad0e..0d2a82ad0e 100644 --- a/tools/editor/icons/icon_control.png +++ b/editor/icons/icon_control.png diff --git a/tools/editor/icons/icon_control_align_bottom_center.png b/editor/icons/icon_control_align_bottom_center.png Binary files differindex 166f122ace..166f122ace 100644 --- a/tools/editor/icons/icon_control_align_bottom_center.png +++ b/editor/icons/icon_control_align_bottom_center.png diff --git a/tools/editor/icons/icon_control_align_bottom_left.png b/editor/icons/icon_control_align_bottom_left.png Binary files differindex 238f33a098..238f33a098 100644 --- a/tools/editor/icons/icon_control_align_bottom_left.png +++ b/editor/icons/icon_control_align_bottom_left.png diff --git a/tools/editor/icons/icon_control_align_bottom_right.png b/editor/icons/icon_control_align_bottom_right.png Binary files differindex ff8b6a0177..ff8b6a0177 100644 --- a/tools/editor/icons/icon_control_align_bottom_right.png +++ b/editor/icons/icon_control_align_bottom_right.png diff --git a/tools/editor/icons/icon_control_align_bottom_wide.png b/editor/icons/icon_control_align_bottom_wide.png Binary files differindex 309907767e..309907767e 100644 --- a/tools/editor/icons/icon_control_align_bottom_wide.png +++ b/editor/icons/icon_control_align_bottom_wide.png diff --git a/tools/editor/icons/icon_control_align_center.png b/editor/icons/icon_control_align_center.png Binary files differindex 964f132ac3..964f132ac3 100644 --- a/tools/editor/icons/icon_control_align_center.png +++ b/editor/icons/icon_control_align_center.png diff --git a/tools/editor/icons/icon_control_align_center_left.png b/editor/icons/icon_control_align_center_left.png Binary files differindex 704b4f504f..704b4f504f 100644 --- a/tools/editor/icons/icon_control_align_center_left.png +++ b/editor/icons/icon_control_align_center_left.png diff --git a/tools/editor/icons/icon_control_align_center_right.png b/editor/icons/icon_control_align_center_right.png Binary files differindex bd7111aec3..bd7111aec3 100644 --- a/tools/editor/icons/icon_control_align_center_right.png +++ b/editor/icons/icon_control_align_center_right.png diff --git a/tools/editor/icons/icon_control_align_left_center.png b/editor/icons/icon_control_align_left_center.png Binary files differindex 75c2d8573f..75c2d8573f 100644 --- a/tools/editor/icons/icon_control_align_left_center.png +++ b/editor/icons/icon_control_align_left_center.png diff --git a/tools/editor/icons/icon_control_align_left_wide.png b/editor/icons/icon_control_align_left_wide.png Binary files differindex 92a13144cb..92a13144cb 100644 --- a/tools/editor/icons/icon_control_align_left_wide.png +++ b/editor/icons/icon_control_align_left_wide.png diff --git a/tools/editor/icons/icon_control_align_right_center.png b/editor/icons/icon_control_align_right_center.png Binary files differindex a859035439..a859035439 100644 --- a/tools/editor/icons/icon_control_align_right_center.png +++ b/editor/icons/icon_control_align_right_center.png diff --git a/tools/editor/icons/icon_control_align_right_wide.png b/editor/icons/icon_control_align_right_wide.png Binary files differindex b6fef9569e..b6fef9569e 100644 --- a/tools/editor/icons/icon_control_align_right_wide.png +++ b/editor/icons/icon_control_align_right_wide.png diff --git a/tools/editor/icons/icon_control_align_top_center.png b/editor/icons/icon_control_align_top_center.png Binary files differindex 5cdd6cd2fc..5cdd6cd2fc 100644 --- a/tools/editor/icons/icon_control_align_top_center.png +++ b/editor/icons/icon_control_align_top_center.png diff --git a/tools/editor/icons/icon_control_align_top_left.png b/editor/icons/icon_control_align_top_left.png Binary files differindex 558e3f08cb..558e3f08cb 100644 --- a/tools/editor/icons/icon_control_align_top_left.png +++ b/editor/icons/icon_control_align_top_left.png diff --git a/tools/editor/icons/icon_control_align_top_right.png b/editor/icons/icon_control_align_top_right.png Binary files differindex 5ca294de48..5ca294de48 100644 --- a/tools/editor/icons/icon_control_align_top_right.png +++ b/editor/icons/icon_control_align_top_right.png diff --git a/tools/editor/icons/icon_control_align_top_wide.png b/editor/icons/icon_control_align_top_wide.png Binary files differindex ec089d0174..ec089d0174 100644 --- a/tools/editor/icons/icon_control_align_top_wide.png +++ b/editor/icons/icon_control_align_top_wide.png diff --git a/tools/editor/icons/icon_control_align_wide.png b/editor/icons/icon_control_align_wide.png Binary files differindex 45552740bf..45552740bf 100644 --- a/tools/editor/icons/icon_control_align_wide.png +++ b/editor/icons/icon_control_align_wide.png diff --git a/tools/editor/icons/icon_control_hcenter_wide.png b/editor/icons/icon_control_hcenter_wide.png Binary files differindex f298b22f5f..f298b22f5f 100644 --- a/tools/editor/icons/icon_control_hcenter_wide.png +++ b/editor/icons/icon_control_hcenter_wide.png diff --git a/tools/editor/icons/icon_control_vcenter_wide.png b/editor/icons/icon_control_vcenter_wide.png Binary files differindex b6c90646fb..b6c90646fb 100644 --- a/tools/editor/icons/icon_control_vcenter_wide.png +++ b/editor/icons/icon_control_vcenter_wide.png diff --git a/tools/editor/icons/icon_convex_polygon_shape.png b/editor/icons/icon_convex_polygon_shape.png Binary files differindex 4dfc9acc9e..4dfc9acc9e 100644 --- a/tools/editor/icons/icon_convex_polygon_shape.png +++ b/editor/icons/icon_convex_polygon_shape.png diff --git a/tools/editor/icons/icon_convex_polygon_shape_2d.png b/editor/icons/icon_convex_polygon_shape_2d.png Binary files differindex e449c6930f..e449c6930f 100644 --- a/tools/editor/icons/icon_convex_polygon_shape_2d.png +++ b/editor/icons/icon_convex_polygon_shape_2d.png diff --git a/tools/editor/icons/icon_copy_node_path.png b/editor/icons/icon_copy_node_path.png Binary files differindex d777f132d8..d777f132d8 100644 --- a/tools/editor/icons/icon_copy_node_path.png +++ b/editor/icons/icon_copy_node_path.png diff --git a/tools/editor/icons/icon_create_new_scene_from.png b/editor/icons/icon_create_new_scene_from.png Binary files differindex 45df9b1e25..45df9b1e25 100644 --- a/tools/editor/icons/icon_create_new_scene_from.png +++ b/editor/icons/icon_create_new_scene_from.png diff --git a/tools/editor/icons/icon_cube_grid_map.png b/editor/icons/icon_cube_grid_map.png Binary files differindex fe13222691..fe13222691 100644 --- a/tools/editor/icons/icon_cube_grid_map.png +++ b/editor/icons/icon_cube_grid_map.png diff --git a/tools/editor/icons/icon_cube_map.png b/editor/icons/icon_cube_map.png Binary files differindex 9c4c6fdc9f..9c4c6fdc9f 100644 --- a/tools/editor/icons/icon_cube_map.png +++ b/editor/icons/icon_cube_map.png diff --git a/tools/editor/icons/icon_curve.png b/editor/icons/icon_curve.png Binary files differindex 27d423edcd..27d423edcd 100644 --- a/tools/editor/icons/icon_curve.png +++ b/editor/icons/icon_curve.png diff --git a/tools/editor/icons/icon_curve_2d.png b/editor/icons/icon_curve_2d.png Binary files differindex ce46dcaad4..ce46dcaad4 100644 --- a/tools/editor/icons/icon_curve_2d.png +++ b/editor/icons/icon_curve_2d.png diff --git a/tools/editor/icons/icon_curve_3d.png b/editor/icons/icon_curve_3d.png Binary files differindex 561837e4de..561837e4de 100644 --- a/tools/editor/icons/icon_curve_3d.png +++ b/editor/icons/icon_curve_3d.png diff --git a/tools/editor/icons/icon_curve_close.png b/editor/icons/icon_curve_close.png Binary files differindex 9a66015252..9a66015252 100644 --- a/tools/editor/icons/icon_curve_close.png +++ b/editor/icons/icon_curve_close.png diff --git a/tools/editor/icons/icon_curve_constant.png b/editor/icons/icon_curve_constant.png Binary files differindex 510a01c7ec..510a01c7ec 100644 --- a/tools/editor/icons/icon_curve_constant.png +++ b/editor/icons/icon_curve_constant.png diff --git a/tools/editor/icons/icon_curve_create.png b/editor/icons/icon_curve_create.png Binary files differindex b07820a5cd..b07820a5cd 100644 --- a/tools/editor/icons/icon_curve_create.png +++ b/editor/icons/icon_curve_create.png diff --git a/tools/editor/icons/icon_curve_curve.png b/editor/icons/icon_curve_curve.png Binary files differindex 7d71af0a23..7d71af0a23 100644 --- a/tools/editor/icons/icon_curve_curve.png +++ b/editor/icons/icon_curve_curve.png diff --git a/tools/editor/icons/icon_curve_delete.png b/editor/icons/icon_curve_delete.png Binary files differindex 108bfeac35..108bfeac35 100644 --- a/tools/editor/icons/icon_curve_delete.png +++ b/editor/icons/icon_curve_delete.png diff --git a/tools/editor/icons/icon_curve_edit.png b/editor/icons/icon_curve_edit.png Binary files differindex 51eb583384..51eb583384 100644 --- a/tools/editor/icons/icon_curve_edit.png +++ b/editor/icons/icon_curve_edit.png diff --git a/tools/editor/icons/icon_curve_in.png b/editor/icons/icon_curve_in.png Binary files differindex a809ee43d3..a809ee43d3 100644 --- a/tools/editor/icons/icon_curve_in.png +++ b/editor/icons/icon_curve_in.png diff --git a/tools/editor/icons/icon_curve_in_out.png b/editor/icons/icon_curve_in_out.png Binary files differindex 88e07d48a7..88e07d48a7 100644 --- a/tools/editor/icons/icon_curve_in_out.png +++ b/editor/icons/icon_curve_in_out.png diff --git a/tools/editor/icons/icon_curve_linear.png b/editor/icons/icon_curve_linear.png Binary files differindex 80306b6e04..80306b6e04 100644 --- a/tools/editor/icons/icon_curve_linear.png +++ b/editor/icons/icon_curve_linear.png diff --git a/tools/editor/icons/icon_curve_out.png b/editor/icons/icon_curve_out.png Binary files differindex aa05bc8f86..aa05bc8f86 100644 --- a/tools/editor/icons/icon_curve_out.png +++ b/editor/icons/icon_curve_out.png diff --git a/tools/editor/icons/icon_curve_out_in.png b/editor/icons/icon_curve_out_in.png Binary files differindex 7be46fc779..7be46fc779 100644 --- a/tools/editor/icons/icon_curve_out_in.png +++ b/editor/icons/icon_curve_out_in.png diff --git a/tools/editor/icons/icon_cylinder_shape.png b/editor/icons/icon_cylinder_shape.png Binary files differindex fd7d7e26e2..fd7d7e26e2 100644 --- a/tools/editor/icons/icon_cylinder_shape.png +++ b/editor/icons/icon_cylinder_shape.png diff --git a/tools/editor/icons/icon_d_o_f_blur_f_x.png b/editor/icons/icon_d_o_f_blur_f_x.png Binary files differindex fda7d48353..fda7d48353 100644 --- a/tools/editor/icons/icon_d_o_f_blur_f_x.png +++ b/editor/icons/icon_d_o_f_blur_f_x.png diff --git a/tools/editor/icons/icon_damped_spring_joint_2d.png b/editor/icons/icon_damped_spring_joint_2d.png Binary files differindex b6a9c2b3a1..b6a9c2b3a1 100644 --- a/tools/editor/icons/icon_damped_spring_joint_2d.png +++ b/editor/icons/icon_damped_spring_joint_2d.png diff --git a/tools/editor/icons/icon_debug.png b/editor/icons/icon_debug.png Binary files differindex 03b98aa9e4..03b98aa9e4 100644 --- a/tools/editor/icons/icon_debug.png +++ b/editor/icons/icon_debug.png diff --git a/tools/editor/icons/icon_debug_continue.png b/editor/icons/icon_debug_continue.png Binary files differindex 78a61aa98f..78a61aa98f 100644 --- a/tools/editor/icons/icon_debug_continue.png +++ b/editor/icons/icon_debug_continue.png diff --git a/tools/editor/icons/icon_debug_next.png b/editor/icons/icon_debug_next.png Binary files differindex c61f221562..c61f221562 100644 --- a/tools/editor/icons/icon_debug_next.png +++ b/editor/icons/icon_debug_next.png diff --git a/tools/editor/icons/icon_debug_step.png b/editor/icons/icon_debug_step.png Binary files differindex a1839d56d8..a1839d56d8 100644 --- a/tools/editor/icons/icon_debug_step.png +++ b/editor/icons/icon_debug_step.png diff --git a/tools/editor/icons/icon_default_project_icon.png b/editor/icons/icon_default_project_icon.png Binary files differindex e87a49bd28..e87a49bd28 100644 --- a/tools/editor/icons/icon_default_project_icon.png +++ b/editor/icons/icon_default_project_icon.png diff --git a/tools/editor/icons/icon_del.png b/editor/icons/icon_del.png Binary files differindex 10e56d5bb8..10e56d5bb8 100644 --- a/tools/editor/icons/icon_del.png +++ b/editor/icons/icon_del.png diff --git a/tools/editor/icons/icon_dependency_changed.png b/editor/icons/icon_dependency_changed.png Binary files differindex 1b396457d3..1b396457d3 100644 --- a/tools/editor/icons/icon_dependency_changed.png +++ b/editor/icons/icon_dependency_changed.png diff --git a/tools/editor/icons/icon_dependency_changed_hl.png b/editor/icons/icon_dependency_changed_hl.png Binary files differindex 51dfe6b39d..51dfe6b39d 100644 --- a/tools/editor/icons/icon_dependency_changed_hl.png +++ b/editor/icons/icon_dependency_changed_hl.png diff --git a/tools/editor/icons/icon_dependency_local_changed.png b/editor/icons/icon_dependency_local_changed.png Binary files differindex d8737fd2f4..d8737fd2f4 100644 --- a/tools/editor/icons/icon_dependency_local_changed.png +++ b/editor/icons/icon_dependency_local_changed.png diff --git a/tools/editor/icons/icon_dependency_local_changed_hl.png b/editor/icons/icon_dependency_local_changed_hl.png Binary files differindex a87c48ca3e..a87c48ca3e 100644 --- a/tools/editor/icons/icon_dependency_local_changed_hl.png +++ b/editor/icons/icon_dependency_local_changed_hl.png diff --git a/tools/editor/icons/icon_dependency_ok.png b/editor/icons/icon_dependency_ok.png Binary files differindex 2b9ac389ba..2b9ac389ba 100644 --- a/tools/editor/icons/icon_dependency_ok.png +++ b/editor/icons/icon_dependency_ok.png diff --git a/tools/editor/icons/icon_dependency_ok_hl.png b/editor/icons/icon_dependency_ok_hl.png Binary files differindex 62e48531e4..62e48531e4 100644 --- a/tools/editor/icons/icon_dependency_ok_hl.png +++ b/editor/icons/icon_dependency_ok_hl.png diff --git a/tools/editor/icons/icon_directional_light.png b/editor/icons/icon_directional_light.png Binary files differindex 31f47c974d..31f47c974d 100644 --- a/tools/editor/icons/icon_directional_light.png +++ b/editor/icons/icon_directional_light.png diff --git a/tools/editor/icons/icon_distraction_free.png b/editor/icons/icon_distraction_free.png Binary files differindex c6f8a08874..c6f8a08874 100644 --- a/tools/editor/icons/icon_distraction_free.png +++ b/editor/icons/icon_distraction_free.png diff --git a/tools/editor/icons/icon_doc_code_font.png b/editor/icons/icon_doc_code_font.png Binary files differindex 628654f6e8..628654f6e8 100644 --- a/tools/editor/icons/icon_doc_code_font.png +++ b/editor/icons/icon_doc_code_font.png diff --git a/tools/editor/icons/icon_doc_font.png b/editor/icons/icon_doc_font.png Binary files differindex 65fbcc5ccc..65fbcc5ccc 100644 --- a/tools/editor/icons/icon_doc_font.png +++ b/editor/icons/icon_doc_font.png diff --git a/tools/editor/icons/icon_doc_title_font.png b/editor/icons/icon_doc_title_font.png Binary files differindex d78b394da0..d78b394da0 100644 --- a/tools/editor/icons/icon_doc_title_font.png +++ b/editor/icons/icon_doc_title_font.png diff --git a/tools/editor/icons/icon_down.png b/editor/icons/icon_down.png Binary files differindex d2fcdb4c9f..d2fcdb4c9f 100644 --- a/tools/editor/icons/icon_down.png +++ b/editor/icons/icon_down.png diff --git a/tools/editor/icons/icon_dummy.png b/editor/icons/icon_dummy.png Binary files differindex 24998a28af..24998a28af 100644 --- a/tools/editor/icons/icon_dummy.png +++ b/editor/icons/icon_dummy.png diff --git a/tools/editor/icons/icon_duplicate.png b/editor/icons/icon_duplicate.png Binary files differindex 320b36504e..320b36504e 100644 --- a/tools/editor/icons/icon_duplicate.png +++ b/editor/icons/icon_duplicate.png diff --git a/tools/editor/icons/icon_dynamic_character_body.png b/editor/icons/icon_dynamic_character_body.png Binary files differindex b685841e35..b685841e35 100644 --- a/tools/editor/icons/icon_dynamic_character_body.png +++ b/editor/icons/icon_dynamic_character_body.png diff --git a/tools/editor/icons/icon_dynamic_custom_body.png b/editor/icons/icon_dynamic_custom_body.png Binary files differindex d383e7087f..d383e7087f 100644 --- a/tools/editor/icons/icon_dynamic_custom_body.png +++ b/editor/icons/icon_dynamic_custom_body.png diff --git a/tools/editor/icons/icon_dynamic_font.png b/editor/icons/icon_dynamic_font.png Binary files differindex e373553e4e..e373553e4e 100644 --- a/tools/editor/icons/icon_dynamic_font.png +++ b/editor/icons/icon_dynamic_font.png diff --git a/tools/editor/icons/icon_dynamic_font_data.png b/editor/icons/icon_dynamic_font_data.png Binary files differindex 5cff86c40c..5cff86c40c 100644 --- a/tools/editor/icons/icon_dynamic_font_data.png +++ b/editor/icons/icon_dynamic_font_data.png diff --git a/tools/editor/icons/icon_dynamic_rigid_body.png b/editor/icons/icon_dynamic_rigid_body.png Binary files differindex f804b29528..f804b29528 100644 --- a/tools/editor/icons/icon_dynamic_rigid_body.png +++ b/editor/icons/icon_dynamic_rigid_body.png diff --git a/tools/editor/icons/icon_edit.png b/editor/icons/icon_edit.png Binary files differindex c114d2f84d..c114d2f84d 100644 --- a/tools/editor/icons/icon_edit.png +++ b/editor/icons/icon_edit.png diff --git a/tools/editor/icons/icon_edit_key.png b/editor/icons/icon_edit_key.png Binary files differindex 3ebbe75f78..3ebbe75f78 100644 --- a/tools/editor/icons/icon_edit_key.png +++ b/editor/icons/icon_edit_key.png diff --git a/tools/editor/icons/icon_edit_pivot.png b/editor/icons/icon_edit_pivot.png Binary files differindex 230122b969..230122b969 100644 --- a/tools/editor/icons/icon_edit_pivot.png +++ b/editor/icons/icon_edit_pivot.png diff --git a/tools/editor/icons/icon_edit_resource.png b/editor/icons/icon_edit_resource.png Binary files differindex 9f064fea3f..9f064fea3f 100644 --- a/tools/editor/icons/icon_edit_resource.png +++ b/editor/icons/icon_edit_resource.png diff --git a/tools/editor/icons/icon_edit_small.png b/editor/icons/icon_edit_small.png Binary files differindex 19c83415f9..19c83415f9 100644 --- a/tools/editor/icons/icon_edit_small.png +++ b/editor/icons/icon_edit_small.png diff --git a/tools/editor/icons/icon_editor_2d.png b/editor/icons/icon_editor_2d.png Binary files differindex 1594f5adf0..1594f5adf0 100644 --- a/tools/editor/icons/icon_editor_2d.png +++ b/editor/icons/icon_editor_2d.png diff --git a/tools/editor/icons/icon_editor_3d_handle.png b/editor/icons/icon_editor_3d_handle.png Binary files differindex 6935cc9bc4..6935cc9bc4 100644 --- a/tools/editor/icons/icon_editor_3d_handle.png +++ b/editor/icons/icon_editor_3d_handle.png diff --git a/tools/editor/icons/icon_editor_focus.png b/editor/icons/icon_editor_focus.png Binary files differindex 40ce11f381..40ce11f381 100644 --- a/tools/editor/icons/icon_editor_focus.png +++ b/editor/icons/icon_editor_focus.png diff --git a/tools/editor/icons/icon_editor_handle.png b/editor/icons/icon_editor_handle.png Binary files differindex 8950a216da..8950a216da 100644 --- a/tools/editor/icons/icon_editor_handle.png +++ b/editor/icons/icon_editor_handle.png diff --git a/tools/editor/icons/icon_editor_node.png b/editor/icons/icon_editor_node.png Binary files differindex aec161ed54..aec161ed54 100644 --- a/tools/editor/icons/icon_editor_node.png +++ b/editor/icons/icon_editor_node.png diff --git a/tools/editor/icons/icon_editor_pivot.png b/editor/icons/icon_editor_pivot.png Binary files differindex db7feb0be6..db7feb0be6 100644 --- a/tools/editor/icons/icon_editor_pivot.png +++ b/editor/icons/icon_editor_pivot.png diff --git a/tools/editor/icons/icon_editor_plugin.png b/editor/icons/icon_editor_plugin.png Binary files differindex ff7004b993..ff7004b993 100644 --- a/tools/editor/icons/icon_editor_plugin.png +++ b/editor/icons/icon_editor_plugin.png diff --git a/tools/editor/icons/icon_editor_rect_2d.png b/editor/icons/icon_editor_rect_2d.png Binary files differindex f59d493587..f59d493587 100644 --- a/tools/editor/icons/icon_editor_rect_2d.png +++ b/editor/icons/icon_editor_rect_2d.png diff --git a/tools/editor/icons/icon_empty_control.png b/editor/icons/icon_empty_control.png Binary files differindex b43bb14d39..b43bb14d39 100644 --- a/tools/editor/icons/icon_empty_control.png +++ b/editor/icons/icon_empty_control.png diff --git a/tools/editor/icons/icon_enum.png b/editor/icons/icon_enum.png Binary files differindex a98a33aedf..a98a33aedf 100644 --- a/tools/editor/icons/icon_enum.png +++ b/editor/icons/icon_enum.png diff --git a/tools/editor/icons/icon_environment.png b/editor/icons/icon_environment.png Binary files differindex c8c4da3e8f..c8c4da3e8f 100644 --- a/tools/editor/icons/icon_environment.png +++ b/editor/icons/icon_environment.png diff --git a/tools/editor/icons/icon_error.png b/editor/icons/icon_error.png Binary files differindex 7a9bed43aa..7a9bed43aa 100644 --- a/tools/editor/icons/icon_error.png +++ b/editor/icons/icon_error.png diff --git a/tools/editor/icons/icon_error_sign.png b/editor/icons/icon_error_sign.png Binary files differindex 1bfb1f345c..1bfb1f345c 100644 --- a/tools/editor/icons/icon_error_sign.png +++ b/editor/icons/icon_error_sign.png diff --git a/tools/editor/icons/icon_event_player.png b/editor/icons/icon_event_player.png Binary files differindex b5478ca74e..b5478ca74e 100644 --- a/tools/editor/icons/icon_event_player.png +++ b/editor/icons/icon_event_player.png diff --git a/tools/editor/icons/icon_expand.png b/editor/icons/icon_expand.png Binary files differindex 8a604f945b..8a604f945b 100644 --- a/tools/editor/icons/icon_expand.png +++ b/editor/icons/icon_expand.png diff --git a/tools/editor/icons/icon_expand_hl.png b/editor/icons/icon_expand_hl.png Binary files differindex 6f51806db2..6f51806db2 100644 --- a/tools/editor/icons/icon_expand_hl.png +++ b/editor/icons/icon_expand_hl.png diff --git a/tools/editor/icons/icon_favorites.png b/editor/icons/icon_favorites.png Binary files differindex 14e05ad9b9..14e05ad9b9 100644 --- a/tools/editor/icons/icon_favorites.png +++ b/editor/icons/icon_favorites.png diff --git a/tools/editor/icons/icon_file.png b/editor/icons/icon_file.png Binary files differindex 69c6c90dc7..69c6c90dc7 100644 --- a/tools/editor/icons/icon_file.png +++ b/editor/icons/icon_file.png diff --git a/tools/editor/icons/icon_file_big.png b/editor/icons/icon_file_big.png Binary files differindex d429736b57..d429736b57 100644 --- a/tools/editor/icons/icon_file_big.png +++ b/editor/icons/icon_file_big.png diff --git a/tools/editor/icons/icon_file_dialog.png b/editor/icons/icon_file_dialog.png Binary files differindex 162827b2b0..162827b2b0 100644 --- a/tools/editor/icons/icon_file_dialog.png +++ b/editor/icons/icon_file_dialog.png diff --git a/tools/editor/icons/icon_file_list.png b/editor/icons/icon_file_list.png Binary files differindex a98a33aedf..a98a33aedf 100644 --- a/tools/editor/icons/icon_file_list.png +++ b/editor/icons/icon_file_list.png diff --git a/tools/editor/icons/icon_file_server.png b/editor/icons/icon_file_server.png Binary files differindex f5a18fc52d..f5a18fc52d 100644 --- a/tools/editor/icons/icon_file_server.png +++ b/editor/icons/icon_file_server.png diff --git a/tools/editor/icons/icon_file_server_active.png b/editor/icons/icon_file_server_active.png Binary files differindex af5fc0033a..af5fc0033a 100644 --- a/tools/editor/icons/icon_file_server_active.png +++ b/editor/icons/icon_file_server_active.png diff --git a/tools/editor/icons/icon_file_thumbnail.png b/editor/icons/icon_file_thumbnail.png Binary files differindex 6fb4b8f36f..6fb4b8f36f 100644 --- a/tools/editor/icons/icon_file_thumbnail.png +++ b/editor/icons/icon_file_thumbnail.png diff --git a/tools/editor/icons/icon_filesystem.png b/editor/icons/icon_filesystem.png Binary files differindex 5faff250d7..5faff250d7 100644 --- a/tools/editor/icons/icon_filesystem.png +++ b/editor/icons/icon_filesystem.png diff --git a/tools/editor/icons/icon_fixed_material.png b/editor/icons/icon_fixed_material.png Binary files differindex a9b0ebb568..a9b0ebb568 100644 --- a/tools/editor/icons/icon_fixed_material.png +++ b/editor/icons/icon_fixed_material.png diff --git a/tools/editor/icons/icon_fixed_spatial_material.png b/editor/icons/icon_fixed_spatial_material.png Binary files differindex f26ac3be37..f26ac3be37 100644 --- a/tools/editor/icons/icon_fixed_spatial_material.png +++ b/editor/icons/icon_fixed_spatial_material.png diff --git a/tools/editor/icons/icon_fog_f_x.png b/editor/icons/icon_fog_f_x.png Binary files differindex 54691aa9ab..54691aa9ab 100644 --- a/tools/editor/icons/icon_fog_f_x.png +++ b/editor/icons/icon_fog_f_x.png diff --git a/tools/editor/icons/icon_folder.png b/editor/icons/icon_folder.png Binary files differindex cc05e98ebb..cc05e98ebb 100644 --- a/tools/editor/icons/icon_folder.png +++ b/editor/icons/icon_folder.png diff --git a/tools/editor/icons/icon_folder_big.png b/editor/icons/icon_folder_big.png Binary files differindex 05c41720d8..05c41720d8 100644 --- a/tools/editor/icons/icon_folder_big.png +++ b/editor/icons/icon_folder_big.png diff --git a/tools/editor/icons/icon_folder_scene.png b/editor/icons/icon_folder_scene.png Binary files differindex 6f6d706dae..6f6d706dae 100644 --- a/tools/editor/icons/icon_folder_scene.png +++ b/editor/icons/icon_folder_scene.png diff --git a/tools/editor/icons/icon_font.png b/editor/icons/icon_font.png Binary files differindex 543ee01ae4..543ee01ae4 100644 --- a/tools/editor/icons/icon_font.png +++ b/editor/icons/icon_font.png diff --git a/tools/editor/icons/icon_forward.png b/editor/icons/icon_forward.png Binary files differindex 412ffa89d3..412ffa89d3 100644 --- a/tools/editor/icons/icon_forward.png +++ b/editor/icons/icon_forward.png diff --git a/tools/editor/icons/icon_forward_no.png b/editor/icons/icon_forward_no.png Binary files differindex bf62cd6ab2..bf62cd6ab2 100644 --- a/tools/editor/icons/icon_forward_no.png +++ b/editor/icons/icon_forward_no.png diff --git a/tools/editor/icons/icon_func.png b/editor/icons/icon_func.png Binary files differindex 45b32def8a..45b32def8a 100644 --- a/tools/editor/icons/icon_func.png +++ b/editor/icons/icon_func.png diff --git a/tools/editor/icons/icon_g_d_script.png b/editor/icons/icon_g_d_script.png Binary files differindex 4db4c53796..4db4c53796 100644 --- a/tools/editor/icons/icon_g_d_script.png +++ b/editor/icons/icon_g_d_script.png diff --git a/tools/editor/icons/icon_g_i_probe.png b/editor/icons/icon_g_i_probe.png Binary files differindex a15ae18675..a15ae18675 100644 --- a/tools/editor/icons/icon_g_i_probe.png +++ b/editor/icons/icon_g_i_probe.png diff --git a/tools/editor/icons/icon_g_i_probe_data.png b/editor/icons/icon_g_i_probe_data.png Binary files differindex 0aabcc49cb..0aabcc49cb 100644 --- a/tools/editor/icons/icon_g_i_probe_data.png +++ b/editor/icons/icon_g_i_probe_data.png diff --git a/tools/editor/icons/icon_gamma_f_x.png b/editor/icons/icon_gamma_f_x.png Binary files differindex 50474340d1..50474340d1 100644 --- a/tools/editor/icons/icon_gamma_f_x.png +++ b/editor/icons/icon_gamma_f_x.png diff --git a/tools/editor/icons/icon_generic_6_d_o_f_joint.png b/editor/icons/icon_generic_6_d_o_f_joint.png Binary files differindex 00ba76c098..00ba76c098 100644 --- a/tools/editor/icons/icon_generic_6_d_o_f_joint.png +++ b/editor/icons/icon_generic_6_d_o_f_joint.png diff --git a/tools/editor/icons/icon_gizmo_directional_light.png b/editor/icons/icon_gizmo_directional_light.png Binary files differindex bdeb120b43..bdeb120b43 100644 --- a/tools/editor/icons/icon_gizmo_directional_light.png +++ b/editor/icons/icon_gizmo_directional_light.png diff --git a/tools/editor/icons/icon_gizmo_light.png b/editor/icons/icon_gizmo_light.png Binary files differindex be9903f8c2..be9903f8c2 100644 --- a/tools/editor/icons/icon_gizmo_light.png +++ b/editor/icons/icon_gizmo_light.png diff --git a/tools/editor/icons/icon_gizmo_listener.png b/editor/icons/icon_gizmo_listener.png Binary files differindex 47e978be61..47e978be61 100644 --- a/tools/editor/icons/icon_gizmo_listener.png +++ b/editor/icons/icon_gizmo_listener.png diff --git a/tools/editor/icons/icon_gizmo_spatial_sample_player.png b/editor/icons/icon_gizmo_spatial_sample_player.png Binary files differindex 0119dbc433..0119dbc433 100644 --- a/tools/editor/icons/icon_gizmo_spatial_sample_player.png +++ b/editor/icons/icon_gizmo_spatial_sample_player.png diff --git a/tools/editor/icons/icon_gizmo_spatial_stream_player.png b/editor/icons/icon_gizmo_spatial_stream_player.png Binary files differindex 6a4f85d550..6a4f85d550 100644 --- a/tools/editor/icons/icon_gizmo_spatial_stream_player.png +++ b/editor/icons/icon_gizmo_spatial_stream_player.png diff --git a/tools/editor/icons/icon_glow_f_x.png b/editor/icons/icon_glow_f_x.png Binary files differindex c970204359..c970204359 100644 --- a/tools/editor/icons/icon_glow_f_x.png +++ b/editor/icons/icon_glow_f_x.png diff --git a/tools/editor/icons/icon_godot.png b/editor/icons/icon_godot.png Binary files differindex 0b72e6ecc7..0b72e6ecc7 100644 --- a/tools/editor/icons/icon_godot.png +++ b/editor/icons/icon_godot.png diff --git a/tools/editor/icons/icon_godot_asset_default.png b/editor/icons/icon_godot_asset_default.png Binary files differindex 7478399e8b..7478399e8b 100644 --- a/tools/editor/icons/icon_godot_asset_default.png +++ b/editor/icons/icon_godot_asset_default.png diff --git a/tools/editor/icons/icon_graph_color_ramp.png b/editor/icons/icon_graph_color_ramp.png Binary files differindex 03d19a56bb..03d19a56bb 100644 --- a/tools/editor/icons/icon_graph_color_ramp.png +++ b/editor/icons/icon_graph_color_ramp.png diff --git a/tools/editor/icons/icon_graph_comment.png b/editor/icons/icon_graph_comment.png Binary files differindex 1686837d1d..1686837d1d 100644 --- a/tools/editor/icons/icon_graph_comment.png +++ b/editor/icons/icon_graph_comment.png diff --git a/tools/editor/icons/icon_graph_cube_uniform.png b/editor/icons/icon_graph_cube_uniform.png Binary files differindex 8b4ad57c31..8b4ad57c31 100644 --- a/tools/editor/icons/icon_graph_cube_uniform.png +++ b/editor/icons/icon_graph_cube_uniform.png diff --git a/tools/editor/icons/icon_graph_curve_map.png b/editor/icons/icon_graph_curve_map.png Binary files differindex ced27bd62f..ced27bd62f 100644 --- a/tools/editor/icons/icon_graph_curve_map.png +++ b/editor/icons/icon_graph_curve_map.png diff --git a/tools/editor/icons/icon_graph_default_texture.png b/editor/icons/icon_graph_default_texture.png Binary files differindex cad05e8332..cad05e8332 100644 --- a/tools/editor/icons/icon_graph_default_texture.png +++ b/editor/icons/icon_graph_default_texture.png diff --git a/tools/editor/icons/icon_graph_edit.png b/editor/icons/icon_graph_edit.png Binary files differindex f6226b2193..f6226b2193 100644 --- a/tools/editor/icons/icon_graph_edit.png +++ b/editor/icons/icon_graph_edit.png diff --git a/tools/editor/icons/icon_graph_input.png b/editor/icons/icon_graph_input.png Binary files differindex 4725bcf7b1..4725bcf7b1 100644 --- a/tools/editor/icons/icon_graph_input.png +++ b/editor/icons/icon_graph_input.png diff --git a/tools/editor/icons/icon_graph_node.png b/editor/icons/icon_graph_node.png Binary files differindex fec38cb3eb..fec38cb3eb 100644 --- a/tools/editor/icons/icon_graph_node.png +++ b/editor/icons/icon_graph_node.png diff --git a/tools/editor/icons/icon_graph_rgb.png b/editor/icons/icon_graph_rgb.png Binary files differindex 3113a18e8c..3113a18e8c 100644 --- a/tools/editor/icons/icon_graph_rgb.png +++ b/editor/icons/icon_graph_rgb.png diff --git a/tools/editor/icons/icon_graph_rgb_op.png b/editor/icons/icon_graph_rgb_op.png Binary files differindex 09d633e722..09d633e722 100644 --- a/tools/editor/icons/icon_graph_rgb_op.png +++ b/editor/icons/icon_graph_rgb_op.png diff --git a/tools/editor/icons/icon_graph_rgb_uniform.png b/editor/icons/icon_graph_rgb_uniform.png Binary files differindex dbe10c9c8e..dbe10c9c8e 100644 --- a/tools/editor/icons/icon_graph_rgb_uniform.png +++ b/editor/icons/icon_graph_rgb_uniform.png diff --git a/tools/editor/icons/icon_graph_scalar.png b/editor/icons/icon_graph_scalar.png Binary files differindex d44fd34891..d44fd34891 100644 --- a/tools/editor/icons/icon_graph_scalar.png +++ b/editor/icons/icon_graph_scalar.png diff --git a/tools/editor/icons/icon_graph_scalar_interp.png b/editor/icons/icon_graph_scalar_interp.png Binary files differindex adcfc7d857..adcfc7d857 100644 --- a/tools/editor/icons/icon_graph_scalar_interp.png +++ b/editor/icons/icon_graph_scalar_interp.png diff --git a/tools/editor/icons/icon_graph_scalar_op.png b/editor/icons/icon_graph_scalar_op.png Binary files differindex 6459cb9759..6459cb9759 100644 --- a/tools/editor/icons/icon_graph_scalar_op.png +++ b/editor/icons/icon_graph_scalar_op.png diff --git a/tools/editor/icons/icon_graph_scalar_uniform.png b/editor/icons/icon_graph_scalar_uniform.png Binary files differindex e7e0b9a73c..e7e0b9a73c 100644 --- a/tools/editor/icons/icon_graph_scalar_uniform.png +++ b/editor/icons/icon_graph_scalar_uniform.png diff --git a/tools/editor/icons/icon_graph_scalars_to_vec.png b/editor/icons/icon_graph_scalars_to_vec.png Binary files differindex 231a25a02a..231a25a02a 100644 --- a/tools/editor/icons/icon_graph_scalars_to_vec.png +++ b/editor/icons/icon_graph_scalars_to_vec.png diff --git a/tools/editor/icons/icon_graph_texscreen.png b/editor/icons/icon_graph_texscreen.png Binary files differindex 628990553a..628990553a 100644 --- a/tools/editor/icons/icon_graph_texscreen.png +++ b/editor/icons/icon_graph_texscreen.png diff --git a/tools/editor/icons/icon_graph_texture_uniform.png b/editor/icons/icon_graph_texture_uniform.png Binary files differindex 9c0c758dc1..9c0c758dc1 100644 --- a/tools/editor/icons/icon_graph_texture_uniform.png +++ b/editor/icons/icon_graph_texture_uniform.png diff --git a/tools/editor/icons/icon_graph_time.png b/editor/icons/icon_graph_time.png Binary files differindex 2a9b73dc2b..2a9b73dc2b 100644 --- a/tools/editor/icons/icon_graph_time.png +++ b/editor/icons/icon_graph_time.png diff --git a/tools/editor/icons/icon_graph_vec_dp.png b/editor/icons/icon_graph_vec_dp.png Binary files differindex c395b61bb6..c395b61bb6 100644 --- a/tools/editor/icons/icon_graph_vec_dp.png +++ b/editor/icons/icon_graph_vec_dp.png diff --git a/tools/editor/icons/icon_graph_vec_interp.png b/editor/icons/icon_graph_vec_interp.png Binary files differindex 00cfe6ed29..00cfe6ed29 100644 --- a/tools/editor/icons/icon_graph_vec_interp.png +++ b/editor/icons/icon_graph_vec_interp.png diff --git a/tools/editor/icons/icon_graph_vec_length.png b/editor/icons/icon_graph_vec_length.png Binary files differindex af449109fd..af449109fd 100644 --- a/tools/editor/icons/icon_graph_vec_length.png +++ b/editor/icons/icon_graph_vec_length.png diff --git a/tools/editor/icons/icon_graph_vec_op.png b/editor/icons/icon_graph_vec_op.png Binary files differindex c4e3cf409a..c4e3cf409a 100644 --- a/tools/editor/icons/icon_graph_vec_op.png +++ b/editor/icons/icon_graph_vec_op.png diff --git a/tools/editor/icons/icon_graph_vec_scalar_op.png b/editor/icons/icon_graph_vec_scalar_op.png Binary files differindex f7fc3b054e..f7fc3b054e 100644 --- a/tools/editor/icons/icon_graph_vec_scalar_op.png +++ b/editor/icons/icon_graph_vec_scalar_op.png diff --git a/tools/editor/icons/icon_graph_vec_to_scalars.png b/editor/icons/icon_graph_vec_to_scalars.png Binary files differindex 33f9fdf9bd..33f9fdf9bd 100644 --- a/tools/editor/icons/icon_graph_vec_to_scalars.png +++ b/editor/icons/icon_graph_vec_to_scalars.png diff --git a/tools/editor/icons/icon_graph_vecs_to_xform.png b/editor/icons/icon_graph_vecs_to_xform.png Binary files differindex 82c32525dc..82c32525dc 100644 --- a/tools/editor/icons/icon_graph_vecs_to_xform.png +++ b/editor/icons/icon_graph_vecs_to_xform.png diff --git a/tools/editor/icons/icon_graph_vector.png b/editor/icons/icon_graph_vector.png Binary files differindex d78a3fdf5c..d78a3fdf5c 100644 --- a/tools/editor/icons/icon_graph_vector.png +++ b/editor/icons/icon_graph_vector.png diff --git a/tools/editor/icons/icon_graph_vector_uniform.png b/editor/icons/icon_graph_vector_uniform.png Binary files differindex a89166768b..a89166768b 100644 --- a/tools/editor/icons/icon_graph_vector_uniform.png +++ b/editor/icons/icon_graph_vector_uniform.png diff --git a/tools/editor/icons/icon_graph_xform.png b/editor/icons/icon_graph_xform.png Binary files differindex 142ec3eca5..142ec3eca5 100644 --- a/tools/editor/icons/icon_graph_xform.png +++ b/editor/icons/icon_graph_xform.png diff --git a/tools/editor/icons/icon_graph_xform_mult.png b/editor/icons/icon_graph_xform_mult.png Binary files differindex 94981d81af..94981d81af 100644 --- a/tools/editor/icons/icon_graph_xform_mult.png +++ b/editor/icons/icon_graph_xform_mult.png diff --git a/tools/editor/icons/icon_graph_xform_scalar_func.png b/editor/icons/icon_graph_xform_scalar_func.png Binary files differindex d0edded8b0..d0edded8b0 100644 --- a/tools/editor/icons/icon_graph_xform_scalar_func.png +++ b/editor/icons/icon_graph_xform_scalar_func.png diff --git a/tools/editor/icons/icon_graph_xform_to_vecs.png b/editor/icons/icon_graph_xform_to_vecs.png Binary files differindex 3d59c7957d..3d59c7957d 100644 --- a/tools/editor/icons/icon_graph_xform_to_vecs.png +++ b/editor/icons/icon_graph_xform_to_vecs.png diff --git a/tools/editor/icons/icon_graph_xform_uniform.png b/editor/icons/icon_graph_xform_uniform.png Binary files differindex 36ed91e427..36ed91e427 100644 --- a/tools/editor/icons/icon_graph_xform_uniform.png +++ b/editor/icons/icon_graph_xform_uniform.png diff --git a/tools/editor/icons/icon_graph_xform_vec_func.png b/editor/icons/icon_graph_xform_vec_func.png Binary files differindex 3866430f72..3866430f72 100644 --- a/tools/editor/icons/icon_graph_xform_vec_func.png +++ b/editor/icons/icon_graph_xform_vec_func.png diff --git a/tools/editor/icons/icon_graph_xform_vec_imult.png b/editor/icons/icon_graph_xform_vec_imult.png Binary files differindex 07a7e214c2..07a7e214c2 100644 --- a/tools/editor/icons/icon_graph_xform_vec_imult.png +++ b/editor/icons/icon_graph_xform_vec_imult.png diff --git a/tools/editor/icons/icon_graph_xform_vec_mult.png b/editor/icons/icon_graph_xform_vec_mult.png Binary files differindex 8048e755c5..8048e755c5 100644 --- a/tools/editor/icons/icon_graph_xform_vec_mult.png +++ b/editor/icons/icon_graph_xform_vec_mult.png diff --git a/tools/editor/icons/icon_grid.png b/editor/icons/icon_grid.png Binary files differindex 1366205fe0..1366205fe0 100644 --- a/tools/editor/icons/icon_grid.png +++ b/editor/icons/icon_grid.png diff --git a/tools/editor/icons/icon_grid_container.png b/editor/icons/icon_grid_container.png Binary files differindex 027e992770..027e992770 100644 --- a/tools/editor/icons/icon_grid_container.png +++ b/editor/icons/icon_grid_container.png diff --git a/tools/editor/icons/icon_grid_map.png b/editor/icons/icon_grid_map.png Binary files differindex 570b11d085..570b11d085 100644 --- a/tools/editor/icons/icon_grid_map.png +++ b/editor/icons/icon_grid_map.png diff --git a/tools/editor/icons/icon_grid_map_floor.png b/editor/icons/icon_grid_map_floor.png Binary files differindex a75871188b..a75871188b 100644 --- a/tools/editor/icons/icon_grid_map_floor.png +++ b/editor/icons/icon_grid_map_floor.png diff --git a/tools/editor/icons/icon_groove_joint_2d.png b/editor/icons/icon_groove_joint_2d.png Binary files differindex f65dc2b6b8..f65dc2b6b8 100644 --- a/tools/editor/icons/icon_groove_joint_2d.png +++ b/editor/icons/icon_groove_joint_2d.png diff --git a/tools/editor/icons/icon_group.png b/editor/icons/icon_group.png Binary files differindex 5ffc90455e..5ffc90455e 100644 --- a/tools/editor/icons/icon_group.png +++ b/editor/icons/icon_group.png diff --git a/tools/editor/icons/icon_groups.png b/editor/icons/icon_groups.png Binary files differindex 84a05560a9..84a05560a9 100644 --- a/tools/editor/icons/icon_groups.png +++ b/editor/icons/icon_groups.png diff --git a/tools/editor/icons/icon_h_box_container.png b/editor/icons/icon_h_box_container.png Binary files differindex 36cef0a03c..36cef0a03c 100644 --- a/tools/editor/icons/icon_h_box_container.png +++ b/editor/icons/icon_h_box_container.png diff --git a/tools/editor/icons/icon_h_button_array.png b/editor/icons/icon_h_button_array.png Binary files differindex baf3386801..baf3386801 100644 --- a/tools/editor/icons/icon_h_button_array.png +++ b/editor/icons/icon_h_button_array.png diff --git a/tools/editor/icons/icon_h_scroll_bar.png b/editor/icons/icon_h_scroll_bar.png Binary files differindex e4576c4ae3..e4576c4ae3 100644 --- a/tools/editor/icons/icon_h_scroll_bar.png +++ b/editor/icons/icon_h_scroll_bar.png diff --git a/tools/editor/icons/icon_h_separator.png b/editor/icons/icon_h_separator.png Binary files differindex 8ab1348c3b..8ab1348c3b 100644 --- a/tools/editor/icons/icon_h_separator.png +++ b/editor/icons/icon_h_separator.png diff --git a/tools/editor/icons/icon_h_slider.png b/editor/icons/icon_h_slider.png Binary files differindex 87cf585e14..87cf585e14 100644 --- a/tools/editor/icons/icon_h_slider.png +++ b/editor/icons/icon_h_slider.png diff --git a/tools/editor/icons/icon_h_split_container.png b/editor/icons/icon_h_split_container.png Binary files differindex 65ef8655dd..65ef8655dd 100644 --- a/tools/editor/icons/icon_h_split_container.png +++ b/editor/icons/icon_h_split_container.png diff --git a/tools/editor/icons/icon_h_t_t_p_request.png b/editor/icons/icon_h_t_t_p_request.png Binary files differindex 60c6845b33..60c6845b33 100644 --- a/tools/editor/icons/icon_h_t_t_p_request.png +++ b/editor/icons/icon_h_t_t_p_request.png diff --git a/tools/editor/icons/icon_headphones.png b/editor/icons/icon_headphones.png Binary files differindex 83309d91d5..83309d91d5 100644 --- a/tools/editor/icons/icon_headphones.png +++ b/editor/icons/icon_headphones.png diff --git a/tools/editor/icons/icon_help.png b/editor/icons/icon_help.png Binary files differindex f05b512f4c..f05b512f4c 100644 --- a/tools/editor/icons/icon_help.png +++ b/editor/icons/icon_help.png diff --git a/tools/editor/icons/icon_hidden.png b/editor/icons/icon_hidden.png Binary files differindex ef3039f580..ef3039f580 100644 --- a/tools/editor/icons/icon_hidden.png +++ b/editor/icons/icon_hidden.png diff --git a/tools/editor/icons/icon_hinge_joint.png b/editor/icons/icon_hinge_joint.png Binary files differindex 246ca1ba42..246ca1ba42 100644 --- a/tools/editor/icons/icon_hinge_joint.png +++ b/editor/icons/icon_hinge_joint.png diff --git a/tools/editor/icons/icon_history.png b/editor/icons/icon_history.png Binary files differindex 4782918233..4782918233 100644 --- a/tools/editor/icons/icon_history.png +++ b/editor/icons/icon_history.png diff --git a/tools/editor/icons/icon_hsize.png b/editor/icons/icon_hsize.png Binary files differindex 7be48946b4..7be48946b4 100644 --- a/tools/editor/icons/icon_hsize.png +++ b/editor/icons/icon_hsize.png diff --git a/tools/editor/icons/icon_iapi.png b/editor/icons/icon_iapi.png Binary files differindex dc2639da83..dc2639da83 100644 --- a/tools/editor/icons/icon_iapi.png +++ b/editor/icons/icon_iapi.png diff --git a/tools/editor/icons/icon_image.png b/editor/icons/icon_image.png Binary files differindex ddfabace25..ddfabace25 100644 --- a/tools/editor/icons/icon_image.png +++ b/editor/icons/icon_image.png diff --git a/tools/editor/icons/icon_image_sky_box.png b/editor/icons/icon_image_sky_box.png Binary files differindex cf80258577..cf80258577 100644 --- a/tools/editor/icons/icon_image_sky_box.png +++ b/editor/icons/icon_image_sky_box.png diff --git a/tools/editor/icons/icon_image_texture.png b/editor/icons/icon_image_texture.png Binary files differindex 7c4493395e..7c4493395e 100644 --- a/tools/editor/icons/icon_image_texture.png +++ b/editor/icons/icon_image_texture.png diff --git a/tools/editor/icons/icon_immediate_geometry.png b/editor/icons/icon_immediate_geometry.png Binary files differindex 1ff9976921..1ff9976921 100644 --- a/tools/editor/icons/icon_immediate_geometry.png +++ b/editor/icons/icon_immediate_geometry.png diff --git a/tools/editor/icons/icon_import_check.png b/editor/icons/icon_import_check.png Binary files differindex e72a30603d..e72a30603d 100644 --- a/tools/editor/icons/icon_import_check.png +++ b/editor/icons/icon_import_check.png diff --git a/tools/editor/icons/icon_import_fail.png b/editor/icons/icon_import_fail.png Binary files differindex f7dd6fd79a..f7dd6fd79a 100644 --- a/tools/editor/icons/icon_import_fail.png +++ b/editor/icons/icon_import_fail.png diff --git a/tools/editor/icons/icon_influence_zone.png b/editor/icons/icon_influence_zone.png Binary files differindex 6d687735e9..6d687735e9 100644 --- a/tools/editor/icons/icon_influence_zone.png +++ b/editor/icons/icon_influence_zone.png diff --git a/tools/editor/icons/icon_instance.png b/editor/icons/icon_instance.png Binary files differindex 51859a0425..51859a0425 100644 --- a/tools/editor/icons/icon_instance.png +++ b/editor/icons/icon_instance.png diff --git a/tools/editor/icons/icon_instance_options.png b/editor/icons/icon_instance_options.png Binary files differindex ce6810ad27..ce6810ad27 100644 --- a/tools/editor/icons/icon_instance_options.png +++ b/editor/icons/icon_instance_options.png diff --git a/tools/editor/icons/icon_integer.png b/editor/icons/icon_integer.png Binary files differindex 583b9bda0b..583b9bda0b 100644 --- a/tools/editor/icons/icon_integer.png +++ b/editor/icons/icon_integer.png diff --git a/tools/editor/icons/icon_interp_cubic.png b/editor/icons/icon_interp_cubic.png Binary files differindex c723f7b648..c723f7b648 100644 --- a/tools/editor/icons/icon_interp_cubic.png +++ b/editor/icons/icon_interp_cubic.png diff --git a/tools/editor/icons/icon_interp_linear.png b/editor/icons/icon_interp_linear.png Binary files differindex 9d130b4507..9d130b4507 100644 --- a/tools/editor/icons/icon_interp_linear.png +++ b/editor/icons/icon_interp_linear.png diff --git a/tools/editor/icons/icon_interp_raw.png b/editor/icons/icon_interp_raw.png Binary files differindex 93ade1d674..93ade1d674 100644 --- a/tools/editor/icons/icon_interp_raw.png +++ b/editor/icons/icon_interp_raw.png diff --git a/tools/editor/icons/icon_interp_wrap_clamp.png b/editor/icons/icon_interp_wrap_clamp.png Binary files differindex 1024bd7d29..1024bd7d29 100644 --- a/tools/editor/icons/icon_interp_wrap_clamp.png +++ b/editor/icons/icon_interp_wrap_clamp.png diff --git a/tools/editor/icons/icon_interp_wrap_loop.png b/editor/icons/icon_interp_wrap_loop.png Binary files differindex 3a7ddacdb2..3a7ddacdb2 100644 --- a/tools/editor/icons/icon_interp_wrap_loop.png +++ b/editor/icons/icon_interp_wrap_loop.png diff --git a/tools/editor/icons/icon_interpolated_camera.png b/editor/icons/icon_interpolated_camera.png Binary files differindex c66724f513..c66724f513 100644 --- a/tools/editor/icons/icon_interpolated_camera.png +++ b/editor/icons/icon_interpolated_camera.png diff --git a/tools/editor/icons/icon_invalid_key.png b/editor/icons/icon_invalid_key.png Binary files differindex 8ebc6d6add..8ebc6d6add 100644 --- a/tools/editor/icons/icon_invalid_key.png +++ b/editor/icons/icon_invalid_key.png diff --git a/tools/editor/icons/icon_inverse_kinematics.png b/editor/icons/icon_inverse_kinematics.png Binary files differindex dd404765d3..dd404765d3 100644 --- a/tools/editor/icons/icon_inverse_kinematics.png +++ b/editor/icons/icon_inverse_kinematics.png diff --git a/tools/editor/icons/icon_item_list.png b/editor/icons/icon_item_list.png Binary files differindex 3f5245d520..3f5245d520 100644 --- a/tools/editor/icons/icon_item_list.png +++ b/editor/icons/icon_item_list.png diff --git a/tools/editor/icons/icon_joy_axis.png b/editor/icons/icon_joy_axis.png Binary files differindex 8b1affd052..8b1affd052 100644 --- a/tools/editor/icons/icon_joy_axis.png +++ b/editor/icons/icon_joy_axis.png diff --git a/tools/editor/icons/icon_joy_button.png b/editor/icons/icon_joy_button.png Binary files differindex 150102b209..150102b209 100644 --- a/tools/editor/icons/icon_joy_button.png +++ b/editor/icons/icon_joy_button.png diff --git a/tools/editor/icons/icon_joypad.png b/editor/icons/icon_joypad.png Binary files differindex 5df471109a..5df471109a 100644 --- a/tools/editor/icons/icon_joypad.png +++ b/editor/icons/icon_joypad.png diff --git a/tools/editor/icons/icon_key.png b/editor/icons/icon_key.png Binary files differindex 564b474331..564b474331 100644 --- a/tools/editor/icons/icon_key.png +++ b/editor/icons/icon_key.png diff --git a/tools/editor/icons/icon_key_call.png b/editor/icons/icon_key_call.png Binary files differindex 044662eb92..044662eb92 100644 --- a/tools/editor/icons/icon_key_call.png +++ b/editor/icons/icon_key_call.png diff --git a/tools/editor/icons/icon_key_hover.png b/editor/icons/icon_key_hover.png Binary files differindex 7ab405bb07..7ab405bb07 100644 --- a/tools/editor/icons/icon_key_hover.png +++ b/editor/icons/icon_key_hover.png diff --git a/tools/editor/icons/icon_key_invalid.png b/editor/icons/icon_key_invalid.png Binary files differindex 8ebc6d6add..8ebc6d6add 100644 --- a/tools/editor/icons/icon_key_invalid.png +++ b/editor/icons/icon_key_invalid.png diff --git a/tools/editor/icons/icon_key_invalid_hover.png b/editor/icons/icon_key_invalid_hover.png Binary files differindex 6f0396d96a..6f0396d96a 100644 --- a/tools/editor/icons/icon_key_invalid_hover.png +++ b/editor/icons/icon_key_invalid_hover.png diff --git a/tools/editor/icons/icon_key_next.png b/editor/icons/icon_key_next.png Binary files differindex 288161d245..288161d245 100644 --- a/tools/editor/icons/icon_key_next.png +++ b/editor/icons/icon_key_next.png diff --git a/tools/editor/icons/icon_key_selected.png b/editor/icons/icon_key_selected.png Binary files differindex 1838dc95aa..1838dc95aa 100644 --- a/tools/editor/icons/icon_key_selected.png +++ b/editor/icons/icon_key_selected.png diff --git a/tools/editor/icons/icon_key_value.png b/editor/icons/icon_key_value.png Binary files differindex 5c0b25a264..5c0b25a264 100644 --- a/tools/editor/icons/icon_key_value.png +++ b/editor/icons/icon_key_value.png diff --git a/tools/editor/icons/icon_key_xform.png b/editor/icons/icon_key_xform.png Binary files differindex 1171bd80db..1171bd80db 100644 --- a/tools/editor/icons/icon_key_xform.png +++ b/editor/icons/icon_key_xform.png diff --git a/tools/editor/icons/icon_keyboard.png b/editor/icons/icon_keyboard.png Binary files differindex a275345577..a275345577 100644 --- a/tools/editor/icons/icon_keyboard.png +++ b/editor/icons/icon_keyboard.png diff --git a/tools/editor/icons/icon_keying.png b/editor/icons/icon_keying.png Binary files differindex de790a4f09..de790a4f09 100644 --- a/tools/editor/icons/icon_keying.png +++ b/editor/icons/icon_keying.png diff --git a/tools/editor/icons/icon_kinematic_body.png b/editor/icons/icon_kinematic_body.png Binary files differindex 19a401dbf8..19a401dbf8 100644 --- a/tools/editor/icons/icon_kinematic_body.png +++ b/editor/icons/icon_kinematic_body.png diff --git a/tools/editor/icons/icon_kinematic_body_2d.png b/editor/icons/icon_kinematic_body_2d.png Binary files differindex 2f9d834805..2f9d834805 100644 --- a/tools/editor/icons/icon_kinematic_body_2d.png +++ b/editor/icons/icon_kinematic_body_2d.png diff --git a/tools/editor/icons/icon_label.png b/editor/icons/icon_label.png Binary files differindex 16919a5fef..16919a5fef 100644 --- a/tools/editor/icons/icon_label.png +++ b/editor/icons/icon_label.png diff --git a/tools/editor/icons/icon_large_texture.png b/editor/icons/icon_large_texture.png Binary files differindex 1727e2409f..1727e2409f 100644 --- a/tools/editor/icons/icon_large_texture.png +++ b/editor/icons/icon_large_texture.png diff --git a/tools/editor/icons/icon_light_2d.png b/editor/icons/icon_light_2d.png Binary files differindex ebab16c1b1..ebab16c1b1 100644 --- a/tools/editor/icons/icon_light_2d.png +++ b/editor/icons/icon_light_2d.png diff --git a/tools/editor/icons/icon_light_map.png b/editor/icons/icon_light_map.png Binary files differindex e0333f06ea..e0333f06ea 100644 --- a/tools/editor/icons/icon_light_map.png +++ b/editor/icons/icon_light_map.png diff --git a/tools/editor/icons/icon_light_occluder_2d.png b/editor/icons/icon_light_occluder_2d.png Binary files differindex ceefbcbe2a..ceefbcbe2a 100644 --- a/tools/editor/icons/icon_light_occluder_2d.png +++ b/editor/icons/icon_light_occluder_2d.png diff --git a/tools/editor/icons/icon_lightr.png b/editor/icons/icon_lightr.png Binary files differindex 6de8c8de3f..6de8c8de3f 100644 --- a/tools/editor/icons/icon_lightr.png +++ b/editor/icons/icon_lightr.png diff --git a/tools/editor/icons/icon_line_2d.png b/editor/icons/icon_line_2d.png Binary files differindex 4ebf46af04..4ebf46af04 100644 --- a/tools/editor/icons/icon_line_2d.png +++ b/editor/icons/icon_line_2d.png diff --git a/tools/editor/icons/icon_line_edit.png b/editor/icons/icon_line_edit.png Binary files differindex 81b5efcf6c..81b5efcf6c 100644 --- a/tools/editor/icons/icon_line_edit.png +++ b/editor/icons/icon_line_edit.png diff --git a/tools/editor/icons/icon_line_shape_2d.png b/editor/icons/icon_line_shape_2d.png Binary files differindex e31722d69c..e31722d69c 100644 --- a/tools/editor/icons/icon_line_shape_2d.png +++ b/editor/icons/icon_line_shape_2d.png diff --git a/tools/editor/icons/icon_link_button.png b/editor/icons/icon_link_button.png Binary files differindex 7febe3c19a..7febe3c19a 100644 --- a/tools/editor/icons/icon_link_button.png +++ b/editor/icons/icon_link_button.png diff --git a/tools/editor/icons/icon_list_select.png b/editor/icons/icon_list_select.png Binary files differindex 9596d51e72..9596d51e72 100644 --- a/tools/editor/icons/icon_list_select.png +++ b/editor/icons/icon_list_select.png diff --git a/tools/editor/icons/icon_listener.png b/editor/icons/icon_listener.png Binary files differindex 3ce479e2fa..3ce479e2fa 100644 --- a/tools/editor/icons/icon_listener.png +++ b/editor/icons/icon_listener.png diff --git a/tools/editor/icons/icon_live_debug.png b/editor/icons/icon_live_debug.png Binary files differindex ad55646b9a..ad55646b9a 100644 --- a/tools/editor/icons/icon_live_debug.png +++ b/editor/icons/icon_live_debug.png diff --git a/tools/editor/icons/icon_load.png b/editor/icons/icon_load.png Binary files differindex 81835efa25..81835efa25 100644 --- a/tools/editor/icons/icon_load.png +++ b/editor/icons/icon_load.png diff --git a/tools/editor/icons/icon_lock.png b/editor/icons/icon_lock.png Binary files differindex a7059f5e7c..a7059f5e7c 100644 --- a/tools/editor/icons/icon_lock.png +++ b/editor/icons/icon_lock.png diff --git a/tools/editor/icons/icon_logo.png b/editor/icons/icon_logo.png Binary files differindex 9bbd7dc619..9bbd7dc619 100644 --- a/tools/editor/icons/icon_logo.png +++ b/editor/icons/icon_logo.png diff --git a/tools/editor/icons/icon_logo_small.png b/editor/icons/icon_logo_small.png Binary files differindex 9c7c7fe365..9c7c7fe365 100644 --- a/tools/editor/icons/icon_logo_small.png +++ b/editor/icons/icon_logo_small.png diff --git a/tools/editor/icons/icon_loop.png b/editor/icons/icon_loop.png Binary files differindex 91c3ad600e..91c3ad600e 100644 --- a/tools/editor/icons/icon_loop.png +++ b/editor/icons/icon_loop.png diff --git a/tools/editor/icons/icon_loop_interpolation.png b/editor/icons/icon_loop_interpolation.png Binary files differindex 488b33316e..488b33316e 100644 --- a/tools/editor/icons/icon_loop_interpolation.png +++ b/editor/icons/icon_loop_interpolation.png diff --git a/tools/editor/icons/icon_main_play.png b/editor/icons/icon_main_play.png Binary files differindex a72672f963..a72672f963 100644 --- a/tools/editor/icons/icon_main_play.png +++ b/editor/icons/icon_main_play.png diff --git a/tools/editor/icons/icon_main_stop.png b/editor/icons/icon_main_stop.png Binary files differindex 58387519dc..58387519dc 100644 --- a/tools/editor/icons/icon_main_stop.png +++ b/editor/icons/icon_main_stop.png diff --git a/tools/editor/icons/icon_margin_container.png b/editor/icons/icon_margin_container.png Binary files differindex 57f0cec42e..57f0cec42e 100644 --- a/tools/editor/icons/icon_margin_container.png +++ b/editor/icons/icon_margin_container.png diff --git a/tools/editor/icons/icon_material_preview_cube.png b/editor/icons/icon_material_preview_cube.png Binary files differindex f97c23b950..f97c23b950 100644 --- a/tools/editor/icons/icon_material_preview_cube.png +++ b/editor/icons/icon_material_preview_cube.png diff --git a/tools/editor/icons/icon_material_preview_cube_off.png b/editor/icons/icon_material_preview_cube_off.png Binary files differindex ad63218658..ad63218658 100644 --- a/tools/editor/icons/icon_material_preview_cube_off.png +++ b/editor/icons/icon_material_preview_cube_off.png diff --git a/tools/editor/icons/icon_material_preview_light_1.png b/editor/icons/icon_material_preview_light_1.png Binary files differindex 2a49a7530b..2a49a7530b 100644 --- a/tools/editor/icons/icon_material_preview_light_1.png +++ b/editor/icons/icon_material_preview_light_1.png diff --git a/tools/editor/icons/icon_material_preview_light_1_off.png b/editor/icons/icon_material_preview_light_1_off.png Binary files differindex 738dd75594..738dd75594 100644 --- a/tools/editor/icons/icon_material_preview_light_1_off.png +++ b/editor/icons/icon_material_preview_light_1_off.png diff --git a/tools/editor/icons/icon_material_preview_light_2.png b/editor/icons/icon_material_preview_light_2.png Binary files differindex 7e43b4425e..7e43b4425e 100644 --- a/tools/editor/icons/icon_material_preview_light_2.png +++ b/editor/icons/icon_material_preview_light_2.png diff --git a/tools/editor/icons/icon_material_preview_light_2_off.png b/editor/icons/icon_material_preview_light_2_off.png Binary files differindex e2f0e345a9..e2f0e345a9 100644 --- a/tools/editor/icons/icon_material_preview_light_2_off.png +++ b/editor/icons/icon_material_preview_light_2_off.png diff --git a/tools/editor/icons/icon_material_preview_sphere.png b/editor/icons/icon_material_preview_sphere.png Binary files differindex 80b06b39b7..80b06b39b7 100644 --- a/tools/editor/icons/icon_material_preview_sphere.png +++ b/editor/icons/icon_material_preview_sphere.png diff --git a/tools/editor/icons/icon_material_preview_sphere_off.png b/editor/icons/icon_material_preview_sphere_off.png Binary files differindex a5acfcb8c9..a5acfcb8c9 100644 --- a/tools/editor/icons/icon_material_preview_sphere_off.png +++ b/editor/icons/icon_material_preview_sphere_off.png diff --git a/tools/editor/icons/icon_material_shader.png b/editor/icons/icon_material_shader.png Binary files differindex 568a45d938..568a45d938 100644 --- a/tools/editor/icons/icon_material_shader.png +++ b/editor/icons/icon_material_shader.png diff --git a/tools/editor/icons/icon_material_shader_graph.png b/editor/icons/icon_material_shader_graph.png Binary files differindex f40e3755af..f40e3755af 100644 --- a/tools/editor/icons/icon_material_shader_graph.png +++ b/editor/icons/icon_material_shader_graph.png diff --git a/tools/editor/icons/icon_matrix.png b/editor/icons/icon_matrix.png Binary files differindex ba0772ff8a..ba0772ff8a 100644 --- a/tools/editor/icons/icon_matrix.png +++ b/editor/icons/icon_matrix.png diff --git a/tools/editor/icons/icon_menu_button.png b/editor/icons/icon_menu_button.png Binary files differindex 1fd2e41c23..1fd2e41c23 100644 --- a/tools/editor/icons/icon_menu_button.png +++ b/editor/icons/icon_menu_button.png diff --git a/tools/editor/icons/icon_mesh.png b/editor/icons/icon_mesh.png Binary files differindex 03e1501403..03e1501403 100644 --- a/tools/editor/icons/icon_mesh.png +++ b/editor/icons/icon_mesh.png diff --git a/tools/editor/icons/icon_mesh_instance.png b/editor/icons/icon_mesh_instance.png Binary files differindex c513feb1cd..c513feb1cd 100644 --- a/tools/editor/icons/icon_mesh_instance.png +++ b/editor/icons/icon_mesh_instance.png diff --git a/tools/editor/icons/icon_mesh_library.png b/editor/icons/icon_mesh_library.png Binary files differindex 0bb37b1da3..0bb37b1da3 100644 --- a/tools/editor/icons/icon_mesh_library.png +++ b/editor/icons/icon_mesh_library.png diff --git a/tools/editor/icons/icon_mesh_old.png b/editor/icons/icon_mesh_old.png Binary files differindex 18531ff844..18531ff844 100644 --- a/tools/editor/icons/icon_mesh_old.png +++ b/editor/icons/icon_mesh_old.png diff --git a/tools/editor/icons/icon_meshr.png b/editor/icons/icon_meshr.png Binary files differindex 1ed2a123e6..1ed2a123e6 100644 --- a/tools/editor/icons/icon_meshr.png +++ b/editor/icons/icon_meshr.png diff --git a/tools/editor/icons/icon_mini_aabb.png b/editor/icons/icon_mini_aabb.png Binary files differindex eebc4633e4..eebc4633e4 100644 --- a/tools/editor/icons/icon_mini_aabb.png +++ b/editor/icons/icon_mini_aabb.png diff --git a/tools/editor/icons/icon_mini_array.png b/editor/icons/icon_mini_array.png Binary files differindex ade885e4d4..ade885e4d4 100644 --- a/tools/editor/icons/icon_mini_array.png +++ b/editor/icons/icon_mini_array.png diff --git a/tools/editor/icons/icon_mini_boolean.png b/editor/icons/icon_mini_boolean.png Binary files differindex 9cb64fc983..9cb64fc983 100644 --- a/tools/editor/icons/icon_mini_boolean.png +++ b/editor/icons/icon_mini_boolean.png diff --git a/tools/editor/icons/icon_mini_color.png b/editor/icons/icon_mini_color.png Binary files differindex bebf64e262..bebf64e262 100644 --- a/tools/editor/icons/icon_mini_color.png +++ b/editor/icons/icon_mini_color.png diff --git a/tools/editor/icons/icon_mini_color_array.png b/editor/icons/icon_mini_color_array.png Binary files differindex 434b2f96f5..434b2f96f5 100644 --- a/tools/editor/icons/icon_mini_color_array.png +++ b/editor/icons/icon_mini_color_array.png diff --git a/tools/editor/icons/icon_mini_dictionary.png b/editor/icons/icon_mini_dictionary.png Binary files differindex 11fd536a83..11fd536a83 100644 --- a/tools/editor/icons/icon_mini_dictionary.png +++ b/editor/icons/icon_mini_dictionary.png diff --git a/tools/editor/icons/icon_mini_float.png b/editor/icons/icon_mini_float.png Binary files differindex f8c8d9a174..f8c8d9a174 100644 --- a/tools/editor/icons/icon_mini_float.png +++ b/editor/icons/icon_mini_float.png diff --git a/tools/editor/icons/icon_mini_float_array.png b/editor/icons/icon_mini_float_array.png Binary files differindex 8b8177e151..8b8177e151 100644 --- a/tools/editor/icons/icon_mini_float_array.png +++ b/editor/icons/icon_mini_float_array.png diff --git a/tools/editor/icons/icon_mini_image.png b/editor/icons/icon_mini_image.png Binary files differindex 2ad359bdbe..2ad359bdbe 100644 --- a/tools/editor/icons/icon_mini_image.png +++ b/editor/icons/icon_mini_image.png diff --git a/tools/editor/icons/icon_mini_input.png b/editor/icons/icon_mini_input.png Binary files differindex fec26dd68e..fec26dd68e 100644 --- a/tools/editor/icons/icon_mini_input.png +++ b/editor/icons/icon_mini_input.png diff --git a/tools/editor/icons/icon_mini_int_array.png b/editor/icons/icon_mini_int_array.png Binary files differindex d1bd2e82a7..d1bd2e82a7 100644 --- a/tools/editor/icons/icon_mini_int_array.png +++ b/editor/icons/icon_mini_int_array.png diff --git a/tools/editor/icons/icon_mini_integer.png b/editor/icons/icon_mini_integer.png Binary files differindex dad1bb160b..dad1bb160b 100644 --- a/tools/editor/icons/icon_mini_integer.png +++ b/editor/icons/icon_mini_integer.png diff --git a/tools/editor/icons/icon_mini_matrix3.png b/editor/icons/icon_mini_matrix3.png Binary files differindex dd59d093cc..dd59d093cc 100644 --- a/tools/editor/icons/icon_mini_matrix3.png +++ b/editor/icons/icon_mini_matrix3.png diff --git a/tools/editor/icons/icon_mini_matrix32.png b/editor/icons/icon_mini_matrix32.png Binary files differindex 6018a00747..6018a00747 100644 --- a/tools/editor/icons/icon_mini_matrix32.png +++ b/editor/icons/icon_mini_matrix32.png diff --git a/tools/editor/icons/icon_mini_object.png b/editor/icons/icon_mini_object.png Binary files differindex 4afe7cfca1..4afe7cfca1 100644 --- a/tools/editor/icons/icon_mini_object.png +++ b/editor/icons/icon_mini_object.png diff --git a/tools/editor/icons/icon_mini_path.png b/editor/icons/icon_mini_path.png Binary files differindex 9eb0632571..9eb0632571 100644 --- a/tools/editor/icons/icon_mini_path.png +++ b/editor/icons/icon_mini_path.png diff --git a/tools/editor/icons/icon_mini_plane.png b/editor/icons/icon_mini_plane.png Binary files differindex 45676236bd..45676236bd 100644 --- a/tools/editor/icons/icon_mini_plane.png +++ b/editor/icons/icon_mini_plane.png diff --git a/tools/editor/icons/icon_mini_quat.png b/editor/icons/icon_mini_quat.png Binary files differindex 4ed2f5695c..4ed2f5695c 100644 --- a/tools/editor/icons/icon_mini_quat.png +++ b/editor/icons/icon_mini_quat.png diff --git a/tools/editor/icons/icon_mini_raw_array.png b/editor/icons/icon_mini_raw_array.png Binary files differindex 66bcf7c740..66bcf7c740 100644 --- a/tools/editor/icons/icon_mini_raw_array.png +++ b/editor/icons/icon_mini_raw_array.png diff --git a/tools/editor/icons/icon_mini_rect2.png b/editor/icons/icon_mini_rect2.png Binary files differindex db13e1a48e..db13e1a48e 100644 --- a/tools/editor/icons/icon_mini_rect2.png +++ b/editor/icons/icon_mini_rect2.png diff --git a/tools/editor/icons/icon_mini_rid.png b/editor/icons/icon_mini_rid.png Binary files differindex 278a9d1ee6..278a9d1ee6 100644 --- a/tools/editor/icons/icon_mini_rid.png +++ b/editor/icons/icon_mini_rid.png diff --git a/tools/editor/icons/icon_mini_string.png b/editor/icons/icon_mini_string.png Binary files differindex 504556dd74..504556dd74 100644 --- a/tools/editor/icons/icon_mini_string.png +++ b/editor/icons/icon_mini_string.png diff --git a/tools/editor/icons/icon_mini_string_array.png b/editor/icons/icon_mini_string_array.png Binary files differindex 5177014185..5177014185 100644 --- a/tools/editor/icons/icon_mini_string_array.png +++ b/editor/icons/icon_mini_string_array.png diff --git a/tools/editor/icons/icon_mini_transform.png b/editor/icons/icon_mini_transform.png Binary files differindex 068ea0506c..068ea0506c 100644 --- a/tools/editor/icons/icon_mini_transform.png +++ b/editor/icons/icon_mini_transform.png diff --git a/tools/editor/icons/icon_mini_variant.png b/editor/icons/icon_mini_variant.png Binary files differindex 285f0bcd16..285f0bcd16 100644 --- a/tools/editor/icons/icon_mini_variant.png +++ b/editor/icons/icon_mini_variant.png diff --git a/tools/editor/icons/icon_mini_vector2.png b/editor/icons/icon_mini_vector2.png Binary files differindex a7caa1797f..a7caa1797f 100644 --- a/tools/editor/icons/icon_mini_vector2.png +++ b/editor/icons/icon_mini_vector2.png diff --git a/tools/editor/icons/icon_mini_vector2_array.png b/editor/icons/icon_mini_vector2_array.png Binary files differindex de546de16c..de546de16c 100644 --- a/tools/editor/icons/icon_mini_vector2_array.png +++ b/editor/icons/icon_mini_vector2_array.png diff --git a/tools/editor/icons/icon_mini_vector3.png b/editor/icons/icon_mini_vector3.png Binary files differindex 69baeb229b..69baeb229b 100644 --- a/tools/editor/icons/icon_mini_vector3.png +++ b/editor/icons/icon_mini_vector3.png diff --git a/tools/editor/icons/icon_mini_vector3_array.png b/editor/icons/icon_mini_vector3_array.png Binary files differindex 6bddbaf627..6bddbaf627 100644 --- a/tools/editor/icons/icon_mini_vector3_array.png +++ b/editor/icons/icon_mini_vector3_array.png diff --git a/tools/editor/icons/icon_mirror_x.png b/editor/icons/icon_mirror_x.png Binary files differindex 7be48946b4..7be48946b4 100644 --- a/tools/editor/icons/icon_mirror_x.png +++ b/editor/icons/icon_mirror_x.png diff --git a/tools/editor/icons/icon_mirror_y.png b/editor/icons/icon_mirror_y.png Binary files differindex ba924f7ae7..ba924f7ae7 100644 --- a/tools/editor/icons/icon_mirror_y.png +++ b/editor/icons/icon_mirror_y.png diff --git a/tools/editor/icons/icon_mouse.png b/editor/icons/icon_mouse.png Binary files differindex ad07a403a6..ad07a403a6 100644 --- a/tools/editor/icons/icon_mouse.png +++ b/editor/icons/icon_mouse.png diff --git a/tools/editor/icons/icon_move_down.png b/editor/icons/icon_move_down.png Binary files differindex 3934310964..3934310964 100644 --- a/tools/editor/icons/icon_move_down.png +++ b/editor/icons/icon_move_down.png diff --git a/tools/editor/icons/icon_move_down_hl.png b/editor/icons/icon_move_down_hl.png Binary files differindex f9de58a940..f9de58a940 100644 --- a/tools/editor/icons/icon_move_down_hl.png +++ b/editor/icons/icon_move_down_hl.png diff --git a/tools/editor/icons/icon_move_point.png b/editor/icons/icon_move_point.png Binary files differindex 00e4ea32bd..00e4ea32bd 100644 --- a/tools/editor/icons/icon_move_point.png +++ b/editor/icons/icon_move_point.png diff --git a/tools/editor/icons/icon_move_up.png b/editor/icons/icon_move_up.png Binary files differindex 684013dc40..684013dc40 100644 --- a/tools/editor/icons/icon_move_up.png +++ b/editor/icons/icon_move_up.png diff --git a/tools/editor/icons/icon_move_up_hl.png b/editor/icons/icon_move_up_hl.png Binary files differindex e076c9a265..e076c9a265 100644 --- a/tools/editor/icons/icon_move_up_hl.png +++ b/editor/icons/icon_move_up_hl.png diff --git a/tools/editor/icons/icon_multi_edit.png b/editor/icons/icon_multi_edit.png Binary files differindex 0256ae094a..0256ae094a 100644 --- a/tools/editor/icons/icon_multi_edit.png +++ b/editor/icons/icon_multi_edit.png diff --git a/tools/editor/icons/icon_multi_line.png b/editor/icons/icon_multi_line.png Binary files differindex 95a029cc6e..95a029cc6e 100644 --- a/tools/editor/icons/icon_multi_line.png +++ b/editor/icons/icon_multi_line.png diff --git a/tools/editor/icons/icon_multi_mesh.png b/editor/icons/icon_multi_mesh.png Binary files differindex 6ff9d22266..6ff9d22266 100644 --- a/tools/editor/icons/icon_multi_mesh.png +++ b/editor/icons/icon_multi_mesh.png diff --git a/tools/editor/icons/icon_multi_mesh_instance.png b/editor/icons/icon_multi_mesh_instance.png Binary files differindex 124bf81b5a..124bf81b5a 100644 --- a/tools/editor/icons/icon_multi_mesh_instance.png +++ b/editor/icons/icon_multi_mesh_instance.png diff --git a/tools/editor/icons/icon_multi_node_edit.png b/editor/icons/icon_multi_node_edit.png Binary files differindex 0256ae094a..0256ae094a 100644 --- a/tools/editor/icons/icon_multi_node_edit.png +++ b/editor/icons/icon_multi_node_edit.png diff --git a/tools/editor/icons/icon_navigation.png b/editor/icons/icon_navigation.png Binary files differindex 3c5a3bdc4a..3c5a3bdc4a 100644 --- a/tools/editor/icons/icon_navigation.png +++ b/editor/icons/icon_navigation.png diff --git a/tools/editor/icons/icon_navigation_2d.png b/editor/icons/icon_navigation_2d.png Binary files differindex a6ea55ef13..a6ea55ef13 100644 --- a/tools/editor/icons/icon_navigation_2d.png +++ b/editor/icons/icon_navigation_2d.png diff --git a/tools/editor/icons/icon_navigation_mesh.png b/editor/icons/icon_navigation_mesh.png Binary files differindex e3bb7f775f..e3bb7f775f 100644 --- a/tools/editor/icons/icon_navigation_mesh.png +++ b/editor/icons/icon_navigation_mesh.png diff --git a/tools/editor/icons/icon_navigation_mesh_instance.png b/editor/icons/icon_navigation_mesh_instance.png Binary files differindex f5f25ef421..f5f25ef421 100644 --- a/tools/editor/icons/icon_navigation_mesh_instance.png +++ b/editor/icons/icon_navigation_mesh_instance.png diff --git a/tools/editor/icons/icon_navigation_polygon.png b/editor/icons/icon_navigation_polygon.png Binary files differindex bfc4bfb542..bfc4bfb542 100644 --- a/tools/editor/icons/icon_navigation_polygon.png +++ b/editor/icons/icon_navigation_polygon.png diff --git a/tools/editor/icons/icon_navigation_polygon_instance.png b/editor/icons/icon_navigation_polygon_instance.png Binary files differindex 89d420ca14..89d420ca14 100644 --- a/tools/editor/icons/icon_navigation_polygon_instance.png +++ b/editor/icons/icon_navigation_polygon_instance.png diff --git a/tools/editor/icons/icon_new.png b/editor/icons/icon_new.png Binary files differindex 69c6c90dc7..69c6c90dc7 100644 --- a/tools/editor/icons/icon_new.png +++ b/editor/icons/icon_new.png diff --git a/tools/editor/icons/icon_nine_patch_rect.png b/editor/icons/icon_nine_patch_rect.png Binary files differindex bdd1467144..bdd1467144 100644 --- a/tools/editor/icons/icon_nine_patch_rect.png +++ b/editor/icons/icon_nine_patch_rect.png diff --git a/tools/editor/icons/icon_node.png b/editor/icons/icon_node.png Binary files differindex 628b632332..628b632332 100644 --- a/tools/editor/icons/icon_node.png +++ b/editor/icons/icon_node.png diff --git a/tools/editor/icons/icon_node_2d.png b/editor/icons/icon_node_2d.png Binary files differindex d6c8f1f988..d6c8f1f988 100644 --- a/tools/editor/icons/icon_node_2d.png +++ b/editor/icons/icon_node_2d.png diff --git a/tools/editor/icons/icon_node_real_slot.png b/editor/icons/icon_node_real_slot.png Binary files differindex 6373bc0fa5..6373bc0fa5 100644 --- a/tools/editor/icons/icon_node_real_slot.png +++ b/editor/icons/icon_node_real_slot.png diff --git a/tools/editor/icons/icon_node_vec_slot.png b/editor/icons/icon_node_vec_slot.png Binary files differindex aedd983fb4..aedd983fb4 100644 --- a/tools/editor/icons/icon_node_vec_slot.png +++ b/editor/icons/icon_node_vec_slot.png diff --git a/tools/editor/icons/icon_node_warning.png b/editor/icons/icon_node_warning.png Binary files differindex 8b1e9212a8..8b1e9212a8 100644 --- a/tools/editor/icons/icon_node_warning.png +++ b/editor/icons/icon_node_warning.png diff --git a/tools/editor/icons/icon_non_favorite.png b/editor/icons/icon_non_favorite.png Binary files differindex 92351bde04..92351bde04 100644 --- a/tools/editor/icons/icon_non_favorite.png +++ b/editor/icons/icon_non_favorite.png diff --git a/tools/editor/icons/icon_object.png b/editor/icons/icon_object.png Binary files differindex f4f018c863..f4f018c863 100644 --- a/tools/editor/icons/icon_object.png +++ b/editor/icons/icon_object.png diff --git a/tools/editor/icons/icon_occluder_polygon_2d.png b/editor/icons/icon_occluder_polygon_2d.png Binary files differindex bbfc9ac0a5..bbfc9ac0a5 100644 --- a/tools/editor/icons/icon_occluder_polygon_2d.png +++ b/editor/icons/icon_occluder_polygon_2d.png diff --git a/tools/editor/icons/icon_omni_light.png b/editor/icons/icon_omni_light.png Binary files differindex 286ce723a4..286ce723a4 100644 --- a/tools/editor/icons/icon_omni_light.png +++ b/editor/icons/icon_omni_light.png diff --git a/tools/editor/icons/icon_open.png b/editor/icons/icon_open.png Binary files differindex cc05e98ebb..cc05e98ebb 100644 --- a/tools/editor/icons/icon_open.png +++ b/editor/icons/icon_open.png diff --git a/tools/editor/icons/icon_option_button.png b/editor/icons/icon_option_button.png Binary files differindex c1155309aa..c1155309aa 100644 --- a/tools/editor/icons/icon_option_button.png +++ b/editor/icons/icon_option_button.png diff --git a/tools/editor/icons/icon_override.png b/editor/icons/icon_override.png Binary files differindex 9d917ede75..9d917ede75 100644 --- a/tools/editor/icons/icon_override.png +++ b/editor/icons/icon_override.png diff --git a/tools/editor/icons/icon_p_hash_translation.png b/editor/icons/icon_p_hash_translation.png Binary files differindex abca359eea..abca359eea 100644 --- a/tools/editor/icons/icon_p_hash_translation.png +++ b/editor/icons/icon_p_hash_translation.png diff --git a/tools/editor/icons/icon_packed_data_container.png b/editor/icons/icon_packed_data_container.png Binary files differindex af89da48a9..af89da48a9 100644 --- a/tools/editor/icons/icon_packed_data_container.png +++ b/editor/icons/icon_packed_data_container.png diff --git a/tools/editor/icons/icon_packed_scene.png b/editor/icons/icon_packed_scene.png Binary files differindex 9079762932..9079762932 100644 --- a/tools/editor/icons/icon_packed_scene.png +++ b/editor/icons/icon_packed_scene.png diff --git a/tools/editor/icons/icon_pane_drag.png b/editor/icons/icon_pane_drag.png Binary files differindex 57f8e49ba3..57f8e49ba3 100644 --- a/tools/editor/icons/icon_pane_drag.png +++ b/editor/icons/icon_pane_drag.png diff --git a/tools/editor/icons/icon_pane_drag_hover.png b/editor/icons/icon_pane_drag_hover.png Binary files differindex 068253ecef..068253ecef 100644 --- a/tools/editor/icons/icon_pane_drag_hover.png +++ b/editor/icons/icon_pane_drag_hover.png diff --git a/tools/editor/icons/icon_panel.png b/editor/icons/icon_panel.png Binary files differindex dca2da94f3..dca2da94f3 100644 --- a/tools/editor/icons/icon_panel.png +++ b/editor/icons/icon_panel.png diff --git a/tools/editor/icons/icon_panel_container.png b/editor/icons/icon_panel_container.png Binary files differindex 05bd1e082f..05bd1e082f 100644 --- a/tools/editor/icons/icon_panel_container.png +++ b/editor/icons/icon_panel_container.png diff --git a/tools/editor/icons/icon_panel_top.png b/editor/icons/icon_panel_top.png Binary files differindex 20e67fad1a..20e67fad1a 100644 --- a/tools/editor/icons/icon_panel_top.png +++ b/editor/icons/icon_panel_top.png diff --git a/tools/editor/icons/icon_panels_1.png b/editor/icons/icon_panels_1.png Binary files differindex a909e6aee8..a909e6aee8 100644 --- a/tools/editor/icons/icon_panels_1.png +++ b/editor/icons/icon_panels_1.png diff --git a/tools/editor/icons/icon_panels_2.png b/editor/icons/icon_panels_2.png Binary files differindex 28a1ca2a59..28a1ca2a59 100644 --- a/tools/editor/icons/icon_panels_2.png +++ b/editor/icons/icon_panels_2.png diff --git a/tools/editor/icons/icon_panels_2_alt.png b/editor/icons/icon_panels_2_alt.png Binary files differindex 14f21304c5..14f21304c5 100644 --- a/tools/editor/icons/icon_panels_2_alt.png +++ b/editor/icons/icon_panels_2_alt.png diff --git a/tools/editor/icons/icon_panels_3.png b/editor/icons/icon_panels_3.png Binary files differindex 76f1f53636..76f1f53636 100644 --- a/tools/editor/icons/icon_panels_3.png +++ b/editor/icons/icon_panels_3.png diff --git a/tools/editor/icons/icon_panels_3_alt.png b/editor/icons/icon_panels_3_alt.png Binary files differindex b121bc62c3..b121bc62c3 100644 --- a/tools/editor/icons/icon_panels_3_alt.png +++ b/editor/icons/icon_panels_3_alt.png diff --git a/tools/editor/icons/icon_panels_4.png b/editor/icons/icon_panels_4.png Binary files differindex 19a3bc0bf2..19a3bc0bf2 100644 --- a/tools/editor/icons/icon_panels_4.png +++ b/editor/icons/icon_panels_4.png diff --git a/tools/editor/icons/icon_parallax_background.png b/editor/icons/icon_parallax_background.png Binary files differindex 78d7484e8b..78d7484e8b 100644 --- a/tools/editor/icons/icon_parallax_background.png +++ b/editor/icons/icon_parallax_background.png diff --git a/tools/editor/icons/icon_parallax_layer.png b/editor/icons/icon_parallax_layer.png Binary files differindex 748c9164bb..748c9164bb 100644 --- a/tools/editor/icons/icon_parallax_layer.png +++ b/editor/icons/icon_parallax_layer.png diff --git a/tools/editor/icons/icon_particle_attractor_2d.png b/editor/icons/icon_particle_attractor_2d.png Binary files differindex 84be7dff3b..84be7dff3b 100644 --- a/tools/editor/icons/icon_particle_attractor_2d.png +++ b/editor/icons/icon_particle_attractor_2d.png diff --git a/tools/editor/icons/icon_particles.png b/editor/icons/icon_particles.png Binary files differindex 8d146b2946..8d146b2946 100644 --- a/tools/editor/icons/icon_particles.png +++ b/editor/icons/icon_particles.png diff --git a/tools/editor/icons/icon_particles_2d.png b/editor/icons/icon_particles_2d.png Binary files differindex e03ff1e189..e03ff1e189 100644 --- a/tools/editor/icons/icon_particles_2d.png +++ b/editor/icons/icon_particles_2d.png diff --git a/tools/editor/icons/icon_particles_frame.png b/editor/icons/icon_particles_frame.png Binary files differindex 968bbccf8a..968bbccf8a 100644 --- a/tools/editor/icons/icon_particles_frame.png +++ b/editor/icons/icon_particles_frame.png diff --git a/tools/editor/icons/icon_particles_shader.png b/editor/icons/icon_particles_shader.png Binary files differindex 3b5c5644b2..3b5c5644b2 100644 --- a/tools/editor/icons/icon_particles_shader.png +++ b/editor/icons/icon_particles_shader.png diff --git a/tools/editor/icons/icon_patch_9_rect.png b/editor/icons/icon_patch_9_rect.png Binary files differindex bdd1467144..bdd1467144 100644 --- a/tools/editor/icons/icon_patch_9_rect.png +++ b/editor/icons/icon_patch_9_rect.png diff --git a/tools/editor/icons/icon_path.png b/editor/icons/icon_path.png Binary files differindex 4ebdcbdc44..4ebdcbdc44 100644 --- a/tools/editor/icons/icon_path.png +++ b/editor/icons/icon_path.png diff --git a/tools/editor/icons/icon_path_2d.png b/editor/icons/icon_path_2d.png Binary files differindex c5b0d5d7c6..c5b0d5d7c6 100644 --- a/tools/editor/icons/icon_path_2d.png +++ b/editor/icons/icon_path_2d.png diff --git a/tools/editor/icons/icon_path_follow.png b/editor/icons/icon_path_follow.png Binary files differindex f71651d241..f71651d241 100644 --- a/tools/editor/icons/icon_path_follow.png +++ b/editor/icons/icon_path_follow.png diff --git a/tools/editor/icons/icon_path_follow_2d.png b/editor/icons/icon_path_follow_2d.png Binary files differindex d82e682dba..d82e682dba 100644 --- a/tools/editor/icons/icon_path_follow_2d.png +++ b/editor/icons/icon_path_follow_2d.png diff --git a/tools/editor/icons/icon_pause.png b/editor/icons/icon_pause.png Binary files differindex aec11d5c35..aec11d5c35 100644 --- a/tools/editor/icons/icon_pause.png +++ b/editor/icons/icon_pause.png diff --git a/tools/editor/icons/icon_pe_edit.png b/editor/icons/icon_pe_edit.png Binary files differindex 7082303a4e..7082303a4e 100644 --- a/tools/editor/icons/icon_pe_edit.png +++ b/editor/icons/icon_pe_edit.png diff --git a/tools/editor/icons/icon_physics_joint_pin.png b/editor/icons/icon_physics_joint_pin.png Binary files differindex 27ac67ed0a..27ac67ed0a 100644 --- a/tools/editor/icons/icon_physics_joint_pin.png +++ b/editor/icons/icon_physics_joint_pin.png diff --git a/tools/editor/icons/icon_pin.png b/editor/icons/icon_pin.png Binary files differindex cf89679f88..cf89679f88 100644 --- a/tools/editor/icons/icon_pin.png +++ b/editor/icons/icon_pin.png diff --git a/tools/editor/icons/icon_pin_joint.png b/editor/icons/icon_pin_joint.png Binary files differindex 78e8a83724..78e8a83724 100644 --- a/tools/editor/icons/icon_pin_joint.png +++ b/editor/icons/icon_pin_joint.png diff --git a/tools/editor/icons/icon_pin_joint_2d.png b/editor/icons/icon_pin_joint_2d.png Binary files differindex 355d5a2022..355d5a2022 100644 --- a/tools/editor/icons/icon_pin_joint_2d.png +++ b/editor/icons/icon_pin_joint_2d.png diff --git a/tools/editor/icons/icon_pin_pressed.png b/editor/icons/icon_pin_pressed.png Binary files differindex cf89679f88..cf89679f88 100644 --- a/tools/editor/icons/icon_pin_pressed.png +++ b/editor/icons/icon_pin_pressed.png diff --git a/tools/editor/icons/icon_plane.png b/editor/icons/icon_plane.png Binary files differindex 25d869f31e..25d869f31e 100644 --- a/tools/editor/icons/icon_plane.png +++ b/editor/icons/icon_plane.png diff --git a/tools/editor/icons/icon_plane_shape.png b/editor/icons/icon_plane_shape.png Binary files differindex e7ebe1fbcd..e7ebe1fbcd 100644 --- a/tools/editor/icons/icon_plane_shape.png +++ b/editor/icons/icon_plane_shape.png diff --git a/tools/editor/icons/icon_play.png b/editor/icons/icon_play.png Binary files differindex 864e4e4fb9..864e4e4fb9 100644 --- a/tools/editor/icons/icon_play.png +++ b/editor/icons/icon_play.png diff --git a/tools/editor/icons/icon_play_backwards.png b/editor/icons/icon_play_backwards.png Binary files differindex bab2858373..bab2858373 100644 --- a/tools/editor/icons/icon_play_backwards.png +++ b/editor/icons/icon_play_backwards.png diff --git a/tools/editor/icons/icon_play_custom.png b/editor/icons/icon_play_custom.png Binary files differindex b742e131ca..b742e131ca 100644 --- a/tools/editor/icons/icon_play_custom.png +++ b/editor/icons/icon_play_custom.png diff --git a/tools/editor/icons/icon_play_scene.png b/editor/icons/icon_play_scene.png Binary files differindex ebba318799..ebba318799 100644 --- a/tools/editor/icons/icon_play_scene.png +++ b/editor/icons/icon_play_scene.png diff --git a/tools/editor/icons/icon_play_start.png b/editor/icons/icon_play_start.png Binary files differindex dacc156614..dacc156614 100644 --- a/tools/editor/icons/icon_play_start.png +++ b/editor/icons/icon_play_start.png diff --git a/tools/editor/icons/icon_play_start_backwards.png b/editor/icons/icon_play_start_backwards.png Binary files differindex 7608e18cba..7608e18cba 100644 --- a/tools/editor/icons/icon_play_start_backwards.png +++ b/editor/icons/icon_play_start_backwards.png diff --git a/tools/editor/icons/icon_polygon_2d.png b/editor/icons/icon_polygon_2d.png Binary files differindex b372749cb0..b372749cb0 100644 --- a/tools/editor/icons/icon_polygon_2d.png +++ b/editor/icons/icon_polygon_2d.png diff --git a/tools/editor/icons/icon_polygon_path_finder.png b/editor/icons/icon_polygon_path_finder.png Binary files differindex 9d76d872db..9d76d872db 100644 --- a/tools/editor/icons/icon_polygon_path_finder.png +++ b/editor/icons/icon_polygon_path_finder.png diff --git a/tools/editor/icons/icon_popup.png b/editor/icons/icon_popup.png Binary files differindex 4dda9e50f9..4dda9e50f9 100644 --- a/tools/editor/icons/icon_popup.png +++ b/editor/icons/icon_popup.png diff --git a/tools/editor/icons/icon_popup_dialog.png b/editor/icons/icon_popup_dialog.png Binary files differindex 82b011e06c..82b011e06c 100644 --- a/tools/editor/icons/icon_popup_dialog.png +++ b/editor/icons/icon_popup_dialog.png diff --git a/tools/editor/icons/icon_popup_menu.png b/editor/icons/icon_popup_menu.png Binary files differindex 28d928a98e..28d928a98e 100644 --- a/tools/editor/icons/icon_popup_menu.png +++ b/editor/icons/icon_popup_menu.png diff --git a/tools/editor/icons/icon_popup_panel.png b/editor/icons/icon_popup_panel.png Binary files differindex 90c86c2c05..90c86c2c05 100644 --- a/tools/editor/icons/icon_popup_panel.png +++ b/editor/icons/icon_popup_panel.png diff --git a/tools/editor/icons/icon_portal.png b/editor/icons/icon_portal.png Binary files differindex b10aee650d..b10aee650d 100644 --- a/tools/editor/icons/icon_portal.png +++ b/editor/icons/icon_portal.png diff --git a/tools/editor/icons/icon_position_2d.png b/editor/icons/icon_position_2d.png Binary files differindex da7446e3e2..da7446e3e2 100644 --- a/tools/editor/icons/icon_position_2d.png +++ b/editor/icons/icon_position_2d.png diff --git a/tools/editor/icons/icon_position_3d.png b/editor/icons/icon_position_3d.png Binary files differindex a36bca3260..a36bca3260 100644 --- a/tools/editor/icons/icon_position_3d.png +++ b/editor/icons/icon_position_3d.png diff --git a/tools/editor/icons/icon_prev_scene.png b/editor/icons/icon_prev_scene.png Binary files differindex 9d8dda5180..9d8dda5180 100644 --- a/tools/editor/icons/icon_prev_scene.png +++ b/editor/icons/icon_prev_scene.png diff --git a/tools/editor/icons/icon_progress_1.png b/editor/icons/icon_progress_1.png Binary files differindex 34196ec2dd..34196ec2dd 100644 --- a/tools/editor/icons/icon_progress_1.png +++ b/editor/icons/icon_progress_1.png diff --git a/tools/editor/icons/icon_progress_2.png b/editor/icons/icon_progress_2.png Binary files differindex 6f683f2473..6f683f2473 100644 --- a/tools/editor/icons/icon_progress_2.png +++ b/editor/icons/icon_progress_2.png diff --git a/tools/editor/icons/icon_progress_3.png b/editor/icons/icon_progress_3.png Binary files differindex 82202d28a6..82202d28a6 100644 --- a/tools/editor/icons/icon_progress_3.png +++ b/editor/icons/icon_progress_3.png diff --git a/tools/editor/icons/icon_progress_4.png b/editor/icons/icon_progress_4.png Binary files differindex 70198ab26a..70198ab26a 100644 --- a/tools/editor/icons/icon_progress_4.png +++ b/editor/icons/icon_progress_4.png diff --git a/tools/editor/icons/icon_progress_5.png b/editor/icons/icon_progress_5.png Binary files differindex b5f4bdcdec..b5f4bdcdec 100644 --- a/tools/editor/icons/icon_progress_5.png +++ b/editor/icons/icon_progress_5.png diff --git a/tools/editor/icons/icon_progress_6.png b/editor/icons/icon_progress_6.png Binary files differindex df8f27c60d..df8f27c60d 100644 --- a/tools/editor/icons/icon_progress_6.png +++ b/editor/icons/icon_progress_6.png diff --git a/tools/editor/icons/icon_progress_7.png b/editor/icons/icon_progress_7.png Binary files differindex 892d5b53ba..892d5b53ba 100644 --- a/tools/editor/icons/icon_progress_7.png +++ b/editor/icons/icon_progress_7.png diff --git a/tools/editor/icons/icon_progress_8.png b/editor/icons/icon_progress_8.png Binary files differindex c593afb7dd..c593afb7dd 100644 --- a/tools/editor/icons/icon_progress_8.png +++ b/editor/icons/icon_progress_8.png diff --git a/tools/editor/icons/icon_progress_bar.png b/editor/icons/icon_progress_bar.png Binary files differindex 30822dd7a8..30822dd7a8 100644 --- a/tools/editor/icons/icon_progress_bar.png +++ b/editor/icons/icon_progress_bar.png diff --git a/tools/editor/icons/icon_property_editor.png b/editor/icons/icon_property_editor.png Binary files differindex 5ee0ab8068..5ee0ab8068 100644 --- a/tools/editor/icons/icon_property_editor.png +++ b/editor/icons/icon_property_editor.png diff --git a/tools/editor/icons/icon_proximity_group.png b/editor/icons/icon_proximity_group.png Binary files differindex 230ca752ec..230ca752ec 100644 --- a/tools/editor/icons/icon_proximity_group.png +++ b/editor/icons/icon_proximity_group.png diff --git a/tools/editor/icons/icon_quad.png b/editor/icons/icon_quad.png Binary files differindex a1b31b026b..a1b31b026b 100644 --- a/tools/editor/icons/icon_quad.png +++ b/editor/icons/icon_quad.png diff --git a/tools/editor/icons/icon_quat.png b/editor/icons/icon_quat.png Binary files differindex 0fcaa35b56..0fcaa35b56 100644 --- a/tools/editor/icons/icon_quat.png +++ b/editor/icons/icon_quat.png diff --git a/tools/editor/icons/icon_range.png b/editor/icons/icon_range.png Binary files differindex 6e46df9690..6e46df9690 100644 --- a/tools/editor/icons/icon_range.png +++ b/editor/icons/icon_range.png diff --git a/tools/editor/icons/icon_rating_no_star.png b/editor/icons/icon_rating_no_star.png Binary files differindex e7421bdb13..e7421bdb13 100644 --- a/tools/editor/icons/icon_rating_no_star.png +++ b/editor/icons/icon_rating_no_star.png diff --git a/tools/editor/icons/icon_rating_star.png b/editor/icons/icon_rating_star.png Binary files differindex b2a7e01322..b2a7e01322 100644 --- a/tools/editor/icons/icon_rating_star.png +++ b/editor/icons/icon_rating_star.png diff --git a/tools/editor/icons/icon_ray_cast.png b/editor/icons/icon_ray_cast.png Binary files differindex 19cba12d1d..19cba12d1d 100644 --- a/tools/editor/icons/icon_ray_cast.png +++ b/editor/icons/icon_ray_cast.png diff --git a/tools/editor/icons/icon_ray_cast_2d.png b/editor/icons/icon_ray_cast_2d.png Binary files differindex 2a5054ab00..2a5054ab00 100644 --- a/tools/editor/icons/icon_ray_cast_2d.png +++ b/editor/icons/icon_ray_cast_2d.png diff --git a/tools/editor/icons/icon_ray_shape.png b/editor/icons/icon_ray_shape.png Binary files differindex a3188d1a3a..a3188d1a3a 100644 --- a/tools/editor/icons/icon_ray_shape.png +++ b/editor/icons/icon_ray_shape.png diff --git a/tools/editor/icons/icon_ray_shape_2d.png b/editor/icons/icon_ray_shape_2d.png Binary files differindex c91a63570d..c91a63570d 100644 --- a/tools/editor/icons/icon_ray_shape_2d.png +++ b/editor/icons/icon_ray_shape_2d.png diff --git a/tools/editor/icons/icon_rayito.png b/editor/icons/icon_rayito.png Binary files differindex 1afb5975d1..1afb5975d1 100644 --- a/tools/editor/icons/icon_rayito.png +++ b/editor/icons/icon_rayito.png diff --git a/tools/editor/icons/icon_real.png b/editor/icons/icon_real.png Binary files differindex 555b61427f..555b61427f 100644 --- a/tools/editor/icons/icon_real.png +++ b/editor/icons/icon_real.png diff --git a/tools/editor/icons/icon_rect2.png b/editor/icons/icon_rect2.png Binary files differindex cf3cfe3b22..cf3cfe3b22 100644 --- a/tools/editor/icons/icon_rect2.png +++ b/editor/icons/icon_rect2.png diff --git a/tools/editor/icons/icon_rect3.png b/editor/icons/icon_rect3.png Binary files differindex 8eacfff207..8eacfff207 100644 --- a/tools/editor/icons/icon_rect3.png +++ b/editor/icons/icon_rect3.png diff --git a/tools/editor/icons/icon_rectangle_shape_2d.png b/editor/icons/icon_rectangle_shape_2d.png Binary files differindex 002730b942..002730b942 100644 --- a/tools/editor/icons/icon_rectangle_shape_2d.png +++ b/editor/icons/icon_rectangle_shape_2d.png diff --git a/tools/editor/icons/icon_reference_rect.png b/editor/icons/icon_reference_rect.png Binary files differindex b253af477f..b253af477f 100644 --- a/tools/editor/icons/icon_reference_rect.png +++ b/editor/icons/icon_reference_rect.png diff --git a/tools/editor/icons/icon_reflection_probe.png b/editor/icons/icon_reflection_probe.png Binary files differindex a6646114fb..a6646114fb 100644 --- a/tools/editor/icons/icon_reflection_probe.png +++ b/editor/icons/icon_reflection_probe.png diff --git a/tools/editor/icons/icon_region_edit.png b/editor/icons/icon_region_edit.png Binary files differindex 5f133072d4..5f133072d4 100644 --- a/tools/editor/icons/icon_region_edit.png +++ b/editor/icons/icon_region_edit.png diff --git a/tools/editor/icons/icon_reload.png b/editor/icons/icon_reload.png Binary files differindex 9303fabb9c..9303fabb9c 100644 --- a/tools/editor/icons/icon_reload.png +++ b/editor/icons/icon_reload.png diff --git a/tools/editor/icons/icon_reload_empty.png b/editor/icons/icon_reload_empty.png Binary files differindex d43582b2c4..d43582b2c4 100644 --- a/tools/editor/icons/icon_reload_empty.png +++ b/editor/icons/icon_reload_empty.png diff --git a/tools/editor/icons/icon_reload_small.png b/editor/icons/icon_reload_small.png Binary files differindex 1397ac6aa5..1397ac6aa5 100644 --- a/tools/editor/icons/icon_reload_small.png +++ b/editor/icons/icon_reload_small.png diff --git a/tools/editor/icons/icon_remote.png b/editor/icons/icon_remote.png Binary files differindex 7eb7608b13..7eb7608b13 100644 --- a/tools/editor/icons/icon_remote.png +++ b/editor/icons/icon_remote.png diff --git a/tools/editor/icons/icon_remote_transform.png b/editor/icons/icon_remote_transform.png Binary files differindex 2a8b5f4d0e..2a8b5f4d0e 100644 --- a/tools/editor/icons/icon_remote_transform.png +++ b/editor/icons/icon_remote_transform.png diff --git a/tools/editor/icons/icon_remote_transform_2d.png b/editor/icons/icon_remote_transform_2d.png Binary files differindex 16d2691832..16d2691832 100644 --- a/tools/editor/icons/icon_remote_transform_2d.png +++ b/editor/icons/icon_remote_transform_2d.png diff --git a/tools/editor/icons/icon_remove.png b/editor/icons/icon_remove.png Binary files differindex b6bf05a16d..b6bf05a16d 100644 --- a/tools/editor/icons/icon_remove.png +++ b/editor/icons/icon_remove.png diff --git a/tools/editor/icons/icon_remove_hl.png b/editor/icons/icon_remove_hl.png Binary files differindex 0d3b887e7f..0d3b887e7f 100644 --- a/tools/editor/icons/icon_remove_hl.png +++ b/editor/icons/icon_remove_hl.png diff --git a/tools/editor/icons/icon_remove_small.png b/editor/icons/icon_remove_small.png Binary files differindex e0903689cf..e0903689cf 100644 --- a/tools/editor/icons/icon_remove_small.png +++ b/editor/icons/icon_remove_small.png diff --git a/tools/editor/icons/icon_rename.png b/editor/icons/icon_rename.png Binary files differindex 2df503f100..2df503f100 100644 --- a/tools/editor/icons/icon_rename.png +++ b/editor/icons/icon_rename.png diff --git a/tools/editor/icons/icon_reparent.png b/editor/icons/icon_reparent.png Binary files differindex 135ccee4ad..135ccee4ad 100644 --- a/tools/editor/icons/icon_reparent.png +++ b/editor/icons/icon_reparent.png diff --git a/tools/editor/icons/icon_replace.png b/editor/icons/icon_replace.png Binary files differindex 662a58dc93..662a58dc93 100644 --- a/tools/editor/icons/icon_replace.png +++ b/editor/icons/icon_replace.png diff --git a/tools/editor/icons/icon_resource_preloader.png b/editor/icons/icon_resource_preloader.png Binary files differindex d3064f5e90..d3064f5e90 100644 --- a/tools/editor/icons/icon_resource_preloader.png +++ b/editor/icons/icon_resource_preloader.png diff --git a/tools/editor/icons/icon_rich_text_label.png b/editor/icons/icon_rich_text_label.png Binary files differindex 1aea6e8fa7..1aea6e8fa7 100644 --- a/tools/editor/icons/icon_rich_text_label.png +++ b/editor/icons/icon_rich_text_label.png diff --git a/tools/editor/icons/icon_rid.png b/editor/icons/icon_rid.png Binary files differindex f7bc02e128..f7bc02e128 100644 --- a/tools/editor/icons/icon_rid.png +++ b/editor/icons/icon_rid.png diff --git a/tools/editor/icons/icon_rigid_body.png b/editor/icons/icon_rigid_body.png Binary files differindex 4072308f71..4072308f71 100644 --- a/tools/editor/icons/icon_rigid_body.png +++ b/editor/icons/icon_rigid_body.png diff --git a/tools/editor/icons/icon_rigid_body_2_d.png b/editor/icons/icon_rigid_body_2_d.png Binary files differindex c296b88636..c296b88636 100644 --- a/tools/editor/icons/icon_rigid_body_2_d.png +++ b/editor/icons/icon_rigid_body_2_d.png diff --git a/tools/editor/icons/icon_rigid_body_2d.png b/editor/icons/icon_rigid_body_2d.png Binary files differindex 8d11d536c1..8d11d536c1 100644 --- a/tools/editor/icons/icon_rigid_body_2d.png +++ b/editor/icons/icon_rigid_body_2d.png diff --git a/tools/editor/icons/icon_room.png b/editor/icons/icon_room.png Binary files differindex 840db145fd..840db145fd 100644 --- a/tools/editor/icons/icon_room.png +++ b/editor/icons/icon_room.png diff --git a/tools/editor/icons/icon_room_bounds.png b/editor/icons/icon_room_bounds.png Binary files differindex 15b198e821..15b198e821 100644 --- a/tools/editor/icons/icon_room_bounds.png +++ b/editor/icons/icon_room_bounds.png diff --git a/tools/editor/icons/icon_room_instance.png b/editor/icons/icon_room_instance.png Binary files differindex f0c46e689c..f0c46e689c 100644 --- a/tools/editor/icons/icon_room_instance.png +++ b/editor/icons/icon_room_instance.png diff --git a/tools/editor/icons/icon_rotate_0.png b/editor/icons/icon_rotate_0.png Binary files differindex 75bd667845..75bd667845 100644 --- a/tools/editor/icons/icon_rotate_0.png +++ b/editor/icons/icon_rotate_0.png diff --git a/tools/editor/icons/icon_rotate_180.png b/editor/icons/icon_rotate_180.png Binary files differindex dd9333207e..dd9333207e 100644 --- a/tools/editor/icons/icon_rotate_180.png +++ b/editor/icons/icon_rotate_180.png diff --git a/tools/editor/icons/icon_rotate_270.png b/editor/icons/icon_rotate_270.png Binary files differindex 551fd3afb9..551fd3afb9 100644 --- a/tools/editor/icons/icon_rotate_270.png +++ b/editor/icons/icon_rotate_270.png diff --git a/tools/editor/icons/icon_rotate_90.png b/editor/icons/icon_rotate_90.png Binary files differindex 55a084cc4e..55a084cc4e 100644 --- a/tools/editor/icons/icon_rotate_90.png +++ b/editor/icons/icon_rotate_90.png diff --git a/tools/editor/icons/icon_run.png b/editor/icons/icon_run.png Binary files differindex 133d383d9e..133d383d9e 100644 --- a/tools/editor/icons/icon_run.png +++ b/editor/icons/icon_run.png diff --git a/tools/editor/icons/icon_s_s_a_o_f_x.png b/editor/icons/icon_s_s_a_o_f_x.png Binary files differindex 36eccedca5..36eccedca5 100644 --- a/tools/editor/icons/icon_s_s_a_o_f_x.png +++ b/editor/icons/icon_s_s_a_o_f_x.png diff --git a/tools/editor/icons/icon_sample.png b/editor/icons/icon_sample.png Binary files differindex 25755699be..25755699be 100644 --- a/tools/editor/icons/icon_sample.png +++ b/editor/icons/icon_sample.png diff --git a/tools/editor/icons/icon_sample_library.png b/editor/icons/icon_sample_library.png Binary files differindex 5921aa86e7..5921aa86e7 100644 --- a/tools/editor/icons/icon_sample_library.png +++ b/editor/icons/icon_sample_library.png diff --git a/tools/editor/icons/icon_sample_player.png b/editor/icons/icon_sample_player.png Binary files differindex 4056cceeff..4056cceeff 100644 --- a/tools/editor/icons/icon_sample_player.png +++ b/editor/icons/icon_sample_player.png diff --git a/tools/editor/icons/icon_sample_player_2d.png b/editor/icons/icon_sample_player_2d.png Binary files differindex eb70340db8..eb70340db8 100644 --- a/tools/editor/icons/icon_sample_player_2d.png +++ b/editor/icons/icon_sample_player_2d.png diff --git a/tools/editor/icons/icon_save.png b/editor/icons/icon_save.png Binary files differindex 8695b7839d..8695b7839d 100644 --- a/tools/editor/icons/icon_save.png +++ b/editor/icons/icon_save.png diff --git a/tools/editor/icons/icon_scene.png b/editor/icons/icon_scene.png Binary files differindex 9629bb91c2..9629bb91c2 100644 --- a/tools/editor/icons/icon_scene.png +++ b/editor/icons/icon_scene.png diff --git a/tools/editor/icons/icon_scene_instance.png b/editor/icons/icon_scene_instance.png Binary files differindex 05df811aa0..05df811aa0 100644 --- a/tools/editor/icons/icon_scene_instance.png +++ b/editor/icons/icon_scene_instance.png diff --git a/tools/editor/icons/icon_scene_tree_editor.png b/editor/icons/icon_scene_tree_editor.png Binary files differindex 0b51763555..0b51763555 100644 --- a/tools/editor/icons/icon_scene_tree_editor.png +++ b/editor/icons/icon_scene_tree_editor.png diff --git a/tools/editor/icons/icon_script.png b/editor/icons/icon_script.png Binary files differindex 5aa673fcd6..5aa673fcd6 100644 --- a/tools/editor/icons/icon_script.png +++ b/editor/icons/icon_script.png diff --git a/tools/editor/icons/icon_script_control.png b/editor/icons/icon_script_control.png Binary files differindex cd1cc9b9af..cd1cc9b9af 100644 --- a/tools/editor/icons/icon_script_control.png +++ b/editor/icons/icon_script_control.png diff --git a/tools/editor/icons/icon_script_create.png b/editor/icons/icon_script_create.png Binary files differindex 86c19f748b..86c19f748b 100644 --- a/tools/editor/icons/icon_script_create.png +++ b/editor/icons/icon_script_create.png diff --git a/tools/editor/icons/icon_script_error.png b/editor/icons/icon_script_error.png Binary files differindex 3532c2c379..3532c2c379 100644 --- a/tools/editor/icons/icon_script_error.png +++ b/editor/icons/icon_script_error.png diff --git a/tools/editor/icons/icon_script_list.png b/editor/icons/icon_script_list.png Binary files differindex cdea1e161e..cdea1e161e 100644 --- a/tools/editor/icons/icon_script_list.png +++ b/editor/icons/icon_script_list.png diff --git a/tools/editor/icons/icon_script_node.png b/editor/icons/icon_script_node.png Binary files differindex fcf205b2e9..fcf205b2e9 100644 --- a/tools/editor/icons/icon_script_node.png +++ b/editor/icons/icon_script_node.png diff --git a/tools/editor/icons/icon_script_remove.png b/editor/icons/icon_script_remove.png Binary files differindex c200b01690..c200b01690 100644 --- a/tools/editor/icons/icon_script_remove.png +++ b/editor/icons/icon_script_remove.png diff --git a/tools/editor/icons/icon_scroll_bar.png b/editor/icons/icon_scroll_bar.png Binary files differindex e4576c4ae3..e4576c4ae3 100644 --- a/tools/editor/icons/icon_scroll_bar.png +++ b/editor/icons/icon_scroll_bar.png diff --git a/tools/editor/icons/icon_scroll_container.png b/editor/icons/icon_scroll_container.png Binary files differindex 4e42d84ab1..4e42d84ab1 100644 --- a/tools/editor/icons/icon_scroll_container.png +++ b/editor/icons/icon_scroll_container.png diff --git a/tools/editor/icons/icon_segment_shape_2d.png b/editor/icons/icon_segment_shape_2d.png Binary files differindex 8f3771be7a..8f3771be7a 100644 --- a/tools/editor/icons/icon_segment_shape_2d.png +++ b/editor/icons/icon_segment_shape_2d.png diff --git a/tools/editor/icons/icon_shader.png b/editor/icons/icon_shader.png Binary files differindex 568a45d938..568a45d938 100644 --- a/tools/editor/icons/icon_shader.png +++ b/editor/icons/icon_shader.png diff --git a/tools/editor/icons/icon_shader_material.png b/editor/icons/icon_shader_material.png Binary files differindex 568a45d938..568a45d938 100644 --- a/tools/editor/icons/icon_shader_material.png +++ b/editor/icons/icon_shader_material.png diff --git a/tools/editor/icons/icon_short_cut.png b/editor/icons/icon_short_cut.png Binary files differindex 22e15c3889..22e15c3889 100644 --- a/tools/editor/icons/icon_short_cut.png +++ b/editor/icons/icon_short_cut.png diff --git a/tools/editor/icons/icon_signal.png b/editor/icons/icon_signal.png Binary files differindex c2f393228c..c2f393228c 100644 --- a/tools/editor/icons/icon_signal.png +++ b/editor/icons/icon_signal.png diff --git a/tools/editor/icons/icon_skeleton.png b/editor/icons/icon_skeleton.png Binary files differindex 17b003caac..17b003caac 100644 --- a/tools/editor/icons/icon_skeleton.png +++ b/editor/icons/icon_skeleton.png diff --git a/tools/editor/icons/icon_skeletonr.png b/editor/icons/icon_skeletonr.png Binary files differindex dcb2d512ab..dcb2d512ab 100644 --- a/tools/editor/icons/icon_skeletonr.png +++ b/editor/icons/icon_skeletonr.png diff --git a/tools/editor/icons/icon_sky_box_f_x.png b/editor/icons/icon_sky_box_f_x.png Binary files differindex cabd19e550..cabd19e550 100644 --- a/tools/editor/icons/icon_sky_box_f_x.png +++ b/editor/icons/icon_sky_box_f_x.png diff --git a/tools/editor/icons/icon_slider_joint.png b/editor/icons/icon_slider_joint.png Binary files differindex d65fb3650d..d65fb3650d 100644 --- a/tools/editor/icons/icon_slider_joint.png +++ b/editor/icons/icon_slider_joint.png diff --git a/tools/editor/icons/icon_slot.png b/editor/icons/icon_slot.png Binary files differindex 856bf72281..856bf72281 100644 --- a/tools/editor/icons/icon_slot.png +++ b/editor/icons/icon_slot.png diff --git a/tools/editor/icons/icon_small_next.png b/editor/icons/icon_small_next.png Binary files differindex f853d100b5..f853d100b5 100644 --- a/tools/editor/icons/icon_small_next.png +++ b/editor/icons/icon_small_next.png diff --git a/tools/editor/icons/icon_snap.png b/editor/icons/icon_snap.png Binary files differindex 93194d34e7..93194d34e7 100644 --- a/tools/editor/icons/icon_snap.png +++ b/editor/icons/icon_snap.png diff --git a/tools/editor/icons/icon_sound_room_params.png b/editor/icons/icon_sound_room_params.png Binary files differindex 6f66da2e43..6f66da2e43 100644 --- a/tools/editor/icons/icon_sound_room_params.png +++ b/editor/icons/icon_sound_room_params.png diff --git a/tools/editor/icons/icon_spatial.png b/editor/icons/icon_spatial.png Binary files differindex 7c9f721053..7c9f721053 100644 --- a/tools/editor/icons/icon_spatial.png +++ b/editor/icons/icon_spatial.png diff --git a/tools/editor/icons/icon_spatial_add.png b/editor/icons/icon_spatial_add.png Binary files differindex 47950fbbb5..47950fbbb5 100644 --- a/tools/editor/icons/icon_spatial_add.png +++ b/editor/icons/icon_spatial_add.png diff --git a/tools/editor/icons/icon_spatial_sample_player.png b/editor/icons/icon_spatial_sample_player.png Binary files differindex bb2451da99..bb2451da99 100644 --- a/tools/editor/icons/icon_spatial_sample_player.png +++ b/editor/icons/icon_spatial_sample_player.png diff --git a/tools/editor/icons/icon_spatial_shader.png b/editor/icons/icon_spatial_shader.png Binary files differindex 7608fc9036..7608fc9036 100644 --- a/tools/editor/icons/icon_spatial_shader.png +++ b/editor/icons/icon_spatial_shader.png diff --git a/tools/editor/icons/icon_spatial_stream_player.png b/editor/icons/icon_spatial_stream_player.png Binary files differindex a6f9851548..a6f9851548 100644 --- a/tools/editor/icons/icon_spatial_stream_player.png +++ b/editor/icons/icon_spatial_stream_player.png diff --git a/tools/editor/icons/icon_sphere_shape.png b/editor/icons/icon_sphere_shape.png Binary files differindex 23300a0da1..23300a0da1 100644 --- a/tools/editor/icons/icon_sphere_shape.png +++ b/editor/icons/icon_sphere_shape.png diff --git a/tools/editor/icons/icon_spin_box.png b/editor/icons/icon_spin_box.png Binary files differindex 6da0dbec79..6da0dbec79 100644 --- a/tools/editor/icons/icon_spin_box.png +++ b/editor/icons/icon_spin_box.png diff --git a/tools/editor/icons/icon_spline.png b/editor/icons/icon_spline.png Binary files differindex 3239aff383..3239aff383 100644 --- a/tools/editor/icons/icon_spline.png +++ b/editor/icons/icon_spline.png diff --git a/tools/editor/icons/icon_spot_light.png b/editor/icons/icon_spot_light.png Binary files differindex f52570a5cd..f52570a5cd 100644 --- a/tools/editor/icons/icon_spot_light.png +++ b/editor/icons/icon_spot_light.png diff --git a/tools/editor/icons/icon_sprite.png b/editor/icons/icon_sprite.png Binary files differindex b698d32d4c..b698d32d4c 100644 --- a/tools/editor/icons/icon_sprite.png +++ b/editor/icons/icon_sprite.png diff --git a/tools/editor/icons/icon_sprite_3d.png b/editor/icons/icon_sprite_3d.png Binary files differindex 47a3ff429b..47a3ff429b 100644 --- a/tools/editor/icons/icon_sprite_3d.png +++ b/editor/icons/icon_sprite_3d.png diff --git a/tools/editor/icons/icon_sprite_frames.png b/editor/icons/icon_sprite_frames.png Binary files differindex 5576b24f2e..5576b24f2e 100644 --- a/tools/editor/icons/icon_sprite_frames.png +++ b/editor/icons/icon_sprite_frames.png diff --git a/tools/editor/icons/icon_squirrel_script.png b/editor/icons/icon_squirrel_script.png Binary files differindex 32926b5975..32926b5975 100644 --- a/tools/editor/icons/icon_squirrel_script.png +++ b/editor/icons/icon_squirrel_script.png diff --git a/tools/editor/icons/icon_static_body.png b/editor/icons/icon_static_body.png Binary files differindex 62948f97cd..62948f97cd 100644 --- a/tools/editor/icons/icon_static_body.png +++ b/editor/icons/icon_static_body.png diff --git a/tools/editor/icons/icon_static_body_2_d.png b/editor/icons/icon_static_body_2_d.png Binary files differindex 9af0274a65..9af0274a65 100644 --- a/tools/editor/icons/icon_static_body_2_d.png +++ b/editor/icons/icon_static_body_2_d.png diff --git a/tools/editor/icons/icon_static_body_2d.png b/editor/icons/icon_static_body_2d.png Binary files differindex b7bad4f742..b7bad4f742 100644 --- a/tools/editor/icons/icon_static_body_2d.png +++ b/editor/icons/icon_static_body_2d.png diff --git a/tools/editor/icons/icon_stop.png b/editor/icons/icon_stop.png Binary files differindex 0fd43b403a..0fd43b403a 100644 --- a/tools/editor/icons/icon_stop.png +++ b/editor/icons/icon_stop.png diff --git a/tools/editor/icons/icon_stream_player.png b/editor/icons/icon_stream_player.png Binary files differindex 15bdbdf440..15bdbdf440 100644 --- a/tools/editor/icons/icon_stream_player.png +++ b/editor/icons/icon_stream_player.png diff --git a/tools/editor/icons/icon_string.png b/editor/icons/icon_string.png Binary files differindex 8d01b738da..8d01b738da 100644 --- a/tools/editor/icons/icon_string.png +++ b/editor/icons/icon_string.png diff --git a/tools/editor/icons/icon_style_box_empty.png b/editor/icons/icon_style_box_empty.png Binary files differindex f595eaaa57..f595eaaa57 100644 --- a/tools/editor/icons/icon_style_box_empty.png +++ b/editor/icons/icon_style_box_empty.png diff --git a/tools/editor/icons/icon_style_box_flat.png b/editor/icons/icon_style_box_flat.png Binary files differindex 6ec6a6dd35..6ec6a6dd35 100644 --- a/tools/editor/icons/icon_style_box_flat.png +++ b/editor/icons/icon_style_box_flat.png diff --git a/tools/editor/icons/icon_style_box_texture.png b/editor/icons/icon_style_box_texture.png Binary files differindex f649508418..f649508418 100644 --- a/tools/editor/icons/icon_style_box_texture.png +++ b/editor/icons/icon_style_box_texture.png diff --git a/tools/editor/icons/icon_surface.png b/editor/icons/icon_surface.png Binary files differindex e7af8e9444..e7af8e9444 100644 --- a/tools/editor/icons/icon_surface.png +++ b/editor/icons/icon_surface.png diff --git a/tools/editor/icons/icon_tab_container.png b/editor/icons/icon_tab_container.png Binary files differindex 7ff3081ec1..7ff3081ec1 100644 --- a/tools/editor/icons/icon_tab_container.png +++ b/editor/icons/icon_tab_container.png diff --git a/tools/editor/icons/icon_tab_menu.png b/editor/icons/icon_tab_menu.png Binary files differindex 29edd02f01..29edd02f01 100644 --- a/tools/editor/icons/icon_tab_menu.png +++ b/editor/icons/icon_tab_menu.png diff --git a/tools/editor/icons/icon_tabs.png b/editor/icons/icon_tabs.png Binary files differindex bef0f60660..bef0f60660 100644 --- a/tools/editor/icons/icon_tabs.png +++ b/editor/icons/icon_tabs.png diff --git a/tools/editor/icons/icon_test_cube.png b/editor/icons/icon_test_cube.png Binary files differindex 4d11a69c3e..4d11a69c3e 100644 --- a/tools/editor/icons/icon_test_cube.png +++ b/editor/icons/icon_test_cube.png diff --git a/tools/editor/icons/icon_text_edit.png b/editor/icons/icon_text_edit.png Binary files differindex 7599e89eb1..7599e89eb1 100644 --- a/tools/editor/icons/icon_text_edit.png +++ b/editor/icons/icon_text_edit.png diff --git a/tools/editor/icons/icon_texture.png b/editor/icons/icon_texture.png Binary files differindex 7c4493395e..7c4493395e 100644 --- a/tools/editor/icons/icon_texture.png +++ b/editor/icons/icon_texture.png diff --git a/tools/editor/icons/icon_texture_button.png b/editor/icons/icon_texture_button.png Binary files differindex ea1d8235e1..ea1d8235e1 100644 --- a/tools/editor/icons/icon_texture_button.png +++ b/editor/icons/icon_texture_button.png diff --git a/tools/editor/icons/icon_texture_progress.png b/editor/icons/icon_texture_progress.png Binary files differindex ea3cc35da8..ea3cc35da8 100644 --- a/tools/editor/icons/icon_texture_progress.png +++ b/editor/icons/icon_texture_progress.png diff --git a/tools/editor/icons/icon_texture_rect.png b/editor/icons/icon_texture_rect.png Binary files differindex 84e4a90bfb..84e4a90bfb 100644 --- a/tools/editor/icons/icon_texture_rect.png +++ b/editor/icons/icon_texture_rect.png diff --git a/tools/editor/icons/icon_theme.png b/editor/icons/icon_theme.png Binary files differindex 55d799c722..55d799c722 100644 --- a/tools/editor/icons/icon_theme.png +++ b/editor/icons/icon_theme.png diff --git a/tools/editor/icons/icon_thumbnail_wait.png b/editor/icons/icon_thumbnail_wait.png Binary files differindex 96a7d424e3..96a7d424e3 100644 --- a/tools/editor/icons/icon_thumbnail_wait.png +++ b/editor/icons/icon_thumbnail_wait.png diff --git a/tools/editor/icons/icon_tile_map.png b/editor/icons/icon_tile_map.png Binary files differindex 0ba6276e25..0ba6276e25 100644 --- a/tools/editor/icons/icon_tile_map.png +++ b/editor/icons/icon_tile_map.png diff --git a/tools/editor/icons/icon_tile_set.png b/editor/icons/icon_tile_set.png Binary files differindex a1c3fccddd..a1c3fccddd 100644 --- a/tools/editor/icons/icon_tile_set.png +++ b/editor/icons/icon_tile_set.png diff --git a/tools/editor/icons/icon_time.png b/editor/icons/icon_time.png Binary files differindex a8e97ea7b8..a8e97ea7b8 100644 --- a/tools/editor/icons/icon_time.png +++ b/editor/icons/icon_time.png diff --git a/tools/editor/icons/icon_timer.png b/editor/icons/icon_timer.png Binary files differindex d3eb6a4b49..d3eb6a4b49 100644 --- a/tools/editor/icons/icon_timer.png +++ b/editor/icons/icon_timer.png diff --git a/tools/editor/icons/icon_tool_button.png b/editor/icons/icon_tool_button.png Binary files differindex b2f3f6103f..b2f3f6103f 100644 --- a/tools/editor/icons/icon_tool_button.png +++ b/editor/icons/icon_tool_button.png diff --git a/tools/editor/icons/icon_tool_move.png b/editor/icons/icon_tool_move.png Binary files differindex 2b6984e8b2..2b6984e8b2 100644 --- a/tools/editor/icons/icon_tool_move.png +++ b/editor/icons/icon_tool_move.png diff --git a/tools/editor/icons/icon_tool_pan.png b/editor/icons/icon_tool_pan.png Binary files differindex a24545a6d4..a24545a6d4 100644 --- a/tools/editor/icons/icon_tool_pan.png +++ b/editor/icons/icon_tool_pan.png diff --git a/tools/editor/icons/icon_tool_rotate.png b/editor/icons/icon_tool_rotate.png Binary files differindex 9303fabb9c..9303fabb9c 100644 --- a/tools/editor/icons/icon_tool_rotate.png +++ b/editor/icons/icon_tool_rotate.png diff --git a/tools/editor/icons/icon_tool_scale.png b/editor/icons/icon_tool_scale.png Binary files differindex b389c40746..b389c40746 100644 --- a/tools/editor/icons/icon_tool_scale.png +++ b/editor/icons/icon_tool_scale.png diff --git a/tools/editor/icons/icon_tool_select.png b/editor/icons/icon_tool_select.png Binary files differindex dcf6fcd2c8..dcf6fcd2c8 100644 --- a/tools/editor/icons/icon_tool_select.png +++ b/editor/icons/icon_tool_select.png diff --git a/tools/editor/icons/icon_tools.png b/editor/icons/icon_tools.png Binary files differindex 4db4c53796..4db4c53796 100644 --- a/tools/editor/icons/icon_tools.png +++ b/editor/icons/icon_tools.png diff --git a/tools/editor/icons/icon_touch_screen_button.png b/editor/icons/icon_touch_screen_button.png Binary files differindex 6bd0af3f47..6bd0af3f47 100644 --- a/tools/editor/icons/icon_touch_screen_button.png +++ b/editor/icons/icon_touch_screen_button.png diff --git a/tools/editor/icons/icon_track_add_key.png b/editor/icons/icon_track_add_key.png Binary files differindex 02d92439a3..02d92439a3 100644 --- a/tools/editor/icons/icon_track_add_key.png +++ b/editor/icons/icon_track_add_key.png diff --git a/tools/editor/icons/icon_track_add_key_hl.png b/editor/icons/icon_track_add_key_hl.png Binary files differindex 0e857f5fe2..0e857f5fe2 100644 --- a/tools/editor/icons/icon_track_add_key_hl.png +++ b/editor/icons/icon_track_add_key_hl.png diff --git a/tools/editor/icons/icon_track_continuous.png b/editor/icons/icon_track_continuous.png Binary files differindex dabdc718d5..dabdc718d5 100644 --- a/tools/editor/icons/icon_track_continuous.png +++ b/editor/icons/icon_track_continuous.png diff --git a/tools/editor/icons/icon_track_discrete.png b/editor/icons/icon_track_discrete.png Binary files differindex 3f580ac5fc..3f580ac5fc 100644 --- a/tools/editor/icons/icon_track_discrete.png +++ b/editor/icons/icon_track_discrete.png diff --git a/tools/editor/icons/icon_track_method.png b/editor/icons/icon_track_method.png Binary files differindex 1355c84e67..1355c84e67 100644 --- a/tools/editor/icons/icon_track_method.png +++ b/editor/icons/icon_track_method.png diff --git a/tools/editor/icons/icon_track_prop.png b/editor/icons/icon_track_prop.png Binary files differindex de8f549cd2..de8f549cd2 100644 --- a/tools/editor/icons/icon_track_prop.png +++ b/editor/icons/icon_track_prop.png diff --git a/tools/editor/icons/icon_track_trigger.png b/editor/icons/icon_track_trigger.png Binary files differindex e89f95561a..e89f95561a 100644 --- a/tools/editor/icons/icon_track_trigger.png +++ b/editor/icons/icon_track_trigger.png diff --git a/tools/editor/icons/icon_track_value.png b/editor/icons/icon_track_value.png Binary files differindex 5f5dc0d315..5f5dc0d315 100644 --- a/tools/editor/icons/icon_track_value.png +++ b/editor/icons/icon_track_value.png diff --git a/tools/editor/icons/icon_translation.png b/editor/icons/icon_translation.png Binary files differindex abca359eea..abca359eea 100644 --- a/tools/editor/icons/icon_translation.png +++ b/editor/icons/icon_translation.png diff --git a/tools/editor/icons/icon_transparent.png b/editor/icons/icon_transparent.png Binary files differindex 07e9b52b5c..07e9b52b5c 100644 --- a/tools/editor/icons/icon_transparent.png +++ b/editor/icons/icon_transparent.png diff --git a/tools/editor/icons/icon_transpose.png b/editor/icons/icon_transpose.png Binary files differindex 7a126c8428..7a126c8428 100644 --- a/tools/editor/icons/icon_transpose.png +++ b/editor/icons/icon_transpose.png diff --git a/tools/editor/icons/icon_tree.png b/editor/icons/icon_tree.png Binary files differindex 50ec1df98b..50ec1df98b 100644 --- a/tools/editor/icons/icon_tree.png +++ b/editor/icons/icon_tree.png diff --git a/tools/editor/icons/icon_tween.png b/editor/icons/icon_tween.png Binary files differindex 36717c0922..36717c0922 100644 --- a/tools/editor/icons/icon_tween.png +++ b/editor/icons/icon_tween.png diff --git a/tools/editor/icons/icon_unbone.png b/editor/icons/icon_unbone.png Binary files differindex 919e13ad6b..919e13ad6b 100644 --- a/tools/editor/icons/icon_unbone.png +++ b/editor/icons/icon_unbone.png diff --git a/tools/editor/icons/icon_ungroup.png b/editor/icons/icon_ungroup.png Binary files differindex b4c2e01814..b4c2e01814 100644 --- a/tools/editor/icons/icon_ungroup.png +++ b/editor/icons/icon_ungroup.png diff --git a/tools/editor/icons/icon_uninstance.png b/editor/icons/icon_uninstance.png Binary files differindex de8b2f9a40..de8b2f9a40 100644 --- a/tools/editor/icons/icon_uninstance.png +++ b/editor/icons/icon_uninstance.png diff --git a/tools/editor/icons/icon_unlock.png b/editor/icons/icon_unlock.png Binary files differindex d314aa46fe..d314aa46fe 100644 --- a/tools/editor/icons/icon_unlock.png +++ b/editor/icons/icon_unlock.png diff --git a/tools/editor/icons/icon_up.png b/editor/icons/icon_up.png Binary files differindex 346c4cdba8..346c4cdba8 100644 --- a/tools/editor/icons/icon_up.png +++ b/editor/icons/icon_up.png diff --git a/tools/editor/icons/icon_updown.png b/editor/icons/icon_updown.png Binary files differindex 3141dc56ae..3141dc56ae 100644 --- a/tools/editor/icons/icon_updown.png +++ b/editor/icons/icon_updown.png diff --git a/tools/editor/icons/icon_uv.png b/editor/icons/icon_uv.png Binary files differindex f5d901ab91..f5d901ab91 100644 --- a/tools/editor/icons/icon_uv.png +++ b/editor/icons/icon_uv.png diff --git a/tools/editor/icons/icon_v_box_container.png b/editor/icons/icon_v_box_container.png Binary files differindex 4d9bdb67b8..4d9bdb67b8 100644 --- a/tools/editor/icons/icon_v_box_container.png +++ b/editor/icons/icon_v_box_container.png diff --git a/tools/editor/icons/icon_v_button_array.png b/editor/icons/icon_v_button_array.png Binary files differindex d7ea9cc375..d7ea9cc375 100644 --- a/tools/editor/icons/icon_v_button_array.png +++ b/editor/icons/icon_v_button_array.png diff --git a/tools/editor/icons/icon_v_scroll_bar.png b/editor/icons/icon_v_scroll_bar.png Binary files differindex 91e00f4619..91e00f4619 100644 --- a/tools/editor/icons/icon_v_scroll_bar.png +++ b/editor/icons/icon_v_scroll_bar.png diff --git a/tools/editor/icons/icon_v_separator.png b/editor/icons/icon_v_separator.png Binary files differindex f0122d197f..f0122d197f 100644 --- a/tools/editor/icons/icon_v_separator.png +++ b/editor/icons/icon_v_separator.png diff --git a/tools/editor/icons/icon_v_slider.png b/editor/icons/icon_v_slider.png Binary files differindex 545c126d23..545c126d23 100644 --- a/tools/editor/icons/icon_v_slider.png +++ b/editor/icons/icon_v_slider.png diff --git a/tools/editor/icons/icon_v_split_container.png b/editor/icons/icon_v_split_container.png Binary files differindex 23093e334f..23093e334f 100644 --- a/tools/editor/icons/icon_v_split_container.png +++ b/editor/icons/icon_v_split_container.png diff --git a/tools/editor/icons/icon_variant.png b/editor/icons/icon_variant.png Binary files differindex 1ae2812ff7..1ae2812ff7 100644 --- a/tools/editor/icons/icon_variant.png +++ b/editor/icons/icon_variant.png diff --git a/tools/editor/icons/icon_vector.png b/editor/icons/icon_vector.png Binary files differindex 8dba948daf..8dba948daf 100644 --- a/tools/editor/icons/icon_vector.png +++ b/editor/icons/icon_vector.png diff --git a/tools/editor/icons/icon_vector2.png b/editor/icons/icon_vector2.png Binary files differindex f84052cda0..f84052cda0 100644 --- a/tools/editor/icons/icon_vector2.png +++ b/editor/icons/icon_vector2.png diff --git a/tools/editor/icons/icon_vehicle_body.png b/editor/icons/icon_vehicle_body.png Binary files differindex c404218911..c404218911 100644 --- a/tools/editor/icons/icon_vehicle_body.png +++ b/editor/icons/icon_vehicle_body.png diff --git a/tools/editor/icons/icon_vehicle_wheel.png b/editor/icons/icon_vehicle_wheel.png Binary files differindex 23299a0425..23299a0425 100644 --- a/tools/editor/icons/icon_vehicle_wheel.png +++ b/editor/icons/icon_vehicle_wheel.png diff --git a/tools/editor/icons/icon_video_player.png b/editor/icons/icon_video_player.png Binary files differindex 5fd3723b22..5fd3723b22 100644 --- a/tools/editor/icons/icon_video_player.png +++ b/editor/icons/icon_video_player.png diff --git a/tools/editor/icons/icon_video_stream_theora.png b/editor/icons/icon_video_stream_theora.png Binary files differindex 3f019f9b61..3f019f9b61 100644 --- a/tools/editor/icons/icon_video_stream_theora.png +++ b/editor/icons/icon_video_stream_theora.png diff --git a/tools/editor/icons/icon_view.png b/editor/icons/icon_view.png Binary files differindex c7975ed461..c7975ed461 100644 --- a/tools/editor/icons/icon_view.png +++ b/editor/icons/icon_view.png diff --git a/tools/editor/icons/icon_viewport.png b/editor/icons/icon_viewport.png Binary files differindex 8b25ea8764..8b25ea8764 100644 --- a/tools/editor/icons/icon_viewport.png +++ b/editor/icons/icon_viewport.png diff --git a/tools/editor/icons/icon_viewport_container.png b/editor/icons/icon_viewport_container.png Binary files differindex c70dee3698..c70dee3698 100644 --- a/tools/editor/icons/icon_viewport_container.png +++ b/editor/icons/icon_viewport_container.png diff --git a/tools/editor/icons/icon_viewport_sprite.png b/editor/icons/icon_viewport_sprite.png Binary files differindex 9aefb471d6..9aefb471d6 100644 --- a/tools/editor/icons/icon_viewport_sprite.png +++ b/editor/icons/icon_viewport_sprite.png diff --git a/tools/editor/icons/icon_viewport_texture.png b/editor/icons/icon_viewport_texture.png Binary files differindex ae744cc407..ae744cc407 100644 --- a/tools/editor/icons/icon_viewport_texture.png +++ b/editor/icons/icon_viewport_texture.png diff --git a/tools/editor/icons/icon_visibility_area.png b/editor/icons/icon_visibility_area.png Binary files differindex f3ca05711b..f3ca05711b 100644 --- a/tools/editor/icons/icon_visibility_area.png +++ b/editor/icons/icon_visibility_area.png diff --git a/tools/editor/icons/icon_visibility_enabler.png b/editor/icons/icon_visibility_enabler.png Binary files differindex 66dffd3483..66dffd3483 100644 --- a/tools/editor/icons/icon_visibility_enabler.png +++ b/editor/icons/icon_visibility_enabler.png diff --git a/tools/editor/icons/icon_visibility_enabler_2d.png b/editor/icons/icon_visibility_enabler_2d.png Binary files differindex e198b9785b..e198b9785b 100644 --- a/tools/editor/icons/icon_visibility_enabler_2d.png +++ b/editor/icons/icon_visibility_enabler_2d.png diff --git a/tools/editor/icons/icon_visibility_notifier.png b/editor/icons/icon_visibility_notifier.png Binary files differindex 624122fb4c..624122fb4c 100644 --- a/tools/editor/icons/icon_visibility_notifier.png +++ b/editor/icons/icon_visibility_notifier.png diff --git a/tools/editor/icons/icon_visibility_notifier_2d.png b/editor/icons/icon_visibility_notifier_2d.png Binary files differindex f904223edf..f904223edf 100644 --- a/tools/editor/icons/icon_visibility_notifier_2d.png +++ b/editor/icons/icon_visibility_notifier_2d.png diff --git a/tools/editor/icons/icon_visible.png b/editor/icons/icon_visible.png Binary files differindex 4e79dd3245..4e79dd3245 100644 --- a/tools/editor/icons/icon_visible.png +++ b/editor/icons/icon_visible.png diff --git a/tools/editor/icons/icon_visual_script.png b/editor/icons/icon_visual_script.png Binary files differindex 1678998d17..1678998d17 100644 --- a/tools/editor/icons/icon_visual_script.png +++ b/editor/icons/icon_visual_script.png diff --git a/tools/editor/icons/icon_visual_shader_port.png b/editor/icons/icon_visual_shader_port.png Binary files differindex 27daedbdd0..27daedbdd0 100644 --- a/tools/editor/icons/icon_visual_shader_port.png +++ b/editor/icons/icon_visual_shader_port.png diff --git a/tools/editor/icons/icon_volume.png b/editor/icons/icon_volume.png Binary files differindex 2ce013cb03..2ce013cb03 100644 --- a/tools/editor/icons/icon_volume.png +++ b/editor/icons/icon_volume.png diff --git a/tools/editor/icons/icon_vu_db.png b/editor/icons/icon_vu_db.png Binary files differindex 405a929e2a..405a929e2a 100644 --- a/tools/editor/icons/icon_vu_db.png +++ b/editor/icons/icon_vu_db.png diff --git a/tools/editor/icons/icon_vu_empty.png b/editor/icons/icon_vu_empty.png Binary files differindex b749e1f2ca..b749e1f2ca 100644 --- a/tools/editor/icons/icon_vu_empty.png +++ b/editor/icons/icon_vu_empty.png diff --git a/tools/editor/icons/icon_vu_full.png b/editor/icons/icon_vu_full.png Binary files differindex cb2b30d397..cb2b30d397 100644 --- a/tools/editor/icons/icon_vu_full.png +++ b/editor/icons/icon_vu_full.png diff --git a/tools/editor/icons/icon_wait_no_preview.png b/editor/icons/icon_wait_no_preview.png Binary files differindex 5d20cd99ec..5d20cd99ec 100644 --- a/tools/editor/icons/icon_wait_no_preview.png +++ b/editor/icons/icon_wait_no_preview.png diff --git a/tools/editor/icons/icon_wait_preview_1.png b/editor/icons/icon_wait_preview_1.png Binary files differindex 0aab42e04a..0aab42e04a 100644 --- a/tools/editor/icons/icon_wait_preview_1.png +++ b/editor/icons/icon_wait_preview_1.png diff --git a/tools/editor/icons/icon_wait_preview_2.png b/editor/icons/icon_wait_preview_2.png Binary files differindex f476b9ce1f..f476b9ce1f 100644 --- a/tools/editor/icons/icon_wait_preview_2.png +++ b/editor/icons/icon_wait_preview_2.png diff --git a/tools/editor/icons/icon_wait_preview_3.png b/editor/icons/icon_wait_preview_3.png Binary files differindex 2775d1ef43..2775d1ef43 100644 --- a/tools/editor/icons/icon_wait_preview_3.png +++ b/editor/icons/icon_wait_preview_3.png diff --git a/tools/editor/icons/icon_wait_preview_4.png b/editor/icons/icon_wait_preview_4.png Binary files differindex 2eaa86fec9..2eaa86fec9 100644 --- a/tools/editor/icons/icon_wait_preview_4.png +++ b/editor/icons/icon_wait_preview_4.png diff --git a/tools/editor/icons/icon_wait_preview_5.png b/editor/icons/icon_wait_preview_5.png Binary files differindex 6590644bc1..6590644bc1 100644 --- a/tools/editor/icons/icon_wait_preview_5.png +++ b/editor/icons/icon_wait_preview_5.png diff --git a/tools/editor/icons/icon_wait_preview_6.png b/editor/icons/icon_wait_preview_6.png Binary files differindex 307e412310..307e412310 100644 --- a/tools/editor/icons/icon_wait_preview_6.png +++ b/editor/icons/icon_wait_preview_6.png diff --git a/tools/editor/icons/icon_wait_preview_7.png b/editor/icons/icon_wait_preview_7.png Binary files differindex b0edc94d93..b0edc94d93 100644 --- a/tools/editor/icons/icon_wait_preview_7.png +++ b/editor/icons/icon_wait_preview_7.png diff --git a/tools/editor/icons/icon_wait_preview_8.png b/editor/icons/icon_wait_preview_8.png Binary files differindex 67a2f48ec3..67a2f48ec3 100644 --- a/tools/editor/icons/icon_wait_preview_8.png +++ b/editor/icons/icon_wait_preview_8.png diff --git a/tools/editor/icons/icon_warning.png b/editor/icons/icon_warning.png Binary files differindex 451beba820..451beba820 100644 --- a/tools/editor/icons/icon_warning.png +++ b/editor/icons/icon_warning.png diff --git a/tools/editor/icons/icon_window_dialog.png b/editor/icons/icon_window_dialog.png Binary files differindex 8591b15613..8591b15613 100644 --- a/tools/editor/icons/icon_window_dialog.png +++ b/editor/icons/icon_window_dialog.png diff --git a/tools/editor/icons/icon_world.png b/editor/icons/icon_world.png Binary files differindex d54b979cad..d54b979cad 100644 --- a/tools/editor/icons/icon_world.png +++ b/editor/icons/icon_world.png diff --git a/tools/editor/icons/icon_world_2d.png b/editor/icons/icon_world_2d.png Binary files differindex ebe54262ff..ebe54262ff 100644 --- a/tools/editor/icons/icon_world_2d.png +++ b/editor/icons/icon_world_2d.png diff --git a/tools/editor/icons/icon_world_environment.png b/editor/icons/icon_world_environment.png Binary files differindex d9f1323386..d9f1323386 100644 --- a/tools/editor/icons/icon_world_environment.png +++ b/editor/icons/icon_world_environment.png diff --git a/tools/editor/icons/icon_y_sort.png b/editor/icons/icon_y_sort.png Binary files differindex 585956983c..585956983c 100644 --- a/tools/editor/icons/icon_y_sort.png +++ b/editor/icons/icon_y_sort.png diff --git a/tools/editor/icons/icon_zoom.png b/editor/icons/icon_zoom.png Binary files differindex f3748803cf..f3748803cf 100644 --- a/tools/editor/icons/icon_zoom.png +++ b/editor/icons/icon_zoom.png diff --git a/tools/editor/icons/icon_zoom_less.png b/editor/icons/icon_zoom_less.png Binary files differindex fd8ef9075e..fd8ef9075e 100644 --- a/tools/editor/icons/icon_zoom_less.png +++ b/editor/icons/icon_zoom_less.png diff --git a/tools/editor/icons/icon_zoom_more.png b/editor/icons/icon_zoom_more.png Binary files differindex 8e818db1ee..8e818db1ee 100644 --- a/tools/editor/icons/icon_zoom_more.png +++ b/editor/icons/icon_zoom_more.png diff --git a/tools/editor/icons/icon_zoom_reset.png b/editor/icons/icon_zoom_reset.png Binary files differindex fa8a9d197e..fa8a9d197e 100644 --- a/tools/editor/icons/icon_zoom_reset.png +++ b/editor/icons/icon_zoom_reset.png diff --git a/tools/editor/icons/source/icon_accept_dialog.svg b/editor/icons/source/icon_accept_dialog.svg index 9f82b30c94..9f82b30c94 100644 --- a/tools/editor/icons/source/icon_accept_dialog.svg +++ b/editor/icons/source/icon_accept_dialog.svg diff --git a/tools/editor/icons/source/icon_add_track.svg b/editor/icons/source/icon_add_track.svg index d19448efb0..d19448efb0 100644 --- a/tools/editor/icons/source/icon_add_track.svg +++ b/editor/icons/source/icon_add_track.svg diff --git a/tools/editor/icons/source/icon_anchor.svg b/editor/icons/source/icon_anchor.svg index 6b10be040b..6b10be040b 100644 --- a/tools/editor/icons/source/icon_anchor.svg +++ b/editor/icons/source/icon_anchor.svg diff --git a/tools/editor/icons/source/icon_animated_sprite.svg b/editor/icons/source/icon_animated_sprite.svg index 36ccd8bca2..36ccd8bca2 100644 --- a/tools/editor/icons/source/icon_animated_sprite.svg +++ b/editor/icons/source/icon_animated_sprite.svg diff --git a/tools/editor/icons/source/icon_animated_sprite_3d.svg b/editor/icons/source/icon_animated_sprite_3d.svg index f088c9e32d..f088c9e32d 100644 --- a/tools/editor/icons/source/icon_animated_sprite_3d.svg +++ b/editor/icons/source/icon_animated_sprite_3d.svg diff --git a/tools/editor/icons/source/icon_animation.svg b/editor/icons/source/icon_animation.svg index 371979345f..371979345f 100644 --- a/tools/editor/icons/source/icon_animation.svg +++ b/editor/icons/source/icon_animation.svg diff --git a/tools/editor/icons/source/icon_animation_player.svg b/editor/icons/source/icon_animation_player.svg index add4d5ac42..add4d5ac42 100644 --- a/tools/editor/icons/source/icon_animation_player.svg +++ b/editor/icons/source/icon_animation_player.svg diff --git a/tools/editor/icons/source/icon_animation_tree_player.svg b/editor/icons/source/icon_animation_tree_player.svg index ab81cb226a..ab81cb226a 100644 --- a/tools/editor/icons/source/icon_animation_tree_player.svg +++ b/editor/icons/source/icon_animation_tree_player.svg diff --git a/tools/editor/icons/source/icon_area.svg b/editor/icons/source/icon_area.svg index d16ad26e23..d16ad26e23 100644 --- a/tools/editor/icons/source/icon_area.svg +++ b/editor/icons/source/icon_area.svg diff --git a/tools/editor/icons/source/icon_area_2d.svg b/editor/icons/source/icon_area_2d.svg index ef7b16dd06..ef7b16dd06 100644 --- a/tools/editor/icons/source/icon_area_2d.svg +++ b/editor/icons/source/icon_area_2d.svg diff --git a/tools/editor/icons/source/icon_arrow_left.svg b/editor/icons/source/icon_arrow_left.svg index 75a9ef0d68..75a9ef0d68 100644 --- a/tools/editor/icons/source/icon_arrow_left.svg +++ b/editor/icons/source/icon_arrow_left.svg diff --git a/tools/editor/icons/source/icon_arrow_right.svg b/editor/icons/source/icon_arrow_right.svg index a7600699f7..a7600699f7 100644 --- a/tools/editor/icons/source/icon_arrow_right.svg +++ b/editor/icons/source/icon_arrow_right.svg diff --git a/tools/editor/icons/source/icon_arrow_up.svg b/editor/icons/source/icon_arrow_up.svg index c1839cd69e..c1839cd69e 100644 --- a/tools/editor/icons/source/icon_arrow_up.svg +++ b/editor/icons/source/icon_arrow_up.svg diff --git a/tools/editor/icons/source/icon_atlas_texture.svg b/editor/icons/source/icon_atlas_texture.svg index 10c8b745b6..10c8b745b6 100644 --- a/tools/editor/icons/source/icon_atlas_texture.svg +++ b/editor/icons/source/icon_atlas_texture.svg diff --git a/tools/editor/icons/source/icon_audio_stream_gibberish.svg b/editor/icons/source/icon_audio_stream_gibberish.svg index 82b48c7004..82b48c7004 100644 --- a/tools/editor/icons/source/icon_audio_stream_gibberish.svg +++ b/editor/icons/source/icon_audio_stream_gibberish.svg diff --git a/tools/editor/icons/source/icon_auto_play.svg b/editor/icons/source/icon_auto_play.svg index d4e1068ebf..d4e1068ebf 100644 --- a/tools/editor/icons/source/icon_auto_play.svg +++ b/editor/icons/source/icon_auto_play.svg diff --git a/tools/editor/icons/source/icon_back.svg b/editor/icons/source/icon_back.svg index 597a1c3068..597a1c3068 100644 --- a/tools/editor/icons/source/icon_back.svg +++ b/editor/icons/source/icon_back.svg diff --git a/tools/editor/icons/source/icon_back_buffer_copy.svg b/editor/icons/source/icon_back_buffer_copy.svg index 17d83ed73f..17d83ed73f 100644 --- a/tools/editor/icons/source/icon_back_buffer_copy.svg +++ b/editor/icons/source/icon_back_buffer_copy.svg diff --git a/tools/editor/icons/source/icon_bake.svg b/editor/icons/source/icon_bake.svg index ca07bca379..ca07bca379 100644 --- a/tools/editor/icons/source/icon_bake.svg +++ b/editor/icons/source/icon_bake.svg diff --git a/tools/editor/icons/source/icon_baked_light.svg b/editor/icons/source/icon_baked_light.svg index 98dc3135f6..98dc3135f6 100644 --- a/tools/editor/icons/source/icon_baked_light.svg +++ b/editor/icons/source/icon_baked_light.svg diff --git a/tools/editor/icons/source/icon_baked_light_instance.svg b/editor/icons/source/icon_baked_light_instance.svg index d854378f12..d854378f12 100644 --- a/tools/editor/icons/source/icon_baked_light_instance.svg +++ b/editor/icons/source/icon_baked_light_instance.svg diff --git a/tools/editor/icons/source/icon_baked_light_sampler.svg b/editor/icons/source/icon_baked_light_sampler.svg index 2dc7c39621..2dc7c39621 100644 --- a/tools/editor/icons/source/icon_baked_light_sampler.svg +++ b/editor/icons/source/icon_baked_light_sampler.svg diff --git a/tools/editor/icons/source/icon_bit_map.svg b/editor/icons/source/icon_bit_map.svg index fbaf573af6..fbaf573af6 100644 --- a/tools/editor/icons/source/icon_bit_map.svg +++ b/editor/icons/source/icon_bit_map.svg diff --git a/tools/editor/icons/source/icon_bitmap_font.svg b/editor/icons/source/icon_bitmap_font.svg index 70749923d5..70749923d5 100644 --- a/tools/editor/icons/source/icon_bitmap_font.svg +++ b/editor/icons/source/icon_bitmap_font.svg diff --git a/tools/editor/icons/source/icon_blend.svg b/editor/icons/source/icon_blend.svg index 64d2aeec83..64d2aeec83 100644 --- a/tools/editor/icons/source/icon_blend.svg +++ b/editor/icons/source/icon_blend.svg diff --git a/tools/editor/icons/source/icon_bone.svg b/editor/icons/source/icon_bone.svg index c87902a336..c87902a336 100644 --- a/tools/editor/icons/source/icon_bone.svg +++ b/editor/icons/source/icon_bone.svg diff --git a/tools/editor/icons/source/icon_bone_attachment.svg b/editor/icons/source/icon_bone_attachment.svg index 5cb85c3c17..5cb85c3c17 100644 --- a/tools/editor/icons/source/icon_bone_attachment.svg +++ b/editor/icons/source/icon_bone_attachment.svg diff --git a/tools/editor/icons/source/icon_bone_track.svg b/editor/icons/source/icon_bone_track.svg index cdaab7e34a..cdaab7e34a 100644 --- a/tools/editor/icons/source/icon_bone_track.svg +++ b/editor/icons/source/icon_bone_track.svg diff --git a/tools/editor/icons/source/icon_bool.svg b/editor/icons/source/icon_bool.svg index e471871adf..e471871adf 100644 --- a/tools/editor/icons/source/icon_bool.svg +++ b/editor/icons/source/icon_bool.svg diff --git a/tools/editor/icons/source/icon_box_shape.svg b/editor/icons/source/icon_box_shape.svg index 04aaf16ebc..04aaf16ebc 100644 --- a/tools/editor/icons/source/icon_box_shape.svg +++ b/editor/icons/source/icon_box_shape.svg diff --git a/tools/editor/icons/source/icon_button.svg b/editor/icons/source/icon_button.svg index 54644ecb9b..54644ecb9b 100644 --- a/tools/editor/icons/source/icon_button.svg +++ b/editor/icons/source/icon_button.svg diff --git a/tools/editor/icons/source/icon_button_group.svg b/editor/icons/source/icon_button_group.svg index 9d5df99deb..9d5df99deb 100644 --- a/tools/editor/icons/source/icon_button_group.svg +++ b/editor/icons/source/icon_button_group.svg diff --git a/tools/editor/icons/source/icon_camera.svg b/editor/icons/source/icon_camera.svg index 55d4aa698d..55d4aa698d 100644 --- a/tools/editor/icons/source/icon_camera.svg +++ b/editor/icons/source/icon_camera.svg diff --git a/tools/editor/icons/source/icon_camera_2d.svg b/editor/icons/source/icon_camera_2d.svg index 1be8c0f984..1be8c0f984 100644 --- a/tools/editor/icons/source/icon_camera_2d.svg +++ b/editor/icons/source/icon_camera_2d.svg diff --git a/tools/editor/icons/source/icon_canvas_item.svg b/editor/icons/source/icon_canvas_item.svg index d15a9a71b7..d15a9a71b7 100644 --- a/tools/editor/icons/source/icon_canvas_item.svg +++ b/editor/icons/source/icon_canvas_item.svg diff --git a/tools/editor/icons/source/icon_canvas_item_material.svg b/editor/icons/source/icon_canvas_item_material.svg index ce8fd4b7de..ce8fd4b7de 100644 --- a/tools/editor/icons/source/icon_canvas_item_material.svg +++ b/editor/icons/source/icon_canvas_item_material.svg diff --git a/tools/editor/icons/source/icon_canvas_item_shader.svg b/editor/icons/source/icon_canvas_item_shader.svg index 6d1d7e6bb1..6d1d7e6bb1 100644 --- a/tools/editor/icons/source/icon_canvas_item_shader.svg +++ b/editor/icons/source/icon_canvas_item_shader.svg diff --git a/tools/editor/icons/source/icon_canvas_item_shader_graph.svg b/editor/icons/source/icon_canvas_item_shader_graph.svg index 84575ad388..84575ad388 100644 --- a/tools/editor/icons/source/icon_canvas_item_shader_graph.svg +++ b/editor/icons/source/icon_canvas_item_shader_graph.svg diff --git a/tools/editor/icons/source/icon_canvas_layer.svg b/editor/icons/source/icon_canvas_layer.svg index 794d832eea..794d832eea 100644 --- a/tools/editor/icons/source/icon_canvas_layer.svg +++ b/editor/icons/source/icon_canvas_layer.svg diff --git a/tools/editor/icons/source/icon_canvas_modulate.svg b/editor/icons/source/icon_canvas_modulate.svg index 8f8bd55f82..8f8bd55f82 100644 --- a/tools/editor/icons/source/icon_canvas_modulate.svg +++ b/editor/icons/source/icon_canvas_modulate.svg diff --git a/tools/editor/icons/source/icon_capsule_shape.svg b/editor/icons/source/icon_capsule_shape.svg index dcc6e8c00f..dcc6e8c00f 100644 --- a/tools/editor/icons/source/icon_capsule_shape.svg +++ b/editor/icons/source/icon_capsule_shape.svg diff --git a/tools/editor/icons/source/icon_capsule_shape_2d.svg b/editor/icons/source/icon_capsule_shape_2d.svg index 13c6648368..13c6648368 100644 --- a/tools/editor/icons/source/icon_capsule_shape_2d.svg +++ b/editor/icons/source/icon_capsule_shape_2d.svg diff --git a/tools/editor/icons/source/icon_center_container.svg b/editor/icons/source/icon_center_container.svg index 31262f8494..31262f8494 100644 --- a/tools/editor/icons/source/icon_center_container.svg +++ b/editor/icons/source/icon_center_container.svg diff --git a/tools/editor/icons/source/icon_check_box.svg b/editor/icons/source/icon_check_box.svg index 1068b424bd..1068b424bd 100644 --- a/tools/editor/icons/source/icon_check_box.svg +++ b/editor/icons/source/icon_check_box.svg diff --git a/tools/editor/icons/source/icon_check_button.svg b/editor/icons/source/icon_check_button.svg index 1dddc7bf43..1dddc7bf43 100644 --- a/tools/editor/icons/source/icon_check_button.svg +++ b/editor/icons/source/icon_check_button.svg diff --git a/tools/editor/icons/source/icon_circle_shape_2d.svg b/editor/icons/source/icon_circle_shape_2d.svg index 56ac538672..56ac538672 100644 --- a/tools/editor/icons/source/icon_circle_shape_2d.svg +++ b/editor/icons/source/icon_circle_shape_2d.svg diff --git a/tools/editor/icons/source/icon_class_list.svg b/editor/icons/source/icon_class_list.svg index 326174e566..326174e566 100644 --- a/tools/editor/icons/source/icon_class_list.svg +++ b/editor/icons/source/icon_class_list.svg diff --git a/tools/editor/icons/source/icon_close.svg b/editor/icons/source/icon_close.svg index 65b71ae860..65b71ae860 100644 --- a/tools/editor/icons/source/icon_close.svg +++ b/editor/icons/source/icon_close.svg diff --git a/tools/editor/icons/source/icon_collapse.svg b/editor/icons/source/icon_collapse.svg index a1c55e92de..a1c55e92de 100644 --- a/tools/editor/icons/source/icon_collapse.svg +++ b/editor/icons/source/icon_collapse.svg diff --git a/tools/editor/icons/source/icon_collision_2d.svg b/editor/icons/source/icon_collision_2d.svg index 29905795bd..29905795bd 100644 --- a/tools/editor/icons/source/icon_collision_2d.svg +++ b/editor/icons/source/icon_collision_2d.svg diff --git a/tools/editor/icons/source/icon_collision_polygon.svg b/editor/icons/source/icon_collision_polygon.svg index 41f20abb5f..41f20abb5f 100644 --- a/tools/editor/icons/source/icon_collision_polygon.svg +++ b/editor/icons/source/icon_collision_polygon.svg diff --git a/tools/editor/icons/source/icon_collision_shape.svg b/editor/icons/source/icon_collision_shape.svg index 066e3bc0fd..066e3bc0fd 100644 --- a/tools/editor/icons/source/icon_collision_shape.svg +++ b/editor/icons/source/icon_collision_shape.svg diff --git a/tools/editor/icons/source/icon_collision_shape_2d.svg b/editor/icons/source/icon_collision_shape_2d.svg index e0a750c946..e0a750c946 100644 --- a/tools/editor/icons/source/icon_collision_shape_2d.svg +++ b/editor/icons/source/icon_collision_shape_2d.svg diff --git a/tools/editor/icons/source/icon_color.svg b/editor/icons/source/icon_color.svg index c46f64b8ed..c46f64b8ed 100644 --- a/tools/editor/icons/source/icon_color.svg +++ b/editor/icons/source/icon_color.svg diff --git a/tools/editor/icons/source/icon_color_pick.svg b/editor/icons/source/icon_color_pick.svg index bbb05fc6b6..bbb05fc6b6 100644 --- a/tools/editor/icons/source/icon_color_pick.svg +++ b/editor/icons/source/icon_color_pick.svg diff --git a/tools/editor/icons/source/icon_color_picker.svg b/editor/icons/source/icon_color_picker.svg index 0efd276c50..0efd276c50 100644 --- a/tools/editor/icons/source/icon_color_picker.svg +++ b/editor/icons/source/icon_color_picker.svg diff --git a/tools/editor/icons/source/icon_color_picker_button.svg b/editor/icons/source/icon_color_picker_button.svg index 4e4fb8cc1b..4e4fb8cc1b 100644 --- a/tools/editor/icons/source/icon_color_picker_button.svg +++ b/editor/icons/source/icon_color_picker_button.svg diff --git a/tools/editor/icons/source/icon_color_ramp.svg b/editor/icons/source/icon_color_ramp.svg index ff23cdba8d..ff23cdba8d 100644 --- a/tools/editor/icons/source/icon_color_ramp.svg +++ b/editor/icons/source/icon_color_ramp.svg diff --git a/tools/editor/icons/source/icon_color_rect.svg b/editor/icons/source/icon_color_rect.svg index 76bf6596a9..76bf6596a9 100644 --- a/tools/editor/icons/source/icon_color_rect.svg +++ b/editor/icons/source/icon_color_rect.svg diff --git a/tools/editor/icons/source/icon_concave_polygon_shape.svg b/editor/icons/source/icon_concave_polygon_shape.svg index b0e0fe63ce..b0e0fe63ce 100644 --- a/tools/editor/icons/source/icon_concave_polygon_shape.svg +++ b/editor/icons/source/icon_concave_polygon_shape.svg diff --git a/tools/editor/icons/source/icon_concave_polygon_shape_2d.svg b/editor/icons/source/icon_concave_polygon_shape_2d.svg index 624105e5a8..624105e5a8 100644 --- a/tools/editor/icons/source/icon_concave_polygon_shape_2d.svg +++ b/editor/icons/source/icon_concave_polygon_shape_2d.svg diff --git a/tools/editor/icons/source/icon_cone_twist_joint.svg b/editor/icons/source/icon_cone_twist_joint.svg index 4799deb1d5..4799deb1d5 100644 --- a/tools/editor/icons/source/icon_cone_twist_joint.svg +++ b/editor/icons/source/icon_cone_twist_joint.svg diff --git a/tools/editor/icons/source/icon_confirmation_dialog.svg b/editor/icons/source/icon_confirmation_dialog.svg index 49dbc21e92..49dbc21e92 100644 --- a/tools/editor/icons/source/icon_confirmation_dialog.svg +++ b/editor/icons/source/icon_confirmation_dialog.svg diff --git a/tools/editor/icons/source/icon_connect.svg b/editor/icons/source/icon_connect.svg index 745d3cc436..745d3cc436 100644 --- a/tools/editor/icons/source/icon_connect.svg +++ b/editor/icons/source/icon_connect.svg diff --git a/tools/editor/icons/source/icon_connection_and_groups.svg b/editor/icons/source/icon_connection_and_groups.svg index 5468312b4b..5468312b4b 100644 --- a/tools/editor/icons/source/icon_connection_and_groups.svg +++ b/editor/icons/source/icon_connection_and_groups.svg diff --git a/tools/editor/icons/source/icon_container.svg b/editor/icons/source/icon_container.svg index 2d39efafee..2d39efafee 100644 --- a/tools/editor/icons/source/icon_container.svg +++ b/editor/icons/source/icon_container.svg diff --git a/tools/editor/icons/source/icon_control.svg b/editor/icons/source/icon_control.svg index 675a9f5c43..675a9f5c43 100644 --- a/tools/editor/icons/source/icon_control.svg +++ b/editor/icons/source/icon_control.svg diff --git a/tools/editor/icons/source/icon_control_align_bottom_center.svg b/editor/icons/source/icon_control_align_bottom_center.svg index d6c660bb2d..d6c660bb2d 100644 --- a/tools/editor/icons/source/icon_control_align_bottom_center.svg +++ b/editor/icons/source/icon_control_align_bottom_center.svg diff --git a/tools/editor/icons/source/icon_control_align_bottom_left.svg b/editor/icons/source/icon_control_align_bottom_left.svg index 7a234b10ad..7a234b10ad 100644 --- a/tools/editor/icons/source/icon_control_align_bottom_left.svg +++ b/editor/icons/source/icon_control_align_bottom_left.svg diff --git a/tools/editor/icons/source/icon_control_align_bottom_right.svg b/editor/icons/source/icon_control_align_bottom_right.svg index a4ba9a552a..a4ba9a552a 100644 --- a/tools/editor/icons/source/icon_control_align_bottom_right.svg +++ b/editor/icons/source/icon_control_align_bottom_right.svg diff --git a/tools/editor/icons/source/icon_control_align_bottom_wide.svg b/editor/icons/source/icon_control_align_bottom_wide.svg index 93352dd3f5..93352dd3f5 100644 --- a/tools/editor/icons/source/icon_control_align_bottom_wide.svg +++ b/editor/icons/source/icon_control_align_bottom_wide.svg diff --git a/tools/editor/icons/source/icon_control_align_center.svg b/editor/icons/source/icon_control_align_center.svg index 0c34d13def..0c34d13def 100644 --- a/tools/editor/icons/source/icon_control_align_center.svg +++ b/editor/icons/source/icon_control_align_center.svg diff --git a/tools/editor/icons/source/icon_control_align_center_left.svg b/editor/icons/source/icon_control_align_center_left.svg index ea62c9457d..ea62c9457d 100644 --- a/tools/editor/icons/source/icon_control_align_center_left.svg +++ b/editor/icons/source/icon_control_align_center_left.svg diff --git a/tools/editor/icons/source/icon_control_align_center_right.svg b/editor/icons/source/icon_control_align_center_right.svg index 3212ce8538..3212ce8538 100644 --- a/tools/editor/icons/source/icon_control_align_center_right.svg +++ b/editor/icons/source/icon_control_align_center_right.svg diff --git a/tools/editor/icons/source/icon_control_align_left_center.svg b/editor/icons/source/icon_control_align_left_center.svg index 716b6a2fd0..716b6a2fd0 100644 --- a/tools/editor/icons/source/icon_control_align_left_center.svg +++ b/editor/icons/source/icon_control_align_left_center.svg diff --git a/tools/editor/icons/source/icon_control_align_left_wide.svg b/editor/icons/source/icon_control_align_left_wide.svg index 7092c78508..7092c78508 100644 --- a/tools/editor/icons/source/icon_control_align_left_wide.svg +++ b/editor/icons/source/icon_control_align_left_wide.svg diff --git a/tools/editor/icons/source/icon_control_align_right_center.svg b/editor/icons/source/icon_control_align_right_center.svg index 7e7e4f2b23..7e7e4f2b23 100644 --- a/tools/editor/icons/source/icon_control_align_right_center.svg +++ b/editor/icons/source/icon_control_align_right_center.svg diff --git a/tools/editor/icons/source/icon_control_align_right_wide.svg b/editor/icons/source/icon_control_align_right_wide.svg index ef2d105bd8..ef2d105bd8 100644 --- a/tools/editor/icons/source/icon_control_align_right_wide.svg +++ b/editor/icons/source/icon_control_align_right_wide.svg diff --git a/tools/editor/icons/source/icon_control_align_top_center.svg b/editor/icons/source/icon_control_align_top_center.svg index a5b60846f4..a5b60846f4 100644 --- a/tools/editor/icons/source/icon_control_align_top_center.svg +++ b/editor/icons/source/icon_control_align_top_center.svg diff --git a/tools/editor/icons/source/icon_control_align_top_left.svg b/editor/icons/source/icon_control_align_top_left.svg index 9f4631cf31..9f4631cf31 100644 --- a/tools/editor/icons/source/icon_control_align_top_left.svg +++ b/editor/icons/source/icon_control_align_top_left.svg diff --git a/tools/editor/icons/source/icon_control_align_top_right.svg b/editor/icons/source/icon_control_align_top_right.svg index d968ba3d09..d968ba3d09 100644 --- a/tools/editor/icons/source/icon_control_align_top_right.svg +++ b/editor/icons/source/icon_control_align_top_right.svg diff --git a/tools/editor/icons/source/icon_control_align_top_wide.svg b/editor/icons/source/icon_control_align_top_wide.svg index 886ef60fe0..886ef60fe0 100644 --- a/tools/editor/icons/source/icon_control_align_top_wide.svg +++ b/editor/icons/source/icon_control_align_top_wide.svg diff --git a/tools/editor/icons/source/icon_control_align_wide.svg b/editor/icons/source/icon_control_align_wide.svg index 3f58ed93b6..3f58ed93b6 100644 --- a/tools/editor/icons/source/icon_control_align_wide.svg +++ b/editor/icons/source/icon_control_align_wide.svg diff --git a/tools/editor/icons/source/icon_control_hcenter_wide.svg b/editor/icons/source/icon_control_hcenter_wide.svg index 3aafa0340e..3aafa0340e 100644 --- a/tools/editor/icons/source/icon_control_hcenter_wide.svg +++ b/editor/icons/source/icon_control_hcenter_wide.svg diff --git a/tools/editor/icons/source/icon_control_vcenter_wide.svg b/editor/icons/source/icon_control_vcenter_wide.svg index 96fd44f3c8..96fd44f3c8 100644 --- a/tools/editor/icons/source/icon_control_vcenter_wide.svg +++ b/editor/icons/source/icon_control_vcenter_wide.svg diff --git a/tools/editor/icons/source/icon_convex_polygon_shape.svg b/editor/icons/source/icon_convex_polygon_shape.svg index b867a58f6f..b867a58f6f 100644 --- a/tools/editor/icons/source/icon_convex_polygon_shape.svg +++ b/editor/icons/source/icon_convex_polygon_shape.svg diff --git a/tools/editor/icons/source/icon_convex_polygon_shape_2d.svg b/editor/icons/source/icon_convex_polygon_shape_2d.svg index 3b55df7fba..3b55df7fba 100644 --- a/tools/editor/icons/source/icon_convex_polygon_shape_2d.svg +++ b/editor/icons/source/icon_convex_polygon_shape_2d.svg diff --git a/tools/editor/icons/source/icon_copy_node_path.svg b/editor/icons/source/icon_copy_node_path.svg index 9f33c5e54d..9f33c5e54d 100644 --- a/tools/editor/icons/source/icon_copy_node_path.svg +++ b/editor/icons/source/icon_copy_node_path.svg diff --git a/tools/editor/icons/source/icon_create_new_scene_from.svg b/editor/icons/source/icon_create_new_scene_from.svg index 529553bbd3..529553bbd3 100644 --- a/tools/editor/icons/source/icon_create_new_scene_from.svg +++ b/editor/icons/source/icon_create_new_scene_from.svg diff --git a/tools/editor/icons/source/icon_cube_map.svg b/editor/icons/source/icon_cube_map.svg index 4fd86b1233..4fd86b1233 100644 --- a/tools/editor/icons/source/icon_cube_map.svg +++ b/editor/icons/source/icon_cube_map.svg diff --git a/tools/editor/icons/source/icon_curve_2d.svg b/editor/icons/source/icon_curve_2d.svg index 34719e37de..34719e37de 100644 --- a/tools/editor/icons/source/icon_curve_2d.svg +++ b/editor/icons/source/icon_curve_2d.svg diff --git a/tools/editor/icons/source/icon_curve_3d.svg b/editor/icons/source/icon_curve_3d.svg index 66034968b2..66034968b2 100644 --- a/tools/editor/icons/source/icon_curve_3d.svg +++ b/editor/icons/source/icon_curve_3d.svg diff --git a/tools/editor/icons/source/icon_curve_close.svg b/editor/icons/source/icon_curve_close.svg index 15909df7c8..15909df7c8 100644 --- a/tools/editor/icons/source/icon_curve_close.svg +++ b/editor/icons/source/icon_curve_close.svg diff --git a/tools/editor/icons/source/icon_curve_constant.svg b/editor/icons/source/icon_curve_constant.svg index 6d9a7dc959..6d9a7dc959 100644 --- a/tools/editor/icons/source/icon_curve_constant.svg +++ b/editor/icons/source/icon_curve_constant.svg diff --git a/tools/editor/icons/source/icon_curve_create.svg b/editor/icons/source/icon_curve_create.svg index 8ab578e9a0..8ab578e9a0 100644 --- a/tools/editor/icons/source/icon_curve_create.svg +++ b/editor/icons/source/icon_curve_create.svg diff --git a/tools/editor/icons/source/icon_curve_curve.svg b/editor/icons/source/icon_curve_curve.svg index e3b6b64a4c..e3b6b64a4c 100644 --- a/tools/editor/icons/source/icon_curve_curve.svg +++ b/editor/icons/source/icon_curve_curve.svg diff --git a/tools/editor/icons/source/icon_curve_delete.svg b/editor/icons/source/icon_curve_delete.svg index f40dd1eeb1..f40dd1eeb1 100644 --- a/tools/editor/icons/source/icon_curve_delete.svg +++ b/editor/icons/source/icon_curve_delete.svg diff --git a/tools/editor/icons/source/icon_curve_edit.svg b/editor/icons/source/icon_curve_edit.svg index f695e96b8c..f695e96b8c 100644 --- a/tools/editor/icons/source/icon_curve_edit.svg +++ b/editor/icons/source/icon_curve_edit.svg diff --git a/tools/editor/icons/source/icon_curve_in.svg b/editor/icons/source/icon_curve_in.svg index 9dc033aa95..9dc033aa95 100644 --- a/tools/editor/icons/source/icon_curve_in.svg +++ b/editor/icons/source/icon_curve_in.svg diff --git a/tools/editor/icons/source/icon_curve_in_out.svg b/editor/icons/source/icon_curve_in_out.svg index c68f906423..c68f906423 100644 --- a/tools/editor/icons/source/icon_curve_in_out.svg +++ b/editor/icons/source/icon_curve_in_out.svg diff --git a/tools/editor/icons/source/icon_curve_linear.svg b/editor/icons/source/icon_curve_linear.svg index ae7a889a71..ae7a889a71 100644 --- a/tools/editor/icons/source/icon_curve_linear.svg +++ b/editor/icons/source/icon_curve_linear.svg diff --git a/tools/editor/icons/source/icon_curve_out.svg b/editor/icons/source/icon_curve_out.svg index 080aa755dc..080aa755dc 100644 --- a/tools/editor/icons/source/icon_curve_out.svg +++ b/editor/icons/source/icon_curve_out.svg diff --git a/tools/editor/icons/source/icon_curve_out_in.svg b/editor/icons/source/icon_curve_out_in.svg index d2b4d06e5f..d2b4d06e5f 100644 --- a/tools/editor/icons/source/icon_curve_out_in.svg +++ b/editor/icons/source/icon_curve_out_in.svg diff --git a/tools/editor/icons/source/icon_damped_spring_joint_2d.svg b/editor/icons/source/icon_damped_spring_joint_2d.svg index bf12810a6c..bf12810a6c 100644 --- a/tools/editor/icons/source/icon_damped_spring_joint_2d.svg +++ b/editor/icons/source/icon_damped_spring_joint_2d.svg diff --git a/tools/editor/icons/source/icon_debug_continue.svg b/editor/icons/source/icon_debug_continue.svg index 5d9ccd5a7e..5d9ccd5a7e 100644 --- a/tools/editor/icons/source/icon_debug_continue.svg +++ b/editor/icons/source/icon_debug_continue.svg diff --git a/tools/editor/icons/source/icon_debug_next.svg b/editor/icons/source/icon_debug_next.svg index 4dd9bb8c4b..4dd9bb8c4b 100644 --- a/tools/editor/icons/source/icon_debug_next.svg +++ b/editor/icons/source/icon_debug_next.svg diff --git a/tools/editor/icons/source/icon_debug_step.svg b/editor/icons/source/icon_debug_step.svg index 20d11f8710..20d11f8710 100644 --- a/tools/editor/icons/source/icon_debug_step.svg +++ b/editor/icons/source/icon_debug_step.svg diff --git a/tools/editor/icons/source/icon_dependency_changed.svg b/editor/icons/source/icon_dependency_changed.svg index bbcd3f0c0a..bbcd3f0c0a 100644 --- a/tools/editor/icons/source/icon_dependency_changed.svg +++ b/editor/icons/source/icon_dependency_changed.svg diff --git a/tools/editor/icons/source/icon_dependency_changed_hl.svg b/editor/icons/source/icon_dependency_changed_hl.svg index 54a37695ef..54a37695ef 100644 --- a/tools/editor/icons/source/icon_dependency_changed_hl.svg +++ b/editor/icons/source/icon_dependency_changed_hl.svg diff --git a/tools/editor/icons/source/icon_dependency_local_changed.svg b/editor/icons/source/icon_dependency_local_changed.svg index 799d69c4e0..799d69c4e0 100644 --- a/tools/editor/icons/source/icon_dependency_local_changed.svg +++ b/editor/icons/source/icon_dependency_local_changed.svg diff --git a/tools/editor/icons/source/icon_dependency_local_changed_hl.svg b/editor/icons/source/icon_dependency_local_changed_hl.svg index 67c04c312a..67c04c312a 100644 --- a/tools/editor/icons/source/icon_dependency_local_changed_hl.svg +++ b/editor/icons/source/icon_dependency_local_changed_hl.svg diff --git a/tools/editor/icons/source/icon_dependency_ok.svg b/editor/icons/source/icon_dependency_ok.svg index 76d7f54065..76d7f54065 100644 --- a/tools/editor/icons/source/icon_dependency_ok.svg +++ b/editor/icons/source/icon_dependency_ok.svg diff --git a/tools/editor/icons/source/icon_dependency_ok_hl.svg b/editor/icons/source/icon_dependency_ok_hl.svg index 190458c532..190458c532 100644 --- a/tools/editor/icons/source/icon_dependency_ok_hl.svg +++ b/editor/icons/source/icon_dependency_ok_hl.svg diff --git a/tools/editor/icons/source/icon_directional_light.svg b/editor/icons/source/icon_directional_light.svg index dbec755039..dbec755039 100644 --- a/tools/editor/icons/source/icon_directional_light.svg +++ b/editor/icons/source/icon_directional_light.svg diff --git a/tools/editor/icons/source/icon_distraction_free.svg b/editor/icons/source/icon_distraction_free.svg index 4ae48b2fb6..4ae48b2fb6 100644 --- a/tools/editor/icons/source/icon_distraction_free.svg +++ b/editor/icons/source/icon_distraction_free.svg diff --git a/tools/editor/icons/source/icon_duplicate.svg b/editor/icons/source/icon_duplicate.svg index b1d5544fc0..b1d5544fc0 100644 --- a/tools/editor/icons/source/icon_duplicate.svg +++ b/editor/icons/source/icon_duplicate.svg diff --git a/tools/editor/icons/source/icon_dynamic_font.svg b/editor/icons/source/icon_dynamic_font.svg index a40c0e3408..a40c0e3408 100644 --- a/tools/editor/icons/source/icon_dynamic_font.svg +++ b/editor/icons/source/icon_dynamic_font.svg diff --git a/tools/editor/icons/source/icon_dynamic_font_data.svg b/editor/icons/source/icon_dynamic_font_data.svg index 9f06172fef..9f06172fef 100644 --- a/tools/editor/icons/source/icon_dynamic_font_data.svg +++ b/editor/icons/source/icon_dynamic_font_data.svg diff --git a/tools/editor/icons/source/icon_edit.svg b/editor/icons/source/icon_edit.svg index 6da05a6603..6da05a6603 100644 --- a/tools/editor/icons/source/icon_edit.svg +++ b/editor/icons/source/icon_edit.svg diff --git a/tools/editor/icons/source/icon_edit_key.svg b/editor/icons/source/icon_edit_key.svg index 46795bef35..46795bef35 100644 --- a/tools/editor/icons/source/icon_edit_key.svg +++ b/editor/icons/source/icon_edit_key.svg diff --git a/tools/editor/icons/source/icon_edit_pivot.svg b/editor/icons/source/icon_edit_pivot.svg index 8ae55ad8b7..8ae55ad8b7 100644 --- a/tools/editor/icons/source/icon_edit_pivot.svg +++ b/editor/icons/source/icon_edit_pivot.svg diff --git a/tools/editor/icons/source/icon_edit_resource.svg b/editor/icons/source/icon_edit_resource.svg index 1950988ca2..1950988ca2 100644 --- a/tools/editor/icons/source/icon_edit_resource.svg +++ b/editor/icons/source/icon_edit_resource.svg diff --git a/tools/editor/icons/source/icon_editor_3d_handle.svg b/editor/icons/source/icon_editor_3d_handle.svg index 255d1801a9..255d1801a9 100644 --- a/tools/editor/icons/source/icon_editor_3d_handle.svg +++ b/editor/icons/source/icon_editor_3d_handle.svg diff --git a/tools/editor/icons/source/icon_editor_handle.svg b/editor/icons/source/icon_editor_handle.svg index 17ed2a61e7..17ed2a61e7 100644 --- a/tools/editor/icons/source/icon_editor_handle.svg +++ b/editor/icons/source/icon_editor_handle.svg diff --git a/tools/editor/icons/source/icon_editor_pivot.svg b/editor/icons/source/icon_editor_pivot.svg index 8ce7d48970..8ce7d48970 100644 --- a/tools/editor/icons/source/icon_editor_pivot.svg +++ b/editor/icons/source/icon_editor_pivot.svg diff --git a/tools/editor/icons/source/icon_editor_plugin.svg b/editor/icons/source/icon_editor_plugin.svg index b9460de683..b9460de683 100644 --- a/tools/editor/icons/source/icon_editor_plugin.svg +++ b/editor/icons/source/icon_editor_plugin.svg diff --git a/tools/editor/icons/source/icon_environment.svg b/editor/icons/source/icon_environment.svg index 45add2c7f7..45add2c7f7 100644 --- a/tools/editor/icons/source/icon_environment.svg +++ b/editor/icons/source/icon_environment.svg diff --git a/tools/editor/icons/source/icon_error.svg b/editor/icons/source/icon_error.svg index a0b04a98cb..a0b04a98cb 100644 --- a/tools/editor/icons/source/icon_error.svg +++ b/editor/icons/source/icon_error.svg diff --git a/tools/editor/icons/source/icon_error_sign.svg b/editor/icons/source/icon_error_sign.svg index 01c1dbb4d5..01c1dbb4d5 100644 --- a/tools/editor/icons/source/icon_error_sign.svg +++ b/editor/icons/source/icon_error_sign.svg diff --git a/tools/editor/icons/source/icon_event_player.svg b/editor/icons/source/icon_event_player.svg index 3f5f7da693..3f5f7da693 100644 --- a/tools/editor/icons/source/icon_event_player.svg +++ b/editor/icons/source/icon_event_player.svg diff --git a/tools/editor/icons/source/icon_favorites.svg b/editor/icons/source/icon_favorites.svg index 12d4b56897..12d4b56897 100644 --- a/tools/editor/icons/source/icon_favorites.svg +++ b/editor/icons/source/icon_favorites.svg diff --git a/tools/editor/icons/source/icon_file_big.svg b/editor/icons/source/icon_file_big.svg index 38ad9b707a..38ad9b707a 100644 --- a/tools/editor/icons/source/icon_file_big.svg +++ b/editor/icons/source/icon_file_big.svg diff --git a/tools/editor/icons/source/icon_file_dialog.svg b/editor/icons/source/icon_file_dialog.svg index 9dee04c220..9dee04c220 100644 --- a/tools/editor/icons/source/icon_file_dialog.svg +++ b/editor/icons/source/icon_file_dialog.svg diff --git a/tools/editor/icons/source/icon_file_list.svg b/editor/icons/source/icon_file_list.svg index 82dad29aac..82dad29aac 100644 --- a/tools/editor/icons/source/icon_file_list.svg +++ b/editor/icons/source/icon_file_list.svg diff --git a/tools/editor/icons/source/icon_file_server.svg b/editor/icons/source/icon_file_server.svg index 1e1f9b6e42..1e1f9b6e42 100644 --- a/tools/editor/icons/source/icon_file_server.svg +++ b/editor/icons/source/icon_file_server.svg diff --git a/tools/editor/icons/source/icon_file_server_active.svg b/editor/icons/source/icon_file_server_active.svg index f01ba578da..f01ba578da 100644 --- a/tools/editor/icons/source/icon_file_server_active.svg +++ b/editor/icons/source/icon_file_server_active.svg diff --git a/tools/editor/icons/source/icon_file_thumbnail.svg b/editor/icons/source/icon_file_thumbnail.svg index 48d90dd3c6..48d90dd3c6 100644 --- a/tools/editor/icons/source/icon_file_thumbnail.svg +++ b/editor/icons/source/icon_file_thumbnail.svg diff --git a/tools/editor/icons/source/icon_fixed_material.svg b/editor/icons/source/icon_fixed_material.svg index 5be74f490d..5be74f490d 100644 --- a/tools/editor/icons/source/icon_fixed_material.svg +++ b/editor/icons/source/icon_fixed_material.svg diff --git a/tools/editor/icons/source/icon_fixed_spatial_material.svg b/editor/icons/source/icon_fixed_spatial_material.svg index 7ae0f93ffc..7ae0f93ffc 100644 --- a/tools/editor/icons/source/icon_fixed_spatial_material.svg +++ b/editor/icons/source/icon_fixed_spatial_material.svg diff --git a/tools/editor/icons/source/icon_folder.svg b/editor/icons/source/icon_folder.svg index ca16a5737f..ca16a5737f 100644 --- a/tools/editor/icons/source/icon_folder.svg +++ b/editor/icons/source/icon_folder.svg diff --git a/tools/editor/icons/source/icon_folder_big.svg b/editor/icons/source/icon_folder_big.svg index 818eaa2ba3..818eaa2ba3 100644 --- a/tools/editor/icons/source/icon_folder_big.svg +++ b/editor/icons/source/icon_folder_big.svg diff --git a/tools/editor/icons/source/icon_font.svg b/editor/icons/source/icon_font.svg index 36567fe10c..36567fe10c 100644 --- a/tools/editor/icons/source/icon_font.svg +++ b/editor/icons/source/icon_font.svg diff --git a/tools/editor/icons/source/icon_forward.svg b/editor/icons/source/icon_forward.svg index f6cb351cc1..f6cb351cc1 100644 --- a/tools/editor/icons/source/icon_forward.svg +++ b/editor/icons/source/icon_forward.svg diff --git a/tools/editor/icons/source/icon_g_d_script.svg b/editor/icons/source/icon_g_d_script.svg index f2b8cd9343..f2b8cd9343 100644 --- a/tools/editor/icons/source/icon_g_d_script.svg +++ b/editor/icons/source/icon_g_d_script.svg diff --git a/tools/editor/icons/source/icon_g_i_probe.svg b/editor/icons/source/icon_g_i_probe.svg index d803a5f63d..d803a5f63d 100644 --- a/tools/editor/icons/source/icon_g_i_probe.svg +++ b/editor/icons/source/icon_g_i_probe.svg diff --git a/tools/editor/icons/source/icon_g_i_probe_data.svg b/editor/icons/source/icon_g_i_probe_data.svg index 96fa62723c..96fa62723c 100644 --- a/tools/editor/icons/source/icon_g_i_probe_data.svg +++ b/editor/icons/source/icon_g_i_probe_data.svg diff --git a/tools/editor/icons/source/icon_generic_6_d_o_f_joint.svg b/editor/icons/source/icon_generic_6_d_o_f_joint.svg index 485040c6dc..485040c6dc 100644 --- a/tools/editor/icons/source/icon_generic_6_d_o_f_joint.svg +++ b/editor/icons/source/icon_generic_6_d_o_f_joint.svg diff --git a/tools/editor/icons/source/icon_gizmo_directional_light.svg b/editor/icons/source/icon_gizmo_directional_light.svg index 65202877a0..65202877a0 100644 --- a/tools/editor/icons/source/icon_gizmo_directional_light.svg +++ b/editor/icons/source/icon_gizmo_directional_light.svg diff --git a/tools/editor/icons/source/icon_gizmo_light.svg b/editor/icons/source/icon_gizmo_light.svg index c42d6e1f76..c42d6e1f76 100644 --- a/tools/editor/icons/source/icon_gizmo_light.svg +++ b/editor/icons/source/icon_gizmo_light.svg diff --git a/tools/editor/icons/source/icon_gizmo_listener.svg b/editor/icons/source/icon_gizmo_listener.svg index 3667cbc69b..3667cbc69b 100644 --- a/tools/editor/icons/source/icon_gizmo_listener.svg +++ b/editor/icons/source/icon_gizmo_listener.svg diff --git a/tools/editor/icons/source/icon_gizmo_spatial_sample_player.svg b/editor/icons/source/icon_gizmo_spatial_sample_player.svg index a734095268..a734095268 100644 --- a/tools/editor/icons/source/icon_gizmo_spatial_sample_player.svg +++ b/editor/icons/source/icon_gizmo_spatial_sample_player.svg diff --git a/tools/editor/icons/source/icon_gizmo_spatial_stream_player.svg b/editor/icons/source/icon_gizmo_spatial_stream_player.svg index c333641249..c333641249 100644 --- a/tools/editor/icons/source/icon_gizmo_spatial_stream_player.svg +++ b/editor/icons/source/icon_gizmo_spatial_stream_player.svg diff --git a/tools/editor/icons/source/icon_godot.svg b/editor/icons/source/icon_godot.svg index 419f23125b..419f23125b 100644 --- a/tools/editor/icons/source/icon_godot.svg +++ b/editor/icons/source/icon_godot.svg diff --git a/tools/editor/icons/source/icon_graph_comment.svg b/editor/icons/source/icon_graph_comment.svg index 5ad8fc8253..5ad8fc8253 100644 --- a/tools/editor/icons/source/icon_graph_comment.svg +++ b/editor/icons/source/icon_graph_comment.svg diff --git a/tools/editor/icons/source/icon_graph_cube_uniform.svg b/editor/icons/source/icon_graph_cube_uniform.svg index 63774a7431..63774a7431 100644 --- a/tools/editor/icons/source/icon_graph_cube_uniform.svg +++ b/editor/icons/source/icon_graph_cube_uniform.svg diff --git a/tools/editor/icons/source/icon_graph_curve_map.svg b/editor/icons/source/icon_graph_curve_map.svg index 6c3594cb1b..6c3594cb1b 100644 --- a/tools/editor/icons/source/icon_graph_curve_map.svg +++ b/editor/icons/source/icon_graph_curve_map.svg diff --git a/tools/editor/icons/source/icon_graph_default_texture.svg b/editor/icons/source/icon_graph_default_texture.svg index 8d1c78ddd7..8d1c78ddd7 100644 --- a/tools/editor/icons/source/icon_graph_default_texture.svg +++ b/editor/icons/source/icon_graph_default_texture.svg diff --git a/tools/editor/icons/source/icon_graph_edit.svg b/editor/icons/source/icon_graph_edit.svg index 30d3ad96f6..30d3ad96f6 100644 --- a/tools/editor/icons/source/icon_graph_edit.svg +++ b/editor/icons/source/icon_graph_edit.svg diff --git a/tools/editor/icons/source/icon_graph_input.svg b/editor/icons/source/icon_graph_input.svg index 265fb7279e..265fb7279e 100644 --- a/tools/editor/icons/source/icon_graph_input.svg +++ b/editor/icons/source/icon_graph_input.svg diff --git a/tools/editor/icons/source/icon_graph_node.svg b/editor/icons/source/icon_graph_node.svg index 078b0ffe9e..078b0ffe9e 100644 --- a/tools/editor/icons/source/icon_graph_node.svg +++ b/editor/icons/source/icon_graph_node.svg diff --git a/tools/editor/icons/source/icon_graph_rgb.svg b/editor/icons/source/icon_graph_rgb.svg index a00e97a104..a00e97a104 100644 --- a/tools/editor/icons/source/icon_graph_rgb.svg +++ b/editor/icons/source/icon_graph_rgb.svg diff --git a/tools/editor/icons/source/icon_graph_rgb_op.svg b/editor/icons/source/icon_graph_rgb_op.svg index fdd3d3a9f4..fdd3d3a9f4 100644 --- a/tools/editor/icons/source/icon_graph_rgb_op.svg +++ b/editor/icons/source/icon_graph_rgb_op.svg diff --git a/tools/editor/icons/source/icon_graph_rgb_uniform.svg b/editor/icons/source/icon_graph_rgb_uniform.svg index 359c86d61a..359c86d61a 100644 --- a/tools/editor/icons/source/icon_graph_rgb_uniform.svg +++ b/editor/icons/source/icon_graph_rgb_uniform.svg diff --git a/tools/editor/icons/source/icon_graph_scalar.svg b/editor/icons/source/icon_graph_scalar.svg index 7a75ddba78..7a75ddba78 100644 --- a/tools/editor/icons/source/icon_graph_scalar.svg +++ b/editor/icons/source/icon_graph_scalar.svg diff --git a/tools/editor/icons/source/icon_graph_scalar_interp.svg b/editor/icons/source/icon_graph_scalar_interp.svg index 47b619d608..47b619d608 100644 --- a/tools/editor/icons/source/icon_graph_scalar_interp.svg +++ b/editor/icons/source/icon_graph_scalar_interp.svg diff --git a/tools/editor/icons/source/icon_graph_scalar_op.svg b/editor/icons/source/icon_graph_scalar_op.svg index fcb54f9aa0..fcb54f9aa0 100644 --- a/tools/editor/icons/source/icon_graph_scalar_op.svg +++ b/editor/icons/source/icon_graph_scalar_op.svg diff --git a/tools/editor/icons/source/icon_graph_scalar_uniform.svg b/editor/icons/source/icon_graph_scalar_uniform.svg index e5e5edea9c..e5e5edea9c 100644 --- a/tools/editor/icons/source/icon_graph_scalar_uniform.svg +++ b/editor/icons/source/icon_graph_scalar_uniform.svg diff --git a/tools/editor/icons/source/icon_graph_scalars_to_vec.svg b/editor/icons/source/icon_graph_scalars_to_vec.svg index 0f2994a606..0f2994a606 100644 --- a/tools/editor/icons/source/icon_graph_scalars_to_vec.svg +++ b/editor/icons/source/icon_graph_scalars_to_vec.svg diff --git a/tools/editor/icons/source/icon_graph_texscreen.svg b/editor/icons/source/icon_graph_texscreen.svg index 89d000d7cb..89d000d7cb 100644 --- a/tools/editor/icons/source/icon_graph_texscreen.svg +++ b/editor/icons/source/icon_graph_texscreen.svg diff --git a/tools/editor/icons/source/icon_graph_texture_uniform.svg b/editor/icons/source/icon_graph_texture_uniform.svg index 440f83642c..440f83642c 100644 --- a/tools/editor/icons/source/icon_graph_texture_uniform.svg +++ b/editor/icons/source/icon_graph_texture_uniform.svg diff --git a/tools/editor/icons/source/icon_graph_time.svg b/editor/icons/source/icon_graph_time.svg index 77b80e920b..77b80e920b 100644 --- a/tools/editor/icons/source/icon_graph_time.svg +++ b/editor/icons/source/icon_graph_time.svg diff --git a/tools/editor/icons/source/icon_graph_vec_dp.svg b/editor/icons/source/icon_graph_vec_dp.svg index 8994d8ce59..8994d8ce59 100644 --- a/tools/editor/icons/source/icon_graph_vec_dp.svg +++ b/editor/icons/source/icon_graph_vec_dp.svg diff --git a/tools/editor/icons/source/icon_graph_vec_interp.svg b/editor/icons/source/icon_graph_vec_interp.svg index 885b342a54..885b342a54 100644 --- a/tools/editor/icons/source/icon_graph_vec_interp.svg +++ b/editor/icons/source/icon_graph_vec_interp.svg diff --git a/tools/editor/icons/source/icon_graph_vec_length.svg b/editor/icons/source/icon_graph_vec_length.svg index aa01e3ef2a..aa01e3ef2a 100644 --- a/tools/editor/icons/source/icon_graph_vec_length.svg +++ b/editor/icons/source/icon_graph_vec_length.svg diff --git a/tools/editor/icons/source/icon_graph_vec_op.svg b/editor/icons/source/icon_graph_vec_op.svg index da7540ce86..da7540ce86 100644 --- a/tools/editor/icons/source/icon_graph_vec_op.svg +++ b/editor/icons/source/icon_graph_vec_op.svg diff --git a/tools/editor/icons/source/icon_graph_vec_scalar_op.svg b/editor/icons/source/icon_graph_vec_scalar_op.svg index aeb2626120..aeb2626120 100644 --- a/tools/editor/icons/source/icon_graph_vec_scalar_op.svg +++ b/editor/icons/source/icon_graph_vec_scalar_op.svg diff --git a/tools/editor/icons/source/icon_graph_vec_to_scalars.svg b/editor/icons/source/icon_graph_vec_to_scalars.svg index fb58db9d78..fb58db9d78 100644 --- a/tools/editor/icons/source/icon_graph_vec_to_scalars.svg +++ b/editor/icons/source/icon_graph_vec_to_scalars.svg diff --git a/tools/editor/icons/source/icon_graph_vecs_to_xform.svg b/editor/icons/source/icon_graph_vecs_to_xform.svg index f8ba3eb4b8..f8ba3eb4b8 100644 --- a/tools/editor/icons/source/icon_graph_vecs_to_xform.svg +++ b/editor/icons/source/icon_graph_vecs_to_xform.svg diff --git a/tools/editor/icons/source/icon_graph_vector.svg b/editor/icons/source/icon_graph_vector.svg index e7f6bd927f..e7f6bd927f 100644 --- a/tools/editor/icons/source/icon_graph_vector.svg +++ b/editor/icons/source/icon_graph_vector.svg diff --git a/tools/editor/icons/source/icon_graph_vector_uniform.svg b/editor/icons/source/icon_graph_vector_uniform.svg index 2310938af5..2310938af5 100644 --- a/tools/editor/icons/source/icon_graph_vector_uniform.svg +++ b/editor/icons/source/icon_graph_vector_uniform.svg diff --git a/tools/editor/icons/source/icon_graph_xform.svg b/editor/icons/source/icon_graph_xform.svg index c9b027ee2d..c9b027ee2d 100644 --- a/tools/editor/icons/source/icon_graph_xform.svg +++ b/editor/icons/source/icon_graph_xform.svg diff --git a/tools/editor/icons/source/icon_graph_xform_mult.svg b/editor/icons/source/icon_graph_xform_mult.svg index 71fca83f3d..71fca83f3d 100644 --- a/tools/editor/icons/source/icon_graph_xform_mult.svg +++ b/editor/icons/source/icon_graph_xform_mult.svg diff --git a/tools/editor/icons/source/icon_graph_xform_scalar_func.svg b/editor/icons/source/icon_graph_xform_scalar_func.svg index 45fd97a671..45fd97a671 100644 --- a/tools/editor/icons/source/icon_graph_xform_scalar_func.svg +++ b/editor/icons/source/icon_graph_xform_scalar_func.svg diff --git a/tools/editor/icons/source/icon_graph_xform_to_vecs.svg b/editor/icons/source/icon_graph_xform_to_vecs.svg index cc113e72fd..cc113e72fd 100644 --- a/tools/editor/icons/source/icon_graph_xform_to_vecs.svg +++ b/editor/icons/source/icon_graph_xform_to_vecs.svg diff --git a/tools/editor/icons/source/icon_graph_xform_uniform.svg b/editor/icons/source/icon_graph_xform_uniform.svg index f1cdcd408c..f1cdcd408c 100644 --- a/tools/editor/icons/source/icon_graph_xform_uniform.svg +++ b/editor/icons/source/icon_graph_xform_uniform.svg diff --git a/tools/editor/icons/source/icon_graph_xform_vec_func.svg b/editor/icons/source/icon_graph_xform_vec_func.svg index 0d141bc646..0d141bc646 100644 --- a/tools/editor/icons/source/icon_graph_xform_vec_func.svg +++ b/editor/icons/source/icon_graph_xform_vec_func.svg diff --git a/tools/editor/icons/source/icon_graph_xform_vec_imult.svg b/editor/icons/source/icon_graph_xform_vec_imult.svg index 74dc1ba7e3..74dc1ba7e3 100644 --- a/tools/editor/icons/source/icon_graph_xform_vec_imult.svg +++ b/editor/icons/source/icon_graph_xform_vec_imult.svg diff --git a/tools/editor/icons/source/icon_graph_xform_vec_mult.svg b/editor/icons/source/icon_graph_xform_vec_mult.svg index c3e59abd46..c3e59abd46 100644 --- a/tools/editor/icons/source/icon_graph_xform_vec_mult.svg +++ b/editor/icons/source/icon_graph_xform_vec_mult.svg diff --git a/tools/editor/icons/source/icon_grid.svg b/editor/icons/source/icon_grid.svg index 2d9288de14..2d9288de14 100644 --- a/tools/editor/icons/source/icon_grid.svg +++ b/editor/icons/source/icon_grid.svg diff --git a/tools/editor/icons/source/icon_grid_container.svg b/editor/icons/source/icon_grid_container.svg index a27578f196..a27578f196 100644 --- a/tools/editor/icons/source/icon_grid_container.svg +++ b/editor/icons/source/icon_grid_container.svg diff --git a/tools/editor/icons/source/icon_grid_map.svg b/editor/icons/source/icon_grid_map.svg index 5bbea0ff2c..5bbea0ff2c 100644 --- a/tools/editor/icons/source/icon_grid_map.svg +++ b/editor/icons/source/icon_grid_map.svg diff --git a/tools/editor/icons/source/icon_groove_joint_2d.svg b/editor/icons/source/icon_groove_joint_2d.svg index d05bebef48..d05bebef48 100644 --- a/tools/editor/icons/source/icon_groove_joint_2d.svg +++ b/editor/icons/source/icon_groove_joint_2d.svg diff --git a/tools/editor/icons/source/icon_group.svg b/editor/icons/source/icon_group.svg index a0a2f02af5..a0a2f02af5 100644 --- a/tools/editor/icons/source/icon_group.svg +++ b/editor/icons/source/icon_group.svg diff --git a/tools/editor/icons/source/icon_groups.svg b/editor/icons/source/icon_groups.svg index 00249597a4..00249597a4 100644 --- a/tools/editor/icons/source/icon_groups.svg +++ b/editor/icons/source/icon_groups.svg diff --git a/tools/editor/icons/source/icon_h_box_container.svg b/editor/icons/source/icon_h_box_container.svg index f180dde93a..f180dde93a 100644 --- a/tools/editor/icons/source/icon_h_box_container.svg +++ b/editor/icons/source/icon_h_box_container.svg diff --git a/tools/editor/icons/source/icon_h_button_array.svg b/editor/icons/source/icon_h_button_array.svg index 9470aeb370..9470aeb370 100644 --- a/tools/editor/icons/source/icon_h_button_array.svg +++ b/editor/icons/source/icon_h_button_array.svg diff --git a/tools/editor/icons/source/icon_h_scroll_bar.svg b/editor/icons/source/icon_h_scroll_bar.svg index 2f007c7c94..2f007c7c94 100644 --- a/tools/editor/icons/source/icon_h_scroll_bar.svg +++ b/editor/icons/source/icon_h_scroll_bar.svg diff --git a/tools/editor/icons/source/icon_h_separator.svg b/editor/icons/source/icon_h_separator.svg index 461299731d..461299731d 100644 --- a/tools/editor/icons/source/icon_h_separator.svg +++ b/editor/icons/source/icon_h_separator.svg diff --git a/tools/editor/icons/source/icon_h_slider.svg b/editor/icons/source/icon_h_slider.svg index beee5f8b6a..beee5f8b6a 100644 --- a/tools/editor/icons/source/icon_h_slider.svg +++ b/editor/icons/source/icon_h_slider.svg diff --git a/tools/editor/icons/source/icon_h_split_container.svg b/editor/icons/source/icon_h_split_container.svg index 9ca2df0ff1..9ca2df0ff1 100644 --- a/tools/editor/icons/source/icon_h_split_container.svg +++ b/editor/icons/source/icon_h_split_container.svg diff --git a/tools/editor/icons/source/icon_h_t_t_p_request.svg b/editor/icons/source/icon_h_t_t_p_request.svg index f43141dd7c..f43141dd7c 100644 --- a/tools/editor/icons/source/icon_h_t_t_p_request.svg +++ b/editor/icons/source/icon_h_t_t_p_request.svg diff --git a/tools/editor/icons/source/icon_headphones.svg b/editor/icons/source/icon_headphones.svg index 456a9b8d4e..456a9b8d4e 100644 --- a/tools/editor/icons/source/icon_headphones.svg +++ b/editor/icons/source/icon_headphones.svg diff --git a/tools/editor/icons/source/icon_help.svg b/editor/icons/source/icon_help.svg index 01e85e0f55..01e85e0f55 100644 --- a/tools/editor/icons/source/icon_help.svg +++ b/editor/icons/source/icon_help.svg diff --git a/tools/editor/icons/source/icon_hidden.svg b/editor/icons/source/icon_hidden.svg index 1d504f02fb..1d504f02fb 100644 --- a/tools/editor/icons/source/icon_hidden.svg +++ b/editor/icons/source/icon_hidden.svg diff --git a/tools/editor/icons/source/icon_hinge_joint.svg b/editor/icons/source/icon_hinge_joint.svg index 767feac9d5..767feac9d5 100644 --- a/tools/editor/icons/source/icon_hinge_joint.svg +++ b/editor/icons/source/icon_hinge_joint.svg diff --git a/tools/editor/icons/source/icon_history.svg b/editor/icons/source/icon_history.svg index f81390f0f5..f81390f0f5 100644 --- a/tools/editor/icons/source/icon_history.svg +++ b/editor/icons/source/icon_history.svg diff --git a/tools/editor/icons/source/icon_hsize.svg b/editor/icons/source/icon_hsize.svg index f24a630770..f24a630770 100644 --- a/tools/editor/icons/source/icon_hsize.svg +++ b/editor/icons/source/icon_hsize.svg diff --git a/tools/editor/icons/source/icon_image.svg b/editor/icons/source/icon_image.svg index bb15e96251..bb15e96251 100644 --- a/tools/editor/icons/source/icon_image.svg +++ b/editor/icons/source/icon_image.svg diff --git a/tools/editor/icons/source/icon_image_sky_box.svg b/editor/icons/source/icon_image_sky_box.svg index 9a89c04e58..9a89c04e58 100644 --- a/tools/editor/icons/source/icon_image_sky_box.svg +++ b/editor/icons/source/icon_image_sky_box.svg diff --git a/tools/editor/icons/source/icon_image_texture.svg b/editor/icons/source/icon_image_texture.svg index 39e88e592b..39e88e592b 100644 --- a/tools/editor/icons/source/icon_image_texture.svg +++ b/editor/icons/source/icon_image_texture.svg diff --git a/tools/editor/icons/source/icon_immediate_geometry.svg b/editor/icons/source/icon_immediate_geometry.svg index 54bc4766d9..54bc4766d9 100644 --- a/tools/editor/icons/source/icon_immediate_geometry.svg +++ b/editor/icons/source/icon_immediate_geometry.svg diff --git a/tools/editor/icons/source/icon_import_check.svg b/editor/icons/source/icon_import_check.svg index 606236d82e..606236d82e 100644 --- a/tools/editor/icons/source/icon_import_check.svg +++ b/editor/icons/source/icon_import_check.svg diff --git a/tools/editor/icons/source/icon_import_fail.svg b/editor/icons/source/icon_import_fail.svg index b5d142f968..b5d142f968 100644 --- a/tools/editor/icons/source/icon_import_fail.svg +++ b/editor/icons/source/icon_import_fail.svg diff --git a/tools/editor/icons/source/icon_instance.svg b/editor/icons/source/icon_instance.svg index f12e067e7a..f12e067e7a 100644 --- a/tools/editor/icons/source/icon_instance.svg +++ b/editor/icons/source/icon_instance.svg diff --git a/tools/editor/icons/source/icon_instance_options.svg b/editor/icons/source/icon_instance_options.svg index a8c00bc43f..a8c00bc43f 100644 --- a/tools/editor/icons/source/icon_instance_options.svg +++ b/editor/icons/source/icon_instance_options.svg diff --git a/tools/editor/icons/source/icon_integer.svg b/editor/icons/source/icon_integer.svg index d4e7a9860a..d4e7a9860a 100644 --- a/tools/editor/icons/source/icon_integer.svg +++ b/editor/icons/source/icon_integer.svg diff --git a/tools/editor/icons/source/icon_interp_cubic.svg b/editor/icons/source/icon_interp_cubic.svg index 7d8d5ef70d..7d8d5ef70d 100644 --- a/tools/editor/icons/source/icon_interp_cubic.svg +++ b/editor/icons/source/icon_interp_cubic.svg diff --git a/tools/editor/icons/source/icon_interp_linear.svg b/editor/icons/source/icon_interp_linear.svg index 7b1e4f2dd1..7b1e4f2dd1 100644 --- a/tools/editor/icons/source/icon_interp_linear.svg +++ b/editor/icons/source/icon_interp_linear.svg diff --git a/tools/editor/icons/source/icon_interp_raw.svg b/editor/icons/source/icon_interp_raw.svg index e2e2070449..e2e2070449 100644 --- a/tools/editor/icons/source/icon_interp_raw.svg +++ b/editor/icons/source/icon_interp_raw.svg diff --git a/tools/editor/icons/source/icon_interp_wrap_clamp.svg b/editor/icons/source/icon_interp_wrap_clamp.svg index 068e79ace0..068e79ace0 100644 --- a/tools/editor/icons/source/icon_interp_wrap_clamp.svg +++ b/editor/icons/source/icon_interp_wrap_clamp.svg diff --git a/tools/editor/icons/source/icon_interp_wrap_loop.svg b/editor/icons/source/icon_interp_wrap_loop.svg index bfca46331b..bfca46331b 100644 --- a/tools/editor/icons/source/icon_interp_wrap_loop.svg +++ b/editor/icons/source/icon_interp_wrap_loop.svg diff --git a/tools/editor/icons/source/icon_interpolated_camera.svg b/editor/icons/source/icon_interpolated_camera.svg index 16fc731c12..16fc731c12 100644 --- a/tools/editor/icons/source/icon_interpolated_camera.svg +++ b/editor/icons/source/icon_interpolated_camera.svg diff --git a/tools/editor/icons/source/icon_invalid_key.svg b/editor/icons/source/icon_invalid_key.svg index cbccff571a..cbccff571a 100644 --- a/tools/editor/icons/source/icon_invalid_key.svg +++ b/editor/icons/source/icon_invalid_key.svg diff --git a/tools/editor/icons/source/icon_inverse_kinematics.svg b/editor/icons/source/icon_inverse_kinematics.svg index 227d22f911..227d22f911 100644 --- a/tools/editor/icons/source/icon_inverse_kinematics.svg +++ b/editor/icons/source/icon_inverse_kinematics.svg diff --git a/tools/editor/icons/source/icon_item_list.svg b/editor/icons/source/icon_item_list.svg index 943f6fe435..943f6fe435 100644 --- a/tools/editor/icons/source/icon_item_list.svg +++ b/editor/icons/source/icon_item_list.svg diff --git a/tools/editor/icons/source/icon_joy_axis.svg b/editor/icons/source/icon_joy_axis.svg index 9313342a53..9313342a53 100644 --- a/tools/editor/icons/source/icon_joy_axis.svg +++ b/editor/icons/source/icon_joy_axis.svg diff --git a/tools/editor/icons/source/icon_joy_button.svg b/editor/icons/source/icon_joy_button.svg index f6d4344807..f6d4344807 100644 --- a/tools/editor/icons/source/icon_joy_button.svg +++ b/editor/icons/source/icon_joy_button.svg diff --git a/tools/editor/icons/source/icon_joypad.svg b/editor/icons/source/icon_joypad.svg index fb84462919..fb84462919 100644 --- a/tools/editor/icons/source/icon_joypad.svg +++ b/editor/icons/source/icon_joypad.svg diff --git a/tools/editor/icons/source/icon_key.svg b/editor/icons/source/icon_key.svg index f5d7b85381..f5d7b85381 100644 --- a/tools/editor/icons/source/icon_key.svg +++ b/editor/icons/source/icon_key.svg diff --git a/tools/editor/icons/source/icon_key_hover.svg b/editor/icons/source/icon_key_hover.svg index c3f34a781b..c3f34a781b 100644 --- a/tools/editor/icons/source/icon_key_hover.svg +++ b/editor/icons/source/icon_key_hover.svg diff --git a/tools/editor/icons/source/icon_key_invalid.svg b/editor/icons/source/icon_key_invalid.svg index b6407dc178..b6407dc178 100644 --- a/tools/editor/icons/source/icon_key_invalid.svg +++ b/editor/icons/source/icon_key_invalid.svg diff --git a/tools/editor/icons/source/icon_key_next.svg b/editor/icons/source/icon_key_next.svg index 942245305c..942245305c 100644 --- a/tools/editor/icons/source/icon_key_next.svg +++ b/editor/icons/source/icon_key_next.svg diff --git a/tools/editor/icons/source/icon_key_selected.svg b/editor/icons/source/icon_key_selected.svg index c3f01dbec8..c3f01dbec8 100644 --- a/tools/editor/icons/source/icon_key_selected.svg +++ b/editor/icons/source/icon_key_selected.svg diff --git a/tools/editor/icons/source/icon_key_value.svg b/editor/icons/source/icon_key_value.svg index 5e6333e54b..5e6333e54b 100644 --- a/tools/editor/icons/source/icon_key_value.svg +++ b/editor/icons/source/icon_key_value.svg diff --git a/tools/editor/icons/source/icon_key_xform.svg b/editor/icons/source/icon_key_xform.svg index 06a282f705..06a282f705 100644 --- a/tools/editor/icons/source/icon_key_xform.svg +++ b/editor/icons/source/icon_key_xform.svg diff --git a/tools/editor/icons/source/icon_keyboard.svg b/editor/icons/source/icon_keyboard.svg index a03798e4a4..a03798e4a4 100644 --- a/tools/editor/icons/source/icon_keyboard.svg +++ b/editor/icons/source/icon_keyboard.svg diff --git a/tools/editor/icons/source/icon_kinematic_body.svg b/editor/icons/source/icon_kinematic_body.svg index 6a4c8965ab..6a4c8965ab 100644 --- a/tools/editor/icons/source/icon_kinematic_body.svg +++ b/editor/icons/source/icon_kinematic_body.svg diff --git a/tools/editor/icons/source/icon_kinematic_body_2d.svg b/editor/icons/source/icon_kinematic_body_2d.svg index 04f140b930..04f140b930 100644 --- a/tools/editor/icons/source/icon_kinematic_body_2d.svg +++ b/editor/icons/source/icon_kinematic_body_2d.svg diff --git a/tools/editor/icons/source/icon_label.svg b/editor/icons/source/icon_label.svg index ac9b52be6f..ac9b52be6f 100644 --- a/tools/editor/icons/source/icon_label.svg +++ b/editor/icons/source/icon_label.svg diff --git a/tools/editor/icons/source/icon_large_texture.svg b/editor/icons/source/icon_large_texture.svg index 4db0342041..4db0342041 100644 --- a/tools/editor/icons/source/icon_large_texture.svg +++ b/editor/icons/source/icon_large_texture.svg diff --git a/tools/editor/icons/source/icon_light_2d.svg b/editor/icons/source/icon_light_2d.svg index 27e07a649a..27e07a649a 100644 --- a/tools/editor/icons/source/icon_light_2d.svg +++ b/editor/icons/source/icon_light_2d.svg diff --git a/tools/editor/icons/source/icon_light_occluder_2d.svg b/editor/icons/source/icon_light_occluder_2d.svg index 3558f3f2da..3558f3f2da 100644 --- a/tools/editor/icons/source/icon_light_occluder_2d.svg +++ b/editor/icons/source/icon_light_occluder_2d.svg diff --git a/tools/editor/icons/source/icon_line_2d.svg b/editor/icons/source/icon_line_2d.svg index 7f833f4a9c..7f833f4a9c 100644 --- a/tools/editor/icons/source/icon_line_2d.svg +++ b/editor/icons/source/icon_line_2d.svg diff --git a/tools/editor/icons/source/icon_line_edit.svg b/editor/icons/source/icon_line_edit.svg index 61ba1ebe7e..61ba1ebe7e 100644 --- a/tools/editor/icons/source/icon_line_edit.svg +++ b/editor/icons/source/icon_line_edit.svg diff --git a/tools/editor/icons/source/icon_line_shape_2d.svg b/editor/icons/source/icon_line_shape_2d.svg index 6a8ab39ef3..6a8ab39ef3 100644 --- a/tools/editor/icons/source/icon_line_shape_2d.svg +++ b/editor/icons/source/icon_line_shape_2d.svg diff --git a/tools/editor/icons/source/icon_link_button.svg b/editor/icons/source/icon_link_button.svg index 3872e43b29..3872e43b29 100644 --- a/tools/editor/icons/source/icon_link_button.svg +++ b/editor/icons/source/icon_link_button.svg diff --git a/tools/editor/icons/source/icon_list_select.svg b/editor/icons/source/icon_list_select.svg index 569a0c6fea..569a0c6fea 100644 --- a/tools/editor/icons/source/icon_list_select.svg +++ b/editor/icons/source/icon_list_select.svg diff --git a/tools/editor/icons/source/icon_listener.svg b/editor/icons/source/icon_listener.svg index f815cb842a..f815cb842a 100644 --- a/tools/editor/icons/source/icon_listener.svg +++ b/editor/icons/source/icon_listener.svg diff --git a/tools/editor/icons/source/icon_load.svg b/editor/icons/source/icon_load.svg index 395a5c1b8a..395a5c1b8a 100644 --- a/tools/editor/icons/source/icon_load.svg +++ b/editor/icons/source/icon_load.svg diff --git a/tools/editor/icons/source/icon_lock.svg b/editor/icons/source/icon_lock.svg index 140b073e83..140b073e83 100644 --- a/tools/editor/icons/source/icon_lock.svg +++ b/editor/icons/source/icon_lock.svg diff --git a/tools/editor/icons/source/icon_loop.svg b/editor/icons/source/icon_loop.svg index fe7f648648..fe7f648648 100644 --- a/tools/editor/icons/source/icon_loop.svg +++ b/editor/icons/source/icon_loop.svg diff --git a/tools/editor/icons/source/icon_loop_interpolation.svg b/editor/icons/source/icon_loop_interpolation.svg index 3733acb253..3733acb253 100644 --- a/tools/editor/icons/source/icon_loop_interpolation.svg +++ b/editor/icons/source/icon_loop_interpolation.svg diff --git a/tools/editor/icons/source/icon_main_play.svg b/editor/icons/source/icon_main_play.svg index 0fb48bb155..0fb48bb155 100644 --- a/tools/editor/icons/source/icon_main_play.svg +++ b/editor/icons/source/icon_main_play.svg diff --git a/tools/editor/icons/source/icon_main_stop.svg b/editor/icons/source/icon_main_stop.svg index 9d01bd5cf5..9d01bd5cf5 100644 --- a/tools/editor/icons/source/icon_main_stop.svg +++ b/editor/icons/source/icon_main_stop.svg diff --git a/tools/editor/icons/source/icon_margin_container.svg b/editor/icons/source/icon_margin_container.svg index 68a6971bd7..68a6971bd7 100644 --- a/tools/editor/icons/source/icon_margin_container.svg +++ b/editor/icons/source/icon_margin_container.svg diff --git a/tools/editor/icons/source/icon_material_preview_cube.svg b/editor/icons/source/icon_material_preview_cube.svg index 2e8e5a6457..2e8e5a6457 100644 --- a/tools/editor/icons/source/icon_material_preview_cube.svg +++ b/editor/icons/source/icon_material_preview_cube.svg diff --git a/tools/editor/icons/source/icon_material_preview_cube_off.svg b/editor/icons/source/icon_material_preview_cube_off.svg index e03905ed05..e03905ed05 100644 --- a/tools/editor/icons/source/icon_material_preview_cube_off.svg +++ b/editor/icons/source/icon_material_preview_cube_off.svg diff --git a/tools/editor/icons/source/icon_material_preview_light_1.svg b/editor/icons/source/icon_material_preview_light_1.svg index d8335641f6..d8335641f6 100644 --- a/tools/editor/icons/source/icon_material_preview_light_1.svg +++ b/editor/icons/source/icon_material_preview_light_1.svg diff --git a/tools/editor/icons/source/icon_material_preview_light_1_off.svg b/editor/icons/source/icon_material_preview_light_1_off.svg index c387b1845b..c387b1845b 100644 --- a/tools/editor/icons/source/icon_material_preview_light_1_off.svg +++ b/editor/icons/source/icon_material_preview_light_1_off.svg diff --git a/tools/editor/icons/source/icon_material_preview_light_2.svg b/editor/icons/source/icon_material_preview_light_2.svg index f192c19959..f192c19959 100644 --- a/tools/editor/icons/source/icon_material_preview_light_2.svg +++ b/editor/icons/source/icon_material_preview_light_2.svg diff --git a/tools/editor/icons/source/icon_material_preview_light_2_off.svg b/editor/icons/source/icon_material_preview_light_2_off.svg index 9d71248cba..9d71248cba 100644 --- a/tools/editor/icons/source/icon_material_preview_light_2_off.svg +++ b/editor/icons/source/icon_material_preview_light_2_off.svg diff --git a/tools/editor/icons/source/icon_material_preview_sphere.svg b/editor/icons/source/icon_material_preview_sphere.svg index 76a6ec97bd..76a6ec97bd 100644 --- a/tools/editor/icons/source/icon_material_preview_sphere.svg +++ b/editor/icons/source/icon_material_preview_sphere.svg diff --git a/tools/editor/icons/source/icon_material_preview_sphere_off.svg b/editor/icons/source/icon_material_preview_sphere_off.svg index f9c8cadb34..f9c8cadb34 100644 --- a/tools/editor/icons/source/icon_material_preview_sphere_off.svg +++ b/editor/icons/source/icon_material_preview_sphere_off.svg diff --git a/tools/editor/icons/source/icon_matrix.svg b/editor/icons/source/icon_matrix.svg index eacf2cdc9d..eacf2cdc9d 100644 --- a/tools/editor/icons/source/icon_matrix.svg +++ b/editor/icons/source/icon_matrix.svg diff --git a/tools/editor/icons/source/icon_menu_button.svg b/editor/icons/source/icon_menu_button.svg index 9cfbf2d502..9cfbf2d502 100644 --- a/tools/editor/icons/source/icon_menu_button.svg +++ b/editor/icons/source/icon_menu_button.svg diff --git a/tools/editor/icons/source/icon_mesh.svg b/editor/icons/source/icon_mesh.svg index f3c33a37b1..f3c33a37b1 100644 --- a/tools/editor/icons/source/icon_mesh.svg +++ b/editor/icons/source/icon_mesh.svg diff --git a/tools/editor/icons/source/icon_mesh_instance.svg b/editor/icons/source/icon_mesh_instance.svg index 51e6447eb2..51e6447eb2 100644 --- a/tools/editor/icons/source/icon_mesh_instance.svg +++ b/editor/icons/source/icon_mesh_instance.svg diff --git a/tools/editor/icons/source/icon_mesh_library.svg b/editor/icons/source/icon_mesh_library.svg index b908a4db6e..b908a4db6e 100644 --- a/tools/editor/icons/source/icon_mesh_library.svg +++ b/editor/icons/source/icon_mesh_library.svg diff --git a/tools/editor/icons/source/icon_mini_aabb.svg b/editor/icons/source/icon_mini_aabb.svg index ebfd505bea..ebfd505bea 100644 --- a/tools/editor/icons/source/icon_mini_aabb.svg +++ b/editor/icons/source/icon_mini_aabb.svg diff --git a/tools/editor/icons/source/icon_mini_array.svg b/editor/icons/source/icon_mini_array.svg index a0a2014fbb..a0a2014fbb 100644 --- a/tools/editor/icons/source/icon_mini_array.svg +++ b/editor/icons/source/icon_mini_array.svg diff --git a/tools/editor/icons/source/icon_mini_boolean.svg b/editor/icons/source/icon_mini_boolean.svg index eb17279a62..eb17279a62 100644 --- a/tools/editor/icons/source/icon_mini_boolean.svg +++ b/editor/icons/source/icon_mini_boolean.svg diff --git a/tools/editor/icons/source/icon_mini_color.svg b/editor/icons/source/icon_mini_color.svg index cdc176e00c..cdc176e00c 100644 --- a/tools/editor/icons/source/icon_mini_color.svg +++ b/editor/icons/source/icon_mini_color.svg diff --git a/tools/editor/icons/source/icon_mini_color_array.svg b/editor/icons/source/icon_mini_color_array.svg index 2ec0e186b5..2ec0e186b5 100644 --- a/tools/editor/icons/source/icon_mini_color_array.svg +++ b/editor/icons/source/icon_mini_color_array.svg diff --git a/tools/editor/icons/source/icon_mini_dictionary.svg b/editor/icons/source/icon_mini_dictionary.svg index 813ba97613..813ba97613 100644 --- a/tools/editor/icons/source/icon_mini_dictionary.svg +++ b/editor/icons/source/icon_mini_dictionary.svg diff --git a/tools/editor/icons/source/icon_mini_float.svg b/editor/icons/source/icon_mini_float.svg index 1007955ea9..1007955ea9 100644 --- a/tools/editor/icons/source/icon_mini_float.svg +++ b/editor/icons/source/icon_mini_float.svg diff --git a/tools/editor/icons/source/icon_mini_float_array.svg b/editor/icons/source/icon_mini_float_array.svg index 86807ca731..86807ca731 100644 --- a/tools/editor/icons/source/icon_mini_float_array.svg +++ b/editor/icons/source/icon_mini_float_array.svg diff --git a/tools/editor/icons/source/icon_mini_image.svg b/editor/icons/source/icon_mini_image.svg index 57faded5c8..57faded5c8 100644 --- a/tools/editor/icons/source/icon_mini_image.svg +++ b/editor/icons/source/icon_mini_image.svg diff --git a/tools/editor/icons/source/icon_mini_input.svg b/editor/icons/source/icon_mini_input.svg index 9e966f77d1..9e966f77d1 100644 --- a/tools/editor/icons/source/icon_mini_input.svg +++ b/editor/icons/source/icon_mini_input.svg diff --git a/tools/editor/icons/source/icon_mini_int_array.svg b/editor/icons/source/icon_mini_int_array.svg index 23b086d5e1..23b086d5e1 100644 --- a/tools/editor/icons/source/icon_mini_int_array.svg +++ b/editor/icons/source/icon_mini_int_array.svg diff --git a/tools/editor/icons/source/icon_mini_integer.svg b/editor/icons/source/icon_mini_integer.svg index c21322adb2..c21322adb2 100644 --- a/tools/editor/icons/source/icon_mini_integer.svg +++ b/editor/icons/source/icon_mini_integer.svg diff --git a/tools/editor/icons/source/icon_mini_matrix3.svg b/editor/icons/source/icon_mini_matrix3.svg index 592230d13c..592230d13c 100644 --- a/tools/editor/icons/source/icon_mini_matrix3.svg +++ b/editor/icons/source/icon_mini_matrix3.svg diff --git a/tools/editor/icons/source/icon_mini_matrix32.svg b/editor/icons/source/icon_mini_matrix32.svg index 5159ea0b87..5159ea0b87 100644 --- a/tools/editor/icons/source/icon_mini_matrix32.svg +++ b/editor/icons/source/icon_mini_matrix32.svg diff --git a/tools/editor/icons/source/icon_mini_object.svg b/editor/icons/source/icon_mini_object.svg index 380be34903..380be34903 100644 --- a/tools/editor/icons/source/icon_mini_object.svg +++ b/editor/icons/source/icon_mini_object.svg diff --git a/tools/editor/icons/source/icon_mini_path.svg b/editor/icons/source/icon_mini_path.svg index ef247b8b8c..ef247b8b8c 100644 --- a/tools/editor/icons/source/icon_mini_path.svg +++ b/editor/icons/source/icon_mini_path.svg diff --git a/tools/editor/icons/source/icon_mini_plane.svg b/editor/icons/source/icon_mini_plane.svg index bc3992cdd6..bc3992cdd6 100644 --- a/tools/editor/icons/source/icon_mini_plane.svg +++ b/editor/icons/source/icon_mini_plane.svg diff --git a/tools/editor/icons/source/icon_mini_quat.svg b/editor/icons/source/icon_mini_quat.svg index 27188a3410..27188a3410 100644 --- a/tools/editor/icons/source/icon_mini_quat.svg +++ b/editor/icons/source/icon_mini_quat.svg diff --git a/tools/editor/icons/source/icon_mini_raw_array.svg b/editor/icons/source/icon_mini_raw_array.svg index cb735b5615..cb735b5615 100644 --- a/tools/editor/icons/source/icon_mini_raw_array.svg +++ b/editor/icons/source/icon_mini_raw_array.svg diff --git a/tools/editor/icons/source/icon_mini_rect2.svg b/editor/icons/source/icon_mini_rect2.svg index ded27f049f..ded27f049f 100644 --- a/tools/editor/icons/source/icon_mini_rect2.svg +++ b/editor/icons/source/icon_mini_rect2.svg diff --git a/tools/editor/icons/source/icon_mini_rid.svg b/editor/icons/source/icon_mini_rid.svg index 6df13ae43d..6df13ae43d 100644 --- a/tools/editor/icons/source/icon_mini_rid.svg +++ b/editor/icons/source/icon_mini_rid.svg diff --git a/tools/editor/icons/source/icon_mini_string.svg b/editor/icons/source/icon_mini_string.svg index a655f70d33..a655f70d33 100644 --- a/tools/editor/icons/source/icon_mini_string.svg +++ b/editor/icons/source/icon_mini_string.svg diff --git a/tools/editor/icons/source/icon_mini_string_array.svg b/editor/icons/source/icon_mini_string_array.svg index cd2e850c49..cd2e850c49 100644 --- a/tools/editor/icons/source/icon_mini_string_array.svg +++ b/editor/icons/source/icon_mini_string_array.svg diff --git a/tools/editor/icons/source/icon_mini_transform.svg b/editor/icons/source/icon_mini_transform.svg index 6da4eb806d..6da4eb806d 100644 --- a/tools/editor/icons/source/icon_mini_transform.svg +++ b/editor/icons/source/icon_mini_transform.svg diff --git a/tools/editor/icons/source/icon_mini_variant.svg b/editor/icons/source/icon_mini_variant.svg index 6883baa584..6883baa584 100644 --- a/tools/editor/icons/source/icon_mini_variant.svg +++ b/editor/icons/source/icon_mini_variant.svg diff --git a/tools/editor/icons/source/icon_mini_vector2.svg b/editor/icons/source/icon_mini_vector2.svg index 5c9aaeccff..5c9aaeccff 100644 --- a/tools/editor/icons/source/icon_mini_vector2.svg +++ b/editor/icons/source/icon_mini_vector2.svg diff --git a/tools/editor/icons/source/icon_mini_vector2_array.svg b/editor/icons/source/icon_mini_vector2_array.svg index 03850f7c86..03850f7c86 100644 --- a/tools/editor/icons/source/icon_mini_vector2_array.svg +++ b/editor/icons/source/icon_mini_vector2_array.svg diff --git a/tools/editor/icons/source/icon_mini_vector3.svg b/editor/icons/source/icon_mini_vector3.svg index e99a211ae0..e99a211ae0 100644 --- a/tools/editor/icons/source/icon_mini_vector3.svg +++ b/editor/icons/source/icon_mini_vector3.svg diff --git a/tools/editor/icons/source/icon_mini_vector3_array.svg b/editor/icons/source/icon_mini_vector3_array.svg index bbac554614..bbac554614 100644 --- a/tools/editor/icons/source/icon_mini_vector3_array.svg +++ b/editor/icons/source/icon_mini_vector3_array.svg diff --git a/tools/editor/icons/source/icon_mirror_x.svg b/editor/icons/source/icon_mirror_x.svg index f24a630770..f24a630770 100644 --- a/tools/editor/icons/source/icon_mirror_x.svg +++ b/editor/icons/source/icon_mirror_x.svg diff --git a/tools/editor/icons/source/icon_mirror_y.svg b/editor/icons/source/icon_mirror_y.svg index bb913b84af..bb913b84af 100644 --- a/tools/editor/icons/source/icon_mirror_y.svg +++ b/editor/icons/source/icon_mirror_y.svg diff --git a/tools/editor/icons/source/icon_mouse.svg b/editor/icons/source/icon_mouse.svg index 731ceeefd8..731ceeefd8 100644 --- a/tools/editor/icons/source/icon_mouse.svg +++ b/editor/icons/source/icon_mouse.svg diff --git a/tools/editor/icons/source/icon_move_down.svg b/editor/icons/source/icon_move_down.svg index e83a69ad50..e83a69ad50 100644 --- a/tools/editor/icons/source/icon_move_down.svg +++ b/editor/icons/source/icon_move_down.svg diff --git a/tools/editor/icons/source/icon_move_point.svg b/editor/icons/source/icon_move_point.svg index c951d6b90a..c951d6b90a 100644 --- a/tools/editor/icons/source/icon_move_point.svg +++ b/editor/icons/source/icon_move_point.svg diff --git a/tools/editor/icons/source/icon_move_up.svg b/editor/icons/source/icon_move_up.svg index 8f671a0d72..8f671a0d72 100644 --- a/tools/editor/icons/source/icon_move_up.svg +++ b/editor/icons/source/icon_move_up.svg diff --git a/tools/editor/icons/source/icon_multi_edit.svg b/editor/icons/source/icon_multi_edit.svg index ef63861e97..ef63861e97 100644 --- a/tools/editor/icons/source/icon_multi_edit.svg +++ b/editor/icons/source/icon_multi_edit.svg diff --git a/tools/editor/icons/source/icon_multi_line.svg b/editor/icons/source/icon_multi_line.svg index 542e311286..542e311286 100644 --- a/tools/editor/icons/source/icon_multi_line.svg +++ b/editor/icons/source/icon_multi_line.svg diff --git a/tools/editor/icons/source/icon_multi_mesh.svg b/editor/icons/source/icon_multi_mesh.svg index 22f843a686..22f843a686 100644 --- a/tools/editor/icons/source/icon_multi_mesh.svg +++ b/editor/icons/source/icon_multi_mesh.svg diff --git a/tools/editor/icons/source/icon_multi_mesh_instance.svg b/editor/icons/source/icon_multi_mesh_instance.svg index deceae5a03..deceae5a03 100644 --- a/tools/editor/icons/source/icon_multi_mesh_instance.svg +++ b/editor/icons/source/icon_multi_mesh_instance.svg diff --git a/tools/editor/icons/source/icon_navigation.svg b/editor/icons/source/icon_navigation.svg index 42e8f59165..42e8f59165 100644 --- a/tools/editor/icons/source/icon_navigation.svg +++ b/editor/icons/source/icon_navigation.svg diff --git a/tools/editor/icons/source/icon_navigation_2d.svg b/editor/icons/source/icon_navigation_2d.svg index 5252541e70..5252541e70 100644 --- a/tools/editor/icons/source/icon_navigation_2d.svg +++ b/editor/icons/source/icon_navigation_2d.svg diff --git a/tools/editor/icons/source/icon_navigation_mesh.svg b/editor/icons/source/icon_navigation_mesh.svg index 31ab5df8ad..31ab5df8ad 100644 --- a/tools/editor/icons/source/icon_navigation_mesh.svg +++ b/editor/icons/source/icon_navigation_mesh.svg diff --git a/tools/editor/icons/source/icon_navigation_mesh_instance.svg b/editor/icons/source/icon_navigation_mesh_instance.svg index 5c4e0f1579..5c4e0f1579 100644 --- a/tools/editor/icons/source/icon_navigation_mesh_instance.svg +++ b/editor/icons/source/icon_navigation_mesh_instance.svg diff --git a/tools/editor/icons/source/icon_navigation_polygon.svg b/editor/icons/source/icon_navigation_polygon.svg index f3b6fcbcc3..f3b6fcbcc3 100644 --- a/tools/editor/icons/source/icon_navigation_polygon.svg +++ b/editor/icons/source/icon_navigation_polygon.svg diff --git a/tools/editor/icons/source/icon_navigation_polygon_instance.svg b/editor/icons/source/icon_navigation_polygon_instance.svg index 5153227b15..5153227b15 100644 --- a/tools/editor/icons/source/icon_navigation_polygon_instance.svg +++ b/editor/icons/source/icon_navigation_polygon_instance.svg diff --git a/tools/editor/icons/source/icon_new.svg b/editor/icons/source/icon_new.svg index a37ba1be3f..a37ba1be3f 100644 --- a/tools/editor/icons/source/icon_new.svg +++ b/editor/icons/source/icon_new.svg diff --git a/tools/editor/icons/source/icon_nine_patch_rect.svg b/editor/icons/source/icon_nine_patch_rect.svg index f12789c19e..f12789c19e 100644 --- a/tools/editor/icons/source/icon_nine_patch_rect.svg +++ b/editor/icons/source/icon_nine_patch_rect.svg diff --git a/tools/editor/icons/source/icon_node.svg b/editor/icons/source/icon_node.svg index 02e2774669..02e2774669 100644 --- a/tools/editor/icons/source/icon_node.svg +++ b/editor/icons/source/icon_node.svg diff --git a/tools/editor/icons/source/icon_node_2d.svg b/editor/icons/source/icon_node_2d.svg index e546f68539..e546f68539 100644 --- a/tools/editor/icons/source/icon_node_2d.svg +++ b/editor/icons/source/icon_node_2d.svg diff --git a/tools/editor/icons/source/icon_node_warning.svg b/editor/icons/source/icon_node_warning.svg index 89d3663fb0..89d3663fb0 100644 --- a/tools/editor/icons/source/icon_node_warning.svg +++ b/editor/icons/source/icon_node_warning.svg diff --git a/tools/editor/icons/source/icon_non_favorite.svg b/editor/icons/source/icon_non_favorite.svg index 54fcb8577e..54fcb8577e 100644 --- a/tools/editor/icons/source/icon_non_favorite.svg +++ b/editor/icons/source/icon_non_favorite.svg diff --git a/tools/editor/icons/source/icon_object.svg b/editor/icons/source/icon_object.svg index 6b36b61168..6b36b61168 100644 --- a/tools/editor/icons/source/icon_object.svg +++ b/editor/icons/source/icon_object.svg diff --git a/tools/editor/icons/source/icon_occluder_polygon_2d.svg b/editor/icons/source/icon_occluder_polygon_2d.svg index 8ae6dc176d..8ae6dc176d 100644 --- a/tools/editor/icons/source/icon_occluder_polygon_2d.svg +++ b/editor/icons/source/icon_occluder_polygon_2d.svg diff --git a/tools/editor/icons/source/icon_omni_light.svg b/editor/icons/source/icon_omni_light.svg index e1049d0039..e1049d0039 100644 --- a/tools/editor/icons/source/icon_omni_light.svg +++ b/editor/icons/source/icon_omni_light.svg diff --git a/tools/editor/icons/source/icon_option_button.svg b/editor/icons/source/icon_option_button.svg index 4537b14616..4537b14616 100644 --- a/tools/editor/icons/source/icon_option_button.svg +++ b/editor/icons/source/icon_option_button.svg diff --git a/tools/editor/icons/source/icon_override.svg b/editor/icons/source/icon_override.svg index b7948c531c..b7948c531c 100644 --- a/tools/editor/icons/source/icon_override.svg +++ b/editor/icons/source/icon_override.svg diff --git a/tools/editor/icons/source/icon_packed_data_container.svg b/editor/icons/source/icon_packed_data_container.svg index 70aed22f2c..70aed22f2c 100644 --- a/tools/editor/icons/source/icon_packed_data_container.svg +++ b/editor/icons/source/icon_packed_data_container.svg diff --git a/tools/editor/icons/source/icon_packed_scene.svg b/editor/icons/source/icon_packed_scene.svg index 910a274841..910a274841 100644 --- a/tools/editor/icons/source/icon_packed_scene.svg +++ b/editor/icons/source/icon_packed_scene.svg diff --git a/tools/editor/icons/source/icon_panel.svg b/editor/icons/source/icon_panel.svg index 28921c4031..28921c4031 100644 --- a/tools/editor/icons/source/icon_panel.svg +++ b/editor/icons/source/icon_panel.svg diff --git a/tools/editor/icons/source/icon_panel_container.svg b/editor/icons/source/icon_panel_container.svg index decf220705..decf220705 100644 --- a/tools/editor/icons/source/icon_panel_container.svg +++ b/editor/icons/source/icon_panel_container.svg diff --git a/tools/editor/icons/source/icon_panels_1.svg b/editor/icons/source/icon_panels_1.svg index fa8bbe9fad..fa8bbe9fad 100644 --- a/tools/editor/icons/source/icon_panels_1.svg +++ b/editor/icons/source/icon_panels_1.svg diff --git a/tools/editor/icons/source/icon_panels_2.svg b/editor/icons/source/icon_panels_2.svg index f00cc4b339..f00cc4b339 100644 --- a/tools/editor/icons/source/icon_panels_2.svg +++ b/editor/icons/source/icon_panels_2.svg diff --git a/tools/editor/icons/source/icon_panels_2_alt.svg b/editor/icons/source/icon_panels_2_alt.svg index cc3a634a3e..cc3a634a3e 100644 --- a/tools/editor/icons/source/icon_panels_2_alt.svg +++ b/editor/icons/source/icon_panels_2_alt.svg diff --git a/tools/editor/icons/source/icon_panels_3.svg b/editor/icons/source/icon_panels_3.svg index 04517c5a66..04517c5a66 100644 --- a/tools/editor/icons/source/icon_panels_3.svg +++ b/editor/icons/source/icon_panels_3.svg diff --git a/tools/editor/icons/source/icon_panels_3_alt.svg b/editor/icons/source/icon_panels_3_alt.svg index e5a9493287..e5a9493287 100644 --- a/tools/editor/icons/source/icon_panels_3_alt.svg +++ b/editor/icons/source/icon_panels_3_alt.svg diff --git a/tools/editor/icons/source/icon_panels_4.svg b/editor/icons/source/icon_panels_4.svg index 6d07a0b6d5..6d07a0b6d5 100644 --- a/tools/editor/icons/source/icon_panels_4.svg +++ b/editor/icons/source/icon_panels_4.svg diff --git a/tools/editor/icons/source/icon_parallax_background.svg b/editor/icons/source/icon_parallax_background.svg index e1b6a4fb2f..e1b6a4fb2f 100644 --- a/tools/editor/icons/source/icon_parallax_background.svg +++ b/editor/icons/source/icon_parallax_background.svg diff --git a/tools/editor/icons/source/icon_parallax_layer.svg b/editor/icons/source/icon_parallax_layer.svg index 022fdd5339..022fdd5339 100644 --- a/tools/editor/icons/source/icon_parallax_layer.svg +++ b/editor/icons/source/icon_parallax_layer.svg diff --git a/tools/editor/icons/source/icon_particle_attractor_2d.svg b/editor/icons/source/icon_particle_attractor_2d.svg index f755d7fc37..f755d7fc37 100644 --- a/tools/editor/icons/source/icon_particle_attractor_2d.svg +++ b/editor/icons/source/icon_particle_attractor_2d.svg diff --git a/tools/editor/icons/source/icon_particles.svg b/editor/icons/source/icon_particles.svg index f48929a7ef..f48929a7ef 100644 --- a/tools/editor/icons/source/icon_particles.svg +++ b/editor/icons/source/icon_particles.svg diff --git a/tools/editor/icons/source/icon_particles_2d.svg b/editor/icons/source/icon_particles_2d.svg index 1ad1d511f8..1ad1d511f8 100644 --- a/tools/editor/icons/source/icon_particles_2d.svg +++ b/editor/icons/source/icon_particles_2d.svg diff --git a/tools/editor/icons/source/icon_particles_shader.svg b/editor/icons/source/icon_particles_shader.svg index b4c2ef7ccd..b4c2ef7ccd 100644 --- a/tools/editor/icons/source/icon_particles_shader.svg +++ b/editor/icons/source/icon_particles_shader.svg diff --git a/tools/editor/icons/source/icon_patch_9_rect.svg b/editor/icons/source/icon_patch_9_rect.svg index c5a09603a6..c5a09603a6 100644 --- a/tools/editor/icons/source/icon_patch_9_rect.svg +++ b/editor/icons/source/icon_patch_9_rect.svg diff --git a/tools/editor/icons/source/icon_path.svg b/editor/icons/source/icon_path.svg index 39c63eac8a..39c63eac8a 100644 --- a/tools/editor/icons/source/icon_path.svg +++ b/editor/icons/source/icon_path.svg diff --git a/tools/editor/icons/source/icon_path_2d.svg b/editor/icons/source/icon_path_2d.svg index 6887834048..6887834048 100644 --- a/tools/editor/icons/source/icon_path_2d.svg +++ b/editor/icons/source/icon_path_2d.svg diff --git a/tools/editor/icons/source/icon_path_follow.svg b/editor/icons/source/icon_path_follow.svg index 6999df33de..6999df33de 100644 --- a/tools/editor/icons/source/icon_path_follow.svg +++ b/editor/icons/source/icon_path_follow.svg diff --git a/tools/editor/icons/source/icon_path_follow_2d.svg b/editor/icons/source/icon_path_follow_2d.svg index 020a094c0a..020a094c0a 100644 --- a/tools/editor/icons/source/icon_path_follow_2d.svg +++ b/editor/icons/source/icon_path_follow_2d.svg diff --git a/tools/editor/icons/source/icon_pause.svg b/editor/icons/source/icon_pause.svg index 411f1b22da..411f1b22da 100644 --- a/tools/editor/icons/source/icon_pause.svg +++ b/editor/icons/source/icon_pause.svg diff --git a/tools/editor/icons/source/icon_pin.svg b/editor/icons/source/icon_pin.svg index 8281b6438b..8281b6438b 100644 --- a/tools/editor/icons/source/icon_pin.svg +++ b/editor/icons/source/icon_pin.svg diff --git a/tools/editor/icons/source/icon_pin_joint.svg b/editor/icons/source/icon_pin_joint.svg index 47dbe6be60..47dbe6be60 100644 --- a/tools/editor/icons/source/icon_pin_joint.svg +++ b/editor/icons/source/icon_pin_joint.svg diff --git a/tools/editor/icons/source/icon_pin_joint_2d.svg b/editor/icons/source/icon_pin_joint_2d.svg index 90e1579903..90e1579903 100644 --- a/tools/editor/icons/source/icon_pin_joint_2d.svg +++ b/editor/icons/source/icon_pin_joint_2d.svg diff --git a/tools/editor/icons/source/icon_pin_pressed.svg b/editor/icons/source/icon_pin_pressed.svg index 8281b6438b..8281b6438b 100644 --- a/tools/editor/icons/source/icon_pin_pressed.svg +++ b/editor/icons/source/icon_pin_pressed.svg diff --git a/tools/editor/icons/source/icon_plane.svg b/editor/icons/source/icon_plane.svg index de5b5efc82..de5b5efc82 100644 --- a/tools/editor/icons/source/icon_plane.svg +++ b/editor/icons/source/icon_plane.svg diff --git a/tools/editor/icons/source/icon_plane_shape.svg b/editor/icons/source/icon_plane_shape.svg index b2d5e18b8f..b2d5e18b8f 100644 --- a/tools/editor/icons/source/icon_plane_shape.svg +++ b/editor/icons/source/icon_plane_shape.svg diff --git a/tools/editor/icons/source/icon_play.svg b/editor/icons/source/icon_play.svg index 9d3beab97d..9d3beab97d 100644 --- a/tools/editor/icons/source/icon_play.svg +++ b/editor/icons/source/icon_play.svg diff --git a/tools/editor/icons/source/icon_play_backwards.svg b/editor/icons/source/icon_play_backwards.svg index d93d529dd8..d93d529dd8 100644 --- a/tools/editor/icons/source/icon_play_backwards.svg +++ b/editor/icons/source/icon_play_backwards.svg diff --git a/tools/editor/icons/source/icon_play_custom.svg b/editor/icons/source/icon_play_custom.svg index 62ff7fe710..62ff7fe710 100644 --- a/tools/editor/icons/source/icon_play_custom.svg +++ b/editor/icons/source/icon_play_custom.svg diff --git a/tools/editor/icons/source/icon_play_scene.svg b/editor/icons/source/icon_play_scene.svg index 599cd14981..599cd14981 100644 --- a/tools/editor/icons/source/icon_play_scene.svg +++ b/editor/icons/source/icon_play_scene.svg diff --git a/tools/editor/icons/source/icon_play_start.svg b/editor/icons/source/icon_play_start.svg index 7157f59f35..7157f59f35 100644 --- a/tools/editor/icons/source/icon_play_start.svg +++ b/editor/icons/source/icon_play_start.svg diff --git a/tools/editor/icons/source/icon_play_start_backwards.svg b/editor/icons/source/icon_play_start_backwards.svg index 06998f1043..06998f1043 100644 --- a/tools/editor/icons/source/icon_play_start_backwards.svg +++ b/editor/icons/source/icon_play_start_backwards.svg diff --git a/tools/editor/icons/source/icon_polygon_path_finder.svg b/editor/icons/source/icon_polygon_path_finder.svg index c2f8d80c3d..c2f8d80c3d 100644 --- a/tools/editor/icons/source/icon_polygon_path_finder.svg +++ b/editor/icons/source/icon_polygon_path_finder.svg diff --git a/tools/editor/icons/source/icon_popup.svg b/editor/icons/source/icon_popup.svg index 1681e537f6..1681e537f6 100644 --- a/tools/editor/icons/source/icon_popup.svg +++ b/editor/icons/source/icon_popup.svg diff --git a/tools/editor/icons/source/icon_popup_dialog.svg b/editor/icons/source/icon_popup_dialog.svg index 54e14accc7..54e14accc7 100644 --- a/tools/editor/icons/source/icon_popup_dialog.svg +++ b/editor/icons/source/icon_popup_dialog.svg diff --git a/tools/editor/icons/source/icon_popup_menu.svg b/editor/icons/source/icon_popup_menu.svg index e812ca695b..e812ca695b 100644 --- a/tools/editor/icons/source/icon_popup_menu.svg +++ b/editor/icons/source/icon_popup_menu.svg diff --git a/tools/editor/icons/source/icon_popup_panel.svg b/editor/icons/source/icon_popup_panel.svg index c307257efe..c307257efe 100644 --- a/tools/editor/icons/source/icon_popup_panel.svg +++ b/editor/icons/source/icon_popup_panel.svg diff --git a/tools/editor/icons/source/icon_portal.svg b/editor/icons/source/icon_portal.svg index 2f3d22025f..2f3d22025f 100644 --- a/tools/editor/icons/source/icon_portal.svg +++ b/editor/icons/source/icon_portal.svg diff --git a/tools/editor/icons/source/icon_position_2d.svg b/editor/icons/source/icon_position_2d.svg index 4dbb2c188a..4dbb2c188a 100644 --- a/tools/editor/icons/source/icon_position_2d.svg +++ b/editor/icons/source/icon_position_2d.svg diff --git a/tools/editor/icons/source/icon_position_3d.svg b/editor/icons/source/icon_position_3d.svg index b735af4ac3..b735af4ac3 100644 --- a/tools/editor/icons/source/icon_position_3d.svg +++ b/editor/icons/source/icon_position_3d.svg diff --git a/tools/editor/icons/source/icon_progress_1.svg b/editor/icons/source/icon_progress_1.svg index 4b4694d0d4..4b4694d0d4 100644 --- a/tools/editor/icons/source/icon_progress_1.svg +++ b/editor/icons/source/icon_progress_1.svg diff --git a/tools/editor/icons/source/icon_progress_2.svg b/editor/icons/source/icon_progress_2.svg index 1edad60e03..1edad60e03 100644 --- a/tools/editor/icons/source/icon_progress_2.svg +++ b/editor/icons/source/icon_progress_2.svg diff --git a/tools/editor/icons/source/icon_progress_3.svg b/editor/icons/source/icon_progress_3.svg index 405a16854e..405a16854e 100644 --- a/tools/editor/icons/source/icon_progress_3.svg +++ b/editor/icons/source/icon_progress_3.svg diff --git a/tools/editor/icons/source/icon_progress_4.svg b/editor/icons/source/icon_progress_4.svg index 26e97928ee..26e97928ee 100644 --- a/tools/editor/icons/source/icon_progress_4.svg +++ b/editor/icons/source/icon_progress_4.svg diff --git a/tools/editor/icons/source/icon_progress_5.svg b/editor/icons/source/icon_progress_5.svg index 024190e9fd..024190e9fd 100644 --- a/tools/editor/icons/source/icon_progress_5.svg +++ b/editor/icons/source/icon_progress_5.svg diff --git a/tools/editor/icons/source/icon_progress_6.svg b/editor/icons/source/icon_progress_6.svg index 3783c528e7..3783c528e7 100644 --- a/tools/editor/icons/source/icon_progress_6.svg +++ b/editor/icons/source/icon_progress_6.svg diff --git a/tools/editor/icons/source/icon_progress_7.svg b/editor/icons/source/icon_progress_7.svg index 2a2c744b5b..2a2c744b5b 100644 --- a/tools/editor/icons/source/icon_progress_7.svg +++ b/editor/icons/source/icon_progress_7.svg diff --git a/tools/editor/icons/source/icon_progress_8.svg b/editor/icons/source/icon_progress_8.svg index 2331aee2e7..2331aee2e7 100644 --- a/tools/editor/icons/source/icon_progress_8.svg +++ b/editor/icons/source/icon_progress_8.svg diff --git a/tools/editor/icons/source/icon_progress_bar.svg b/editor/icons/source/icon_progress_bar.svg index 1a5458080b..1a5458080b 100644 --- a/tools/editor/icons/source/icon_progress_bar.svg +++ b/editor/icons/source/icon_progress_bar.svg diff --git a/tools/editor/icons/source/icon_proximity_group.svg b/editor/icons/source/icon_proximity_group.svg index 041d0c5ee2..041d0c5ee2 100644 --- a/tools/editor/icons/source/icon_proximity_group.svg +++ b/editor/icons/source/icon_proximity_group.svg diff --git a/tools/editor/icons/source/icon_quad.svg b/editor/icons/source/icon_quad.svg index 86bb1979e7..86bb1979e7 100644 --- a/tools/editor/icons/source/icon_quad.svg +++ b/editor/icons/source/icon_quad.svg diff --git a/tools/editor/icons/source/icon_quat.svg b/editor/icons/source/icon_quat.svg index 36560d9d8f..36560d9d8f 100644 --- a/tools/editor/icons/source/icon_quat.svg +++ b/editor/icons/source/icon_quat.svg diff --git a/tools/editor/icons/source/icon_range.svg b/editor/icons/source/icon_range.svg index 1dd857ff32..1dd857ff32 100644 --- a/tools/editor/icons/source/icon_range.svg +++ b/editor/icons/source/icon_range.svg diff --git a/tools/editor/icons/source/icon_rating_no_star.svg b/editor/icons/source/icon_rating_no_star.svg index 09a9efa112..09a9efa112 100644 --- a/tools/editor/icons/source/icon_rating_no_star.svg +++ b/editor/icons/source/icon_rating_no_star.svg diff --git a/tools/editor/icons/source/icon_rating_star.svg b/editor/icons/source/icon_rating_star.svg index 7ed3f9fbfa..7ed3f9fbfa 100644 --- a/tools/editor/icons/source/icon_rating_star.svg +++ b/editor/icons/source/icon_rating_star.svg diff --git a/tools/editor/icons/source/icon_ray_cast.svg b/editor/icons/source/icon_ray_cast.svg index b8cab72d07..b8cab72d07 100644 --- a/tools/editor/icons/source/icon_ray_cast.svg +++ b/editor/icons/source/icon_ray_cast.svg diff --git a/tools/editor/icons/source/icon_ray_cast_2d.svg b/editor/icons/source/icon_ray_cast_2d.svg index faadd41a17..faadd41a17 100644 --- a/tools/editor/icons/source/icon_ray_cast_2d.svg +++ b/editor/icons/source/icon_ray_cast_2d.svg diff --git a/tools/editor/icons/source/icon_ray_shape.svg b/editor/icons/source/icon_ray_shape.svg index 0e0f2940ae..0e0f2940ae 100644 --- a/tools/editor/icons/source/icon_ray_shape.svg +++ b/editor/icons/source/icon_ray_shape.svg diff --git a/tools/editor/icons/source/icon_ray_shape_2d.svg b/editor/icons/source/icon_ray_shape_2d.svg index 7ffc2ff3b5..7ffc2ff3b5 100644 --- a/tools/editor/icons/source/icon_ray_shape_2d.svg +++ b/editor/icons/source/icon_ray_shape_2d.svg diff --git a/tools/editor/icons/source/icon_rayito.svg b/editor/icons/source/icon_rayito.svg index 56988b9e4f..56988b9e4f 100644 --- a/tools/editor/icons/source/icon_rayito.svg +++ b/editor/icons/source/icon_rayito.svg diff --git a/tools/editor/icons/source/icon_real.svg b/editor/icons/source/icon_real.svg index 1a3406ed48..1a3406ed48 100644 --- a/tools/editor/icons/source/icon_real.svg +++ b/editor/icons/source/icon_real.svg diff --git a/tools/editor/icons/source/icon_rectangle_shape_2d.svg b/editor/icons/source/icon_rectangle_shape_2d.svg index d362944e7a..d362944e7a 100644 --- a/tools/editor/icons/source/icon_rectangle_shape_2d.svg +++ b/editor/icons/source/icon_rectangle_shape_2d.svg diff --git a/tools/editor/icons/source/icon_reference_rect.svg b/editor/icons/source/icon_reference_rect.svg index cee814360d..cee814360d 100644 --- a/tools/editor/icons/source/icon_reference_rect.svg +++ b/editor/icons/source/icon_reference_rect.svg diff --git a/tools/editor/icons/source/icon_reflection_probe.svg b/editor/icons/source/icon_reflection_probe.svg index 64b6493d6d..64b6493d6d 100644 --- a/tools/editor/icons/source/icon_reflection_probe.svg +++ b/editor/icons/source/icon_reflection_probe.svg diff --git a/tools/editor/icons/source/icon_region_edit.svg b/editor/icons/source/icon_region_edit.svg index b42a53e88d..b42a53e88d 100644 --- a/tools/editor/icons/source/icon_region_edit.svg +++ b/editor/icons/source/icon_region_edit.svg diff --git a/tools/editor/icons/source/icon_reload_small.svg b/editor/icons/source/icon_reload_small.svg index 2d891c2238..2d891c2238 100644 --- a/tools/editor/icons/source/icon_reload_small.svg +++ b/editor/icons/source/icon_reload_small.svg diff --git a/tools/editor/icons/source/icon_remote.svg b/editor/icons/source/icon_remote.svg index f5b458c348..f5b458c348 100644 --- a/tools/editor/icons/source/icon_remote.svg +++ b/editor/icons/source/icon_remote.svg diff --git a/tools/editor/icons/source/icon_remote_transform.svg b/editor/icons/source/icon_remote_transform.svg index fbbfacf629..fbbfacf629 100644 --- a/tools/editor/icons/source/icon_remote_transform.svg +++ b/editor/icons/source/icon_remote_transform.svg diff --git a/tools/editor/icons/source/icon_remote_transform_2d.svg b/editor/icons/source/icon_remote_transform_2d.svg index 479cc0eb25..479cc0eb25 100644 --- a/tools/editor/icons/source/icon_remote_transform_2d.svg +++ b/editor/icons/source/icon_remote_transform_2d.svg diff --git a/tools/editor/icons/source/icon_remove.svg b/editor/icons/source/icon_remove.svg index 9d75f1e921..9d75f1e921 100644 --- a/tools/editor/icons/source/icon_remove.svg +++ b/editor/icons/source/icon_remove.svg diff --git a/tools/editor/icons/source/icon_rename.svg b/editor/icons/source/icon_rename.svg index 41eb10c7fc..41eb10c7fc 100644 --- a/tools/editor/icons/source/icon_rename.svg +++ b/editor/icons/source/icon_rename.svg diff --git a/tools/editor/icons/source/icon_reparent.svg b/editor/icons/source/icon_reparent.svg index 79543fe066..79543fe066 100644 --- a/tools/editor/icons/source/icon_reparent.svg +++ b/editor/icons/source/icon_reparent.svg diff --git a/tools/editor/icons/source/icon_resource_preloader.svg b/editor/icons/source/icon_resource_preloader.svg index bab1bb4e1e..bab1bb4e1e 100644 --- a/tools/editor/icons/source/icon_resource_preloader.svg +++ b/editor/icons/source/icon_resource_preloader.svg diff --git a/tools/editor/icons/source/icon_rich_text_label.svg b/editor/icons/source/icon_rich_text_label.svg index 4a77dbe672..4a77dbe672 100644 --- a/tools/editor/icons/source/icon_rich_text_label.svg +++ b/editor/icons/source/icon_rich_text_label.svg diff --git a/tools/editor/icons/source/icon_rigid_body.svg b/editor/icons/source/icon_rigid_body.svg index 6bebb5250f..6bebb5250f 100644 --- a/tools/editor/icons/source/icon_rigid_body.svg +++ b/editor/icons/source/icon_rigid_body.svg diff --git a/tools/editor/icons/source/icon_rigid_body_2d.svg b/editor/icons/source/icon_rigid_body_2d.svg index 9c8309ecfb..9c8309ecfb 100644 --- a/tools/editor/icons/source/icon_rigid_body_2d.svg +++ b/editor/icons/source/icon_rigid_body_2d.svg diff --git a/tools/editor/icons/source/icon_room.svg b/editor/icons/source/icon_room.svg index 599bbeb770..599bbeb770 100644 --- a/tools/editor/icons/source/icon_room.svg +++ b/editor/icons/source/icon_room.svg diff --git a/tools/editor/icons/source/icon_room_bounds.svg b/editor/icons/source/icon_room_bounds.svg index 8f7e6e6c83..8f7e6e6c83 100644 --- a/tools/editor/icons/source/icon_room_bounds.svg +++ b/editor/icons/source/icon_room_bounds.svg diff --git a/tools/editor/icons/source/icon_rotate_0.svg b/editor/icons/source/icon_rotate_0.svg index 710edc8fee..710edc8fee 100644 --- a/tools/editor/icons/source/icon_rotate_0.svg +++ b/editor/icons/source/icon_rotate_0.svg diff --git a/tools/editor/icons/source/icon_rotate_180.svg b/editor/icons/source/icon_rotate_180.svg index ba44fa295d..ba44fa295d 100644 --- a/tools/editor/icons/source/icon_rotate_180.svg +++ b/editor/icons/source/icon_rotate_180.svg diff --git a/tools/editor/icons/source/icon_rotate_270.svg b/editor/icons/source/icon_rotate_270.svg index 403321cb89..403321cb89 100644 --- a/tools/editor/icons/source/icon_rotate_270.svg +++ b/editor/icons/source/icon_rotate_270.svg diff --git a/tools/editor/icons/source/icon_rotate_90.svg b/editor/icons/source/icon_rotate_90.svg index f6b7d84032..f6b7d84032 100644 --- a/tools/editor/icons/source/icon_rotate_90.svg +++ b/editor/icons/source/icon_rotate_90.svg diff --git a/tools/editor/icons/source/icon_sample.svg b/editor/icons/source/icon_sample.svg index 782e07a012..782e07a012 100644 --- a/tools/editor/icons/source/icon_sample.svg +++ b/editor/icons/source/icon_sample.svg diff --git a/tools/editor/icons/source/icon_sample_library.svg b/editor/icons/source/icon_sample_library.svg index 78b01430c2..78b01430c2 100644 --- a/tools/editor/icons/source/icon_sample_library.svg +++ b/editor/icons/source/icon_sample_library.svg diff --git a/tools/editor/icons/source/icon_sample_player.svg b/editor/icons/source/icon_sample_player.svg index 2254718a9b..2254718a9b 100644 --- a/tools/editor/icons/source/icon_sample_player.svg +++ b/editor/icons/source/icon_sample_player.svg diff --git a/tools/editor/icons/source/icon_sample_player_2d.svg b/editor/icons/source/icon_sample_player_2d.svg index 33a7eba019..33a7eba019 100644 --- a/tools/editor/icons/source/icon_sample_player_2d.svg +++ b/editor/icons/source/icon_sample_player_2d.svg diff --git a/tools/editor/icons/source/icon_save.svg b/editor/icons/source/icon_save.svg index 9307537d4b..9307537d4b 100644 --- a/tools/editor/icons/source/icon_save.svg +++ b/editor/icons/source/icon_save.svg diff --git a/tools/editor/icons/source/icon_script.svg b/editor/icons/source/icon_script.svg index 8073692ce8..8073692ce8 100644 --- a/tools/editor/icons/source/icon_script.svg +++ b/editor/icons/source/icon_script.svg diff --git a/tools/editor/icons/source/icon_script_create.svg b/editor/icons/source/icon_script_create.svg index 0cf16a9c3b..0cf16a9c3b 100644 --- a/tools/editor/icons/source/icon_script_create.svg +++ b/editor/icons/source/icon_script_create.svg diff --git a/tools/editor/icons/source/icon_script_remove.svg b/editor/icons/source/icon_script_remove.svg index 1a0a0eebe3..1a0a0eebe3 100644 --- a/tools/editor/icons/source/icon_script_remove.svg +++ b/editor/icons/source/icon_script_remove.svg diff --git a/tools/editor/icons/source/icon_scroll_bar.svg b/editor/icons/source/icon_scroll_bar.svg index 2f007c7c94..2f007c7c94 100644 --- a/tools/editor/icons/source/icon_scroll_bar.svg +++ b/editor/icons/source/icon_scroll_bar.svg diff --git a/tools/editor/icons/source/icon_scroll_container.svg b/editor/icons/source/icon_scroll_container.svg index d694b646e0..d694b646e0 100644 --- a/tools/editor/icons/source/icon_scroll_container.svg +++ b/editor/icons/source/icon_scroll_container.svg diff --git a/tools/editor/icons/source/icon_segment_shape_2d.svg b/editor/icons/source/icon_segment_shape_2d.svg index b509a31362..b509a31362 100644 --- a/tools/editor/icons/source/icon_segment_shape_2d.svg +++ b/editor/icons/source/icon_segment_shape_2d.svg diff --git a/tools/editor/icons/source/icon_shader.svg b/editor/icons/source/icon_shader.svg index 1a2393fec2..1a2393fec2 100644 --- a/tools/editor/icons/source/icon_shader.svg +++ b/editor/icons/source/icon_shader.svg diff --git a/tools/editor/icons/source/icon_short_cut.svg b/editor/icons/source/icon_short_cut.svg index 05069e8ea1..05069e8ea1 100644 --- a/tools/editor/icons/source/icon_short_cut.svg +++ b/editor/icons/source/icon_short_cut.svg diff --git a/tools/editor/icons/source/icon_signal.svg b/editor/icons/source/icon_signal.svg index b4d3ff5ac8..b4d3ff5ac8 100644 --- a/tools/editor/icons/source/icon_signal.svg +++ b/editor/icons/source/icon_signal.svg diff --git a/tools/editor/icons/source/icon_skeleton.svg b/editor/icons/source/icon_skeleton.svg index 2850b0331d..2850b0331d 100644 --- a/tools/editor/icons/source/icon_skeleton.svg +++ b/editor/icons/source/icon_skeleton.svg diff --git a/tools/editor/icons/source/icon_slider_joint.svg b/editor/icons/source/icon_slider_joint.svg index 021a295186..021a295186 100644 --- a/tools/editor/icons/source/icon_slider_joint.svg +++ b/editor/icons/source/icon_slider_joint.svg diff --git a/tools/editor/icons/source/icon_slot.svg b/editor/icons/source/icon_slot.svg index d613f1e1a4..d613f1e1a4 100644 --- a/tools/editor/icons/source/icon_slot.svg +++ b/editor/icons/source/icon_slot.svg diff --git a/tools/editor/icons/source/icon_snap.svg b/editor/icons/source/icon_snap.svg index 321dedf6b6..321dedf6b6 100644 --- a/tools/editor/icons/source/icon_snap.svg +++ b/editor/icons/source/icon_snap.svg diff --git a/tools/editor/icons/source/icon_sound_room_params.svg b/editor/icons/source/icon_sound_room_params.svg index a71c126ddc..a71c126ddc 100644 --- a/tools/editor/icons/source/icon_sound_room_params.svg +++ b/editor/icons/source/icon_sound_room_params.svg diff --git a/tools/editor/icons/source/icon_spatial.svg b/editor/icons/source/icon_spatial.svg index 0d03754016..0d03754016 100644 --- a/tools/editor/icons/source/icon_spatial.svg +++ b/editor/icons/source/icon_spatial.svg diff --git a/tools/editor/icons/source/icon_spatial_sample_player.svg b/editor/icons/source/icon_spatial_sample_player.svg index 9b5f5d9af6..9b5f5d9af6 100644 --- a/tools/editor/icons/source/icon_spatial_sample_player.svg +++ b/editor/icons/source/icon_spatial_sample_player.svg diff --git a/tools/editor/icons/source/icon_spatial_shader.svg b/editor/icons/source/icon_spatial_shader.svg index 329354b716..329354b716 100644 --- a/tools/editor/icons/source/icon_spatial_shader.svg +++ b/editor/icons/source/icon_spatial_shader.svg diff --git a/tools/editor/icons/source/icon_spatial_stream_player.svg b/editor/icons/source/icon_spatial_stream_player.svg index bd081a3dc2..bd081a3dc2 100644 --- a/tools/editor/icons/source/icon_spatial_stream_player.svg +++ b/editor/icons/source/icon_spatial_stream_player.svg diff --git a/tools/editor/icons/source/icon_sphere_shape.svg b/editor/icons/source/icon_sphere_shape.svg index b1bca49f97..b1bca49f97 100644 --- a/tools/editor/icons/source/icon_sphere_shape.svg +++ b/editor/icons/source/icon_sphere_shape.svg diff --git a/tools/editor/icons/source/icon_spin_box.svg b/editor/icons/source/icon_spin_box.svg index e0086ed12e..e0086ed12e 100644 --- a/tools/editor/icons/source/icon_spin_box.svg +++ b/editor/icons/source/icon_spin_box.svg diff --git a/tools/editor/icons/source/icon_spot_light.svg b/editor/icons/source/icon_spot_light.svg index 04f5b42f4d..04f5b42f4d 100644 --- a/tools/editor/icons/source/icon_spot_light.svg +++ b/editor/icons/source/icon_spot_light.svg diff --git a/tools/editor/icons/source/icon_sprite.svg b/editor/icons/source/icon_sprite.svg index 488bbf934d..488bbf934d 100644 --- a/tools/editor/icons/source/icon_sprite.svg +++ b/editor/icons/source/icon_sprite.svg diff --git a/tools/editor/icons/source/icon_sprite_3d.svg b/editor/icons/source/icon_sprite_3d.svg index 4ea81f7ea2..4ea81f7ea2 100644 --- a/tools/editor/icons/source/icon_sprite_3d.svg +++ b/editor/icons/source/icon_sprite_3d.svg diff --git a/tools/editor/icons/source/icon_sprite_frames.svg b/editor/icons/source/icon_sprite_frames.svg index dc445da773..dc445da773 100644 --- a/tools/editor/icons/source/icon_sprite_frames.svg +++ b/editor/icons/source/icon_sprite_frames.svg diff --git a/tools/editor/icons/source/icon_static_body.svg b/editor/icons/source/icon_static_body.svg index fcaa2b7d3e..fcaa2b7d3e 100644 --- a/tools/editor/icons/source/icon_static_body.svg +++ b/editor/icons/source/icon_static_body.svg diff --git a/tools/editor/icons/source/icon_static_body_2d.svg b/editor/icons/source/icon_static_body_2d.svg index 0ed3ef7cf0..0ed3ef7cf0 100644 --- a/tools/editor/icons/source/icon_static_body_2d.svg +++ b/editor/icons/source/icon_static_body_2d.svg diff --git a/tools/editor/icons/source/icon_stream_player.svg b/editor/icons/source/icon_stream_player.svg index 618646bbed..618646bbed 100644 --- a/tools/editor/icons/source/icon_stream_player.svg +++ b/editor/icons/source/icon_stream_player.svg diff --git a/tools/editor/icons/source/icon_string.svg b/editor/icons/source/icon_string.svg index f32e82256f..f32e82256f 100644 --- a/tools/editor/icons/source/icon_string.svg +++ b/editor/icons/source/icon_string.svg diff --git a/tools/editor/icons/source/icon_style_box_empty.svg b/editor/icons/source/icon_style_box_empty.svg index c881fe1c10..c881fe1c10 100644 --- a/tools/editor/icons/source/icon_style_box_empty.svg +++ b/editor/icons/source/icon_style_box_empty.svg diff --git a/tools/editor/icons/source/icon_style_box_flat.svg b/editor/icons/source/icon_style_box_flat.svg index 9071014ff3..9071014ff3 100644 --- a/tools/editor/icons/source/icon_style_box_flat.svg +++ b/editor/icons/source/icon_style_box_flat.svg diff --git a/tools/editor/icons/source/icon_style_box_texture.svg b/editor/icons/source/icon_style_box_texture.svg index 30b1f1af68..30b1f1af68 100644 --- a/tools/editor/icons/source/icon_style_box_texture.svg +++ b/editor/icons/source/icon_style_box_texture.svg diff --git a/tools/editor/icons/source/icon_tab_container.svg b/editor/icons/source/icon_tab_container.svg index 6c197a86f6..6c197a86f6 100644 --- a/tools/editor/icons/source/icon_tab_container.svg +++ b/editor/icons/source/icon_tab_container.svg diff --git a/tools/editor/icons/source/icon_tabs.svg b/editor/icons/source/icon_tabs.svg index 79ed1e5910..79ed1e5910 100644 --- a/tools/editor/icons/source/icon_tabs.svg +++ b/editor/icons/source/icon_tabs.svg diff --git a/tools/editor/icons/source/icon_test_cube.svg b/editor/icons/source/icon_test_cube.svg index c42c0bb674..c42c0bb674 100644 --- a/tools/editor/icons/source/icon_test_cube.svg +++ b/editor/icons/source/icon_test_cube.svg diff --git a/tools/editor/icons/source/icon_text_edit.svg b/editor/icons/source/icon_text_edit.svg index 4d08e9e3b2..4d08e9e3b2 100644 --- a/tools/editor/icons/source/icon_text_edit.svg +++ b/editor/icons/source/icon_text_edit.svg diff --git a/tools/editor/icons/source/icon_texture.svg b/editor/icons/source/icon_texture.svg index 39e88e592b..39e88e592b 100644 --- a/tools/editor/icons/source/icon_texture.svg +++ b/editor/icons/source/icon_texture.svg diff --git a/tools/editor/icons/source/icon_texture_button.svg b/editor/icons/source/icon_texture_button.svg index ef447af082..ef447af082 100644 --- a/tools/editor/icons/source/icon_texture_button.svg +++ b/editor/icons/source/icon_texture_button.svg diff --git a/tools/editor/icons/source/icon_texture_progress.svg b/editor/icons/source/icon_texture_progress.svg index 493dd7fd63..493dd7fd63 100644 --- a/tools/editor/icons/source/icon_texture_progress.svg +++ b/editor/icons/source/icon_texture_progress.svg diff --git a/tools/editor/icons/source/icon_texture_rect.svg b/editor/icons/source/icon_texture_rect.svg index 88d9b4081f..88d9b4081f 100644 --- a/tools/editor/icons/source/icon_texture_rect.svg +++ b/editor/icons/source/icon_texture_rect.svg diff --git a/tools/editor/icons/source/icon_theme.svg b/editor/icons/source/icon_theme.svg index 2cacb9755a..2cacb9755a 100644 --- a/tools/editor/icons/source/icon_theme.svg +++ b/editor/icons/source/icon_theme.svg diff --git a/tools/editor/icons/source/icon_tile_map.svg b/editor/icons/source/icon_tile_map.svg index 28f75a97e5..28f75a97e5 100644 --- a/tools/editor/icons/source/icon_tile_map.svg +++ b/editor/icons/source/icon_tile_map.svg diff --git a/tools/editor/icons/source/icon_tile_set.svg b/editor/icons/source/icon_tile_set.svg index e697f03888..e697f03888 100644 --- a/tools/editor/icons/source/icon_tile_set.svg +++ b/editor/icons/source/icon_tile_set.svg diff --git a/tools/editor/icons/source/icon_timer.svg b/editor/icons/source/icon_timer.svg index 0615ab865a..0615ab865a 100644 --- a/tools/editor/icons/source/icon_timer.svg +++ b/editor/icons/source/icon_timer.svg diff --git a/tools/editor/icons/source/icon_tool_button.svg b/editor/icons/source/icon_tool_button.svg index 1c5176c8c9..1c5176c8c9 100644 --- a/tools/editor/icons/source/icon_tool_button.svg +++ b/editor/icons/source/icon_tool_button.svg diff --git a/tools/editor/icons/source/icon_tool_move.svg b/editor/icons/source/icon_tool_move.svg index 243b680dfe..243b680dfe 100644 --- a/tools/editor/icons/source/icon_tool_move.svg +++ b/editor/icons/source/icon_tool_move.svg diff --git a/tools/editor/icons/source/icon_tool_pan.svg b/editor/icons/source/icon_tool_pan.svg index a93fc3d29d..a93fc3d29d 100644 --- a/tools/editor/icons/source/icon_tool_pan.svg +++ b/editor/icons/source/icon_tool_pan.svg diff --git a/tools/editor/icons/source/icon_tool_rotate.svg b/editor/icons/source/icon_tool_rotate.svg index 817aee3995..817aee3995 100644 --- a/tools/editor/icons/source/icon_tool_rotate.svg +++ b/editor/icons/source/icon_tool_rotate.svg diff --git a/tools/editor/icons/source/icon_tool_scale.svg b/editor/icons/source/icon_tool_scale.svg index 515bef3bb7..515bef3bb7 100644 --- a/tools/editor/icons/source/icon_tool_scale.svg +++ b/editor/icons/source/icon_tool_scale.svg diff --git a/tools/editor/icons/source/icon_tool_select.svg b/editor/icons/source/icon_tool_select.svg index 2da6a3e6ba..2da6a3e6ba 100644 --- a/tools/editor/icons/source/icon_tool_select.svg +++ b/editor/icons/source/icon_tool_select.svg diff --git a/tools/editor/icons/source/icon_tools.svg b/editor/icons/source/icon_tools.svg index f2b8cd9343..f2b8cd9343 100644 --- a/tools/editor/icons/source/icon_tools.svg +++ b/editor/icons/source/icon_tools.svg diff --git a/tools/editor/icons/source/icon_touch_screen_button.svg b/editor/icons/source/icon_touch_screen_button.svg index 70abc964aa..70abc964aa 100644 --- a/tools/editor/icons/source/icon_touch_screen_button.svg +++ b/editor/icons/source/icon_touch_screen_button.svg diff --git a/tools/editor/icons/source/icon_track_add_key.svg b/editor/icons/source/icon_track_add_key.svg index f550f922bb..f550f922bb 100644 --- a/tools/editor/icons/source/icon_track_add_key.svg +++ b/editor/icons/source/icon_track_add_key.svg diff --git a/tools/editor/icons/source/icon_track_add_key_hl.svg b/editor/icons/source/icon_track_add_key_hl.svg index 1b45cf8c4a..1b45cf8c4a 100644 --- a/tools/editor/icons/source/icon_track_add_key_hl.svg +++ b/editor/icons/source/icon_track_add_key_hl.svg diff --git a/tools/editor/icons/source/icon_track_continuous.svg b/editor/icons/source/icon_track_continuous.svg index 78b9dd3f4b..78b9dd3f4b 100644 --- a/tools/editor/icons/source/icon_track_continuous.svg +++ b/editor/icons/source/icon_track_continuous.svg diff --git a/tools/editor/icons/source/icon_track_discrete.svg b/editor/icons/source/icon_track_discrete.svg index 381782cf6f..381782cf6f 100644 --- a/tools/editor/icons/source/icon_track_discrete.svg +++ b/editor/icons/source/icon_track_discrete.svg diff --git a/tools/editor/icons/source/icon_track_trigger.svg b/editor/icons/source/icon_track_trigger.svg index 9c13791f70..9c13791f70 100644 --- a/tools/editor/icons/source/icon_track_trigger.svg +++ b/editor/icons/source/icon_track_trigger.svg diff --git a/tools/editor/icons/source/icon_translation.svg b/editor/icons/source/icon_translation.svg index 389b8a40de..389b8a40de 100644 --- a/tools/editor/icons/source/icon_translation.svg +++ b/editor/icons/source/icon_translation.svg diff --git a/tools/editor/icons/source/icon_transpose.svg b/editor/icons/source/icon_transpose.svg index ceccfecfa3..ceccfecfa3 100644 --- a/tools/editor/icons/source/icon_transpose.svg +++ b/editor/icons/source/icon_transpose.svg diff --git a/tools/editor/icons/source/icon_tree.svg b/editor/icons/source/icon_tree.svg index b31fd38097..b31fd38097 100644 --- a/tools/editor/icons/source/icon_tree.svg +++ b/editor/icons/source/icon_tree.svg diff --git a/tools/editor/icons/source/icon_tween.svg b/editor/icons/source/icon_tween.svg index 5cb5cad227..5cb5cad227 100644 --- a/tools/editor/icons/source/icon_tween.svg +++ b/editor/icons/source/icon_tween.svg diff --git a/tools/editor/icons/source/icon_unbone.svg b/editor/icons/source/icon_unbone.svg index 7e4109f2ec..7e4109f2ec 100644 --- a/tools/editor/icons/source/icon_unbone.svg +++ b/editor/icons/source/icon_unbone.svg diff --git a/tools/editor/icons/source/icon_ungroup.svg b/editor/icons/source/icon_ungroup.svg index f0b33465cd..f0b33465cd 100644 --- a/tools/editor/icons/source/icon_ungroup.svg +++ b/editor/icons/source/icon_ungroup.svg diff --git a/tools/editor/icons/source/icon_unlock.svg b/editor/icons/source/icon_unlock.svg index b821d486ed..b821d486ed 100644 --- a/tools/editor/icons/source/icon_unlock.svg +++ b/editor/icons/source/icon_unlock.svg diff --git a/tools/editor/icons/source/icon_uv.svg b/editor/icons/source/icon_uv.svg index 698a57fc0a..698a57fc0a 100644 --- a/tools/editor/icons/source/icon_uv.svg +++ b/editor/icons/source/icon_uv.svg diff --git a/tools/editor/icons/source/icon_v_box_container.svg b/editor/icons/source/icon_v_box_container.svg index 9773b253fb..9773b253fb 100644 --- a/tools/editor/icons/source/icon_v_box_container.svg +++ b/editor/icons/source/icon_v_box_container.svg diff --git a/tools/editor/icons/source/icon_v_button_array.svg b/editor/icons/source/icon_v_button_array.svg index aded4b401b..aded4b401b 100644 --- a/tools/editor/icons/source/icon_v_button_array.svg +++ b/editor/icons/source/icon_v_button_array.svg diff --git a/tools/editor/icons/source/icon_v_scroll_bar.svg b/editor/icons/source/icon_v_scroll_bar.svg index 659dc39b0b..659dc39b0b 100644 --- a/tools/editor/icons/source/icon_v_scroll_bar.svg +++ b/editor/icons/source/icon_v_scroll_bar.svg diff --git a/tools/editor/icons/source/icon_v_separator.svg b/editor/icons/source/icon_v_separator.svg index 7e5ce39ba0..7e5ce39ba0 100644 --- a/tools/editor/icons/source/icon_v_separator.svg +++ b/editor/icons/source/icon_v_separator.svg diff --git a/tools/editor/icons/source/icon_v_slider.svg b/editor/icons/source/icon_v_slider.svg index 74b59cfce5..74b59cfce5 100644 --- a/tools/editor/icons/source/icon_v_slider.svg +++ b/editor/icons/source/icon_v_slider.svg diff --git a/tools/editor/icons/source/icon_v_split_container.svg b/editor/icons/source/icon_v_split_container.svg index 4e7704eb4e..4e7704eb4e 100644 --- a/tools/editor/icons/source/icon_v_split_container.svg +++ b/editor/icons/source/icon_v_split_container.svg diff --git a/tools/editor/icons/source/icon_vector.svg b/editor/icons/source/icon_vector.svg index 3260aa77ac..3260aa77ac 100644 --- a/tools/editor/icons/source/icon_vector.svg +++ b/editor/icons/source/icon_vector.svg diff --git a/tools/editor/icons/source/icon_vector2.svg b/editor/icons/source/icon_vector2.svg index b7b157db01..b7b157db01 100644 --- a/tools/editor/icons/source/icon_vector2.svg +++ b/editor/icons/source/icon_vector2.svg diff --git a/tools/editor/icons/source/icon_vehicle_body.svg b/editor/icons/source/icon_vehicle_body.svg index a168b98a99..a168b98a99 100644 --- a/tools/editor/icons/source/icon_vehicle_body.svg +++ b/editor/icons/source/icon_vehicle_body.svg diff --git a/tools/editor/icons/source/icon_vehicle_wheel.svg b/editor/icons/source/icon_vehicle_wheel.svg index dff80c4d00..dff80c4d00 100644 --- a/tools/editor/icons/source/icon_vehicle_wheel.svg +++ b/editor/icons/source/icon_vehicle_wheel.svg diff --git a/tools/editor/icons/source/icon_video_player.svg b/editor/icons/source/icon_video_player.svg index bfb499518b..bfb499518b 100644 --- a/tools/editor/icons/source/icon_video_player.svg +++ b/editor/icons/source/icon_video_player.svg diff --git a/tools/editor/icons/source/icon_viewport.svg b/editor/icons/source/icon_viewport.svg index 631260ab33..631260ab33 100644 --- a/tools/editor/icons/source/icon_viewport.svg +++ b/editor/icons/source/icon_viewport.svg diff --git a/tools/editor/icons/source/icon_viewport_container.svg b/editor/icons/source/icon_viewport_container.svg index 300b8390c4..300b8390c4 100644 --- a/tools/editor/icons/source/icon_viewport_container.svg +++ b/editor/icons/source/icon_viewport_container.svg diff --git a/tools/editor/icons/source/icon_viewport_sprite.svg b/editor/icons/source/icon_viewport_sprite.svg index ab1ac198ce..ab1ac198ce 100644 --- a/tools/editor/icons/source/icon_viewport_sprite.svg +++ b/editor/icons/source/icon_viewport_sprite.svg diff --git a/tools/editor/icons/source/icon_viewport_texture.svg b/editor/icons/source/icon_viewport_texture.svg index 4cf6532059..4cf6532059 100644 --- a/tools/editor/icons/source/icon_viewport_texture.svg +++ b/editor/icons/source/icon_viewport_texture.svg diff --git a/tools/editor/icons/source/icon_visibility_enabler.svg b/editor/icons/source/icon_visibility_enabler.svg index 7c3bc54c99..7c3bc54c99 100644 --- a/tools/editor/icons/source/icon_visibility_enabler.svg +++ b/editor/icons/source/icon_visibility_enabler.svg diff --git a/tools/editor/icons/source/icon_visibility_enabler_2d.svg b/editor/icons/source/icon_visibility_enabler_2d.svg index 1e7d1a751f..1e7d1a751f 100644 --- a/tools/editor/icons/source/icon_visibility_enabler_2d.svg +++ b/editor/icons/source/icon_visibility_enabler_2d.svg diff --git a/tools/editor/icons/source/icon_visibility_notifier.svg b/editor/icons/source/icon_visibility_notifier.svg index b307a6162d..b307a6162d 100644 --- a/tools/editor/icons/source/icon_visibility_notifier.svg +++ b/editor/icons/source/icon_visibility_notifier.svg diff --git a/tools/editor/icons/source/icon_visibility_notifier_2d.svg b/editor/icons/source/icon_visibility_notifier_2d.svg index dc2482f9e1..dc2482f9e1 100644 --- a/tools/editor/icons/source/icon_visibility_notifier_2d.svg +++ b/editor/icons/source/icon_visibility_notifier_2d.svg diff --git a/tools/editor/icons/source/icon_visible.svg b/editor/icons/source/icon_visible.svg index 0185e1f3a9..0185e1f3a9 100644 --- a/tools/editor/icons/source/icon_visible.svg +++ b/editor/icons/source/icon_visible.svg diff --git a/tools/editor/icons/source/icon_visual_script.svg b/editor/icons/source/icon_visual_script.svg index be4b47ca54..be4b47ca54 100644 --- a/tools/editor/icons/source/icon_visual_script.svg +++ b/editor/icons/source/icon_visual_script.svg diff --git a/tools/editor/icons/source/icon_visual_shader_port.svg b/editor/icons/source/icon_visual_shader_port.svg index 9e80e0e9e9..9e80e0e9e9 100644 --- a/tools/editor/icons/source/icon_visual_shader_port.svg +++ b/editor/icons/source/icon_visual_shader_port.svg diff --git a/tools/editor/icons/source/icon_vu_empty.svg b/editor/icons/source/icon_vu_empty.svg index c4c7a4e625..c4c7a4e625 100644 --- a/tools/editor/icons/source/icon_vu_empty.svg +++ b/editor/icons/source/icon_vu_empty.svg diff --git a/tools/editor/icons/source/icon_vu_full.svg b/editor/icons/source/icon_vu_full.svg index 7084ddf204..7084ddf204 100644 --- a/tools/editor/icons/source/icon_vu_full.svg +++ b/editor/icons/source/icon_vu_full.svg diff --git a/tools/editor/icons/source/icon_warning.svg b/editor/icons/source/icon_warning.svg index 4d39141a58..4d39141a58 100644 --- a/tools/editor/icons/source/icon_warning.svg +++ b/editor/icons/source/icon_warning.svg diff --git a/tools/editor/icons/source/icon_window_dialog.svg b/editor/icons/source/icon_window_dialog.svg index 433ae48a55..433ae48a55 100644 --- a/tools/editor/icons/source/icon_window_dialog.svg +++ b/editor/icons/source/icon_window_dialog.svg diff --git a/tools/editor/icons/source/icon_world.svg b/editor/icons/source/icon_world.svg index b2be396217..b2be396217 100644 --- a/tools/editor/icons/source/icon_world.svg +++ b/editor/icons/source/icon_world.svg diff --git a/tools/editor/icons/source/icon_world_2d.svg b/editor/icons/source/icon_world_2d.svg index cb4427808a..cb4427808a 100644 --- a/tools/editor/icons/source/icon_world_2d.svg +++ b/editor/icons/source/icon_world_2d.svg diff --git a/tools/editor/icons/source/icon_world_environment.svg b/editor/icons/source/icon_world_environment.svg index 912e348c81..912e348c81 100644 --- a/tools/editor/icons/source/icon_world_environment.svg +++ b/editor/icons/source/icon_world_environment.svg diff --git a/tools/editor/icons/source/icon_y_sort.svg b/editor/icons/source/icon_y_sort.svg index 65990097c6..65990097c6 100644 --- a/tools/editor/icons/source/icon_y_sort.svg +++ b/editor/icons/source/icon_y_sort.svg diff --git a/tools/editor/icons/source/icon_zoom.svg b/editor/icons/source/icon_zoom.svg index 811036b370..811036b370 100644 --- a/tools/editor/icons/source/icon_zoom.svg +++ b/editor/icons/source/icon_zoom.svg diff --git a/tools/editor/icons/source/icon_zoom_less.svg b/editor/icons/source/icon_zoom_less.svg index 970b1954bb..970b1954bb 100644 --- a/tools/editor/icons/source/icon_zoom_less.svg +++ b/editor/icons/source/icon_zoom_less.svg diff --git a/tools/editor/icons/source/icon_zoom_more.svg b/editor/icons/source/icon_zoom_more.svg index 87acdfb021..87acdfb021 100644 --- a/tools/editor/icons/source/icon_zoom_more.svg +++ b/editor/icons/source/icon_zoom_more.svg diff --git a/tools/editor/icons/source/icon_zoom_reset.svg b/editor/icons/source/icon_zoom_reset.svg index a82f93dfea..a82f93dfea 100644 --- a/tools/editor/icons/source/icon_zoom_reset.svg +++ b/editor/icons/source/icon_zoom_reset.svg diff --git a/tools/editor/icons/xpmfix.sh b/editor/icons/xpmfix.sh index a24dede3c9..a24dede3c9 100755 --- a/tools/editor/icons/xpmfix.sh +++ b/editor/icons/xpmfix.sh diff --git a/tools/editor/import/SCsub b/editor/import/SCsub index f1fa50148f..f1fa50148f 100644 --- a/tools/editor/import/SCsub +++ b/editor/import/SCsub diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp new file mode 100644 index 0000000000..7098e8812b --- /dev/null +++ b/editor/import/editor_import_collada.cpp @@ -0,0 +1,2508 @@ +/*************************************************************************/ +/* editor_import_collada.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 "editor_import_collada.h" + + +#include "scene/3d/spatial.h" +#include "scene/3d/skeleton.h" +#include "scene/3d/path.h" +#include "scene/3d/camera.h" +#include "scene/3d/light.h" +#include "scene/animation/animation_player.h" +#include "scene/3d/mesh_instance.h" +#include "scene/resources/animation.h" +#include "scene/resources/packed_scene.h" +#include "os/os.h" +#include "editor/collada/collada.h" +#include "editor/editor_node.h" +#include <iostream> + + +struct ColladaImport { + + Collada collada; + Spatial *scene; + + Vector<Ref<Animation> > animations; + + struct NodeMap { + //String path; + Spatial *node; + int bone; + List<int> anim_tracks; + + NodeMap() { node=NULL; bone=-1; } + }; + + bool found_ambient; + Color ambient; + bool found_directional; + bool force_make_tangents; + bool apply_mesh_xform_to_vertices; + bool use_mesh_builtin_materials; + float bake_fps; + + + + Map<String,NodeMap> node_map; //map from collada node to engine node + Map<String,String> node_name_map; //map from collada node to engine node + Map<String, Ref<Mesh> > mesh_cache; + Map<String, Ref<Curve3D> > curve_cache; + Map<String, Ref<Material> > material_cache; + Map<Collada::Node*,Skeleton*> skeleton_map; + + Map< Skeleton*, Map< String, int> > skeleton_bone_map; + + Set<String> valid_animated_nodes; + Vector<int> valid_animated_properties; + Map<String,bool> bones_with_animation; + + Error _populate_skeleton(Skeleton *p_skeleton,Collada::Node *p_node, int &r_bone, int p_parent); + Error _create_scene_skeletons(Collada::Node *p_node); + Error _create_scene(Collada::Node *p_node, Spatial *p_parent); + Error _create_resources(Collada::Node *p_node); + Error _create_material(const String& p_material); + Error _create_mesh_surfaces(bool p_optimize, Ref<Mesh>& p_mesh, const Map<String,Collada::NodeGeometry::Material>& p_material_map, const Collada::MeshData &meshdata, const Transform& p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_data, const Collada::MorphControllerData *p_morph_data, Vector<Ref<Mesh> > p_morph_meshes=Vector<Ref<Mesh> >(), bool p_for_morph=false, bool p_use_mesh_material=false); + Error load(const String& p_path, int p_flags, bool p_force_make_tangents=false); + void _fix_param_animation_tracks(); + void create_animation(int p_clip,bool p_make_tracks_in_all_bones, bool p_import_value_tracks); + void create_animations(bool p_make_tracks_in_all_bones, bool p_import_value_tracks); + + Set<String> tracks_in_clips; + Vector<String> missing_textures; + + void _pre_process_lights(Collada::Node *p_node); + + ColladaImport() { + + found_ambient=false; + found_directional=false; + force_make_tangents=false; + apply_mesh_xform_to_vertices=true; + bake_fps=15; + + } +}; + + +Error ColladaImport::_populate_skeleton(Skeleton *p_skeleton,Collada::Node *p_node, int &r_bone, int p_parent) { + + + if (p_node->type!=Collada::Node::TYPE_JOINT) + return OK; + + Collada::NodeJoint *joint = static_cast<Collada::NodeJoint*>(p_node); + + print_line("populating joint "+joint->name); + p_skeleton->add_bone(p_node->name); + if (p_parent>=0) + p_skeleton->set_bone_parent(r_bone,p_parent); + + NodeMap nm; + nm.node=p_skeleton; + nm.bone = r_bone; + node_map[p_node->id]=nm; + node_name_map[p_node->name]=p_node->id; + + skeleton_bone_map[p_skeleton][joint->sid]=r_bone; + + if (collada.state.bone_rest_map.has(joint->sid)) { + + p_skeleton->set_bone_rest(r_bone,collada.fix_transform(collada.state.bone_rest_map[joint->sid])); + //should map this bone to something for animation? + } else { + print_line("no rest: "+joint->sid); + WARN_PRINT("Joint has no rest.."); + } + + + int id = r_bone++; + for(int i=0;i<p_node->children.size();i++) { + + Error err = _populate_skeleton(p_skeleton,p_node->children[i],r_bone,id); + if (err) + return err; + } + + return OK; +} + + +void ColladaImport::_pre_process_lights(Collada::Node *p_node) { + + + if (p_node->type==Collada::Node::TYPE_LIGHT) { + + + Collada::NodeLight *light=static_cast<Collada::NodeLight*>(p_node); + if (collada.state.light_data_map.has(light->light)) { + + Collada::LightData &ld = collada.state.light_data_map[light->light]; + if (ld.mode==Collada::LightData::MODE_AMBIENT) { + found_ambient=true; + ambient=ld.color; + } + if (ld.mode==Collada::LightData::MODE_DIRECTIONAL) { + found_directional=true; + } + } + + } + + + for(int i=0;i<p_node->children.size();i++) + _pre_process_lights(p_node->children[i]); +} + +Error ColladaImport::_create_scene_skeletons(Collada::Node *p_node) { + + + if (p_node->type==Collada::Node::TYPE_SKELETON) { + + Skeleton *sk = memnew( Skeleton ); + int bone = 0; + + for(int i=0;i<p_node->children.size();i++) { + + _populate_skeleton(sk,p_node->children[i],bone,-1); + } + sk->localize_rests(); //after creating skeleton, rests must be localized...! + skeleton_map[p_node]=sk; + } + + + for(int i=0;i<p_node->children.size();i++) { + + Error err = _create_scene_skeletons(p_node->children[i]); + if (err) + return err; + } + return OK; + +} + + +Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) { + + Spatial * node=NULL; + + switch(p_node->type) { + + case Collada::Node::TYPE_NODE: { + + node = memnew( Spatial ); + } break; + case Collada::Node::TYPE_JOINT: { + + return OK; // do nothing + } break; + case Collada::Node::TYPE_LIGHT: { + + //node = memnew( Light) + Collada::NodeLight *light = static_cast<Collada::NodeLight*>(p_node); + if (collada.state.light_data_map.has(light->light)) { + + Collada::LightData &ld = collada.state.light_data_map[light->light]; + + if (ld.mode==Collada::LightData::MODE_AMBIENT) { + + if (found_directional) + return OK; //do nothing not needed + + if (!bool(GLOBAL_DEF("collada/use_ambient",false))) + return OK; + //well, it's an ambient light.. + Light *l = memnew( DirectionalLight ); + //l->set_color(Light::COLOR_AMBIENT,ld.color); + //l->set_color(Light::COLOR_DIFFUSE,Color(0,0,0)); + //l->set_color(Light::COLOR_SPECULAR,Color(0,0,0)); + node = l; + + } else if (ld.mode==Collada::LightData::MODE_DIRECTIONAL) { + + //well, it's an ambient light.. + Light *l = memnew( DirectionalLight ); + /* + if (found_ambient) //use it here + l->set_color(Light::COLOR_AMBIENT,ambient); + + l->set_color(Light::COLOR_DIFFUSE,ld.color); + l->set_color(Light::COLOR_SPECULAR,Color(1,1,1)); + */ + node = l; + } else { + + Light *l; + + if (ld.mode==Collada::LightData::MODE_OMNI) + l=memnew( OmniLight ); + else { + l=memnew( SpotLight ); + //l->set_parameter(Light::PARAM_SPOT_ANGLE,ld.spot_angle); + //l->set_parameter(Light::PARAM_SPOT_ATTENUATION,ld.spot_exp); + } + + // + //l->set_color(Light::COLOR_DIFFUSE,ld.color); + //l->set_color(Light::COLOR_SPECULAR,Color(1,1,1)); + //l->approximate_opengl_attenuation(ld.constant_att,ld.linear_att,ld.quad_att); + node=l; + } + + } else { + + node = memnew( Spatial ); + } + } break; + case Collada::Node::TYPE_CAMERA: { + + Collada::NodeCamera *cam = static_cast<Collada::NodeCamera*>(p_node); + Camera *camera = memnew( Camera ); + + if (collada.state.camera_data_map.has(cam->camera)) { + + const Collada::CameraData &cd = collada.state.camera_data_map[cam->camera]; + + switch(cd.mode) { + + case Collada::CameraData::MODE_ORTHOGONAL: { + + if (cd.orthogonal.y_mag) { + + camera->set_keep_aspect_mode(Camera::KEEP_HEIGHT); + camera->set_orthogonal(cd.orthogonal.y_mag*2.0 ,cd.z_near,cd.z_far); + + } else if (!cd.orthogonal.y_mag && cd.orthogonal.x_mag) { + + + camera->set_keep_aspect_mode(Camera::KEEP_WIDTH); + camera->set_orthogonal(cd.orthogonal.x_mag*2.0,cd.z_near,cd.z_far); + } + + } break; + case Collada::CameraData::MODE_PERSPECTIVE: { + + if (cd.perspective.y_fov) { + + camera->set_perspective(cd.perspective.y_fov,cd.z_near,cd.z_far); + + } else if (!cd.perspective.y_fov && cd.perspective.x_fov) { + + camera->set_perspective(cd.perspective.x_fov / cd.aspect,cd.z_near,cd.z_far); + } + + } break; + } + + } + + node=camera; + + } break; + case Collada::Node::TYPE_GEOMETRY: { + + Collada::NodeGeometry *ng = static_cast<Collada::NodeGeometry*>(p_node); + + if (collada.state.curve_data_map.has(ng->source)) { + + node = memnew( Path ); + } else { + //mesh since nothing else + node = memnew( MeshInstance ); + node->cast_to<MeshInstance>()->set_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT,true); + } + } break; + case Collada::Node::TYPE_SKELETON: { + + ERR_FAIL_COND_V(!skeleton_map.has(p_node),ERR_CANT_CREATE); + Skeleton *sk = skeleton_map[p_node]; + node=sk; + } break; + + } + + if (p_node->name!="") + node->set_name(p_node->name); + NodeMap nm; + nm.node=node; + node_map[p_node->id]=nm; + node_name_map[p_node->name]=p_node->id; + Transform xf = p_node->default_transform; + + xf = collada.fix_transform( xf ) * p_node->post_transform; + node->set_transform(xf); + p_parent->add_child(node); + node->set_owner(scene); + + if (p_node->empty_draw_type!="") { + node->set_meta("empty_draw_type", Variant(p_node->empty_draw_type)); + } + + for(int i=0;i<p_node->children.size();i++) { + + Error err = _create_scene(p_node->children[i],node); + if (err) + return err; + } + return OK; +} + + +Error ColladaImport::_create_material(const String& p_target) { + + ERR_FAIL_COND_V(material_cache.has(p_target),ERR_ALREADY_EXISTS); + ERR_FAIL_COND_V(!collada.state.material_map.has(p_target),ERR_INVALID_PARAMETER); + Collada::Material &src_mat=collada.state.material_map[p_target]; + ERR_FAIL_COND_V(!collada.state.effect_map.has(src_mat.instance_effect),ERR_INVALID_PARAMETER); + Collada::Effect &effect=collada.state.effect_map[src_mat.instance_effect]; + + Ref<FixedSpatialMaterial> material= memnew( FixedSpatialMaterial ); + + if (src_mat.name!="") + material->set_name(src_mat.name); + else if (effect.name!="") + material->set_name(effect.name); + + // DIFFUSE + + if (effect.diffuse.texture!="") { + + String texfile = effect.get_texture_path(effect.diffuse.texture,collada); + if (texfile!="") { + + Ref<Texture> texture = ResourceLoader::load(texfile,"Texture"); + if (texture.is_valid()) { + + material->set_texture(FixedSpatialMaterial::TEXTURE_ALBEDO,texture); + material->set_albedo(Color(1,1,1,1)); + //material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1,1)); + } else { + missing_textures.push_back(texfile.get_file()); + } + } + } else { + //material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,effect.diffuse.color); + } + + // SPECULAR + + if (effect.specular.texture!="") { + + String texfile = effect.get_texture_path(effect.specular.texture,collada); + if (texfile!="") { + + Ref<Texture> texture = ResourceLoader::load(texfile,"Texture"); + if (texture.is_valid()) { + material->set_texture(FixedSpatialMaterial::TEXTURE_SPECULAR,texture); + material->set_specular(Color(1,1,1,1)); + + //material->set_texture(FixedSpatialMaterial::PARAM_SPECULAR,texture); + //material->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR,Color(1,1,1,1)); + } else { + missing_textures.push_back(texfile.get_file()); + } + + } + } else { + material->set_metalness(effect.specular.color.get_v()); + } + + + // EMISSION + + if (effect.emission.texture!="") { + + String texfile = effect.get_texture_path(effect.emission.texture,collada); + if (texfile!="") { + + Ref<Texture> texture = ResourceLoader::load(texfile,"Texture"); + if (texture.is_valid()) { + + material->set_feature(FixedSpatialMaterial::FEATURE_EMISSION,true); + material->set_texture(FixedSpatialMaterial::TEXTURE_EMISSION,texture); + material->set_emission(Color(1,1,1,1)); + + //material->set_parameter(FixedSpatialMaterial::PARAM_EMISSION,Color(1,1,1,1)); + }else { + missing_textures.push_back(texfile.get_file()); + } + + } + } else { + if (effect.emission.color!=Color()) { + material->set_feature(FixedSpatialMaterial::FEATURE_EMISSION,true); + material->set_emission(effect.emission.color); + } + } + + // NORMAL + + if (effect.bump.texture!="") { + + String texfile = effect.get_texture_path(effect.bump.texture,collada); + if (texfile!="") { + + Ref<Texture> texture = ResourceLoader::load(texfile,"Texture"); + if (texture.is_valid()) { + material->set_feature(FixedSpatialMaterial::FEATURE_NORMAL_MAPPING,true); + material->set_texture(FixedSpatialMaterial::TEXTURE_NORMAL,texture); + //material->set_emission(Color(1,1,1,1)); + + //material->set_texture(FixedSpatialMaterial::PARAM_NORMAL,texture); + }else { + //missing_textures.push_back(texfile.get_file()); + } + + } + } + + + float roughness = Math::sqrt(1.0-((Math::log(effect.shininess)/Math::log(2.0))/8.0)); //not very right.. + material->set_roughness(roughness); + + if (effect.double_sided) { + material->set_cull_mode(FixedSpatialMaterial::CULL_DISABLED); + } + material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED,effect.unshaded); + + + + material_cache[p_target]=material; + return OK; +} + + +static void _generate_normals(const PoolVector<int>& p_indices,const PoolVector<Vector3>& p_vertices,PoolVector<Vector3>&r_normals) { + + + r_normals.resize(p_vertices.size()); + PoolVector<Vector3>::Write narrayw = r_normals.write(); + + int iacount=p_indices.size()/3; + PoolVector<int>::Read index_arrayr = p_indices.read(); + PoolVector<Vector3>::Read vertex_arrayr = p_vertices.read(); + + for(int idx=0;idx<iacount;idx++) { + + Vector3 v[3]={ + vertex_arrayr[index_arrayr[idx*3+0]], + vertex_arrayr[index_arrayr[idx*3+1]], + vertex_arrayr[index_arrayr[idx*3+2]] + }; + + Vector3 normal = Plane(v[0],v[1],v[2]).normal; + + narrayw[index_arrayr[idx*3+0]]+=normal; + narrayw[index_arrayr[idx*3+1]]+=normal; + narrayw[index_arrayr[idx*3+2]]+=normal; + } + + int vlen=p_vertices.size(); + + for(int idx=0;idx<vlen;idx++) { + narrayw[idx].normalize(); + } + +} + + +static void _generate_tangents_and_binormals(const PoolVector<int>& p_indices,const PoolVector<Vector3>& p_vertices,const PoolVector<Vector3>& p_uvs,const PoolVector<Vector3>& p_normals,PoolVector<real_t>&r_tangents) { + + int vlen=p_vertices.size(); + + Vector<Vector3> tangents; + tangents.resize(vlen); + Vector<Vector3> binormals; + binormals.resize(vlen); + + + int iacount=p_indices.size()/3; + + PoolVector<int>::Read index_arrayr = p_indices.read(); + PoolVector<Vector3>::Read vertex_arrayr = p_vertices.read(); + PoolVector<Vector3>::Read narrayr = p_normals.read(); + PoolVector<Vector3>::Read uvarrayr = p_uvs.read(); + + + for(int idx=0;idx<iacount;idx++) { + + + Vector3 v1 = vertex_arrayr[ index_arrayr[idx*3+0] ]; + Vector3 v2 = vertex_arrayr[ index_arrayr[idx*3+1] ]; + Vector3 v3 = vertex_arrayr[ index_arrayr[idx*3+2] ]; + + Vector3 w1 = uvarrayr[ index_arrayr[idx*3+0] ]; + Vector3 w2 = uvarrayr[ index_arrayr[idx*3+1] ]; + Vector3 w3 = uvarrayr[ index_arrayr[idx*3+2] ]; + + real_t x1 = v2.x - v1.x; + real_t x2 = v3.x - v1.x; + real_t y1 = v2.y - v1.y; + real_t y2 = v3.y - v1.y; + real_t z1 = v2.z - v1.z; + real_t z2 = v3.z - v1.z; + + real_t s1 = w2.x - w1.x; + real_t s2 = w3.x - w1.x; + real_t t1 = w2.y - w1.y; + real_t t2 = w3.y - w1.y; + + real_t r = (s1 * t2 - s2 * t1); + + Vector3 tangent; + Vector3 binormal; + + if (r==0) { + + binormal=Vector3(); + tangent=Vector3(); + } else { + tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, + (t2 * z1 - t1 * z2) * r).normalized(); + binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, + (s1 * z2 - s2 * z1) * r).normalized(); + } + + tangents[ index_arrayr[idx*3+0] ]+=tangent; + binormals[ index_arrayr[idx*3+0] ]+=binormal; + tangents[ index_arrayr[idx*3+1] ]+=tangent; + binormals[ index_arrayr[idx*3+1] ]+=binormal; + tangents[ index_arrayr[idx*3+2] ]+=tangent; + binormals[ index_arrayr[idx*3+2] ]+=binormal; + + //print_line(itos(idx)+" tangent: "+tangent); + //print_line(itos(idx)+" binormal: "+binormal); + } + + r_tangents.resize(vlen*4); + PoolVector<real_t>::Write tarrayw = r_tangents.write(); + + for(int idx=0;idx<vlen;idx++) { + Vector3 tangent = tangents[idx]; + Vector3 bingen = narrayr[idx].cross(tangent); + float dir; + if (bingen.dot(binormals[idx]) < 0 ) + dir=-1.0; + else + dir=+1.0; + + tarrayw[idx*4+0]=tangent.x; + tarrayw[idx*4+1]=tangent.y; + tarrayw[idx*4+2]=tangent.z; + tarrayw[idx*4+3]=dir; + } +} + +Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,const Map<String,Collada::NodeGeometry::Material>& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector<int> &bone_remap, const Collada::SkinControllerData *skin_controller, const Collada::MorphControllerData *p_morph_data,Vector<Ref<Mesh> > p_morph_meshes,bool p_for_morph,bool p_use_mesh_material) { + + + bool local_xform_mirror=p_local_xform.basis.determinant() < 0; + + if (p_morph_data) { + + //add morphie target + ERR_FAIL_COND_V( !p_morph_data->targets.has("MORPH_TARGET"), ERR_INVALID_DATA ); + String mt = p_morph_data->targets["MORPH_TARGET"]; + ERR_FAIL_COND_V( !p_morph_data->sources.has(mt), ERR_INVALID_DATA); + int morph_targets = p_morph_data->sources[mt].sarray.size(); + for(int i=0;i<morph_targets;i++) { + + String target = p_morph_data->sources[mt].sarray[i]; + ERR_FAIL_COND_V( !collada.state.mesh_data_map.has(target), ERR_INVALID_DATA ); + String name = collada.state.mesh_data_map[target].name; + + p_mesh->add_blend_shape(name); + } + if (p_morph_data->mode=="RELATIVE") + p_mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_RELATIVE); + else if (p_morph_data->mode=="NORMALIZED") + p_mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED); + } + + + int surface=0; + for(int p_i = 0; p_i < meshdata.primitives.size(); p_i ++ ) { + + + + const Collada::MeshData::Primitives& p = meshdata.primitives[p_i]; + + /* VERTEX SOURCE */ + ERR_FAIL_COND_V(!p.sources.has("VERTEX"),ERR_INVALID_DATA); + + String vertex_src_id = p.sources["VERTEX"].source; + int vertex_ofs=p.sources["VERTEX"].offset; + + ERR_FAIL_COND_V(!meshdata.vertices.has(vertex_src_id),ERR_INVALID_DATA); + + ERR_FAIL_COND_V(!meshdata.vertices[vertex_src_id].sources.has("POSITION"),ERR_INVALID_DATA); + String position_src_id = meshdata.vertices[vertex_src_id].sources["POSITION"]; + + ERR_FAIL_COND_V(!meshdata.sources.has(position_src_id),ERR_INVALID_DATA); + + const Collada::MeshData::Source *vertex_src=&meshdata.sources[position_src_id]; + + /* NORMAL SOURCE */ + + const Collada::MeshData::Source *normal_src=NULL; + int normal_ofs=0; + + if (p.sources.has("NORMAL")) { + + String normal_source_id = p.sources["NORMAL"].source; + normal_ofs = p.sources["NORMAL"].offset; + ERR_FAIL_COND_V( !meshdata.sources.has(normal_source_id),ERR_INVALID_DATA); + normal_src=&meshdata.sources[normal_source_id]; + } + + const Collada::MeshData::Source *binormal_src=NULL; + int binormal_ofs=0; + + if (p.sources.has("TEXBINORMAL")) { + + String binormal_source_id = p.sources["TEXBINORMAL"].source; + binormal_ofs = p.sources["TEXBINORMAL"].offset; + ERR_FAIL_COND_V( !meshdata.sources.has(binormal_source_id),ERR_INVALID_DATA); + binormal_src=&meshdata.sources[binormal_source_id]; + } + + const Collada::MeshData::Source *tangent_src=NULL; + int tangent_ofs=0; + + if (p.sources.has("TEXTANGENT")) { + + String tangent_source_id = p.sources["TEXTANGENT"].source; + tangent_ofs = p.sources["TEXTANGENT"].offset; + ERR_FAIL_COND_V( !meshdata.sources.has(tangent_source_id),ERR_INVALID_DATA); + tangent_src=&meshdata.sources[tangent_source_id]; + } + + + const Collada::MeshData::Source *uv_src=NULL; + int uv_ofs=0; + + if (p.sources.has("TEXCOORD0")) { + + String uv_source_id = p.sources["TEXCOORD0"].source; + uv_ofs = p.sources["TEXCOORD0"].offset; + ERR_FAIL_COND_V( !meshdata.sources.has(uv_source_id),ERR_INVALID_DATA); + uv_src=&meshdata.sources[uv_source_id]; + } + + const Collada::MeshData::Source *uv2_src=NULL; + int uv2_ofs=0; + + if (p.sources.has("TEXCOORD1")) { + + String uv2_source_id = p.sources["TEXCOORD1"].source; + uv2_ofs = p.sources["TEXCOORD1"].offset; + ERR_FAIL_COND_V( !meshdata.sources.has(uv2_source_id),ERR_INVALID_DATA); + uv2_src=&meshdata.sources[uv2_source_id]; + } + + + const Collada::MeshData::Source *color_src=NULL; + int color_ofs=0; + + if (p.sources.has("COLOR")) { + + String color_source_id = p.sources["COLOR"].source; + color_ofs = p.sources["COLOR"].offset; + ERR_FAIL_COND_V( !meshdata.sources.has(color_source_id), ERR_INVALID_DATA ); + color_src=&meshdata.sources[color_source_id]; + } + + //find largest source.. + + /************************/ + /* ADD WEIGHTS IF EXIST */ + /************************/ + + Map<int,Vector<Collada::Vertex::Weight> > pre_weights; + + bool has_weights=false; + + if (skin_controller) { + + const Collada::SkinControllerData::Source *weight_src=NULL; + int weight_ofs=0; + + if (skin_controller->weights.sources.has("WEIGHT")) { + + String weight_id = skin_controller->weights.sources["WEIGHT"].source; + weight_ofs = skin_controller->weights.sources["WEIGHT"].offset; + if (skin_controller->sources.has(weight_id)) { + + weight_src = &skin_controller->sources[weight_id]; + + } + } + + int joint_ofs=0; + + if (skin_controller->weights.sources.has("JOINT")) { + + joint_ofs = skin_controller->weights.sources["JOINT"].offset; + } + + //should be OK, given this was pre-checked. + + int index_ofs=0; + int wstride = skin_controller->weights.sources.size(); + for(int w_i=0;w_i<skin_controller->weights.sets.size();w_i++) { + + int amount = skin_controller->weights.sets[w_i]; + + Vector<Collada::Vertex::Weight> weights; + + for (int a_i=0;a_i<amount;a_i++) { + + Collada::Vertex::Weight w; + + int read_from = index_ofs+a_i*wstride; + ERR_FAIL_INDEX_V(read_from+wstride-1,skin_controller->weights.indices.size(),ERR_INVALID_DATA); + int weight_index = skin_controller->weights.indices[read_from+weight_ofs]; + ERR_FAIL_INDEX_V(weight_index,weight_src->array.size(),ERR_INVALID_DATA); + + w.weight = weight_src->array[weight_index]; + + int bone_index = skin_controller->weights.indices[read_from+joint_ofs]; + if (bone_index==-1) + continue; //ignore this weight (refers to bind shape) + ERR_FAIL_INDEX_V(bone_index,bone_remap.size(),ERR_INVALID_DATA); + + w.bone_idx=bone_remap[bone_index]; + + + weights.push_back(w); + } + + /* FIX WEIGHTS */ + + + + weights.sort(); + + if (weights.size()>4) { + //cap to 4 and make weights add up 1 + weights.resize(4); + + } + + //make sure weights allways add up to 1 + float total=0; + for(int i=0;i<weights.size();i++) + total+=weights[i].weight; + if (total) + for(int i=0;i<weights.size();i++) + weights[i].weight/=total; + + if (weights.size()==0 || total==0) { //if nothing, add a weight to bone 0 + //no weights assigned + Collada::Vertex::Weight w; + w.bone_idx=0; + w.weight=1.0; + weights.clear(); + weights.push_back(w); + + } + + pre_weights[w_i]=weights; + + /* + for(Set<int>::Element *E=vertex_map[w_i].front();E;E=E->next()) { + + int dst = E->get(); + ERR_EXPLAIN("invalid vertex index in array"); + ERR_FAIL_INDEX_V(dst,vertex_array.size(),ERR_INVALID_DATA); + vertex_array[dst].weights=weights; + + }*/ + + + + + index_ofs+=wstride*amount; + + } + + //vertices need to be localized + has_weights=true; + + } + + Set<Collada::Vertex> vertex_set; //vertex set will be the vertices + List<int> indices_list; //indices will be the indices + //Map<int,Set<int> > vertex_map; //map vertices (for setting skinning/morph) + + /**************************/ + /* CREATE PRIMITIVE ARRAY */ + /**************************/ + + // The way collada uses indices is more optimal, and friendlier with 3D modelling sofware, + // because it can index everything, not only vertices (similar to how the WII works). + // This is, however, more incompatible with standard video cards, so arrays must be converted. + // Must convert to GL/DX format. + + int _prim_ofs=0; + int vertidx=0; + for(int p_i=0;p_i<p.count;p_i++) { + + + int amount; + if (p.polygons.size()) { + + ERR_FAIL_INDEX_V(p_i,p.polygons.size(),ERR_INVALID_DATA); + amount=p.polygons[p_i]; + } else { + amount=3; //triangles; + } + + //COLLADA_PRINT("amount: "+itos(amount)); + + int prev2[2]={0,0}; + + for(int j=0;j<amount;j++) { + + int src=_prim_ofs; + //_prim_ofs+=p.sources.size() + + ERR_FAIL_INDEX_V(src,p.indices.size(),ERR_INVALID_DATA); + + Collada::Vertex vertex; + if (!p_optimize) + vertex.uid=vertidx++; + + + + int vertex_index=p.indices[src+vertex_ofs]; //used for index field (later used by controllers) + int vertex_pos = (vertex_src->stride?vertex_src->stride:3) * vertex_index; + ERR_FAIL_INDEX_V(vertex_pos,vertex_src->array.size(),ERR_INVALID_DATA); + vertex.vertex=Vector3(vertex_src->array[vertex_pos+0],vertex_src->array[vertex_pos+1],vertex_src->array[vertex_pos+2]); + + if (pre_weights.has(vertex_index)) { + vertex.weights=pre_weights[vertex_index]; + } + + if (normal_src) { + + + + int normal_pos = (normal_src->stride?normal_src->stride:3) * p.indices[src+normal_ofs]; + ERR_FAIL_INDEX_V(normal_pos,normal_src->array.size(),ERR_INVALID_DATA); + vertex.normal=Vector3(normal_src->array[normal_pos+0],normal_src->array[normal_pos+1],normal_src->array[normal_pos+2]); + vertex.normal=vertex.normal.snapped(0.001); + + + if (tangent_src && binormal_src) { + + int binormal_pos = (binormal_src->stride?binormal_src->stride:3) * p.indices[src+binormal_ofs]; + ERR_FAIL_INDEX_V(binormal_pos,binormal_src->array.size(),ERR_INVALID_DATA); + Vector3 binormal =Vector3(binormal_src->array[binormal_pos+0],binormal_src->array[binormal_pos+1],binormal_src->array[binormal_pos+2]); + + int tangent_pos = (tangent_src->stride?tangent_src->stride:3) * p.indices[src+tangent_ofs]; + ERR_FAIL_INDEX_V(tangent_pos,tangent_src->array.size(),ERR_INVALID_DATA); + Vector3 tangent =Vector3(tangent_src->array[tangent_pos+0],tangent_src->array[tangent_pos+1],tangent_src->array[tangent_pos+2]); + + vertex.tangent.normal=tangent; + vertex.tangent.d= vertex.normal.cross(tangent).dot(binormal) > 0 ? 1 : -1; + } + + } + + + if (uv_src) { + + int uv_pos = (uv_src->stride?uv_src->stride:2) * p.indices[src+uv_ofs]; + ERR_FAIL_INDEX_V(uv_pos,uv_src->array.size(),ERR_INVALID_DATA); + vertex.uv=Vector3(uv_src->array[uv_pos+0],1.0-uv_src->array[uv_pos+1],0); + } + + if (uv2_src) { + + int uv2_pos = (uv2_src->stride?uv2_src->stride:2) * p.indices[src+uv2_ofs]; + ERR_FAIL_INDEX_V(uv2_pos,uv2_src->array.size(),ERR_INVALID_DATA); + vertex.uv2=Vector3(uv2_src->array[uv2_pos+0],1.0-uv2_src->array[uv2_pos+1],0); + } + + if (color_src) { + + int color_pos = (color_src->stride?color_src->stride:3) * p.indices[src+color_ofs]; // colors are RGB in collada.. + ERR_FAIL_INDEX_V(color_pos,color_src->array.size(),ERR_INVALID_DATA); + vertex.color=Color(color_src->array[color_pos+0],color_src->array[color_pos+1],color_src->array[color_pos+2],(color_src->stride>3)?color_src->array[color_pos+3]:1.0); + + } + +#ifndef NO_UP_AXIS_SWAP + if (collada.state.up_axis==Vector3::AXIS_Z) { + + SWAP( vertex.vertex.z, vertex.vertex.y ); + vertex.vertex.z = -vertex.vertex.z; + SWAP( vertex.normal.z, vertex.normal.y ); + vertex.normal.z = -vertex.normal.z; + SWAP( vertex.tangent.normal.z, vertex.tangent.normal.y ); + vertex.tangent.normal.z = -vertex.tangent.normal.z; + + } + +#endif + + vertex.fix_unit_scale(collada); + int index=0; + //COLLADA_PRINT("vertex: "+vertex.vertex); + + if (vertex_set.has(vertex)) { + + index=vertex_set.find(vertex)->get().idx; + } else { + + index=vertex_set.size(); + vertex.idx=index; + vertex_set.insert(vertex); + } + + /* if (!vertex_map.has(vertex_index)) + vertex_map[vertex_index]=Set<int>(); + vertex_map[vertex_index].insert(index); //should be outside..*/ + //build triangles if needed + if (j==0) + prev2[0]=index; + + if (j>=2) { + //insert indices in reverse order (collada uses CCW as frontface) + if (local_xform_mirror) { + + indices_list.push_back(prev2[0]); + indices_list.push_back(prev2[1]); + indices_list.push_back(index); + + } else { + indices_list.push_back(prev2[0]); + indices_list.push_back(index); + indices_list.push_back(prev2[1]); + } + } + + prev2[1]=index; + _prim_ofs+=p.vertex_size; + } + + } + + + + Vector<Collada::Vertex> vertex_array; //there we go, vertex array + + vertex_array.resize(vertex_set.size()); + for(Set<Collada::Vertex>::Element *F=vertex_set.front();F;F=F->next()) { + + vertex_array[F->get().idx]=F->get(); + } + + + if (has_weights) { + + //if skeleton, localize + Transform local_xform = p_local_xform; + for(int i=0;i<vertex_array.size();i++) { + + vertex_array[i].vertex=local_xform.xform(vertex_array[i].vertex); + vertex_array[i].normal=local_xform.basis.xform(vertex_array[i].normal).normalized(); + vertex_array[i].tangent.normal=local_xform.basis.xform(vertex_array[i].tangent.normal).normalized(); + if (local_xform_mirror) { + //i shouldn't do this? wtf? + //vertex_array[i].normal*=-1.0; + //vertex_array[i].tangent.normal*=-1.0; + } + } + } + + + PoolVector<int> index_array; + index_array.resize(indices_list.size()); + PoolVector<int>::Write index_arrayw = index_array.write(); + + int iidx=0; + for(List<int>::Element *F=indices_list.front();F;F=F->next()) { + + index_arrayw[iidx++]=F->get(); + } + + index_arrayw=PoolVector<int>::Write(); + + + /*****************/ + /* MAKE SURFACES */ + /*****************/ + + + { + + Ref<FixedSpatialMaterial> material; + + //find material + Mesh::PrimitiveType primitive=Mesh::PRIMITIVE_TRIANGLES; + + { + + if (p_material_map.has(p.material)) { + String target=p_material_map[p.material].target; + + if (!material_cache.has(target)) { + Error err = _create_material(target); + if (!err) + material=material_cache[target]; + } else + material=material_cache[target]; + + } else if (p.material!=""){ + print_line("Warning, unreferenced material in geometry instance: "+p.material); + } + } + + + + PoolVector<Vector3> final_vertex_array; + PoolVector<Vector3> final_normal_array; + PoolVector<float> final_tangent_array; + PoolVector<Color> final_color_array; + PoolVector<Vector3> final_uv_array; + PoolVector<Vector3> final_uv2_array; + PoolVector<int> final_bone_array; + PoolVector<float> final_weight_array; + + uint32_t final_format=0; + + //create format + final_format=Mesh::ARRAY_FORMAT_VERTEX|Mesh::ARRAY_FORMAT_INDEX; + + if (normal_src) { + final_format|=Mesh::ARRAY_FORMAT_NORMAL; + if (uv_src && binormal_src && tangent_src) { + final_format|=Mesh::ARRAY_FORMAT_TANGENT; + } + + } + + + + if (color_src) + final_format|=Mesh::ARRAY_FORMAT_COLOR; + if (uv_src) + final_format|=Mesh::ARRAY_FORMAT_TEX_UV; + if (uv2_src) + final_format|=Mesh::ARRAY_FORMAT_TEX_UV2; + + if (has_weights) { + final_format|=Mesh::ARRAY_FORMAT_WEIGHTS; + final_format|=Mesh::ARRAY_FORMAT_BONES; + } + + + //set arrays + + int vlen = vertex_array.size(); + { //vertices + + PoolVector<Vector3> varray; + varray.resize(vertex_array.size()); + + PoolVector<Vector3>::Write varrayw = varray.write(); + + for(int k=0;k<vlen;k++) + varrayw[k]=vertex_array[k].vertex; + + varrayw = PoolVector<Vector3>::Write(); + final_vertex_array=varray; + + } + + + if (uv_src) { //compute uv first, may be needed for computing tangent/bionrmal + PoolVector<Vector3> uvarray; + uvarray.resize(vertex_array.size()); + PoolVector<Vector3>::Write uvarrayw = uvarray.write(); + + for(int k=0;k<vlen;k++) { + uvarrayw[k]=vertex_array[k].uv; + } + + uvarrayw = PoolVector<Vector3>::Write(); + final_uv_array=uvarray; + + } + + if (uv2_src) { //compute uv first, may be needed for computing tangent/bionrmal + PoolVector<Vector3> uv2array; + uv2array.resize(vertex_array.size()); + PoolVector<Vector3>::Write uv2arrayw = uv2array.write(); + + for(int k=0;k<vlen;k++) { + uv2arrayw[k]=vertex_array[k].uv2; + } + + uv2arrayw = PoolVector<Vector3>::Write(); + final_uv2_array=uv2array; + + } + + if (normal_src) { + PoolVector<Vector3> narray; + narray.resize(vertex_array.size()); + PoolVector<Vector3>::Write narrayw = narray.write(); + + for(int k=0;k<vlen;k++) { + narrayw[k]=vertex_array[k].normal; + } + + narrayw = PoolVector<Vector3>::Write(); + final_normal_array=narray; + + /* + PoolVector<Vector3> altnaray; + _generate_normals(index_array,final_vertex_array,altnaray); + + for(int i=0;i<altnaray.size();i++) + print_line(rtos(altnaray[i].dot(final_normal_array[i]))); + */ + + } else if (primitive==Mesh::PRIMITIVE_TRIANGLES) { + //generate normals (even if unused later) + + _generate_normals(index_array,final_vertex_array,final_normal_array); + if (OS::get_singleton()->is_stdout_verbose()) + print_line("Collada: Triangle mesh lacks normals, so normals were generated."); + final_format|=Mesh::ARRAY_FORMAT_NORMAL; + + } + + if (final_normal_array.size() && uv_src && binormal_src && tangent_src && !force_make_tangents) { + + PoolVector<real_t> tarray; + tarray.resize(vertex_array.size()*4); + PoolVector<real_t>::Write tarrayw = tarray.write(); + + + for(int k=0;k<vlen;k++) { + tarrayw[k*4+0]=vertex_array[k].tangent.normal.x; + tarrayw[k*4+1]=vertex_array[k].tangent.normal.y; + tarrayw[k*4+2]=vertex_array[k].tangent.normal.z; + tarrayw[k*4+3]=vertex_array[k].tangent.d; + + } + + tarrayw = PoolVector<real_t>::Write(); + + final_tangent_array=tarray; + } else if (final_normal_array.size() && primitive==Mesh::PRIMITIVE_TRIANGLES && final_uv_array.size() && (force_make_tangents || (material.is_valid()))){ + //if this uses triangles, there are uvs and the material is using a normalmap, generate tangents and binormals, because they WILL be needed + //generate binormals/tangents + _generate_tangents_and_binormals(index_array,final_vertex_array,final_uv_array,final_normal_array,final_tangent_array); + final_format|=Mesh::ARRAY_FORMAT_TANGENT; + if (OS::get_singleton()->is_stdout_verbose()) + print_line("Collada: Triangle mesh lacks tangents (And normalmap was used), so tangents were generated."); + + } + + + if (color_src) { + PoolVector<Color> colorarray; + colorarray.resize(vertex_array.size()); + PoolVector<Color>::Write colorarrayw = colorarray.write(); + + for(int k=0;k<vlen;k++) { + colorarrayw[k]=vertex_array[k].color; + } + + colorarrayw = PoolVector<Color>::Write(); + + final_color_array=colorarray; + } + + if (has_weights) { + PoolVector<float> weightarray; + PoolVector<int> bonearray; + + weightarray.resize(vertex_array.size()*4); + PoolVector<float>::Write weightarrayw = weightarray.write(); + bonearray.resize(vertex_array.size()*4); + PoolVector<int>::Write bonearrayw = bonearray.write(); + + for(int k=0;k<vlen;k++) { + float sum=0; + + for(int l=0;l<VS::ARRAY_WEIGHTS_SIZE;l++) { + if (l<vertex_array[k].weights.size()) { + weightarrayw[k*VS::ARRAY_WEIGHTS_SIZE+l]=vertex_array[k].weights[l].weight; + sum+=weightarrayw[k*VS::ARRAY_WEIGHTS_SIZE+l]; + bonearrayw[k*VS::ARRAY_WEIGHTS_SIZE+l]=int(vertex_array[k].weights[l].bone_idx); + //COLLADA_PRINT(itos(k)+": "+rtos(bonearrayw[k*VS::ARRAY_WEIGHTS_SIZE+l])+":"+rtos(weightarray[k*VS::ARRAY_WEIGHTS_SIZE+l])); + } else { + + weightarrayw[k*VS::ARRAY_WEIGHTS_SIZE+l]=0; + bonearrayw[k*VS::ARRAY_WEIGHTS_SIZE+l]=0; + + } + + + } + /* + if (sum<0.8) + COLLADA_PRINT("ERROR SUMMING INDEX "+itos(k)+" had weights: "+itos(vertex_array[k].weights.size())); + */ + + } + + weightarrayw = PoolVector<float>::Write(); + bonearrayw = PoolVector<int>::Write(); + + final_weight_array = weightarray; + final_bone_array = bonearray; + } + + + + //////////////////////////// + // FINALLY CREATE SUFRACE // + //////////////////////////// + + Array d; + d.resize(VS::ARRAY_MAX); + + d[Mesh::ARRAY_INDEX]=index_array; + d[Mesh::ARRAY_VERTEX]=final_vertex_array; + + if (final_normal_array.size()) + d[Mesh::ARRAY_NORMAL]=final_normal_array; + if (final_tangent_array.size()) + d[Mesh::ARRAY_TANGENT]=final_tangent_array; + if (final_uv_array.size()) + d[Mesh::ARRAY_TEX_UV]=final_uv_array; + if (final_uv2_array.size()) + d[Mesh::ARRAY_TEX_UV2]=final_uv2_array; + if (final_color_array.size()) + d[Mesh::ARRAY_COLOR]=final_color_array; + if (final_weight_array.size()) + d[Mesh::ARRAY_WEIGHTS]=final_weight_array; + if (final_bone_array.size()) + d[Mesh::ARRAY_BONES]=final_bone_array; + + + Array mr; + + //////////////////////////// + // THEN THE MORPH TARGETS // + //////////////////////////// +#if 0 + if (p_morph_data) { + + //add morphie target + ERR_FAIL_COND_V( !p_morph_data->targets.has("MORPH_TARGET"), ERR_INVALID_DATA ); + String mt = p_morph_data->targets["MORPH_TARGET"]; + ERR_FAIL_COND_V( !p_morph_data->sources.has(mt), ERR_INVALID_DATA); + int morph_targets = p_morph_data->sources[mt].sarray.size(); + mr.resize(morph_targets); + + for(int j=0;j<morph_targets;j++) { + + Array mrt; + mrt.resize(VS::ARRAY_MAX); + + String target = p_morph_data->sources[mt].sarray[j]; + ERR_FAIL_COND_V( !collada.state.mesh_data_map.has(target), ERR_INVALID_DATA ); + String name = collada.state.mesh_data_map[target].name; + Collada::MeshData &md = collada.state.mesh_data_map[target]; + + // collada in itself supports morphing everything. However, the spec is unclear and no examples or exporters that + // morph anything but "POSITIONS" seem to exit. Because of this, normals and binormals/tangents have to be regenerated here, + // which may result in inaccurate (but most of the time good enough) results. + + PoolVector<Vector3> vertices; + vertices.resize(vlen); + + ERR_FAIL_COND_V( md.vertices.size() != 1, ERR_INVALID_DATA); + String vertex_src_id=md.vertices.front()->key(); + ERR_FAIL_COND_V(!md.vertices[vertex_src_id].sources.has("POSITION"),ERR_INVALID_DATA); + String position_src_id = md.vertices[vertex_src_id].sources["POSITION"]; + + ERR_FAIL_COND_V(!md.sources.has(position_src_id),ERR_INVALID_DATA); + + const Collada::MeshData::Source *m=&md.sources[position_src_id]; + + ERR_FAIL_COND_V( m->array.size() != vertex_src->array.size(), ERR_INVALID_DATA); + int stride=m->stride; + if (stride==0) + stride=3; + + + //read vertices from morph target + PoolVector<Vector3>::Write vertw = vertices.write(); + + for(int m_i=0;m_i<m->array.size()/stride;m_i++) { + + int pos = m_i*stride; + Vector3 vtx( m->array[pos+0], m->array[pos+1], m->array[pos+2] ); + +#ifndef NO_UP_AXIS_SWAP + if (collada.state.up_axis==Vector3::AXIS_Z) { + + SWAP( vtx.z, vtx.y ); + vtx.z = -vtx.z; + + } +#endif + + Collada::Vertex vertex; + vertex.vertex=vtx; + vertex.fix_unit_scale(collada); + vtx=vertex.vertex; + + vtx = p_local_xform.xform(vtx); + + + if (vertex_map.has(m_i)) { //vertex may no longer be here, don't bother converting + + + for (Set<int> ::Element *E=vertex_map[m_i].front() ; E; E=E->next() ) { + + vertw[E->get()]=vtx; + } + } + } + + + //vertices are in place, now generate everything else + vertw = PoolVector<Vector3>::Write(); + PoolVector<Vector3> normals; + PoolVector<float> tangents; + print_line("vertex source id: "+vertex_src_id); + if(md.vertices[vertex_src_id].sources.has("NORMAL")){ + //has normals + normals.resize(vlen); + //std::cout << "has normals" << std::endl; + String normal_src_id = md.vertices[vertex_src_id].sources["NORMAL"]; + //std::cout << "normals source: "<< normal_src_id.utf8().get_data() <<std::endl; + ERR_FAIL_COND_V(!md.sources.has(normal_src_id),ERR_INVALID_DATA); + + const Collada::MeshData::Source *m=&md.sources[normal_src_id]; + + ERR_FAIL_COND_V( m->array.size() != vertex_src->array.size(), ERR_INVALID_DATA); + int stride=m->stride; + if (stride==0) + stride=3; + + + //read normals from morph target + PoolVector<Vector3>::Write vertw = normals.write(); + + for(int m_i=0;m_i<m->array.size()/stride;m_i++) { + + int pos = m_i*stride; + Vector3 vtx( m->array[pos+0], m->array[pos+1], m->array[pos+2] ); + + #ifndef NO_UP_AXIS_SWAP + if (collada.state.up_axis==Vector3::AXIS_Z) { + + SWAP( vtx.z, vtx.y ); + vtx.z = -vtx.z; + + } + #endif + + Collada::Vertex vertex; + vertex.vertex=vtx; + vertex.fix_unit_scale(collada); + vtx=vertex.vertex; + + vtx = p_local_xform.xform(vtx); + + + if (vertex_map.has(m_i)) { //vertex may no longer be here, don't bother converting + + + for (Set<int> ::Element *E=vertex_map[m_i].front() ; E; E=E->next() ) { + + vertw[E->get()]=vtx; + } + } + } + + print_line("using built-in normals"); + }else{ + print_line("generating normals"); + _generate_normals(index_array,vertices,normals);//no normals + } + if (final_tangent_array.size() && final_uv_array.size()) { + + _generate_tangents_and_binormals(index_array,vertices,final_uv_array,normals,tangents); + + } + + mrt[Mesh::ARRAY_VERTEX]=vertices; + + mrt[Mesh::ARRAY_NORMAL]=normals; + if (tangents.size()) + mrt[Mesh::ARRAY_TANGENT]=tangents; + if (final_uv_array.size()) + mrt[Mesh::ARRAY_TEX_UV]=final_uv_array; + if (final_uv2_array.size()) + mrt[Mesh::ARRAY_TEX_UV2]=final_uv2_array; + if (final_color_array.size()) + mrt[Mesh::ARRAY_COLOR]=final_color_array; + + mr[j]=mrt; + + } + + } + +#endif + for(int mi=0;mi<p_morph_meshes.size();mi++) { + + //print_line("want surface "+itos(mi)+" has "+itos(p_morph_meshes[mi]->get_surface_count())); + Array a = p_morph_meshes[mi]->surface_get_arrays(surface); + //add valid weight and bone arrays if they exist, TODO check if they are unique to shape (generally not) + + if (final_weight_array.size()) + a[Mesh::ARRAY_WEIGHTS]=final_weight_array; + if (final_bone_array.size()) + a[Mesh::ARRAY_BONES]=final_bone_array; + + a[Mesh::ARRAY_INDEX]=Variant(); + //a.resize(Mesh::ARRAY_MAX); //no need for index + mr.push_back(a); + } + + + p_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES,d,mr,p_for_morph?0:Mesh::ARRAY_COMPRESS_DEFAULT); + + if (material.is_valid()) { + if (p_use_mesh_material) { + p_mesh->surface_set_material(surface, material); + } + p_mesh->surface_set_name(surface, material->get_name()); + } + } + + /*****************/ + /* FIND MATERIAL */ + /*****************/ + + surface++; + } + + + return OK; + +} + + +Error ColladaImport::_create_resources(Collada::Node *p_node) { + + + if (p_node->type==Collada::Node::TYPE_GEOMETRY && node_map.has(p_node->id)) { + + + Spatial * node=node_map[p_node->id].node; + Collada::NodeGeometry *ng = static_cast<Collada::NodeGeometry*>(p_node); + + + if (node->cast_to<Path>()) { + + Path *path = node->cast_to<Path>(); + + String curve = ng->source; + + if (curve_cache.has(ng->source)) { + + path->set_curve(curve_cache[ng->source]); + } else { + + Ref<Curve3D> c = memnew( Curve3D ); + + const Collada::CurveData &cd = collada.state.curve_data_map[ng->source]; + + ERR_FAIL_COND_V( !cd.control_vertices.has("POSITION") , ERR_INVALID_DATA); + ERR_FAIL_COND_V( !cd.control_vertices.has("IN_TANGENT") , ERR_INVALID_DATA); + ERR_FAIL_COND_V( !cd.control_vertices.has("OUT_TANGENT") , ERR_INVALID_DATA); + ERR_FAIL_COND_V( !cd.control_vertices.has("INTERPOLATION") , ERR_INVALID_DATA); + + + ERR_FAIL_COND_V( !cd.sources.has(cd.control_vertices["POSITION"] ) , ERR_INVALID_DATA); + const Collada::CurveData::Source &vertices = cd.sources[ cd.control_vertices["POSITION"] ]; + ERR_FAIL_COND_V( vertices.stride!=3, ERR_INVALID_DATA ); + + ERR_FAIL_COND_V( !cd.sources.has(cd.control_vertices["IN_TANGENT"] ) , ERR_INVALID_DATA); + const Collada::CurveData::Source &in_tangents = cd.sources[ cd.control_vertices["IN_TANGENT"] ]; + ERR_FAIL_COND_V( in_tangents.stride!=3 , ERR_INVALID_DATA); + + ERR_FAIL_COND_V( !cd.sources.has(cd.control_vertices["OUT_TANGENT"] ), ERR_INVALID_DATA ); + const Collada::CurveData::Source &out_tangents = cd.sources[ cd.control_vertices["OUT_TANGENT"] ]; + ERR_FAIL_COND_V( out_tangents.stride!=3, ERR_INVALID_DATA ); + + ERR_FAIL_COND_V( !cd.sources.has(cd.control_vertices["INTERPOLATION"] ), ERR_INVALID_DATA ); + const Collada::CurveData::Source &interps = cd.sources[ cd.control_vertices["INTERPOLATION"] ]; + ERR_FAIL_COND_V( interps.stride!=1, ERR_INVALID_DATA ); + + const Collada::CurveData::Source *tilts=NULL; + if (cd.control_vertices.has("TILT") && cd.sources.has(cd.control_vertices["TILT"])) + tilts=&cd.sources[ cd.control_vertices["TILT"] ]; + + + if (tilts) { + print_line("FOUND TILTS!!!"); + } + int pc = vertices.array.size()/3; + for(int i=0;i<pc;i++) { + + Vector3 pos( vertices.array[i*3+0], vertices.array[i*3+1], vertices.array[i*3+2] ); + Vector3 in( in_tangents.array[i*3+0], in_tangents.array[i*3+1], in_tangents.array[i*3+2] ); + Vector3 out( out_tangents.array[i*3+0], out_tangents.array[i*3+1], out_tangents.array[i*3+2] ); + +#ifndef NO_UP_AXIS_SWAP + if (collada.state.up_axis==Vector3::AXIS_Z) { + + SWAP(pos.y,pos.z); + pos.z=-pos.z; + SWAP(in.y,in.z); + in.z=-in.z; + SWAP(out.y,out.z); + out.z=-out.z; + } +#endif + pos*=collada.state.unit_scale; + in*=collada.state.unit_scale; + out*=collada.state.unit_scale; + + c->add_point(pos,in-pos,out-pos); + if (tilts) + c->set_point_tilt(i,tilts->array[i]); + + } + + curve_cache[ng->source]=c; + path->set_curve(c); + + } + + + } + + + if (node->cast_to<MeshInstance>()) { + + + Collada::NodeGeometry *ng = static_cast<Collada::NodeGeometry*>(p_node); + + MeshInstance *mi = node->cast_to<MeshInstance>(); + + + ERR_FAIL_COND_V(!mi,ERR_BUG); + + + Collada::SkinControllerData *skin=NULL; + Collada::MorphControllerData *morph=NULL; + String meshid; + Transform apply_xform; + Vector<int> bone_remap; + Vector<Ref<Mesh> > morphs; + + print_line("mesh: "+String(mi->get_name())); + + if (ng->controller) { + + print_line("has controller"); + + String ngsource = ng->source; + + if (collada.state.skin_controller_data_map.has(ngsource)) { + + + ERR_FAIL_COND_V(!collada.state.skin_controller_data_map.has(ngsource),ERR_INVALID_DATA); + skin=&collada.state.skin_controller_data_map[ngsource]; + + Vector<String> skeletons = ng->skeletons; + + ERR_FAIL_COND_V( skeletons.empty(), ERR_INVALID_DATA ); + + String skname = skeletons[0]; + if (!node_map.has(skname)) { + print_line("no node for skeleton "+skname); + } + ERR_FAIL_COND_V( !node_map.has(skname), ERR_INVALID_DATA ); + NodeMap nmsk = node_map[skname]; + Skeleton *sk = nmsk.node->cast_to<Skeleton>(); + ERR_FAIL_COND_V( !sk, ERR_INVALID_DATA ); + ERR_FAIL_COND_V( !skeleton_bone_map.has(sk), ERR_INVALID_DATA ); + Map<String, int> &bone_remap_map=skeleton_bone_map[sk]; + + + meshid=skin->base; + + if (collada.state.morph_controller_data_map.has(meshid)) { + //it's a morph!! + morph = &collada.state.morph_controller_data_map[meshid]; + ngsource=meshid; + meshid=morph->mesh; + } else { + ngsource=""; + } + + if (apply_mesh_xform_to_vertices) { + apply_xform=collada.fix_transform(p_node->default_transform); + node->set_transform(Transform()); + } else { + apply_xform=Transform(); + } + + Collada::SkinControllerData::Source *joint_src=NULL; + + ERR_FAIL_COND_V(!skin->weights.sources.has("JOINT"),ERR_INVALID_DATA); + + String joint_id = skin->weights.sources["JOINT"].source; + ERR_FAIL_COND_V(!skin->sources.has(joint_id),ERR_INVALID_DATA); + + joint_src = &skin->sources[joint_id]; + + bone_remap.resize(joint_src->sarray.size()); + + for(int i=0;i<bone_remap.size();i++) { + + String str = joint_src->sarray[i]; + if (!bone_remap_map.has(str)) { + print_line("bone not found for remap: "+str); + print_line("in skeleton: "+skname); + } + ERR_FAIL_COND_V( !bone_remap_map.has(str), ERR_INVALID_DATA ); + bone_remap[i]=bone_remap_map[str]; + } + } + + if (collada.state.morph_controller_data_map.has(ngsource)) { + print_line("is morph "+ngsource); + //it's a morph!! + morph = &collada.state.morph_controller_data_map[ngsource]; + meshid=morph->mesh; + printf("KKmorph: %p\n",morph); + print_line("morph mshid: "+meshid); + + Vector<String> targets; + + morph->targets.has("MORPH_TARGET"); + String target = morph->targets["MORPH_TARGET"]; + bool valid=false; + if (morph->sources.has(target)) { + valid=true; + Vector<String> names = morph->sources[target].sarray; + for(int i=0;i<names.size();i++) { + + String meshid=names[i]; + if (collada.state.mesh_data_map.has(meshid)) { + Ref<Mesh> mesh=Ref<Mesh>(memnew( Mesh )); + const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid]; + Error err = _create_mesh_surfaces(false,mesh,ng->material_map,meshdata,apply_xform,bone_remap,skin,NULL,Vector<Ref<Mesh> >(),true); + ERR_FAIL_COND_V(err,err); + + morphs.push_back(mesh); + } else { + valid=false; + } + } + } + + if (!valid) + morphs.clear(); + + ngsource=""; + } + + if (ngsource!=""){ + ERR_EXPLAIN("Controller Instance Source '"+ngsource+"' is neither skin or morph!"); + ERR_FAIL_V( ERR_INVALID_DATA ); + } + + + + } else { + meshid=ng->source; + } + + Ref<Mesh> mesh; + if (mesh_cache.has(meshid)) { + mesh=mesh_cache[meshid]; + } else { + if (collada.state.mesh_data_map.has(meshid)) { + //bleh, must ignore invalid + + ERR_FAIL_COND_V(!collada.state.mesh_data_map.has(meshid),ERR_INVALID_DATA); + mesh=Ref<Mesh>(memnew( Mesh )); + const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid]; + mesh->set_name( meshdata.name ); + Error err = _create_mesh_surfaces(morphs.size()==0,mesh,ng->material_map,meshdata,apply_xform,bone_remap,skin,morph,morphs,false,use_mesh_builtin_materials); + ERR_FAIL_COND_V(err,err); + + mesh_cache[meshid]=mesh; + } else { + + print_line("Warning, will not import geometry: "+meshid); + } + } + + if (!mesh.is_null()) { + + mi->set_mesh(mesh); + if (!use_mesh_builtin_materials) { + const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid]; + + for(int i=0;i<meshdata.primitives.size();i++) { + + String matname=meshdata.primitives[i].material; + + if (ng->material_map.has(matname)) { + String target=ng->material_map[matname].target; + + Ref<Material> material; + if (!material_cache.has(target)) { + Error err = _create_material(target); + if (!err) + material=material_cache[target]; + } else + material=material_cache[target]; + + mi->set_surface_material(i,material); + } else if (matname!=""){ + print_line("Warning, unreferenced material in geometry instance: "+matname); + } + + } + } + } + } + } + + for(int i=0;i<p_node->children.size();i++) { + + Error err = _create_resources(p_node->children[i]); + if (err) + return err; + } + return OK; +} + + +Error ColladaImport::load(const String& p_path,int p_flags,bool p_force_make_tangents) { + + Error err = collada.load(p_path,p_flags); + ERR_FAIL_COND_V(err,err); + + force_make_tangents=p_force_make_tangents; + ERR_FAIL_COND_V( !collada.state.visual_scene_map.has( collada.state.root_visual_scene ), ERR_INVALID_DATA ); + Collada::VisualScene &vs = collada.state.visual_scene_map[ collada.state.root_visual_scene ]; + + scene = memnew( Spatial ); // root + + //determine what's going on with the lights + for(int i=0;i<vs.root_nodes.size();i++) { + + _pre_process_lights(vs.root_nodes[i]); + + } + //import scene + + for(int i=0;i<vs.root_nodes.size();i++) { + + Error err = _create_scene_skeletons(vs.root_nodes[i]); + if (err!=OK) { + memdelete(scene); + ERR_FAIL_COND_V(err,err); + } + } + + for(int i=0;i<vs.root_nodes.size();i++) { + + Error err = _create_scene(vs.root_nodes[i],scene); + if (err!=OK) { + memdelete(scene); + ERR_FAIL_COND_V(err,err); + } + + Error err2 = _create_resources(vs.root_nodes[i]); + if (err2!=OK) { + memdelete(scene); + ERR_FAIL_COND_V(err2,err2); + } + } + + //optatively, set unit scale in the root + scene->set_transform(collada.get_root_transform()); + + + return OK; + +} + +void ColladaImport::_fix_param_animation_tracks() { + + for (Map<String,Collada::Node*>::Element *E=collada.state.scene_map.front();E;E=E->next()) { + + Collada::Node *n = E->get(); + switch(n->type) { + + case Collada::Node::TYPE_NODE: { + // ? do nothing + } break; + case Collada::Node::TYPE_JOINT: { + + } break; + case Collada::Node::TYPE_SKELETON: { + + } break; + case Collada::Node::TYPE_LIGHT: { + + } break; + case Collada::Node::TYPE_CAMERA: { + + } break; + case Collada::Node::TYPE_GEOMETRY: { + + Collada::NodeGeometry *ng = static_cast<Collada::NodeGeometry*>(n); + // test source(s) + String source = ng->source; + + while (source!="") { + + if (collada.state.skin_controller_data_map.has(source)) { + + const Collada::SkinControllerData& skin = collada.state.skin_controller_data_map[source]; + + //nothing to animate here i think + + source=skin.base; + } else if (collada.state.morph_controller_data_map.has(source)) { + + + const Collada::MorphControllerData& morph = collada.state.morph_controller_data_map[source]; + + if (morph.targets.has("MORPH_WEIGHT") && morph.targets.has("MORPH_TARGET")) { + + + String weights = morph.targets["MORPH_WEIGHT"]; + String targets = morph.targets["MORPH_TARGET"]; + //fails here + + if (morph.sources.has(targets) && morph.sources.has(weights)) { + const Collada::MorphControllerData::Source &weight_src=morph.sources[weights]; + const Collada::MorphControllerData::Source &target_src=morph.sources[targets]; + + + ERR_FAIL_COND(weight_src.array.size() != target_src.sarray.size()); + + for(int i=0;i<weight_src.array.size();i++) { + + String track_name = weights+"("+itos(i)+")"; + String mesh_name = target_src.sarray[i]; + if (collada.state.mesh_name_map.has(mesh_name) && collada.state.referenced_tracks.has(track_name)) { + + + const Vector<int>&rt = collada.state.referenced_tracks[track_name]; + + for(int rti=0;rti<rt.size();rti++) { + Collada::AnimationTrack *at = &collada.state.animation_tracks[rt[rti]]; + + at->target=E->key(); + at->param="morph/"+collada.state.mesh_name_map[mesh_name]; + at->property=true; + //at->param + } + } + } + } + } + source=morph.mesh; + } else { + + source=""; // for now nothing else supported + } + } + + } break; + + } + } + +} + +void ColladaImport::create_animations(bool p_make_tracks_in_all_bones, bool p_import_value_tracks) { + + + _fix_param_animation_tracks(); + for(int i=0;i<collada.state.animation_clips.size();i++) { + + for(int j=0;j<collada.state.animation_clips[i].tracks.size();j++) + tracks_in_clips.insert(collada.state.animation_clips[i].tracks[j]); + } + + + + for(int i=0;i<collada.state.animation_tracks.size();i++) { + + Collada::AnimationTrack &at = collada.state.animation_tracks[i]; + //print_line("CHANNEL: "+at.target+" PARAM: "+at.param); + + String node; + + if (!node_map.has(at.target)) { + + if (node_name_map.has(at.target)) { + + node=node_name_map[at.target]; + } else { + print_line("Coudlnt find node: "+at.target); + continue; + } + } else { + node=at.target; + } + + + if (at.property) { + + valid_animated_properties.push_back(i); + + } else { + + node_map[node].anim_tracks.push_back(i); + valid_animated_nodes.insert(node); + } + + } + + create_animation(-1,p_make_tracks_in_all_bones, p_import_value_tracks); + //print_line("clipcount: "+itos(collada.state.animation_clips.size())); + for(int i=0;i<collada.state.animation_clips.size();i++) + create_animation(i, p_make_tracks_in_all_bones, p_import_value_tracks); + +} + +void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones, bool p_import_value_tracks) { + + Ref<Animation> animation = Ref<Animation>( memnew( Animation )); + + + if (p_clip==-1) { + + //print_line("default"); + animation->set_name("default"); + } else { + //print_line("clip name: "+collada.state.animation_clips[p_clip].name); + animation->set_name(collada.state.animation_clips[p_clip].name); + } + + for(Map<String,NodeMap>::Element *E=node_map.front();E;E=E->next()) { + + if (E->get().bone<0) + continue; + bones_with_animation[E->key()]=false; + } + //store and validate tracks + + if (p_clip==-1) { + //main anim + } + + Set<int> track_filter; + + + if (p_clip==-1) { + + for(int i=0;i<collada.state.animation_clips.size();i++) { + + int tc = collada.state.animation_clips[i].tracks.size(); + for(int j=0;j<tc;j++) { + + String n = collada.state.animation_clips[i].tracks[j]; + if (collada.state.by_id_tracks.has(n)) { + + const Vector<int>&ti = collada.state.by_id_tracks[n]; + for(int k=0;k<ti.size();k++) { + track_filter.insert(ti[k]); + } + } + } + } + } else { + + int tc = collada.state.animation_clips[p_clip].tracks.size(); + for(int j=0;j<tc;j++) { + + String n = collada.state.animation_clips[p_clip].tracks[j]; + if (collada.state.by_id_tracks.has(n)) { + + const Vector<int>&ti = collada.state.by_id_tracks[n]; + for(int k=0;k<ti.size();k++) { + track_filter.insert(ti[k]); + } + } + } + + } + + //animation->set_loop(true); + //create animation tracks + + Vector<float> base_snapshots; + + float f=0; + float snapshot_interval = 1.0/bake_fps; //should be customizable somewhere... + + float anim_length=collada.state.animation_length; + if (p_clip>=0 && collada.state.animation_clips[p_clip].end) + anim_length=collada.state.animation_clips[p_clip].end; + + while(f<anim_length) { + + base_snapshots.push_back(f); + + f+=snapshot_interval; + + if (f>=anim_length) { + base_snapshots.push_back(anim_length); + + } + } + + //print_line("anim len: "+rtos(anim_length)); + animation->set_length(anim_length); + + bool tracks_found=false; + + + + for(Set<String>::Element* E=valid_animated_nodes.front();E;E=E->next()) { + + // take snapshots + + + if (!collada.state.scene_map.has(E->get())) { + + continue; + } + + NodeMap &nm = node_map[E->get()]; + String path = scene->get_path_to(nm.node); + + if (nm.bone>=0) { + Skeleton *sk = static_cast<Skeleton*>(nm.node); + String name = sk->get_bone_name(nm.bone); + path=path+":"+name; + } + + bool found_anim=false; + + + Collada::Node *cn = collada.state.scene_map[E->get()]; + if (cn->ignore_anim) { + + continue; + } + + + + animation->add_track(Animation::TYPE_TRANSFORM); + int track = animation->get_track_count() -1; + animation->track_set_path( track , path ); + animation->track_set_imported( track , true ); //helps merging later + + Vector<float> snapshots = base_snapshots; + + if (nm.anim_tracks.size()==1) { + //use snapshot keys from anim track instead, because this was most likely exported baked + Collada::AnimationTrack &at = collada.state.animation_tracks[nm.anim_tracks.front()->get()]; + snapshots.clear(); + for(int i=0;i<at.keys.size();i++) + snapshots.push_back(at.keys[i].time); + + + } + + + for(int i=0;i<snapshots.size();i++) { + + + for(List<int>::Element *ET=nm.anim_tracks.front();ET;ET=ET->next()) { + //apply tracks + + + if (p_clip==-1) { + + if (track_filter.has(ET->get())) { + + continue; + } + } else { + + if (!track_filter.has(ET->get())) + continue; + + } + + found_anim=true; + + Collada::AnimationTrack &at = collada.state.animation_tracks[ET->get()]; + + int xform_idx=-1; + for(int j=0;j<cn->xform_list.size();j++) { + + + if (cn->xform_list[j].id==at.param) { + + xform_idx=j; + break; + } + } + + if (xform_idx==-1) { + print_line("couldnt find matching node "+at.target+" xform for track "+at.param); + continue; + } + + ERR_CONTINUE(xform_idx==-1); + + Vector<float> data = at.get_value_at_time(snapshots[i]); + ERR_CONTINUE(data.empty()); + + + Collada::Node::XForm &xf = cn->xform_list[xform_idx]; + + if (at.component=="ANGLE") { + ERR_CONTINUE(data.size()!=1); + ERR_CONTINUE(xf.op!=Collada::Node::XForm::OP_ROTATE); + ERR_CONTINUE(xf.data.size()<4); + xf.data[3]=data[0]; + } else if (at.component=="X" || at.component=="Y" || at.component=="Z") { + int cn=at.component[0]-'X'; + ERR_CONTINUE(cn>=xf.data.size()); + ERR_CONTINUE(data.size()>1); + xf.data[cn]=data[0]; + } else if (data.size()==xf.data.size()) { + + xf.data=data; + } else { + + + if ( data.size()!=xf.data.size() ) { + print_line("component "+at.component+" datasize "+itos(data.size())+" xfdatasize "+itos(xf.data.size())); + } + + ERR_CONTINUE( data.size()!=xf.data.size() ); + } + } + + Transform xform = cn->compute_transform(collada); + xform = collada.fix_transform(xform) * cn->post_transform; + + + if (nm.bone>=0) { + //make bone transform relative to rest (in case of skeleton) + Skeleton *sk = nm.node->cast_to<Skeleton>(); + if (sk) { + + xform = sk->get_bone_rest(nm.bone).affine_inverse() * xform; + } else { + + ERR_PRINT("INVALID SKELETON!!!!"); + } + } + + Quat q = xform.basis; + q.normalize(); + Vector3 s = xform.basis.get_scale(); + Vector3 l = xform.origin; + + animation->transform_track_insert_key(track,snapshots[i],l,q,s); + + } + + + + if (nm.bone>=0) { + if (found_anim) + bones_with_animation[E->get()]=true; + } + + if (found_anim) + tracks_found=true; + else { + animation->remove_track( track ); + } + + } + + if (p_make_tracks_in_all_bones) { + + //some bones may lack animation, but since we don't store pose as a property, we must add keyframes! + for(Map<String,bool>::Element *E=bones_with_animation.front();E;E=E->next()) { + + if (E->get()) + continue; + + //print_line("BONE LACKS ANIM: "+E->key()); + + NodeMap &nm = node_map[E->key()]; + String path = scene->get_path_to(nm.node); + ERR_CONTINUE( nm.bone <0 ); + Skeleton *sk = static_cast<Skeleton*>(nm.node); + String name = sk->get_bone_name(nm.bone); + path=path+":"+name; + + Collada::Node *cn = collada.state.scene_map[E->key()]; + if (cn->ignore_anim) { + print_line("warning, ignoring animation on node: "+path); + continue; + } + + animation->add_track(Animation::TYPE_TRANSFORM); + int track = animation->get_track_count() -1; + animation->track_set_path( track , path ); + animation->track_set_imported( track , true ); //helps merging later + + + Transform xform = cn->compute_transform(collada); + xform = collada.fix_transform(xform) * cn->post_transform; + + xform = sk->get_bone_rest(nm.bone).affine_inverse() * xform; + + Quat q = xform.basis; + q.normalize(); + Vector3 s = xform.basis.get_scale(); + Vector3 l = xform.origin; + + animation->transform_track_insert_key(track,0,l,q,s); + + tracks_found=true; + } + } + + + + if (p_import_value_tracks) { + for (int i = 0; i < valid_animated_properties.size(); i++) { + + + int ti = valid_animated_properties[i]; + + if (p_clip == -1) { + + if (track_filter.has(ti)) + continue; + } + else { + + if (!track_filter.has(ti)) + continue; + + } + + + Collada::AnimationTrack &at = collada.state.animation_tracks[ti]; + + // take snapshots + if (!collada.state.scene_map.has(at.target)) + continue; + + NodeMap &nm = node_map[at.target]; + String path = scene->get_path_to(nm.node); + + animation->add_track(Animation::TYPE_VALUE); + int track = animation->get_track_count() - 1; + + path = path + ":" + at.param; + animation->track_set_path(track, path); + animation->track_set_imported(track, true); //helps merging later + + + for (int i = 0; i < at.keys.size(); i++) { + + float time = at.keys[i].time; + Variant value; + Vector<float> data = at.keys[i].data; + if (data.size() == 1) { + //push a float + value = data[0]; + + } + else if (data.size() == 16) { + //matrix + print_line("value keys for matrices not supported"); + } + else { + + print_line("don't know what to do with this amount of value keys: " + itos(data.size())); + } + + animation->track_insert_key(track, time, value); + } + + + tracks_found = true; + + } + } + + + + if (tracks_found) { + + animations.push_back(animation); + } + + + +} + + +/*********************************************************************************/ +/*************************************** SCENE ***********************************/ +/*********************************************************************************/ + + +#define DEBUG_ANIMATION + + +uint32_t EditorSceneImporterCollada::get_import_flags() const { + + return IMPORT_SCENE|IMPORT_ANIMATION; + +} +void EditorSceneImporterCollada::get_extensions(List<String> *r_extensions) const { + + + r_extensions->push_back("dae"); +} +Node* EditorSceneImporterCollada::import_scene(const String& p_path, uint32_t p_flags,int p_bake_fps, List<String> *r_missing_deps, Error* r_err) { + + ColladaImport state; + uint32_t flags=Collada::IMPORT_FLAG_SCENE; + if (p_flags&IMPORT_ANIMATION) + flags|=Collada::IMPORT_FLAG_ANIMATION; + + state.use_mesh_builtin_materials=!(p_flags&IMPORT_MATERIALS_IN_INSTANCES); + state.bake_fps=p_bake_fps; + + Error err = state.load(p_path,flags,p_flags&EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS); + + ERR_FAIL_COND_V(err!=OK,NULL); + + if (state.missing_textures.size()) { + + /* + for(int i=0;i<state.missing_textures.size();i++) { + EditorNode::add_io_error("Texture Not Found: "+state.missing_textures[i]); + } + */ + + + if (r_missing_deps) { + + for(int i=0;i<state.missing_textures.size();i++) { + //EditorNode::add_io_error("Texture Not Found: "+state.missing_textures[i]); + r_missing_deps->push_back(state.missing_textures[i]); + } + + } + } + + if (p_flags&IMPORT_ANIMATION) { + + state.create_animations(p_flags&IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS,p_flags&EditorSceneImporter::IMPORT_ANIMATION_KEEP_VALUE_TRACKS); + AnimationPlayer *ap = memnew( AnimationPlayer ); + for(int i=0;i<state.animations.size();i++) { + String name; + if (state.animations[i]->get_name()=="") + name="default"; + else + name=state.animations[i]->get_name(); + + if (p_flags&IMPORT_ANIMATION_DETECT_LOOP) { + + if (name.begins_with("loop") || name.ends_with("loop") || name.begins_with("cycle") || name.ends_with("cycle")) { + state.animations[i]->set_loop(true); + } + } + + ap->add_animation(name,state.animations[i]); + } + state.scene->add_child(ap); + ap->set_owner(state.scene); + + } + + return state.scene; + +} + +Ref<Animation> EditorSceneImporterCollada::import_animation(const String& p_path,uint32_t p_flags) { + + + ColladaImport state; + + + state.use_mesh_builtin_materials=false; + + Error err = state.load(p_path,Collada::IMPORT_FLAG_ANIMATION,p_flags&EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS); + ERR_FAIL_COND_V(err!=OK,RES()); + + + state.create_animations(p_flags&EditorSceneImporter::IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS,p_flags&EditorSceneImporter::IMPORT_ANIMATION_KEEP_VALUE_TRACKS); + if (state.scene) + memdelete(state.scene); + + if (state.animations.size()==0) + return Ref<Animation>(); + Ref<Animation> anim=state.animations[0]; + anim=state.animations[0]; + print_line("Anim Load OK"); + String base = p_path.get_basename().to_lower(); + if (p_flags&IMPORT_ANIMATION_DETECT_LOOP) { + + if (base.begins_with("loop") || base.ends_with("loop") || base.begins_with("cycle") || base.ends_with("cycle")) { + anim->set_loop(true); + } + } + + + return anim; +} + + +EditorSceneImporterCollada::EditorSceneImporterCollada() { + + +} + diff --git a/editor/import/editor_import_collada.h b/editor/import/editor_import_collada.h new file mode 100644 index 0000000000..5c7624bd33 --- /dev/null +++ b/editor/import/editor_import_collada.h @@ -0,0 +1,51 @@ +/*************************************************************************/ +/* editor_import_collada.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITOR_IMPORT_COLLADA_H +#define EDITOR_IMPORT_COLLADA_H + +#include "editor/import/resource_importer_scene.h" + + + +class EditorSceneImporterCollada : public EditorSceneImporter { + + GDCLASS(EditorSceneImporterCollada,EditorSceneImporter ); +public: + + virtual uint32_t get_import_flags() const; + virtual void get_extensions(List<String> *r_extensions) const; + virtual Node* import_scene(const String& p_path,uint32_t p_flags,int p_bake_fps,List<String> *r_missing_deps=NULL,Error* r_err=NULL); + virtual Ref<Animation> import_animation(const String& p_path,uint32_t p_flags); + + EditorSceneImporterCollada(); +}; + + +#endif + diff --git a/tools/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp index f14c10fb99..f14c10fb99 100644 --- a/tools/editor/import/resource_importer_csv_translation.cpp +++ b/editor/import/resource_importer_csv_translation.cpp diff --git a/tools/editor/import/resource_importer_csv_translation.h b/editor/import/resource_importer_csv_translation.h index d08218e7d9..d08218e7d9 100644 --- a/tools/editor/import/resource_importer_csv_translation.h +++ b/editor/import/resource_importer_csv_translation.h diff --git a/tools/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp index aacb5fbb2d..aacb5fbb2d 100644 --- a/tools/editor/import/resource_importer_obj.cpp +++ b/editor/import/resource_importer_obj.cpp diff --git a/tools/editor/import/resource_importer_obj.h b/editor/import/resource_importer_obj.h index d2a3c4fddd..d2a3c4fddd 100644 --- a/tools/editor/import/resource_importer_obj.h +++ b/editor/import/resource_importer_obj.h diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp new file mode 100644 index 0000000000..cdaf40798b --- /dev/null +++ b/editor/import/resource_importer_scene.cpp @@ -0,0 +1,1328 @@ +#include "resource_importer_scene.h" + +#include "scene/resources/packed_scene.h" +#include "io/resource_saver.h" +#include "editor/editor_node.h" + +#include "scene/3d/mesh_instance.h" +#include "scene/3d/navigation.h" +#include "scene/3d/room_instance.h" +#include "scene/3d/body_shape.h" +#include "scene/3d/physics_body.h" +#include "scene/3d/portal.h" +#include "scene/3d/vehicle_body.h" +#include "scene/resources/sphere_shape.h" +#include "scene/resources/box_shape.h" +#include "scene/resources/ray_shape.h" +#include "scene/resources/plane_shape.h" + + +void EditorScenePostImport::_bind_methods() { + + BIND_VMETHOD( MethodInfo("post_import",PropertyInfo(Variant::OBJECT,"scene")) ); + +} + +Node *EditorScenePostImport::post_import(Node* p_scene) { + + if (get_script_instance()) + return get_script_instance()->call("post_import",p_scene); + + return p_scene; +} + +EditorScenePostImport::EditorScenePostImport() { + + +} + + +String ResourceImporterScene::get_importer_name() const { + + return "scene"; +} + +String ResourceImporterScene::get_visible_name() const{ + + return "Scene"; +} + +void ResourceImporterScene::get_recognized_extensions(List<String> *p_extensions) const{ + + for (Set< Ref<EditorSceneImporter> >::Element *E=importers.front();E;E=E->next()) { + E->get()->get_extensions(p_extensions); + } +} + +String ResourceImporterScene::get_save_extension() const { + return "scn"; +} + +String ResourceImporterScene::get_resource_type() const{ + + return "PackedScene"; +} + +bool ResourceImporterScene::get_option_visibility(const String& p_option,const Map<StringName,Variant>& p_options) const { + + if (p_option.begins_with("animation/")) { + if (p_option!="animation/import" && !bool(p_options["animation/import"])) + return false; + + if (p_option.begins_with("animation/optimizer/") && p_option!="animation/optimizer/enabled" && !bool(p_options["animation/optimizer/enabled"])) + return false; + + if (p_option.begins_with("animation/clip_")) { + int max_clip = p_options["animation/clips/amount"]; + int clip = p_option.get_slice("/",1).get_slice("_",1).to_int()-1; + if (clip>=max_clip) + return false; + } + } + + return true; + +} + +int ResourceImporterScene::get_preset_count() const { + return 0; +} +String ResourceImporterScene::get_preset_name(int p_idx) const { + + return ""; +} + + +static bool _teststr(const String& p_what,const String& p_str) { + + if (p_what.findn("$"+p_str)!=-1) //blender and other stuff + return true; + if (p_what.to_lower().ends_with("-"+p_str)) //collada only supports "_" and "-" besides letters + return true; + if (p_what.to_lower().ends_with("_"+p_str)) //collada only supports "_" and "-" besides letters + return true; + return false; +} + +static String _fixstr(const String& p_what,const String& p_str) { + + if (p_what.findn("$"+p_str)!=-1) //blender and other stuff + return p_what.replace("$"+p_str,""); + if (p_what.to_lower().ends_with("-"+p_str)) //collada only supports "_" and "-" besides letters + return p_what.substr(0,p_what.length()-(p_str.length()+1)); + if (p_what.to_lower().ends_with("_"+p_str)) //collada only supports "_" and "-" besides letters + return p_what.substr(0,p_what.length()-(p_str.length()+1)); + return p_what; +} + + +Node* ResourceImporterScene::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map) { + + // children first.. + for(int i=0;i<p_node->get_child_count();i++) { + + + Node *r = _fix_node(p_node->get_child(i),p_root,collision_map); + if (!r) { + print_line("was erased.."); + i--; //was erased + } + } + + String name = p_node->get_name(); + + bool isroot = p_node==p_root; + + + if (!isroot && _teststr(name,"noimp")) { + + memdelete(p_node); + return NULL; + } + + + if (p_node->cast_to<MeshInstance>()) { + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + bool bb=false; + + if ((_teststr(name,"bb"))) { + bb=true; + } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"bb"))) { + bb=true; + + } + + if (bb) { + mi->set_flag(GeometryInstance::FLAG_BILLBOARD,true); + if (mi->get_mesh().is_valid()) { + + Ref<Mesh> m = mi->get_mesh(); + for(int i=0;i<m->get_surface_count();i++) { + + Ref<FixedSpatialMaterial> fm = m->surface_get_material(i); + if (fm.is_valid()) { + //fm->set_flag(Material::FLAG_UNSHADED,true); + //fm->set_flag(Material::FLAG_DOUBLE_SIDED,true); + //fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); + //fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); + } + } + } + } + } + + + if (p_node->cast_to<MeshInstance>()) { + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + Ref<Mesh> m = mi->get_mesh(); + + if (m.is_valid()) { + + for(int i=0;i<m->get_surface_count();i++) { + + Ref<FixedSpatialMaterial> mat = m->surface_get_material(i); + if (!mat.is_valid()) + continue; + + if (_teststr(mat->get_name(),"alpha")) { + + mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT,true); + mat->set_name(_fixstr(mat->get_name(),"alpha")); + } + if (_teststr(mat->get_name(),"vcol")) { + + mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR,true); + mat->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR,true); + mat->set_name(_fixstr(mat->get_name(),"vcol")); + } + + } + } + } + + if (p_node->cast_to<AnimationPlayer>()) { + //remove animations referencing non-importable nodes + AnimationPlayer *ap = p_node->cast_to<AnimationPlayer>(); + + List<StringName> anims; + ap->get_animation_list(&anims); + for(List<StringName>::Element *E=anims.front();E;E=E->next()) { + + Ref<Animation> anim=ap->get_animation(E->get()); + ERR_CONTINUE(anim.is_null()); + for(int i=0;i<anim->get_track_count();i++) { + NodePath path = anim->track_get_path(i); + + for(int j=0;j<path.get_name_count();j++) { + String node = path.get_name(j); + if (_teststr(node,"noimp")) { + anim->remove_track(i); + i--; + break; + } + } + } + + } + } + + + if (p_node->cast_to<MeshInstance>()) { + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + String str; + + if ((_teststr(name,"imp"))) { + str=name; + } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"imp"))) { + str=mi->get_mesh()->get_name(); + + } + + + if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) { + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>(); + String d=str.substr(str.find("imp")+3,str.length()); + if (d!="") { + if ((d[0]<'0' || d[0]>'9')) + d=d.substr(1,d.length()); + if (d.length() && d[0]>='0' && d[0]<='9') { + float dist = d.to_double(); + mi->set_flag(GeometryInstance::FLAG_BILLBOARD,true); + mi->set_flag(GeometryInstance::FLAG_BILLBOARD_FIX_Y,true); + //mi->set_draw_range_begin(dist); + //mi->set_draw_range_end(100000); + + //mip->set_draw_range_begin(0); + //mip->set_draw_range_end(dist); + + if (mi->get_mesh().is_valid()) { + + Ref<Mesh> m = mi->get_mesh(); + for(int i=0;i<m->get_surface_count();i++) { + + Ref<FixedSpatialMaterial> fm = m->surface_get_material(i); + if (fm.is_valid()) { + //fm->set_flag(Material::FLAG_UNSHADED,true); + //fm->set_flag(Material::FLAG_DOUBLE_SIDED,true); + //fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); + //fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); + } + } + } + } + } + } + } +#if 0 + if (p_flags&SCENE_FLAG_CREATE_LODS && p_node->cast_to<MeshInstance>()) { + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + String str; + + if ((_teststr(name,"lod"))) { + str=name; + } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"lod"))) { + str=mi->get_mesh()->get_name(); + + } + + + if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) { + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>(); + String d=str.substr(str.find("lod")+3,str.length()); + if (d!="") { + if ((d[0]<'0' || d[0]>'9')) + d=d.substr(1,d.length()); + if (d.length() && d[0]>='0' && d[0]<='9') { + float dist = d.to_double(); + /// mi->set_draw_range_begin(dist); + // mi->set_draw_range_end(100000); + + // mip->set_draw_range_begin(0); + // mip->set_draw_range_end(dist); + + /*if (mi->get_mesh().is_valid()) { + + Ref<Mesh> m = mi->get_mesh(); + for(int i=0;i<m->get_surface_count();i++) { + + Ref<FixedSpatialMaterial> fm = m->surface_get_material(i); + if (fm.is_valid()) { + fm->set_flag(Material::FLAG_UNSHADED,true); + fm->set_flag(Material::FLAG_DOUBLE_SIDED,true); + fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true); + fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); + } + } + }*/ + } + } + } + } + + + if (p_flags&SCENE_FLAG_DETECT_LIGHTMAP_LAYER && _teststr(name,"lm") && p_node->cast_to<MeshInstance>()) { + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + String str=name; + int layer = str.substr(str.find("lm")+3,str.length()).to_int(); + //mi->set_baked_light_texture_id(layer); + } +#endif + if (_teststr(name,"colonly")) { + + if (isroot) + return p_node; + + if (p_node->cast_to<MeshInstance>()) { + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + Node * col = mi->create_trimesh_collision_node(); + ERR_FAIL_COND_V(!col,NULL); + + col->set_name(_fixstr(name,"colonly")); + col->cast_to<Spatial>()->set_transform(mi->get_transform()); + p_node->replace_by(col); + memdelete(p_node); + p_node=col; + + StaticBody *sb = col->cast_to<StaticBody>(); + CollisionShape *colshape = memnew( CollisionShape); + colshape->set_shape(sb->get_shape(0)); + colshape->set_name("shape"); + sb->add_child(colshape); + colshape->set_owner(p_node->get_owner()); + } else if (p_node->has_meta("empty_draw_type")) { + String empty_draw_type = String(p_node->get_meta("empty_draw_type")); + print_line(empty_draw_type); + StaticBody *sb = memnew( StaticBody); + sb->set_name(_fixstr(name,"colonly")); + sb->cast_to<Spatial>()->set_transform(p_node->cast_to<Spatial>()->get_transform()); + p_node->replace_by(sb); + memdelete(p_node); + CollisionShape *colshape = memnew( CollisionShape); + if (empty_draw_type == "CUBE") { + BoxShape *boxShape = memnew( BoxShape); + boxShape->set_extents(Vector3(1, 1, 1)); + colshape->set_shape(boxShape); + colshape->set_name("BoxShape"); + } else if (empty_draw_type == "SINGLE_ARROW") { + RayShape *rayShape = memnew( RayShape); + rayShape->set_length(1); + colshape->set_shape(rayShape); + colshape->set_name("RayShape"); + sb->cast_to<Spatial>()->rotate_x(Math_PI / 2); + } else if (empty_draw_type == "IMAGE") { + PlaneShape *planeShape = memnew( PlaneShape); + colshape->set_shape(planeShape); + colshape->set_name("PlaneShape"); + } else { + SphereShape *sphereShape = memnew( SphereShape); + sphereShape->set_radius(1); + colshape->set_shape(sphereShape); + colshape->set_name("SphereShape"); + } + sb->add_child(colshape); + colshape->set_owner(sb->get_owner()); + } + + } else if (_teststr(name,"rigid") && p_node->cast_to<MeshInstance>()) { + + if (isroot) + return p_node; + + // get mesh instance and bounding box + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + Rect3 aabb = mi->get_aabb(); + + // create a new rigid body collision node + RigidBody * rigid_body = memnew( RigidBody ); + Node * col = rigid_body; + ERR_FAIL_COND_V(!col,NULL); + + // remove node name postfix + col->set_name(_fixstr(name,"rigid")); + // get mesh instance xform matrix to the rigid body collision node + col->cast_to<Spatial>()->set_transform(mi->get_transform()); + // save original node by duplicating it into a new instance and correcting the name + Node * mesh = p_node->duplicate(); + mesh->set_name(_fixstr(name,"rigid")); + // reset the xform matrix of the duplicated node so it can inherit parent node xform + mesh->cast_to<Spatial>()->set_transform(Transform(Basis())); + // reparent the new mesh node to the rigid body collision node + p_node->add_child(mesh); + mesh->set_owner(p_node->get_owner()); + // replace the original node with the rigid body collision node + p_node->replace_by(col); + memdelete(p_node); + p_node=col; + + // create an alias for the rigid body collision node + RigidBody *rb = col->cast_to<RigidBody>(); + // create a new Box collision shape and set the right extents + Ref<BoxShape> shape = memnew( BoxShape ); + shape->set_extents(aabb.get_size() * 0.5); + CollisionShape *colshape = memnew( CollisionShape); + colshape->set_name("shape"); + colshape->set_shape(shape); + // reparent the new collision shape to the rigid body collision node + rb->add_child(colshape); + colshape->set_owner(p_node->get_owner()); + + } else if (_teststr(name,"col") && p_node->cast_to<MeshInstance>()) { + + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + mi->set_name(_fixstr(name,"col")); + Node *col= mi->create_trimesh_collision_node(); + ERR_FAIL_COND_V(!col,NULL); + + col->set_name("col"); + p_node->add_child(col); + + StaticBody *sb=col->cast_to<StaticBody>(); + CollisionShape *colshape = memnew( CollisionShape); + colshape->set_shape(sb->get_shape(0)); + colshape->set_name("shape"); + col->add_child(colshape); + colshape->set_owner(p_node->get_owner()); + sb->set_owner(p_node->get_owner()); + + } else if (_teststr(name,"navmesh") && p_node->cast_to<MeshInstance>()) { + + if (isroot) + return p_node; + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + Ref<Mesh> mesh=mi->get_mesh(); + ERR_FAIL_COND_V(mesh.is_null(),NULL); + NavigationMeshInstance *nmi = memnew( NavigationMeshInstance ); + + + nmi->set_name(_fixstr(name,"navmesh")); + Ref<NavigationMesh> nmesh = memnew( NavigationMesh); + nmesh->create_from_mesh(mesh); + nmi->set_navigation_mesh(nmesh); + nmi->cast_to<Spatial>()->set_transform(mi->get_transform()); + p_node->replace_by(nmi); + memdelete(p_node); + p_node=nmi; + } else if (_teststr(name,"vehicle")) { + + if (isroot) + return p_node; + + Node *owner = p_node->get_owner(); + Spatial *s = p_node->cast_to<Spatial>(); + VehicleBody *bv = memnew( VehicleBody ); + String n = _fixstr(p_node->get_name(),"vehicle"); + bv->set_name(n); + p_node->replace_by(bv); + p_node->set_name(n); + bv->add_child(p_node); + bv->set_owner(owner); + p_node->set_owner(owner); + bv->set_transform(s->get_transform()); + s->set_transform(Transform()); + + p_node=bv; + + + } else if (_teststr(name,"wheel")) { + + if (isroot) + return p_node; + + Node *owner = p_node->get_owner(); + Spatial *s = p_node->cast_to<Spatial>(); + VehicleWheel *bv = memnew( VehicleWheel ); + String n = _fixstr(p_node->get_name(),"wheel"); + bv->set_name(n); + p_node->replace_by(bv); + p_node->set_name(n); + bv->add_child(p_node); + bv->set_owner(owner); + p_node->set_owner(owner); + bv->set_transform(s->get_transform()); + s->set_transform(Transform()); + + p_node=bv; + + } else if (_teststr(name,"room") && p_node->cast_to<MeshInstance>()) { + + + if (isroot) + return p_node; + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + PoolVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID); + + + BSP_Tree bsptree(faces); + + Ref<RoomBounds> area = memnew( RoomBounds ); + //area->set_bounds(faces); + //area->set_geometry_hint(faces); + + + Room * room = memnew( Room ); + room->set_name(_fixstr(name,"room")); + room->set_transform(mi->get_transform()); + room->set_room(area); + + p_node->replace_by(room); + memdelete(p_node); + p_node=room; + + } else if (_teststr(name,"room")) { + + if (isroot) + return p_node; + + Spatial *dummy = p_node->cast_to<Spatial>(); + ERR_FAIL_COND_V(!dummy,NULL); + + Room * room = memnew( Room ); + room->set_name(_fixstr(name,"room")); + room->set_transform(dummy->get_transform()); + + p_node->replace_by(room); + memdelete(p_node); + p_node=room; + + //room->compute_room_from_subtree(); + + } else if (_teststr(name,"portal") && p_node->cast_to<MeshInstance>()) { + + if (isroot) + return p_node; + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + PoolVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID); + + ERR_FAIL_COND_V(faces.size()==0,NULL); + //step 1 compute the plane + Set<Vector3> points; + Plane plane; + + Vector3 center; + + for(int i=0;i<faces.size();i++) { + + Face3 f = faces.get(i); + Plane p = f.get_plane(); + plane.normal+=p.normal; + plane.d+=p.d; + + for(int i=0;i<3;i++) { + + Vector3 v = f.vertex[i].snapped(0.01); + if (!points.has(v)) { + points.insert(v); + center+=v; + } + } + } + + plane.normal.normalize(); + plane.d/=faces.size(); + center/=points.size(); + + //step 2, create points + + Transform t; + t.basis.from_z(plane.normal); + t.basis.transpose(); + t.origin=center; + + Vector<Point2> portal_points; + + for(Set<Vector3>::Element *E=points.front();E;E=E->next()) { + + Vector3 local = t.xform_inv(E->get()); + portal_points.push_back(Point2(local.x,local.y)); + } + // step 3 bubbly sort points + + int swaps=0; + + do { + swaps=0; + + for(int i=0;i<portal_points.size()-1;i++) { + + float a = portal_points[i].angle(); + float b = portal_points[i+1].angle(); + + if (a>b) { + SWAP( portal_points[i], portal_points[i+1] ); + swaps++; + } + + } + + } while(swaps); + + + Portal *portal = memnew( Portal ); + + portal->set_shape(portal_points); + portal->set_transform( mi->get_transform() * t); + + p_node->replace_by(portal); + memdelete(p_node); + p_node=portal; + + } else if (p_node->cast_to<MeshInstance>()) { + + //last attempt, maybe collision insde the mesh data + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + Ref<Mesh> mesh = mi->get_mesh(); + if (!mesh.is_null()) { + + if (_teststr(mesh->get_name(),"col")) { + + mesh->set_name( _fixstr(mesh->get_name(),"col") ); + Ref<Shape> shape; + + if (collision_map.has(mesh)) { + shape = collision_map[mesh]; + + } else { + + shape = mesh->create_trimesh_shape(); + if (!shape.is_null()) + collision_map[mesh]=shape; + + + } + + if (!shape.is_null()) { +#if 0 + StaticBody* static_body = memnew( StaticBody ); + ERR_FAIL_COND_V(!static_body,NULL); + static_body->set_name( String(mesh->get_name()) + "_col" ); + shape->set_name(static_body->get_name()); + static_body->add_shape(shape); + + mi->add_child(static_body); + if (mi->get_owner()) + static_body->set_owner( mi->get_owner() ); +#endif + } + + } + + for(int i=0;i<mesh->get_surface_count();i++) { + + Ref<FixedSpatialMaterial> fm = mesh->surface_get_material(i); + if (fm.is_valid()) { + String name = fm->get_name(); + /* if (_teststr(name,"alpha")) { + fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); + name=_fixstr(name,"alpha"); + } + + if (_teststr(name,"vcol")) { + fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY,true); + name=_fixstr(name,"vcol"); + }*/ + fm->set_name(name); + } + } + + } + + } + + + return p_node; +} + + +void ResourceImporterScene::_create_clips(Node *scene, const Array& p_clips,bool p_bake_all) { + + if (!scene->has_node(String("AnimationPlayer"))) + return; + + Node* n = scene->get_node(String("AnimationPlayer")); + ERR_FAIL_COND(!n); + AnimationPlayer *anim = n->cast_to<AnimationPlayer>(); + ERR_FAIL_COND(!anim); + + if (!anim->has_animation("default")) + return; + + + Ref<Animation> default_anim = anim->get_animation("default"); + + for(int i=0;i<p_clips.size();i+=4) { + + String name = p_clips[i]; + float from=p_clips[i+1]; + float to=p_clips[i+2]; + bool loop=p_clips[i+3]; + if (from>=to) + continue; + + Ref<Animation> new_anim = memnew( Animation ); + + for(int j=0;j<default_anim->get_track_count();j++) { + + + List<float> keys; + int kc = default_anim->track_get_key_count(j); + int dtrack=-1; + for(int k=0;k<kc;k++) { + + float kt = default_anim->track_get_key_time(j,k); + if (kt>=from && kt<to) { + + //found a key within range, so create track + if (dtrack==-1) { + new_anim->add_track(default_anim->track_get_type(j)); + dtrack = new_anim->get_track_count()-1; + new_anim->track_set_path(dtrack,default_anim->track_get_path(j)); + + if (kt>(from+0.01) && k>0) { + + if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { + Quat q; + Vector3 p; + Vector3 s; + default_anim->transform_track_interpolate(j,from,&p,&q,&s); + new_anim->transform_track_insert_key(dtrack,0,p,q,s); + } + } + + } + + if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { + Quat q; + Vector3 p; + Vector3 s; + default_anim->transform_track_get_key(j,k,&p,&q,&s); + new_anim->transform_track_insert_key(dtrack,kt-from,p,q,s); + } + + } + + if (dtrack!=-1 && kt>=to) { + + if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { + Quat q; + Vector3 p; + Vector3 s; + default_anim->transform_track_interpolate(j,to,&p,&q,&s); + new_anim->transform_track_insert_key(dtrack,to-from,p,q,s); + } + } + + } + + if (dtrack==-1 && p_bake_all) { + new_anim->add_track(default_anim->track_get_type(j)); + dtrack = new_anim->get_track_count()-1; + new_anim->track_set_path(dtrack,default_anim->track_get_path(j)); + if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { + + + Quat q; + Vector3 p; + Vector3 s; + default_anim->transform_track_interpolate(j,from,&p,&q,&s); + new_anim->transform_track_insert_key(dtrack,0,p,q,s); + default_anim->transform_track_interpolate(j,to,&p,&q,&s); + new_anim->transform_track_insert_key(dtrack,to-from,p,q,s); + } + + } + } + + + new_anim->set_loop(loop); + new_anim->set_length(to-from); + anim->add_animation(name,new_anim); + } + + anim->remove_animation("default"); //remove default (no longer needed) +} + +void ResourceImporterScene::_filter_anim_tracks(Ref<Animation> anim,Set<String> &keep) { + + Ref<Animation> a = anim; + ERR_FAIL_COND(!a.is_valid()); + + print_line("From Anim "+anim->get_name()+":"); + + for(int j=0;j<a->get_track_count();j++) { + + String path = a->track_get_path(j); + + if (!keep.has(path)) { + + print_line("Remove: "+path); + a->remove_track(j); + j--; + } + + } +} + + +void ResourceImporterScene::_filter_tracks(Node *scene, const String& p_text) { + + if (!scene->has_node(String("AnimationPlayer"))) + return; + Node* n = scene->get_node(String("AnimationPlayer")); + ERR_FAIL_COND(!n); + AnimationPlayer *anim = n->cast_to<AnimationPlayer>(); + ERR_FAIL_COND(!anim); + + Vector<String> strings = p_text.split("\n"); + for(int i=0;i<strings.size();i++) { + + strings[i]=strings[i].strip_edges(); + } + + List<StringName> anim_names; + anim->get_animation_list(&anim_names); + for(List<StringName>::Element *E=anim_names.front();E;E=E->next()) { + + String name = E->get(); + bool valid_for_this=false; + bool valid=false; + + Set<String> keep; + Set<String> keep_local; + + + for(int i=0;i<strings.size();i++) { + + + if (strings[i].begins_with("@")) { + + valid_for_this=false; + for(Set<String>::Element *F=keep_local.front();F;F=F->next()) { + keep.insert(F->get()); + } + keep_local.clear(); + + Vector<String> filters=strings[i].substr(1,strings[i].length()).split(","); + for(int j=0;j<filters.size();j++) { + + String fname = filters[j].strip_edges(); + if (fname=="") + continue; + int fc = fname[0]; + bool plus; + if (fc=='+') + plus=true; + else if (fc=='-') + plus=false; + else + continue; + + String filter=fname.substr(1,fname.length()).strip_edges(); + + if (!name.matchn(filter)) + continue; + valid_for_this=plus; + } + + if (valid_for_this) + valid=true; + + } else if (valid_for_this) { + + Ref<Animation> a = anim->get_animation(name); + if (!a.is_valid()) + continue; + + for(int j=0;j<a->get_track_count();j++) { + + String path = a->track_get_path(j); + + String tname = strings[i]; + if (tname=="") + continue; + int fc = tname[0]; + bool plus; + if (fc=='+') + plus=true; + else if (fc=='-') + plus=false; + else + continue; + + String filter=tname.substr(1,tname.length()).strip_edges(); + + if (!path.matchn(filter)) + continue; + + if (plus) + keep_local.insert(path); + else if (!keep.has(path)) { + keep_local.erase(path); + } + } + + } + + } + + if (valid) { + for(Set<String>::Element *F=keep_local.front();F;F=F->next()) { + keep.insert(F->get()); + } + _filter_anim_tracks(anim->get_animation(name),keep); + } else { + + } + + } + + + +} + +void ResourceImporterScene::_optimize_animations(Node *scene, float p_max_lin_error,float p_max_ang_error,float p_max_angle) { + + if (!scene->has_node(String("AnimationPlayer"))) + return; + Node* n = scene->get_node(String("AnimationPlayer")); + ERR_FAIL_COND(!n); + AnimationPlayer *anim = n->cast_to<AnimationPlayer>(); + ERR_FAIL_COND(!anim); + + + List<StringName> anim_names; + anim->get_animation_list(&anim_names); + for(List<StringName>::Element *E=anim_names.front();E;E=E->next()) { + + Ref<Animation> a = anim->get_animation(E->get()); + a->optimize(p_max_lin_error,p_max_ang_error,Math::deg2rad(p_max_angle)); + } +} + + +static String _make_extname(const String& p_str) { + + String ext_name=p_str.replace(".","_"); + ext_name=ext_name.replace(":","_"); + ext_name=ext_name.replace("\"","_"); + ext_name=ext_name.replace("<","_"); + ext_name=ext_name.replace(">","_"); + ext_name=ext_name.replace("/","_"); + ext_name=ext_name.replace("|","_"); + ext_name=ext_name.replace("\\","_"); + ext_name=ext_name.replace("?","_"); + ext_name=ext_name.replace("*","_"); + + return ext_name; +} + +void ResourceImporterScene::_make_external_resources(Node* p_node,const String& p_base_path, bool p_make_materials, bool p_make_meshes, Map<Ref<Material>,Ref<Material> >& p_materials, Map<Ref<Mesh>,Ref<Mesh> >& p_meshes) { + + List<PropertyInfo> pi; + + p_node->get_property_list(&pi); + + for (List<PropertyInfo>::Element *E=pi.front();E;E=E->next()) { + + if (E->get().type==Variant::OBJECT) { + + Ref<Material> mat = p_node->get(E->get().name); + if (p_make_materials && mat.is_valid() && mat->get_name()!="") { + + + if (!p_materials.has(mat)) { + + String ext_name = p_base_path+"."+_make_extname(mat->get_name())+".mtl"; + if (FileAccess::exists(ext_name)) { + //if exists, use it + Ref<Material> existing = ResourceLoader::load(ext_name); + p_materials[mat]=existing; + } else { + + ResourceSaver::save(ext_name,mat,ResourceSaver::FLAG_CHANGE_PATH); + p_materials[mat]=mat; + } + } + + if (p_materials[mat]!=mat) { + + p_node->set(E->get().name,p_materials[mat]); + } + } else { + + Ref<Mesh> mesh = p_node->get(E->get().name); + + if (mesh.is_valid()) { + + bool mesh_just_added=false; + + if (p_make_meshes) { + + if (!p_meshes.has(mesh)) { + + String ext_name = p_base_path+"."+_make_extname(mesh->get_name())+".msh"; + if (FileAccess::exists(ext_name)) { + //if exists, use it + Ref<Mesh> existing = ResourceLoader::load(ext_name); + p_meshes[mesh]=existing; + } else { + + ResourceSaver::save(ext_name,mesh,ResourceSaver::FLAG_CHANGE_PATH); + p_meshes[mesh]=mesh; + mesh_just_added=true; + } + + + } + } + + + if (p_make_materials){ + + if (mesh_just_added || !p_meshes.has(mesh)) { + + + for(int i=0;i<mesh->get_surface_count();i++) { + mat=mesh->surface_get_material(i); + if (!mat.is_valid() || mat->get_name()=="") + continue; + + if (!p_materials.has(mat)) { + + String ext_name = p_base_path+"."+_make_extname(mat->get_name())+".mtl"; + if (FileAccess::exists(ext_name)) { + //if exists, use it + Ref<Material> existing = ResourceLoader::load(ext_name); + p_materials[mat]=existing; + } else { + + ResourceSaver::save(ext_name,mat,ResourceSaver::FLAG_CHANGE_PATH); + p_materials[mat]=mat; + } + } + + if (p_materials[mat]!=mat) { + + mesh->surface_set_material(i,p_materials[mat]); + } + + } + + if(!p_make_meshes) { + p_meshes[mesh]=Ref<Mesh>(); //save it anyway, so it won't be checked again + } + } + } + } + } + } + } + + for(int i=0;i<p_node->get_child_count();i++) { + + _make_external_resources(p_node->get_child(i),p_base_path,p_make_materials,p_make_meshes,p_materials,p_meshes); + } +} + + +void ResourceImporterScene::get_import_options(List<ImportOption> *r_options,int p_preset) const { + + + r_options->push_back(ImportOption(PropertyInfo(Variant::STRING,"nodes/root_type",PROPERTY_HINT_TYPE_STRING,"Node"),"Spatial")); + r_options->push_back(ImportOption(PropertyInfo(Variant::STRING,"nodes/root_name"),"Scene Root")); + + List<String> script_extentions; + ResourceLoader::get_recognized_extensions_for_type("Script",&script_extentions); + + String script_ext_hint; + + for(List<String>::Element *E=script_extentions.front();E;E=E->next()) { + if (script_ext_hint!="") + script_ext_hint+=","; + script_ext_hint+="*."+E->get(); + } + + r_options->push_back(ImportOption(PropertyInfo(Variant::STRING,"nodes/custom_script",PROPERTY_HINT_FILE,script_ext_hint),"")); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"materials/location",PROPERTY_HINT_ENUM,"Node,Mesh"),0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"materials/storage",PROPERTY_HINT_ENUM,"Bult-In,Files"),0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"geometry/compress"),true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"geometry/ensure_tangents"),true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"geometry/storage",PROPERTY_HINT_ENUM,"Built-In,Files"),0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"animation/import",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED),true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::REAL,"animation/fps",PROPERTY_HINT_RANGE,"1,120,1"),15)); + r_options->push_back(ImportOption(PropertyInfo(Variant::STRING,"animation/filter_script",PROPERTY_HINT_MULTILINE_TEXT),"")); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"animation/optimizer/enabled",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED),true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::REAL,"animation/optimizer/max_linear_error"),0.05)); + r_options->push_back(ImportOption(PropertyInfo(Variant::REAL,"animation/optimizer/max_angular_error"),0.01)); + r_options->push_back(ImportOption(PropertyInfo(Variant::REAL,"animation/optimizer/max_angle"),22)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"animation/optimizer/remove_unused_tracks"),true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"animation/clips/amount",PROPERTY_HINT_RANGE,"0,256,1",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED),0)); + for(int i=0;i<256;i++) { + r_options->push_back(ImportOption(PropertyInfo(Variant::STRING,"animation/clip_"+itos(i+1)+"/name"),"")); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"animation/clip_"+itos(i+1)+"/start_frame"),0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"animation/clip_"+itos(i+1)+"/end_frame"),0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"animation/clip_"+itos(i+1)+"/loops"),false)); + } +} + +Error ResourceImporterScene::import(const String& p_source_file, const String& p_save_path, const Map<StringName,Variant>& p_options, List<String>* r_platform_variants, List<String> *r_gen_files) { + + String src_path=p_source_file; + + Ref<EditorSceneImporter> importer; + String ext=src_path.get_extension().to_lower(); + + + EditorProgress progress("import",TTR("Import Scene"),104); + progress.step(TTR("Importing Scene.."),0); + + for(Set< Ref<EditorSceneImporter> >::Element *E=importers.front();E;E=E->next()) { + + List<String> extensions; + E->get()->get_extensions(&extensions); + + for(List<String>::Element *F=extensions.front();F;F=F->next()) { + + if (F->get().to_lower()==ext) { + + importer = E->get(); + break; + } + } + + if (importer.is_valid()) + break; + } + + ERR_FAIL_COND_V(!importer.is_valid(),ERR_FILE_UNRECOGNIZED); + + float fps=p_options["animation/fps"]; + + + + int import_flags=EditorSceneImporter::IMPORT_ANIMATION_DETECT_LOOP; + if (!bool(p_options["animation/optimizer/remove_unused_tracks"])) + import_flags|=EditorSceneImporter::IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS; + + if (bool(p_options["animation/import"])) + import_flags|=EditorSceneImporter::IMPORT_ANIMATION; + + if (bool(p_options["geometry/ensure_tangents"])) + import_flags|=EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS; + + if (int(p_options["materials/location"])==0) + import_flags|=EditorSceneImporter::IMPORT_MATERIALS_IN_INSTANCES; + + + Error err=OK; + List<String> missing_deps; // for now, not much will be done with this + Node *scene = importer->import_scene(src_path,import_flags,fps,&missing_deps,&err); + if (!scene || err!=OK) { + return err; + } + + String root_type = p_options["nodes/root_type"]; + + if (scene->get_class()!=root_type) { + Object *base = ClassDB::instance(root_type); + Node *base_node = NULL; + if (base) + base_node=base->cast_to<Node>(); + + if (base_node) { + + scene->replace_by(base_node); + memdelete(scene); + scene=base_node; + } + } + + scene->set_name(p_options["nodes/root_name"]); + + + err=OK; + + String animation_filter = String(p_options["animation/filter_script"]).strip_edges(); + + bool use_optimizer = p_options["animation/optimizer/enabled"]; + float anim_optimizer_linerr=p_options["animation/optimizer/max_linear_error"]; + float anim_optimizer_angerr=p_options["animation/optimizer/max_angular_error"]; + float anim_optimizer_maxang=p_options["animation/optimizer/max_angle"]; + + Map<Ref<Mesh>,Ref<Shape> > collision_map; + + scene=_fix_node(scene,scene,collision_map); + + if (use_optimizer) { + _optimize_animations(scene,anim_optimizer_linerr,anim_optimizer_angerr,anim_optimizer_maxang); + } + + Array animation_clips; + { + + + int clip_count = p_options["animation/clips/amount"]; + + for(int i=0;i<clip_count;i++) { + String name = p_options["animation/clip_"+itos(i+1)+"/name"]; + int from_frame = p_options["animation/clip_"+itos(i+1)+"/start_frame"]; + int end_frame = p_options["animation/clip_"+itos(i+1)+"/end_frame"]; + bool loop = p_options["animation/clip_"+itos(i+1)+"/loops"]; + + animation_clips.push_back(name); + animation_clips.push_back(from_frame/fps); + animation_clips.push_back(end_frame/fps); + animation_clips.push_back(loop); + } + + } + if (animation_clips.size()) { + _create_clips(scene,animation_clips,!bool(p_options["animation/optimizer/remove_unused_tracks"])); + } + + if (animation_filter!="") { + _filter_tracks(scene,animation_filter); + } + + + bool external_materials = p_options["materials/storage"]; + bool external_meshes = p_options["geometry/storage"]; + + if (external_materials || external_meshes) { + Map<Ref<Material>, Ref<Material> > mat_map; + Map<Ref<Mesh>, Ref<Mesh> > mesh_map; + _make_external_resources(scene,p_source_file.get_basename(),external_materials,external_meshes,mat_map,mesh_map); + } + + progress.step(TTR("Running Custom Script.."),2); + + String post_import_script_path = p_options["nodes/custom_script"]; + Ref<EditorScenePostImport> post_import_script; + + if (post_import_script_path!="") { + post_import_script_path = post_import_script_path; // FIXME: is there a good reason for this? + Ref<Script> scr = ResourceLoader::load(post_import_script_path); + if (!scr.is_valid()) { + EditorNode::add_io_error(TTR("Couldn't load post-import script:")+" "+post_import_script_path); + } else { + + post_import_script = Ref<EditorScenePostImport>( memnew( EditorScenePostImport ) ); + post_import_script->set_script(scr.get_ref_ptr()); + if (!post_import_script->get_script_instance()) { + EditorNode::add_io_error(TTR("Invalid/broken script for post-import (check console):")+" "+post_import_script_path); + post_import_script.unref(); + return ERR_CANT_CREATE; + } + } + } + + + if (post_import_script.is_valid()) { + scene = post_import_script->post_import(scene); + if (!scene) { + EditorNode::add_io_error(TTR("Error running post-import script:")+" "+post_import_script_path); + return err; + } + + + } + + progress.step(TTR("Saving.."),104); + + Ref<PackedScene> packer = memnew( PackedScene ); + packer->pack(scene); + print_line("SAVING TO: "+p_save_path+".scn"); + err = ResourceSaver::save(p_save_path+".scn",packer); //do not take over, let the changed files reload themselves + + memdelete(scene); + + EditorNode::get_singleton()->reload_scene(p_source_file); + + return OK; +} + +ResourceImporterScene *ResourceImporterScene::singleton=NULL; + +ResourceImporterScene::ResourceImporterScene() +{ + singleton=this; +} diff --git a/tools/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index cfa44b160a..cfa44b160a 100644 --- a/tools/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp new file mode 100644 index 0000000000..43c7ff79c6 --- /dev/null +++ b/editor/import/resource_importer_texture.cpp @@ -0,0 +1,393 @@ +#include "resource_importer_texture.h" +#include "io/image_loader.h" +#include "scene/resources/texture.h" +#include "editor/editor_file_system.h" +#include "io/config_file.h" + + +void ResourceImporterTexture::_texture_reimport_srgb(const Ref<StreamTexture>& p_tex) { + + singleton->mutex->lock(); + StringName path = p_tex->get_path(); + + if (!singleton->make_flags.has(path)) { + singleton->make_flags[path]=0; + } + + singleton->make_flags[path]|=MAKE_SRGB_FLAG; + + print_line("requesting srgb for "+String(path)); + + singleton->mutex->unlock(); + +} + + + +void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture>& p_tex) { + + + singleton->mutex->lock(); + StringName path = p_tex->get_path(); + + if (!singleton->make_flags.has(path)) { + singleton->make_flags[path]=0; + } + + singleton->make_flags[path]|=MAKE_3D_FLAG; + + print_line("requesting 3d for "+String(path)); + + singleton->mutex->unlock(); + + +} + +void ResourceImporterTexture::update_imports() { + + if (EditorFileSystem::get_singleton()->is_scanning() || EditorFileSystem::get_singleton()->is_importing()) { + return; // do nothing for noe + } + mutex->lock(); + + if (make_flags.empty()) { + mutex->unlock(); + return; + } + + Vector<String> to_reimport; + for (Map<StringName,int>::Element *E=make_flags.front();E;E=E->next()) { + + print_line("checking for reimport "+String(E->key())); + + + Ref<ConfigFile> cf; + cf.instance(); + String src_path = String(E->key())+".import"; + + Error err = cf->load(src_path); + ERR_CONTINUE(err!=OK); + + bool changed=false; + if (E->get()&MAKE_SRGB_FLAG && int(cf->get_value("params","flags/srgb"))==2) { + cf->set_value("params","flags/srgb",1); + changed=true; + } + + if (E->get()&MAKE_3D_FLAG && bool(cf->get_value("params","detect_3d"))) { + cf->set_value("params","detect_3d",false); + cf->set_value("params","compress/mode",2); + cf->set_value("params","flags/repeat",true); + cf->set_value("params","flags/filter",true); + cf->set_value("params","flags/mipmaps",true); + changed=true; + } + + if (changed) { + cf->save(src_path); + to_reimport.push_back(E->key()); + } + + } + + make_flags.clear(); + + mutex->unlock(); + + if (to_reimport.size()) { + EditorFileSystem::get_singleton()->reimport_files(to_reimport); + } + +} + + + +String ResourceImporterTexture::get_importer_name() const { + + return "texture"; +} + +String ResourceImporterTexture::get_visible_name() const{ + + return "Texture"; +} +void ResourceImporterTexture::get_recognized_extensions(List<String> *p_extensions) const{ + + ImageLoader::get_recognized_extensions(p_extensions); +} +String ResourceImporterTexture::get_save_extension() const { + return "stex"; +} + +String ResourceImporterTexture::get_resource_type() const{ + + return "StreamTexture"; +} + +bool ResourceImporterTexture::get_option_visibility(const String& p_option,const Map<StringName,Variant>& p_options) const { + + if (p_option=="compress/lossy_quality" && int(p_options["compress/mode"])!=COMPRESS_LOSSY) + return false; + + return true; +} + +int ResourceImporterTexture::get_preset_count() const { + return 4; +} +String ResourceImporterTexture::get_preset_name(int p_idx) const { + + static const char* preset_names[]={ + "2D, Detect 3D", + "2D", + "2D Pixel", + "3D" + }; + + return preset_names[p_idx]; +} + + +void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,int p_preset) const { + + + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"compress/mode",PROPERTY_HINT_ENUM,"Lossless,Lossy,Video RAM,Uncompressed",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED),p_preset==PRESET_3D?2:0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::REAL,"compress/lossy_quality",PROPERTY_HINT_RANGE,"0,1,0.01"),0.7)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"flags/repeat",PROPERTY_HINT_ENUM,"Disabled,Enabled,Mirrored"),p_preset==PRESET_3D?1:0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"flags/filter"),p_preset==PRESET_2D_PIXEL?false:true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"flags/mipmaps"),p_preset==PRESET_3D?true:false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"flags/anisotropic"),false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"flags/srgb",PROPERTY_HINT_ENUM,"Disable,Enable,Detect"),2)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"process/fix_alpha_border"),p_preset!=PRESET_3D?true:false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"process/premult_alpha"),true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"stream"),false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"size_limit",PROPERTY_HINT_RANGE,"0,4096,1"),0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"detect_3d"),p_preset==PRESET_DETECT)); + +} + + +void ResourceImporterTexture::_save_stex(const Image& p_image, const String& p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable, bool p_detect_3d, bool p_detect_srgb) { + + + FileAccess *f = FileAccess::open(p_to_path,FileAccess::WRITE); + f->store_8('G'); + f->store_8('D'); + f->store_8('S'); + f->store_8('T'); //godot streamable texture + + f->store_32(p_image.get_width()); + f->store_32(p_image.get_height()); + f->store_32(p_texture_flags); + + uint32_t format=0; + + if (p_streamable) + format|=StreamTexture::FORMAT_BIT_STREAM; + if (p_mipmaps || p_compress_mode==COMPRESS_VIDEO_RAM) //VRAM always uses mipmaps + format|=StreamTexture::FORMAT_BIT_HAS_MIPMAPS; //mipmaps bit + if (p_detect_3d) + format|=StreamTexture::FORMAT_BIT_DETECT_3D; + if (p_detect_srgb) + format|=StreamTexture::FORMAT_BIT_DETECT_SRGB; + + + switch (p_compress_mode) { + case COMPRESS_LOSSLESS: { + + Image image = p_image; + if (p_mipmaps) { + image.generate_mipmaps(); + } else { + image.clear_mipmaps(); + } + + int mmc = image.get_mipmap_count() + 1; + + format|=StreamTexture::FORMAT_BIT_LOSSLESS; + f->store_32(format); + f->store_32(mmc); + + for(int i=0;i<mmc;i++) { + + if (i>0) { + image.shrink_x2(); + } + + PoolVector<uint8_t> data = Image::lossless_packer(image); + int data_len = data.size(); + f->store_32(data_len); + + PoolVector<uint8_t>::Read r= data.read(); + f->store_buffer(r.ptr(),data_len); + + } + + + } break; + case COMPRESS_LOSSY: { + Image image = p_image; + if (p_mipmaps) { + image.generate_mipmaps(); + } else { + image.clear_mipmaps(); + } + + int mmc = image.get_mipmap_count() + 1; + + format|=StreamTexture::FORMAT_BIT_LOSSY; + f->store_32(format); + f->store_32(mmc); + + for(int i=0;i<mmc;i++) { + + if (i>0) { + image.shrink_x2(); + } + + PoolVector<uint8_t> data = Image::lossy_packer(image,p_lossy_quality); + int data_len = data.size(); + f->store_32(data_len); + + PoolVector<uint8_t>::Read r = data.read(); + f->store_buffer(r.ptr(),data_len); + + } + } break; + case COMPRESS_VIDEO_RAM: { + + Image image = p_image; + image.generate_mipmaps(); + image.compress(p_vram_compression); + + format |= image.get_format(); + + f->store_32(format); + + PoolVector<uint8_t> data=image.get_data(); + int dl = data.size(); + PoolVector<uint8_t>::Read r = data.read(); + f->store_buffer(r.ptr(),dl); + + } break; + case COMPRESS_UNCOMPRESSED: { + + Image image = p_image; + if (p_mipmaps) { + image.generate_mipmaps(); + } else { + image.clear_mipmaps(); + } + + format |= image.get_format(); + f->store_32(format); + + PoolVector<uint8_t> data=image.get_data(); + int dl = data.size(); + PoolVector<uint8_t>::Read r = data.read(); + + f->store_buffer(r.ptr(),dl); + + } break; + } + + memdelete(f); +} + +Error ResourceImporterTexture::import(const String& p_source_file, const String& p_save_path, const Map<StringName,Variant>& p_options, List<String>* r_platform_variants, List<String> *r_gen_files) { + + int compress_mode = p_options["compress/mode"]; + float lossy= p_options["compress/lossy_quality"]; + int repeat= p_options["flags/repeat"]; + bool filter= p_options["flags/filter"]; + bool mipmaps= p_options["flags/mipmaps"]; + bool anisotropic= p_options["flags/anisotropic"]; + int srgb= p_options["flags/srgb"]; + bool fix_alpha_border= p_options["process/fix_alpha_border"]; + bool premult_alpha= p_options["process/premult_alpha"]; + bool stream = p_options["stream"]; + int size_limit = p_options["size_limit"]; + + + Image image; + Error err = ImageLoader::load_image(p_source_file,&image); + if (err!=OK) + return err; + + + int tex_flags=0; + if (repeat>0) + tex_flags|=Texture::FLAG_REPEAT; + if (repeat==2) + tex_flags|=Texture::FLAG_MIRRORED_REPEAT; + if (filter) + tex_flags|=Texture::FLAG_FILTER; + if (mipmaps || compress_mode==COMPRESS_VIDEO_RAM) + tex_flags|=Texture::FLAG_MIPMAPS; + if (anisotropic) + tex_flags|=Texture::FLAG_ANISOTROPIC_FILTER; + if (srgb==1) + tex_flags|=Texture::FLAG_CONVERT_TO_LINEAR; + + if (size_limit >0 && (image.get_width()>size_limit || image.get_height()>size_limit )) { + //limit size + if (image.get_width() >= image.get_height()) { + int new_width = size_limit; + int new_height = image.get_height() * new_width / image.get_width(); + + image.resize(new_width,new_height,Image::INTERPOLATE_CUBIC); + } else { + + int new_height = size_limit; + int new_width = image.get_width() * new_height / image.get_height(); + + image.resize(new_width,new_height,Image::INTERPOLATE_CUBIC); + } + } + + if (fix_alpha_border) { + image.fix_alpha_edges(); + } + + if (premult_alpha) { + image.premultiply_alpha(); + } + + bool detect_3d = p_options["detect_3d"]; + bool detect_srgb = srgb==2; + + if (compress_mode==COMPRESS_VIDEO_RAM) { + //must import in all formats + //Android, GLES 2.x + _save_stex(image,p_save_path+".etc.stex",compress_mode,lossy,Image::COMPRESS_ETC,mipmaps,tex_flags,stream,detect_3d,detect_srgb); + r_platform_variants->push_back("etc"); + //_save_stex(image,p_save_path+".etc2.stex",compress_mode,lossy,Image::COMPRESS_ETC2,mipmaps,tex_flags,stream); + //r_platform_variants->push_back("etc2"); + _save_stex(image,p_save_path+".s3tc.stex",compress_mode,lossy,Image::COMPRESS_S3TC,mipmaps,tex_flags,stream,detect_3d,detect_srgb); + r_platform_variants->push_back("s3tc"); + + } else { + //import normally + _save_stex(image,p_save_path+".stex",compress_mode,lossy,Image::COMPRESS_16BIT /*this is ignored */,mipmaps,tex_flags,stream,detect_3d,detect_srgb); + } + + return OK; +} + +ResourceImporterTexture *ResourceImporterTexture::singleton=NULL; + +ResourceImporterTexture::ResourceImporterTexture() +{ + + singleton=this; + StreamTexture::request_3d_callback=_texture_reimport_3d; + StreamTexture::request_srgb_callback=_texture_reimport_srgb; + mutex = Mutex::create(); +} + +ResourceImporterTexture::~ResourceImporterTexture() +{ + + memdelete(mutex); +} + diff --git a/tools/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index 4c795e132c..4c795e132c 100644 --- a/tools/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h diff --git a/tools/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index ee53b740ca..ee53b740ca 100644 --- a/tools/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp diff --git a/tools/editor/import/resource_importer_wav.h b/editor/import/resource_importer_wav.h index 9f1bd57da7..9f1bd57da7 100644 --- a/tools/editor/import/resource_importer_wav.h +++ b/editor/import/resource_importer_wav.h diff --git a/tools/editor/import_dock.cpp b/editor/import_dock.cpp index bf61ca4df0..bf61ca4df0 100644 --- a/tools/editor/import_dock.cpp +++ b/editor/import_dock.cpp diff --git a/tools/editor/import_dock.h b/editor/import_dock.h index bddf5480b8..bddf5480b8 100644 --- a/tools/editor/import_dock.h +++ b/editor/import_dock.h diff --git a/tools/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index 253f9bcc01..253f9bcc01 100644 --- a/tools/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp diff --git a/tools/editor/inspector_dock.h b/editor/inspector_dock.h index be6ed5fa87..be6ed5fa87 100644 --- a/tools/editor/inspector_dock.h +++ b/editor/inspector_dock.h diff --git a/tools/editor/io_plugins/SCsub b/editor/io_plugins/SCsub index f1fa50148f..f1fa50148f 100644 --- a/tools/editor/io_plugins/SCsub +++ b/editor/io_plugins/SCsub diff --git a/tools/editor/io_plugins/editor_atlas.cpp b/editor/io_plugins/editor_atlas.cpp index c5f1ee73cf..c5f1ee73cf 100644 --- a/tools/editor/io_plugins/editor_atlas.cpp +++ b/editor/io_plugins/editor_atlas.cpp diff --git a/tools/editor/io_plugins/editor_atlas.h b/editor/io_plugins/editor_atlas.h index e0cf76576e..e0cf76576e 100644 --- a/tools/editor/io_plugins/editor_atlas.h +++ b/editor/io_plugins/editor_atlas.h diff --git a/editor/io_plugins/editor_bitmask_import_plugin.cpp b/editor/io_plugins/editor_bitmask_import_plugin.cpp new file mode 100644 index 0000000000..7282cbe4e7 --- /dev/null +++ b/editor/io_plugins/editor_bitmask_import_plugin.cpp @@ -0,0 +1,387 @@ +/*************************************************************************/ +/* editor_bitmask_import_plugin.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 "editor_bitmask_import_plugin.h" +#if 0 +#include "io/image_loader.h" +#include "editor/editor_file_dialog.h" +#include "editor/editor_dir_dialog.h" +#include "editor/editor_node.h" +#include "editor/property_editor.h" +#include "io/resource_saver.h" +#include "os/file_access.h" +#include "io/marshalls.h" +#include "editor/editor_settings.h" + +class _EditorBitMaskImportOptions : public Object { + + GDCLASS(_EditorBitMaskImportOptions, Object); +public: + + bool _set(const StringName& p_name, const Variant& p_value) { + + return false; + } + + bool _get(const StringName& p_name, Variant &r_ret) const{ + + return false; + } + + void _get_property_list(List<PropertyInfo> *p_list) const{ + + } + + static void _bind_methods() { + + ADD_SIGNAL(MethodInfo("changed")); + } + + + _EditorBitMaskImportOptions() { + + } + +}; + +class EditorBitMaskImportDialog : public ConfirmationDialog { + + GDCLASS(EditorBitMaskImportDialog, ConfirmationDialog); + + EditorBitMaskImportPlugin *plugin; + + LineEdit *import_path; + LineEdit *save_path; + EditorFileDialog *file_select; + EditorDirDialog *save_select; + ConfirmationDialog *error_dialog; + PropertyEditor *option_editor; + +public: + + void _choose_files(const Vector<String>& p_path) { + + String files; + for (int i = 0; i<p_path.size(); i++) { + + if (i>0) + files += ","; + files += p_path[i]; + } + + import_path->set_text(files); + + } + void _choose_save_dir(const String& p_path) { + + save_path->set_text(p_path); + } + + void _browse() { + + file_select->popup_centered_ratio(); + } + + void _browse_target() { + + save_select->popup_centered_ratio(); + + } + + + void popup_import(const String& p_path) { + + popup_centered(Size2(400, 100)*EDSCALE); + if (p_path != "") { + + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); + ERR_FAIL_COND(!rimd.is_valid()); + + save_path->set_text(p_path.get_base_dir()); + + String src = ""; + for (int i = 0; i<rimd->get_source_count(); i++) { + if (i>0) + src += ","; + src += EditorImportPlugin::expand_source_path(rimd->get_source_path(i)); + } + import_path->set_text(src); + } + } + + + void _import() { + + Vector<String> bitmasks = import_path->get_text().split(","); + + if (bitmasks.size() == 0) { + error_dialog->set_text(TTR("No bit masks to import!")); + error_dialog->popup_centered(Size2(200, 100)*EDSCALE); + } + + if (save_path->get_text().strip_edges() == "") { + error_dialog->set_text(TTR("Target path is empty.")); + error_dialog->popup_centered_minsize(); + return; + } + + if (!save_path->get_text().begins_with("res://")) { + error_dialog->set_text(TTR("Target path must be a complete resource path.")); + error_dialog->popup_centered_minsize(); + return; + } + + if (!DirAccess::exists(save_path->get_text())) { + error_dialog->set_text(TTR("Target path must exist.")); + error_dialog->popup_centered_minsize(); + return; + } + + for (int i = 0; i<bitmasks.size(); i++) { + + Ref<ResourceImportMetadata> imd = memnew(ResourceImportMetadata); + + imd->add_source(EditorImportPlugin::validate_source_path(bitmasks[i])); + + String dst = save_path->get_text(); + if (dst == "") { + error_dialog->set_text(TTR("Save path is empty!")); + error_dialog->popup_centered(Size2(200, 100)*EDSCALE); + } + + dst = dst.plus_file(bitmasks[i].get_file().get_basename() + ".pbm"); + + plugin->import(dst, imd); + } + + hide(); + + } + + + void _notification(int p_what) { + + } + + static void _bind_methods() { + + + ClassDB::bind_method("_choose_files", &EditorBitMaskImportDialog::_choose_files); + ClassDB::bind_method("_choose_save_dir", &EditorBitMaskImportDialog::_choose_save_dir); + ClassDB::bind_method("_import", &EditorBitMaskImportDialog::_import); + ClassDB::bind_method("_browse", &EditorBitMaskImportDialog::_browse); + ClassDB::bind_method("_browse_target", &EditorBitMaskImportDialog::_browse_target); + //ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); + } + + EditorBitMaskImportDialog(EditorBitMaskImportPlugin *p_plugin) { + + plugin = p_plugin; + + + set_title(TTR("Import BitMasks")); + + VBoxContainer *vbc = memnew(VBoxContainer); + add_child(vbc); + //set_child_rect(vbc); + + + HBoxContainer *hbc = memnew(HBoxContainer); + vbc->add_margin_child(TTR("Source Texture(s):"), hbc); + + import_path = memnew(LineEdit); + import_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(import_path); + + Button * import_choose = memnew(Button); + import_choose->set_text(" .. "); + hbc->add_child(import_choose); + + import_choose->connect("pressed", this, "_browse"); + + hbc = memnew(HBoxContainer); + vbc->add_margin_child(TTR("Target Path:"), hbc); + + save_path = memnew(LineEdit); + save_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(save_path); + + Button * save_choose = memnew(Button); + save_choose->set_text(" .. "); + hbc->add_child(save_choose); + + save_choose->connect("pressed", this, "_browse_target"); + + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + add_child(file_select); + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); + file_select->connect("files_selected", this, "_choose_files"); + + List<String> extensions; + ImageLoader::get_recognized_extensions(&extensions); + file_select->clear_filters(); + for (int i = 0; i<extensions.size(); i++) { + + file_select->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper()); + } + + save_select = memnew(EditorDirDialog); + add_child(save_select); + + //save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); + save_select->connect("dir_selected", this, "_choose_save_dir"); + + get_ok()->connect("pressed", this, "_import"); + get_ok()->set_text(TTR("Import")); + + + error_dialog = memnew(ConfirmationDialog); + add_child(error_dialog); + error_dialog->get_ok()->set_text(TTR("Accept")); + //error_dialog->get_cancel()->hide(); + + set_hide_on_ok(false); + } + + ~EditorBitMaskImportDialog() { + } + +}; + + +String EditorBitMaskImportPlugin::get_name() const { + + return "bitmask"; +} +String EditorBitMaskImportPlugin::get_visible_name() const{ + + return TTR("Bit Mask"); +} +void EditorBitMaskImportPlugin::import_dialog(const String& p_from){ + + dialog->popup_import(p_from); +} +Error EditorBitMaskImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from){ + + ERR_FAIL_COND_V(p_from->get_source_count() != 1, ERR_INVALID_PARAMETER); + + Ref<ResourceImportMetadata> from = p_from; + + String src_path = EditorImportPlugin::expand_source_path(from->get_source_path(0)); + Ref<ImageTexture> it = ResourceLoader::load(src_path); + ERR_FAIL_COND_V(it.is_null(), ERR_CANT_OPEN); + + Ref<BitMap> target = memnew(BitMap); + target->create_from_image_alpha(it.ptr()->get_data()); + + from->set_source_md5(0, FileAccess::get_md5(src_path)); + from->set_editor(get_name()); + target->set_import_metadata(from); + + + Error err = ResourceSaver::save(p_path, target); + + return err; + +} + + +EditorBitMaskImportPlugin* EditorBitMaskImportPlugin::singleton = NULL; + + +void EditorBitMaskImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + Vector<String> files; + + List<String> valid_extensions; + ImageLoader::get_recognized_extensions(&valid_extensions); + for(int i=0;i<p_drop.size();i++) { + + String extension=p_drop[i].get_extension().to_lower(); + + for (List<String>::Element *E=valid_extensions.front();E;E=E->next()) { + + if (E->get()==extension) { + files.push_back(p_drop[i]); + break; + } + } + } + + if (files.size()) { + import_dialog(); + dialog->_choose_files(files); + dialog->_choose_save_dir(p_dest_path); + } +} + +void EditorBitMaskImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { + + if (p_list.size() == 0) + return; + + Vector<String> sources; + for (int i = 0; i<p_list.size(); i++) { + int idx; + EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->find_file(p_list[i], &idx); + if (efsd) { + for (int j = 0; j<efsd->get_source_count(idx); j++) { + String file = expand_source_path(efsd->get_source_file(idx, j)); + if (sources.find(file) == -1) { + sources.push_back(file); + } + + } + } + } + + if (sources.size()) { + + dialog->popup_import(p_list[0]); + dialog->_choose_files(sources); + dialog->_choose_save_dir(p_list[0].get_base_dir()); + } +} + +bool EditorBitMaskImportPlugin::can_reimport_multiple_files() const { + + return true; +} + +EditorBitMaskImportPlugin::EditorBitMaskImportPlugin(EditorNode* p_editor) { + + singleton = this; + dialog = memnew(EditorBitMaskImportDialog(this)); + p_editor->get_gui_base()->add_child(dialog); +} + +EditorBitMaskExportPlugin::EditorBitMaskExportPlugin() { + +} +#endif diff --git a/editor/io_plugins/editor_bitmask_import_plugin.h b/editor/io_plugins/editor_bitmask_import_plugin.h new file mode 100644 index 0000000000..d1618d7843 --- /dev/null +++ b/editor/io_plugins/editor_bitmask_import_plugin.h @@ -0,0 +1,70 @@ +/*************************************************************************/ +/* editor_bitmask_import_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITOR_BITMASK_IMPORT_PLUGIN_H +#define EDITOR_BITMASK_IMPORT_PLUGIN_H +#if 0 +#include "editor/editor_import_export.h" +#include "scene/resources/font.h" + +class EditorNode; +class EditorBitMaskImportDialog; + +class EditorBitMaskImportPlugin : public EditorImportPlugin { + + GDCLASS(EditorBitMaskImportPlugin, EditorImportPlugin); + + EditorBitMaskImportDialog *dialog; +public: + + static EditorBitMaskImportPlugin *singleton; + + virtual String get_name() const; + virtual String get_visible_name() const; + virtual void import_dialog(const String& p_from = ""); + virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); + virtual void reimport_multiple_files(const Vector<String>& p_list); + virtual bool can_reimport_multiple_files() const; + + + EditorBitMaskImportPlugin(EditorNode* p_editor); +}; + +class EditorBitMaskExportPlugin : public EditorExportPlugin { + + GDCLASS(EditorBitMaskExportPlugin, EditorExportPlugin); + + +public: + + EditorBitMaskExportPlugin(); +}; + +#endif +#endif // EDITOR_SAMPLE_IMPORT_PLUGIN_H diff --git a/editor/io_plugins/editor_export_scene.cpp b/editor/io_plugins/editor_export_scene.cpp new file mode 100644 index 0000000000..a593b870f9 --- /dev/null +++ b/editor/io_plugins/editor_export_scene.cpp @@ -0,0 +1,142 @@ +/*************************************************************************/ +/* editor_export_scene.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 "editor_export_scene.h" +#if 0 +#include "io/resource_loader.h" +#include "io/resource_saver.h" +#include "os/dir_access.h" +#include "os/file_access.h" +#include "editor/editor_settings.h" +#include "scene/resources/packed_scene.h" +#include "global_config.h" + +Vector<uint8_t> EditorSceneExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) { + + if (!EditorImportExport::get_singleton()->get_convert_text_scenes()) { + return Vector<uint8_t>(); + } + + + String extension = p_path.get_extension(); + + //step 1 check if scene + + if (extension=="xml" || extension=="xres") { + + String type = ResourceLoader::get_resource_type(p_path); + + if (type!="PackedScene") + return Vector<uint8_t>(); + + } else if (extension!="tscn" && extension!="xscn") { + return Vector<uint8_t>(); + } + + //step 2 check if cached + + uint64_t sd=0; + String smd5; + String gp = GlobalConfig::get_singleton()->globalize_path(p_path); + String md5=gp.md5_text(); + String tmp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/"); + + bool valid=false; + { + //if existing, make sure it's valid + FileAccessRef f = FileAccess::open(tmp_path+"scnexp-"+md5+".txt",FileAccess::READ); + if (f) { + + uint64_t d = f->get_line().strip_edges().to_int64(); + sd = FileAccess::get_modified_time(p_path); + + if (d==sd) { + valid=true; + } else { + String cmd5 = f->get_line().strip_edges(); + smd5 = FileAccess::get_md5(p_path); + if (cmd5==smd5) { + valid=true; + } + } + + + } + } + + if (!valid) { + //cache failed, convert + DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + + String copy = p_path+".convert."+extension; + + // a copy will allow loading the internal resources without conflicting with opened scenes + da->copy(p_path,copy); + + //@todo for tscn use something more efficient + + Ref<PackedScene> copyres = ResourceLoader::load(copy,"PackedScene"); + + da->remove(copy); + + memdelete(da); + + ERR_FAIL_COND_V(!copyres.is_valid(),Vector<uint8_t>()); + + Error err = ResourceSaver::save(tmp_path+"scnexp-"+md5+".scn",copyres); + + copyres=Ref<PackedScene>(); + + ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>()); + + FileAccessRef f = FileAccess::open(tmp_path+"scnexp-"+md5+".txt",FileAccess::WRITE); + + if (sd==0) + sd = FileAccess::get_modified_time(p_path); + if (smd5==String()) + smd5 = FileAccess::get_md5(p_path); + + f->store_line(String::num(sd)); + f->store_line(smd5); + f->store_line(gp); //source path for reference + } + + + Vector<uint8_t> ret = FileAccess::get_file_as_array(tmp_path+"scnexp-"+md5+".scn"); + + p_path+=".converted.scn"; + + return ret; + +} + + +EditorSceneExportPlugin::EditorSceneExportPlugin() +{ +} +#endif diff --git a/editor/io_plugins/editor_export_scene.h b/editor/io_plugins/editor_export_scene.h new file mode 100644 index 0000000000..ac425fbedd --- /dev/null +++ b/editor/io_plugins/editor_export_scene.h @@ -0,0 +1,44 @@ +/*************************************************************************/ +/* editor_export_scene.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITOR_EXPORT_SCENE_H +#define EDITOR_EXPORT_SCENE_H + +#include "editor/editor_export.h" + +#if 0 +class EditorSceneExportPlugin : public EditorExportPlugin { + GDCLASS( EditorSceneExportPlugin, EditorExportPlugin ); +public: + + virtual Vector<uint8_t> custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform); + + EditorSceneExportPlugin(); +}; +#endif +#endif // EDITOR_EXPORT_SCENE_H diff --git a/editor/io_plugins/editor_font_import_plugin.cpp b/editor/io_plugins/editor_font_import_plugin.cpp new file mode 100644 index 0000000000..c792ad717a --- /dev/null +++ b/editor/io_plugins/editor_font_import_plugin.cpp @@ -0,0 +1,1704 @@ +/*************************************************************************/ +/* editor_font_import_plugin.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 "editor_font_import_plugin.h" +#if 0 +#include "scene/gui/dialogs.h" +#include "editor/editor_file_dialog.h" +#include "editor/editor_node.h" +#include "os/file_access.h" +#include "editor_atlas.h" +#include "io/image_loader.h" +#include "io/resource_saver.h" + +#ifdef FREETYPE_ENABLED +#include <ft2build.h> +#include FT_FREETYPE_H +#endif + + +class _EditorFontImportOptions : public Object { + + GDCLASS(_EditorFontImportOptions,Object); +public: + + enum FontMode { + + FONT_BITMAP, + FONT_DISTANCE_FIELD + }; + + enum ColorType { + COLOR_WHITE, + COLOR_CUSTOM, + COLOR_GRADIENT_RANGE, + COLOR_GRADIENT_IMAGE + }; + + + int char_extra_spacing; + int top_extra_spacing; + int bottom_extra_spacing; + int space_extra_spacing; + + enum CharacterSet { + + CHARSET_ASCII, + CHARSET_LATIN, + CHARSET_UNICODE, + CHARSET_CUSTOM, + CHARSET_CUSTOM_LATIN + }; + + + FontMode font_mode; + + CharacterSet character_set; + String custom_file; + + bool shadow; + Vector2 shadow_offset; + int shadow_radius; + Color shadow_color; + float shadow_transition; + + bool shadow2; + Vector2 shadow2_offset; + int shadow2_radius; + Color shadow2_color; + float shadow2_transition; + + ColorType color_type; + Color color; + Color gradient_begin; + Color gradient_end; + bool color_use_monochrome; + String gradient_image; + + bool enable_filter; + bool round_advance; + bool premultiply_alpha; + + + + bool _set(const StringName& p_name, const Variant& p_value) { + + String n = p_name; + if (n=="mode/mode") { + font_mode=FontMode(int(p_value)); + _change_notify(); + } else if (n=="extra_space/char") + char_extra_spacing=p_value; + else if (n=="extra_space/space") + space_extra_spacing=p_value; + else if (n=="extra_space/top") + top_extra_spacing=p_value; + else if (n=="extra_space/bottom") + bottom_extra_spacing=p_value; + + else if (n=="character_set/mode") { + character_set=CharacterSet(int(p_value)); + _change_notify(); + } else if (n=="character_set/custom") + custom_file=p_value; + + else if (n=="shadow/enabled") { + shadow=p_value; + _change_notify(); + }else if (n=="shadow/radius") + shadow_radius=p_value; + else if (n=="shadow/offset") + shadow_offset=p_value; + else if (n=="shadow/color") + shadow_color=p_value; + else if (n=="shadow/transition") + shadow_transition=p_value; + + else if (n=="shadow2/enabled") { + shadow2=p_value; + _change_notify(); + }else if (n=="shadow2/radius") + shadow2_radius=p_value; + else if (n=="shadow2/offset") + shadow2_offset=p_value; + else if (n=="shadow2/color") + shadow2_color=p_value; + else if (n=="shadow2/transition") + shadow2_transition=p_value; + + else if (n=="color/mode") { + color_type=ColorType(int(p_value)); + _change_notify(); + }else if (n=="color/color") + color=p_value; + else if (n=="color/begin") + gradient_begin=p_value; + else if (n=="color/end") + gradient_end=p_value; + else if (n=="color/image") + gradient_image=p_value; + else if (n=="color/monochrome") + color_use_monochrome=p_value; + else if (n=="advanced/round_advance") + round_advance=p_value; + else if (n=="advanced/enable_filter") + enable_filter=p_value; + else if (n=="advanced/premultiply_alpha") + premultiply_alpha=p_value; + else + return false; + + emit_signal("changed"); + + + return true; + + } + + bool _get(const StringName& p_name,Variant &r_ret) const{ + + String n = p_name; + if (n=="mode/mode") + r_ret=font_mode; + else if (n=="extra_space/char") + r_ret=char_extra_spacing; + else if (n=="extra_space/space") + r_ret=space_extra_spacing; + else if (n=="extra_space/top") + r_ret=top_extra_spacing; + else if (n=="extra_space/bottom") + r_ret=bottom_extra_spacing; + + else if (n=="character_set/mode") + r_ret=character_set; + else if (n=="character_set/custom") + r_ret=custom_file; + + else if (n=="shadow/enabled") + r_ret=shadow; + else if (n=="shadow/radius") + r_ret=shadow_radius; + else if (n=="shadow/offset") + r_ret=shadow_offset; + else if (n=="shadow/color") + r_ret=shadow_color; + else if (n=="shadow/transition") + r_ret=shadow_transition; + + else if (n=="shadow2/enabled") + r_ret=shadow2; + else if (n=="shadow2/radius") + r_ret=shadow2_radius; + else if (n=="shadow2/offset") + r_ret=shadow2_offset; + else if (n=="shadow2/color") + r_ret=shadow2_color; + else if (n=="shadow2/transition") + r_ret=shadow2_transition; + + + else if (n=="color/mode") + r_ret=color_type; + else if (n=="color/color") + r_ret=color; + else if (n=="color/begin") + r_ret=gradient_begin; + else if (n=="color/end") + r_ret=gradient_end; + else if (n=="color/image") + r_ret=gradient_image; + else if (n=="color/monochrome") + r_ret=color_use_monochrome; + else if (n=="advanced/round_advance") + r_ret=round_advance; + else if (n=="advanced/enable_filter") + r_ret=enable_filter; + else if (n=="advanced/premultiply_alpha") + r_ret=premultiply_alpha; + else + return false; + + return true; + + } + + void _get_property_list( List<PropertyInfo> *p_list) const{ + + + p_list->push_back(PropertyInfo(Variant::INT,"mode/mode",PROPERTY_HINT_ENUM,"Bitmap,Distance Field")); + + p_list->push_back(PropertyInfo(Variant::INT,"extra_space/char",PROPERTY_HINT_RANGE,"-64,64,1")); + p_list->push_back(PropertyInfo(Variant::INT,"extra_space/space",PROPERTY_HINT_RANGE,"-64,64,1")); + p_list->push_back(PropertyInfo(Variant::INT,"extra_space/top",PROPERTY_HINT_RANGE,"-64,64,1")); + p_list->push_back(PropertyInfo(Variant::INT,"extra_space/bottom",PROPERTY_HINT_RANGE,"-64,64,1")); + p_list->push_back(PropertyInfo(Variant::INT,"character_set/mode",PROPERTY_HINT_ENUM,"Ascii,Latin,Unicode,Custom,Custom&Latin")); + + if (character_set>=CHARSET_CUSTOM) + p_list->push_back(PropertyInfo(Variant::STRING,"character_set/custom",PROPERTY_HINT_GLOBAL_FILE)); + + int usage = PROPERTY_USAGE_DEFAULT; + + if (font_mode==FONT_DISTANCE_FIELD) { + usage = PROPERTY_USAGE_NOEDITOR; + } + + { + + p_list->push_back(PropertyInfo(Variant::BOOL,"shadow/enabled",PROPERTY_HINT_NONE,"",usage)); + if (shadow) { + p_list->push_back(PropertyInfo(Variant::INT,"shadow/radius",PROPERTY_HINT_RANGE,"-64,64,1",usage)); + p_list->push_back(PropertyInfo(Variant::VECTOR2,"shadow/offset",PROPERTY_HINT_NONE,"",usage)); + p_list->push_back(PropertyInfo(Variant::COLOR,"shadow/color",PROPERTY_HINT_NONE,"",usage)); + p_list->push_back(PropertyInfo(Variant::REAL,"shadow/transition",PROPERTY_HINT_EXP_EASING,"",usage)); + } + + p_list->push_back(PropertyInfo(Variant::BOOL,"shadow2/enabled",PROPERTY_HINT_NONE,"",usage)); + if (shadow2) { + p_list->push_back(PropertyInfo(Variant::INT,"shadow2/radius",PROPERTY_HINT_RANGE,"-64,64,1",usage)); + p_list->push_back(PropertyInfo(Variant::VECTOR2,"shadow2/offset",PROPERTY_HINT_NONE,"",usage)); + p_list->push_back(PropertyInfo(Variant::COLOR,"shadow2/color",PROPERTY_HINT_NONE,"",usage)); + p_list->push_back(PropertyInfo(Variant::REAL,"shadow2/transition",PROPERTY_HINT_EXP_EASING,"",usage)); + } + + p_list->push_back(PropertyInfo(Variant::INT,"color/mode",PROPERTY_HINT_ENUM,"White,Color,Gradient,Gradient Image",usage)); + if (color_type==COLOR_CUSTOM) { + p_list->push_back(PropertyInfo(Variant::COLOR,"color/color",PROPERTY_HINT_NONE,"",usage)); + + } + if (color_type==COLOR_GRADIENT_RANGE) { + p_list->push_back(PropertyInfo(Variant::COLOR,"color/begin",PROPERTY_HINT_NONE,"",usage)); + p_list->push_back(PropertyInfo(Variant::COLOR,"color/end",PROPERTY_HINT_NONE,"",usage)); + } + if (color_type==COLOR_GRADIENT_IMAGE) { + p_list->push_back(PropertyInfo(Variant::STRING,"color/image",PROPERTY_HINT_GLOBAL_FILE,"",usage)); + } + p_list->push_back(PropertyInfo(Variant::BOOL,"color/monochrome",PROPERTY_HINT_NONE,"",usage)); + } + + p_list->push_back(PropertyInfo(Variant::BOOL,"advanced/round_advance")); + p_list->push_back(PropertyInfo(Variant::BOOL,"advanced/enable_filter")); + p_list->push_back(PropertyInfo(Variant::BOOL,"advanced/premultiply_alpha")); + + } + + + static void _bind_methods() { + + + ADD_SIGNAL( MethodInfo("changed")); + } + + + void reset() { + + char_extra_spacing=0; + top_extra_spacing=0; + bottom_extra_spacing=0; + space_extra_spacing=0; + + character_set=CHARSET_LATIN; + + shadow=false; + shadow_radius=2; + shadow_color=Color(0,0,0,0.3); + shadow_transition=1.0; + + shadow2=false; + shadow2_radius=2; + shadow2_color=Color(0,0,0,0.3); + shadow2_transition=1.0; + + color_type=COLOR_WHITE; + color=Color(1,1,1,1); + gradient_begin=Color(1,1,1,1); + gradient_end=Color(0.5,0.5,0.5,1); + color_use_monochrome=false; + + font_mode=FONT_BITMAP; + round_advance=true; + enable_filter=true; + premultiply_alpha=false; + + } + + _EditorFontImportOptions() { + + font_mode=FONT_BITMAP; + + char_extra_spacing=0; + top_extra_spacing=0; + bottom_extra_spacing=0; + space_extra_spacing=0; + + character_set=CHARSET_LATIN; + + shadow=false; + shadow_radius=2; + shadow_color=Color(0,0,0,0.3); + shadow_transition=1.0; + + shadow2=false; + shadow2_radius=2; + shadow2_color=Color(0,0,0,0.3); + shadow2_transition=1.0; + + color_type=COLOR_WHITE; + color=Color(1,1,1,1); + gradient_begin=Color(1,1,1,1); + gradient_end=Color(0.5,0.5,0.5,1); + color_use_monochrome=false; + + round_advance=true; + enable_filter=true; + premultiply_alpha=false; + } + + +}; + + +class EditorFontImportDialog : public ConfirmationDialog { + + GDCLASS(EditorFontImportDialog, ConfirmationDialog); + + + EditorLineEditFileChooser *source; + EditorLineEditFileChooser *dest; + SpinBox *font_size; + LineEdit *test_string; + ColorPickerButton *test_color; + Label *test_label; + PropertyEditor *prop_edit; + Timer *timer; + ConfirmationDialog *error_dialog; + + + Ref<ResourceImportMetadata> get_rimd() { + + Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); + List<PropertyInfo> pl; + options->_get_property_list(&pl); + for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { + + Variant v; + String opt=E->get().name; + options->_get(opt,v); + if (opt=="color/image" || opt=="character_set/custom") { + v = EditorImportPlugin::validate_source_path(v); + } + imd->set_option(opt,v); + } + + String src_path = EditorImportPlugin::validate_source_path(source->get_line_edit()->get_text()); + //print_line("pre src path "+source->get_line_edit()->get_text()); + //print_line("src path "+src_path); + imd->add_source(src_path); + imd->set_option("font/size",font_size->get_value()); + + return imd; + + } + + void _src_changed(String) { + _prop_changed(); + } + + void _update_text2(String) { + _update_text(); + } + void _update_text3(Color) { + _update_text(); + } + + void _update_text() { + + test_label->set_text(""); + test_label->set_text(test_string->get_text()); + test_label->add_color_override("font_color",test_color->get_pick_color()); + } + + void _update() { + + Ref<ResourceImportMetadata> imd = get_rimd(); + Ref<BitmapFont> font = plugin->generate_font(imd); + test_label->add_font_override("font",font); + _update_text(); + } + + void _font_size_changed(double) { + + _prop_changed(); + } + + void _prop_changed() { + + timer->start(); + } + + void _import_inc(String p_font) { + + Ref<BitmapFont> font = ResourceLoader::load(p_font); + if (!font.is_valid()) + return; + Ref<ImageTexture> tex = font->get_texture(0); + if (tex.is_null()) + return; + FileAccessRef f=FileAccess::open(p_font.get_basename()+".inc",FileAccess::WRITE); + Vector<CharType> ck = font->get_char_keys(); + + f->store_line("static const int _builtin_font_height="+itos(font->get_height())+";"); + f->store_line("static const int _builtin_font_ascent="+itos(font->get_ascent())+";"); + f->store_line("static const int _builtin_font_charcount="+itos(ck.size())+";"); + f->store_line("static const int _builtin_font_charrects["+itos(ck.size())+"][8]={"); + f->store_line("/* charidx , ofs_x, ofs_y, size_x, size_y, valign, halign, advance */"); + + for(int i=0;i<ck.size();i++) { + CharType k=ck[i]; + BitmapFont::Character c=font->get_character(k); + f->store_line("{"+itos(k)+","+rtos(c.rect.pos.x)+","+rtos(c.rect.pos.y)+","+rtos(c.rect.size.x)+","+rtos(c.rect.size.y)+","+rtos(c.v_align)+","+rtos(c.h_align)+","+rtos(c.advance)+"},"); + } + f->store_line("};"); + + Vector<BitmapFont::KerningPairKey> kp=font->get_kerning_pair_keys(); + f->store_line("static const int _builtin_font_kerning_pair_count="+itos(kp.size())+";"); + f->store_line("static const int _builtin_font_kerning_pairs["+itos(kp.size())+"][3]={"); + for(int i=0;i<kp.size();i++) { + + int d = font->get_kerning_pair(kp[i].A,kp[i].B); + f->store_line("{"+itos(kp[i].A)+","+itos(kp[i].B)+","+itos(d)+"},"); + } + + f->store_line("};"); + Image img = tex->get_data(); + + f->store_line("static const int _builtin_font_img_width="+itos(img.get_width())+";"); + f->store_line("static const int _builtin_font_img_height="+itos(img.get_height())+";"); + + String fname = p_font.get_basename()+".sv.png"; + ResourceSaver::save(fname,tex); + Vector<uint8_t> data=FileAccess::get_file_as_array(fname); + + + f->store_line("static const int _builtin_font_img_data_size="+itos(data.size())+";"); + f->store_line("static const unsigned char _builtin_font_img_data["+itos(data.size())+"]={"); + + + + for(int i=0;i<data.size();i++) { + + f->store_line(itos(data[i])+","); + + } + f->store_line("};"); + + } + + void _import() { + + if (source->get_line_edit()->get_text()=="") { + error_dialog->set_text(TTR("No source font file!")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + } + + if (dest->get_line_edit()->get_text()=="") { + error_dialog->set_text(TTR("No target font resource!")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + } + + if (dest->get_line_edit()->get_text().get_file()==".fnt") { + dest->get_line_edit()->set_text(dest->get_line_edit()->get_text().get_base_dir() + "/" + source->get_line_edit()->get_text().get_file().get_basename() + ".fnt" ); + } + + if (dest->get_line_edit()->get_text().get_extension() == dest->get_line_edit()->get_text()) { + dest->get_line_edit()->set_text(dest->get_line_edit()->get_text() + ".fnt"); + } + + if (dest->get_line_edit()->get_text().get_extension().to_lower() != "fnt") { + error_dialog->set_text(TTR("Invalid file extension.\nPlease use .fnt.")); + error_dialog->popup_centered(Size2(200,100)); + return; + } + + Ref<ResourceImportMetadata> rimd = get_rimd(); + + if (rimd.is_null()) { + error_dialog->set_text(TTR("Can't load/process source font.")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + } + + Error err = plugin->import(dest->get_line_edit()->get_text(),rimd); + + if (err!=OK) { + error_dialog->set_text(TTR("Couldn't save font.")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + } + + _import_inc(dest->get_line_edit()->get_text()); + + hide(); + } + + EditorFontImportPlugin *plugin; + _EditorFontImportOptions *options; + + static void _bind_methods() { + + ClassDB::bind_method("_update",&EditorFontImportDialog::_update); + ClassDB::bind_method("_update_text",&EditorFontImportDialog::_update_text); + ClassDB::bind_method("_update_text2",&EditorFontImportDialog::_update_text2); + ClassDB::bind_method("_update_text3",&EditorFontImportDialog::_update_text3); + ClassDB::bind_method("_prop_changed",&EditorFontImportDialog::_prop_changed); + ClassDB::bind_method("_src_changed",&EditorFontImportDialog::_src_changed); + ClassDB::bind_method("_font_size_changed",&EditorFontImportDialog::_font_size_changed); + ClassDB::bind_method("_import",&EditorFontImportDialog::_import); + + } + +public: + + void _notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + prop_edit->edit(options); + _update_text(); + } + } + + void popup_import(const String& p_path) { + + popup_centered(Size2(600,500)*EDSCALE); + + if (p_path!="") { + + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); + ERR_FAIL_COND(!rimd.is_valid()); + + dest->get_line_edit()->set_text(p_path); + List<String> opts; + rimd->get_options(&opts); + options->reset(); + for(List<String>::Element *E=opts.front();E;E=E->next()) { + + options->_set(E->get(),rimd->get_option(E->get())); + } + + String src = ""; + for(int i=0;i<rimd->get_source_count();i++) { + if (i>0) + src+=","; + src+=EditorImportPlugin::expand_source_path(rimd->get_source_path(i)); + } + source->get_line_edit()->set_text(src); + + font_size->set_value(rimd->get_option("font/size")); + } + } + + + void set_source_and_dest(const String& p_font,const String& p_dest) { + source->get_line_edit()->set_text(p_font); + dest->get_line_edit()->set_text(p_dest); + _prop_changed(); + } + + EditorFontImportDialog(EditorFontImportPlugin *p_plugin) { + plugin=p_plugin; + VBoxContainer *vbc = memnew( VBoxContainer ); + add_child(vbc); + //set_child_rect(vbc); + HBoxContainer *hbc = memnew( HBoxContainer); + vbc->add_child(hbc); + VBoxContainer *vbl = memnew( VBoxContainer ); + hbc->add_child(vbl); + hbc->set_v_size_flags(SIZE_EXPAND_FILL); + vbl->set_h_size_flags(SIZE_EXPAND_FILL); + VBoxContainer *vbr = memnew( VBoxContainer ); + hbc->add_child(vbr); + vbr->set_h_size_flags(SIZE_EXPAND_FILL); + + source = memnew( EditorLineEditFileChooser ); + source->get_file_dialog()->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + source->get_file_dialog()->set_mode(EditorFileDialog::MODE_OPEN_FILE); + source->get_file_dialog()->add_filter("*.ttf;TrueType"); + source->get_file_dialog()->add_filter("*.otf;OpenType"); + source->get_file_dialog()->add_filter("*.fnt;BMFont"); + source->get_line_edit()->connect("text_entered",this,"_src_changed"); + + vbl->add_margin_child(TTR("Source Font:"),source); + font_size = memnew( SpinBox ); + vbl->add_margin_child(TTR("Source Font Size:"),font_size); + font_size->set_min(3); + font_size->set_max(256); + font_size->set_value(16); + font_size->connect("value_changed",this,"_font_size_changed"); + dest = memnew( EditorLineEditFileChooser ); + // + List<String> fl; + Ref<BitmapFont> font= memnew(BitmapFont); + dest->get_file_dialog()->add_filter("*.fnt ; Font" ); + /* + ResourceSaver::get_recognized_extensions(font,&fl); + for(List<String>::Element *E=fl.front();E;E=E->next()) { + dest->get_file_dialog()->add_filter("*."+E->get()); + } + */ + + vbl->add_margin_child(TTR("Dest Resource:"),dest); + HBoxContainer *testhb = memnew( HBoxContainer ); + test_string = memnew( LineEdit ); + test_string->set_text(TTR("The quick brown fox jumps over the lazy dog.")); + test_string->set_h_size_flags(SIZE_EXPAND_FILL); + test_string->set_stretch_ratio(5); + + testhb->add_child(test_string); + test_color = memnew( ColorPickerButton ); + test_color->set_pick_color(get_color("font_color","Label")); + test_color->set_h_size_flags(SIZE_EXPAND_FILL); + test_color->set_stretch_ratio(1); + test_color->connect("color_changed",this,"_update_text3"); + testhb->add_child(test_color); + + vbl->add_spacer(); + vbl->add_margin_child(TTR("Test:")+" ",testhb); + /* + HBoxContainer *upd_hb = memnew( HBoxContainer ); + //vbl->add_child(upd_hb); + upd_hb->add_spacer(); + Button *update = memnew( Button); + upd_hb->add_child(update); + update->set_text("Update"); + update->connect("pressed",this,"_update"); +*/ + options = memnew( _EditorFontImportOptions ); + prop_edit = memnew( PropertyEditor() ); + vbr->add_margin_child(TTR("Options:"),prop_edit,true); + options->connect("changed",this,"_prop_changed"); + + prop_edit->hide_top_label(); + + Panel *panel = memnew( Panel ); + vbc->add_child(panel); + test_label = memnew( Label ); + test_label->set_autowrap(true); + panel->add_child(test_label); + test_label->set_area_as_parent_rect(); + panel->set_v_size_flags(SIZE_EXPAND_FILL); + test_string->connect("text_changed",this,"_update_text2"); + set_title(TTR("Font Import")); + timer = memnew( Timer ); + add_child(timer); + timer->connect("timeout",this,"_update"); + timer->set_wait_time(0.4); + timer->set_one_shot(true); + + get_ok()->connect("pressed", this,"_import"); + get_ok()->set_text(TTR("Import")); + + error_dialog = memnew ( ConfirmationDialog ); + add_child(error_dialog); + error_dialog->get_ok()->set_text(TTR("Accept")); + set_hide_on_ok(false); + + + } + + ~EditorFontImportDialog() { + memdelete(options); + } +}; + + +/////////////////////////////////////// + + + +struct _EditorFontData { + + Vector<uint8_t> bitmap; + int width,height; + int ofs_x; //ofset to center, from ABOVE + int ofs_y; //ofset to begining, from LEFT + int valign; //vertical alignment + int halign; + float advance; + int character; + int glyph; + + int texture; + Image blit; + Point2i blit_ofs; + //bool printable; + +}; + + +struct _EditorFontDataSort { + + bool operator()(const _EditorFontData *p_A,const _EditorFontData *p_B) const { + return p_A->height > p_B->height; + }; +}; + +struct _EditorKerningKey { + + CharType A,B; + bool operator<(const _EditorKerningKey& p_k) const { return (A==p_k.A)?(B<p_k.B):(A<p_k.A); } + +}; + + +static unsigned char get_SDF_radial( + unsigned char *fontmap, + int w, int h, + int x, int y, + int max_radius ) +{ + //hideous brute force method + float d2 = max_radius*max_radius+1.0; + unsigned char v = fontmap[x+y*w]; + for( int radius = 1; (radius <= max_radius) && (radius*radius < d2); ++radius ) + { + int line, lo, hi; + //north + line = y - radius; + if( (line >= 0) && (line < h) ) + { + lo = x - radius; + hi = x + radius; + if( lo < 0 ) { lo = 0; } + if( hi >= w ) { hi = w-1; } + int idx = line * w + lo; + for( int i = lo; i <= hi; ++i ) + { + //check this pixel + if( fontmap[idx] != v ) + { + float nx = i - x; + float ny = line - y; + float nd2 = nx*nx+ny*ny; + if( nd2 < d2 ) + { + d2 = nd2; + } + } + //move on + ++idx; + } + } + //south + line = y + radius; + if( (line >= 0) && (line < h) ) + { + lo = x - radius; + hi = x + radius; + if( lo < 0 ) { lo = 0; } + if( hi >= w ) { hi = w-1; } + int idx = line * w + lo; + for( int i = lo; i <= hi; ++i ) + { + //check this pixel + if( fontmap[idx] != v ) + { + float nx = i - x; + float ny = line - y; + float nd2 = nx*nx+ny*ny; + if( nd2 < d2 ) + { + d2 = nd2; + } + } + //move on + ++idx; + } + } + //west + line = x - radius; + if( (line >= 0) && (line < w) ) + { + lo = y - radius + 1; + hi = y + radius - 1; + if( lo < 0 ) { lo = 0; } + if( hi >= h ) { hi = h-1; } + int idx = lo * w + line; + for( int i = lo; i <= hi; ++i ) + { + //check this pixel + if( fontmap[idx] != v ) + { + float nx = line - x; + float ny = i - y; + float nd2 = nx*nx+ny*ny; + if( nd2 < d2 ) + { + d2 = nd2; + } + } + //move on + idx += w; + } + } + //east + line = x + radius; + if( (line >= 0) && (line < w) ) + { + lo = y - radius + 1; + hi = y + radius - 1; + if( lo < 0 ) { lo = 0; } + if( hi >= h ) { hi = h-1; } + int idx = lo * w + line; + for( int i = lo; i <= hi; ++i ) + { + //check this pixel + if( fontmap[idx] != v ) + { + float nx = line - x; + float ny = i - y; + float nd2 = nx*nx+ny*ny; + if( nd2 < d2 ) + { + d2 = nd2; + } + } + //move on + idx += w; + } + } + } + d2 = sqrtf( d2 ); + if( v==0 ) + { + d2 = -d2; + } + d2 *= 127.5 / max_radius; + d2 += 127.5; + if( d2 < 0.0 ) d2 = 0.0; + if( d2 > 255.0 ) d2 = 255.0; + return (unsigned char)(d2 + 0.5); +} + + +Ref<BitmapFont> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata>& p_from, const String &p_existing) { + + + + Ref<ResourceImportMetadata> from = p_from; + ERR_FAIL_COND_V(from->get_source_count()!=1,Ref<BitmapFont>()); + + String src_path = EditorImportPlugin::expand_source_path(from->get_source_path(0)); + + if (src_path.get_extension().to_lower()=="fnt") { + + if (ResourceLoader::load(src_path).is_valid()) { + EditorNode::get_singleton()->show_warning(TTR("Path:")+" "+src_path+"\n"+TTR("This file is already a Godot font file, please supply a BMFont type file instead.")); + return Ref<BitmapFont>(); + } + + Ref<BitmapFont> font; + font.instance(); + Error err = font->create_from_fnt(src_path); + if (err) { + EditorNode::get_singleton()->show_warning(TTR("Path:")+" "+src_path+"\n"+TTR("Failed opening as BMFont file.")); + return Ref<BitmapFont>(); + } + + return font; + } + + int size = from->get_option("font/size"); + +#ifdef FREETYPE_ENABLED + FT_Library library; /* handle to library */ + FT_Face face; /* handle to face object */ + + Vector<_EditorFontData*> font_data_list; + + int error = FT_Init_FreeType( &library ); + + ERR_EXPLAIN(TTR("Error initializing FreeType.")); + ERR_FAIL_COND_V( error !=0, Ref<BitmapFont>() ); + + print_line("loadfrom: "+src_path); + error = FT_New_Face( library, src_path.utf8().get_data(),0,&face ); + + if ( error == FT_Err_Unknown_File_Format ) { + ERR_EXPLAIN(TTR("Unknown font format.")); + FT_Done_FreeType( library ); + } else if ( error ) { + + ERR_EXPLAIN(TTR("Error loading font.")); + FT_Done_FreeType( library ); + + } + + ERR_FAIL_COND_V(error,Ref<BitmapFont>()); + + + int height=0; + int ascent=0; + int font_spacing=0; + + error = FT_Set_Char_Size(face,0,64*size,512,512); + + if ( error ) { + FT_Done_FreeType( library ); + ERR_EXPLAIN(TTR("Invalid font size.")); + ERR_FAIL_COND_V( error,Ref<BitmapFont>() ); + + } + + int font_mode = from->get_option("mode/mode"); + + int scaler=(font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD)?16:1; + + error = FT_Set_Pixel_Sizes(face,0,size*scaler); + + FT_GlyphSlot slot = face->glyph; + + //error = FT_Set_Charmap(face,ft_encoding_unicode ); /* encoding.. */ + + + /* PRINT CHARACTERS TO INDIVIDUAL BITMAPS */ + + + //int space_size=5; //size for space, if none found.. 5! + //int min_valign=500; //some ridiculous number + + FT_ULong charcode; + FT_UInt gindex; + + int max_up=-1324345; ///gibberish + int max_down=124232; + + Map<_EditorKerningKey,int> kerning_map; + + charcode = FT_Get_First_Char( face, &gindex ); + + Set<CharType> import_chars; + + int import_mode = from->get_option("character_set/mode"); + bool round_advance = from->get_option("advanced/round_advance"); + + if (import_mode>=_EditorFontImportOptions::CHARSET_CUSTOM) { + + //load from custom text + String path = from->get_option("character_set/custom"); + + FileAccess *fa = FileAccess::open(EditorImportPlugin::expand_source_path(path),FileAccess::READ); + + if ( !fa ) { + + FT_Done_FreeType( library ); + ERR_EXPLAIN(TTR("Invalid font custom source.")); + ERR_FAIL_COND_V( !fa,Ref<BitmapFont>() ); + + } + + + while(!fa->eof_reached()) { + + String line = fa->get_line(); + for(int i=0;i<line.length();i++) { + import_chars.insert(line[i]); + } + } + + if (import_mode==_EditorFontImportOptions::CHARSET_CUSTOM_LATIN) { + + for(int i=32;i<128;i++) + import_chars.insert(i); + } + + memdelete(fa); + } + + int xsize=0; + while ( gindex != 0 ) + { + + bool skip=false; + error = FT_Load_Char( face, charcode, font_mode==_EditorFontImportOptions::FONT_BITMAP?FT_LOAD_RENDER:FT_LOAD_MONOCHROME ); + if (error) skip=true; + else error = FT_Render_Glyph( face->glyph, font_mode==_EditorFontImportOptions::FONT_BITMAP?ft_render_mode_normal:ft_render_mode_mono ); + if (error) { + skip=true; + } else if (!skip) { + + switch(import_mode) { + + case _EditorFontImportOptions::CHARSET_ASCII: skip = charcode>127; break; + case _EditorFontImportOptions::CHARSET_LATIN: skip = charcode>255 ;break; + case _EditorFontImportOptions::CHARSET_UNICODE: break; //none + case _EditorFontImportOptions::CHARSET_CUSTOM: + case _EditorFontImportOptions::CHARSET_CUSTOM_LATIN: skip = !import_chars.has(charcode); break; + + } + } + + if (charcode<=32) //?? + skip=true; + + if (skip) { + charcode=FT_Get_Next_Char(face,charcode,&gindex); + continue; + } + + _EditorFontData * fdata = memnew( _EditorFontData ); + + + int w = slot->bitmap.width; + int h = slot->bitmap.rows; + int p = slot->bitmap.pitch; + + //print_line("W: "+itos(w)+" P: "+itos(slot->bitmap.pitch)); + + if (font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD) { + + //oversize the holding buffer so I can smooth it! + int sw = w + scaler * 4; + int sh = h + scaler * 4; + //do the SDF + int sdfw = sw / scaler; + int sdfh = sh / scaler; + + fdata->width=sdfw; + fdata->height=sdfh; + } else { + fdata->width=w; + fdata->height=h; + } + + fdata->character=charcode; + fdata->glyph=FT_Get_Char_Index(face,charcode); + if (charcode=='x') + xsize=w/scaler; + + + + fdata->valign=slot->bitmap_top; + fdata->halign=slot->bitmap_left; + + if (round_advance) + fdata->advance=(slot->advance.x+(1<<5))>>6; + else + fdata->advance=slot->advance.x/float(1<<6); + + if (font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD) { + + fdata->halign = fdata->halign / scaler - 1.5; + fdata->valign = fdata->valign / scaler + 1.5; + fdata->advance/=scaler; + + } + + fdata->advance+=font_spacing; + + + if (charcode<127) { + int top = fdata->valign; + int hmax = h/scaler; + + if (top>max_up) { + + max_up=top; + } + + + if ( (top - hmax)<max_down ) { + + max_down=top - hmax; + } + } + + if (font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD) { + + + //oversize the holding buffer so I can smooth it! + int sw = w + scaler * 4; + int sh = h + scaler * 4; + + unsigned char *smooth_buf = new unsigned char[sw*sh]; + + for( int i = 0; i < sw*sh; ++i ) { + smooth_buf[i] = 0; + } + + // copy the glyph into the buffer to be smoothed + unsigned char *buf = slot->bitmap.buffer; + for( int j = 0; j < h; ++j ) { + for( int i = 0; i < w; ++i ) { + smooth_buf[scaler*2+i+(j+scaler*2)*sw] = 255 * ((buf[j*p+(i>>3)] >> (7 - (i & 7))) & 1); + } + } + + // do the SDF + int sdfw = fdata->width; + int sdfh = fdata->height; + + fdata->bitmap.resize( sdfw*sdfh ); + + for( int j = 0; j < sdfh; ++j ) { + for( int i = 0; i < sdfw; ++i ) { + int pd_idx = j*sdfw+i; + + //fdata->bitmap[j*slot->bitmap.width+i]=slot->bitmap.buffer[j*slot->bitmap.width+i]; + + fdata->bitmap[pd_idx] = + //get_SDF + get_SDF_radial + ( smooth_buf, sw, sh, + i*scaler + (scaler >>1), j*scaler + (scaler >>1), + 2*scaler ); + + } + } + + delete [] smooth_buf; + + } else { + fdata->bitmap.resize( slot->bitmap.width*slot->bitmap.rows ); + for (int i=0;i<slot->bitmap.width;i++) { + for (int j=0;j<slot->bitmap.rows;j++) { + + fdata->bitmap[j*slot->bitmap.width+i]=slot->bitmap.buffer[j*slot->bitmap.width+i]; + } + } + } + + font_data_list.push_back(fdata); + charcode=FT_Get_Next_Char(face,charcode,&gindex); +// printf("reading char %i\n",charcode); + } + + /* SPACE */ + + _EditorFontData *spd = memnew( _EditorFontData ); + spd->advance=0; + spd->character=' '; + spd->halign=0; + spd->valign=0; + spd->width=0; + spd->height=0; + spd->ofs_x=0; + spd->ofs_y=0; + + if (!FT_Load_Char( face, ' ', FT_LOAD_RENDER ) && !FT_Render_Glyph( face->glyph, font_mode==_EditorFontImportOptions::FONT_BITMAP?ft_render_mode_normal:ft_render_mode_mono )) { + + spd->advance = slot->advance.x>>6; //round to nearest or store as float + spd->advance/=scaler; + spd->advance+=font_spacing; + } else { + + spd->advance=xsize; + spd->advance+=font_spacing; + } + + font_data_list.push_back(spd); + + Set<CharType> exported; + for (int i=0; i<font_data_list.size(); i++) { + exported.insert(font_data_list[i]->character); + }; + int missing = 0; + for(Set<CharType>::Element *E=import_chars.front();E;E=E->next()) { + CharType c = E->get(); + if (!exported.has(c)) { + CharType str[2] = {c, 0}; + printf("** Warning: character %i (%ls) not exported\n", (int)c, str); + ++missing; + }; + }; + print_line("total_chars: "+itos(font_data_list.size())); + + /* KERNING */ + + + for(int i=0;i<font_data_list.size();i++) { + + if (font_data_list[i]->character>512) + continue; + for(int j=0;j<font_data_list.size();j++) { + + if (font_data_list[j]->character>512) + continue; + + FT_Vector delta; + FT_Get_Kerning( face, font_data_list[i]->glyph,font_data_list[j]->glyph, FT_KERNING_DEFAULT, &delta ); + + if (delta.x!=0) { + + _EditorKerningKey kpk; + kpk.A = font_data_list[i]->character; + kpk.B = font_data_list[j]->character; + int kern = ((-delta.x)+(1<<5))>>6; + + if (kern==0) + continue; + kerning_map[kpk]=kern/scaler; + } + } + } + + height=max_up-max_down; + ascent=max_up; + + /* FIND OUT WHAT THE FONT HEIGHT FOR THIS IS */ + + /* ADJUST THE VALIGN FOR EACH CHARACTER */ + + for (int i=0;i<(int)font_data_list.size();i++) { + + font_data_list[i]->valign=max_up-font_data_list[i]->valign; + } + + + + /* ADD THE SPACEBAR CHARACTER */ +/* + _EditorFontData * fdata = new _EditorFontData; + + fdata->character=32; + fdata->bitmap=0; + fdata->width=xsize; + fdata->height=1; + fdata->valign=0; + + font_data_list.push_back(fdata); +*/ + /* SORT BY HEIGHT, SO THEY FIT BETTER ON THE TEXTURE */ + + font_data_list.sort_custom<_EditorFontDataSort>(); + Color *color=memnew_arr(Color,height); + + int gradient_type=from->get_option("color/mode"); + switch(gradient_type) { + case _EditorFontImportOptions::COLOR_WHITE: { + + for(int i=0;i<height;i++){ + color[i]=Color(1,1,1,1); + } + + } break; + case _EditorFontImportOptions::COLOR_CUSTOM: { + + Color cc = from->get_option("color/color"); + for(int i=0;i<height;i++){ + color[i]=cc; + } + + } break; + case _EditorFontImportOptions::COLOR_GRADIENT_RANGE: { + + Color src=from->get_option("color/begin"); + Color to=from->get_option("color/end"); + for(int i=0;i<height;i++){ + color[i]=src.linear_interpolate(to,i/float(height)); + } + + } break; + case _EditorFontImportOptions::COLOR_GRADIENT_IMAGE: { + + String fp = EditorImportPlugin::expand_source_path(from->get_option("color/image")); + Image img; + Error err = ImageLoader::load_image(fp,&img); + if (err==OK) { + + for(int i=0;i<height;i++){ + //color[i]=img.get_pixel(0,i*img.get_height()/height); + } + } else { + + for(int i=0;i<height;i++){ + color[i]=Color(1,1,1,1); + } + } + + } break; + } + + + for(int i=0;i<font_data_list.size();i++) { + + if (font_data_list[i]->bitmap.size()==0) + continue; + + int margin[4]={0,0,0,0}; + + if (from->get_option("shadow/enabled").operator bool()) { + int r=from->get_option("shadow/radius"); + Point2i ofs=Point2(from->get_option("shadow/offset")); + margin[ MARGIN_LEFT ] = MAX( r - ofs.x, 0); + margin[ MARGIN_RIGHT ] = MAX( r + ofs.x, 0); + margin[ MARGIN_TOP ] = MAX( r - ofs.y, 0); + margin[ MARGIN_BOTTOM ] = MAX( r + ofs.y, 0); + + } + + if (from->get_option("shadow2/enabled").operator bool()) { + int r=from->get_option("shadow2/radius"); + Point2i ofs=Point2(from->get_option("shadow2/offset")); + margin[ MARGIN_LEFT ] = MAX( r - ofs.x, margin[ MARGIN_LEFT ]); + margin[ MARGIN_RIGHT ] = MAX( r + ofs.x, margin[ MARGIN_RIGHT ]); + margin[ MARGIN_TOP ] = MAX( r - ofs.y, margin[ MARGIN_TOP ]); + margin[ MARGIN_BOTTOM ] = MAX( r + ofs.y, margin[ MARGIN_BOTTOM ]); + + } + + Size2i s; + s.width=font_data_list[i]->width+margin[MARGIN_LEFT]+margin[MARGIN_RIGHT]; + s.height=font_data_list[i]->height+margin[MARGIN_TOP]+margin[MARGIN_BOTTOM]; + Point2i o; + o.x=margin[MARGIN_LEFT]; + o.y=margin[MARGIN_TOP]; + + int ow=font_data_list[i]->width; + int oh=font_data_list[i]->height; + + PoolVector<uint8_t> pixels; + pixels.resize(s.x*s.y*4); + + PoolVector<uint8_t>::Write w = pixels.write(); + //print_line("val: "+itos(font_data_list[i]->valign)); + for(int y=0;y<s.height;y++) { + + int yc=CLAMP(y-o.y+font_data_list[i]->valign,0,height-1); + Color c=color[yc]; + c.a=0; + + for(int x=0;x<s.width;x++) { + + int ofs=y*s.x+x; + w[ofs*4+0]=c.r*255.0; + w[ofs*4+1]=c.g*255.0; + w[ofs*4+2]=c.b*255.0; + w[ofs*4+3]=c.a*255.0; + } + } + + + for(int si=0;si<2;si++) { + +#define S_VAR(m_v) (String(si==0?"shadow/":"shadow2/")+m_v) + if (from->get_option(S_VAR("enabled")).operator bool()) { + int r = from->get_option(S_VAR("radius")); + + Color sc = from->get_option(S_VAR("color")); + Point2i so=Point2(from->get_option(S_VAR("offset"))); + + float tr = from->get_option(S_VAR("transition")); + print_line("shadow enabled: "+itos(si)); + + Vector<uint8_t> s2buf; + s2buf.resize(s.x*s.y); + uint8_t *wa=s2buf.ptr(); + + for(int j=0;j<s.x*s.y;j++){ + + wa[j]=0; + } + + // blit shadowa + for(int x=0;x<ow;x++) { + for(int y=0;y<oh;y++) { + int ofs = (o.y+y+so.y)*s.x+x+o.x+so.x; + wa[ofs]=font_data_list[i]->bitmap[y*ow+x]; + } + } + //blur shadow2 with separatable convolution + + if (r>0) { + + Vector<uint8_t> pixels2; + pixels2.resize(s2buf.size()); + uint8_t *w2=pixels2.ptr(); + //vert + for(int x=0;x<s.width;x++) { + for(int y=0;y<s.height;y++) { + + int ofs = y*s.width+x; + int sum=wa[ofs]; + + for(int k=1;k<=r;k++) { + + int ofs_d=MIN(y+k,s.height-1)*s.width+x; + int ofs_u=MAX(y-k,0)*s.width+x; + sum+=wa[ofs_d]; + sum+=wa[ofs_u]; + } + + w2[ofs]=sum/(r*2+1); + + } + } + //horiz + for(int x=0;x<s.width;x++) { + for(int y=0;y<s.height;y++) { + + int ofs = y*s.width+x; + int sum=w2[ofs]; + + for(int k=1;k<=r;k++) { + + int ofs_r=MIN(x+k,s.width-1)+s.width*y; + int ofs_l=MAX(x-k,0)+s.width*y; + sum+=w2[ofs_r]; + sum+=w2[ofs_l]; + } + + wa[ofs]=Math::pow(float(sum/(r*2+1))/255.0f,tr)*255.0f; + + } + } + + } + + //blend back + + for(int j=0;j<s.x*s.y;j++){ + Color wd(w[j*4+0]/255.0,w[j*4+1]/255.0,w[j*4+2]/255.0,w[j*4+3]/255.0); + Color ws(sc.r,sc.g,sc.b,sc.a*(wa[j]/255.0)); + Color b = wd.blend(ws); + + w[j*4+0]=b.r*255.0; + w[j*4+1]=b.g*255.0; + w[j*4+2]=b.b*255.0; + w[j*4+3]=b.a*255.0; + + } + } + } + + for(int y=0;y<oh;y++) { + int yc=CLAMP(y+font_data_list[i]->valign,0,height-1); + Color sc=color[yc]; + for(int x=0;x<ow;x++) { + int ofs = (o.y+y)*s.x+x+o.x; + float c = font_data_list[i]->bitmap[y*ow+x]/255.0; + Color src_col=sc; + src_col.a*=c; + Color dst_col(w[ofs*4+0]/255.0,w[ofs*4+1]/255.0,w[ofs*4+2]/255.0,w[ofs*4+3]/255.0); + dst_col = dst_col.blend(src_col); + w[ofs*4+0]=dst_col.r*255.0; + w[ofs*4+1]=dst_col.g*255.0; + w[ofs*4+2]=dst_col.b*255.0; + w[ofs*4+3]=dst_col.a*255.0; + } + } + + + w=PoolVector<uint8_t>::Write(); + + Image img(s.width,s.height,0,Image::FORMAT_RGBA8,pixels); + + font_data_list[i]->blit=img; + font_data_list[i]->blit_ofs=o; + + } + + //make atlas + int spacing=2; + Vector<Size2i> sizes; + sizes.resize(font_data_list.size()); + for(int i=0;i<font_data_list.size();i++) { + + sizes[i]=Size2(font_data_list[i]->blit.get_width()+spacing*2,font_data_list[i]->blit.get_height()+spacing*2); + + } + Vector<Point2i> res; + Size2i res_size; + EditorAtlas::fit(sizes,res,res_size); + res_size.x=nearest_power_of_2(res_size.x); + res_size.y=nearest_power_of_2(res_size.y); + print_line("Atlas size: "+res_size); + + Image atlas(res_size.x,res_size.y,0,Image::FORMAT_RGBA8); + + for(int i=0;i<font_data_list.size();i++) { + + if (font_data_list[i]->bitmap.size()==0) + continue; + atlas.blit_rect(font_data_list[i]->blit,Rect2(0,0,font_data_list[i]->blit.get_width(),font_data_list[i]->blit.get_height()),res[i]+Size2(spacing,spacing)); + font_data_list[i]->ofs_x=res[i].x+spacing; + font_data_list[i]->ofs_y=res[i].y+spacing; + + + } + + if (from->has_option("advanced/premultiply_alpha") && bool(from->get_option("advanced/premultiply_alpha"))) { + + PoolVector<uint8_t> data = atlas.get_data(); + int dl = data.size(); + { + PoolVector<uint8_t>::Write w = data.write(); + + for(int i=0;i<dl;i+=4) { + + w[i+0]= uint8_t(int(w[i+0])*int(w[i+3])/255); + w[i+1]= uint8_t(int(w[i+1])*int(w[i+3])/255); + w[i+2]= uint8_t(int(w[i+2])*int(w[i+3])/255); + } + } + + atlas=Image(res_size.x,res_size.y,0,Image::FORMAT_RGBA8,data); + } + + if (from->has_option("color/monochrome") && bool(from->get_option("color/monochrome"))) { + + atlas.convert(Image::FORMAT_LA8); + } + + + if (0) { + //debug the texture + Ref<ImageTexture> atlast = memnew( ImageTexture ); + atlast->create_from_image(atlas); + //atlast->create_from_image(font_data_list[5]->blit); + TextureRect *tf = memnew( TextureRect ); + tf->set_texture(atlast); + dialog->add_child(tf); + } + + + /* CREATE FONT */ + + int char_space = from->get_option("extra_space/char"); + int space_space = from->get_option("extra_space/space"); + int top_space = from->get_option("extra_space/top"); + int bottom_space = from->get_option("extra_space/bottom"); + bool enable_filter = from->get_option("advanced/enable_filter"); + if (from->has_option("advanced/disable_filter")){ // this is a compatibility check for a deprecated option + enable_filter = !from->get_option("advanced/disable_filter"); + } + + Ref<BitmapFont> font; + + if (p_existing!=String() && ResourceCache::has(p_existing)) { + + font = Ref<BitmapFont>( ResourceCache::get(p_existing)->cast_to<BitmapFont>()); + } + + if (font.is_null()) { + font = Ref<BitmapFont>( memnew( BitmapFont ) ); + } + + font->clear(); + font->set_height(height+bottom_space+top_space); + font->set_ascent(ascent+top_space); + font->set_distance_field_hint(font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD); + + //register texures + { + Ref<ImageTexture> t = memnew(ImageTexture); + int flags; + if (!enable_filter) + flags=0; + else + flags=Texture::FLAG_FILTER; + t->create_from_image(atlas,flags); + t->set_storage( ImageTexture::STORAGE_COMPRESS_LOSSLESS ); + font->add_texture(t); + + } + //register characters + + + for(int i=0;i<font_data_list.size();i++) { + _EditorFontData *fd=font_data_list[i]; + int tex_idx=0; + + font->add_char(fd->character,tex_idx,Rect2( fd->ofs_x, fd->ofs_y, fd->blit.get_width(), fd->blit.get_height()),Point2(fd->halign-fd->blit_ofs.x,fd->valign-fd->blit_ofs.y+top_space), fd->advance+char_space+(fd->character==' '?space_space:0)); + memdelete(fd); + } + + for(Map<_EditorKerningKey,int>::Element *E=kerning_map.front();E;E=E->next()) { + + font->add_kerning_pair(E->key().A,E->key().B,E->get()); + } + + FT_Done_FreeType( library ); + + return font; +#else + + return Ref<BitmapFont>(); +#endif +} + + +String EditorFontImportPlugin::get_name() const { + + return "font"; +} +String EditorFontImportPlugin::get_visible_name() const{ + + return TTR("Font"); +} +void EditorFontImportPlugin::import_dialog(const String& p_from){ + + dialog->popup_import(p_from); +} +Error EditorFontImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from){ + + + Ref<BitmapFont> font = EditorFontImportPlugin::generate_font(p_from,p_path); + if (!font.is_valid()) + return ERR_CANT_CREATE; + + Ref<ResourceImportMetadata> from=p_from; + from->set_source_md5(0,FileAccess::get_md5(EditorImportPlugin::expand_source_path(from->get_source_path(0)))); + from->set_editor(get_name()); + font->set_import_metadata(from); + + return ResourceSaver::save(p_path,font); + +} + +void EditorFontImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + for(int i=0;i<p_drop.size();i++) { + String ext = p_drop[i].get_extension().to_lower(); + String file = p_drop[i].get_file(); + if (ext=="ttf" || ext=="otf" || ext=="fnt") { + + import_dialog(); + dialog->set_source_and_dest(p_drop[i],p_dest_path.plus_file(file.get_basename()+".fnt")); + break; + } + } +} + + +EditorFontImportPlugin::EditorFontImportPlugin(EditorNode* p_editor) { + + dialog = memnew( EditorFontImportDialog(this) ); + p_editor->get_gui_base()->add_child(dialog); +} +#endif diff --git a/editor/io_plugins/editor_font_import_plugin.h b/editor/io_plugins/editor_font_import_plugin.h new file mode 100644 index 0000000000..315a80e8cd --- /dev/null +++ b/editor/io_plugins/editor_font_import_plugin.h @@ -0,0 +1,58 @@ +/*************************************************************************/ +/* editor_font_import_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITOR_FONT_IMPORT_PLUGIN_H +#define EDITOR_FONT_IMPORT_PLUGIN_H + +#include "editor/editor_export.h" +#include "scene/resources/font.h" +#if 0 +class EditorNode; +class EditorFontImportDialog; + +class EditorFontImportPlugin : public EditorImportPlugin { + + GDCLASS(EditorFontImportPlugin,EditorImportPlugin); + + EditorFontImportDialog *dialog; +public: + + Ref<BitmapFont> generate_font(const Ref<ResourceImportMetadata>& p_from,const String& p_existing=String()); //used by editor + + virtual String get_name() const; + virtual String get_visible_name() const; + virtual void import_dialog(const String& p_from=""); + virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + virtual void import_from_drop(const Vector<String>& p_drop,const String& p_dest_path); + + + EditorFontImportPlugin(EditorNode* p_editor); +}; + +#endif // EDITOR_FONT_IMPORT_PLUGIN_H +#endif diff --git a/editor/io_plugins/editor_mesh_import_plugin.cpp b/editor/io_plugins/editor_mesh_import_plugin.cpp new file mode 100644 index 0000000000..df9d0a62e6 --- /dev/null +++ b/editor/io_plugins/editor_mesh_import_plugin.cpp @@ -0,0 +1,593 @@ +/*************************************************************************/ +/* editor_mesh_import_plugin.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 "editor_mesh_import_plugin.h" + +#if 0 + +#include "editor/editor_file_dialog.h" +#include "editor/editor_dir_dialog.h" +#include "editor/editor_node.h" +#include "editor/property_editor.h" +//#include "scene/resources/sample.h" +#include "io/resource_saver.h" +#include "os/file_access.h" +#include "io/marshalls.h" +#include "scene/resources/surface_tool.h" + +class _EditorMeshImportOptions : public Object { + + GDCLASS(_EditorMeshImportOptions,Object); +public: + + + bool generate_tangents; + bool generate_normals; + bool flip_faces; + bool smooth_shading; + bool weld_vertices; + bool import_material; + bool import_textures; + float weld_tolerance; + + + bool _set(const StringName& p_name, const Variant& p_value) { + + String n = p_name; + if (n=="generate/tangents") + generate_tangents=p_value; + else if (n=="generate/normals") + generate_normals=p_value; + else if (n=="import/materials") + import_material=p_value; + else if (n=="import/textures") + import_textures=p_value; + else if (n=="force/flip_faces") + flip_faces=p_value; + else if (n=="force/smooth_shading") + smooth_shading=p_value; + else if (n=="force/weld_vertices") + weld_vertices=p_value; + else if (n=="force/weld_tolerance") + weld_tolerance=p_value; + else + return false; + + return true; + + } + + bool _get(const StringName& p_name,Variant &r_ret) const{ + + String n = p_name; + if (n=="generate/tangents") + r_ret=generate_tangents; + else if (n=="generate/normals") + r_ret=generate_normals; + else if (n=="import/materials") + r_ret=import_material; + else if (n=="import/textures") + r_ret=import_textures; + else if (n=="force/flip_faces") + r_ret=flip_faces; + else if (n=="force/smooth_shading") + r_ret=smooth_shading; + else if (n=="force/weld_vertices") + r_ret=weld_vertices; + else if (n=="force/weld_tolerance") + r_ret=weld_tolerance; + else + return false; + + return true; + + } + void _get_property_list( List<PropertyInfo> *p_list) const{ + + p_list->push_back(PropertyInfo(Variant::BOOL,"generate/tangents")); + p_list->push_back(PropertyInfo(Variant::BOOL,"generate/normals")); + //not for nowp + //p_list->push_back(PropertyInfo(Variant::BOOL,"import/materials")); + //p_list->push_back(PropertyInfo(Variant::BOOL,"import/textures")); + p_list->push_back(PropertyInfo(Variant::BOOL,"force/flip_faces")); + p_list->push_back(PropertyInfo(Variant::BOOL,"force/smooth_shading")); + p_list->push_back(PropertyInfo(Variant::BOOL,"force/weld_vertices")); + p_list->push_back(PropertyInfo(Variant::REAL,"force/weld_tolerance",PROPERTY_HINT_RANGE,"0.00001,16,0.00001")); + //p_list->push_back(PropertyInfo(Variant::BOOL,"compress/enable")); + //p_list->push_back(PropertyInfo(Variant::INT,"compress/bitrate",PROPERTY_HINT_ENUM,"64,96,128,192")); + + + } + + + static void _bind_methods() { + + + ADD_SIGNAL( MethodInfo("changed")); + } + + + _EditorMeshImportOptions() { + + generate_tangents=true; + generate_normals=false; + flip_faces=false; + smooth_shading=false; + weld_vertices=true; + weld_tolerance=0.0001; + import_material=false; + import_textures=false; + + } + + +}; + +class EditorMeshImportDialog : public ConfirmationDialog { + + GDCLASS(EditorMeshImportDialog,ConfirmationDialog); + + EditorMeshImportPlugin *plugin; + + LineEdit *import_path; + LineEdit *save_path; + EditorFileDialog *file_select; + EditorDirDialog *save_select; + AcceptDialog *error_dialog; + PropertyEditor *option_editor; + + _EditorMeshImportOptions *options; + + +public: + + void _choose_files(const Vector<String>& p_path) { + + String files; + for(int i=0;i<p_path.size();i++) { + + if (i>0) + files+=","; + files+=p_path[i]; + } + /* + if (p_path.size()) { + String srctex=p_path[0]; + String ipath = EditorImportDB::get_singleton()->find_source_path(srctex); + + if (ipath!="") + save_path->set_text(ipath.get_base_dir()); + }*/ + import_path->set_text(files); + + } + void _choose_save_dir(const String& p_path) { + + save_path->set_text(p_path); + } + + void _browse() { + + file_select->popup_centered_ratio(); + } + + void _browse_target() { + + save_select->popup_centered_ratio(); + } + + void popup_import(const String& p_path) { + + popup_centered(Size2(400,400)*EDSCALE); + + if (p_path!="") { + + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); + ERR_FAIL_COND(!rimd.is_valid()); + + save_path->set_text(p_path.get_base_dir()); + List<String> opts; + rimd->get_options(&opts); + for(List<String>::Element *E=opts.front();E;E=E->next()) { + + options->_set(E->get(),rimd->get_option(E->get())); + } + + String src = ""; + for(int i=0;i<rimd->get_source_count();i++) { + if (i>0) + src+=","; + src+=EditorImportPlugin::expand_source_path(rimd->get_source_path(i)); + } + import_path->set_text(src); + } + } + + void _import() { + + Vector<String> meshes = import_path->get_text().split(","); + if (meshes.size()==0) { + error_dialog->set_text(TTR("No meshes to import!")); + error_dialog->popup_centered_minsize(); + return; + } + + String dst = save_path->get_text(); + if (dst=="") { + error_dialog->set_text(TTR("Save path is empty!")); + error_dialog->popup_centered_minsize(); + return; + } + + for(int i=0;i<meshes.size();i++) { + + Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); + + List<PropertyInfo> pl; + options->_get_property_list(&pl); + for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { + + Variant v; + String opt=E->get().name; + options->_get(opt,v); + imd->set_option(opt,v); + + } + + imd->add_source(EditorImportPlugin::validate_source_path(meshes[i])); + + String file_path = dst.plus_file(meshes[i].get_file().get_basename()+".msh"); + + plugin->import(file_path,imd); + } + + hide(); + } + + void _notification(int p_what) { + + + if (p_what==NOTIFICATION_ENTER_TREE) { + + option_editor->edit(options); + } + } + + static void _bind_methods() { + + ClassDB::bind_method("_choose_files",&EditorMeshImportDialog::_choose_files); + ClassDB::bind_method("_choose_save_dir",&EditorMeshImportDialog::_choose_save_dir); + ClassDB::bind_method("_import",&EditorMeshImportDialog::_import); + ClassDB::bind_method("_browse",&EditorMeshImportDialog::_browse); + ClassDB::bind_method("_browse_target",&EditorMeshImportDialog::_browse_target); + } + + EditorMeshImportDialog(EditorMeshImportPlugin *p_plugin) { + + plugin=p_plugin; + + set_title(TTR("Single Mesh Import")); + set_hide_on_ok(false); + + VBoxContainer *vbc = memnew( VBoxContainer ); + add_child(vbc); + //set_child_rect(vbc); + + HBoxContainer *hbc = memnew( HBoxContainer ); + vbc->add_margin_child(TTR("Source Mesh(es):"),hbc); + + import_path = memnew( LineEdit ); + import_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(import_path); + + Button * import_choose = memnew( Button ); + import_choose->set_text(" .. "); + hbc->add_child(import_choose); + + import_choose->connect("pressed", this,"_browse"); + + hbc = memnew( HBoxContainer ); + vbc->add_margin_child(TTR("Target Path:"),hbc); + + save_path = memnew( LineEdit ); + save_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(save_path); + + Button * save_choose = memnew( Button ); + save_choose->set_text(" .. "); + hbc->add_child(save_choose); + + save_choose->connect("pressed", this,"_browse_target"); + + file_select = memnew( EditorFileDialog ); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); + file_select->add_filter("*.obj ; Wavefront OBJ"); + add_child(file_select); + file_select->connect("files_selected", this,"_choose_files"); + + save_select = memnew( EditorDirDialog ); + add_child(save_select); + save_select->connect("dir_selected", this,"_choose_save_dir"); + + get_ok()->connect("pressed", this,"_import"); + get_ok()->set_text(TTR("Import")); + + error_dialog = memnew( AcceptDialog ); + add_child(error_dialog); + + options = memnew( _EditorMeshImportOptions ); + + option_editor = memnew( PropertyEditor ); + option_editor->hide_top_label(); + vbc->add_margin_child(TTR("Options:"),option_editor,true); + } + + ~EditorMeshImportDialog() { + memdelete(options); + } + +}; + + +String EditorMeshImportPlugin::get_name() const { + + return "mesh"; +} +String EditorMeshImportPlugin::get_visible_name() const{ + + return TTR("Mesh"); +} +void EditorMeshImportPlugin::import_dialog(const String& p_from){ + + dialog->popup_import(p_from); +} +Error EditorMeshImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from){ + + + ERR_FAIL_COND_V(p_from->get_source_count()!=1,ERR_INVALID_PARAMETER); + + Ref<ResourceImportMetadata> from=p_from; + + String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0)); + FileAccessRef f = FileAccess::open(src_path,FileAccess::READ); + ERR_FAIL_COND_V(!f,ERR_CANT_OPEN); + + Ref<Mesh> mesh; + Map<String,Ref<Material> > name_map; + + if (FileAccess::exists(p_path)) { + mesh=ResourceLoader::load(p_path,"Mesh"); + if (mesh.is_valid()) { + for(int i=0;i<mesh->get_surface_count();i++) { + + if (!mesh->surface_get_material(i).is_valid()) + continue; + String name; + if (mesh->surface_get_name(i)!="") + name=mesh->surface_get_name(i); + else + name=vformat(TTR("Surface %d"),i+1); + + name_map[name]=mesh->surface_get_material(i); + } + + while(mesh->get_surface_count()) { + mesh->surface_remove(0); + } + } + } + + if (!mesh.is_valid()) + mesh = Ref<Mesh>( memnew( Mesh ) ); + + + bool generate_normals=from->get_option("generate/normals"); + bool generate_tangents=from->get_option("generate/tangents"); + bool flip_faces=from->get_option("force/flip_faces"); + bool force_smooth=from->get_option("force/smooth_shading"); + bool weld_vertices=from->get_option("force/weld_vertices"); + float weld_tolerance=from->get_option("force/weld_tolerance"); + Vector<Vector3> vertices; + Vector<Vector3> normals; + Vector<Vector2> uvs; + String name; + + Ref<SurfaceTool> surf_tool = memnew( SurfaceTool) ; + surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES); + if (force_smooth) + surf_tool->add_smooth_group(true); + int has_index_data=false; + + while(true) { + + + String l = f->get_line().strip_edges(); + + if (l.begins_with("v ")) { + //vertex + Vector<String> v = l.split(" ",false); + ERR_FAIL_COND_V(v.size()<4,ERR_INVALID_DATA); + Vector3 vtx; + vtx.x=v[1].to_float(); + vtx.y=v[2].to_float(); + vtx.z=v[3].to_float(); + vertices.push_back(vtx); + } else if (l.begins_with("vt ")) { + //uv + Vector<String> v = l.split(" ",false); + ERR_FAIL_COND_V(v.size()<3,ERR_INVALID_DATA); + Vector2 uv; + uv.x=v[1].to_float(); + uv.y=1.0-v[2].to_float(); + uvs.push_back(uv); + + } else if (l.begins_with("vn ")) { + //normal + Vector<String> v = l.split(" ",false); + ERR_FAIL_COND_V(v.size()<4,ERR_INVALID_DATA); + Vector3 nrm; + nrm.x=v[1].to_float(); + nrm.y=v[2].to_float(); + nrm.z=v[3].to_float(); + normals.push_back(nrm); + } if (l.begins_with("f ")) { + //vertex + + has_index_data=true; + Vector<String> v = l.split(" ",false); + ERR_FAIL_COND_V(v.size()<4,ERR_INVALID_DATA); + + //not very fast, could be sped up + + + Vector<String> face[3]; + face[0] = v[1].split("/"); + face[1] = v[2].split("/"); + ERR_FAIL_COND_V(face[0].size()==0,ERR_PARSE_ERROR); + ERR_FAIL_COND_V(face[0].size()!=face[1].size(),ERR_PARSE_ERROR); + for(int i=2;i<v.size()-1;i++) { + + face[2] = v[i+1].split("/"); + ERR_FAIL_COND_V(face[0].size()!=face[2].size(),ERR_PARSE_ERROR); + for(int j=0;j<3;j++) { + + int idx=j; + + if (!flip_faces && idx<2) { + idx=1^idx; + } + + + if (face[idx].size()==3) { + int norm = face[idx][2].to_int()-1; + ERR_FAIL_INDEX_V(norm,normals.size(),ERR_PARSE_ERROR); + surf_tool->add_normal(normals[norm]); + } + + if (face[idx].size()>=2 && face[idx][1]!=String()) { + + int uv = face[idx][1].to_int()-1; + ERR_FAIL_INDEX_V(uv,uvs.size(),ERR_PARSE_ERROR); + surf_tool->add_uv(uvs[uv]); + } + + int vtx = face[idx][0].to_int()-1; + ERR_FAIL_INDEX_V(vtx,vertices.size(),ERR_PARSE_ERROR); + + Vector3 vertex = vertices[vtx]; + if (weld_vertices) + vertex=vertex.snapped(weld_tolerance); + surf_tool->add_vertex(vertex); + } + + face[1]=face[2]; + } + } else if (l.begins_with("s ") && !force_smooth) { //smoothing + String what = l.substr(2,l.length()).strip_edges(); + if (what=="off") + surf_tool->add_smooth_group(false); + else + surf_tool->add_smooth_group(true); + + } else if (l.begins_with("o ") || f->eof_reached()) { //new surface or done + + if (has_index_data) { + //new object/surface + if (generate_normals || force_smooth) + surf_tool->generate_normals(); + if (uvs.size() && (normals.size() || generate_normals) && generate_tangents) + surf_tool->generate_tangents(); + + surf_tool->index(); + mesh = surf_tool->commit(mesh); + if (name=="") + name=vformat(TTR("Surface %d"),mesh->get_surface_count()-1); + mesh->surface_set_name(mesh->get_surface_count()-1,name); + name=""; + surf_tool->clear(); + surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES); + if (force_smooth) + surf_tool->add_smooth_group(true); + + has_index_data=false; + + if (f->eof_reached()) + break; + } + + if (l.begins_with("o ")) //name + name=l.substr(2,l.length()).strip_edges(); + } + } + + + from->set_source_md5(0,FileAccess::get_md5(src_path)); + from->set_editor(get_name()); + mesh->set_import_metadata(from); + + //re-apply materials if exist + for(int i=0;i<mesh->get_surface_count();i++) { + + String n = mesh->surface_get_name(i); + if (name_map.has(n)) + mesh->surface_set_material(i,name_map[n]); + } + + Error err = ResourceSaver::save(p_path,mesh); + + return err; +} + + +void EditorMeshImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + + Vector<String> files; + for(int i=0;i<p_drop.size();i++) { + String ext = p_drop[i].get_extension().to_lower(); + String file = p_drop[i].get_file(); + if (ext=="obj") { + + files.push_back(p_drop[i]); + } + } + + if (files.size()) { + import_dialog(); + dialog->_choose_files(files); + dialog->_choose_save_dir(p_dest_path); + } +} + +EditorMeshImportPlugin::EditorMeshImportPlugin(EditorNode* p_editor) { + + dialog = memnew( EditorMeshImportDialog(this)); + p_editor->get_gui_base()->add_child(dialog); +} +#endif diff --git a/editor/io_plugins/editor_mesh_import_plugin.h b/editor/io_plugins/editor_mesh_import_plugin.h new file mode 100644 index 0000000000..df374549d4 --- /dev/null +++ b/editor/io_plugins/editor_mesh_import_plugin.h @@ -0,0 +1,59 @@ +/*************************************************************************/ +/* editor_mesh_import_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITOR_MESH_IMPORT_PLUGIN_H +#define EDITOR_MESH_IMPORT_PLUGIN_H + +#if 0 +#include "editor/editor_import_export.h" +#include "scene/resources/font.h" + +class EditorNode; +class EditorMeshImportDialog; + +class EditorMeshImportPlugin : public EditorImportPlugin { + + GDCLASS(EditorMeshImportPlugin,EditorImportPlugin); + + EditorMeshImportDialog *dialog; + + +public: + + virtual String get_name() const; + virtual String get_visible_name() const; + virtual void import_dialog(const String& p_from=""); + virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); + + + EditorMeshImportPlugin(EditorNode* p_editor); +}; + +#endif +#endif // EDITOR_MESH_IMPORT_PLUGIN_H diff --git a/editor/io_plugins/editor_sample_import_plugin.cpp b/editor/io_plugins/editor_sample_import_plugin.cpp new file mode 100644 index 0000000000..d446d39027 --- /dev/null +++ b/editor/io_plugins/editor_sample_import_plugin.cpp @@ -0,0 +1,929 @@ +/*************************************************************************/ +/* editor_sample_import_plugin.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 "editor_sample_import_plugin.h" + +#include "editor/editor_file_dialog.h" +#include "editor/editor_dir_dialog.h" +#include "editor/editor_node.h" +#include "editor/property_editor.h" +#include "io/resource_saver.h" +#include "os/file_access.h" +#include "io/marshalls.h" +#include "editor/editor_settings.h" + +#if 0 + +class _EditorSampleImportOptions : public Object { + + GDCLASS(_EditorSampleImportOptions,Object); +public: + + enum CompressMode { + COMPRESS_MODE_DISABLED, + COMPRESS_MODE_RAM, + COMPRESS_MODE_DISK + }; + + enum CompressBitrate { + COMPRESS_64, + COMPRESS_96, + COMPRESS_128, + COMPRESS_192 + }; + + bool force_8_bit; + bool force_mono; + bool force_rate; + float force_rate_hz; + + bool edit_trim; + bool edit_normalize; + bool edit_loop; + + CompressMode compress_mode; + CompressBitrate compress_bitrate; + + + bool _set(const StringName& p_name, const Variant& p_value) { + + String n = p_name; + if (n=="force/8_bit") + force_8_bit=p_value; + else if (n=="force/mono") + force_mono=p_value; + else if (n=="force/max_rate") + force_rate=p_value; + else if (n=="force/max_rate_hz") + force_rate_hz=p_value; + else if (n=="edit/trim") + edit_trim=p_value; + else if (n=="edit/normalize") + edit_normalize=p_value; + else if (n=="edit/loop") + edit_loop=p_value; + else if (n=="compress/mode") + compress_mode=CompressMode(int(p_value)); + else if (n=="compress/bitrate") + compress_bitrate=CompressBitrate(int(p_value)); + else + return false; + + return true; + + } + + bool _get(const StringName& p_name,Variant &r_ret) const{ + + String n = p_name; + if (n=="force/8_bit") + r_ret=force_8_bit; + else if (n=="force/mono") + r_ret=force_mono; + else if (n=="force/max_rate") + r_ret=force_rate; + else if (n=="force/max_rate_hz") + r_ret=force_rate_hz; + else if (n=="edit/trim") + r_ret=edit_trim; + else if (n=="edit/normalize") + r_ret=edit_normalize; + else if (n=="edit/loop") + r_ret=edit_loop; + else if (n=="compress/mode") + r_ret=compress_mode; + else if (n=="compress/bitrate") + r_ret=compress_bitrate; + else + return false; + + return true; + + } + void _get_property_list( List<PropertyInfo> *p_list) const{ + + p_list->push_back(PropertyInfo(Variant::BOOL,"force/8_bit")); + p_list->push_back(PropertyInfo(Variant::BOOL,"force/mono")); + p_list->push_back(PropertyInfo(Variant::BOOL,"force/max_rate")); + p_list->push_back(PropertyInfo(Variant::REAL,"force/max_rate_hz",PROPERTY_HINT_EXP_RANGE,"11025,192000,1")); + p_list->push_back(PropertyInfo(Variant::BOOL,"edit/trim")); + p_list->push_back(PropertyInfo(Variant::BOOL,"edit/normalize")); + p_list->push_back(PropertyInfo(Variant::BOOL,"edit/loop")); + p_list->push_back(PropertyInfo(Variant::INT,"compress/mode",PROPERTY_HINT_ENUM,"Disabled,RAM (Ima-ADPCM)")); + //p_list->push_back(PropertyInfo(Variant::INT,"compress/bitrate",PROPERTY_HINT_ENUM,"64,96,128,192")); + + + } + + + static void _bind_methods() { + + + ADD_SIGNAL( MethodInfo("changed")); + } + + + _EditorSampleImportOptions() { + + force_8_bit=false; + force_mono=false; + force_rate=true; + force_rate_hz=44100; + + edit_trim=true; + edit_normalize=true; + edit_loop=false; + + compress_mode=COMPRESS_MODE_RAM; + compress_bitrate=COMPRESS_128; + } + + +}; + +class EditorSampleImportDialog : public ConfirmationDialog { + + GDCLASS(EditorSampleImportDialog,ConfirmationDialog); + + EditorSampleImportPlugin *plugin; + + LineEdit *import_path; + LineEdit *save_path; + EditorFileDialog *file_select; + EditorDirDialog *save_select; + ConfirmationDialog *error_dialog; + PropertyEditor *option_editor; + + _EditorSampleImportOptions *options; + + +public: + + void _choose_files(const Vector<String>& p_path) { + + String files; + for(int i=0;i<p_path.size();i++) { + + if (i>0) + files+=","; + files+=p_path[i]; + } + /* + if (p_path.size()) { + String srctex=p_path[0]; + String ipath = EditorImportDB::get_singleton()->find_source_path(srctex); + + if (ipath!="") + save_path->set_text(ipath.get_base_dir()); + }*/ + import_path->set_text(files); + + } + void _choose_save_dir(const String& p_path) { + + save_path->set_text(p_path); + } + + void _browse() { + + file_select->popup_centered_ratio(); + } + + void _browse_target() { + + save_select->popup_centered_ratio(); + + } + + + void popup_import(const String& p_path) { + + popup_centered(Size2(400,400)*EDSCALE); + if (p_path!="") { + + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); + ERR_FAIL_COND(!rimd.is_valid()); + + save_path->set_text(p_path.get_base_dir()); + List<String> opts; + rimd->get_options(&opts); + for(List<String>::Element *E=opts.front();E;E=E->next()) { + + options->_set(E->get(),rimd->get_option(E->get())); + } + + String src = ""; + for(int i=0;i<rimd->get_source_count();i++) { + if (i>0) + src+=","; + src+=EditorImportPlugin::expand_source_path(rimd->get_source_path(i)); + } + import_path->set_text(src); + } + } + + + void _import() { + + Vector<String> samples = import_path->get_text().split(","); + + if (samples.size()==0) { + error_dialog->set_text(TTR("No samples to import!")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + } + + if (save_path->get_text().strip_edges()=="") { + error_dialog->set_text(TTR("Target path is empty.")); + error_dialog->popup_centered_minsize(); + return; + } + + if (!save_path->get_text().begins_with("res://")) { + error_dialog->set_text(TTR("Target path must be a complete resource path.")); + error_dialog->popup_centered_minsize(); + return; + } + + if (!DirAccess::exists(save_path->get_text())) { + error_dialog->set_text(TTR("Target path must exist.")); + error_dialog->popup_centered_minsize(); + return; + } + + for(int i=0;i<samples.size();i++) { + + Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); + + List<PropertyInfo> pl; + options->_get_property_list(&pl); + for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { + + Variant v; + String opt=E->get().name; + options->_get(opt,v); + imd->set_option(opt,v); + + } + + imd->add_source(EditorImportPlugin::validate_source_path(samples[i])); + + String dst = save_path->get_text(); + if (dst=="") { + error_dialog->set_text(TTR("Save path is empty!")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + } + + dst = dst.plus_file(samples[i].get_file().get_basename()+".smp"); + + plugin->import(dst,imd); + } + + hide(); + + } + + + void _notification(int p_what) { + + + if (p_what==NOTIFICATION_ENTER_TREE) { + + option_editor->edit(options); + } + } + + static void _bind_methods() { + + + ClassDB::bind_method("_choose_files",&EditorSampleImportDialog::_choose_files); + ClassDB::bind_method("_choose_save_dir",&EditorSampleImportDialog::_choose_save_dir); + ClassDB::bind_method("_import",&EditorSampleImportDialog::_import); + ClassDB::bind_method("_browse",&EditorSampleImportDialog::_browse); + ClassDB::bind_method("_browse_target",&EditorSampleImportDialog::_browse_target); + //ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); + } + + EditorSampleImportDialog(EditorSampleImportPlugin *p_plugin) { + + plugin=p_plugin; + + + set_title(TTR("Import Audio Samples")); + + VBoxContainer *vbc = memnew( VBoxContainer ); + add_child(vbc); + //set_child_rect(vbc); + + + HBoxContainer *hbc = memnew( HBoxContainer ); + vbc->add_margin_child(TTR("Source Sample(s):"),hbc); + + import_path = memnew( LineEdit ); + import_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(import_path); + + Button * import_choose = memnew( Button ); + import_choose->set_text(" .. "); + hbc->add_child(import_choose); + + import_choose->connect("pressed", this,"_browse"); + + hbc = memnew( HBoxContainer ); + vbc->add_margin_child(TTR("Target Path:"),hbc); + + save_path = memnew( LineEdit ); + save_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(save_path); + + Button * save_choose = memnew( Button ); + save_choose->set_text(" .. "); + hbc->add_child(save_choose); + + save_choose->connect("pressed", this,"_browse_target"); + + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + add_child(file_select); + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); + file_select->connect("files_selected", this,"_choose_files"); + file_select->add_filter("*.wav ; MS Waveform"); + save_select = memnew( EditorDirDialog ); + add_child(save_select); + + //save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); + save_select->connect("dir_selected", this,"_choose_save_dir"); + + get_ok()->connect("pressed", this,"_import"); + get_ok()->set_text(TTR("Import")); + + + error_dialog = memnew ( ConfirmationDialog ); + add_child(error_dialog); + error_dialog->get_ok()->set_text(TTR("Accept")); + //error_dialog->get_cancel()->hide(); + + set_hide_on_ok(false); + options = memnew( _EditorSampleImportOptions ); + + option_editor = memnew( PropertyEditor ); + option_editor->hide_top_label(); + vbc->add_margin_child(TTR("Options:"),option_editor,true); + } + + ~EditorSampleImportDialog() { + memdelete(options); + } + +}; + + +String EditorSampleImportPlugin::get_name() const { + + return "sample"; +} +String EditorSampleImportPlugin::get_visible_name() const{ + + return TTR("Audio Sample"); +} +void EditorSampleImportPlugin::import_dialog(const String& p_from){ + + dialog->popup_import(p_from); +} +Error EditorSampleImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from){ + + ERR_FAIL_COND_V(p_from->get_source_count()!=1,ERR_INVALID_PARAMETER); + + Ref<ResourceImportMetadata> from=p_from; + + String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0)); + Ref<Sample> smp = ResourceLoader::load(src_path); + ERR_FAIL_COND_V(smp.is_null(),ERR_CANT_OPEN); + + + float rate = smp->get_mix_rate(); + bool is16 = smp->get_format()==Sample::FORMAT_PCM16; + int chans = smp->is_stereo()?2:1; + int len = smp->get_length(); + Sample::LoopFormat loop= smp->get_loop_format(); + int loop_beg = smp->get_loop_begin(); + int loop_end = smp->get_loop_end(); + + print_line("Input Sample: "); + print_line("\tlen: "+itos(len)); + print_line("\tchans: "+itos(chans)); + print_line("\t16bits: "+itos(is16)); + print_line("\trate: "+itos(rate)); + print_line("\tloop: "+itos(loop)); + print_line("\tloop begin: "+itos(loop_beg)); + print_line("\tloop end: "+itos(loop_end)); + Vector<float> data; + data.resize(len*chans); + + { + PoolVector<uint8_t> src_data = smp->get_data(); + PoolVector<uint8_t>::Read sr = src_data.read(); + + + for(int i=0;i<len*chans;i++) { + + float s=0; + if (is16) { + + int16_t i16 = decode_uint16(&sr[i*2]); + s=i16/32767.0; + } else { + + int8_t i8 = sr[i]; + s=i8/127.0; + } + data[i]=s; + } + } + + //apply frequency limit + + bool limit_rate = from->get_option("force/max_rate"); + int limit_rate_hz = from->get_option("force/max_rate_hz"); + if (limit_rate && rate > limit_rate_hz) { + //resampleeee!!! + int new_data_len = len * limit_rate_hz / rate; + Vector<float> new_data; + new_data.resize( new_data_len * chans ); + for(int c=0;c<chans;c++) { + + for(int i=0;i<new_data_len;i++) { + + //simple cubic interpolation should be enough. + float pos = float(i) * len / new_data_len; + float mu = pos-Math::floor(pos); + int ipos = int(Math::floor(pos)); + + float y0=data[MAX(0,ipos-1)*chans+c]; + float y1=data[ipos*chans+c]; + float y2=data[MIN(len-1,ipos+1)*chans+c]; + float y3=data[MIN(len-1,ipos+2)*chans+c]; + + float mu2 = mu*mu; + float a0 = y3 - y2 - y0 + y1; + float a1 = y0 - y1 - a0; + float a2 = y2 - y0; + float a3 = y1; + + float res=(a0*mu*mu2+a1*mu2+a2*mu+a3); + + new_data[i*chans+c]=res; + } + } + + if (loop) { + + loop_beg=loop_beg*new_data_len/len; + loop_end=loop_end*new_data_len/len; + } + data=new_data; + rate=limit_rate_hz; + len=new_data_len; + } + + + bool normalize = from->get_option("edit/normalize"); + + if (normalize) { + + float max=0; + for(int i=0;i<data.size();i++) { + + float amp = Math::abs(data[i]); + if (amp>max) + max=amp; + } + + if (max>0) { + + float mult=1.0/max; + for(int i=0;i<data.size();i++) { + + data[i]*=mult; + } + + } + } + + bool trim = from->get_option("edit/trim"); + + if (trim && !loop) { + + int first=0; + int last=(len*chans)-1; + bool found=false; + float limit = Math::db2linear((float)-30); + for(int i=0;i<data.size();i++) { + float amp = Math::abs(data[i]); + + if (!found && amp > limit) { + first=i; + found=true; + } + + if (found && amp > limit) { + last=i; + } + } + + first/=chans; + last/=chans; + + if (first<last) { + + Vector<float> new_data; + new_data.resize((last-first+1)*chans); + for(int i=first*chans;i<=last*chans;i++) { + new_data[i-first*chans]=data[i]; + } + + data=new_data; + len=data.size()/chans; + } + + } + + bool make_loop = from->get_option("edit/loop"); + + if (make_loop && !loop) { + + loop=Sample::LOOP_FORWARD; + loop_beg=0; + loop_end=len; + } + + int compression = from->get_option("compress/mode"); + bool force_mono = from->get_option("force/mono"); + + + if (force_mono && chans==2) { + + Vector<float> new_data; + new_data.resize(data.size()/2); + for(int i=0;i<len;i++) { + new_data[i]=(data[i*2+0]+data[i*2+1])/2.0; + } + + data=new_data; + chans=1; + } + + bool force_8_bit = from->get_option("force/8_bit"); + if (force_8_bit) { + + is16=false; + } + + + PoolVector<uint8_t> dst_data; + Sample::Format dst_format; + + if ( compression == _EditorSampleImportOptions::COMPRESS_MODE_RAM) { + + dst_format=Sample::FORMAT_IMA_ADPCM; + if (chans==1) { + _compress_ima_adpcm(data,dst_data); + } else { + + print_line("INTERLEAAVE!"); + + + + //byte interleave + Vector<float> left; + Vector<float> right; + + int tlen = data.size()/2; + left.resize(tlen); + right.resize(tlen); + + for(int i=0;i<tlen;i++) { + left[i]=data[i*2+0]; + right[i]=data[i*2+1]; + } + + PoolVector<uint8_t> bleft; + PoolVector<uint8_t> bright; + + _compress_ima_adpcm(left,bleft); + _compress_ima_adpcm(right,bright); + + int dl = bleft.size(); + dst_data.resize( dl *2 ); + + PoolVector<uint8_t>::Write w=dst_data.write(); + PoolVector<uint8_t>::Read rl=bleft.read(); + PoolVector<uint8_t>::Read rr=bright.read(); + + for(int i=0;i<dl;i++) { + w[i*2+0]=rl[i]; + w[i*2+1]=rr[i]; + } + } + + //print_line("compressing ima-adpcm, resulting buffersize is "+itos(dst_data.size())+" from "+itos(data.size())); + + } else { + + dst_format=is16?Sample::FORMAT_PCM16:Sample::FORMAT_PCM8; + dst_data.resize( data.size() * (is16?2:1)); + { + PoolVector<uint8_t>::Write w = dst_data.write(); + + int ds=data.size(); + for(int i=0;i<ds;i++) { + + if (is16) { + int16_t v = CLAMP(data[i]*32767,-32768,32767); + encode_uint16(v,&w[i*2]); + } else { + int8_t v = CLAMP(data[i]*127,-128,127); + w[i]=v; + } + } + } + } + + + Ref<Sample> target; + + if (ResourceCache::has(p_path)) { + + target = Ref<Sample>( ResourceCache::get(p_path)->cast_to<Sample>() ); + } else { + + target = smp; + } + + target->create(dst_format,chans==2?true:false,len); + target->set_data(dst_data); + target->set_mix_rate(rate); + target->set_loop_format(loop); + target->set_loop_begin(loop_beg); + target->set_loop_end(loop_end); + + from->set_source_md5(0,FileAccess::get_md5(src_path)); + from->set_editor(get_name()); + target->set_import_metadata(from); + + + Error err = ResourceSaver::save(p_path,smp); + + return err; + +} + +void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,PoolVector<uint8_t>& dst_data) { + + + /*p_sample_data->data = (void*)malloc(len); + xm_s8 *dataptr=(xm_s8*)p_sample_data->data;*/ + + static const int16_t _ima_adpcm_step_table[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 + }; + + static const int8_t _ima_adpcm_index_table[16] = { + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8 + }; + + + int datalen = p_data.size(); + int datamax=datalen; + if (datalen&1) + datalen++; + + dst_data.resize(datalen/2+4); + PoolVector<uint8_t>::Write w = dst_data.write(); + + + int i,step_idx=0,prev=0; + uint8_t *out = w.ptr(); + //int16_t xm_prev=0; + const float *in=p_data.ptr(); + + + /* initial value is zero */ + *(out++) =0; + *(out++) =0; + /* Table index initial value */ + *(out++) =0; + /* unused */ + *(out++) =0; + + for (i=0;i<datalen;i++) { + int step,diff,vpdiff,mask; + uint8_t nibble; + int16_t xm_sample; + + if (i>=datamax) + xm_sample=0; + else { + + + xm_sample=CLAMP(in[i]*32767.0,-32768,32767); + /* + if (xm_sample==32767 || xm_sample==-32768) + printf("clippy!\n",xm_sample); + */ + } + + //xm_sample=xm_sample+xm_prev; + //xm_prev=xm_sample; + + diff = (int)xm_sample - prev ; + + nibble=0 ; + step = _ima_adpcm_step_table[ step_idx ]; + vpdiff = step >> 3 ; + if (diff < 0) { + nibble=8; + diff=-diff ; + } + mask = 4 ; + while (mask) { + + if (diff >= step) { + + nibble |= mask; + diff -= step; + vpdiff += step; + } + + step >>= 1 ; + mask >>= 1 ; + }; + + if (nibble&8) + prev-=vpdiff ; + else + prev+=vpdiff ; + + if (prev > 32767) { + //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip up %i\n",i,xm_sample,prev,diff,vpdiff,prev); + prev=32767; + } else if (prev < -32768) { + //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip down %i\n",i,xm_sample,prev,diff,vpdiff,prev); + prev = -32768 ; + } + + step_idx += _ima_adpcm_index_table[nibble]; + if (step_idx< 0) + step_idx= 0 ; + else if (step_idx> 88) + step_idx= 88 ; + + + if (i&1) { + *out|=nibble<<4; + out++; + } else { + *out=nibble; + } + /*dataptr[i]=prev>>8;*/ + } + +} + + +EditorSampleImportPlugin* EditorSampleImportPlugin::singleton=NULL; + + +void EditorSampleImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + + Vector<String> files; + for(int i=0;i<p_drop.size();i++) { + String ext = p_drop[i].get_extension().to_lower(); + + if (ext=="wav") { + + files.push_back(p_drop[i]); + } + } + + if (files.size()) { + import_dialog(); + dialog->_choose_files(files); + dialog->_choose_save_dir(p_dest_path); + } +} + +void EditorSampleImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { + + if (p_list.size()==0) + return; + + Vector<String> sources; + for(int i=0;i<p_list.size();i++) { + int idx; + EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->find_file(p_list[i],&idx); + if (efsd) { + for(int j=0;j<efsd->get_source_count(idx);j++) { + String file = expand_source_path(efsd->get_source_file(idx,j)); + if (sources.find(file)==-1) { + sources.push_back(file); + } + + } + } + } + + if (sources.size()) { + + dialog->popup_import(p_list[0]); + dialog->_choose_files(sources); + dialog->_choose_save_dir(p_list[0].get_base_dir()); + } +} + +bool EditorSampleImportPlugin::can_reimport_multiple_files() const { + + return true; +} + +EditorSampleImportPlugin::EditorSampleImportPlugin(EditorNode* p_editor) { + + singleton=this; + dialog = memnew( EditorSampleImportDialog(this)); + p_editor->get_gui_base()->add_child(dialog); +} + +Vector<uint8_t> EditorSampleExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) { + + + + if (EditorImportExport::get_singleton()->sample_get_action()==EditorImportExport::SAMPLE_ACTION_NONE || p_path.get_extension().to_lower()!="wav") { + + return Vector<uint8_t>(); + } + + Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); + + imd->add_source(EditorImportPlugin::validate_source_path(p_path)); + + imd->set_option("force/8_bit",false); + imd->set_option("force/mono",false); + imd->set_option("force/max_rate",true); + imd->set_option("force/max_rate_hz",EditorImportExport::get_singleton()->sample_get_max_hz()); + imd->set_option("edit/trim",EditorImportExport::get_singleton()->sample_get_trim()); + imd->set_option("edit/normalize",false); + imd->set_option("edit/loop",false); + imd->set_option("compress/mode",1); + + String savepath = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/smpconv.smp"); + Error err = EditorSampleImportPlugin::singleton->import(savepath,imd); + + + ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>()); + + p_path=p_path.get_basename()+".converted.smp"; + return FileAccess::get_file_as_array(savepath); + +} + + + +EditorSampleExportPlugin::EditorSampleExportPlugin() { + +} + +#endif diff --git a/editor/io_plugins/editor_sample_import_plugin.h b/editor/io_plugins/editor_sample_import_plugin.h new file mode 100644 index 0000000000..6085043a83 --- /dev/null +++ b/editor/io_plugins/editor_sample_import_plugin.h @@ -0,0 +1,74 @@ +/*************************************************************************/ +/* editor_sample_import_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITOR_SAMPLE_IMPORT_PLUGIN_H +#define EDITOR_SAMPLE_IMPORT_PLUGIN_H + +#if 0 +#include "editor/editor_import_export.h" +#include "scene/resources/font.h" + +class EditorNode; +class EditorSampleImportDialog; + +class EditorSampleImportPlugin : public EditorImportPlugin { + + GDCLASS(EditorSampleImportPlugin,EditorImportPlugin); + + EditorSampleImportDialog *dialog; + void _compress_ima_adpcm(const Vector<float>& p_data,PoolVector<uint8_t>& dst_data); +public: + + static EditorSampleImportPlugin *singleton; + + virtual String get_name() const; + virtual String get_visible_name() const; + virtual void import_dialog(const String& p_from=""); + virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); + virtual void reimport_multiple_files(const Vector<String>& p_list); + virtual bool can_reimport_multiple_files() const; + + + EditorSampleImportPlugin(EditorNode* p_editor); +}; + +class EditorSampleExportPlugin : public EditorExportPlugin { + + GDCLASS( EditorSampleExportPlugin, EditorExportPlugin); + + +public: + + virtual Vector<uint8_t> custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform); + + EditorSampleExportPlugin(); +}; + +#endif // EDITOR_SAMPLE_IMPORT_PLUGIN_H +#endif diff --git a/editor/io_plugins/editor_scene_import_plugin.cpp b/editor/io_plugins/editor_scene_import_plugin.cpp new file mode 100644 index 0000000000..963968ce47 --- /dev/null +++ b/editor/io_plugins/editor_scene_import_plugin.cpp @@ -0,0 +1,2992 @@ +/*************************************************************************/ +/* editor_scene_import_plugin.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 "editor_scene_import_plugin.h" +#if 0 +#include "global_config.h" +#include "editor/editor_node.h" +#include "scene/resources/packed_scene.h" +#include "scene/resources/box_shape.h" +#include "os/file_access.h" +#include "scene/3d/path.h" +#include "scene/animation/animation_player.h" +#include "io/resource_saver.h" +#include "scene/3d/mesh_instance.h" +#include "scene/3d/navigation.h" +#include "scene/3d/room_instance.h" +#include "scene/3d/body_shape.h" +#include "scene/3d/physics_body.h" +#include "scene/3d/portal.h" +#include "scene/3d/vehicle_body.h" +#include "scene/resources/sphere_shape.h" +#include <scene/resources/box_shape.h> +#include <scene/resources/ray_shape.h> +#include <scene/resources/plane_shape.h> +#include "editor/create_dialog.h" +#include "os/os.h" + + + + +EditorSceneImporter::EditorSceneImporter() { + + +} + +void EditorScenePostImport::_bind_methods() { + + BIND_VMETHOD( MethodInfo("post_import",PropertyInfo(Variant::OBJECT,"scene")) ); + +} + +Node *EditorScenePostImport::post_import(Node* p_scene) { + + if (get_script_instance()) + return get_script_instance()->call("post_import",p_scene); + + return p_scene; +} + +EditorScenePostImport::EditorScenePostImport() { + + +} + + +///////////////////////////// + + +class EditorImportAnimationOptions : public VBoxContainer { + + GDCLASS( EditorImportAnimationOptions, VBoxContainer ); + + + + TreeItem *fps; + TreeItem* optimize_linear_error; + TreeItem* optimize_angular_error; + TreeItem* optimize_max_angle; + + TreeItem *clips_base; + + TextEdit *filters; + Vector<TreeItem*> clips; + + Tree *flags; + Tree *clips_tree; + Tree *optimization_tree; + Vector<TreeItem*> items; + + + bool updating; + bool validating; + + + + void _changed(); + void _item_edited(); + void _button_action(Object *p_obj,int p_col,int p_id); + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: + + void set_flags(uint32_t p_flags); + uint32_t get_flags() const; + + void set_fps(int p_fps); + int get_fps() const; + + void set_optimize_linear_error(float p_error); + float get_optimize_linear_error() const; + + void set_optimize_angular_error(float p_error); + float get_optimize_angular_error() const; + + void set_optimize_max_angle(float p_error); + float get_optimize_max_angle() const; + + void setup_clips(const Array& p_clips); + Array get_clips() const; + + void set_filter(const String& p_filter); + String get_filter() const; + + EditorImportAnimationOptions(); + + +}; + +//////////////////////////// + +class EditorSceneImportDialog : public ConfirmationDialog { + + GDCLASS(EditorSceneImportDialog,ConfirmationDialog); + + + struct FlagInfo { + int value; + const char *category; + const char *text; + bool defval; + }; + + static const FlagInfo scene_flag_names[]; + + EditorImportTextureOptions *texture_options; + EditorImportAnimationOptions *animation_options; + + EditorSceneImportPlugin *plugin; + + EditorNode *editor; + + LineEdit *import_path; + LineEdit *save_path; + LineEdit *script_path; + Tree *import_options; + EditorFileDialog *file_select; + EditorFileDialog *script_select; + EditorDirDialog *save_select; + OptionButton *texture_action; + CreateDialog *root_type_choose; + LineEdit *root_node_name; + + ConfirmationDialog *confirm_open; + + ConfirmationDialog *confirm_import; + RichTextLabel *missing_files; + + Vector<TreeItem*> scene_flags; + + Map<Ref<Mesh>,Ref<Shape> > collision_map; + ConfirmationDialog *error_dialog; + + Button *root_type; + CheckBox *root_default; + + + void _root_default_pressed(); + void _root_type_pressed(); + void _set_root_type(); + + void _choose_file(const String& p_path); + void _choose_save_file(const String& p_path); + void _choose_script(const String& p_path); + void _browse(); + void _browse_target(); + void _browse_script(); + void _import(bool p_and_open=false); + void _import_confirm(); + + Ref<ResourceImportMetadata> wip_rimd; + Node *wip_import; + String wip_save_file; + bool wip_blocked; + bool wip_open; + + void _dialog_hid(); + void _open_and_import(); + + +protected: + + void _notification(int p_what); + static void _bind_methods(); +public: + + void setup_popup(const String& p_from,const String& p_to_path) { + _choose_file(p_from); + _choose_save_file(p_to_path); + } + + Error import(const String& p_from, const String& p_to, const String& p_preset); + void popup_import(const String& p_from); + EditorSceneImportDialog(EditorNode *p_editor,EditorSceneImportPlugin *p_plugin); +}; + +/////////////////////////////////// + + +static const char *anim_flag_names[]={ + "Detect Loop (-loop,-cycle)", + "Keep Value Tracks", + "Optimize", + "Force All Tracks in All Clips", + NULL +}; + +static const char *anim_flag_descript[]={ + "Set loop flag for animation names that\ncontain 'cycle' or 'loop' in the name.", + "When merging an existing aimation,\nkeep the user-created value-tracks.", + "Remove redundant keyframes in\n transform tacks.", + "Some exporters will rely on default pose for some bones.\nThis forces those bones to have at least one animation key.", + NULL +}; + + + +void EditorImportAnimationOptions::set_flags(uint32_t p_flags){ + + updating=true; + for(int i=0;i<items.size();i++) { + + items[i]->set_checked(0,p_flags&(1<<i)); + } + updating=false; + +} +uint32_t EditorImportAnimationOptions::get_flags() const{ + + uint32_t f=0; + for(int i=0;i<items.size();i++) { + + if (items[i]->is_checked(0)) + f|=(1<<i); + } + + return f; +} + + +void EditorImportAnimationOptions::_changed() { + + if (updating) + return; + emit_signal("changed"); +} + + +void EditorImportAnimationOptions::_button_action(Object *p_obj,int p_col,int p_id) { + + memdelete(p_obj); + +} + + +void EditorImportAnimationOptions::_item_edited() { + + if (validating) + return; + + if (clips.size()==0) + return; + validating=true; + print_line("edited"); + TreeItem *item = clips_tree->get_edited(); + if (item==clips[clips.size()-1]) { + //add new + print_line("islast"); + if (item->get_text(0).find("<")!=-1 || item->get_text(0).find(">")!=-1) { + validating=false; + return; //fuckit + } + + item->set_editable(1,true); + item->set_editable(2,true); + item->add_button(0,EditorNode::get_singleton()->get_gui_base()->get_icon("Del","EditorIcons")); + item->set_cell_mode(1,TreeItem::CELL_MODE_RANGE); + item->set_range_config(1,0,3600,0.01); + item->set_range(1,0); + item->set_editable(1,true); + item->set_cell_mode(2,TreeItem::CELL_MODE_RANGE); + item->set_range_config(2,0,3600,0.01); + item->set_range(2,0); + item->set_cell_mode(3,TreeItem::CELL_MODE_CHECK); + item->set_editable(3,true); + + TreeItem *newclip = clips_tree->create_item(clips_base); + newclip->set_text(0,"<new clip>"); + newclip->set_editable(0,true); + newclip->set_editable(1,false); + newclip->set_editable(2,false); + clips.push_back(newclip); + + + + } + + + //make name unique JUST IN CASE + String name = item->get_text(0); + name=name.replace("/","_").replace(":","_").strip_edges(); + if (name=="") + name=TTR("New Clip"); + + if (clips.size()>2) { + int index=1; + while(true) { + bool valid = true; + String try_name=name; + if (index>1) + try_name+=" "+itos(index); + + for(int i=0;i<clips.size()-1;i++) { + + if (clips[i]==item) + continue; + if (clips[i]->get_text(0)==try_name) { + index++; + valid=false; + break; + } + } + + if (valid) { + name=try_name; + break; + } + + } + } + + if (item->get_text(0)!=name) + item->set_text(0,name); + + validating=false; + +} + +void EditorImportAnimationOptions::_bind_methods() { + + ClassDB::bind_method("_changed",&EditorImportAnimationOptions::_changed); + ClassDB::bind_method("_item_edited",&EditorImportAnimationOptions::_item_edited); + ClassDB::bind_method("_button_action",&EditorImportAnimationOptions::_button_action); + //ClassDB::bind_method("_changedp",&EditorImportAnimationOptions::_changedp); + + ADD_SIGNAL(MethodInfo("changed")); +} + + +void EditorImportAnimationOptions::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + + flags->connect("item_edited",this,"_changed"); + clips_tree->connect("item_edited",this,"_item_edited"); + clips_tree->connect("button_pressed",this,"_button_action",varray(),CONNECT_DEFERRED); + //format->connect("item_selected",this,"_changedp"); + } +} + + +Array EditorImportAnimationOptions::get_clips() const { + + Array arr; + for(int i=0;i<clips.size()-1;i++) { + + arr.push_back(clips[i]->get_text(0)); + arr.push_back(clips[i]->get_range(1)); + arr.push_back(clips[i]->get_range(2)); + arr.push_back(clips[i]->is_checked(3)); + } + + return arr; +} + + +void EditorImportAnimationOptions::setup_clips(const Array& p_clips) { + + ERR_FAIL_COND(p_clips.size()%4!=0); + for(int i=0;i<clips.size();i++) { + + memdelete(clips[i]); + } + + + clips.clear(); + + for(int i=0;i<p_clips.size();i+=4) { + + TreeItem *clip = clips_tree->create_item(clips_base); + clip->set_text(0,p_clips[i]); + clip->add_button(0,EditorNode::get_singleton()->get_gui_base()->get_icon("Del","EditorIcons")); + clip->set_editable(0,true); + clip->set_cell_mode(1,TreeItem::CELL_MODE_RANGE); + clip->set_range_config(1,0,3600,0.01); + clip->set_range(1,p_clips[i+1]); + clip->set_editable(1,true); + clip->set_cell_mode(2,TreeItem::CELL_MODE_RANGE); + clip->set_range_config(2,0,3600,0.01); + clip->set_range(2,p_clips[i+2]); + clip->set_editable(2,true); + clip->set_cell_mode(3,TreeItem::CELL_MODE_CHECK); + clip->set_editable(3,true); + clip->set_checked(3,p_clips[i+3]); + clips.push_back(clip); + + } + + TreeItem *newclip = clips_tree->create_item(clips_base); + newclip->set_text(0,"<new clip>"); + newclip->set_editable(0,true); + newclip->set_editable(1,false); + newclip->set_editable(2,false); + newclip->set_editable(3,false); + clips.push_back(newclip); + +} + + +EditorImportAnimationOptions::EditorImportAnimationOptions() { + + + updating=false; + validating=false; + + TabContainer *tab= memnew(TabContainer); + add_margin_child(TTR("Animation Options"),tab,true); + + flags = memnew( Tree ); + flags->set_hide_root(true); + tab->add_child(flags); + flags->set_name(TTR("Flags")); + TreeItem *root = flags->create_item(); + + const char ** fname=anim_flag_names; + const char ** fdescr=anim_flag_descript; + + while( *fname ) { + + TreeItem*ti = flags->create_item(root); + ti->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); + ti->set_text(0,*fname); + ti->set_editable(0,true); + ti->set_tooltip(0,*fdescr); + items.push_back(ti); + fname++; + fdescr++; + } + + + TreeItem *fps_base = flags->create_item(root); + fps_base->set_text(0,TTR("Bake FPS:")); + fps_base->set_editable(0,false); + fps = flags->create_item(fps_base); + fps->set_cell_mode(0,TreeItem::CELL_MODE_RANGE); + fps->set_editable(0,true); + fps->set_range_config(0,1,120,1); + fps->set_range(0,15); + + optimization_tree = memnew( Tree ); + optimization_tree->set_columns(2); + tab->add_child(optimization_tree); + optimization_tree->set_name(TTR("Optimizer")); + optimization_tree->set_column_expand(0,true); + optimization_tree->set_column_expand(1,false); + optimization_tree->set_column_min_width(1,80); + optimization_tree->set_hide_root(true); + + + TreeItem *optimize_root = optimization_tree->create_item(); + + optimize_linear_error = optimization_tree->create_item(optimize_root); + optimize_linear_error->set_text(0,TTR("Max Linear Error")); + optimize_linear_error->set_cell_mode(1,TreeItem::CELL_MODE_RANGE); + optimize_linear_error->set_editable(1,true); + optimize_linear_error->set_range_config(1,0,1,0.001); + optimize_linear_error->set_range(1,0.05); + + optimize_angular_error = optimization_tree->create_item(optimize_root); + optimize_angular_error->set_text(0,TTR("Max Angular Error")); + optimize_angular_error->set_cell_mode(1,TreeItem::CELL_MODE_RANGE); + optimize_angular_error->set_editable(1,true); + optimize_angular_error->set_range_config(1,0,1,0.001); + optimize_angular_error->set_range(1,0.01); + + optimize_max_angle = optimization_tree->create_item(optimize_root); + optimize_max_angle->set_text(0,TTR("Max Angle")); + optimize_max_angle->set_cell_mode(1,TreeItem::CELL_MODE_RANGE); + optimize_max_angle->set_editable(1,true); + optimize_max_angle->set_range_config(1,0,360,0.001); + optimize_max_angle->set_range(1,int(180*0.125)); + + clips_tree = memnew( Tree ); + clips_tree->set_hide_root(true); + tab->add_child(clips_tree); + clips_tree->set_name(TTR("Clips")); + + clips_tree->set_columns(4); + clips_tree->set_column_expand(0,1); + clips_tree->set_column_expand(1,0); + clips_tree->set_column_expand(2,0); + clips_tree->set_column_expand(3,0); + clips_tree->set_column_min_width(1,60); + clips_tree->set_column_min_width(2,60); + clips_tree->set_column_min_width(3,40); + clips_tree->set_column_titles_visible(true); + clips_tree->set_column_title(0,TTR("Name")); + clips_tree->set_column_title(1,TTR("Start(s)")); + clips_tree->set_column_title(2,TTR("End(s)")); + clips_tree->set_column_title(3,TTR("Loop")); + clips_base =clips_tree->create_item(0); + + + setup_clips(Array()); + + + filters = memnew( TextEdit ); + tab->add_child(filters); + filters->set_name(TTR("Filters")); +} + + + +void EditorImportAnimationOptions::set_fps(int p_fps) { + + fps->set_range(0,p_fps); +} + +int EditorImportAnimationOptions::get_fps() const { + + return fps->get_range(0); +} + + +void EditorImportAnimationOptions::set_optimize_linear_error(float p_optimize_linear_error) { + + optimize_linear_error->set_range(1,p_optimize_linear_error); +} + +float EditorImportAnimationOptions::get_optimize_linear_error() const { + + return optimize_linear_error->get_range(1); +} + +void EditorImportAnimationOptions::set_optimize_angular_error(float p_optimize_angular_error) { + + optimize_angular_error->set_range(1,p_optimize_angular_error); +} + +float EditorImportAnimationOptions::get_optimize_angular_error() const { + + return optimize_angular_error->get_range(1); +} + +void EditorImportAnimationOptions::set_optimize_max_angle(float p_optimize_max_angle) { + + optimize_max_angle->set_range(1,p_optimize_max_angle); +} + +float EditorImportAnimationOptions::get_optimize_max_angle() const { + + return optimize_max_angle->get_range(1); +} + + +void EditorImportAnimationOptions::set_filter(const String& p_filter) { + + filters->set_text(p_filter); +} + +String EditorImportAnimationOptions::get_filter() const { + + return filters->get_text(); +} + + + + + +//////////////////////////////////////////////////////// + + + +void EditorSceneImportDialog::_choose_file(const String& p_path) { +#if 0 + StringName sn = EditorImportDB::get_singleton()->find_source_path(p_path); + if (sn!=StringName()) { + + EditorImportDB::ImportScene isc; + if (EditorImportDB::get_singleton()->get_scene(sn,isc)==OK) { + + save_path->set_text(String(sn).get_base_dir()); + texture_options->set_flags( isc.image_flags ); + texture_options->set_quality( isc.image_quality ); + texture_options->set_format( isc.image_format ); + animation_options->set_flags( isc.anim_flags ); + script_path->set_text( isc.import_script ); + uint32_t f = isc.flags; + for(int i=0;i<scene_flags.size();i++) { + + scene_flags[i]->set_checked(0,f&(1<<i)); + } + } + } else { +#endif + save_path->set_text(""); + root_node_name->set_text(""); + //save_path->set_text(p_path.get_file().basename()+".scn"); +#if 0 + } +#endif + + if (p_path!=String()) { + + String from_path = EditorFileSystem::get_singleton()->find_resource_from_source(EditorImportPlugin::validate_source_path(p_path)); + print_line("from path.."+from_path); + if (from_path!=String()) { + popup_import(from_path); + + } + } + + + import_path->set_text(p_path); + if (root_node_name->get_text().size()==0){ + root_node_name->set_text(import_path->get_text().get_file().get_basename()); + } + +} +void EditorSceneImportDialog::_choose_save_file(const String& p_path) { + + save_path->set_text(p_path); +} + +void EditorSceneImportDialog::_choose_script(const String& p_path) { + + String p = GlobalConfig::get_singleton()->localize_path(p_path); + if (!p.is_resource_file()) + p=GlobalConfig::get_singleton()->get_resource_path().path_to(p_path.get_base_dir())+p_path.get_file(); + script_path->set_text(p); + +} + + +void EditorSceneImportDialog::_open_and_import() { + + bool unsaved=EditorNode::has_unsaved_changes(); + + if (unsaved) { + + confirm_open->popup_centered_minsize(Size2(300,80)*EDSCALE); + } else { + _import(true); + } +} + +void EditorSceneImportDialog::_import(bool p_and_open) { + + wip_open=p_and_open; +//' ImportMonitorBlock imb; + + + if (import_path->get_text().strip_edges()=="") { + error_dialog->set_text(TTR("Source path is empty.")); + error_dialog->popup_centered_minsize(); + return; + } + + if (save_path->get_text().strip_edges()=="") { + error_dialog->set_text(TTR("Target path is empty.")); + error_dialog->popup_centered_minsize(); + return; + } + + if (!save_path->get_text().begins_with("res://")) { + error_dialog->set_text(TTR("Target path must be a complete resource path.")); + error_dialog->popup_centered_minsize(); + return; + } + + if (!DirAccess::exists(save_path->get_text())) { + error_dialog->set_text(TTR("Target path must exist.")); + error_dialog->popup_centered_minsize(); + return; + } + + String dst_path; + + if (texture_action->get_selected()==0) + dst_path=save_path->get_text();//.get_base_dir(); + else + dst_path=GlobalConfig::get_singleton()->get("import/shared_textures"); + + uint32_t flags=0; + + for(int i=0;i<scene_flags.size();i++) { + + if (scene_flags[i]->is_checked(0)) { + int md = scene_flags[i]->get_metadata(0); + flags|=md; + } + } + + + + + + if (script_path->get_text()!="") { + Ref<Script> scr = ResourceLoader::load(script_path->get_text()); + if (!scr.is_valid()) { + error_dialog->set_text(TTR("Couldn't load post-import script.")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + } + + Ref<EditorScenePostImport> pi = Ref<EditorScenePostImport>( memnew( EditorScenePostImport ) ); + pi->set_script(scr.get_ref_ptr()); + if (!pi->get_script_instance()) { + + error_dialog->set_text(TTR("Invalid/broken script for post-import.")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + } + + } + + + // Scenes should always be imported as binary format since vertex data is large and would take + // up a lot of space and time to load if imported as text format (GH-5778) + String save_file = save_path->get_text().plus_file(import_path->get_text().get_file().get_basename()+".scn"); + print_line("Saving to: "+save_file); + + + + + + Node *scene=NULL; + + + Ref<ResourceImportMetadata> rim = memnew( ResourceImportMetadata ); + + rim->add_source(EditorImportPlugin::validate_source_path(import_path->get_text())); + rim->set_option("flags",flags); + print_line("GET FLAGS: "+itos(texture_options->get_flags())); + rim->set_option("texture_flags",texture_options->get_flags()); + rim->set_option("texture_format",texture_options->get_format()); + rim->set_option("texture_quality",texture_options->get_quality()); + rim->set_option("animation_flags",animation_options->get_flags()); + rim->set_option("animation_bake_fps",animation_options->get_fps()); + rim->set_option("animation_optimizer_linear_error",animation_options->get_optimize_linear_error()); + rim->set_option("animation_optimizer_angular_error",animation_options->get_optimize_angular_error()); + rim->set_option("animation_optimizer_max_angle",animation_options->get_optimize_max_angle()); + rim->set_option("animation_filters",animation_options->get_filter()); + rim->set_option("animation_clips",animation_options->get_clips()); + rim->set_option("post_import_script",script_path->get_text()); + rim->set_option("reimport",true); + if (!root_default->is_pressed()) { + rim->set_option("root_type",root_type->get_text()); + } + if (root_node_name->get_text().size()==0) { + root_node_name->set_text(import_path->get_text().get_file().get_basename()); + } + rim->set_option("root_name",root_node_name->get_text()); + + List<String> missing; + Error err = plugin->import1(rim,&scene,&missing); + + if (err || !scene) { + + error_dialog->set_text(TTR("Error importing scene.")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + } + + if (missing.size()) { + + missing_files->clear(); + for(List<String>::Element *E=missing.front();E;E=E->next()) { + + missing_files->add_text(E->get()); + missing_files->add_newline(); + } + wip_import=scene; + wip_rimd=rim; + wip_save_file=save_file; + confirm_import->popup_centered_ratio(); + return; + + } else { + + err = plugin->import2(scene,save_file,rim); + + if (err) { + + error_dialog->set_text(TTR("Error importing scene.")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + } + if (wip_open) + EditorNode::get_singleton()->load_scene(save_file,false,false,false); + + } + + hide(); + + /* + editor->clear_scene(); + + Error err = EditorImport::import_scene(import_path->get_text(),save_file,dst_path,flags,texture_options->get_format(),compression,texture_options->get_flags(),texture_options->get_quality(),animation_options->get_flags(), &scene,pi); + + if (err) { + + error_dialog->set_text("Error importing scene."); + error_dialog->popup_centered(Size2(200,100)); + return; + } + + editor->save_import_export(); + if (scene) + editor->set_edited_scene(scene); + + hide(); + */ +}; + + +void EditorSceneImportDialog::_import_confirm() { + + wip_blocked=true; + print_line("import confirm!"); + Error err = plugin->import2(wip_import,wip_save_file,wip_rimd); + wip_blocked=false; + wip_import=NULL; + wip_rimd=Ref<ResourceImportMetadata>(); + confirm_import->hide(); + if (err) { + + wip_save_file=""; + error_dialog->set_text(TTR("Error importing scene.")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + } + + if (wip_open) + EditorNode::get_singleton()->load_scene(wip_save_file,false,false,false); + wip_open=false; + wip_save_file=""; + + hide(); + +} + + +void EditorSceneImportDialog::_browse() { + + file_select->popup_centered_ratio(); +} + +void EditorSceneImportDialog::_browse_target() { + + save_select->popup_centered_ratio(); + if (save_path->get_text()!="") + save_select->set_current_path(save_path->get_text()); + +} + +void EditorSceneImportDialog::_browse_script() { + + script_select->popup_centered_ratio(); + +} + +void EditorSceneImportDialog::popup_import(const String &p_from) { + + popup_centered(Size2(750,550)*EDSCALE); + if (p_from!="") { + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from); + if (rimd.is_null()) + return; + + int flags = rimd->get_option("flags"); + + for(int i=0;i<scene_flags.size();i++) { + + int md = scene_flags[i]->get_metadata(0); + scene_flags[i]->set_checked(0,flags&md); + } + + texture_options->set_flags(rimd->get_option("texture_flags")); + texture_options->set_format(EditorTextureImportPlugin::ImageFormat(int(rimd->get_option("texture_format")))); + texture_options->set_quality(rimd->get_option("texture_quality")); + animation_options->set_flags(rimd->get_option("animation_flags")); + if (rimd->has_option("animation_clips")) + animation_options->setup_clips(rimd->get_option("animation_clips")); + if (rimd->has_option("animation_filters")) + animation_options->set_filter(rimd->get_option("animation_filters")); + if (rimd->has_option("animation_bake_fps")) + animation_options->set_fps(rimd->get_option("animation_bake_fps")); + if (rimd->has_option("animation_optimizer_linear_error")) + animation_options->set_optimize_linear_error(rimd->get_option("animation_optimizer_linear_error")); + if (rimd->has_option("animation_optimizer_angular_error")) + animation_options->set_optimize_angular_error(rimd->get_option("animation_optimizer_angular_error")); + if (rimd->has_option("animation_optimizer_max_angle")) + animation_options->set_optimize_max_angle(rimd->get_option("animation_optimizer_max_angle")); + + if (rimd->has_option("root_type")) { + root_default->set_pressed(false); + String type = rimd->get_option("root_type"); + root_type->set_text(type); + root_type->set_disabled(false); + + if (has_icon(type,"EditorIcons")) { + root_type->set_icon(get_icon(type,"EditorIcons")); + } else { + root_type->set_icon(get_icon("Object","EditorIcons")); + } + + } else { + root_default->set_pressed(true); + root_type->set_disabled(true); + } + if (rimd->has_option("root_name")) { + root_node_name->set_text(rimd->get_option("root_name")); + } else { + root_node_name->set_text(root_type->get_text()); // backward compatibility for 2.1 or before + } + script_path->set_text(rimd->get_option("post_import_script")); + + save_path->set_text(p_from.get_base_dir()); + import_path->set_text(EditorImportPlugin::expand_source_path(rimd->get_source_path(0))); + + } +} + + +void EditorSceneImportDialog::_notification(int p_what) { + + + if (p_what==NOTIFICATION_ENTER_TREE) { + + + List<String> extensions; + file_select->clear_filters(); + root_type->set_icon(get_icon("Spatial","EditorIcons")); + root_type->set_text("Spatial"); + root_type->set_disabled(true); + + for(int i=0;i<plugin->get_importers().size();i++) { + plugin->get_importers()[i]->get_extensions(&extensions); + } + + + for(int i=0;i<extensions.size();i++) { + + file_select->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); + } + + extensions.clear(); + + //EditorImport::get_import_extensions(&extensions) + /* ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions); + save_select->clear_filters(); + for(int i=0;i<extensions.size();i++) { + + save_select->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); + }*/ + + + } +} + +Error EditorSceneImportDialog::import(const String& p_from, const String& p_to, const String& p_preset) { + + import_path->set_text(p_from); + save_path->set_text(p_to); + script_path->set_text(p_preset); + + _import(); + + + + return OK; +} + +void EditorSceneImportDialog::_dialog_hid() { + + if (wip_blocked) + return; + print_line("DIALOGHID!"); + if (wip_import) { + memdelete(wip_import); + wip_import=NULL; + wip_save_file=""; + wip_rimd=Ref<ResourceImportMetadata>(); + } +} +void EditorSceneImportDialog::_root_default_pressed() { + + root_type->set_disabled(root_default->is_pressed()); +} + +void EditorSceneImportDialog::_root_type_pressed() { + + + root_type_choose->popup(false); +} + + +void EditorSceneImportDialog::_set_root_type() { + + String type = root_type_choose->get_selected_type(); + if (type==String()) + return; + root_type->set_text(type); + if (has_icon(type,"EditorIcons")) { + root_type->set_icon(get_icon(type,"EditorIcons")); + } else { + root_type->set_icon(get_icon("Object","EditorIcons")); + } +} + +void EditorSceneImportDialog::_bind_methods() { + + + ClassDB::bind_method("_choose_file",&EditorSceneImportDialog::_choose_file); + ClassDB::bind_method("_choose_save_file",&EditorSceneImportDialog::_choose_save_file); + ClassDB::bind_method("_choose_script",&EditorSceneImportDialog::_choose_script); + ClassDB::bind_method("_import",&EditorSceneImportDialog::_import,DEFVAL(false)); + ClassDB::bind_method("_browse",&EditorSceneImportDialog::_browse); + ClassDB::bind_method("_browse_target",&EditorSceneImportDialog::_browse_target); + ClassDB::bind_method("_browse_script",&EditorSceneImportDialog::_browse_script); + ClassDB::bind_method("_dialog_hid",&EditorSceneImportDialog::_dialog_hid); + ClassDB::bind_method("_import_confirm",&EditorSceneImportDialog::_import_confirm); + ClassDB::bind_method("_open_and_import",&EditorSceneImportDialog::_open_and_import); + ClassDB::bind_method("_root_default_pressed",&EditorSceneImportDialog::_root_default_pressed); + ClassDB::bind_method("_root_type_pressed",&EditorSceneImportDialog::_root_type_pressed); + ClassDB::bind_method("_set_root_type",&EditorSceneImportDialog::_set_root_type); + + + ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); +} + + + +const EditorSceneImportDialog::FlagInfo EditorSceneImportDialog::scene_flag_names[]={ + + {EditorSceneImportPlugin::SCENE_FLAG_REMOVE_NOIMP,("Actions"),"Remove Nodes (-noimp)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_IMPORT_ANIMATIONS,("Actions"),"Import Animations",true}, + {EditorSceneImportPlugin::SCENE_FLAG_COMPRESS_GEOMETRY,("Actions"),"Compress Geometry",false}, + {EditorSceneImportPlugin::SCENE_FLAG_GENERATE_TANGENT_ARRAYS,("Actions"),"Force Generation of Tangent Arrays",false}, + {EditorSceneImportPlugin::SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES,("Actions"),"SRGB->Linear Of Diffuse Textures",false}, + {EditorSceneImportPlugin::SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY,("Actions"),"Convert Normal Maps to XY",true}, + {EditorSceneImportPlugin::SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS,("Actions"),"Set Material Lightmap to UV2 if Tex2Array Exists",true}, + {EditorSceneImportPlugin::SCENE_FLAG_MERGE_KEEP_MATERIALS,("Merge"),"Keep Materials after first import (delete them for re-import).",true}, + {EditorSceneImportPlugin::SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS,("Merge"),"Keep user-added Animation tracks.",true}, + {EditorSceneImportPlugin::SCENE_FLAG_DETECT_ALPHA,("Materials"),"Set Alpha in Materials (-alpha)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_DETECT_VCOLOR,("Materials"),"Set Vert. Color in Materials (-vcol)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_COLLISIONS,("Create"),"Create Collisions and/or Rigid Bodies (-col,-colonly,-rigid)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_PORTALS,("Create"),"Create Portals (-portal)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_ROOMS,("Create"),"Create Rooms (-room)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_SIMPLIFY_ROOMS,("Create"),"Simplify Rooms",false}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_BILLBOARDS,("Create"),"Create Billboards (-bb)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_IMPOSTORS,("Create"),"Create Impostors (-imp:dist)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_LODS,("Create"),"Create LODs (-lod:dist)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_CARS,("Create"),"Create Vehicles (-vehicle)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_WHEELS,("Create"),"Create Vehicle Wheels (-wheel)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_NAVMESH,("Create"),"Create Navigation Meshes (-navmesh)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_DETECT_LIGHTMAP_LAYER,("Create"),"Detect LightMap Layer (-lm:<int>).",true}, + {-1,NULL,NULL,false} +}; + + +EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSceneImportPlugin *p_plugin) { + + + editor=p_editor; + plugin=p_plugin; + + set_title(TTR("Import 3D Scene")); + HBoxContainer *import_hb = memnew( HBoxContainer ); + add_child(import_hb); + //set_child_rect(import_hb); + + VBoxContainer *vbc = memnew( VBoxContainer ); + import_hb->add_child(vbc); + vbc->set_h_size_flags(SIZE_EXPAND_FILL); + + HBoxContainer *hbc = memnew( HBoxContainer ); + vbc->add_margin_child(TTR("Source Scene:"),hbc); + + import_path = memnew( LineEdit ); + import_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(import_path); + + Button * import_choose = memnew( Button ); + import_choose->set_text(" .. "); + hbc->add_child(import_choose); + + import_choose->connect("pressed", this,"_browse"); + + hbc = memnew( HBoxContainer ); + vbc->add_margin_child(TTR("Target Path:"),hbc); + + save_path = memnew( LineEdit ); + save_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(save_path); + + Button * save_choose = memnew( Button ); + save_choose->set_text(" .. "); + hbc->add_child(save_choose); + + save_choose->connect("pressed", this,"_browse_target"); + + texture_action = memnew( OptionButton ); + texture_action->add_item(TTR("Same as Target Scene")); + texture_action->add_item(TTR("Shared")); + texture_action->select(0); + vbc->add_margin_child(TTR("Target Texture Folder:"),texture_action); + + import_options = memnew( Tree ); + vbc->set_v_size_flags(SIZE_EXPAND_FILL); + vbc->add_margin_child(TTR("Options:"),import_options,true); + + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + add_child(file_select); + + + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); + + file_select->connect("file_selected", this,"_choose_file"); + + save_select = memnew(EditorDirDialog); + add_child(save_select); + + //save_select->set_mode(EditorFileDialog::MODE_SAVE_FILE); + save_select->connect("dir_selected", this,"_choose_save_file"); + + get_ok()->connect("pressed", this,"_import"); + get_ok()->set_text(TTR("Import")); + + TreeItem *root = import_options->create_item(NULL); + import_options->set_hide_root(true); + + const FlagInfo* fn=scene_flag_names; + + Map<String,TreeItem*> categories; + + while(fn->text) { + + String cat = fn->category; + TreeItem *parent; + if (!categories.has(cat)) { + parent = import_options->create_item(root); + parent->set_text(0,cat); + categories[cat]=parent; + } else { + parent=categories[cat]; + } + + TreeItem *opt = import_options->create_item(parent); + opt->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); + opt->set_checked(0,fn->defval); + opt->set_editable(0,true); + opt->set_text(0,fn->text); + opt->set_metadata(0,fn->value); + + scene_flags.push_back(opt); + fn++; + } + + hbc = memnew( HBoxContainer ); + vbc->add_margin_child(TTR("Post-Process Script:"),hbc); + + script_path = memnew( LineEdit ); + script_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(script_path); + + Button * script_choose = memnew( Button ); + script_choose->set_text(" .. "); + hbc->add_child(script_choose); + + script_choose->connect("pressed", this,"_browse_script"); + + script_select = memnew(EditorFileDialog); + add_child(script_select); + for(int i=0;i<ScriptServer::get_language_count();i++) { + + ScriptLanguage *sl=ScriptServer::get_language(i); + String ext = sl->get_extension(); + if (ext=="") + continue; + script_select->add_filter("*."+ext+" ; "+sl->get_name()); + } + + + script_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); + + script_select->connect("file_selected", this,"_choose_script"); + + error_dialog = memnew ( ConfirmationDialog ); + add_child(error_dialog); + error_dialog->get_ok()->set_text(TTR("Accept")); + //error_dialog->get_cancel()->hide(); + + + HBoxContainer *custom_root_hb = memnew( HBoxContainer ); + vbc->add_margin_child(TTR("Custom Root Node Type:"),custom_root_hb); + root_type = memnew(Button); + root_type->set_h_size_flags(SIZE_EXPAND_FILL); + root_type->set_text_align(Button::ALIGN_LEFT); + root_type->connect("pressed",this,"_root_type_pressed"); + custom_root_hb->add_child(root_type); + + root_default = memnew(CheckBox); + root_default->set_text(TTR("Auto")); + root_default->set_pressed(true); + root_default->connect("pressed",this,"_root_default_pressed"); + custom_root_hb->add_child(root_default); + + root_node_name = memnew( LineEdit ); + root_node_name->set_h_size_flags(SIZE_EXPAND_FILL); + vbc->add_margin_child(TTR("Root Node Name:"),root_node_name); + /* + this_import = memnew( OptionButton ); + this_import->add_item("Overwrite Existing Scene"); + this_import->add_item("Overwrite Existing, Keep Materials"); + this_import->add_item("Keep Existing, Merge with New"); + this_import->add_item("Keep Existing, Ignore New"); + vbc->add_margin_child("This Time:",this_import); + + next_import = memnew( OptionButton ); + next_import->add_item("Overwrite Existing Scene"); + next_import->add_item("Overwrite Existing, Keep Materials"); + next_import->add_item("Keep Existing, Merge with New"); + next_import->add_item("Keep Existing, Ignore New"); + vbc->add_margin_child("Next Time:",next_import); +*/ + set_hide_on_ok(false); + + GLOBAL_DEF("import/shared_textures","res://"); + GlobalConfig::get_singleton()->set_custom_property_info("import/shared_textures",PropertyInfo(Variant::STRING,"import/shared_textures",PROPERTY_HINT_DIR)); + + import_hb->add_constant_override("separation",30); + + + VBoxContainer *ovb = memnew( VBoxContainer); + ovb->set_h_size_flags(SIZE_EXPAND_FILL); + import_hb->add_child(ovb); + + texture_options = memnew( EditorImportTextureOptions ); + ovb->add_child(texture_options); + texture_options->set_v_size_flags(SIZE_EXPAND_FILL); + //animation_options->set_flags(EditorImport:: + texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM); + texture_options->set_flags( EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA | EditorTextureImportPlugin::IMAGE_FLAG_REPEAT | EditorTextureImportPlugin::IMAGE_FLAG_FILTER ); + + + animation_options = memnew( EditorImportAnimationOptions ); + ovb->add_child(animation_options); + animation_options->set_v_size_flags(SIZE_EXPAND_FILL); + animation_options->set_flags(EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP|EditorSceneAnimationImportPlugin::ANIMATION_KEEP_VALUE_TRACKS|EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE|EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS); + + + confirm_import = memnew( ConfirmationDialog ); + add_child(confirm_import); + VBoxContainer *cvb = memnew( VBoxContainer ); + confirm_import->add_child(cvb); + //confirm_import->set_child_rect(cvb); + + PanelContainer *pc = memnew( PanelContainer ); + pc->add_style_override("panel",get_stylebox("normal","TextEdit")); + //ec->add_child(pc); + missing_files = memnew( RichTextLabel ); + cvb->add_margin_child(TTR("The Following Files are Missing:"),pc,true); + pc->add_child(missing_files); + confirm_import->get_ok()->set_text(TTR("Import Anyway")); + confirm_import->get_cancel()->set_text(TTR("Cancel")); + confirm_import->connect("popup_hide",this,"_dialog_hid"); + confirm_import->connect("confirmed",this,"_import_confirm"); + confirm_import->set_hide_on_ok(false); + + add_button(TTR("Import & Open"),!OS::get_singleton()->get_swap_ok_cancel())->connect("pressed",this,"_open_and_import"); + + confirm_open = memnew( ConfirmationDialog ); + add_child(confirm_open); + confirm_open->set_text(TTR("Edited scene has not been saved, open imported scene anyway?")); + confirm_open->connect("confirmed",this,"_import",varray(true)); + + + wip_import=NULL; + wip_blocked=false; + wip_open=false; + //texture_options->set_format(EditorImport::IMAGE_FORMAT_C); + + root_type_choose = memnew( CreateDialog ); + add_child(root_type_choose); + root_type_choose->set_base_type("Node"); + root_type_choose->connect("create",this,"_set_root_type"); +} + + + +//////////////////////////////// + + + +String EditorSceneImportPlugin::get_name() const { + + return "scene_3d"; +} + +String EditorSceneImportPlugin::get_visible_name() const{ + + return TTR("Scene"); +} + +void EditorSceneImportPlugin::import_dialog(const String& p_from){ + + dialog->popup_import(p_from); +} + + +////////////////////////// + + +static bool _teststr(const String& p_what,const String& p_str) { + + if (p_what.findn("$"+p_str)!=-1) //blender and other stuff + return true; + if (p_what.to_lower().ends_with("-"+p_str)) //collada only supports "_" and "-" besides letters + return true; + if (p_what.to_lower().ends_with("_"+p_str)) //collada only supports "_" and "-" besides letters + return true; + return false; +} + +static String _fixstr(const String& p_what,const String& p_str) { + + if (p_what.findn("$"+p_str)!=-1) //blender and other stuff + return p_what.replace("$"+p_str,""); + if (p_what.to_lower().ends_with("-"+p_str)) //collada only supports "_" and "-" besides letters + return p_what.substr(0,p_what.length()-(p_str.length()+1)); + if (p_what.to_lower().ends_with("_"+p_str)) //collada only supports "_" and "-" besides letters + return p_what.substr(0,p_what.length()-(p_str.length()+1)); + return p_what; +} + + + +void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<ImageTexture>, TextureRole> &image_map,int p_flags) { + + + switch(p_var.get_type()) { + + case Variant::OBJECT: { + + Ref<Resource> res = p_var; + if (res.is_valid()) { + + if (res->is_class("Texture") && !image_map.has(res)) { + + image_map.insert(res,TEXTURE_ROLE_DEFAULT); + + + } else { + + + List<PropertyInfo> pl; + res->get_property_list(&pl); + for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { + + if (E->get().type==Variant::OBJECT || E->get().type==Variant::ARRAY || E->get().type==Variant::DICTIONARY) { + if (E->get().type==Variant::OBJECT && res->cast_to<FixedSpatialMaterial>() && (E->get().name=="textures/diffuse" || E->get().name=="textures/detail" || E->get().name=="textures/emission")) { + + Ref<ImageTexture> tex =res->get(E->get().name); + if (tex.is_valid()) { + + image_map.insert(tex,TEXTURE_ROLE_DIFFUSE); + } + + } else if (E->get().type==Variant::OBJECT && res->cast_to<FixedSpatialMaterial>() && (E->get().name=="textures/normal")) { + + Ref<ImageTexture> tex =res->get(E->get().name); + if (tex.is_valid()) { + + image_map.insert(tex,TEXTURE_ROLE_NORMALMAP); + /* + if (p_flags&SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY) + res->cast_to<FixedSpatialMaterial>()->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_XY_NORMALMAP,true); + */ + } + + + } else { + _find_resources(res->get(E->get().name),image_map,p_flags); + } + } + } + + } + } + + } break; + case Variant::DICTIONARY: { + + Dictionary d= p_var; + + List<Variant> keys; + d.get_key_list(&keys); + + for(List<Variant>::Element *E=keys.front();E;E=E->next()) { + + + _find_resources(E->get(),image_map,p_flags); + _find_resources(d[E->get()],image_map,p_flags); + + } + + + } break; + case Variant::ARRAY: { + + Array a = p_var; + for(int i=0;i<a.size();i++) { + + _find_resources(a[i],image_map,p_flags); + } + + } break; + default: {} + + } + +} + + +Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,TextureRole >& image_map) { + + // children first.. + for(int i=0;i<p_node->get_child_count();i++) { + + + Node *r = _fix_node(p_node->get_child(i),p_root,collision_map,p_flags,image_map); + if (!r) { + print_line("was erased.."); + i--; //was erased + } + } + + String name = p_node->get_name(); + + bool isroot = p_node==p_root; + + + if (!isroot && p_flags&SCENE_FLAG_REMOVE_NOIMP && _teststr(name,"noimp")) { + + memdelete(p_node); + return NULL; + } + + { + + List<PropertyInfo> pl; + p_node->get_property_list(&pl); + for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { + + if (E->get().type==Variant::OBJECT || E->get().type==Variant::ARRAY || E->get().type==Variant::DICTIONARY) { + _find_resources(p_node->get(E->get().name),image_map,p_flags); + } + } + + } + + + + + if (p_flags&SCENE_FLAG_CREATE_BILLBOARDS && p_node->cast_to<MeshInstance>()) { + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + bool bb=false; + + if ((_teststr(name,"bb"))) { + bb=true; + } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"bb"))) { + bb=true; + + } + + if (bb) { + mi->set_flag(GeometryInstance::FLAG_BILLBOARD,true); + if (mi->get_mesh().is_valid()) { + + Ref<Mesh> m = mi->get_mesh(); + for(int i=0;i<m->get_surface_count();i++) { + + Ref<FixedSpatialMaterial> fm = m->surface_get_material(i); + if (fm.is_valid()) { + //fm->set_flag(Material::FLAG_UNSHADED,true); + //fm->set_flag(Material::FLAG_DOUBLE_SIDED,true); + //fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); + //fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); + } + } + } + } + } + + + if (p_flags&(SCENE_FLAG_DETECT_ALPHA|SCENE_FLAG_DETECT_VCOLOR|SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS) && p_node->cast_to<MeshInstance>()) { + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + Ref<Mesh> m = mi->get_mesh(); + + if (m.is_valid()) { + + for(int i=0;i<m->get_surface_count();i++) { + + Ref<FixedSpatialMaterial> mat = m->surface_get_material(i); + if (!mat.is_valid()) + continue; + + if (p_flags&SCENE_FLAG_DETECT_ALPHA && _teststr(mat->get_name(),"alpha")) { + + //mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); + //mat->set_name(_fixstr(mat->get_name(),"alpha")); + } + if (p_flags&SCENE_FLAG_DETECT_VCOLOR && _teststr(mat->get_name(),"vcol")) { + + //mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY,true); + //mat->set_name(_fixstr(mat->get_name(),"vcol")); + } + + if (p_flags&SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS && m->surface_get_format(i)&Mesh::ARRAY_FORMAT_TEX_UV2) { + //mat->set_flag(Material::FLAG_LIGHTMAP_ON_UV2,true); + } + + } + } + } + + if (p_flags&SCENE_FLAG_REMOVE_NOIMP && p_node->cast_to<AnimationPlayer>()) { + //remove animations referencing non-importable nodes + AnimationPlayer *ap = p_node->cast_to<AnimationPlayer>(); + + List<StringName> anims; + ap->get_animation_list(&anims); + for(List<StringName>::Element *E=anims.front();E;E=E->next()) { + + Ref<Animation> anim=ap->get_animation(E->get()); + ERR_CONTINUE(anim.is_null()); + for(int i=0;i<anim->get_track_count();i++) { + NodePath path = anim->track_get_path(i); + + for(int j=0;j<path.get_name_count();j++) { + String node = path.get_name(j); + if (_teststr(node,"noimp")) { + anim->remove_track(i); + i--; + break; + } + } + } + + } + } + + + if (p_flags&SCENE_FLAG_CREATE_IMPOSTORS && p_node->cast_to<MeshInstance>()) { + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + String str; + + if ((_teststr(name,"imp"))) { + str=name; + } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"imp"))) { + str=mi->get_mesh()->get_name(); + + } + + + if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) { + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>(); + String d=str.substr(str.find("imp")+3,str.length()); + if (d!="") { + if ((d[0]<'0' || d[0]>'9')) + d=d.substr(1,d.length()); + if (d.length() && d[0]>='0' && d[0]<='9') { + float dist = d.to_double(); + mi->set_flag(GeometryInstance::FLAG_BILLBOARD,true); + mi->set_flag(GeometryInstance::FLAG_BILLBOARD_FIX_Y,true); + //mi->set_draw_range_begin(dist); + //mi->set_draw_range_end(100000); + + //mip->set_draw_range_begin(0); + //mip->set_draw_range_end(dist); + + if (mi->get_mesh().is_valid()) { + + Ref<Mesh> m = mi->get_mesh(); + for(int i=0;i<m->get_surface_count();i++) { + + Ref<FixedSpatialMaterial> fm = m->surface_get_material(i); + if (fm.is_valid()) { + //fm->set_flag(Material::FLAG_UNSHADED,true); + //fm->set_flag(Material::FLAG_DOUBLE_SIDED,true); + //fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); + //fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); + } + } + } + } + } + } + } + + if (p_flags&SCENE_FLAG_CREATE_LODS && p_node->cast_to<MeshInstance>()) { + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + String str; + + if ((_teststr(name,"lod"))) { + str=name; + } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"lod"))) { + str=mi->get_mesh()->get_name(); + + } + + + if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) { + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>(); + String d=str.substr(str.find("lod")+3,str.length()); + if (d!="") { + if ((d[0]<'0' || d[0]>'9')) + d=d.substr(1,d.length()); + if (d.length() && d[0]>='0' && d[0]<='9') { + float dist = d.to_double(); + /// mi->set_draw_range_begin(dist); + // mi->set_draw_range_end(100000); + + // mip->set_draw_range_begin(0); + // mip->set_draw_range_end(dist); + + /*if (mi->get_mesh().is_valid()) { + + Ref<Mesh> m = mi->get_mesh(); + for(int i=0;i<m->get_surface_count();i++) { + + Ref<FixedSpatialMaterial> fm = m->surface_get_material(i); + if (fm.is_valid()) { + fm->set_flag(Material::FLAG_UNSHADED,true); + fm->set_flag(Material::FLAG_DOUBLE_SIDED,true); + fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true); + fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); + } + } + }*/ + } + } + } + } + + + if (p_flags&SCENE_FLAG_DETECT_LIGHTMAP_LAYER && _teststr(name,"lm") && p_node->cast_to<MeshInstance>()) { + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + String str=name; + int layer = str.substr(str.find("lm")+3,str.length()).to_int(); + //mi->set_baked_light_texture_id(layer); + } + + if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(name,"colonly")) { + + if (isroot) + return p_node; + + if (p_node->cast_to<MeshInstance>()) { + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + Node * col = mi->create_trimesh_collision_node(); + ERR_FAIL_COND_V(!col,NULL); + + col->set_name(_fixstr(name,"colonly")); + col->cast_to<Spatial>()->set_transform(mi->get_transform()); + p_node->replace_by(col); + memdelete(p_node); + p_node=col; + + StaticBody *sb = col->cast_to<StaticBody>(); + CollisionShape *colshape = memnew( CollisionShape); + colshape->set_shape(sb->get_shape(0)); + colshape->set_name("shape"); + sb->add_child(colshape); + colshape->set_owner(p_node->get_owner()); + } else if (p_node->has_meta("empty_draw_type")) { + String empty_draw_type = String(p_node->get_meta("empty_draw_type")); + print_line(empty_draw_type); + StaticBody *sb = memnew( StaticBody); + sb->set_name(_fixstr(name,"colonly")); + sb->cast_to<Spatial>()->set_transform(p_node->cast_to<Spatial>()->get_transform()); + p_node->replace_by(sb); + memdelete(p_node); + CollisionShape *colshape = memnew( CollisionShape); + if (empty_draw_type == "CUBE") { + BoxShape *boxShape = memnew( BoxShape); + boxShape->set_extents(Vector3(1, 1, 1)); + colshape->set_shape(boxShape); + colshape->set_name("BoxShape"); + } else if (empty_draw_type == "SINGLE_ARROW") { + RayShape *rayShape = memnew( RayShape); + rayShape->set_length(1); + colshape->set_shape(rayShape); + colshape->set_name("RayShape"); + sb->cast_to<Spatial>()->rotate_x(Math_PI / 2); + } else if (empty_draw_type == "IMAGE") { + PlaneShape *planeShape = memnew( PlaneShape); + colshape->set_shape(planeShape); + colshape->set_name("PlaneShape"); + } else { + SphereShape *sphereShape = memnew( SphereShape); + sphereShape->set_radius(1); + colshape->set_shape(sphereShape); + colshape->set_name("SphereShape"); + } + sb->add_child(colshape); + colshape->set_owner(sb->get_owner()); + } + + } else if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(name,"rigid") && p_node->cast_to<MeshInstance>()) { + + if (isroot) + return p_node; + + // get mesh instance and bounding box + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + Rect3 aabb = mi->get_aabb(); + + // create a new rigid body collision node + RigidBody * rigid_body = memnew( RigidBody ); + Node * col = rigid_body; + ERR_FAIL_COND_V(!col,NULL); + + // remove node name postfix + col->set_name(_fixstr(name,"rigid")); + // get mesh instance xform matrix to the rigid body collision node + col->cast_to<Spatial>()->set_transform(mi->get_transform()); + // save original node by duplicating it into a new instance and correcting the name + Node * mesh = p_node->duplicate(); + mesh->set_name(_fixstr(name,"rigid")); + // reset the xform matrix of the duplicated node so it can inherit parent node xform + mesh->cast_to<Spatial>()->set_transform(Transform(Basis())); + // reparent the new mesh node to the rigid body collision node + p_node->add_child(mesh); + mesh->set_owner(p_node->get_owner()); + // replace the original node with the rigid body collision node + p_node->replace_by(col); + memdelete(p_node); + p_node=col; + + // create an alias for the rigid body collision node + RigidBody *rb = col->cast_to<RigidBody>(); + // create a new Box collision shape and set the right extents + Ref<BoxShape> shape = memnew( BoxShape ); + shape->set_extents(aabb.get_size() * 0.5); + CollisionShape *colshape = memnew( CollisionShape); + colshape->set_name("shape"); + colshape->set_shape(shape); + // reparent the new collision shape to the rigid body collision node + rb->add_child(colshape); + colshape->set_owner(p_node->get_owner()); + + } else if (p_flags&SCENE_FLAG_CREATE_COLLISIONS &&_teststr(name,"col") && p_node->cast_to<MeshInstance>()) { + + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + mi->set_name(_fixstr(name,"col")); + Node *col= mi->create_trimesh_collision_node(); + ERR_FAIL_COND_V(!col,NULL); + + col->set_name("col"); + p_node->add_child(col); + + StaticBody *sb=col->cast_to<StaticBody>(); + CollisionShape *colshape = memnew( CollisionShape); + colshape->set_shape(sb->get_shape(0)); + colshape->set_name("shape"); + col->add_child(colshape); + colshape->set_owner(p_node->get_owner()); + sb->set_owner(p_node->get_owner()); + + } else if (p_flags&SCENE_FLAG_CREATE_NAVMESH &&_teststr(name,"navmesh") && p_node->cast_to<MeshInstance>()) { + + if (isroot) + return p_node; + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + Ref<Mesh> mesh=mi->get_mesh(); + ERR_FAIL_COND_V(mesh.is_null(),NULL); + NavigationMeshInstance *nmi = memnew( NavigationMeshInstance ); + + + nmi->set_name(_fixstr(name,"navmesh")); + Ref<NavigationMesh> nmesh = memnew( NavigationMesh); + nmesh->create_from_mesh(mesh); + nmi->set_navigation_mesh(nmesh); + nmi->cast_to<Spatial>()->set_transform(mi->get_transform()); + p_node->replace_by(nmi); + memdelete(p_node); + p_node=nmi; + } else if (p_flags&SCENE_FLAG_CREATE_CARS &&_teststr(name,"vehicle")) { + + if (isroot) + return p_node; + + Node *owner = p_node->get_owner(); + Spatial *s = p_node->cast_to<Spatial>(); + VehicleBody *bv = memnew( VehicleBody ); + String n = _fixstr(p_node->get_name(),"vehicle"); + bv->set_name(n); + p_node->replace_by(bv); + p_node->set_name(n); + bv->add_child(p_node); + bv->set_owner(owner); + p_node->set_owner(owner); + bv->set_transform(s->get_transform()); + s->set_transform(Transform()); + + p_node=bv; + + + } else if (p_flags&SCENE_FLAG_CREATE_CARS &&_teststr(name,"wheel")) { + + if (isroot) + return p_node; + + Node *owner = p_node->get_owner(); + Spatial *s = p_node->cast_to<Spatial>(); + VehicleWheel *bv = memnew( VehicleWheel ); + String n = _fixstr(p_node->get_name(),"wheel"); + bv->set_name(n); + p_node->replace_by(bv); + p_node->set_name(n); + bv->add_child(p_node); + bv->set_owner(owner); + p_node->set_owner(owner); + bv->set_transform(s->get_transform()); + s->set_transform(Transform()); + + p_node=bv; + + } else if (p_flags&SCENE_FLAG_CREATE_ROOMS && _teststr(name,"room") && p_node->cast_to<MeshInstance>()) { + + + if (isroot) + return p_node; + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + PoolVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID); + + + BSP_Tree bsptree(faces); + + Ref<RoomBounds> area = memnew( RoomBounds ); + //area->set_bounds(faces); + //area->set_geometry_hint(faces); + + + Room * room = memnew( Room ); + room->set_name(_fixstr(name,"room")); + room->set_transform(mi->get_transform()); + room->set_room(area); + + p_node->replace_by(room); + memdelete(p_node); + p_node=room; + + } else if (p_flags&SCENE_FLAG_CREATE_ROOMS &&_teststr(name,"room")) { + + if (isroot) + return p_node; + + Spatial *dummy = p_node->cast_to<Spatial>(); + ERR_FAIL_COND_V(!dummy,NULL); + + Room * room = memnew( Room ); + room->set_name(_fixstr(name,"room")); + room->set_transform(dummy->get_transform()); + + p_node->replace_by(room); + memdelete(p_node); + p_node=room; + + //room->compute_room_from_subtree(); + + } else if (p_flags&SCENE_FLAG_CREATE_PORTALS &&_teststr(name,"portal") && p_node->cast_to<MeshInstance>()) { + + if (isroot) + return p_node; + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + PoolVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID); + + ERR_FAIL_COND_V(faces.size()==0,NULL); + //step 1 compute the plane + Set<Vector3> points; + Plane plane; + + Vector3 center; + + for(int i=0;i<faces.size();i++) { + + Face3 f = faces.get(i); + Plane p = f.get_plane(); + plane.normal+=p.normal; + plane.d+=p.d; + + for(int i=0;i<3;i++) { + + Vector3 v = f.vertex[i].snapped(0.01); + if (!points.has(v)) { + points.insert(v); + center+=v; + } + } + } + + plane.normal.normalize(); + plane.d/=faces.size(); + center/=points.size(); + + //step 2, create points + + Transform t; + t.basis.from_z(plane.normal); + t.basis.transpose(); + t.origin=center; + + Vector<Point2> portal_points; + + for(Set<Vector3>::Element *E=points.front();E;E=E->next()) { + + Vector3 local = t.xform_inv(E->get()); + portal_points.push_back(Point2(local.x,local.y)); + } + // step 3 bubbly sort points + + int swaps=0; + + do { + swaps=0; + + for(int i=0;i<portal_points.size()-1;i++) { + + float a = portal_points[i].angle(); + float b = portal_points[i+1].angle(); + + if (a>b) { + SWAP( portal_points[i], portal_points[i+1] ); + swaps++; + } + + } + + } while(swaps); + + + Portal *portal = memnew( Portal ); + + portal->set_shape(portal_points); + portal->set_transform( mi->get_transform() * t); + + p_node->replace_by(portal); + memdelete(p_node); + p_node=portal; + + } else if (p_node->cast_to<MeshInstance>()) { + + //last attempt, maybe collision insde the mesh data + + MeshInstance *mi = p_node->cast_to<MeshInstance>(); + + Ref<Mesh> mesh = mi->get_mesh(); + if (!mesh.is_null()) { + + if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(mesh->get_name(),"col")) { + + mesh->set_name( _fixstr(mesh->get_name(),"col") ); + Ref<Shape> shape; + + if (collision_map.has(mesh)) { + shape = collision_map[mesh]; + + } else { + + shape = mesh->create_trimesh_shape(); + if (!shape.is_null()) + collision_map[mesh]=shape; + + + } + + if (!shape.is_null()) { +#if 0 + StaticBody* static_body = memnew( StaticBody ); + ERR_FAIL_COND_V(!static_body,NULL); + static_body->set_name( String(mesh->get_name()) + "_col" ); + shape->set_name(static_body->get_name()); + static_body->add_shape(shape); + + mi->add_child(static_body); + if (mi->get_owner()) + static_body->set_owner( mi->get_owner() ); +#endif + } + + } + + for(int i=0;i<mesh->get_surface_count();i++) { + + Ref<FixedSpatialMaterial> fm = mesh->surface_get_material(i); + if (fm.is_valid()) { + String name = fm->get_name(); + /* if (_teststr(name,"alpha")) { + fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); + name=_fixstr(name,"alpha"); + } + + if (_teststr(name,"vcol")) { + fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY,true); + name=_fixstr(name,"vcol"); + }*/ + fm->set_name(name); + } + } + + } + + } + + + return p_node; +} + + + + +#if 0 + +Error EditorImport::import_scene(const String& p_path,const String& p_dest_path,const String& p_resource_path,uint32_t p_flags,ImageFormat p_image_format,ImageCompression p_image_compression,uint32_t p_image_flags,float p_quality,uint32_t animation_flags,Node **r_scene,Ref<EditorPostImport> p_post_import) { + + +} +#endif + +void EditorSceneImportPlugin::_tag_import_paths(Node *p_scene,Node *p_node) { + + if (p_scene!=p_node && p_node->get_owner()!=p_scene) + return; + + NodePath path = p_scene->get_path_to(p_node); + p_node->set_import_path( path ); + + Spatial *snode=p_node->cast_to<Spatial>(); + + if (snode) { + + snode->set_import_transform(snode->get_transform()); + } + + for(int i=0;i<p_node->get_child_count();i++) { + _tag_import_paths(p_scene,p_node->get_child(i)); + } + +} + +Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from,Node**r_node,List<String> *r_missing) { + + Ref<ResourceImportMetadata> from=p_from; + + ERR_FAIL_COND_V(from->get_source_count()!=1,ERR_INVALID_PARAMETER); + + String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0)); + + Ref<EditorSceneImporter> importer; + String ext=src_path.get_extension().to_lower(); + + + EditorProgress progress("import",TTR("Import Scene"),104); + progress.step(TTR("Importing Scene.."),0); + + for(int i=0;i<importers.size();i++) { + + List<String> extensions; + importers[i]->get_extensions(&extensions); + + for(List<String>::Element *E=extensions.front();E;E=E->next()) { + + if (E->get().to_lower()==ext) { + + importer = importers[i]; + break; + } + } + + if (importer.is_valid()) + break; + } + + ERR_FAIL_COND_V(!importer.is_valid(),ERR_FILE_UNRECOGNIZED); + + int animation_flags=p_from->get_option("animation_flags"); + int scene_flags = from->get_option("flags"); + int fps = 24; + if (from->has_option("animation_bake_fps")) + fps=from->get_option("animation_bake_fps"); + + + Array clips; + if (from->has_option("animation_clips")) + clips=from->get_option("animation_clips"); + + uint32_t import_flags=0; + if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP) + import_flags|=EditorSceneImporter::IMPORT_ANIMATION_DETECT_LOOP; + if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_KEEP_VALUE_TRACKS) + import_flags |= EditorSceneImporter::IMPORT_ANIMATION_KEEP_VALUE_TRACKS; + if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE) + import_flags|=EditorSceneImporter::IMPORT_ANIMATION_OPTIMIZE; + if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS) + import_flags|=EditorSceneImporter::IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS; + if (scene_flags&SCENE_FLAG_IMPORT_ANIMATIONS) + import_flags|=EditorSceneImporter::IMPORT_ANIMATION; + /* + if (scene_flags&SCENE_FLAG_FAIL_ON_MISSING_IMAGES) + import_flags|=EditorSceneImporter::IMPORT_FAIL_ON_MISSING_DEPENDENCIES; + */ + if (scene_flags&SCENE_FLAG_GENERATE_TANGENT_ARRAYS) + import_flags|=EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS; + + + + + + Error err=OK; + Node *scene = importer->import_scene(src_path,import_flags,fps,r_missing,&err); + if (!scene || err!=OK) { + return err; + } + + if (from->has_option("root_type")) { + String type = from->get_option("root_type"); + Object *base = ClassDB::instance(type); + Node *base_node = NULL; + if (base) + base_node=base->cast_to<Node>(); + + if (base_node) { + + scene->replace_by(base_node); + memdelete(scene); + scene=base_node; + } + } + + scene->set_name(from->get_option("root_name")); + _tag_import_paths(scene,scene); + + *r_node=scene; + return OK; +} + + +void EditorSceneImportPlugin::_create_clips(Node *scene, const Array& p_clips,bool p_bake_all) { + + if (!scene->has_node(String("AnimationPlayer"))) + return; + + Node* n = scene->get_node(String("AnimationPlayer")); + ERR_FAIL_COND(!n); + AnimationPlayer *anim = n->cast_to<AnimationPlayer>(); + ERR_FAIL_COND(!anim); + + if (!anim->has_animation("default")) + return; + + + Ref<Animation> default_anim = anim->get_animation("default"); + + for(int i=0;i<p_clips.size();i+=4) { + + String name = p_clips[i]; + float from=p_clips[i+1]; + float to=p_clips[i+2]; + bool loop=p_clips[i+3]; + if (from>=to) + continue; + + Ref<Animation> new_anim = memnew( Animation ); + + for(int j=0;j<default_anim->get_track_count();j++) { + + + List<float> keys; + int kc = default_anim->track_get_key_count(j); + int dtrack=-1; + for(int k=0;k<kc;k++) { + + float kt = default_anim->track_get_key_time(j,k); + if (kt>=from && kt<to) { + + //found a key within range, so create track + if (dtrack==-1) { + new_anim->add_track(default_anim->track_get_type(j)); + dtrack = new_anim->get_track_count()-1; + new_anim->track_set_path(dtrack,default_anim->track_get_path(j)); + + if (kt>(from+0.01) && k>0) { + + if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { + Quat q; + Vector3 p; + Vector3 s; + default_anim->transform_track_interpolate(j,from,&p,&q,&s); + new_anim->transform_track_insert_key(dtrack,0,p,q,s); + } + } + + } + + if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { + Quat q; + Vector3 p; + Vector3 s; + default_anim->transform_track_get_key(j,k,&p,&q,&s); + new_anim->transform_track_insert_key(dtrack,kt-from,p,q,s); + } + + } + + if (dtrack!=-1 && kt>=to) { + + if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { + Quat q; + Vector3 p; + Vector3 s; + default_anim->transform_track_interpolate(j,to,&p,&q,&s); + new_anim->transform_track_insert_key(dtrack,to-from,p,q,s); + } + } + + } + + if (dtrack==-1 && p_bake_all) { + new_anim->add_track(default_anim->track_get_type(j)); + dtrack = new_anim->get_track_count()-1; + new_anim->track_set_path(dtrack,default_anim->track_get_path(j)); + if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { + + + Quat q; + Vector3 p; + Vector3 s; + default_anim->transform_track_interpolate(j,from,&p,&q,&s); + new_anim->transform_track_insert_key(dtrack,0,p,q,s); + default_anim->transform_track_interpolate(j,to,&p,&q,&s); + new_anim->transform_track_insert_key(dtrack,to-from,p,q,s); + } + + } + } + + + new_anim->set_loop(loop); + new_anim->set_length(to-from); + anim->add_animation(name,new_anim); + } + + anim->remove_animation("default"); //remove default (no longer needed) +} + +void EditorSceneImportPlugin::_filter_anim_tracks(Ref<Animation> anim,Set<String> &keep) { + + Ref<Animation> a = anim; + ERR_FAIL_COND(!a.is_valid()); + + print_line("From Anim "+anim->get_name()+":"); + + for(int j=0;j<a->get_track_count();j++) { + + String path = a->track_get_path(j); + + if (!keep.has(path)) { + + print_line("Remove: "+path); + a->remove_track(j); + j--; + } + + } +} + + +void EditorSceneImportPlugin::_filter_tracks(Node *scene, const String& p_text) { + + if (!scene->has_node(String("AnimationPlayer"))) + return; + Node* n = scene->get_node(String("AnimationPlayer")); + ERR_FAIL_COND(!n); + AnimationPlayer *anim = n->cast_to<AnimationPlayer>(); + ERR_FAIL_COND(!anim); + + Vector<String> strings = p_text.split("\n"); + for(int i=0;i<strings.size();i++) { + + strings[i]=strings[i].strip_edges(); + } + + List<StringName> anim_names; + anim->get_animation_list(&anim_names); + for(List<StringName>::Element *E=anim_names.front();E;E=E->next()) { + + String name = E->get(); + bool valid_for_this=false; + bool valid=false; + + Set<String> keep; + Set<String> keep_local; + + + for(int i=0;i<strings.size();i++) { + + + if (strings[i].begins_with("@")) { + + valid_for_this=false; + for(Set<String>::Element *F=keep_local.front();F;F=F->next()) { + keep.insert(F->get()); + } + keep_local.clear(); + + Vector<String> filters=strings[i].substr(1,strings[i].length()).split(","); + for(int j=0;j<filters.size();j++) { + + String fname = filters[j].strip_edges(); + if (fname=="") + continue; + int fc = fname[0]; + bool plus; + if (fc=='+') + plus=true; + else if (fc=='-') + plus=false; + else + continue; + + String filter=fname.substr(1,fname.length()).strip_edges(); + + if (!name.matchn(filter)) + continue; + valid_for_this=plus; + } + + if (valid_for_this) + valid=true; + + } else if (valid_for_this) { + + Ref<Animation> a = anim->get_animation(name); + if (!a.is_valid()) + continue; + + for(int j=0;j<a->get_track_count();j++) { + + String path = a->track_get_path(j); + + String tname = strings[i]; + if (tname=="") + continue; + int fc = tname[0]; + bool plus; + if (fc=='+') + plus=true; + else if (fc=='-') + plus=false; + else + continue; + + String filter=tname.substr(1,tname.length()).strip_edges(); + + if (!path.matchn(filter)) + continue; + + if (plus) + keep_local.insert(path); + else if (!keep.has(path)) { + keep_local.erase(path); + } + } + + } + + } + + if (valid) { + for(Set<String>::Element *F=keep_local.front();F;F=F->next()) { + keep.insert(F->get()); + } + print_line("FILTERING ANIM: "+String(E->get())); + _filter_anim_tracks(anim->get_animation(name),keep); + } else { + print_line("NOT FILTERING ANIM: "+String(E->get())); + + } + + } + + + +} + +void EditorSceneImportPlugin::_optimize_animations(Node *scene, float p_max_lin_error,float p_max_ang_error,float p_max_angle) { + + if (!scene->has_node(String("AnimationPlayer"))) + return; + Node* n = scene->get_node(String("AnimationPlayer")); + ERR_FAIL_COND(!n); + AnimationPlayer *anim = n->cast_to<AnimationPlayer>(); + ERR_FAIL_COND(!anim); + + + List<StringName> anim_names; + anim->get_animation_list(&anim_names); + for(List<StringName>::Element *E=anim_names.front();E;E=E->next()) { + + Ref<Animation> a = anim->get_animation(E->get()); + a->optimize(p_max_lin_error,p_max_ang_error,Math::deg2rad(p_max_angle)); + } +} + + +void EditorSceneImportPlugin::_find_resources_to_merge(Node *scene, Node *node, bool p_merge_material, Map<String, Ref<Material> > &materials, bool p_merge_anims, Map<String,Ref<Animation> >& merged_anims,Set<Ref<Mesh> > &tested_meshes) { + + if (node!=scene && node->get_owner()!=scene) + return; + + String path = scene->get_path_to(node); + + if (p_merge_anims && node->cast_to<AnimationPlayer>()) { + + AnimationPlayer *ap = node->cast_to<AnimationPlayer>(); + List<StringName> anims; + ap->get_animation_list(&anims); + for (List<StringName>::Element *E=anims.front();E;E=E->next()) { + Ref<Animation> anim = ap->get_animation(E->get()); + Ref<Animation> clone; + + bool has_user_tracks=false; + + for(int i=0;i<anim->get_track_count();i++) { + + if (!anim->track_is_imported(i)) { + has_user_tracks=true; + break; + } + } + + if (has_user_tracks) { + + clone = anim->duplicate(); + for(int i=0;i<clone->get_track_count();i++) { + if (clone->track_is_imported(i)) { + clone->remove_track(i); + i--; + } + } + + merged_anims[path+"::"+String(E->get())]=clone; + } + } + } + + + + if (p_merge_material && node->cast_to<MeshInstance>()) { + MeshInstance *mi=node->cast_to<MeshInstance>(); + Ref<Mesh> mesh = mi->get_mesh(); + if (mesh.is_valid() && mesh->get_name()!=String() && !tested_meshes.has(mesh)) { + + for(int i=0;i<mesh->get_surface_count();i++) { + Ref<Material> material = mesh->surface_get_material(i); + + if (material.is_valid()) { + + String sname = mesh->surface_get_name(i); + if (sname=="") + sname="surf_"+itos(i); + + sname=mesh->get_name()+":surf:"+sname; + materials[sname]=material; + } + } + + tested_meshes.insert(mesh); + } + + if (mesh.is_valid()) { + + for(int i=0;i<mesh->get_surface_count();i++) { + Ref<Material> material = mi->get_surface_material(i); + if (material.is_valid()) { + String sname = mesh->surface_get_name(i); + if (sname=="") + sname="surf_"+itos(i); + + sname=path+":inst_surf:"+sname; + materials[sname]=material; + } + } + + } + + Ref<Material> override = mi->get_material_override(); + + if (override.is_valid()) { + + materials[path+":override"]=override; + } + } + + + + for(int i=0;i<node->get_child_count();i++) { + _find_resources_to_merge(scene,node->get_child(i),p_merge_material,materials,p_merge_anims,merged_anims,tested_meshes); + } + +} + + +void EditorSceneImportPlugin::_merge_found_resources(Node *scene, Node *node, bool p_merge_material, const Map<String, Ref<Material> > &materials, bool p_merge_anims, const Map<String,Ref<Animation> >& merged_anims, Set<Ref<Mesh> > &tested_meshes) { + + if (node!=scene && node->get_owner()!=scene) + return; + + String path = scene->get_path_to(node); + + print_line("at path: "+path); + + if (node->cast_to<AnimationPlayer>()) { + + AnimationPlayer *ap = node->cast_to<AnimationPlayer>(); + List<StringName> anims; + ap->get_animation_list(&anims); + for (List<StringName>::Element *E=anims.front();E;E=E->next()) { + Ref<Animation> anim = ap->get_animation(E->get()); + + String anim_path = path+"::"+String(E->get()); + + if (merged_anims.has(anim_path)) { + + Ref<Animation> user_tracks = merged_anims[anim_path]; + for(int i=0;i<user_tracks->get_track_count();i++) { + + int idx = anim->get_track_count(); + anim->add_track(user_tracks->track_get_type(i)); + anim->track_set_path(idx,user_tracks->track_get_path(i)); + anim->track_set_interpolation_type(idx,user_tracks->track_get_interpolation_type(i)); + for(int j=0;j<user_tracks->track_get_key_count(i);j++) { + + float ofs = user_tracks->track_get_key_time(i,j); + float trans = user_tracks->track_get_key_transition(i,j); + Variant value = user_tracks->track_get_key_value(i,j); + + anim->track_insert_key(idx,ofs,value,trans); + } + } + } + } + } + + + + if (node->cast_to<MeshInstance>()) { + MeshInstance *mi=node->cast_to<MeshInstance>(); + Ref<Mesh> mesh = mi->get_mesh(); + if (mesh.is_valid() && mesh->get_name()!=String() && !tested_meshes.has(mesh)) { + + for(int i=0;i<mesh->get_surface_count();i++) { + + String sname = mesh->surface_get_name(i); + if (sname=="") + sname="surf_"+itos(i); + + sname=mesh->get_name()+":surf:"+sname; + + + if (materials.has(sname)) { + + mesh->surface_set_material(i,materials[sname]); + } + } + + tested_meshes.insert(mesh); + } + + if (mesh.is_valid()) { + + for(int i=0;i<mesh->get_surface_count();i++) { + + String sname = mesh->surface_get_name(i); + if (sname=="") + sname="surf_"+itos(i); + + sname=path+":inst_surf:"+sname; + + + if (materials.has(sname)) { + + mi->set_surface_material(i,materials[sname]); + } + } + + } + + + String opath = path+":override"; + if (materials.has(opath)) { + mi->set_material_override(materials[opath]); + } + + } + + + + for(int i=0;i<node->get_child_count();i++) { + _merge_found_resources(scene,node->get_child(i),p_merge_material,materials,p_merge_anims,merged_anims,tested_meshes); + } + +} + +Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, const Ref<ResourceImportMetadata>& p_from) { + + Error err=OK; + Ref<ResourceImportMetadata> from=p_from; + String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0)); + int animation_flags=p_from->get_option("animation_flags"); + Array animation_clips = p_from->get_option("animation_clips"); + String animation_filter = p_from->get_option("animation_filters"); + int scene_flags = from->get_option("flags"); + float anim_optimizer_linerr=0.05; + float anim_optimizer_angerr=0.01; + float anim_optimizer_maxang=22; + + if (from->has_option("animation_optimizer_linear_error")) + anim_optimizer_linerr=from->get_option("animation_optimizer_linear_error"); + if (from->has_option("animation_optimizer_angular_error")) + anim_optimizer_angerr=from->get_option("animation_optimizer_angular_error"); + if (from->has_option("animation_optimizer_max_angle")) + anim_optimizer_maxang=from->get_option("animation_optimizer_max_angle"); + + EditorProgress progress("import",TTR("Import Scene"),104); + progress.step(TTR("Importing Scene.."),2); + + + from->set_source_md5(0,FileAccess::get_md5(src_path)); + from->set_editor(get_name()); + + from->set_option("reimport",false); + String target_res_path=p_dest_path.get_base_dir(); + + Map<Ref<Mesh>,Ref<Shape> > collision_map; + + Map< Ref<ImageTexture>,TextureRole > imagemap; + + scene=_fix_node(scene,scene,collision_map,scene_flags,imagemap); + if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE) + _optimize_animations(scene,anim_optimizer_linerr,anim_optimizer_angerr,anim_optimizer_maxang); + if (animation_clips.size()) + _create_clips(scene,animation_clips,animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS); + + _filter_tracks(scene,animation_filter); + + + if (scene_flags&(SCENE_FLAG_MERGE_KEEP_MATERIALS|SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS) && FileAccess::exists(p_dest_path)) { + //must merge! + + print_line("MUST MERGE"); + Ref<PackedScene> pscene = ResourceLoader::load(p_dest_path,"PackedScene",true); + if (pscene.is_valid()) { + + Node *instance = pscene->instance(); + if (instance) { + Map<String,Ref<Animation> > merged_anims; + Map<String,Ref<Material> > merged_materials; + Set<Ref<Mesh> > tested_meshes; + + _find_resources_to_merge(instance,instance,scene_flags&SCENE_FLAG_MERGE_KEEP_MATERIALS,merged_materials,scene_flags&SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS,merged_anims,tested_meshes); + + tested_meshes.clear(); + _merge_found_resources(scene,scene,scene_flags&SCENE_FLAG_MERGE_KEEP_MATERIALS,merged_materials,scene_flags&SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS,merged_anims,tested_meshes); + + memdelete(instance); + } + + } + + } + + /// BEFORE ANYTHING, RUN SCRIPT + + progress.step(TTR("Running Custom Script.."),2); + + String post_import_script_path = from->get_option("post_import_script"); + Ref<EditorScenePostImport> post_import_script; + + if (post_import_script_path!="") { + post_import_script_path = post_import_script_path; + Ref<Script> scr = ResourceLoader::load(post_import_script_path); + if (!scr.is_valid()) { + EditorNode::add_io_error(TTR("Couldn't load post-import script:")+" "+post_import_script_path); + } else { + + post_import_script = Ref<EditorScenePostImport>( memnew( EditorScenePostImport ) ); + post_import_script->set_script(scr.get_ref_ptr()); + if (!post_import_script->get_script_instance()) { + EditorNode::add_io_error(TTR("Invalid/broken script for post-import (check console):")+" "+post_import_script_path); + post_import_script.unref(); + return ERR_CANT_CREATE; + } + } + } + + + if (post_import_script.is_valid()) { + scene = post_import_script->post_import(scene); + if (!scene) { + EditorNode::add_io_error(TTR("Error running post-import script:")+" "+post_import_script_path); + return err; + } + + + } + + + /// IMPORT IMAGES + + + int idx=0; + + int image_format = from->get_option("texture_format"); + int image_flags = from->get_option("texture_flags"); + float image_quality = from->get_option("texture_quality"); + + for (Map< Ref<ImageTexture>,TextureRole >::Element *E=imagemap.front();E;E=E->next()) { + + //texture could be converted to something more useful for 3D, that could load individual mipmaps and stuff + //but not yet.. + + Ref<ImageTexture> texture = E->key(); + + ERR_CONTINUE(!texture.is_valid()); + + String path = texture->get_path(); + String fname= path.get_file(); + String target_path = GlobalConfig::get_singleton()->localize_path(target_res_path.plus_file(fname)); + progress.step(TTR("Import Image:")+" "+fname,3+(idx)*100/imagemap.size()); + + idx++; + + if (path==target_path) { + + EditorNode::add_io_error(TTR("Can't import a file over itself:")+" "+target_path); + continue; + } + + if (!target_path.begins_with("res://")) { + EditorNode::add_io_error(vformat(TTR("Couldn't localize path: %s (already local)"),target_path)); + continue; + } + + + { + + + target_path=target_path.get_basename()+".tex"; + + Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); + + uint32_t flags = image_flags; + if (E->get()==TEXTURE_ROLE_DIFFUSE && scene_flags&SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES) + flags|=EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_TO_LINEAR; + + if (E->get()==TEXTURE_ROLE_NORMALMAP && scene_flags&SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY) + flags|=EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_NORMAL_TO_XY; + + imd->set_option("flags",flags); + imd->set_option("format",image_format); + imd->set_option("quality",image_quality); + imd->set_option("atlas",false); + imd->add_source(EditorImportPlugin::validate_source_path(path)); + + + if (FileAccess::exists(target_path)) { + + Ref<ResourceImportMetadata> rimdex = ResourceLoader::load_import_metadata(target_path); + if (rimdex.is_valid()) { + //make sure the options are the same, otherwise re-import + List<String> opts; + imd->get_options(&opts); + bool differ=false; + for (List<String>::Element *E=opts.front();E;E=E->next()) { + if (!(rimdex->get_option(E->get())==imd->get_option(E->get()))) { + differ=true; + break; + } + } + + if (!differ) { + texture->set_path(target_path); + continue; //already imported + } + } + } + + EditorTextureImportPlugin::get_singleton()->import(target_path,imd); + + } + } + + + + progress.step(TTR("Saving.."),104); + + Ref<PackedScene> packer = memnew( PackedScene ); + packer->pack(scene); + //packer->set_path(p_dest_path); do not take over, let the changed files reload themselves + packer->set_import_metadata(from); + + print_line("SAVING TO: "+p_dest_path); + err = ResourceSaver::save(p_dest_path,packer); //do not take over, let the changed files reload themselves + + //EditorFileSystem::get_singleton()->update_resource(packer); + + memdelete(scene); + + /* + scene->set_filename(p_dest_path); + if (r_scene) { + *r_scene=scene; + } else { + memdelete(scene); + } + + String sp; + if (p_post_import.is_valid() && !p_post_import->get_script().is_null()) { + Ref<Script> scr = p_post_import->get_script(); + if (scr.is_valid()) + sp=scr->get_path(); + } + + String op=_getrelpath(p_path,p_dest_path); + + */ + + EditorNode::get_singleton()->reload_scene(p_dest_path); + + return err; + +} + + +Error EditorSceneImportPlugin::import(const String& p_dest_path, const Ref<ResourceImportMetadata>& p_from){ + + + Node *n=NULL; + Error err = import1(p_from,&n); + if (err!=OK) { + if (n) { + memdelete(n); + } + return err; + } + return import2(n,p_dest_path,p_from); +} + +void EditorSceneImportPlugin::add_importer(const Ref<EditorSceneImporter>& p_importer) { + + importers.push_back(p_importer); +} + +void EditorSceneImportPlugin::import_from_drop(const Vector<String>& p_drop,const String& p_dest_path) { + + List<String> extensions; + for(int i=0;i<importers.size();i++) { + importers[i]->get_extensions(&extensions); + } + //bool warn_compatible=false; + for(int i=0;i<p_drop.size();i++) { + + String extension = p_drop[i].get_extension().to_lower(); + + for(List<String>::Element *E=extensions.front();E;E=E->next()) { + + if (E->get()==extension) { + + dialog->popup_import(String()); + dialog->setup_popup(p_drop[i],p_dest_path); + return; + } + } + } + +} + + +EditorSceneImportPlugin::EditorSceneImportPlugin(EditorNode* p_editor) { + + dialog = memnew( EditorSceneImportDialog(p_editor,this) ); + p_editor->get_gui_base()->add_child(dialog); +} + + +/////////////////////////////// + + +String EditorSceneAnimationImportPlugin::get_name() const { + + return "anim_3d"; +} +String EditorSceneAnimationImportPlugin::get_visible_name() const{ + + + return TTR("3D Scene Animation"); +} +void EditorSceneAnimationImportPlugin::import_dialog(const String& p_from){ + + +} +Error EditorSceneAnimationImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from){ + + return OK; +} + +EditorSceneAnimationImportPlugin::EditorSceneAnimationImportPlugin(EditorNode* p_editor) { + + +} +#endif diff --git a/editor/io_plugins/editor_scene_import_plugin.h b/editor/io_plugins/editor_scene_import_plugin.h new file mode 100644 index 0000000000..2ae0693600 --- /dev/null +++ b/editor/io_plugins/editor_scene_import_plugin.h @@ -0,0 +1,200 @@ +/*************************************************************************/ +/* editor_scene_import_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITOR_SCENE_IMPORT_PLUGIN_H +#define EDITOR_SCENE_IMPORT_PLUGIN_H +#if 0 +#include "scene/gui/dialogs.h" +#include "scene/gui/tree.h" +#include "scene/gui/label.h" +#include "scene/gui/option_button.h" +#include "scene/gui/line_edit.h" +#include "scene/gui/file_dialog.h" +#include "scene/gui/progress_bar.h" +#include "scene/gui/slider.h" +#include "scene/gui/spin_box.h" +#include "scene/resources/mesh.h" +#include "editor/editor_file_system.h" +#include "editor/editor_dir_dialog.h" +#include "editor/editor_import_export.h" +#include "editor/io_plugins/editor_texture_import_plugin.h" +#include "scene/resources/animation.h" + + +class EditorNode; +class EditorSceneImportDialog; + +class EditorSceneImporter : public Reference { + + GDCLASS(EditorSceneImporter,Reference ); +public: + + enum ImportFlags { + IMPORT_SCENE=1, + IMPORT_ANIMATION=2, + IMPORT_ANIMATION_DETECT_LOOP=4, + IMPORT_ANIMATION_OPTIMIZE=8, + IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS=16, + IMPORT_ANIMATION_KEEP_VALUE_TRACKS=32, + IMPORT_GENERATE_TANGENT_ARRAYS=256, + IMPORT_FAIL_ON_MISSING_DEPENDENCIES=512 + + }; + + virtual uint32_t get_import_flags() const=0; + virtual void get_extensions(List<String> *r_extensions) const=0; + virtual Node* import_scene(const String& p_path,uint32_t p_flags,int p_bake_fps,List<String> *r_missing_deps,Error* r_err=NULL)=0; + virtual Ref<Animation> import_animation(const String& p_path,uint32_t p_flags)=0; + + + + EditorSceneImporter(); +}; + +///////////////////////////////////////// + + +//Plugin for post processing scenes or images + +class EditorScenePostImport : public Reference { + + GDCLASS(EditorScenePostImport,Reference ); +protected: + + static void _bind_methods(); +public: + + virtual Node* post_import(Node* p_scene); + EditorScenePostImport(); +}; + + +class EditorSceneImportPlugin : public EditorImportPlugin { + + GDCLASS(EditorSceneImportPlugin,EditorImportPlugin); + + EditorSceneImportDialog *dialog; + + Vector<Ref<EditorSceneImporter> > importers; + + enum TextureRole { + TEXTURE_ROLE_DEFAULT, + TEXTURE_ROLE_DIFFUSE, + TEXTURE_ROLE_NORMALMAP + }; + + void _find_resources(const Variant& p_var,Map<Ref<ImageTexture>,TextureRole >& image_map,int p_flags); + Node* _fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,TextureRole >& image_map); + void _create_clips(Node *scene, const Array& p_clips, bool p_bake_all); + void _filter_anim_tracks(Ref<Animation> anim,Set<String> &keep); + void _filter_tracks(Node *scene, const String& p_text); + void _optimize_animations(Node *scene, float p_max_lin_error,float p_max_ang_error,float p_max_angle); + + void _tag_import_paths(Node *p_scene,Node *p_node); + + void _find_resources_to_merge(Node *scene, Node *node, bool p_merge_material, Map<String,Ref<Material> >&materials, bool p_merge_anims, Map<String,Ref<Animation> >& merged_anims, Set<Ref<Mesh> > &tested_meshes); + void _merge_found_resources(Node *scene, Node *node, bool p_merge_material, const Map<String, Ref<Material> > &materials, bool p_merge_anims, const Map<String,Ref<Animation> >& merged_anims, Set<Ref<Mesh> > &tested_meshes); + + +public: + + enum SceneFlags { + + SCENE_FLAG_CREATE_COLLISIONS=1<<0, + SCENE_FLAG_CREATE_PORTALS=1<<1, + SCENE_FLAG_CREATE_ROOMS=1<<2, + SCENE_FLAG_SIMPLIFY_ROOMS=1<<3, + SCENE_FLAG_CREATE_BILLBOARDS=1<<4, + SCENE_FLAG_CREATE_IMPOSTORS=1<<5, + SCENE_FLAG_CREATE_LODS=1<<6, + SCENE_FLAG_CREATE_CARS=1<<8, + SCENE_FLAG_CREATE_WHEELS=1<<9, + SCENE_FLAG_DETECT_ALPHA=1<<15, + SCENE_FLAG_DETECT_VCOLOR=1<<16, + SCENE_FLAG_CREATE_NAVMESH=1<<17, + SCENE_FLAG_DETECT_LIGHTMAP_LAYER=1<<18, + + SCENE_FLAG_MERGE_KEEP_MATERIALS=1<<20, + SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS=1<<21, + + SCENE_FLAG_REMOVE_NOIMP=1<<24, + SCENE_FLAG_IMPORT_ANIMATIONS=1<<25, + SCENE_FLAG_COMPRESS_GEOMETRY=1<<26, + SCENE_FLAG_GENERATE_TANGENT_ARRAYS=1<<27, + SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES=1<<28, + SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS=1<<29, + SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY=1<<30, + }; + + + + virtual String get_name() const; + virtual String get_visible_name() const; + virtual void import_dialog(const String& p_from=""); + virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + + Error import1(const Ref<ResourceImportMetadata>& p_from,Node**r_node,List<String> *r_missing=NULL); + Error import2(Node* p_scene,const String& p_path, const Ref<ResourceImportMetadata>& p_from); + + void add_importer(const Ref<EditorSceneImporter>& p_importer); + const Vector<Ref<EditorSceneImporter> >& get_importers() { return importers; } + + virtual void import_from_drop(const Vector<String>& p_drop,const String& p_dest_path); + + EditorSceneImportPlugin(EditorNode* p_editor=NULL); + + +}; + + +class EditorSceneAnimationImportPlugin : public EditorImportPlugin { + + GDCLASS(EditorSceneAnimationImportPlugin,EditorImportPlugin); +public: + + + enum AnimationFlags { + + ANIMATION_DETECT_LOOP=1, + ANIMATION_KEEP_VALUE_TRACKS=2, + ANIMATION_OPTIMIZE=4, + ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS=8 + }; + + virtual String get_name() const; + virtual String get_visible_name() const; + virtual void import_dialog(const String& p_from=""); + virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + + EditorSceneAnimationImportPlugin(EditorNode* p_editor=NULL); + + +}; + +#endif +#endif // EDITOR_SCENE_IMPORT_PLUGIN_H diff --git a/editor/io_plugins/editor_scene_importer_fbxconv.cpp b/editor/io_plugins/editor_scene_importer_fbxconv.cpp new file mode 100644 index 0000000000..d75a26a948 --- /dev/null +++ b/editor/io_plugins/editor_scene_importer_fbxconv.cpp @@ -0,0 +1,1136 @@ +/*************************************************************************/ +/* editor_scene_importer_fbxconv.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 "editor_scene_importer_fbxconv.h" + +#include "os/file_access.h" +#include "os/os.h" +#include "editor/editor_settings.h" +#include "scene/3d/mesh_instance.h" +#include "scene/animation/animation_player.h" + +#if 0 +String EditorSceneImporterFBXConv::_id(const String& p_id) const { + + return p_id.replace(":","_").replace("/","_"); +} + +uint32_t EditorSceneImporterFBXConv::get_import_flags() const { + + return IMPORT_SCENE|IMPORT_ANIMATION; +} +void EditorSceneImporterFBXConv::get_extensions(List<String> *r_extensions) const{ + + r_extensions->push_back("fbx"); + r_extensions->push_back("g3dj"); +} + + +Color EditorSceneImporterFBXConv::_get_color(const Array& a) { + + if (a.size()<3) + return Color(); + Color c; + c.r=a[0]; + c.g=a[1]; + c.b=a[2]; + if (a.size()>=4) + c.a=a[3]; + return c; + +} + +Transform EditorSceneImporterFBXConv::_get_transform_mixed(const Dictionary& d,const Dictionary& dbase) { + + + + + Array translation; + + if (d.has("translation")) + translation=d["translation"]; + else if (dbase.has("translation")) + translation=dbase["translation"]; + + Array rotation; + + if (d.has("rotation")) + rotation=d["rotation"]; + else if (dbase.has("rotation")) + rotation=dbase["rotation"]; + + Array scale; + + if (d.has("scale")) + scale=d["scale"]; + else if (dbase.has("scale")) + scale=dbase["scale"]; + + Transform t; + + + if (translation.size()) { + Array tr = translation; + if (tr.size()>=3) { + t.origin.x=tr[0]; + t.origin.y=tr[1]; + t.origin.z=tr[2]; + } + } + + if (rotation.size()) { + + Array r = rotation; + if (r.size()>=4) { + + Quat q; + q.x = r[0]; + q.y = r[1]; + q.z = r[2]; + q.w = r[3]; + t.basis=Matrix3(q); + } + } + + + if (scale.size()) { + + Array sc = scale; + if (sc.size()>=3) { + Vector3 s; + s.x=sc[0]; + s.y=sc[1]; + s.z=sc[2]; + t.basis.scale(s); + } + } + + return t; + + +} + +Transform EditorSceneImporterFBXConv::_get_transform(const Dictionary& d) { + + + Transform t; + + if (d.has("translation")) { + Array tr = d["translation"]; + if (tr.size()>=3) { + t.origin.x=tr[0]; + t.origin.y=tr[1]; + t.origin.z=tr[2]; + } + } + + if (d.has("rotation")) { + + Array r = d["rotation"]; + if (r.size()>=4) { + + Quat q; + q.x = r[0]; + q.y = r[1]; + q.z = r[2]; + q.w = r[3]; + t.basis=Matrix3(q); + } + } + + + if (d.has("scale")) { + + Array sc = d["scale"]; + if (sc.size()>=3) { + Vector3 s; + s.x=sc[0]; + s.y=sc[1]; + s.z=sc[2]; + t.basis.scale(s); + } + } + + return t; +} + + +void EditorSceneImporterFBXConv::_detect_bones_in_nodes(State& state,const Array& p_nodes) { + + + for(int i=0;i<p_nodes.size();i++) { + + Dictionary d = p_nodes[i]; + if (d.has("isBone") && bool(d["isBone"])) { + + String bone_name=_id(d["id"]); + print_line("IS BONE: "+bone_name); + if (!state.bones.has(bone_name)) { + state.bones.insert(bone_name,BoneInfo()); + } + + if (!state.bones[bone_name].has_rest) { + state.bones[bone_name].rest=_get_transform(d).affine_inverse(); + } + + state.bones[bone_name].node=d; + + //state.bones[name].rest=_get_transform(b); + } + + if (d.has("parts")) { + + Array parts=d["parts"]; + for(int j=0;j<parts.size();j++) { + + Dictionary p=parts[j]; + if (p.has("bones")) { + Array bones=p["bones"]; + //omfg + for(int k=0;k<bones.size();k++) { + + Dictionary b = bones[k]; + if (b.has("node")) { + + String name = _id(b["node"]); + if (!state.bones.has(name)) { + state.bones.insert(name,BoneInfo()); + } + + state.bones[name].rest=_get_transform(b); + state.bones[name].has_rest=true; + } + } + } + + } + } + + if (d.has("children")) { + + _detect_bones_in_nodes(state,d["children"]); + } + } + +} + +void EditorSceneImporterFBXConv::_parse_skeletons(const String& p_name,State& state, const Array &p_nodes, Skeleton *p_skeleton,int p_parent) { + + + + for(int i=0;i<p_nodes.size();i++) { + + + Dictionary d = p_nodes[i]; + int bone_idx=-1; + String id; + Skeleton* skeleton=p_skeleton; + if (d.has("id")) { + + id=_id(d["id"]); + if (state.bones.has(id)) { + //BONER + if (!skeleton) { + skeleton=memnew( Skeleton ); + state.skeletons[id]=skeleton; + } + bone_idx = skeleton->get_bone_count(); + skeleton->add_bone(id); + skeleton->set_bone_parent(bone_idx,p_parent); + skeleton->set_bone_rest(bone_idx,state.bones[id].rest); + state.bones[id].skeleton=skeleton; + } + } + + if (d.has("children")) { + + _parse_skeletons(id,state,d["children"],skeleton,bone_idx); + } + } + +} + +void EditorSceneImporterFBXConv::_detect_bones(State& state) { + //This format should mark when a node is a bone, + //which is the only thing that Collada does right. + //think about others implementing a parser. + //Just _one_ string and you avoid loads of lines of code to other people. + + for(int i=0;i<state.animations.size();i++) { + + Dictionary an = state.animations[i]; + if (an.has("bones")) { + + Array bo=an["bones"]; + for(int j=0;j<bo.size();j++) { + + Dictionary b=bo[j]; + if (b.has("boneId")) { + + String id = b["boneId"]; + if (!state.bones.has(id)) { + state.bones.insert(id,BoneInfo()); + } + state.bones[id].has_anim_chan=true; //used in anim + + + } + } + } + } + + _detect_bones_in_nodes(state,state.nodes); + _parse_skeletons("",state,state.nodes,NULL,-1); + + print_line("found bones: "+itos(state.bones.size())); + print_line("found skeletons: "+itos(state.skeletons.size())); +} + +Error EditorSceneImporterFBXConv::_parse_bones(State& state,const Array &p_bones,Skeleton* p_skeleton) { + + + + return OK; +} + + +void EditorSceneImporterFBXConv::_add_surface(State& state,Ref<Mesh>& m,const Dictionary &part) { + + if (part.has("meshpartid")) { + + String id = part["meshpartid"]; + ERR_FAIL_COND(!state.surface_cache.has(id)); + + + Ref<Material> mat; + if (part.has("materialid")) { + String matid=part["materialid"]; + if (state.material_cache.has(matid)) { + mat=state.material_cache[matid]; + } + } + int idx = m->get_surface_count(); + + Array array = state.surface_cache[id].array; + PoolVector<float> indices = array[Mesh::ARRAY_BONES]; + if (indices.size() && part.has("bones")) { + + + Map<int,int> index_map; + + Array bones=part["bones"]; + + for(int i=0;i<bones.size();i++) { + + Dictionary bone=bones[i]; + String name=_id(bone["node"]); + + if (state.bones.has(name)) { + int idx=state.bones[name].skeleton->find_bone(name); + if (idx==-1) + idx=0; + index_map[i]=idx; + } + } + + + + int ilen=indices.size(); + { + PoolVector<float>::Write iw=indices.write(); + for(int j=0;j<ilen;j++) { + int b = iw[j]; + ERR_CONTINUE(!index_map.has(b)); + b=index_map[b]; + iw[j]=b; + } + } + + array[Mesh::ARRAY_BONES]=indices; + + + } + + m->add_surface(state.surface_cache[id].primitive,array); + m->surface_set_material(idx,mat); + m->surface_set_name(idx,id); + } + +} + +Error EditorSceneImporterFBXConv::_parse_nodes(State& state,const Array &p_nodes,Node* p_base) { + + for(int i=0;i<p_nodes.size();i++) { + + Dictionary n = p_nodes[i]; + Spatial *node=NULL; + bool skip=false; + + String id; + if (n.has("id")) { + id=_id(n["id"]); + } + + print_line("ID: "+id); + + if (state.skeletons.has(id)) { + + Skeleton *skeleton = state.skeletons[id]; + node=skeleton; + skeleton->localize_rests(); + print_line("IS SKELETON! "); + } else if (state.bones.has(id)) { + if (p_base) + node=p_base->cast_to<Spatial>(); + if (!state.bones[id].has_anim_chan) { + print_line("no has anim "+id); + } + skip=true; + } else if (n.has("parts")) { + //is a mesh + MeshInstance *mesh = memnew( MeshInstance ); + node=mesh; + + Array parts=n["parts"]; + String long_identifier; + for(int j=0;j<parts.size();j++) { + + Dictionary part=parts[j]; + if (part.has("meshpartid")) { + String partid=part["meshpartid"]; + long_identifier+=partid; + } + } + + Ref<Mesh> m; + + if (state.mesh_cache.has(long_identifier)) { + m=state.mesh_cache[long_identifier]; + } else { + m = Ref<Mesh>( memnew( Mesh ) ); + + //and parts are surfaces + for(int j=0;j<parts.size();j++) { + + Dictionary part=parts[j]; + if (part.has("meshpartid")) { + _add_surface(state,m,part); + } + } + + + state.mesh_cache[long_identifier]=m; + } + + mesh->set_mesh(m); + } + + if (!skip) { + + if (!node) { + node = memnew( Spatial ); + } + + node->set_name(id); + node->set_transform(_get_transform(n)); + p_base->add_child(node); + node->set_owner(state.scene); + } + + + if (n.has("children")) { + Error err = _parse_nodes(state,n["children"],node); + if (err) + return err; + } + } + + return OK; +} + + +void EditorSceneImporterFBXConv::_parse_materials(State& state) { + + for(int i=0;i<state.materials.size();i++) { + + Dictionary material = state.materials[i]; + + ERR_CONTINUE(!material.has("id")); + String id = _id(material["id"]); + + Ref<FixedSpatialMaterial> mat = memnew( FixedSpatialMaterial ); + + if (material.has("diffuse")) { + mat->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,_get_color(material["diffuse"])); + } + + if (material.has("specular")) { + mat->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR,_get_color(material["specular"])); + } + + if (material.has("emissive")) { + mat->set_parameter(FixedSpatialMaterial::PARAM_EMISSION,_get_color(material["emissive"])); + } + + if (material.has("shininess")) { + float exp = material["shininess"]; + mat->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR_EXP,exp); + } + + if (material.has("opacity")) { + Color c = mat->get_parameter(FixedSpatialMaterial::PARAM_DIFFUSE); + c.a=material["opacity"]; + mat->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,c); + } + + + if (material.has("textures")) { + + Array textures = material["textures"]; + for(int j=0;j<textures.size();j++) { + + Dictionary texture=textures[j]; + Ref<Texture> tex; + if (texture.has("filename")) { + + + String filename=texture["filename"]; + String path=state.base_path+"/"+filename.replace("\\","/"); + if (state.texture_cache.has(path)) { + tex=state.texture_cache[path]; + } else { + tex = ResourceLoader::load(path,"ImageTexture"); + if (tex.is_null()) { + if (state.missing_deps) + state.missing_deps->push_back(path); + } + state.texture_cache[path]=tex; //add anyway + } + } + + if (tex.is_valid() && texture.has("type")) { + + String type=texture["type"]; + if (type=="DIFFUSE") + mat->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,tex); + else if (type=="SPECULAR") + mat->set_texture(FixedSpatialMaterial::PARAM_SPECULAR,tex); + else if (type=="SHININESS") + mat->set_texture(FixedSpatialMaterial::PARAM_SPECULAR_EXP,tex); + else if (type=="NORMAL") + mat->set_texture(FixedSpatialMaterial::PARAM_NORMAL,tex); + else if (type=="EMISSIVE") + mat->set_texture(FixedSpatialMaterial::PARAM_EMISSION,tex); + } + + } + } + + state.material_cache[id]=mat; + + } + +} + +void EditorSceneImporterFBXConv::_parse_surfaces(State& state) { + + for(int i=0;i<state.meshes.size();i++) { + + Dictionary mesh = state.meshes[i]; + + ERR_CONTINUE(!mesh.has("attributes")); + ERR_CONTINUE(!mesh.has("vertices")); + ERR_CONTINUE(!mesh.has("parts")); + + print_line("MESH #"+itos(i)); + + Array attrlist=mesh["attributes"]; + Array vertices=mesh["vertices"]; + bool exists[Mesh::ARRAY_MAX]; + int ofs[Mesh::ARRAY_MAX]; + int weight_max=0; + int binormal_ofs=-1; + int weight_ofs[4]; + + for(int j=0;j<Mesh::ARRAY_MAX;j++) { + exists[j]=false; + ofs[j]=0; + } + exists[Mesh::ARRAY_INDEX]=true; + float stride=0; + + for(int j=0;j<attrlist.size();j++) { + + String attr=attrlist[j]; + if (attr=="POSITION") { + exists[Mesh::ARRAY_VERTEX]=true; + ofs[Mesh::ARRAY_VERTEX]=stride; + stride+=3; + } else if (attr=="NORMAL") { + exists[Mesh::ARRAY_NORMAL]=true; + ofs[Mesh::ARRAY_NORMAL]=stride; + stride+=3; + } else if (attr=="COLOR") { + exists[Mesh::ARRAY_COLOR]=true; + ofs[Mesh::ARRAY_COLOR]=stride; + stride+=4; + } else if (attr=="COLORPACKED") { + stride+=1; //ignore + } else if (attr=="TANGENT") { + exists[Mesh::ARRAY_TANGENT]=true; + ofs[Mesh::ARRAY_TANGENT]=stride; + stride+=3; + } else if (attr=="BINORMAL") { + binormal_ofs=stride; + stride+=3; + } else if (attr=="TEXCOORD0") { + exists[Mesh::ARRAY_TEX_UV]=true; + ofs[Mesh::ARRAY_TEX_UV]=stride; + stride+=2; + } else if (attr=="TEXCOORD1") { + exists[Mesh::ARRAY_TEX_UV2]=true; + ofs[Mesh::ARRAY_TEX_UV2]=stride; + stride+=2; + } else if (attr.begins_with("TEXCOORD")) { + stride+=2; + } else if (attr.begins_with("BLENDWEIGHT")) { + int idx=attr.replace("BLENDWEIGHT","").to_int(); + if (idx==0) { + exists[Mesh::ARRAY_BONES]=true; + ofs[Mesh::ARRAY_BONES]=stride; + exists[Mesh::ARRAY_WEIGHTS]=true; + ofs[Mesh::ARRAY_WEIGHTS]=stride+1; + } if (idx<4) { + weight_ofs[idx]=stride; + weight_max=MAX(weight_max,idx+1); + } + + stride+=2; + } + + print_line("ATTR "+attr+" OFS: "+itos(stride)); + + } + + Array parts=mesh["parts"]; + + for(int j=0;j<parts.size();j++) { + + + + Dictionary part=parts[j]; + ERR_CONTINUE(!part.has("indices")); + ERR_CONTINUE(!part.has("id")); + + print_line("PART: "+String(part["id"])); + Array indices=part["indices"]; + Map<int,int> iarray; + Map<int,int> array; + + for(int k=0;k<indices.size();k++) { + + int idx = indices[k]; + if (!iarray.has(idx)) { + int map_to=array.size(); + iarray[idx]=map_to; + array[map_to]=idx; + } + } + + print_line("indices total "+itos(indices.size())+" vertices used: "+itos(array.size())); + + Array arrays; + arrays.resize(Mesh::ARRAY_MAX); + + + + for(int k=0;k<Mesh::ARRAY_MAX;k++) { + + + if (!exists[k]) + continue; + print_line("exists: "+itos(k)); + int lofs = ofs[k]; + switch(k) { + + case Mesh::ARRAY_VERTEX: + case Mesh::ARRAY_NORMAL: { + + PoolVector<Vector3> vtx; + vtx.resize(array.size()); + { + int len=array.size(); + PoolVector<Vector3>::Write w = vtx.write(); + for(int l=0;l<len;l++) { + + int pos = array[l]; + w[l].x=vertices[pos*stride+lofs+0]; + w[l].y=vertices[pos*stride+lofs+1]; + w[l].z=vertices[pos*stride+lofs+2]; + } + } + arrays[k]=vtx; + + } break; + case Mesh::ARRAY_TANGENT: { + + if (binormal_ofs<0) + break; + + PoolVector<float> tangents; + tangents.resize(array.size()*4); + { + int len=array.size(); + + PoolVector<float>::Write w = tangents.write(); + for(int l=0;l<len;l++) { + + int pos = array[l]; + Vector3 n; + n.x=vertices[pos*stride+ofs[Mesh::ARRAY_NORMAL]+0]; + n.y=vertices[pos*stride+ofs[Mesh::ARRAY_NORMAL]+1]; + n.z=vertices[pos*stride+ofs[Mesh::ARRAY_NORMAL]+2]; + Vector3 t; + t.x=vertices[pos*stride+lofs+0]; + t.y=vertices[pos*stride+lofs+1]; + t.z=vertices[pos*stride+lofs+2]; + Vector3 bi; + bi.x=vertices[pos*stride+binormal_ofs+0]; + bi.y=vertices[pos*stride+binormal_ofs+1]; + bi.z=vertices[pos*stride+binormal_ofs+2]; + float d = bi.dot(n.cross(t)); + + w[l*4+0]=t.x; + w[l*4+1]=t.y; + w[l*4+2]=t.z; + w[l*4+3]=d; + + } + } + arrays[k]=tangents; + + } break; + case Mesh::ARRAY_COLOR: { + + PoolVector<Color> cols; + cols.resize(array.size()); + { + int len=array.size(); + PoolVector<Color>::Write w = cols.write(); + for(int l=0;l<len;l++) { + + int pos = array[l]; + w[l].r=vertices[pos*stride+lofs+0]; + w[l].g=vertices[pos*stride+lofs+1]; + w[l].b=vertices[pos*stride+lofs+2]; + w[l].a=vertices[pos*stride+lofs+3]; + } + } + arrays[k]=cols; + + } break; + case Mesh::ARRAY_TEX_UV: + case Mesh::ARRAY_TEX_UV2: { + + PoolVector<Vector2> uvs; + uvs.resize(array.size()); + { + int len=array.size(); + PoolVector<Vector2>::Write w = uvs.write(); + for(int l=0;l<len;l++) { + + int pos = array[l]; + w[l].x=vertices[pos*stride+lofs+0]; + w[l].y=vertices[pos*stride+lofs+1]; + w[l].y=1.0-w[l].y; + } + } + arrays[k]=uvs; + + } break; + case Mesh::ARRAY_BONES: + case Mesh::ARRAY_WEIGHTS: { + + PoolVector<float> arr; + arr.resize(array.size()*4); + int po=k==Mesh::ARRAY_WEIGHTS?1:0; + lofs=ofs[Mesh::ARRAY_BONES]; + { + int len=array.size(); + + PoolVector<float>::Write w = arr.write(); + for(int l=0;l<len;l++) { + + int pos = array[l]; + + for(int m=0;m<4;m++) { + + float val=0; + if (m<=weight_max) + val=vertices[pos*stride+lofs+m*2+po]; + w[l*4+m]=val; + } + } + } + + arrays[k]=arr; + } break; + case Mesh::ARRAY_INDEX: { + + PoolVector<int> arr; + arr.resize(indices.size()); + { + int len=indices.size(); + + PoolVector<int>::Write w = arr.write(); + for(int l=0;l<len;l++) { + + w[l]=iarray[ indices[l] ]; + } + } + + arrays[k]=arr; + + } break; + + + } + + + } + + Mesh::PrimitiveType pt=Mesh::PRIMITIVE_TRIANGLES; + + if (part.has("type")) { + String type=part["type"]; + if (type=="LINES") + pt=Mesh::PRIMITIVE_LINES; + else if (type=="POINTS") + pt=Mesh::PRIMITIVE_POINTS; + else if (type=="TRIANGLE_STRIP") + pt=Mesh::PRIMITIVE_TRIANGLE_STRIP; + else if (type=="LINE_STRIP") + pt=Mesh::PRIMITIVE_LINE_STRIP; + } + + if (pt==Mesh::PRIMITIVE_TRIANGLES) { + PoolVector<int> ia=arrays[Mesh::ARRAY_INDEX]; + int len=ia.size(); + { + PoolVector<int>::Write w=ia.write(); + for(int l=0;l<len;l+=3) { + SWAP(w[l+1],w[l+2]); + } + } + arrays[Mesh::ARRAY_INDEX]=ia; + + + } + SurfaceInfo si; + si.array=arrays; + si.primitive=pt; + state.surface_cache[_id(part["id"])]=si; + + } + } +} + + +Error EditorSceneImporterFBXConv::_parse_animations(State& state) { + + AnimationPlayer *ap = memnew( AnimationPlayer ); + + state.scene->add_child(ap); + ap->set_owner(state.scene); + + for(int i=0;i<state.animations.size();i++) { + + Dictionary anim = state.animations[i]; + ERR_CONTINUE(!anim.has("id")); + Ref<Animation> an = memnew( Animation ); + an->set_name(_id(anim["id"])); + + + if (anim.has("bones")) { + + Array bone_tracks = anim["bones"]; + for(int j=0;j<bone_tracks.size();j++) { + Dictionary bone_track=bone_tracks[j]; + String bone = bone_track["boneId"]; + if (!bone_track.has("keyframes")) + continue; + if (!state.bones.has(bone)) + continue; + + Skeleton *sk = state.bones[bone].skeleton; + + if (!sk) + continue; + int bone_idx=sk->find_bone(bone); + if (bone_idx==-1) + continue; + + + + String path = state.scene->get_path_to(sk); + path+=":"+bone; + an->add_track(Animation::TYPE_TRANSFORM); + int tidx = an->get_track_count()-1; + an->track_set_path(tidx,path); + + + Dictionary parent_xform_dict; + Dictionary xform_dict; + + if (state.bones.has(bone)) { + xform_dict=state.bones[bone].node; + } + + + Array parent_keyframes; + if (sk->get_bone_parent(bone_idx)!=-1) { + String parent_name = sk->get_bone_name(sk->get_bone_parent(bone_idx)); + if (state.bones.has(parent_name)) { + parent_xform_dict=state.bones[parent_name].node; + } + + print_line("parent for "+bone+"? "+parent_name+" XFD: "+String(Variant(parent_xform_dict))); + for(int k=0;k<bone_tracks.size();k++) { + Dictionary d = bone_tracks[k]; + if (d["boneId"]==parent_name) { + parent_keyframes=d["keyframes"]; + print_line("found keyframes"); + break; + } + } + + + } + + print_line("BONE XFD "+String(Variant(xform_dict))); + + Array keyframes=bone_track["keyframes"]; + + for(int k=0;k<keyframes.size();k++) { + + Dictionary key=keyframes[k]; + Transform xform=_get_transform_mixed(key,xform_dict); + float time = key["keytime"]; + time=time/1000.0; +#if 0 + if (parent_keyframes.size()) { + //localize + print_line(itos(k)+" localizate for: "+bone); + + float prev_kt=-1; + float kt; + int idx=0; + + for(int l=0;l<parent_keyframes.size();l++) { + + Dictionary d=parent_keyframes[l]; + kt=d["keytime"]; + kt=kt/1000.0; + if (kt>time) + break; + prev_kt=kt; + idx++; + + } + + Transform t; + if (idx==0) { + t=_get_transform_mixed(parent_keyframes[0],parent_xform_dict); + } else if (idx==parent_keyframes.size()){ + t=_get_transform_mixed(parent_keyframes[idx-1],parent_xform_dict); + } else { + t=_get_transform_mixed(parent_keyframes[idx-1],parent_xform_dict); + float d = (time-prev_kt)/(kt-prev_kt); + if (d>0) { + Transform t2=_get_transform_mixed(parent_keyframes[idx],parent_xform_dict); + t=t.interpolate_with(t2,d); + } else { + print_line("exact: "+rtos(kt)); + } + } + + xform = t.affine_inverse() * xform; //localize + } else if (!parent_xform_dict.empty()) { + Transform t = _get_transform(parent_xform_dict); + xform = t.affine_inverse() * xform; //localize + } +#endif + + xform = sk->get_bone_rest(bone_idx).affine_inverse() * xform; + + + Quat q = xform.basis; + q.normalize(); + Vector3 s = xform.basis.get_scale(); + Vector3 l = xform.origin; + + + + an->transform_track_insert_key(tidx,time,l,q,s); + + } + + } + + + } + + + ap->add_animation(_id(anim["id"]),an); + + } + + return OK; +} + +Error EditorSceneImporterFBXConv::_parse_json(State& state, const String &p_path) { + + //not the happiest.... + Vector<uint8_t> data = FileAccess::get_file_as_array(p_path); + ERR_FAIL_COND_V(!data.size(),ERR_FILE_CANT_OPEN); + String str; + bool utferr = str.parse_utf8((const char*)data.ptr(),data.size()); + ERR_FAIL_COND_V(utferr,ERR_PARSE_ERROR); + + Dictionary dict; + Error err = dict.parse_json(str); + str=String(); //free mem immediately + ERR_FAIL_COND_V(err,err); + + if (dict.has("meshes")) + state.meshes=dict["meshes"]; + if (dict.has("materials")) + state.materials=dict["materials"]; + if (dict.has("nodes")) + state.nodes=dict["nodes"]; + if (dict.has("animations")) + state.animations=dict["animations"]; + + + state.scene = memnew( Spatial ); + _detect_bones(state); + _parse_surfaces(state); + _parse_materials(state); + err = _parse_nodes(state,state.nodes,state.scene); + if (err) + return err; + + if (state.import_animations) { + err = _parse_animations(state); + if (err) + return err; + } + + print_line("JSON PARSED O-K!"); + + return OK; +} + +Error EditorSceneImporterFBXConv::_parse_fbx(State& state,const String& p_path) { + + state.base_path=p_path.get_base_dir(); + + if (p_path.to_lower().ends_with("g3dj")) { + return _parse_json(state,p_path.basename()+".g3dj"); + } + + String tool = EDITOR_DEF("fbxconv/path",""); + ERR_FAIL_COND_V( !FileAccess::exists(tool),ERR_UNCONFIGURED); + String wine = EDITOR_DEF("fbxconv/use_wine",""); + + List<String> args; + String path=p_path; + if (wine!="") { + List<String> wpargs; + wpargs.push_back("-w"); + wpargs.push_back(p_path); + String pipe; //winepath to convert to windows path + int wpres; + Error wperr = OS::get_singleton()->execute(wine+"path",wpargs,true,NULL,&pipe,&wpres); + ERR_FAIL_COND_V(wperr!=OK,ERR_CANT_CREATE); + ERR_FAIL_COND_V(wpres!=0,ERR_CANT_CREATE); + path=pipe.strip_edges(); + args.push_back(tool); + tool=wine; + } + + args.push_back("-o"); + args.push_back("G3DJ"); + args.push_back(path); + + int res; + Error err = OS::get_singleton()->execute(tool,args,true,NULL,NULL,&res); + ERR_FAIL_COND_V(err!=OK,ERR_CANT_CREATE); + ERR_FAIL_COND_V(res!=0,ERR_CANT_CREATE); + + return _parse_json(state,p_path.basename()+".g3dj"); + + +} + +Node* EditorSceneImporterFBXConv::import_scene(const String& p_path,uint32_t p_flags,List<String> *r_missing_deps,Error* r_err){ + + State state; + state.scene=NULL; + state.missing_deps=r_missing_deps; + state.import_animations=p_flags&IMPORT_ANIMATION; + Error err = _parse_fbx(state,p_path); + if (err!=OK) { + if (r_err) + *r_err=err; + return NULL; + } + + + return state.scene; +} +Ref<Animation> EditorSceneImporterFBXConv::import_animation(const String& p_path,uint32_t p_flags){ + + + return Ref<Animation>(); +} + + +EditorSceneImporterFBXConv::EditorSceneImporterFBXConv() { + + EDITOR_DEF("fbxconv/path",""); +#ifndef WINDOWS_ENABLED + EDITOR_DEF("fbxconv/use_wine",""); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"fbxconv/use_wine",PROPERTY_HINT_GLOBAL_FILE)); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"fbxconv/path",PROPERTY_HINT_GLOBAL_FILE)); +#else + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"fbxconv/path",PROPERTY_HINT_GLOBAL_FILE,"exe")); +#endif + +} +#endif diff --git a/editor/io_plugins/editor_scene_importer_fbxconv.h b/editor/io_plugins/editor_scene_importer_fbxconv.h new file mode 100644 index 0000000000..da7058ad88 --- /dev/null +++ b/editor/io_plugins/editor_scene_importer_fbxconv.h @@ -0,0 +1,111 @@ +/*************************************************************************/ +/* editor_scene_importer_fbxconv.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITOR_SCENE_IMPORTER_FBXCONV_H +#define EDITOR_SCENE_IMPORTER_FBXCONV_H + +#include "editor/io_plugins/editor_scene_import_plugin.h" +#include "scene/3d/skeleton.h" + +#if 0 + +class EditorSceneImporterFBXConv : public EditorSceneImporter { + + GDCLASS(EditorSceneImporterFBXConv,EditorSceneImporter ); + + + struct BoneInfo { + + Skeleton *skeleton; + Transform rest; + int index; + bool has_anim_chan; + bool has_rest; + Dictionary node; + BoneInfo() { + has_rest=false; + skeleton=NULL; + index=-1; + has_anim_chan=false; + } + }; + + struct SurfaceInfo { + Array array; + Mesh::PrimitiveType primitive; + }; + + struct State { + + Node *scene; + Array meshes; + Array materials; + Array nodes; + Array animations; + Map<String,BoneInfo > bones; + Map<String,Skeleton*> skeletons; + Map<String,Ref<Mesh> > mesh_cache; + Map<String,SurfaceInfo> surface_cache; + Map<String,Ref<Material> > material_cache; + Map<String,Ref<Texture> > texture_cache; + List<String> *missing_deps; + String base_path; + bool import_animations; + }; + + String _id(const String& p_id) const; + + Transform _get_transform_mixed(const Dictionary& d, const Dictionary& dbase); + Transform _get_transform(const Dictionary& d); + Color _get_color(const Array& a); + void _detect_bones_in_nodes(State& state,const Array& p_nodes); + void _detect_bones(State& state); + + Error _parse_bones(State& state,const Array &p_bones,Skeleton* p_skeleton); + void _parse_skeletons(const String& p_name,State& state, const Array &p_nodes, Skeleton*p_skeleton=NULL, int p_parent=-1); + + void _add_surface(State& state,Ref<Mesh>& m,const Dictionary &part); + Error _parse_nodes(State& state,const Array &p_nodes,Node* p_base); + Error _parse_animations(State& state); + void _parse_materials(State& state); + void _parse_surfaces(State& state); + Error _parse_json(State& state,const String& p_path); + Error _parse_fbx(State &state, const String &p_path); + +public: + + virtual uint32_t get_import_flags() const; + virtual void get_extensions(List<String> *r_extensions) const; + virtual Node* import_scene(const String& p_path,uint32_t p_flags,List<String> *r_missing_deps=NULL,Error* r_err=NULL); + virtual Ref<Animation> import_animation(const String& p_path,uint32_t p_flags); + + EditorSceneImporterFBXConv(); +}; + +#endif // EDITOR_SCENE_IMPORTER_FBXCONV_H +#endif diff --git a/editor/io_plugins/editor_texture_import_plugin.cpp b/editor/io_plugins/editor_texture_import_plugin.cpp new file mode 100644 index 0000000000..8bafe80673 --- /dev/null +++ b/editor/io_plugins/editor_texture_import_plugin.cpp @@ -0,0 +1,1893 @@ +/*************************************************************************/ +/* editor_texture_import_plugin.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 "editor_texture_import_plugin.h" +#if 0 +#include "io/image_loader.h" +#include "editor/editor_node.h" +#include "io/resource_saver.h" +#include "editor_atlas.h" +#include "editor/editor_settings.h" +#include "io/md5.h" +#include "io/marshalls.h" +#include "global_config.h" +#include "scene/gui/check_button.h" +#include "scene/gui/button_group.h" +#include "scene/gui/margin_container.h" +#include "scene/io/resource_format_image.h" + +static const char *flag_names[]={ + ("Streaming Format"), + ("Fix Border Alpha"), + ("Alpha Bit Hint"), + ("Compress Extra (PVRTC2)"), + ("No MipMaps"), + ("Repeat"), + ("Filter (Magnifying)"), + ("Premultiply Alpha"), + ("Convert SRGB->Linear"), + ("Convert NormalMap to XY"), + ("Use Anisotropy"), + NULL +}; + +#if 0 // not used +static const char *flag_short_names[]={ + "Stream", + "FixBorder", + "AlphBit", + "ExtComp", + "NoMipMap", + "Repeat", + "Filter", + "PMAlpha", + "ToLinear", + "ToRG", + "Anisoropic", + NULL +}; +#endif + + +void EditorImportTextureOptions::set_format(EditorTextureImportPlugin::ImageFormat p_format) { + + updating=true; + format->select(p_format); + if (p_format==EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { + quality_vb->show(); + } else { + quality_vb->hide(); + } + + updating=false; + +} + +EditorTextureImportPlugin::ImageFormat EditorImportTextureOptions::get_format() const{ + + return (EditorTextureImportPlugin::ImageFormat)format->get_selected(); + +} + +void EditorImportTextureOptions::set_flags(uint32_t p_flags){ + + updating=true; + for(int i=0;i<items.size();i++) { + + items[i]->set_checked(0,p_flags&(1<<i)); + } + updating=false; + +} + +void EditorImportTextureOptions::set_quality(float p_quality) { + + quality->set_value(p_quality); +} + +float EditorImportTextureOptions::get_quality() const { + + return quality->get_value(); +} + + +uint32_t EditorImportTextureOptions::get_flags() const{ + + uint32_t f=0; + for(int i=0;i<items.size();i++) { + + if (items[i]->is_checked(0)) + f|=(1<<i); + } + + return f; +} + +void EditorImportTextureOptions::_changedp(int p_value) { + + _changed(); +} + +void EditorImportTextureOptions::_changed() { + + if (updating) + return; + if (format->get_selected()==EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { + quality_vb->show(); + } else { + quality_vb->hide(); + } + + emit_signal("changed"); +} + + +void EditorImportTextureOptions::_bind_methods() { + + ClassDB::bind_method("_changed",&EditorImportTextureOptions::_changed); + ClassDB::bind_method("_changedp",&EditorImportTextureOptions::_changedp); + + ADD_SIGNAL(MethodInfo("changed")); +} + + +void EditorImportTextureOptions::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + + flags->connect("item_edited",this,"_changed"); + format->connect("item_selected",this,"_changedp"); + } +} + +void EditorImportTextureOptions::show_2d_notice() { + + //notice_for_2d->show(); +} + +EditorImportTextureOptions::EditorImportTextureOptions() { + + + add_constant_override("separation",3); + updating=false; + format = memnew( OptionButton ); + + format->add_item(TTR("Uncompressed"),EditorTextureImportPlugin::IMAGE_FORMAT_UNCOMPRESSED); + format->add_item(TTR("Compress Lossless (PNG)"),EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS); + format->add_item(TTR("Compress Lossy (WebP)"),EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); + format->add_item(TTR("Compress (VRAM)"),EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM); + + + add_margin_child(TTR("Texture Format"),format); + + quality_vb = memnew( VBoxContainer ); + + HBoxContainer *quality_hb = memnew(HBoxContainer); + HSlider *hs = memnew( HSlider ); + hs->set_h_size_flags(SIZE_EXPAND_FILL); + hs->set_stretch_ratio(0.8); + quality_hb->add_child(hs); + quality_hb->set_h_size_flags(SIZE_EXPAND_FILL); + SpinBox *sb = memnew( SpinBox ); + sb->set_h_size_flags(SIZE_EXPAND_FILL); + sb->set_stretch_ratio(0.2); + quality_hb->add_child(sb); + sb->share(hs); + hs->set_min(0); + hs->set_max(1.0); + hs->set_step(0.01); + hs->set_value(0.7); + quality=hs; + quality_vb->add_margin_child(TTR("Texture Compression Quality (WebP):"),quality_hb); + + add_child(quality_vb); + + flags = memnew( Tree ); + flags->set_hide_root(true); + TreeItem *root = flags->create_item(); + + + + const char ** fname=flag_names; + + while( *fname ) { + + TreeItem*ti = flags->create_item(root); + ti->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); + ti->set_text(0,*fname); + ti->set_editable(0,true); + items.push_back(ti); + fname++; + } + + add_margin_child(TTR("Texture Options"),flags,true); + + +} + +/////////////////////////////////////////////////////////// + + + + +class EditorTextureImportDialog : public ConfirmationDialog { + + GDCLASS(EditorTextureImportDialog,ConfirmationDialog); + + + + HBoxContainer *mode_hb; + CheckBox *mode_check[EditorTextureImportPlugin::MODE_MAX]; + + EditorImportTextureOptions *texture_options; + + EditorTextureImportPlugin::Mode mode; + //EditorNode *editor; + + LineEdit *import_path; + LineEdit *save_path; + EditorFileDialog *file_select; + EditorFileDialog *save_file_select; + EditorDirDialog *save_select; + OptionButton *texture_action; + ConfirmationDialog *error_dialog; + CheckButton *crop_source; + SpinBox *size; + + MarginContainer *size_mc; + Label* size_label; + + Label* source_label; + Label *notice_for_2d; + + EditorTextureImportPlugin *plugin; + + void _mode_changed(int p_mode); + void _choose_files(const Vector<String>& p_path); + void _choose_file(const String& p_path); + void _choose_save_dir(const String& p_path); + void _browse(); + void _browse_target(); + void _import(); + + +protected: + + void _notification(int p_what); + static void _bind_methods(); +public: + + + void setup_multiple_import_3d(const Vector<String>& p_path,const String& p_dest) { + + _mode_changed(EditorTextureImportPlugin::MODE_TEXTURE_3D); + _choose_files(p_path); + _choose_save_dir(p_dest); + } + + void add_sources_and_dest(const Vector<String>& p_path,const String& p_dest) { + + _choose_files(p_path); + _choose_save_dir(p_dest); + } + + Error import(const String& p_from, const String& p_to, const String& p_preset); + void popup_import(const String &p_from=String()); + EditorTextureImportDialog(EditorTextureImportPlugin *p_plugin=NULL); +}; + + +///////////////////////////////////////////////////////// + + + + +void EditorTextureImportDialog::_choose_files(const Vector<String>& p_path) { + + String files; + for(int i=0;i<p_path.size();i++) { + + if (i>0) + files+=","; + files+=p_path[i]; + } + /* + if (p_path.size()) { + String srctex=p_path[0]; + String ipath = EditorImportDB::get_singleton()->find_source_path(srctex); + + if (ipath!="") + save_path->set_text(ipath.get_base_dir()); + }*/ + import_path->set_text(files); + +} + + + +void EditorTextureImportDialog::_choose_file(const String& p_path) { + + + import_path->set_text(p_path); + +} +void EditorTextureImportDialog::_choose_save_dir(const String& p_path) { + + save_path->set_text(p_path); +} + + +void EditorTextureImportDialog::_import() { + + + //ImportMonitorBlock imb; + + Vector<String> files=import_path->get_text().split(","); + + if (!files.size()) { + + error_dialog->set_text(TTR("Please specify some files!")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + } + + String dst_path=save_path->get_text(); + + if (save_path->get_text().strip_edges()=="") { + error_dialog->set_text(TTR("Target path is empty.")); + error_dialog->popup_centered_minsize(); + return; + } + + if (!save_path->get_text().begins_with("res://")) { + error_dialog->set_text(TTR("Target path must be a complete resource path.")); + error_dialog->popup_centered_minsize(); + return; + } + + + if (mode!=EditorTextureImportPlugin::MODE_ATLAS && mode!=EditorTextureImportPlugin::MODE_LARGE && !DirAccess::exists(save_path->get_text())) { + error_dialog->set_text(TTR("Target path must exist.")); + error_dialog->popup_centered_minsize(); + return; + } + + if (mode==EditorTextureImportPlugin::MODE_ATLAS) { //atlas + + if (files.size()==0) { + + error_dialog->set_text(TTR("At least one file needed for Atlas.")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + + } + String dst_file = dst_path; + //dst_file=dst_file.basename()+".tex"; + Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); + //imd->set_editor(); + for(int i=0;i<files.size();i++) { + imd->add_source(EditorImportPlugin::validate_source_path(files[i])); + } + imd->set_option("format",texture_options->get_format()); + imd->set_option("flags",texture_options->get_flags()); + imd->set_option("quality",texture_options->get_quality()); + imd->set_option("atlas",true); + imd->set_option("atlas_size",int(size->get_value())); + imd->set_option("large",false); + imd->set_option("crop",crop_source->is_pressed()); + imd->set_option("mode",mode); + + Error err = plugin->import(dst_file,imd); + if (err) { + + error_dialog->set_text(TTR("Error importing:")+" "+dst_file.get_file()); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + + } + } else if (mode==EditorTextureImportPlugin::MODE_LARGE) { //large + + if (files.size()!=1) { + + error_dialog->set_text(TTR("Only one file is required for large texture.")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + + } + String dst_file = dst_path; + //dst_file=dst_file.basename()+".tex"; + Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); + //imd->set_editor(); + for(int i=0;i<files.size();i++) { + imd->add_source(EditorImportPlugin::validate_source_path(files[i])); + } + imd->set_option("format",texture_options->get_format()); + imd->set_option("flags",texture_options->get_flags()); + imd->set_option("quality",texture_options->get_quality()); + imd->set_option("atlas",false); + imd->set_option("large",true); + imd->set_option("large_cell_size",int(size->get_value())); + imd->set_option("crop",crop_source->is_pressed()); + imd->set_option("mode",mode); + + Error err = plugin->import(dst_file,imd); + if (err) { + + error_dialog->set_text(TTR("Error importing:")+" "+dst_file.get_file()); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + + } + } else { + + + for(int i=0;i<files.size();i++) { + + String dst_file = dst_path.plus_file(files[i].get_file()); + dst_file=dst_file.get_basename()+".tex"; + Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); + //imd->set_editor(); + imd->add_source(EditorImportPlugin::validate_source_path(files[i])); + imd->set_option("format",texture_options->get_format()); + imd->set_option("flags",texture_options->get_flags()); + imd->set_option("quality",texture_options->get_quality()); + imd->set_option("atlas",false); + imd->set_option("large",false); + imd->set_option("mode",mode); + + Error err = plugin->import(dst_file,imd); + if (err) { + + error_dialog->set_text(TTR("Error importing:")+" "+dst_file.get_file()); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + + } + } + } + + hide(); +} + +void EditorTextureImportDialog::_browse() { + + file_select->popup_centered_ratio(); +} + +void EditorTextureImportDialog::_browse_target() { + + if (mode==EditorTextureImportPlugin::MODE_ATLAS || mode==EditorTextureImportPlugin::MODE_LARGE) { + save_file_select->popup_centered_ratio(); + } else { + save_select->popup_centered_ratio(); + } + +} + + +void EditorTextureImportDialog::popup_import(const String& p_from) { + + popup_centered(Size2(600,500)*EDSCALE); + if (p_from!="") { + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from); + ERR_FAIL_COND(!rimd.is_valid()); + + if (rimd->has_option("mode")) { + //new imported stuff uses this option + _mode_changed(rimd->get_option("mode")); + } else { + //this one is for compatibility, will have to guess it + if (rimd->has_option("atlas") && rimd->get_option("atlas")) { + _mode_changed(EditorTextureImportPlugin::MODE_ATLAS); + } else if (rimd->has_option("large") && rimd->get_option("large")) { + _mode_changed(EditorTextureImportPlugin::MODE_LARGE); + } else { + //guess by usage of mipmaps..? + _mode_changed(EditorTextureImportPlugin::MODE_TEXTURE_2D); + } + + } + + if (mode==EditorTextureImportPlugin::MODE_ATLAS || mode==EditorTextureImportPlugin::MODE_LARGE) + save_path->set_text(p_from); + else + save_path->set_text(p_from.get_base_dir()); + + texture_options->set_format(EditorTextureImportPlugin::ImageFormat(int(rimd->get_option("format")))); + texture_options->set_flags(rimd->get_option("flags")); + texture_options->set_quality(rimd->get_option("quality")); + String src = ""; + for(int i=0;i<rimd->get_source_count();i++) { + if (i>0) + src+=","; + src+=EditorImportPlugin::expand_source_path(rimd->get_source_path(i)); + } + import_path->set_text(src); + } +} + + +void EditorTextureImportDialog::_notification(int p_what) { + + + if (p_what==NOTIFICATION_ENTER_TREE) { + + + List<String> extensions; + ImageLoader::get_recognized_extensions(&extensions); + //ResourceLoader::get_recognized_extensions_for_type("PackedTexture",&extensions); + file_select->clear_filters(); + for(int i=0;i<extensions.size();i++) { + + file_select->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); + } + } +} + +Error EditorTextureImportDialog::import(const String& p_from, const String& p_to, const String& p_preset) { + + + import_path->set_text(p_from); + save_path->set_text(p_to); + _import(); + + return OK; +} + +void EditorTextureImportDialog::_mode_changed(int p_mode) { + + mode = EditorTextureImportPlugin::Mode(p_mode); + + for(int i=0;i<EditorTextureImportPlugin::MODE_MAX;i++) { + mode_check[i]->set_pressed(i==mode); + } + + if (p_mode==EditorTextureImportPlugin::MODE_ATLAS) { + + size_label->set_text(TTR("Max Texture Size:")); + size->set_value(2048); + crop_source->show(); + size_label->show(); + size->show(); + + texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); + texture_options->set_quality(0.7); + texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); + set_title(TTR("Import Textures for Atlas (2D)")); + + } else { + crop_source->hide(); + } + + + if (p_mode==EditorTextureImportPlugin::MODE_LARGE) { + + size_label->set_text(TTR("Cell Size:")); + size->set_value(256); + size_label->show(); + size->show(); + + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); + save_file_select->add_filter("*.ltex;"+TTR("Large Texture")); + + texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); + texture_options->set_quality(0.7); + texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS); + set_title(TTR("Import Large Textures (2D)")); + source_label->set_text(TTR("Source Texture")); + + } else { + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); + save_file_select->add_filter("*.tex;"+TTR("Base Atlas Texture")); + source_label->set_text(TTR("Source Texture(s)")); + } + + if (p_mode==EditorTextureImportPlugin::MODE_TEXTURE_2D) { + + size_label->hide(); + size->hide(); + + texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); + texture_options->set_quality(0.7); + texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); + notice_for_2d->show(); + set_title(TTR("Import Textures for 2D")); + + } else { + notice_for_2d->hide(); + } + + if (p_mode==EditorTextureImportPlugin::MODE_TEXTURE_3D) { + + size_label->hide(); + size->hide(); + //texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_); + //texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS); + texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_FILTER|EditorTextureImportPlugin::IMAGE_FLAG_REPEAT); + texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM); + set_title(TTR("Import Textures for 3D")); + } +} + +void EditorTextureImportDialog::_bind_methods() { + + + ClassDB::bind_method("_choose_files",&EditorTextureImportDialog::_choose_files); + ClassDB::bind_method("_choose_file",&EditorTextureImportDialog::_choose_file); + ClassDB::bind_method("_choose_save_dir",&EditorTextureImportDialog::_choose_save_dir); + ClassDB::bind_method("_import",&EditorTextureImportDialog::_import); + ClassDB::bind_method("_browse",&EditorTextureImportDialog::_browse); + ClassDB::bind_method("_browse_target",&EditorTextureImportDialog::_browse_target); + ClassDB::bind_method("_mode_changed",&EditorTextureImportDialog::_mode_changed); + //ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); +} + +EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* p_plugin) { + + + + + + plugin=p_plugin; + set_title(TTR("Import Textures")); + + mode_hb = memnew( HBoxContainer ); + add_child(mode_hb); + //set_child_rect(mode_hb); + + VBoxContainer *vbcg = memnew( VBoxContainer); + + + mode_hb->add_child(vbcg); + mode_hb->add_constant_override("separation",15); + VBoxContainer *bg = memnew( VBoxContainer ); + vbcg->add_margin_child("Import Mode",bg); + + for(int i=0;i<EditorTextureImportPlugin::MODE_MAX;i++) { + String mode_name[EditorTextureImportPlugin::MODE_MAX]={ + TTR("2D Texture"), + TTR("3D Texture"), + TTR("Atlas Texture"), + TTR("Large Texture") + }; + + + mode_check[i]=memnew(CheckBox); + bg->add_child(mode_check[i]); + mode_check[i]->set_text(mode_name[i]); + mode_check[i]->connect("pressed",this,"_mode_changed",varray(i)); + } + + VBoxContainer *vbc = memnew(VBoxContainer); + mode_hb->add_child(vbc); + vbc->set_h_size_flags(SIZE_EXPAND_FILL); + vbc->add_constant_override("separation",4); + + notice_for_2d = memnew( Label ); + notice_for_2d->set_text(TTR("NOTICE: Importing 2D textures is not mandatory. Just copy png/jpg files to the project.")); + //notice_for_2d->set_custom_minimum_size(Size2(0,50)); + notice_for_2d->set_autowrap(true); + notice_for_2d->hide(); + vbcg->add_child(notice_for_2d); + notice_for_2d->set_v_size_flags(SIZE_EXPAND_FILL); + notice_for_2d->set_valign(Label::VALIGN_BOTTOM); + + VBoxContainer *source_vb=memnew(VBoxContainer); + MarginContainer *source_mc = vbc->add_margin_child(TTR("Source Texture(s):"),source_vb); + + source_label = vbc->get_child(source_mc->get_index()-1)->cast_to<Label>(); + + HBoxContainer *hbc = memnew( HBoxContainer ); + source_vb->add_child(hbc); + + import_path = memnew( LineEdit ); + import_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(import_path); + crop_source = memnew( CheckButton ); + crop_source->set_pressed(true); + source_vb->add_child(crop_source); + crop_source->set_text(TTR("Crop empty space.")); + + + Button * import_choose = memnew( Button ); + import_choose->set_text(" .. "); + hbc->add_child(import_choose); + + import_choose->connect("pressed", this,"_browse"); + + hbc = memnew( HBoxContainer ); + vbc->add_margin_child(TTR("Target Path:"),hbc); + + size = memnew( SpinBox ); + size->set_min(128); + size->set_max(16384); + + + size->set_value(256); + size_mc=vbc->add_margin_child(TTR("Cell Size:"),size); + size_label=vbc->get_child(size_mc->get_index()-1)->cast_to<Label>(); + + + save_path = memnew( LineEdit ); + save_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(save_path); + + Button * save_choose = memnew( Button ); + save_choose->set_text(" .. "); + hbc->add_child(save_choose); + + save_choose->connect("pressed", this,"_browse_target"); + + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + add_child(file_select); + + file_select->connect("files_selected", this,"_choose_files"); + file_select->connect("file_selected", this,"_choose_file"); + + save_file_select = memnew(EditorFileDialog); + save_file_select->set_access(EditorFileDialog::ACCESS_RESOURCES); + add_child(save_file_select); + save_file_select->set_mode(EditorFileDialog::MODE_SAVE_FILE); + save_file_select->clear_filters(); + + save_file_select->connect("file_selected", this,"_choose_save_dir"); + + save_select = memnew( EditorDirDialog ); + add_child(save_select); + + //save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); + save_select->connect("dir_selected", this,"_choose_save_dir"); + + get_ok()->connect("pressed", this,"_import"); + get_ok()->set_text(TTR("Import")); + + //move stuff up + /* + for(int i=0;i<4;i++) + vbc->move_child( vbc->get_child( vbc->get_child_count() -1), 0); + */ + + error_dialog = memnew ( ConfirmationDialog ); + add_child(error_dialog); + error_dialog->get_ok()->set_text(TTR("Accept")); + //error_dialog->get_cancel()->hide(); + + set_hide_on_ok(false); + + texture_options = memnew( EditorImportTextureOptions ); + vbc->add_child(texture_options); + texture_options->set_v_size_flags(SIZE_EXPAND_FILL); + + _mode_changed(EditorTextureImportPlugin::MODE_TEXTURE_3D); + + + //GLOBAL_DEF("import/shared_textures","res://"); + //Globals::get_singleton()->set_custom_property_info("import/shared_textures",PropertyInfo(Variant::STRING,"import/shared_textures",PROPERTY_HINT_DIR)); + + +} + + + +/////////////////////////////////////////////////////////// + + +String EditorTextureImportPlugin::get_name() const { + + return "texture"; +#if 0 //old names, kept for compatibility reference + switch(mode) { + case MODE_TEXTURE_2D: { + + return "texture_2d"; + } break; + case MODE_TEXTURE_3D: { + + return "texture_3d"; + + } break; + case MODE_ATLAS: { + + return "texture_atlas"; + } break; + case MODE_LARGE: { + + return "texture_large"; + } break; + + } + + + return ""; +#endif +} + +String EditorTextureImportPlugin::get_visible_name() const { + + return TTR("Texture"); + +} +void EditorTextureImportPlugin::import_dialog(const String& p_from) { + + dialog->popup_import(p_from); +} + +void EditorTextureImportPlugin::compress_image(EditorExportPlatform::ImageCompression p_mode,Image& image,bool p_smaller) { + + + switch(p_mode) { + case EditorExportPlatform::IMAGE_COMPRESSION_NONE: { + + //do absolutely nothing + + } break; + case EditorExportPlatform::IMAGE_COMPRESSION_BC: { + + + // for maximum compatibility, BC shall always use mipmaps and be PO2 + image.resize_to_po2(); + if (!image.has_mipmaps()) + image.generate_mipmaps(); + + image.compress(Image::COMPRESS_S3TC); + /* + if (has_alpha) { + + if (flags&IMAGE_FLAG_ALPHA_BIT) { + image.convert(Image::FORMAT_DXT5); + } else { + image.convert(Image::FORMAT_DXT3); + } + } else { + + image.convert(Image::FORMAT_DXT1); + }*/ + + + } break; + case EditorExportPlatform::IMAGE_COMPRESSION_PVRTC: + case EditorExportPlatform::IMAGE_COMPRESSION_PVRTC_SQUARE: { + + // for maximum compatibility (hi apple!), PVRT shall always + // use mipmaps, be PO2 and square + + if (!image.has_mipmaps()) + image.generate_mipmaps(); + image.resize_to_po2(true); + + if (p_smaller) { + + image.compress(Image::COMPRESS_PVRTC2); + //image.convert(has_alpha ? Image::FORMAT_PVRTC2A : Image::FORMAT_PVRTC2); + } else { + image.compress(Image::COMPRESS_PVRTC4); + //image.convert(has_alpha ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4); + } + + } break; + case EditorExportPlatform::IMAGE_COMPRESSION_ETC1: { + + image.resize_to_po2(); //square or not? + if (!image.has_mipmaps()) + image.generate_mipmaps(); + if (!image.detect_alpha()) { + //ETC1 is only opaque + image.compress(Image::COMPRESS_ETC); + } + + } break; + case EditorExportPlatform::IMAGE_COMPRESSION_ETC2: { + + + } break; + } + + +} + +Error EditorTextureImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from) { + + + return import2(p_path,p_from,EditorExportPlatform::IMAGE_COMPRESSION_BC,false); +} + + +Error EditorTextureImportPlugin::_process_texture_data(Ref<ImageTexture> &texture,int format, float quality,int flags,EditorExportPlatform::ImageCompression p_compr,int tex_flags,float shrink) { + + + if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS || format==IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { + + Image image=texture->get_data(); + ERR_FAIL_COND_V(image.empty(),ERR_INVALID_DATA); + + bool has_alpha=image.detect_alpha(); + if (!has_alpha && image.get_format()==Image::FORMAT_RGBA8) { + + image.convert(Image::FORMAT_RGB8); + + } + + if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_FIX_BORDER_ALPHA) { + + image.fix_alpha_edges(); + } + + if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_PREMULT_ALPHA) { + + image.premultiply_alpha(); + } + + if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) { + image.normalmap_to_xy(); + } + + /* + if ((image.get_format()==Image::FORMAT_RGB8 || image.get_format()==Image::FORMAT_RGBA8) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { + + image.srgb_to_linear(); + } + */ + + if (shrink>1) { + + int orig_w=image.get_width(); + int orig_h=image.get_height(); + image.resize(orig_w/shrink,orig_h/shrink,Image::INTERPOLATE_CUBIC); + texture->create_from_image(image,tex_flags); + texture->set_size_override(Size2(orig_w,orig_h)); + + + } else { + + texture->create_from_image(image,tex_flags); + } + + + if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS) { + texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSLESS); + } else { + texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY); + } + + + + texture->set_lossy_storage_quality(quality); + + + } else { + + + Image image=texture->get_data(); + ERR_FAIL_COND_V(image.empty(),ERR_INVALID_DATA); + + + bool has_alpha=image.detect_alpha(); + if (!has_alpha && image.get_format()==Image::FORMAT_RGBA8) { + + image.convert(Image::FORMAT_RGB8); + + } + + if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_FIX_BORDER_ALPHA) { + + image.fix_alpha_edges(); + } + + if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_PREMULT_ALPHA) { + + image.premultiply_alpha(); + } + + if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) { + image.normalmap_to_xy(); + } + + /* + if ((image.get_format()==Image::FORMAT_RGB8 || image.get_format()==Image::FORMAT_RGBA8) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { + + print_line("CONVERT BECAUSE: "+itos(flags)); + image.srgb_to_linear(); + } + */ + + int orig_w=image.get_width(); + int orig_h=image.get_height(); + + if (shrink>1) { + image.resize(orig_w/shrink,orig_h/shrink,Image::INTERPOLATE_CUBIC); + texture->create_from_image(image,tex_flags); + texture->set_size_override(Size2(orig_w,orig_h)); + } + + if (!(flags&IMAGE_FLAG_NO_MIPMAPS)) { + image.generate_mipmaps(); + + } + + if (format!=IMAGE_FORMAT_UNCOMPRESSED) { + + compress_image(p_compr,image,flags&IMAGE_FLAG_COMPRESS_EXTRA); + } + + + texture->create_from_image(image,tex_flags); + + + if (shrink>1 || (format!=IMAGE_FORMAT_UNCOMPRESSED && (image.get_width()!=orig_w || image.get_height()!=orig_h))) { + texture->set_size_override(Size2(orig_w,orig_h)); + } + + //uint32_t save_flags=ResourceSaver::FLAG_COMPRESS; + } + + return OK; +} + + +Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<ResourceImportMetadata>& p_from,EditorExportPlatform::ImageCompression p_compr, bool p_external){ + + + + ERR_FAIL_COND_V(p_from->get_source_count()==0,ERR_INVALID_PARAMETER); + + Ref<ResourceImportMetadata> from=p_from; + + Ref<ImageTexture> texture; + Vector<Ref<AtlasTexture> > atlases; + bool atlas = from->get_option("atlas"); + bool large = from->get_option("large"); + + int flags=from->get_option("flags"); + int format=from->get_option("format"); + float quality=from->get_option("quality"); + + uint32_t tex_flags=0; + + if (flags&EditorTextureImportPlugin::IMAGE_FLAG_REPEAT) + tex_flags|=Texture::FLAG_REPEAT; + if (flags&EditorTextureImportPlugin::IMAGE_FLAG_FILTER) + tex_flags|=Texture::FLAG_FILTER; + if (!(flags&EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS)) + tex_flags|=Texture::FLAG_MIPMAPS; + if (flags&EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_TO_LINEAR) + tex_flags|=Texture::FLAG_CONVERT_TO_LINEAR; + if (flags&EditorTextureImportPlugin::IMAGE_FLAG_USE_ANISOTROPY) + tex_flags|=Texture::FLAG_ANISOTROPIC_FILTER; + + print_line("path: "+p_path+" flags: "+itos(tex_flags)); + float shrink=1; + if (from->has_option("shrink")) + shrink=from->get_option("shrink"); + + if (large) { + ERR_FAIL_COND_V(from->get_source_count()!=1,ERR_INVALID_PARAMETER); + + String src_path = EditorImportPlugin::expand_source_path(from->get_source_path(0)); + + + int cell_size=from->get_option("large_cell_size"); + ERR_FAIL_COND_V(cell_size<128 || cell_size>16384,ERR_CANT_OPEN); + + EditorProgress pg("ltex",TTR("Import Large Texture"),3); + + pg.step(TTR("Load Source Image"),0); + Image img; + Error err = ImageLoader::load_image(src_path,&img); + if (err) { + return err; + } + + pg.step(TTR("Slicing"),1); + + Map<Vector2,Image> pieces; + for(int i=0;i<img.get_width();i+=cell_size) { + int w = MIN(img.get_width()-i,cell_size); + for(int j=0;j<img.get_height();j+=cell_size) { + int h = MIN(img.get_height()-j,cell_size); + + Image piece(w,h,0,img.get_format()); + piece.blit_rect(img,Rect2(i,j,w,h),Point2(0,0)); + if (!piece.is_invisible()) { + pieces[Vector2(i,j)]=piece; + //print_line("ADDING PIECE AT "+Vector2(i,j)); + } + } + } + + Ref<LargeTexture> existing; + if (ResourceCache::has(p_path)) { + existing = ResourceCache::get(p_path); + } + + if (existing.is_valid()) { + existing->clear(); + } else { + existing = Ref<LargeTexture>(memnew( LargeTexture )); + } + + existing->set_size(Size2(img.get_width(),img.get_height())); + pg.step(TTR("Inserting"),2); + + for (Map<Vector2,Image>::Element *E=pieces.front();E;E=E->next()) { + + Ref<ImageTexture> imgtex = Ref<ImageTexture>( memnew( ImageTexture ) ); + imgtex->create_from_image(E->get(),tex_flags); + _process_texture_data(imgtex,format,quality,flags,p_compr,tex_flags,shrink); + existing->add_piece(E->key(),imgtex); + } + + if (!p_external) { + from->set_editor(get_name()); + from->set_source_md5(0,FileAccess::get_md5(src_path)); + existing->set_path(p_path); + existing->set_import_metadata(from); + } + pg.step(TTR("Saving"),3); + + err = ResourceSaver::save(p_path,existing); + if (err!=OK) { + EditorNode::add_io_error(TTR("Couldn't save large texture:")+" "+p_path); + return err; + } + + return OK; + + + } else if (atlas) { + + //prepare atlas! + Vector< Image > sources; + Vector< Image > tsources; + bool alpha=false; + bool crop = from->get_option("crop"); + + EditorProgress ep("make_atlas",TTR("Build Atlas For:")+" "+p_path.get_file(),from->get_source_count()+3); + + print_line("sources: "+itos(from->get_source_count())); + + for(int i=0;i<from->get_source_count();i++) { + + String path = EditorImportPlugin::expand_source_path(from->get_source_path(i)); + String md5 = FileAccess::get_md5(path); + from->set_source_md5(i,FileAccess::get_md5(path)); + ep.step(TTR("Loading Image:")+" "+path,i); + print_line("source path: "+path+" md5 "+md5); + Image src; + Error err = ImageLoader::load_image(path,&src); + if (err) { + EditorNode::add_io_error(TTR("Couldn't load image:")+" "+path); + return err; + } + + if (src.detect_alpha()) + alpha=true; + + tsources.push_back(src); + } + ep.step(TTR("Converting Images"),sources.size()); + + + Map<uint64_t,int> source_md5; + Map<int,List<int> > source_map; + + for(int i=0;i<tsources.size();i++) { + + Image src = tsources[i]; + + if (alpha) { + src.convert(Image::FORMAT_RGBA8); + } else { + src.convert(Image::FORMAT_RGB8); + } + + PoolVector<uint8_t> data = src.get_data(); + MD5_CTX md5; + PoolVector<uint8_t>::Read r=data.read(); + MD5Init(&md5); + int len=data.size(); + for(int j=0;j<len;j++) { + uint8_t b = r[j]; + b>>=2; //to aid in comparing + MD5Update(&md5,(unsigned char*)&b,1); + } + MD5Final(&md5); + uint64_t *cmp = (uint64_t*)md5.digest; //less bits, but still useful for this + + tsources[i]=Image(); //clear + + if (source_md5.has(*cmp)) { + int sidx=source_md5[*cmp]; + source_map[sidx].push_back(i); + print_line("REUSING "+from->get_source_path(i)); + + } else { + int sidx=sources.size(); + source_md5[*cmp]=sidx; + sources.push_back(src); + List<int> sm; + sm.push_back(i); + source_map[sidx]=sm; + + } + + + } + + //texturepacker is not really good for optimizing, so.. + //will at some point likely replace with my own + //first, will find the nearest to a square packing + int border=1; + + Vector<Size2i> src_sizes; + Vector<Rect2> crops; + + ep.step(TTR("Cropping Images"),sources.size()+1); + + for(int j=0;j<sources.size();j++) { + + Size2i s; + if (crop) { + Rect2 crop = sources[j].get_used_rect(); + print_line("CROP: "+crop); + s=crop.size; + crops.push_back(crop); + } else { + + s=Size2i(sources[j].get_width(),sources[j].get_height()); + } + s+=Size2i(border*2,border*2); + src_sizes.push_back(s); //add a line to constraint width + } + + Vector<Point2i> dst_positions; + Size2i dst_size; + EditorAtlas::fit(src_sizes,dst_positions,dst_size); + + print_line("size that worked: "+itos(dst_size.width)+","+itos(dst_size.height)); + + ep.step(TTR("Blitting Images"),sources.size()+2); + + bool blit_to_po2=tex_flags&Texture::FLAG_MIPMAPS; + int atlas_w=dst_size.width; + int atlas_h=dst_size.height; + if (blit_to_po2) { + atlas_w=nearest_power_of_2(dst_size.width); + atlas_h=nearest_power_of_2(dst_size.height); + } + Image atlas; + atlas.create(atlas_w,atlas_h,0,alpha?Image::FORMAT_RGBA8:Image::FORMAT_RGB8); + + + atlases.resize(from->get_source_count()); + + for(int i=0;i<sources.size();i++) { + + int x=dst_positions[i].x; + int y=dst_positions[i].y; + + Size2 sz = Size2(sources[i].get_width(),sources[i].get_height()); + + Rect2 region; + Rect2 margin; + + if (crop && sz!=crops[i].size) { + Rect2 rect = crops[i]; + rect.size=sz-rect.size; + region=Rect2(x+border,y+border,crops[i].size.width,crops[i].size.height); + margin=rect; + atlas.blit_rect(sources[i],crops[i],Point2(x+border,y+border)); + } else { + region=Rect2(x+border,y+border,sz.x,sz.y); + atlas.blit_rect(sources[i],Rect2(0,0,sources[i].get_width(),sources[i].get_height()),Point2(x+border,y+border)); + } + + ERR_CONTINUE( !source_map.has(i) ); + for (List<int>::Element *E=source_map[i].front();E;E=E->next()) { + + String apath; + String spath = from->get_source_path(E->get()).get_file(); + + if (p_external) { + apath = p_path.get_base_dir().plus_file(spath.get_basename()+"."+from->get_source_path(E->get()).md5_text()+".atex"); + } else { + apath = p_path.get_base_dir().plus_file(spath.get_basename()+".atex"); + } + + Ref<AtlasTexture> at; + + if (ResourceCache::has(apath)) { + + at = Ref<AtlasTexture>( ResourceCache::get(apath)->cast_to<AtlasTexture>() ); + } else { + + at = Ref<AtlasTexture>( memnew( AtlasTexture ) ); + + } + at->set_region(region); + at->set_margin(margin); + at->set_path(apath); + atlases[E->get()]=at; + + } + } + if (ResourceCache::has(p_path)) { + texture = Ref<ImageTexture> ( ResourceCache::get(p_path)->cast_to<ImageTexture>() ); + } else { + texture = Ref<ImageTexture>( memnew( ImageTexture ) ); + } + texture->create_from_image(atlas,tex_flags); + + } else { + ERR_FAIL_COND_V(from->get_source_count()!=1,ERR_INVALID_PARAMETER); + + String src_path = EditorImportPlugin::expand_source_path(from->get_source_path(0)); + + if (ResourceCache::has(p_path)) { + Resource *r = ResourceCache::get(p_path); + + texture = Ref<ImageTexture> ( r->cast_to<ImageTexture>() ); + + Image img; + Error err = img.load(src_path); + ERR_FAIL_COND_V(err!=OK,ERR_CANT_OPEN); + texture->create_from_image(img); + } else { + texture=ResourceLoader::load(src_path,"ImageTexture"); + } + + ERR_FAIL_COND_V(texture.is_null(),ERR_CANT_OPEN); + if (!p_external) + from->set_source_md5(0,FileAccess::get_md5(src_path)); + + } + + + + if (!p_external) { + from->set_editor(get_name()); + texture->set_path(p_path); + texture->set_import_metadata(from); + } + + if (atlas) { + + if (p_external) { + //used by exporter + Array rects; + for(int i=0;i<atlases.size();i++) { + rects.push_back(atlases[i]->get_region()); + rects.push_back(atlases[i]->get_margin()); + } + from->set_option("rects",rects); + + } else { + //used by importer + for(int i=0;i<atlases.size();i++) { + String apath = atlases[i]->get_path(); + atlases[i]->set_atlas(texture); + Error err = ResourceSaver::save(apath,atlases[i]); + if (err) { + EditorNode::add_io_error(TTR("Couldn't save atlas image:")+" "+apath); + return err; + } + //from->set_source_md5(i,FileAccess::get_md5(apath)); + } + } + } + + bool compress=false; +#if 1 + + _process_texture_data(texture,format,quality,flags,p_compr,tex_flags,shrink); +#else + if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS || format==IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { + + Image image=texture->get_data(); + ERR_FAIL_COND_V(image.empty(),ERR_INVALID_DATA); + + bool has_alpha=image.detect_alpha(); + if (!has_alpha && image.get_format()==Image::FORMAT_RGBA8) { + + image.convert(Image::FORMAT_RGB8); + + } + + if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_FIX_BORDER_ALPHA) { + + image.fix_alpha_edges(); + } + + if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_PREMULT_ALPHA) { + + image.premultiply_alpha(); + } + + if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) { + image.normalmap_to_xy(); + } + + /* + if ((image.get_format()==Image::FORMAT_RGB8 || image.get_format()==Image::FORMAT_RGBA8) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { + + image.srgb_to_linear(); + } + */ + + if (shrink>1) { + + int orig_w=image.get_width(); + int orig_h=image.get_height(); + image.resize(orig_w/shrink,orig_h/shrink); + texture->create_from_image(image,tex_flags); + texture->set_size_override(Size2(orig_w,orig_h)); + + + } else { + + texture->create_from_image(image,tex_flags); + } + + + if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS) { + texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSLESS); + } else { + texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY); + } + + + + texture->set_lossy_storage_quality(quality); + + + } else { + + + Image image=texture->get_data(); + ERR_FAIL_COND_V(image.empty(),ERR_INVALID_DATA); + + + bool has_alpha=image.detect_alpha(); + if (!has_alpha && image.get_format()==Image::FORMAT_RGBA8) { + + image.convert(Image::FORMAT_RGB8); + + } + + if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_FIX_BORDER_ALPHA) { + + image.fix_alpha_edges(); + } + + if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_PREMULT_ALPHA) { + + image.premultiply_alpha(); + } + + if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) { + image.normalmap_to_xy(); + } + + /* + if ((image.get_format()==Image::FORMAT_RGB8 || image.get_format()==Image::FORMAT_RGBA8) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { + + print_line("CONVERT BECAUSE: "+itos(flags)); + image.srgb_to_linear(); + } + */ + + int orig_w=image.get_width(); + int orig_h=image.get_height(); + + if (shrink>1) { + image.resize(orig_w/shrink,orig_h/shrink); + texture->create_from_image(image,tex_flags); + texture->set_size_override(Size2(orig_w,orig_h)); + } + + if (!(flags&IMAGE_FLAG_NO_MIPMAPS)) { + image.generate_mipmaps(); + + } + + if (format!=IMAGE_FORMAT_UNCOMPRESSED) { + + compress_image(p_compr,image,flags&IMAGE_FLAG_COMPRESS_EXTRA); + } + + + texture->create_from_image(image,tex_flags); + + + if (shrink>1 || (format!=IMAGE_FORMAT_UNCOMPRESSED && (image.get_width()!=orig_w || image.get_height()!=orig_h))) { + texture->set_size_override(Size2(orig_w,orig_h)); + } + + compress=true; + + + } +#endif + uint32_t save_flags=0; + if (compress) + save_flags=ResourceSaver::FLAG_COMPRESS; + + Error err = ResourceSaver::save(p_path,texture,save_flags); + if (err!=OK) { + EditorNode::add_io_error(TTR("Couldn't save converted texture:")+" "+p_path); + return err; + } + + return OK; +} + +Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, const Ref<EditorExportPlatform> &p_platform) { + + + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); + + if (rimd.is_null()) { + + StringName group = EditorImportExport::get_singleton()->image_get_export_group(p_path); + + if (group!=StringName()) { + //handled by export group + rimd = Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) ); + + int group_format=0; + float group_lossy_quality=EditorImportExport::get_singleton()->image_export_group_get_lossy_quality(group); + int group_shrink=EditorImportExport::get_singleton()->image_export_group_get_shrink(group); + group_shrink*=EditorImportExport::get_singleton()->get_export_image_shrink(); + + switch(EditorImportExport::get_singleton()->image_export_group_get_image_action(group)) { + case EditorImportExport::IMAGE_ACTION_NONE: { + + switch(EditorImportExport::get_singleton()->get_export_image_action()) { + case EditorImportExport::IMAGE_ACTION_NONE: { + + group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS; //? + + } break; //use default + case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: { + group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY; + } break; //use default + case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: { + group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM; + } break; //use default + } + + group_lossy_quality=EditorImportExport::get_singleton()->get_export_image_quality(); + + } break; //use default + case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: { + group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY; + } break; //use default + case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: { + group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM; + } break; //use default + case EditorImportExport::IMAGE_ACTION_KEEP: { + return Vector<uint8_t>(); + } break; //use default + } + + String validated_path=EditorImportPlugin::validate_source_path(p_path); + + int flags=texture_flags_to_export_flags(ResourceFormatLoaderImage::load_image_flags(validated_path)); + flags|=IMAGE_FLAG_FIX_BORDER_ALPHA; + + print_line("group format"+itos(group_format)); + rimd->set_option("format",group_format); + rimd->set_option("flags",flags); + rimd->set_option("quality",group_lossy_quality); + rimd->set_option("atlas",false); + rimd->set_option("shrink",group_shrink); + rimd->add_source(validated_path,FileAccess::get_md5(p_path)); + + } else if (EditorImportExport::get_singleton()->get_image_formats().has(p_path.get_extension().to_lower()) && EditorImportExport::get_singleton()->get_export_image_action()!=EditorImportExport::IMAGE_ACTION_NONE) { + //handled by general image export settings + + rimd = Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) ); + + switch(EditorImportExport::get_singleton()->get_export_image_action()) { + case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: rimd->set_option("format",IMAGE_FORMAT_COMPRESS_DISK_LOSSY); break; + case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: rimd->set_option("format",IMAGE_FORMAT_COMPRESS_RAM); break; + } + + String validated_path=EditorImportPlugin::validate_source_path(p_path); + + int flags=texture_flags_to_export_flags(ResourceFormatLoaderImage::load_image_flags(validated_path)); + flags|=IMAGE_FLAG_FIX_BORDER_ALPHA; + + rimd->set_option("shrink",EditorImportExport::get_singleton()->get_export_image_shrink()); + rimd->set_option("flags",flags); + rimd->set_option("quality",EditorImportExport::get_singleton()->get_export_image_quality()); + rimd->set_option("atlas",false); + rimd->add_source(validated_path,FileAccess::get_md5(p_path)); + + } else { + return Vector<uint8_t>(); + } + } + + int fmt = rimd->get_option("format"); + + if (fmt!=IMAGE_FORMAT_COMPRESS_RAM && fmt!=IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { + print_line("no compress ram or lossy"); + return Vector<uint8_t>(); //pointless to do anything, since no need to reconvert + } + + uint32_t flags = rimd->get_option("flags"); + uint8_t shrink = rimd->has_option("shrink") ? rimd->get_option("shrink"): Variant(1); + uint8_t format = rimd->get_option("format"); + uint8_t comp = (format==EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM)?uint8_t(p_platform->get_image_compression()):uint8_t(255); + + MD5_CTX ctx; + uint8_t f4[4]; + encode_uint32(flags,&f4[0]); + MD5Init(&ctx); + String gp = GlobalConfig::get_singleton()->globalize_path(p_path); + CharString cs = gp.utf8(); + MD5Update(&ctx,(unsigned char*)cs.get_data(),cs.length()); + MD5Update(&ctx,f4,4); + MD5Update(&ctx,&format,1); + MD5Update(&ctx,&comp,1); + MD5Update(&ctx,&shrink,1); + MD5Final(&ctx); + + + + uint64_t sd=0; + String smd5; + + String md5 = String::md5(ctx.digest); + print_line(p_path+" MD5: "+md5+" FLAGS: "+itos(flags)); + + String tmp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/"); + + bool valid=false; + { + //if existing, make sure it's valid + FileAccessRef f = FileAccess::open(tmp_path+"imgexp-"+md5+".txt",FileAccess::READ); + if (f) { + + uint64_t d = f->get_line().strip_edges().to_int64(); + sd = FileAccess::get_modified_time(p_path); + + if (d==sd) { + valid=true; + } else { + String cmd5 = f->get_line().strip_edges(); + smd5 = FileAccess::get_md5(p_path); + if (cmd5==smd5) { + valid=true; + } + } + + + } + } + + if (!valid) { + //cache failed, convert + Error err = import2(tmp_path+"imgexp-"+md5+".tex",rimd,p_platform->get_image_compression(),true); + ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>()); + FileAccessRef f = FileAccess::open(tmp_path+"imgexp-"+md5+".txt",FileAccess::WRITE); + + if (sd==0) + sd = FileAccess::get_modified_time(p_path); + if (smd5==String()) + smd5 = FileAccess::get_md5(p_path); + + f->store_line(String::num(sd)); + f->store_line(smd5); + f->store_line(gp); //source path for reference + } + + + Vector<uint8_t> ret; + FileAccessRef f = FileAccess::open(tmp_path+"imgexp-"+md5+".tex",FileAccess::READ); + ERR_FAIL_COND_V(!f,ret); + + ret.resize(f->get_len()); + f->get_buffer(ret.ptr(),ret.size()); + + return ret; +} + +uint32_t EditorTextureImportPlugin::texture_flags_to_export_flags(uint32_t p_tex_flags) const { + + uint32_t flags=0; + + if (!(p_tex_flags&Texture::FLAG_MIPMAPS)) { + flags|=IMAGE_FLAG_NO_MIPMAPS; + } + if (p_tex_flags&Texture::FLAG_REPEAT) { + flags|=IMAGE_FLAG_REPEAT; + } + if (p_tex_flags&Texture::FLAG_FILTER) { + flags|=IMAGE_FLAG_FILTER; + } + if (p_tex_flags&Texture::FLAG_ANISOTROPIC_FILTER) { + flags|=IMAGE_FLAG_USE_ANISOTROPY; + } + if (p_tex_flags&Texture::FLAG_CONVERT_TO_LINEAR) { + flags|=IMAGE_FLAG_CONVERT_TO_LINEAR; + } + /* // no correspondence yet + if (p_tex_flags&Texture::TEXTURE_FLAG_MIRRORED_REPEAT) { + flags|=; + }*/ + + return flags; +} + +void EditorTextureImportPlugin::import_from_drop(const Vector<String>& p_drop,const String& p_dest_path) { + + Vector<String> valid; + + List<String> valid_extensions; + ImageLoader::get_recognized_extensions(&valid_extensions); + for(int i=0;i<p_drop.size();i++) { + + String extension=p_drop[i].get_extension().to_lower(); + + for (List<String>::Element *E=valid_extensions.front();E;E=E->next()) { + + if (E->get()==extension) { + valid.push_back(p_drop[i]); + break; + } + } + } + + if (valid.size()) { + dialog->popup_import(); + dialog->setup_multiple_import_3d(valid,p_dest_path); + } +} + +void EditorTextureImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { + + Vector<String> valid; + + + for(int i=0;i<p_list.size();i++) { + + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_list[i]); + String type = rimd->get_editor(); + if (type=="texture" || type.begins_with("texture_")) { + + if ((rimd->has_option("atlas") && rimd->get_option("atlas")) || (rimd->has_option("large") && rimd->get_option("large"))) { + continue; + } + + valid.push_back(p_list[i]); + } + } + + if (valid.size()) { + + dialog->popup_import(valid[0]); + + Vector<String> sources; + for(int i=0;i<valid.size();i++) { + int idx; + EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->find_file(valid[i],&idx); + if (efsd) { + for(int j=0;j<efsd->get_source_count(idx);j++) { + String file = expand_source_path(efsd->get_source_file(idx,j)); + if (sources.find(file)==-1) { + sources.push_back(file); + } + + } + } + } + + if (sources.size()) { + + dialog->add_sources_and_dest(sources,valid[0].get_base_dir()); + } + } +} + +bool EditorTextureImportPlugin::can_reimport_multiple_files() const { + + return true; + +} + + + +EditorTextureImportPlugin *EditorTextureImportPlugin::singleton=NULL; + +EditorTextureImportPlugin::EditorTextureImportPlugin(EditorNode *p_editor) { + + singleton=this; + editor=p_editor; + dialog = memnew( EditorTextureImportDialog(this) ); + editor->get_gui_base()->add_child(dialog); + +} + +//////////////////////////// + + + Vector<uint8_t> EditorTextureExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) { + + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); + + if (rimd.is_valid()) { + + if (rimd->get_editor()!="") { + int compression = rimd->get_option("format"); + if (compression!=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM) + return Vector<uint8_t>(); //only useful for RAM compression to reconvert + Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name(rimd->get_editor()); + if (pl.is_valid()) { + Vector<uint8_t> ce = pl->custom_export(p_path,p_platform); + if (ce.size()) + return ce; + } + } + } else if (EditorImportExport::get_singleton()->image_get_export_group(p_path)) { + + + Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name("texture"); + if (pl.is_valid()) { + Vector<uint8_t> ce = pl->custom_export(p_path,p_platform); + if (ce.size()) { + p_path=p_path.get_basename()+".converted.tex"; + return ce; + } + } + + } else if (EditorImportExport::get_singleton()->get_export_image_action()!=EditorImportExport::IMAGE_ACTION_NONE){ + + String xt = p_path.get_extension().to_lower(); + if (EditorImportExport::get_singleton()->get_image_formats().has(xt)) { //should check for more I guess? + + Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name("texture"); + if (pl.is_valid()) { + Vector<uint8_t> ce = pl->custom_export(p_path,p_platform); + if (ce.size()) { + p_path=p_path.get_basename()+".converted.tex"; + return ce; + } + } + } + } + + return Vector<uint8_t>(); +} + +EditorTextureExportPlugin::EditorTextureExportPlugin() { + + +} +#endif diff --git a/editor/io_plugins/editor_texture_import_plugin.h b/editor/io_plugins/editor_texture_import_plugin.h new file mode 100644 index 0000000000..f63bc57ecd --- /dev/null +++ b/editor/io_plugins/editor_texture_import_plugin.h @@ -0,0 +1,179 @@ +/*************************************************************************/ +/* editor_texture_import_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITOR_TEXTURE_IMPORT_PLUGIN_H +#define EDITOR_TEXTURE_IMPORT_PLUGIN_H + + + + + + +#if 0 +#include "editor/editor_import_export.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/tree.h" +#include "scene/gui/label.h" +#include "scene/gui/option_button.h" +#include "scene/gui/line_edit.h" +#include "scene/gui/file_dialog.h" +#include "scene/gui/progress_bar.h" +#include "scene/gui/slider.h" +#include "scene/gui/spin_box.h" +#include "editor/editor_file_system.h" +#include "editor/editor_dir_dialog.h" + + + +class EditorNode; +class EditorTextureImportDialog; + +class EditorTextureImportPlugin : public EditorImportPlugin { + + GDCLASS(EditorTextureImportPlugin,EditorImportPlugin); +public: + + + enum Mode { + MODE_TEXTURE_2D, + MODE_TEXTURE_3D, + MODE_ATLAS, + MODE_LARGE, + MODE_MAX + }; + + + +private: + + EditorNode *editor; + EditorTextureImportDialog *dialog; + static EditorTextureImportPlugin *singleton; + //used by other importers such as mesh + + Error _process_texture_data(Ref<ImageTexture> &texture, int format, float quality, int flags,EditorExportPlatform::ImageCompression p_compr,int tex_flags,float shrink); + void compress_image(EditorExportPlatform::ImageCompression p_mode,Image& image,bool p_smaller); + + uint32_t texture_flags_to_export_flags(uint32_t p_tex_flags) const; +public: + + + static EditorTextureImportPlugin *get_singleton() { return singleton; } + + enum ImageFormat { + + IMAGE_FORMAT_UNCOMPRESSED, + IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS, + IMAGE_FORMAT_COMPRESS_DISK_LOSSY, + IMAGE_FORMAT_COMPRESS_RAM, + }; + + enum ImageFlags { + + IMAGE_FLAG_STREAM_FORMAT=1, + IMAGE_FLAG_FIX_BORDER_ALPHA=2, + IMAGE_FLAG_ALPHA_BIT=4, //hint for compressions that use a bit for alpha + IMAGE_FLAG_COMPRESS_EXTRA=8, // used for pvrtc2 + IMAGE_FLAG_NO_MIPMAPS=16, //normal for 2D games + IMAGE_FLAG_REPEAT=32, //usually disabled in 2D + IMAGE_FLAG_FILTER=64, //almost always enabled + IMAGE_FLAG_PREMULT_ALPHA=128,//almost always enabled + IMAGE_FLAG_CONVERT_TO_LINEAR=256, //convert image to linear + IMAGE_FLAG_CONVERT_NORMAL_TO_XY=512, //convert image to linear + IMAGE_FLAG_USE_ANISOTROPY=1024, //convert image to linear + }; + + virtual String get_name() const; + virtual String get_visible_name() const; + virtual void import_dialog(const String& p_from=""); + virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + virtual Error import2(const String& p_path, const Ref<ResourceImportMetadata>& p_from,EditorExportPlatform::ImageCompression p_compr, bool p_external=false); + virtual Vector<uint8_t> custom_export(const String& p_path,const Ref<EditorExportPlatform> &p_platform); + + virtual void import_from_drop(const Vector<String>& p_drop,const String& p_dest_path); + virtual void reimport_multiple_files(const Vector<String>& p_list); + virtual bool can_reimport_multiple_files() const; + + EditorTextureImportPlugin(EditorNode* p_editor=NULL); +}; + + +class EditorTextureExportPlugin : public EditorExportPlugin { + + GDCLASS( EditorTextureExportPlugin, EditorExportPlugin); + + +public: + + virtual Vector<uint8_t> custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform); + EditorTextureExportPlugin(); +}; + +class EditorImportTextureOptions : public VBoxContainer { + + GDCLASS( EditorImportTextureOptions, VBoxContainer ); + + + OptionButton *format; + VBoxContainer *quality_vb; + HSlider *quality; + Tree *flags; + Vector<TreeItem*> items; + + + bool updating; + + void _changedp(int p_value); + void _changed(); + + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: + + + + void set_format(EditorTextureImportPlugin::ImageFormat p_format); + EditorTextureImportPlugin::ImageFormat get_format() const; + + void set_flags(uint32_t p_flags); + uint32_t get_flags() const; + + void set_quality(float p_quality); + float get_quality() const; + + void show_2d_notice(); + + EditorImportTextureOptions(); + + +}; +#endif // EDITOR_TEXTURE_IMPORT_PLUGIN_H +#endif diff --git a/editor/io_plugins/editor_translation_import_plugin.cpp b/editor/io_plugins/editor_translation_import_plugin.cpp new file mode 100644 index 0000000000..0fd298d6d3 --- /dev/null +++ b/editor/io_plugins/editor_translation_import_plugin.cpp @@ -0,0 +1,479 @@ +/*************************************************************************/ +/* editor_translation_import_plugin.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 "editor_translation_import_plugin.h" + +#if 0 +#include "scene/gui/file_dialog.h" +#include "editor/editor_dir_dialog.h" +#include "editor/editor_node.h" +#include "editor/property_editor.h" +//#include "scene/resources/sample.h" +#include "io/resource_saver.h" +#include "os/file_access.h" +#include "translation.h" +#include "compressed_translation.h" +#include "editor/project_settings.h" + + +class EditorTranslationImportDialog : public ConfirmationDialog { + + GDCLASS(EditorTranslationImportDialog,ConfirmationDialog); + + EditorTranslationImportPlugin *plugin; + + LineEdit *import_path; + LineEdit *save_path; + EditorFileDialog *file_select; + CheckButton *ignore_first; + CheckButton *compress; + CheckButton *add_to_project; + EditorDirDialog *save_select; + ConfirmationDialog *error_dialog; + Vector<TreeItem*> items; + Tree *columns; + +public: + + void _choose_file(const String& p_path) { + + import_path->set_text(p_path); + FileAccess *f = FileAccess::open(p_path,FileAccess::READ); + if (!f) { + + error_dialog->set_text(TTR("Invalid source!")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + + } + + Vector<String> csvh = f->get_csv_line(); + memdelete(f); + + if (csvh.size()<2) { + + error_dialog->set_text(TTR("Invalid translation source!")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + return; + + } + + columns->clear(); + columns->set_columns(2); + TreeItem *root = columns->create_item(); + columns->set_hide_root(true); + columns->set_column_titles_visible(true); + columns->set_column_title(0,TTR("Column")); + columns->set_column_title(1,TTR("Language")); + Vector<String> langs = TranslationServer::get_all_locales(); + Vector<String> names = TranslationServer::get_all_locale_names(); + if (csvh[0]=="") + ignore_first->set_pressed(true); + + + items.clear(); + + for(int i=1;i<csvh.size();i++) { + + TreeItem *ti = columns->create_item(root); + + ti->set_editable(0,true); + ti->set_selectable(0,false); + ti->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); + ti->set_checked(0,true); + ti->set_text(0,itos(i)); + items.push_back(ti); + + String lname = csvh[i].to_lower().strip_edges(); + int idx=-1; + String hint; + for(int j=0;j<langs.size();j++) { + + if (langs[j]==lname.substr(0,langs[j].length()).to_lower()) { + idx=j; + } + if (j>0) { + hint+=","; + } + hint+=names[j].replace(","," "); + } + + ti->set_cell_mode(1,TreeItem::CELL_MODE_RANGE); + ti->set_text(1,hint); + ti->set_editable(1,true); + + + if (idx!=-1) { + ignore_first->set_pressed(true); + ti->set_range(1,idx); + } else { + + //not found, maybe used stupid name + if (lname.begins_with("br")) //brazilian + ti->set_range(1,langs.find("pt")); + else if (lname.begins_with("ch")) //chinese + ti->set_range(1,langs.find("zh")); + else if (lname.begins_with("sp")) //spanish + ti->set_range(1,langs.find("es")); + else if (lname.begins_with("kr"))// kprean + ti->set_range(1,langs.find("ko")); + else if (i==0) + ti->set_range(1,langs.find("en")); + else + ti->set_range(1,langs.find("es")); + } + + ti->set_metadata(1,names[ti->get_range(1)]); + } + + + + } + void _choose_save_dir(const String& p_path) { + + save_path->set_text(p_path); + } + + void _browse() { + + file_select->popup_centered_ratio(); + } + + void _browse_target() { + + save_select->popup_centered_ratio(); + + } + + + void popup_import(const String& p_from) { + + popup_centered(Size2(400,400)*EDSCALE); + + if (p_from!="") { + + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from); + ERR_FAIL_COND(!rimd.is_valid()); + ERR_FAIL_COND(rimd->get_source_count()!=1); + _choose_file(EditorImportPlugin::expand_source_path(rimd->get_source_path(0))); + _choose_save_dir(p_from.get_base_dir()); + String locale = rimd->get_option("locale"); + bool skip_first=rimd->get_option("skip_first"); + bool compressed = rimd->get_option("compress"); + + int idx=-1; + + for(int i=0;i<items.size();i++) { + + String il = TranslationServer::get_all_locales()[items[i]->get_range(1)]; + if (il==locale) { + idx=i; + break; + } + } + + if (idx!=-1) { + idx=rimd->get_option("index"); + } + + for(int i=0;i<items.size();i++) { + + if (i==idx) { + + Vector<String> locs = TranslationServer::get_all_locales(); + for(int j=0;j<locs.size();j++) { + if (locs[j]==locale) { + items[i]->set_range(1,j); + } + + } + items[i]->set_checked(0,true); + } else { + items[i]->set_checked(0,false); + + } + } + + ignore_first->set_pressed(skip_first); + compress->set_pressed(compressed); + + + + } + + } + + + void _import() { + + + if (items.size()==0) { + error_dialog->set_text(TTR("No items to import!")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + } + + if (!save_path->get_text().begins_with("res://")) { + error_dialog->set_text(TTR("No target path!")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + } + + EditorProgress progress("import_xl",TTR("Import Translations"),items.size()); + for(int i=0;i<items.size();i++) { + + progress.step(items[i]->get_metadata(1),i); + if (!items[i]->is_checked(0)) + continue; + + String locale = TranslationServer::get_all_locales()[items[i]->get_range(1)]; + Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); + imd->add_source(EditorImportPlugin::validate_source_path(import_path->get_text())); + imd->set_option("locale",locale); + imd->set_option("index",i); + imd->set_option("skip_first",ignore_first->is_pressed()); + imd->set_option("compress",compress->is_pressed()); + + String savefile = save_path->get_text().plus_file(import_path->get_text().get_file().get_basename()+"."+locale+".xl"); + Error err = plugin->import(savefile,imd); + if (err!=OK) { + error_dialog->set_text(TTR("Couldn't import!")); + error_dialog->popup_centered(Size2(200,100)*EDSCALE); + } else if (add_to_project->is_pressed()) { + + ProjectSettings::get_singleton()->add_translation(savefile); + } + } + hide(); + + } + + + void _notification(int p_what) { + + + if (p_what==NOTIFICATION_ENTER_TREE) { + + + } + } + + static void _bind_methods() { + + + ClassDB::bind_method("_choose_file",&EditorTranslationImportDialog::_choose_file); + ClassDB::bind_method("_choose_save_dir",&EditorTranslationImportDialog::_choose_save_dir); + ClassDB::bind_method("_import",&EditorTranslationImportDialog::_import); + ClassDB::bind_method("_browse",&EditorTranslationImportDialog::_browse); + ClassDB::bind_method("_browse_target",&EditorTranslationImportDialog::_browse_target); + //ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); + } + + EditorTranslationImportDialog(EditorTranslationImportPlugin *p_plugin) { + + plugin=p_plugin; + + + set_title(TTR("Import Translation")); + + VBoxContainer *vbc = memnew( VBoxContainer ); + add_child(vbc); + //set_child_rect(vbc); + + + + VBoxContainer *csvb = memnew( VBoxContainer ); + + HBoxContainer *hbc = memnew( HBoxContainer ); + csvb->add_child(hbc); + vbc->add_margin_child(TTR("Source CSV:"),csvb); + + import_path = memnew( LineEdit ); + import_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(import_path); + ignore_first = memnew( CheckButton ); + ignore_first->set_text(TTR("Ignore First Row")); + csvb->add_child(ignore_first); + + Button * import_choose = memnew( Button ); + import_choose->set_text(" .. "); + hbc->add_child(import_choose); + + import_choose->connect("pressed", this,"_browse"); + + VBoxContainer *tcomp = memnew( VBoxContainer); + hbc = memnew( HBoxContainer ); + tcomp->add_child(hbc); + vbc->add_margin_child(TTR("Target Path:"),tcomp); + + save_path = memnew( LineEdit ); + save_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(save_path); + + Button * save_choose = memnew( Button ); + save_choose->set_text(" .. "); + hbc->add_child(save_choose); + + save_choose->connect("pressed", this,"_browse_target"); + + compress = memnew( CheckButton); + compress->set_pressed(true); + compress->set_text(TTR("Compress")); + tcomp->add_child(compress); + + add_to_project = memnew( CheckButton); + add_to_project->set_pressed(true); + add_to_project->set_text(TTR("Add to Project (godot.cfg)")); + tcomp->add_child(add_to_project); + + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + add_child(file_select); + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); + file_select->connect("file_selected", this,"_choose_file"); + file_select->add_filter("*.csv ; Translation CSV"); + save_select = memnew( EditorDirDialog ); + add_child(save_select); + + //save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); + save_select->connect("dir_selected", this,"_choose_save_dir"); + + get_ok()->connect("pressed", this,"_import"); + get_ok()->set_text(TTR("Import")); + + + error_dialog = memnew ( ConfirmationDialog ); + add_child(error_dialog); + error_dialog->get_ok()->set_text(TTR("Accept")); + //error_dialog->get_cancel()->hide(); + + set_hide_on_ok(false); + + columns = memnew( Tree ); + vbc->add_margin_child(TTR("Import Languages:"),columns,true); + } + + ~EditorTranslationImportDialog() { + + } + +}; + + +String EditorTranslationImportPlugin::get_name() const { + + return "translation"; +} +String EditorTranslationImportPlugin::get_visible_name() const { + + return TTR("Translation"); +} +void EditorTranslationImportPlugin::import_dialog(const String& p_from) { + + dialog->popup_import(p_from); +} + + + +void EditorTranslationImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + + for(int i=0;i<p_drop.size();i++) { + String ext = p_drop[i].get_extension().to_lower(); + + if (ext=="csv") { + + import_dialog(); + dialog->_choose_file(p_drop[i]); + dialog->_choose_save_dir(p_dest_path); + break; + } + } + + +} + +Error EditorTranslationImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from) { + + Ref<ResourceImportMetadata> from = p_from; + ERR_FAIL_COND_V( from->get_source_count()!=1, ERR_INVALID_PARAMETER); + + String source = EditorImportPlugin::expand_source_path( from->get_source_path(0) ); + + FileAccessRef f = FileAccess::open(source,FileAccess::READ); + + ERR_FAIL_COND_V( !f, ERR_INVALID_PARAMETER ); + + bool skip_first = from->get_option("skip_first"); + int index = from->get_option("index"); + index+=1; + String locale = from->get_option("locale"); + + Ref<Translation> translation = memnew( Translation ); + + translation->set_locale( locale ); + + Vector<String> line = f->get_csv_line(); + + while(line.size()>1) { + + if (!skip_first) { + ERR_FAIL_INDEX_V(index,line.size(),ERR_INVALID_DATA ); + translation->add_message(line[0].strip_edges(),line[index]); + + } else { + + skip_first=false; + } + + line = f->get_csv_line(); + } + + from->set_source_md5(0,FileAccess::get_md5(source)); + from->set_editor(get_name()); + + String dst_path = p_path; + + if (from->get_option("compress")) { + + Ref<PHashTranslation> cxl = memnew( PHashTranslation ); + cxl->generate( translation ); + translation=cxl; + } + + translation->set_import_metadata(from); + return ResourceSaver::save(dst_path,translation); + +} + + +EditorTranslationImportPlugin::EditorTranslationImportPlugin(EditorNode* p_editor) { + + dialog = memnew(EditorTranslationImportDialog(this)); + p_editor->get_gui_base()->add_child(dialog); +} + +#endif diff --git a/editor/io_plugins/editor_translation_import_plugin.h b/editor/io_plugins/editor_translation_import_plugin.h new file mode 100644 index 0000000000..030c5bbf6f --- /dev/null +++ b/editor/io_plugins/editor_translation_import_plugin.h @@ -0,0 +1,56 @@ +/*************************************************************************/ +/* editor_translation_import_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITOR_TRANSLATION_IMPORT_PLUGIN_H +#define EDITOR_TRANSLATION_IMPORT_PLUGIN_H + +#include "editor/editor_export.h" +#include "scene/resources/font.h" +#if 0 +class EditorNode; +class EditorTranslationImportDialog; + +class EditorTranslationImportPlugin : public EditorImportPlugin { + + GDCLASS(EditorTranslationImportPlugin,EditorImportPlugin); + + EditorTranslationImportDialog *dialog; +public: + + virtual String get_name() const; + virtual String get_visible_name() const; + virtual void import_dialog(const String& p_from=""); + virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); + + + EditorTranslationImportPlugin(EditorNode* p_editor); +}; + +#endif +#endif // EDITOR_TRANSLATION_IMPORT_PLUGIN_H diff --git a/tools/editor/multi_node_edit.cpp b/editor/multi_node_edit.cpp index 0428d7ef30..0428d7ef30 100644 --- a/tools/editor/multi_node_edit.cpp +++ b/editor/multi_node_edit.cpp diff --git a/tools/editor/multi_node_edit.h b/editor/multi_node_edit.h index 26e557c1cb..26e557c1cb 100644 --- a/tools/editor/multi_node_edit.h +++ b/editor/multi_node_edit.h diff --git a/tools/editor/node_dock.cpp b/editor/node_dock.cpp index fed3d2efb4..fed3d2efb4 100644 --- a/tools/editor/node_dock.cpp +++ b/editor/node_dock.cpp diff --git a/tools/editor/node_dock.h b/editor/node_dock.h index df41ecf5bd..df41ecf5bd 100644 --- a/tools/editor/node_dock.h +++ b/editor/node_dock.h diff --git a/tools/editor/output_strings.cpp b/editor/output_strings.cpp index cb43bb9230..cb43bb9230 100644 --- a/tools/editor/output_strings.cpp +++ b/editor/output_strings.cpp diff --git a/tools/editor/output_strings.h b/editor/output_strings.h index cc721ef652..cc721ef652 100644 --- a/tools/editor/output_strings.h +++ b/editor/output_strings.h diff --git a/tools/editor/pane_drag.cpp b/editor/pane_drag.cpp index 122abd37b9..122abd37b9 100644 --- a/tools/editor/pane_drag.cpp +++ b/editor/pane_drag.cpp diff --git a/tools/editor/pane_drag.h b/editor/pane_drag.h index 8796fc2594..8796fc2594 100644 --- a/tools/editor/pane_drag.h +++ b/editor/pane_drag.h diff --git a/tools/editor/plugins/SCsub b/editor/plugins/SCsub index f1fa50148f..f1fa50148f 100644 --- a/tools/editor/plugins/SCsub +++ b/editor/plugins/SCsub diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp new file mode 100644 index 0000000000..2e6792bbaa --- /dev/null +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -0,0 +1,1604 @@ +/*************************************************************************/ +/* animation_player_editor_plugin.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 "animation_player_editor_plugin.h" + +#include "global_config.h" +#include "io/resource_loader.h" +#include "io/resource_saver.h" +#include "os/keyboard.h" +#include "editor/editor_settings.h" +#include "editor/animation_editor.h" + +void AnimationPlayerEditor::_node_removed(Node *p_node) { + + if (player && player == p_node) { + player=NULL; + + set_process(false); + + key_editor->set_animation(Ref<Animation>()); + key_editor->set_root(NULL); + key_editor->show_select_node_warning(true); + _update_player(); + //editor->animation_editor_make_visible(false); + + } +} + +void AnimationPlayerEditor::_gui_input(InputEvent p_event) { + + +} + +void AnimationPlayerEditor::_notification(int p_what) { + + if (p_what==NOTIFICATION_PROCESS) { + + if (!player) + return; + + updating = true; + + if (player->is_playing()) { + + { + String animname=player->get_current_animation(); + + if (player->has_animation(animname)) { + Ref<Animation> anim = player->get_animation(animname); + if (!anim.is_null()) { + + frame->set_max(anim->get_length()); + } + } + } + frame->set_value(player->get_current_animation_pos()); + key_editor->set_anim_pos(player->get_current_animation_pos()); + EditorNode::get_singleton()->get_property_editor()->refresh(); + + } else if (last_active) { + //need the last frame after it stopped + + frame->set_value(player->get_current_animation_pos()); + } + + last_active=player->is_playing(); + //seek->set_val(player->get_pos()); + updating = false; + } + + if (p_what==NOTIFICATION_ENTER_TREE) { + + //editor->connect("hide_animation_player_editors",this,"_hide_anim_editors"); + add_anim->set_icon( get_icon("New","EditorIcons") ); + rename_anim->set_icon( get_icon("Rename","EditorIcons") ); + duplicate_anim->set_icon( get_icon("Duplicate","EditorIcons") ); + autoplay->set_icon( get_icon("AutoPlay","EditorIcons") ); + load_anim->set_icon( get_icon("Folder","EditorIcons") ); + save_anim->set_icon(get_icon("Save", "EditorIcons")); + save_anim->get_popup()->connect("id_pressed", this, "_animation_save_menu"); + remove_anim->set_icon( get_icon("Remove","EditorIcons") ); + + blend_anim->set_icon( get_icon("Blend","EditorIcons") ); + play->set_icon( get_icon("PlayStart","EditorIcons") ); + play_from->set_icon( get_icon("Play","EditorIcons") ); + play_bw->set_icon( get_icon("PlayStartBackwards","EditorIcons") ); + play_bw_from->set_icon( get_icon("PlayBackwards","EditorIcons") ); + + autoplay_icon=get_icon("AutoPlay","EditorIcons"); + stop->set_icon( get_icon("Stop","EditorIcons") ); + resource_edit_anim->set_icon( get_icon("EditResource","EditorIcons") ); + pin->set_icon(get_icon("Pin","EditorIcons") ); + tool_anim->set_icon(get_icon("Tools","EditorIcons")); + tool_anim->get_popup()->connect("id_pressed",this,"_animation_tool_menu"); + + blend_editor.next->connect("item_selected", this, "_blend_editor_next_changed"); + + nodename->set_icon(get_icon("AnimationPlayer","EditorIcons")); + +/* + anim_editor_load->set_normal_texture( get_icon("AnimGet","EditorIcons")); + anim_editor_store->set_normal_texture( get_icon("AnimSet","EditorIcons")); + anim_editor_load->set_pressed_texture( get_icon("AnimGet","EditorIcons")); + anim_editor_store->set_pressed_texture( get_icon("AnimSet","EditorIcons")); + anim_editor_load->set_hover_texture( get_icon("AnimGetHl","EditorIcons")); + anim_editor_store->set_hover_texture( get_icon("AnimSetHl","EditorIcons")); +*/ + + get_tree()->connect("node_removed",this,"_node_removed"); + } +} + +void AnimationPlayerEditor::_autoplay_pressed() { + + if (updating) + return; + if (animation->get_item_count()==0) { + return; + } + + String current = animation->get_item_text( animation->get_selected() ); + if (player->get_autoplay()==current) { + //unset + undo_redo->create_action(TTR("Toggle Autoplay")); + undo_redo->add_do_method(player,"set_autoplay",""); + undo_redo->add_undo_method(player,"set_autoplay",player->get_autoplay()); + undo_redo->add_do_method(this,"_animation_player_changed",player); + undo_redo->add_undo_method(this,"_animation_player_changed",player); + undo_redo->commit_action(); + + + } else { + //set + undo_redo->create_action(TTR("Toggle Autoplay")); + undo_redo->add_do_method(player,"set_autoplay",current); + undo_redo->add_undo_method(player,"set_autoplay",player->get_autoplay()); + undo_redo->add_do_method(this,"_animation_player_changed",player); + undo_redo->add_undo_method(this,"_animation_player_changed",player); + undo_redo->commit_action(); + } + +} + +void AnimationPlayerEditor::_play_pressed() { + + String current; + if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { + + current = animation->get_item_text( animation->get_selected() ); + } + + if (current!="") { + + if (current==player->get_current_animation()) + player->stop(); //so it wont blend with itself + player->play(current ); + } + + //unstop + stop->set_pressed(false); + //unpause + //pause->set_pressed(false); +} + +void AnimationPlayerEditor::_play_from_pressed() { + + String current; + if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { + + current = animation->get_item_text( animation->get_selected() ); + } + + if (current!="") { + + float time = player->get_current_animation_pos(); + + if (current==player->get_current_animation() && player->is_playing()) { + + player->stop(); //so it wont blend with itself + } + + player->play( current ); + player->seek(time); + } + + //unstop + stop->set_pressed(false); + //unpause + //pause->set_pressed(false); +} + + +void AnimationPlayerEditor::_play_bw_pressed() { + + String current; + if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { + + current = animation->get_item_text( animation->get_selected() ); + } + + if (current!="") { + + if (current==player->get_current_animation()) + player->stop(); //so it wont blend with itself + player->play(current,-1,-1,true); + } + + //unstop + stop->set_pressed(false); + //unpause + //pause->set_pressed(false); +} + +void AnimationPlayerEditor::_play_bw_from_pressed() { + + String current; + if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { + + current = animation->get_item_text( animation->get_selected() ); + } + + if (current!="") { + + float time = player->get_current_animation_pos(); + if (current==player->get_current_animation()) + player->stop(); //so it wont blend with itself + + player->play(current,-1,-1,true); + player->seek(time); + } + + //unstop + stop->set_pressed(false); + //unpause + //pause->set_pressed(false); +} +void AnimationPlayerEditor::_stop_pressed() { + + player->stop(false); + play->set_pressed(false); + stop->set_pressed(true); + //pause->set_pressed(false); + //player->set_pause(false); +} + +void AnimationPlayerEditor::_pause_pressed() { + + //player->set_pause( pause->is_pressed() ); +} +void AnimationPlayerEditor::_animation_selected(int p_which) { + + if (updating) + return; + // when selecting an animation, the idea is that the only interesting behavior + // ui-wise is that it should play/blend the next one if currently playing + String current; + if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { + + current = animation->get_item_text( animation->get_selected() ); + } + + if (current!="") { + + + player->set_current_animation( current ); + + Ref<Animation> anim = player->get_animation(current); + { + + key_editor->set_animation(anim); + Node *root = player->get_node(player->get_root()); + if (root) { + key_editor->set_root(root); + } + } + frame->set_max(anim->get_length()); + if (anim->get_step()) + frame->set_step(anim->get_step()); + else + frame->set_step(0.00001); + + + + } else { + key_editor->set_animation(Ref<Animation>()); + key_editor->set_root(NULL); + + } + + + autoplay->set_pressed(current==player->get_autoplay()); +} + +void AnimationPlayerEditor::_animation_new() { + + renaming=false; + name_title->set_text(TTR("New Animation Name:")); + + int count=1; + String base=TTR("New Anim"); + while(true) { + String attempt = base; + if (count>1) + attempt+=" ("+itos(count)+")"; + if (player->has_animation(attempt)) { + count++; + continue; + } + base=attempt; + break; + } + + name->set_text(base); + name_dialog->popup_centered(Size2(300,90)); + name->select_all(); + name->grab_focus(); +} +void AnimationPlayerEditor::_animation_rename() { + + if (animation->get_item_count()==0) + return; + int selected = animation->get_selected(); + String selected_name = animation->get_item_text(selected); + + name_title->set_text(TTR("Change Animation Name:")); + name->set_text(selected_name); + renaming=true; + name_dialog->popup_centered(Size2(300,90)); + name->select_all(); + name->grab_focus(); + +} +void AnimationPlayerEditor::_animation_load() { + ERR_FAIL_COND(!player); + file->set_mode( EditorFileDialog::MODE_OPEN_FILE ); + file->clear_filters(); + List<String> extensions; + + ResourceLoader::get_recognized_extensions_for_type("Animation",&extensions); + for (List<String>::Element *E=extensions.front();E;E=E->next()) { + + file->add_filter("*."+E->get()+" ; "+E->get().to_upper() ); + + } + + file->popup_centered_ratio(); + current_option = RESOURCE_LOAD; +} + + +void AnimationPlayerEditor::_animation_save_in_path(const Ref<Resource>& p_resource, const String& p_path) { + + int flg = 0; + if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) + flg |= ResourceSaver::FLAG_COMPRESS; + /* + if (EditorSettings::get_singleton()->get("filesystem/on_save/save_paths_as_relative")) + flg |= ResourceSaver::FLAG_RELATIVE_PATHS; + */ + + String path = GlobalConfig::get_singleton()->localize_path(p_path); + Error err = ResourceSaver::save(path, p_resource, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS); + + if (err != OK) { + accept->set_text(TTR("Error saving resource!")); + accept->popup_centered_minsize(); + return; + } + //EditorFileSystem::get_singleton()->update_file(path,p_resource->get_type()); + + ((Resource*)p_resource.ptr())->set_path(path); + editor->emit_signal("resource_saved", p_resource); + +} + +void AnimationPlayerEditor::_animation_save(const Ref<Resource>& p_resource) { + + if (p_resource->get_path().is_resource_file()) { + _animation_save_in_path(p_resource, p_resource->get_path()); + } + else { + _animation_save_as(p_resource); + } +} + +void AnimationPlayerEditor::_animation_save_as(const Ref<Resource>& p_resource) { + + file->set_mode(EditorFileDialog::MODE_SAVE_FILE); + + List<String> extensions; + ResourceSaver::get_recognized_extensions(p_resource, &extensions); + file->clear_filters(); + for (int i = 0; i<extensions.size(); i++) { + + file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper()); + } + + //file->set_current_path(current_path); + if (p_resource->get_path() != "") { + file->set_current_path(p_resource->get_path()); + if (extensions.size()) { + String ext = p_resource->get_path().get_extension().to_lower(); + if (extensions.find(ext) == NULL) { + file->set_current_path(p_resource->get_path().replacen("." + ext, "." + extensions.front()->get())); + } + } + } + else { + + String existing; + if (extensions.size()) { + if( p_resource->get_name() != "" ) { + existing = p_resource->get_name() + "." + extensions.front()->get().to_lower(); + } + else { + existing = "new_" + p_resource->get_class().to_lower() + "." + extensions.front()->get().to_lower(); + } + } + file->set_current_path(existing); + + } + file->popup_centered_ratio(); + file->set_title(TTR("Save Resource As..")); + current_option = RESOURCE_SAVE; +} + +void AnimationPlayerEditor::_animation_remove() { + + if (animation->get_item_count() == 0) + return; + + delete_dialog->set_text(TTR("Delete Animation?")); + delete_dialog->popup_centered_minsize(); +} + +void AnimationPlayerEditor::_animation_remove_confirmed() { + + String current = animation->get_item_text(animation->get_selected()); + Ref<Animation> anim = player->get_animation(current); + + undo_redo->create_action(TTR("Remove Animation")); + undo_redo->add_do_method(player, "remove_animation", current); + undo_redo->add_undo_method(player, "add_animation", current, anim); + undo_redo->add_do_method(this, "_animation_player_changed", player); + undo_redo->add_undo_method(this, "_animation_player_changed", player); + undo_redo->commit_action(); +} + +void AnimationPlayerEditor::_select_anim_by_name(const String& p_anim) { + + int idx=-1; + for(int i=0;i<animation->get_item_count();i++) { + + if (animation->get_item_text(i)==p_anim) { + + idx=i; + break; + } + } + + ERR_FAIL_COND(idx==-1); + + + animation->select(idx); + + _animation_selected(idx); + +} + +void AnimationPlayerEditor::_animation_name_edited() { + + player->stop(); + + String new_name = name->get_text(); + if (new_name=="" || new_name.find(":")!=-1 || new_name.find("/")!=-1) { + error_dialog->set_text(TTR("ERROR: Invalid animation name!")); + error_dialog->popup_centered_minsize(); + return; + } + + if (renaming && animation->get_item_count()>0 && animation->get_item_text(animation->get_selected())==new_name) { + name_dialog->hide(); + return; + } + + if (player->has_animation(new_name)) { + error_dialog->set_text(TTR("ERROR: Animation name already exists!")); + error_dialog->popup_centered_minsize(); + return; + } + + if (renaming) { + String current = animation->get_item_text(animation->get_selected()); + Ref<Animation> anim = player->get_animation(current); + + undo_redo->create_action(TTR("Rename Animation")); + undo_redo->add_do_method(player,"rename_animation",current,new_name); + undo_redo->add_do_method(anim.ptr(),"set_name",new_name); + undo_redo->add_undo_method(player,"rename_animation",new_name,current); + undo_redo->add_undo_method(anim.ptr(),"set_name",current); + undo_redo->add_do_method(this,"_animation_player_changed",player); + undo_redo->add_undo_method(this,"_animation_player_changed",player); + undo_redo->commit_action(); + + _select_anim_by_name(new_name); + + } else { + + Ref<Animation> new_anim = Ref<Animation>(memnew( Animation )); + new_anim->set_name(new_name); + + undo_redo->create_action(TTR("Add Animation")); + undo_redo->add_do_method(player,"add_animation",new_name,new_anim); + undo_redo->add_undo_method(player,"remove_animation",new_name); + undo_redo->add_do_method(this,"_animation_player_changed",player); + undo_redo->add_undo_method(this,"_animation_player_changed",player); + undo_redo->commit_action(); + + _select_anim_by_name(new_name); + + } + + name_dialog->hide(); +} + + +void AnimationPlayerEditor::_blend_editor_next_changed(const int p_idx) { + + if (animation->get_item_count()==0) + return; + + String current = animation->get_item_text(animation->get_selected()); + + undo_redo->create_action(TTR("Blend Next Changed")); + undo_redo->add_do_method(player,"animation_set_next",current,blend_editor.next->get_item_text(p_idx)); + undo_redo->add_undo_method(player,"animation_set_next",current,player->animation_get_next(current)); + undo_redo->add_do_method(this,"_animation_player_changed",player); + undo_redo->add_undo_method(this,"_animation_player_changed",player); + undo_redo->commit_action(); +} + +void AnimationPlayerEditor::_animation_blend() { + + if (updating_blends) + return; + + blend_editor.tree->clear(); + + if (animation->get_item_count()==0) + return; + + String current = animation->get_item_text(animation->get_selected()); + + blend_editor.dialog->popup_centered(Size2(400,400)); + + blend_editor.tree->set_hide_root(true); + blend_editor.tree->set_column_min_width(0,10); + blend_editor.tree->set_column_min_width(1,3); + + List<StringName> anims; + player->get_animation_list(&anims); + TreeItem *root = blend_editor.tree->create_item(); + updating_blends=true; + + int i = 0; + bool anim_found = false; + blend_editor.next->clear(); + blend_editor.next->add_item("", i); + + for(List<StringName>::Element *E=anims.front();E;E=E->next()) { + + String to=E->get(); + TreeItem *blend=blend_editor.tree->create_item(root); + blend->set_editable(0,false); + blend->set_editable(1,true); + blend->set_text(0,to); + blend->set_cell_mode(1,TreeItem::CELL_MODE_RANGE); + blend->set_range_config(1,0,3600,0.001); + blend->set_range(1,player->get_blend_time(current,to)); + + i++; + blend_editor.next->add_item(to, i); + if (to == player->animation_get_next(current)) { + blend_editor.next->select(i); + anim_found = true; + } + } + + // make sure we reset it else it becomes out of sync and could contain a deleted animation + if (!anim_found) { + blend_editor.next->select(0); + player->animation_set_next(current, blend_editor.next->get_item_text(0)); + } + + updating_blends=false; +} + +void AnimationPlayerEditor::_blend_edited() { + + if (updating_blends) + return; + + if (animation->get_item_count()==0) + return; + + String current = animation->get_item_text(animation->get_selected()); + + TreeItem *selected = blend_editor.tree->get_edited(); + if (!selected) + return; + + updating_blends=true; + String to=selected->get_text(0); + float blend_time = selected->get_range(1); + float prev_blend_time = player->get_blend_time(current,to); + + undo_redo->create_action(TTR("Change Blend Time")); + undo_redo->add_do_method(player,"set_blend_time",current,to,blend_time); + undo_redo->add_undo_method(player,"set_blend_time",current,to,prev_blend_time); + undo_redo->add_do_method(this,"_animation_player_changed",player); + undo_redo->add_undo_method(this,"_animation_player_changed",player); + undo_redo->commit_action(); + updating_blends=false; +} + +void AnimationPlayerEditor::ensure_visibility() { + + if (player && pin->is_pressed()) + return; // another player is pinned, don't reset + + _animation_edit(); +} + +Dictionary AnimationPlayerEditor::get_state() const { + + + Dictionary d; + + d["visible"]=is_visible_in_tree(); + if (EditorNode::get_singleton()->get_edited_scene() && is_visible_in_tree() && player) { + d["player"]=EditorNode::get_singleton()->get_edited_scene()->get_path_to(player); + d["animation"]=player->get_current_animation(); + + } + + return d; + +} +void AnimationPlayerEditor::set_state(const Dictionary& p_state) { + + if (p_state.has("visible") && p_state["visible"]) { + + if (!EditorNode::get_singleton()->get_edited_scene()) + return; + + Node *n = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["player"]); + if (n && n->cast_to<AnimationPlayer>() && EditorNode::get_singleton()->get_editor_selection()->is_selected(n)) { + player=n->cast_to<AnimationPlayer>(); + _update_player(); + show(); + set_process(true); + ensure_visibility(); + //EditorNode::get_singleton()->animation_panel_make_visible(true); + + if (p_state.has("animation")) { + String anim = p_state["animation"]; + _select_anim_by_name(anim); + _animation_edit(); + } + + } + } + +} + + +void AnimationPlayerEditor::_animation_resource_edit() { + + if (animation->get_item_count()) { + String current = animation->get_item_text(animation->get_selected()); + Ref<Animation> anim = player->get_animation(current); + editor->edit_resource(anim); + } + +} + +void AnimationPlayerEditor::_animation_edit() { + + if (animation->get_item_count()) { + String current = animation->get_item_text(animation->get_selected()); + Ref<Animation> anim = player->get_animation(current); + key_editor->set_animation(anim); + Node *root = player->get_node(player->get_root()); + if (root) { + key_editor->set_root(root); + } + + } else { + + key_editor->set_animation(Ref<Animation>()); + key_editor->set_root(NULL); + + } + +} +void AnimationPlayerEditor::_dialog_action(String p_file) { + + switch (current_option) { + case RESOURCE_LOAD: { + ERR_FAIL_COND(!player); + + Ref<Resource> res = ResourceLoader::load(p_file, "Animation"); + ERR_FAIL_COND(res.is_null()); + ERR_FAIL_COND(!res->is_class("Animation")); + if (p_file.find_last("/") != -1) { + + p_file = p_file.substr(p_file.find_last("/") + 1, p_file.length()); + + } + if (p_file.find_last("\\") != -1) { + + p_file = p_file.substr(p_file.find_last("\\") + 1, p_file.length()); + + } + + if (p_file.find(".") != -1) + p_file = p_file.substr(0, p_file.find(".")); + + undo_redo->create_action(TTR("Load Animation")); + undo_redo->add_do_method(player, "add_animation", p_file, res); + undo_redo->add_undo_method(player, "remove_animation", p_file); + if (player->has_animation(p_file)) { + undo_redo->add_undo_method(player, "add_animation", p_file, player->get_animation(p_file)); + + } + undo_redo->add_do_method(this, "_animation_player_changed", player); + undo_redo->add_undo_method(this, "_animation_player_changed", player); + undo_redo->commit_action(); + break; + } + case RESOURCE_SAVE: { + + String current = animation->get_item_text(animation->get_selected()); + if (current != "") { + Ref<Animation> anim = player->get_animation(current); + + ERR_FAIL_COND(!anim->cast_to<Resource>()) + + RES current_res = RES(anim->cast_to<Resource>()); + + _animation_save_in_path(current_res, p_file); + } + } + } +} + +void AnimationPlayerEditor::_scale_changed(const String& p_scale) { + + player->set_speed_scale(p_scale.to_double()); +} + +void AnimationPlayerEditor::_update_animation() { + + // the purpose of _update_animation is to reflect the current state + // of the animation player in the current editor.. + + updating=true; + + + if (player->is_playing()) { + + play->set_pressed(true); + stop->set_pressed(false); + + } else { + + play->set_pressed(false); + stop->set_pressed(true); + } + + scale->set_text( String::num(player->get_speed_scale(),2) ); + String current=player->get_current_animation(); + + for (int i=0;i<animation->get_item_count();i++) { + + if (animation->get_item_text(i)==current) { + animation->select(i); + break; + } + } + + updating=false; +} + +void AnimationPlayerEditor::_update_player() { + + + updating=true; + List<StringName> animlist; + if (player) + player->get_animation_list(&animlist); + + animation->clear(); + if (player) + nodename->set_text(player->get_name()); + else + nodename->set_text("<empty>"); + + + add_anim->set_disabled(player==NULL); + load_anim->set_disabled(player==NULL); + stop->set_disabled(animlist.size()==0); + play->set_disabled(animlist.size()==0); + play_bw->set_disabled(animlist.size()==0); + play_bw_from->set_disabled(animlist.size()==0); + play_from->set_disabled(animlist.size()==0); + autoplay->set_disabled(animlist.size()==0); + duplicate_anim->set_disabled(animlist.size()==0); + rename_anim->set_disabled(animlist.size()==0); + blend_anim->set_disabled(animlist.size()==0); + remove_anim->set_disabled(animlist.size()==0); + resource_edit_anim->set_disabled(animlist.size()==0); + save_anim->set_disabled(animlist.size() == 0); + tool_anim->set_disabled(player==NULL); + + + int active_idx=-1; + for (List<StringName>::Element *E=animlist.front();E;E=E->next()) { + + if (player->get_autoplay()==E->get()) + animation->add_icon_item(autoplay_icon,E->get()); + else + animation->add_item(E->get()); + + if (player->get_current_animation()==E->get()) + active_idx=animation->get_item_count()-1; + + } + + if (!player) + return; + + updating=false; + if (active_idx!=-1) { + animation->select(active_idx); + autoplay->set_pressed(animation->get_item_text(active_idx)==player->get_autoplay()); + _animation_selected(active_idx); + + } else if (animation->get_item_count()>0){ + + animation->select(0); + autoplay->set_pressed(animation->get_item_text(0)==player->get_autoplay()); + _animation_selected(0); + } + + //pause->set_pressed(player->is_paused()); + + + if (animation->get_item_count()) { + String current = animation->get_item_text(animation->get_selected()); + Ref<Animation> anim = player->get_animation(current); + key_editor->set_animation(anim); + Node *root = player->get_node(player->get_root()); + if (root) { + key_editor->set_root(root); + } + + } + + _update_animation(); +} + + + +void AnimationPlayerEditor::edit(AnimationPlayer *p_player) { + + + if (player && pin->is_pressed()) + return; //ignore, pinned + player=p_player; + + if (player) { + _update_player(); + key_editor->show_select_node_warning(false); + } else { + key_editor->show_select_node_warning(true); + + //hide(); + + } + +} + + +void AnimationPlayerEditor::_animation_duplicate() { + + + if (!animation->get_item_count()) + return; + + String current = animation->get_item_text(animation->get_selected()); + Ref<Animation> anim = player->get_animation(current); + if (!anim.is_valid()) + return; + + Ref<Animation> new_anim = memnew( Animation ); + List<PropertyInfo> plist; + anim->get_property_list(&plist); + for (List<PropertyInfo>::Element *E=plist.front();E;E=E->next()) { + + if (E->get().usage&PROPERTY_USAGE_STORAGE) { + + new_anim->set(E->get().name, anim->get(E->get().name)); + } + } + new_anim->set_path(""); + + String new_name = current; + while(player->has_animation(new_name)) { + + new_name=new_name+" (copy)"; + } + + + undo_redo->create_action(TTR("Duplicate Animation")); + undo_redo->add_do_method(player,"add_animation",new_name,new_anim); + undo_redo->add_undo_method(player,"remove_animation",new_name); + undo_redo->add_do_method(player,"animation_set_next",new_name,player->animation_get_next(current)); + undo_redo->add_do_method(this,"_animation_player_changed",player); + undo_redo->add_undo_method(this,"_animation_player_changed",player); + undo_redo->commit_action(); + + + for(int i=0;i<animation->get_item_count();i++) { + + if (animation->get_item_text(i)==new_name) { + + animation->select(i); + _animation_selected(i); + return; + } + } + +} + +void AnimationPlayerEditor::_seek_value_changed(float p_value,bool p_set) { + + if (updating || !player || player->is_playing()) { + return; + }; + + + updating=true; + String current=player->get_current_animation(); //animation->get_item_text( animation->get_selected() ); + if (current == "" || !player->has_animation(current)) { + updating=false; + current=""; + return; + }; + + Ref<Animation> anim; + anim=player->get_animation(current); + + float pos = anim->get_length() * (p_value / frame->get_max()); + float step = anim->get_step(); + if (step) { + pos=Math::stepify(pos, step); + if (pos<0) + pos=0; + if (pos>=anim->get_length()) + pos=anim->get_length(); + } + + if (player->is_valid() && !p_set) { + float cpos = player->get_current_animation_pos(); + + player->seek_delta(pos,pos-cpos); + } else { + player->seek(pos,true); + } + + + key_editor->set_anim_pos(pos); + + updating=true; +}; + +void AnimationPlayerEditor::_animation_player_changed(Object *p_pl) { + + if (player==p_pl && is_visible_in_tree()) { + + _update_player(); + if (blend_editor.dialog->is_visible_in_tree()) + _animation_blend(); //update + } +} + + + +void AnimationPlayerEditor::_list_changed() { + + if(is_visible_in_tree()) + _update_player(); +} +#if 0 +void AnimationPlayerEditor::_editor_store() { + + if (animation->get_item_count()==0) + return; + String current = animation->get_item_text(animation->get_selected()); + Ref<Animation> anim = player->get_animation(current); + + if (key_editor->get_current_animation()==anim) + return; //already there + + + undo_redo->create_action("Store anim in editor"); + undo_redo->add_do_method(key_editor,"set_animation",anim); + undo_redo->add_undo_method(key_editor,"remove_animation",anim); + undo_redo->commit_action(); +} + +void AnimationPlayerEditor::_editor_load(){ + + Ref<Animation> anim = key_editor->get_current_animation(); + if (anim.is_null()) + return; + + String existing = player->find_animation(anim); + if (existing!="") { + _select_anim_by_name(existing); + return; //already has + } + + int count=1; + String base=anim->get_name(); + bool noname=false; + if (base=="") { + base="New Anim"; + noname=true; + } + + while(true) { + String attempt = base; + if (count>1) + attempt+=" ("+itos(count)+")"; + if (player->has_animation(attempt)) { + count++; + continue; + } + base=attempt; + break; + } + + if (noname) + anim->set_name(base); + + undo_redo->create_action("Add Animation From Editor"); + undo_redo->add_do_method(player,"add_animation",base,anim); + undo_redo->add_undo_method(player,"remove_animation",base); + undo_redo->add_do_method(this,"_animation_player_changed",player); + undo_redo->add_undo_method(this,"_animation_player_changed",player); + undo_redo->commit_action(); + + _select_anim_by_name(base); + + +} +#endif + +void AnimationPlayerEditor::_animation_key_editor_anim_len_changed(float p_len) { + + + frame->set_max(p_len); + +} + +void AnimationPlayerEditor::_animation_key_editor_anim_step_changed(float p_len) { + + if (p_len) + frame->set_step(p_len); + else + frame->set_step(0.00001); + +} + + +void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos,bool p_drag) { + + if (!is_visible_in_tree()) + return; + if (!player) + return; + + if (player->is_playing() ) + return; + + updating=true; + frame->set_value(p_pos); + updating=false; + _seek_value_changed(p_pos,!p_drag); + + EditorNode::get_singleton()->get_property_editor()->refresh(); + + + + //seekit +} + +void AnimationPlayerEditor::_hide_anim_editors() { + + player=NULL; + hide(); + set_process(false); + + key_editor->set_animation(Ref<Animation>()); + key_editor->set_root(NULL); + key_editor->show_select_node_warning(true); + //editor->animation_editor_make_visible(false); + +} + + +void AnimationPlayerEditor::_animation_tool_menu(int p_option) { + + switch(p_option) { + + case TOOL_COPY_ANIM: { + + if (!animation->get_item_count()) { + error_dialog->set_text(TTR("ERROR: No animation to copy!")); + error_dialog->popup_centered_minsize(); + return; + } + + String current = animation->get_item_text(animation->get_selected()); + Ref<Animation> anim = player->get_animation(current); + //editor->edit_resource(anim); + EditorSettings::get_singleton()->set_resource_clipboard(anim); + + } break; + case TOOL_PASTE_ANIM: { + + Ref<Animation> anim = EditorSettings::get_singleton()->get_resource_clipboard(); + if (!anim.is_valid()) { + error_dialog->set_text(TTR("ERROR: No animation resource on clipboard!")); + error_dialog->popup_centered_minsize(); + return; + } + + String name = anim->get_name(); + if (name=="") { + name=TTR("Pasted Animation"); + } + + int idx=1; + String base = name; + while (player->has_animation(name)) { + + idx++; + name=base+" "+itos(idx); + } + + undo_redo->create_action(TTR("Paste Animation")); + undo_redo->add_do_method(player,"add_animation",name,anim); + undo_redo->add_undo_method(player,"remove_animation",name); + undo_redo->add_do_method(this,"_animation_player_changed",player); + undo_redo->add_undo_method(this,"_animation_player_changed",player); + undo_redo->commit_action(); + + _select_anim_by_name(name); + + + } break; + case TOOL_EDIT_RESOURCE: { + + if (!animation->get_item_count()) { + error_dialog->set_text(TTR("ERROR: No animation to edit!")); + error_dialog->popup_centered_minsize(); + return; + } + + String current = animation->get_item_text(animation->get_selected()); + Ref<Animation> anim = player->get_animation(current); + editor->edit_resource(anim); + + } break; + + } +} + +void AnimationPlayerEditor::_animation_save_menu(int p_option) { + + String current = animation->get_item_text(animation->get_selected()); + if (current != "") { + Ref<Animation> anim = player->get_animation(current); + + switch (p_option) { + case ANIM_SAVE: + _animation_save(anim); + break; + case ANIM_SAVE_AS: + _animation_save_as(anim); + break; + } + } +} + +void AnimationPlayerEditor::_unhandled_key_input(const InputEvent& p_ev) { + + if (is_visible_in_tree() && p_ev.type==InputEvent::KEY && p_ev.key.pressed && !p_ev.key.echo && !p_ev.key.mod.alt && !p_ev.key.mod.control && !p_ev.key.mod.meta) { + + switch(p_ev.key.scancode) { + + case KEY_A: { + if (!p_ev.key.mod.shift) + _play_bw_from_pressed(); + else + _play_bw_pressed(); + } break; + case KEY_S: { + _stop_pressed(); + } break; + case KEY_D: { + if (!p_ev.key.mod.shift) + _play_from_pressed(); + else + _play_pressed(); + } break; + } + } +} + +void AnimationPlayerEditor::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_gui_input"),&AnimationPlayerEditor::_gui_input); + ClassDB::bind_method(D_METHOD("_node_removed"),&AnimationPlayerEditor::_node_removed); + ClassDB::bind_method(D_METHOD("_play_pressed"),&AnimationPlayerEditor::_play_pressed); + ClassDB::bind_method(D_METHOD("_play_from_pressed"),&AnimationPlayerEditor::_play_from_pressed); + ClassDB::bind_method(D_METHOD("_play_bw_pressed"),&AnimationPlayerEditor::_play_bw_pressed); + ClassDB::bind_method(D_METHOD("_play_bw_from_pressed"),&AnimationPlayerEditor::_play_bw_from_pressed); + ClassDB::bind_method(D_METHOD("_stop_pressed"),&AnimationPlayerEditor::_stop_pressed); + ClassDB::bind_method(D_METHOD("_autoplay_pressed"),&AnimationPlayerEditor::_autoplay_pressed); + ClassDB::bind_method(D_METHOD("_pause_pressed"),&AnimationPlayerEditor::_pause_pressed); + ClassDB::bind_method(D_METHOD("_animation_selected"),&AnimationPlayerEditor::_animation_selected); + ClassDB::bind_method(D_METHOD("_animation_name_edited"),&AnimationPlayerEditor::_animation_name_edited); + ClassDB::bind_method(D_METHOD("_animation_new"),&AnimationPlayerEditor::_animation_new); + ClassDB::bind_method(D_METHOD("_animation_rename"),&AnimationPlayerEditor::_animation_rename); + ClassDB::bind_method(D_METHOD("_animation_load"),&AnimationPlayerEditor::_animation_load); + ClassDB::bind_method(D_METHOD("_animation_remove"),&AnimationPlayerEditor::_animation_remove); + ClassDB::bind_method(D_METHOD("_animation_remove_confirmed"),&AnimationPlayerEditor::_animation_remove_confirmed); + ClassDB::bind_method(D_METHOD("_animation_blend"),&AnimationPlayerEditor::_animation_blend); + ClassDB::bind_method(D_METHOD("_animation_edit"),&AnimationPlayerEditor::_animation_edit); + ClassDB::bind_method(D_METHOD("_animation_resource_edit"),&AnimationPlayerEditor::_animation_resource_edit); + ClassDB::bind_method(D_METHOD("_dialog_action"),&AnimationPlayerEditor::_dialog_action); + ClassDB::bind_method(D_METHOD("_seek_value_changed"),&AnimationPlayerEditor::_seek_value_changed,DEFVAL(true)); + ClassDB::bind_method(D_METHOD("_animation_player_changed"),&AnimationPlayerEditor::_animation_player_changed); + ClassDB::bind_method(D_METHOD("_blend_edited"),&AnimationPlayerEditor::_blend_edited); + //ClassDB::bind_method(D_METHOD("_seek_frame_changed"),&AnimationPlayerEditor::_seek_frame_changed); + ClassDB::bind_method(D_METHOD("_scale_changed"),&AnimationPlayerEditor::_scale_changed); + //ClassDB::bind_method(D_METHOD("_editor_store_all"),&AnimationPlayerEditor::_editor_store_all); + //ClassDB::bind_method(D_METHOD("_editor_load_all"),&AnimationPlayerEditor::_editor_load_all); + ClassDB::bind_method(D_METHOD("_list_changed"),&AnimationPlayerEditor::_list_changed); + ClassDB::bind_method(D_METHOD("_animation_key_editor_seek"),&AnimationPlayerEditor::_animation_key_editor_seek); + ClassDB::bind_method(D_METHOD("_animation_key_editor_anim_len_changed"),&AnimationPlayerEditor::_animation_key_editor_anim_len_changed); + ClassDB::bind_method(D_METHOD("_animation_key_editor_anim_step_changed"),&AnimationPlayerEditor::_animation_key_editor_anim_step_changed); + ClassDB::bind_method(D_METHOD("_hide_anim_editors"),&AnimationPlayerEditor::_hide_anim_editors); + ClassDB::bind_method(D_METHOD("_animation_duplicate"),&AnimationPlayerEditor::_animation_duplicate); + ClassDB::bind_method(D_METHOD("_blend_editor_next_changed"),&AnimationPlayerEditor::_blend_editor_next_changed); + ClassDB::bind_method(D_METHOD("_unhandled_key_input"),&AnimationPlayerEditor::_unhandled_key_input); + ClassDB::bind_method(D_METHOD("_animation_tool_menu"),&AnimationPlayerEditor::_animation_tool_menu); + ClassDB::bind_method(D_METHOD("_animation_save_menu"), &AnimationPlayerEditor::_animation_save_menu); + + + + +} + +AnimationPlayerEditor *AnimationPlayerEditor::singleton=NULL; + +AnimationPlayer *AnimationPlayerEditor::get_player() const { + + return player; +} +AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { + editor=p_editor; + singleton=this; + + updating=false; + + set_focus_mode(FOCUS_ALL); + + player=NULL; + add_style_override("panel", get_stylebox("panel","Panel")); + + + Label * l; + + /*l= memnew( Label ); + l->set_text("Animation Player:"); + add_child(l);*/ + + HBoxContainer *hb = memnew( HBoxContainer ); + add_child(hb); + + + play_bw_from = memnew( ToolButton ); + play_bw_from->set_tooltip(TTR("Play selected animation backwards from current pos. (A)")); + hb->add_child(play_bw_from); + + play_bw = memnew( ToolButton ); + play_bw->set_tooltip(TTR("Play selected animation backwards from end. (Shift+A)")); + hb->add_child(play_bw); + + stop = memnew( ToolButton ); + stop->set_toggle_mode(true); + hb->add_child(stop); + stop->set_tooltip(TTR("Stop animation playback. (S)")); + + play = memnew( ToolButton ); + play->set_tooltip(TTR("Play selected animation from start. (Shift+D)")); + hb->add_child(play); + + + play_from = memnew( ToolButton ); + play_from->set_tooltip(TTR("Play selected animation from current pos. (D)")); + hb->add_child(play_from); + + + + //pause = memnew( Button ); + //pause->set_toggle_mode(true); + //hb->add_child(pause); + + frame = memnew( SpinBox ); + hb->add_child(frame); + frame->set_custom_minimum_size(Size2(60,0)); + frame->set_stretch_ratio(2); + frame->set_tooltip(TTR("Animation position (in seconds).")); + + hb->add_child( memnew( VSeparator)); + + scale = memnew( LineEdit ); + hb->add_child(scale); + scale->set_h_size_flags(SIZE_EXPAND_FILL); + scale->set_stretch_ratio(1); + scale->set_tooltip(TTR("Scale animation playback globally for the node.")); + scale->hide(); + + + add_anim = memnew( ToolButton ); + ED_SHORTCUT("animation_player_editor/add_animation", TTR("Create new animation in player.")); + add_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/add_animation")); + add_anim->set_tooltip(TTR("Create new animation in player.")); + + hb->add_child(add_anim); + + + load_anim = memnew( ToolButton ); + ED_SHORTCUT("animation_player_editor/load_from_disk", TTR("Load animation from disk.")); + add_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/load_from_disk")); + load_anim->set_tooltip(TTR("Load an animation from disk.")); + hb->add_child(load_anim); + + save_anim = memnew(MenuButton); + save_anim->set_tooltip(TTR("Save the current animation")); + save_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/save", TTR("Save")), ANIM_SAVE); + save_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/save_as", TTR("Save As")), ANIM_SAVE_AS); + save_anim->set_focus_mode(Control::FOCUS_NONE); + hb->add_child(save_anim); + + accept = memnew(AcceptDialog); + add_child(accept); + accept->connect("confirmed", this, "_menu_confirm_current"); + + delete_dialog = memnew(ConfirmationDialog); + add_child(delete_dialog); + delete_dialog->connect("confirmed", this, "_animation_remove_confirmed"); + + duplicate_anim = memnew( ToolButton ); + hb->add_child(duplicate_anim); + ED_SHORTCUT("animation_player_editor/duplicate_animation", TTR("Duplicate Animation")); + duplicate_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/duplicate_animation")); + duplicate_anim->set_tooltip(TTR("Duplicate Animation")); + + rename_anim = memnew( ToolButton ); + hb->add_child(rename_anim); + ED_SHORTCUT("animation_player_editor/rename_animation", TTR("Rename Animation")); + rename_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/rename_animation")); + rename_anim->set_tooltip(TTR("Rename Animation")); + + remove_anim = memnew( ToolButton ); + hb->add_child(remove_anim); + ED_SHORTCUT("animation_player_editor/remove_animation", TTR("Remove Animation")); + remove_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/remove_animation")); + remove_anim->set_tooltip(TTR("Remove Animation")); + + + animation = memnew( OptionButton ); + hb->add_child(animation); + animation->set_h_size_flags(SIZE_EXPAND_FILL); + animation->set_tooltip(TTR("Display list of animations in player.")); + animation->set_clip_text(true); + + autoplay = memnew( ToolButton ); + hb->add_child(autoplay); + autoplay->set_tooltip(TTR("Autoplay on Load")); + + + + blend_anim = memnew( ToolButton ); + hb->add_child(blend_anim); + blend_anim->set_tooltip(TTR("Edit Target Blend Times")); + + tool_anim = memnew( MenuButton); + //tool_anim->set_flat(false); + tool_anim->set_tooltip(TTR("Animation Tools")); + tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/copy_animation", TTR("Copy Animation")),TOOL_COPY_ANIM); + tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/paste_animation", TTR("Paste Animation")),TOOL_PASTE_ANIM); + //tool_anim->get_popup()->add_separator(); + //tool_anim->get_popup()->add_item("Edit Anim Resource",TOOL_PASTE_ANIM); + hb->add_child(tool_anim); + + nodename = memnew( Button ); + hb->add_child(nodename); + pin = memnew( ToolButton ); + pin->set_toggle_mode(true); + hb->add_child(pin); + + + + resource_edit_anim= memnew( Button ); + hb->add_child(resource_edit_anim); + resource_edit_anim->hide(); + + + file = memnew(EditorFileDialog); + add_child(file); + + name_dialog = memnew( ConfirmationDialog ); + name_dialog->set_title(TTR("Create New Animation")); + name_dialog->set_hide_on_ok(false); + add_child(name_dialog); + name = memnew( LineEdit ); + name_dialog->add_child(name); + name->set_pos(Point2(18,30)); + name->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,10); + name_dialog->register_text_enter(name); + + + l = memnew( Label ); + l->set_text(TTR("Animation Name:")); + l->set_pos( Point2(10,10) ); + + name_dialog->add_child(l); + name_title=l; + + error_dialog = memnew( ConfirmationDialog ); + error_dialog->get_ok()->set_text(TTR("Close")); + //error_dialog->get_cancel()->set_text("Close"); + error_dialog->set_text(TTR("Error!")); + add_child(error_dialog); + + name_dialog->connect("confirmed", this,"_animation_name_edited"); + + blend_editor.dialog = memnew( AcceptDialog ); + add_child(blend_editor.dialog); + blend_editor.dialog->get_ok()->set_text(TTR("Close")); + blend_editor.dialog->set_hide_on_ok(true); + VBoxContainer *blend_vb = memnew( VBoxContainer); + blend_editor.dialog->add_child(blend_vb); + //blend_editor.dialog->set_child_rect(blend_vb); + blend_editor.tree = memnew( Tree ); + blend_editor.tree->set_columns(2); + blend_vb->add_margin_child(TTR("Blend Times:"),blend_editor.tree,true); + blend_editor.next = memnew( OptionButton ); + blend_vb->add_margin_child(TTR("Next (Auto Queue):"),blend_editor.next); + blend_editor.dialog->set_title(TTR("Cross-Animation Blend Times")); + updating_blends=false; + + blend_editor.tree->connect("item_edited",this,"_blend_edited"); + + + autoplay->connect("pressed", this,"_autoplay_pressed"); + autoplay->set_toggle_mode(true); + play->connect("pressed", this,"_play_pressed"); + play_from->connect("pressed", this,"_play_from_pressed"); + play_bw->connect("pressed", this,"_play_bw_pressed"); + play_bw_from->connect("pressed", this,"_play_bw_from_pressed"); + stop->connect("pressed", this,"_stop_pressed"); + //pause->connect("pressed", this,"_pause_pressed"); + add_anim->connect("pressed", this,"_animation_new"); + rename_anim->connect("pressed", this,"_animation_rename"); + load_anim->connect("pressed", this,"_animation_load"); + duplicate_anim->connect("pressed", this,"_animation_duplicate"); + //frame->connect("text_entered", this,"_seek_frame_changed"); + + blend_anim->connect("pressed", this,"_animation_blend"); + remove_anim->connect("pressed", this,"_animation_remove"); + animation->connect("item_selected", this,"_animation_selected",Vector<Variant>(),true); + resource_edit_anim->connect("pressed", this,"_animation_resource_edit"); + file->connect("file_selected", this,"_dialog_action"); + frame->connect("value_changed", this, "_seek_value_changed",Vector<Variant>(),true); + scale->connect("text_entered", this, "_scale_changed",Vector<Variant>(),true); + + + + renaming=false; + last_active=false; + + set_process_unhandled_key_input(true); + + key_editor = memnew( AnimationKeyEditor); + add_child(key_editor); + add_constant_override("separation",get_constant("separation","VBoxContainer")); + key_editor->set_v_size_flags(SIZE_EXPAND_FILL); + key_editor->connect("timeline_changed",this,"_animation_key_editor_seek"); + key_editor->connect("animation_len_changed",this,"_animation_key_editor_anim_len_changed"); + key_editor->connect("animation_step_changed",this,"_animation_key_editor_anim_step_changed"); + + _update_player(); +} + + +void AnimationPlayerEditorPlugin::edit(Object *p_object) { + + anim_editor->set_undo_redo(&get_undo_redo()); + if (!p_object) + return; + anim_editor->edit(p_object->cast_to<AnimationPlayer>()); + + +} + +bool AnimationPlayerEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("AnimationPlayer"); +} + +void AnimationPlayerEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + + editor->make_bottom_panel_item_visible(anim_editor); + anim_editor->set_process(true); + anim_editor->ensure_visibility(); + //editor->animation_panel_make_visible(true); + } else { + + //anim_editor->hide(); + //anim_editor->set_idle_process(false); + } + +} + +AnimationPlayerEditorPlugin::AnimationPlayerEditorPlugin(EditorNode *p_node) { + + editor=p_node; + anim_editor = memnew( AnimationPlayerEditor(editor) ); + anim_editor->set_undo_redo(editor->get_undo_redo()); + + editor->add_bottom_panel_item(TTR("Animation"),anim_editor); + /* + editor->get_viewport()->add_child(anim_editor); + anim_editor->set_area_as_parent_rect(); + anim_editor->set_anchor( MARGIN_TOP, Control::ANCHOR_END); + anim_editor->set_margin( MARGIN_TOP, 75 ); + anim_editor->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END); + anim_editor->set_margin( MARGIN_RIGHT, 0 );*/ + anim_editor->hide(); + + + +} + + +AnimationPlayerEditorPlugin::~AnimationPlayerEditorPlugin() +{ +} diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h new file mode 100644 index 0000000000..d9b6ad52ff --- /dev/null +++ b/editor/plugins/animation_player_editor_plugin.h @@ -0,0 +1,219 @@ +/*************************************************************************/ +/* animation_player_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef ANIMATION_PLAYER_EDITOR_PLUGIN_H +#define ANIMATION_PLAYER_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/animation/animation_player.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/texture_button.h" +#include "scene/gui/slider.h" +#include "scene/gui/spin_box.h" + + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ +class AnimationKeyEditor; +class AnimationPlayerEditor : public VBoxContainer { + + GDCLASS(AnimationPlayerEditor, VBoxContainer ); + + EditorNode *editor; + AnimationPlayer *player; + + enum { + TOOL_COPY_ANIM, + TOOL_PASTE_ANIM, + TOOL_EDIT_RESOURCE + }; + + enum { + ANIM_SAVE, + ANIM_SAVE_AS + }; + + enum { + RESOURCE_LOAD, + RESOURCE_SAVE + }; + + + OptionButton *animation; + Button *stop; + Button *play; + Button *play_from; + Button *play_bw; + Button *play_bw_from; + + //Button *pause; + Button *add_anim; + Button *autoplay; + Button *rename_anim; + Button *duplicate_anim; + + Button *resource_edit_anim; + Button *load_anim; + MenuButton *save_anim; + Button *blend_anim; + Button *remove_anim; + MenuButton *tool_anim; + ToolButton *pin; + Button *nodename; + SpinBox *frame; + LineEdit *scale; + LineEdit *name; + Label *name_title; + UndoRedo *undo_redo; + Ref<Texture> autoplay_icon; + bool last_active; + + EditorFileDialog *file; + AcceptDialog *accept; + ConfirmationDialog* delete_dialog; + int current_option; + + struct BlendEditor { + + AcceptDialog * dialog; + Tree *tree; + OptionButton *next; + + } blend_editor; + + + ConfirmationDialog *name_dialog; + ConfirmationDialog *error_dialog; + bool renaming; + + + bool updating; + bool updating_blends; + + AnimationKeyEditor *key_editor; + + + void _select_anim_by_name(const String& p_anim); + void _play_pressed(); + void _play_from_pressed(); + void _play_bw_pressed(); + void _play_bw_from_pressed(); + void _autoplay_pressed(); + void _stop_pressed(); + void _pause_pressed(); + void _animation_selected(int p_which); + void _animation_new(); + void _animation_rename(); + void _animation_name_edited(); + void _animation_load(); + + void _animation_save_in_path(const Ref<Resource>& p_resource, const String& p_path); + void _animation_save(const Ref<Resource>& p_resource); + void _animation_save_as(const Ref<Resource>& p_resource); + + void _animation_remove(); + void _animation_remove_confirmed(); + void _animation_blend(); + void _animation_edit(); + void _animation_duplicate(); + void _animation_resource_edit(); + void _scale_changed(const String& p_scale); + void _dialog_action(String p_file); + void _seek_frame_changed(const String& p_frame); + void _seek_value_changed(float p_value, bool p_set=false); + void _blend_editor_next_changed(const int p_idx); + + void _list_changed(); + void _update_animation(); + void _update_player(); + void _blend_edited(); + + + void _hide_anim_editors(); + + void _animation_player_changed(Object *p_pl); + + void _animation_key_editor_seek(float p_pos, bool p_drag); + void _animation_key_editor_anim_len_changed(float p_new); + void _animation_key_editor_anim_step_changed(float p_len); + + void _unhandled_key_input(const InputEvent& p_ev); + void _animation_tool_menu(int p_option); + void _animation_save_menu(int p_option); + + + AnimationPlayerEditor(); +protected: + + void _notification(int p_what); + void _gui_input(InputEvent p_event); + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + AnimationPlayer *get_player() const; + static AnimationPlayerEditor *singleton; + + AnimationKeyEditor* get_key_editor() { return key_editor; } + Dictionary get_state() const; + void set_state(const Dictionary& p_state); + + + void ensure_visibility(); + + void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo=p_undo_redo; } + void edit(AnimationPlayer *p_player); + AnimationPlayerEditor(EditorNode *p_editor); +}; + +class AnimationPlayerEditorPlugin : public EditorPlugin { + + GDCLASS( AnimationPlayerEditorPlugin, EditorPlugin ); + + AnimationPlayerEditor *anim_editor; + EditorNode *editor; + +public: + + virtual Dictionary get_state() const { return anim_editor->get_state(); } + virtual void set_state(const Dictionary& p_state) { anim_editor->set_state(p_state); } + + virtual String get_name() const { return "Anim"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + AnimationPlayerEditorPlugin(EditorNode *p_node); + ~AnimationPlayerEditorPlugin(); + +}; + +#endif // ANIMATION_PLAYER_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index 988136d475..988136d475 100644 --- a/tools/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp diff --git a/editor/plugins/animation_tree_editor_plugin.h b/editor/plugins/animation_tree_editor_plugin.h new file mode 100644 index 0000000000..4e5fb871f1 --- /dev/null +++ b/editor/plugins/animation_tree_editor_plugin.h @@ -0,0 +1,194 @@ +/*************************************************************************/ +/* animation_tree_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef ANIMATION_TREE_EDITOR_PLUGIN_H +#define ANIMATION_TREE_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/animation/animation_tree_player.h" +#include "scene/gui/tree.h" +#include "scene/gui/button.h" +#include "scene/gui/popup.h" +#include "editor/property_editor.h" +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +class AnimationTreeEditor : public Control { + + GDCLASS(AnimationTreeEditor, Control ); + + static const char* _node_type_names[]; + + enum ClickType { + CLICK_NONE, + CLICK_NAME, + CLICK_NODE, + CLICK_INPUT_SLOT, + CLICK_OUTPUT_SLOT, + CLICK_PARAMETER + }; + + enum { + + MENU_GRAPH_CLEAR=100, + MENU_IMPORT_ANIMATIONS=101, + NODE_DISCONNECT, + NODE_RENAME, + NODE_ERASE, + NODE_ADD_INPUT, + NODE_DELETE_INPUT, + NODE_SET_AUTOADVANCE, + NODE_CLEAR_AUTOADVANCE + }; + + bool renaming_edit; + StringName edited_node; + bool updating_edit; + Popup *edit_dialog; + HSlider *edit_scroll[2]; + LineEdit *edit_line[4]; + OptionButton *edit_option; + Label *edit_label[4]; + Button *edit_button; + Button *filter_button; + CheckButton *edit_check; + EditorFileDialog* file_dialog; + int file_op; + + void _popup_edit_dialog(); + + + void _setup_edit_dialog(const StringName& p_node); + PopupMenu *master_anim_popup; + PopupMenu *node_popup; + PopupMenu *add_popup; + HScrollBar *h_scroll; + VScrollBar *v_scroll; + MenuButton* add_menu; + + CustomPropertyEditor *property_editor; + + AnimationTreePlayer* anim_tree; + List<StringName> order; + Set<StringName> active_nodes; + + int last_x,last_y; + + Point2 offset; + ClickType click_type; + Point2 click_pos; + StringName click_node; + int click_slot; + Point2 click_motion; + ClickType rclick_type; + StringName rclick_node; + int rclick_slot; + + Button *play_button; + + Size2 _get_maximum_size(); + Size2 get_node_size(const StringName &p_node) const; + void _draw_node(const StringName& p_node); + + AcceptDialog *filter_dialog; + Tree *filter; + + + + void _draw_cos_line(const Vector2& p_from, const Vector2& p_to,const Color& p_color); + void _update_scrollbars(); + void _scroll_moved(float); + void _play_toggled(); +/* + void _node_param_changed(); + void _node_add_callback(); + void _node_add(VisualServer::AnimationTreeNodeType p_type); + void _node_edit_property(const StringName& p_node); +*/ + + void _master_anim_menu_item(int p_item); + void _node_menu_item(int p_item); + void _add_menu_item(int p_item); + + + void _filter_edited(); + void _find_paths_for_filter(const StringName& p_node,Set<String>& paths); + void _edit_filters(); + + + void _edit_oneshot_start(); + void _edit_dialog_animation_changed(); + void _edit_dialog_edit_animation(); + void _edit_dialog_changeds(String); + void _edit_dialog_changede(String); + void _edit_dialog_changedf(float); + void _edit_dialog_changed(); + void _dialog_changed() const; + ClickType _locate_click(const Point2& p_click,StringName *p_node_id,int *p_slot_index) const; + Point2 _get_slot_pos(const StringName& p_node_id,bool p_input,int p_slot); + + StringName _add_node(int p_item); + void _file_dialog_selected(String p_path); + + +protected: + void _notification(int p_what); + void _gui_input(InputEvent p_event); + static void _bind_methods(); +public: + + + virtual Size2 get_minimum_size() const; + void edit(AnimationTreePlayer *p_player); + AnimationTreeEditor(); +}; + +class AnimationTreeEditorPlugin : public EditorPlugin { + + GDCLASS( AnimationTreeEditorPlugin, EditorPlugin ); + + AnimationTreeEditor *anim_tree_editor; + EditorNode *editor; + Button *button; + +public: + + virtual String get_name() const { return "AnimTree"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + AnimationTreeEditorPlugin(EditorNode *p_node); + ~AnimationTreeEditorPlugin(); + +}; + +#endif // ANIMATION_TREE_EDITOR_PLUGIN_H diff --git a/editor/plugins/baked_light_baker.cpp b/editor/plugins/baked_light_baker.cpp new file mode 100644 index 0000000000..e491fe012e --- /dev/null +++ b/editor/plugins/baked_light_baker.cpp @@ -0,0 +1,2731 @@ +/*************************************************************************/ +/* baked_light_baker.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 "baked_light_baker.h" + +#include <stdlib.h> +#include <cmath> +#include "io/marshalls.h" +#include "editor/editor_node.h" +#include "editor/editor_settings.h" + +#if 0 +void baked_light_baker_add_64f(double *dst,double value); +void baked_light_baker_add_64i(int64_t *dst,int64_t value); + +//-separar en 2 testuras? +//*mejorar performance y threads +//*modos lineales +//*saturacion + +_FORCE_INLINE_ static uint64_t get_uv_normal_bit(const Vector3& p_vector) { + + int lat = Math::fast_ftoi(Math::floor(Math::acos(p_vector.dot(Vector3(0,1,0)))*6.0/Math_PI+0.5)); + + if (lat==0) { + return 60; + } else if (lat==6) { + return 61; + } + + int lon = Math::fast_ftoi(Math::floor( (Math_PI+Math::atan2(p_vector.x,p_vector.z))*12.0/(Math_PI*2.0) + 0.5))%12; + + return lon+(lat-1)*12; +} + + + +_FORCE_INLINE_ static Vector3 get_bit_normal(int p_bit) { + + if (p_bit==61) { + return Vector3(0,1,0); + } else if (p_bit==62){ + return Vector3(0,-1,0); + } + + float latang = ((p_bit / 12)+1)*Math_PI/6.0; + + Vector2 latv(Math::sin(latang),Math::cos(latang)); + + float lonang = ((p_bit%12)*Math_PI*2.0/12.0)-Math_PI; + + Vector2 lonv(Math::sin(lonang),Math::cos(lonang)); + + return Vector3(lonv.x*latv.x,latv.y,lonv.y*latv.x).normalized(); + +} + + +BakedLightBaker::MeshTexture* BakedLightBaker::_get_mat_tex(const Ref<Texture>& p_tex) { + + if (!tex_map.has(p_tex)) { + + Ref<ImageTexture> imgtex=p_tex; + if (imgtex.is_null()) + return NULL; + Image image=imgtex->get_data(); + if (image.empty()) + return NULL; + + if (image.get_format()!=Image::FORMAT_RGBA8) { + if (image.get_format()>Image::FORMAT_INDEXED_ALPHA) { + Error err = image.decompress(); + if (err) + return NULL; + } + + if (image.get_format()!=Image::FORMAT_RGBA8) + image.convert(Image::FORMAT_RGBA8); + } + + if (imgtex->get_flags()&Texture::FLAG_CONVERT_TO_LINEAR) { + Image copy = image; + copy.srgb_to_linear(); + image=copy; + } + + PoolVector<uint8_t> dvt=image.get_data(); + PoolVector<uint8_t>::Read r=dvt.read(); + MeshTexture mt; + mt.tex_w=image.get_width(); + mt.tex_h=image.get_height(); + int len = image.get_width()*image.get_height()*4; + mt.tex.resize(len); + copymem(mt.tex.ptr(),r.ptr(),len); + + textures.push_back(mt); + tex_map[p_tex]=&textures.back()->get(); + } + + return tex_map[p_tex]; +} + + +void BakedLightBaker::_add_mesh(const Ref<Mesh>& p_mesh,const Ref<Material>& p_mat_override,const Transform& p_xform,int p_baked_texture) { + + + for(int i=0;i<p_mesh->get_surface_count();i++) { + + if (p_mesh->surface_get_primitive_type(i)!=Mesh::PRIMITIVE_TRIANGLES) + continue; + Ref<Material> mat = p_mat_override.is_valid()?p_mat_override:p_mesh->surface_get_material(i); + + MeshMaterial *matptr=NULL; + int baked_tex=p_baked_texture; + + if (mat.is_valid()) { + + if (!mat_map.has(mat)) { + + MeshMaterial mm; + + Ref<FixedSpatialMaterial> fm = mat; + if (fm.is_valid()) { + //fixed route + mm.diffuse.color=fm->get_parameter(FixedSpatialMaterial::PARAM_DIFFUSE); + if (linear_color) + mm.diffuse.color=mm.diffuse.color.to_linear(); + mm.diffuse.tex=_get_mat_tex(fm->get_texture(FixedSpatialMaterial::PARAM_DIFFUSE)); + mm.specular.color=fm->get_parameter(FixedSpatialMaterial::PARAM_SPECULAR); + if (linear_color) + mm.specular.color=mm.specular.color.to_linear(); + + mm.specular.tex=_get_mat_tex(fm->get_texture(FixedSpatialMaterial::PARAM_SPECULAR)); + } else { + + mm.diffuse.color=Color(1,1,1,1); + mm.diffuse.tex=NULL; + mm.specular.color=Color(0,0,0,1); + mm.specular.tex=NULL; + } + + materials.push_back(mm); + mat_map[mat]=&materials.back()->get(); + + } + + matptr=mat_map[mat]; + + } + + + int facecount=0; + + + if (p_mesh->surface_get_format(i)&Mesh::ARRAY_FORMAT_INDEX) { + + facecount=p_mesh->surface_get_array_index_len(i); + } else { + + facecount=p_mesh->surface_get_array_len(i); + } + + ERR_CONTINUE((facecount==0 || (facecount%3)!=0)); + + facecount/=3; + + int tbase=triangles.size(); + triangles.resize(facecount+tbase); + + + Array a = p_mesh->surface_get_arrays(i); + + PoolVector<Vector3> vertices = a[Mesh::ARRAY_VERTEX]; + PoolVector<Vector3>::Read vr=vertices.read(); + PoolVector<Vector2> uv; + PoolVector<Vector2>::Read uvr; + PoolVector<Vector2> uv2; + PoolVector<Vector2>::Read uv2r; + PoolVector<Vector3> normal; + PoolVector<Vector3>::Read normalr; + bool read_uv=false; + bool read_normal=false; + + if (p_mesh->surface_get_format(i)&Mesh::ARRAY_FORMAT_TEX_UV) { + + uv=a[Mesh::ARRAY_TEX_UV]; + uvr=uv.read(); + read_uv=true; + + if (mat.is_valid() && mat->get_flag(Material::FLAG_LIGHTMAP_ON_UV2) && p_mesh->surface_get_format(i)&Mesh::ARRAY_FORMAT_TEX_UV2) { + + uv2=a[Mesh::ARRAY_TEX_UV2]; + uv2r=uv2.read(); + + } else { + uv2r=uv.read(); + if (baked_light->get_transfer_lightmaps_only_to_uv2()) { + baked_tex=-1; + } + } + } + + if (p_mesh->surface_get_format(i)&Mesh::ARRAY_FORMAT_NORMAL) { + + normal=a[Mesh::ARRAY_NORMAL]; + normalr=normal.read(); + read_normal=true; + } + + Matrix3 normal_xform = p_xform.basis.inverse().transposed(); + + + if (p_mesh->surface_get_format(i)&Mesh::ARRAY_FORMAT_INDEX) { + + PoolVector<int> indices = a[Mesh::ARRAY_INDEX]; + PoolVector<int>::Read ir = indices.read(); + + for(int i=0;i<facecount;i++) { + Triangle &t=triangles[tbase+i]; + t.vertices[0]=p_xform.xform(vr[ ir[i*3+0] ]); + t.vertices[1]=p_xform.xform(vr[ ir[i*3+1] ]); + t.vertices[2]=p_xform.xform(vr[ ir[i*3+2] ]); + t.material=matptr; + t.baked_texture=baked_tex; + if (read_uv) { + + t.uvs[0]=uvr[ ir[i*3+0] ]; + t.uvs[1]=uvr[ ir[i*3+1] ]; + t.uvs[2]=uvr[ ir[i*3+2] ]; + + t.bake_uvs[0]=uv2r[ ir[i*3+0] ]; + t.bake_uvs[1]=uv2r[ ir[i*3+1] ]; + t.bake_uvs[2]=uv2r[ ir[i*3+2] ]; + } + if (read_normal) { + + t.normals[0]=normal_xform.xform(normalr[ ir[i*3+0] ]).normalized(); + t.normals[1]=normal_xform.xform(normalr[ ir[i*3+1] ]).normalized(); + t.normals[2]=normal_xform.xform(normalr[ ir[i*3+2] ]).normalized(); + } + } + + } else { + + for(int i=0;i<facecount;i++) { + Triangle &t=triangles[tbase+i]; + t.vertices[0]=p_xform.xform(vr[ i*3+0 ]); + t.vertices[1]=p_xform.xform(vr[ i*3+1 ]); + t.vertices[2]=p_xform.xform(vr[ i*3+2 ]); + t.material=matptr; + t.baked_texture=baked_tex; + if (read_uv) { + + t.uvs[0]=uvr[ i*3+0 ]; + t.uvs[1]=uvr[ i*3+1 ]; + t.uvs[2]=uvr[ i*3+2 ]; + + t.bake_uvs[0]=uv2r[ i*3+0 ]; + t.bake_uvs[1]=uv2r[ i*3+1 ]; + t.bake_uvs[2]=uv2r[ i*3+2 ]; + + } + if (read_normal) { + + t.normals[0]=normal_xform.xform(normalr[ i*3+0 ]).normalized(); + t.normals[1]=normal_xform.xform(normalr[ i*3+1 ]).normalized(); + t.normals[2]=normal_xform.xform(normalr[ i*3+2 ]).normalized(); + } + } + } + } + +} + + +void BakedLightBaker::_parse_geometry(Node* p_node) { + + if (p_node->cast_to<MeshInstance>()) { + + MeshInstance *meshi=p_node->cast_to<MeshInstance>(); + Ref<Mesh> mesh=meshi->get_mesh(); + if (mesh.is_valid()) { + _add_mesh(mesh,meshi->get_material_override(),base_inv * meshi->get_global_transform(),meshi->get_baked_light_texture_id()); + } + } else if (p_node->cast_to<Light>()) { + + Light *dl=p_node->cast_to<Light>(); + + if (dl->get_bake_mode()!=Light::BAKE_MODE_DISABLED) { + + + LightData dirl; + dirl.type=VS::LightType(dl->get_light_type()); + dirl.diffuse=dl->get_color(DirectionalLight::COLOR_DIFFUSE); + dirl.specular=dl->get_color(DirectionalLight::COLOR_SPECULAR); + if (linear_color) + dirl.diffuse=dirl.diffuse.to_linear(); + if (linear_color) + dirl.specular=dirl.specular.to_linear(); + + dirl.energy=dl->get_parameter(DirectionalLight::PARAM_ENERGY); + dirl.pos=dl->get_global_transform().origin; + dirl.up=dl->get_global_transform().basis.get_axis(1).normalized(); + dirl.left=dl->get_global_transform().basis.get_axis(0).normalized(); + dirl.dir=-dl->get_global_transform().basis.get_axis(2).normalized(); + dirl.spot_angle=dl->get_parameter(DirectionalLight::PARAM_SPOT_ANGLE); + dirl.spot_attenuation=dl->get_parameter(DirectionalLight::PARAM_SPOT_ATTENUATION); + dirl.attenuation=dl->get_parameter(DirectionalLight::PARAM_ATTENUATION); + dirl.darkening=dl->get_parameter(DirectionalLight::PARAM_SHADOW_DARKENING); + dirl.radius=dl->get_parameter(DirectionalLight::PARAM_RADIUS); + dirl.bake_direct=dl->get_bake_mode()==Light::BAKE_MODE_FULL; + dirl.rays_thrown=0; + dirl.bake_shadow=dl->get_bake_mode()==Light::BAKE_MODE_INDIRECT_AND_SHADOWS; + lights.push_back(dirl); + } + + } else if (p_node->cast_to<Spatial>()){ + + Spatial *sp = p_node->cast_to<Spatial>(); + + Array arr = p_node->call("_get_baked_light_meshes"); + for(int i=0;i<arr.size();i+=2) { + + Transform xform=arr[i]; + Ref<Mesh> mesh=arr[i+1]; + _add_mesh(mesh,Ref<Material>(),base_inv * (sp->get_global_transform() * xform)); + } + } + + for(int i=0;i<p_node->get_child_count();i++) { + + _parse_geometry(p_node->get_child(i)); + } +} + + +void BakedLightBaker::_fix_lights() { + + + total_light_area=0; + for(int i=0;i<lights.size();i++) { + + LightData &dl=lights[i]; + + switch(dl.type) { + case VS::LIGHT_DIRECTIONAL: { + + float up_max=-1e10; + float dir_max=-1e10; + float left_max=-1e10; + float up_min=1e10; + float dir_min=1e10; + float left_min=1e10; + + for(int j=0;j<triangles.size();j++) { + + for(int k=0;k<3;k++) { + + Vector3 v = triangles[j].vertices[k]; + + float up_d = dl.up.dot(v); + float dir_d = dl.dir.dot(v); + float left_d = dl.left.dot(v); + + if (up_d>up_max) + up_max=up_d; + if (up_d<up_min) + up_min=up_d; + + if (left_d>left_max) + left_max=left_d; + if (left_d<left_min) + left_min=left_d; + + if (dir_d>dir_max) + dir_max=dir_d; + if (dir_d<dir_min) + dir_min=dir_d; + + } + } + + //make a center point, then the upvector and leftvector + dl.pos = dl.left*( left_max+left_min )*0.5 + dl.up*( up_max+up_min )*0.5 + dl.dir*(dir_min-(dir_max-dir_min)); + dl.left*=(left_max-left_min)*0.5; + dl.up*=(up_max-up_min)*0.5; + dl.length = (dir_max - dir_min)*10; //arbitrary number to keep it in scale + dl.area=dl.left.length()*2*dl.up.length()*2; + dl.constant=1.0/dl.area; + } break; + case VS::LIGHT_OMNI: + case VS::LIGHT_SPOT: { + + dl.attenuation_table.resize(ATTENUATION_CURVE_LEN); + for(int j=0;j<ATTENUATION_CURVE_LEN;j++) { + dl.attenuation_table[j]=1.0-Math::pow(j/float(ATTENUATION_CURVE_LEN),dl.attenuation); + float falloff=j*dl.radius/float(ATTENUATION_CURVE_LEN); + if (falloff==0) + falloff=0.000001; + float intensity=4*Math_PI*(falloff*falloff); + //dl.attenuation_table[j]*=falloff*falloff; + dl.attenuation_table[j]*=1.0/(3.0/intensity); + + } + if (dl.type==VS::LIGHT_OMNI) { + + dl.area=4.0*Math_PI*pow(dl.radius,2.0f); + dl.constant=1.0/3.5; + } else { + + + float r = Math::tan(Math::deg2rad(dl.spot_angle))*dl.radius; + float c = 1.0-(Math::deg2rad(dl.spot_angle)*0.5+0.5); + dl.constant=1.0/3.5; + dl.constant*=1.0/c; + + dl.area=Math_PI*r*r*c; + } + + } break; + + + } + + total_light_area+=dl.area; + } +} + +BakedLightBaker::BVH* BakedLightBaker::_parse_bvh(BVH** p_children, int p_size, int p_depth, int &max_depth) { + + if (p_depth>max_depth) { + max_depth=p_depth; + } + + if (p_size==1) { + + return p_children[0]; + } else if (p_size==0) { + + return NULL; + } + + + AABB aabb; + aabb=p_children[0]->aabb; + for(int i=1;i<p_size;i++) { + + aabb.merge_with(p_children[i]->aabb); + } + + int li=aabb.get_longest_axis_index(); + + switch(li) { + + case Vector3::AXIS_X: { + SortArray<BVH*,BVHCmpX> sort_x; + sort_x.nth_element(0,p_size,p_size/2,p_children); + //sort_x.sort(&p_bb[p_from],p_size); + } break; + case Vector3::AXIS_Y: { + SortArray<BVH*,BVHCmpY> sort_y; + sort_y.nth_element(0,p_size,p_size/2,p_children); + //sort_y.sort(&p_bb[p_from],p_size); + } break; + case Vector3::AXIS_Z: { + SortArray<BVH*,BVHCmpZ> sort_z; + sort_z.nth_element(0,p_size,p_size/2,p_children); + //sort_z.sort(&p_bb[p_from],p_size); + + } break; + } + + + BVH* left = _parse_bvh(p_children,p_size/2,p_depth+1,max_depth); + BVH* right = _parse_bvh(&p_children[p_size/2],p_size-p_size/2,p_depth+1,max_depth); + + BVH *_new = memnew(BVH); + _new->aabb=aabb; + _new->center=aabb.pos+aabb.size*0.5; + _new->children[0]=left; + _new->children[1]=right; + _new->leaf=NULL; + + return _new; +} + +void BakedLightBaker::_make_bvh() { + + Vector<BVH*> bases; + bases.resize(triangles.size()); + int max_depth=0; + for(int i=0;i<triangles.size();i++) { + bases[i]=memnew( BVH ); + bases[i]->leaf=&triangles[i]; + bases[i]->aabb.pos=triangles[i].vertices[0]; + bases[i]->aabb.expand_to(triangles[i].vertices[1]); + bases[i]->aabb.expand_to(triangles[i].vertices[2]); + triangles[i].aabb=bases[i]->aabb; + bases[i]->center=bases[i]->aabb.pos+bases[i]->aabb.size*0.5; + } + + bvh=_parse_bvh(bases.ptr(),bases.size(),1,max_depth); + + ray_stack = memnew_arr(uint32_t,max_depth); + bvh_stack = memnew_arr(BVH*,max_depth); + + bvh_depth = max_depth; +} + +void BakedLightBaker::_octree_insert(int p_octant,Triangle* p_triangle, int p_depth) { + + + + + uint32_t *stack=octant_stack; + uint32_t *ptr_stack=octantptr_stack; + Octant *octants=octant_pool.ptr(); + + stack[0]=0; + ptr_stack[0]=0; + + int stack_pos=0; + + + while(true) { + + Octant *octant=&octants[ptr_stack[stack_pos]]; + if (stack[stack_pos]<8) { + + int i = stack[stack_pos]; + stack[stack_pos]++; + + + + //fit_aabb=fit_aabb.grow(bvh->aabb.size.x*0.0001); + + int child_idx =octant->children[i]; + bool encloses; + if (!child_idx) { + + AABB aabb=octant->aabb; + aabb.size*=0.5; + if (i&1) + aabb.pos.x+=aabb.size.x; + if (i&2) + aabb.pos.y+=aabb.size.y; + if (i&4) + aabb.pos.z+=aabb.size.z; + + aabb.grow_by(cell_size*octree_extra_margin); + if (!aabb.intersects(p_triangle->aabb)) + continue; + encloses=aabb.grow(cell_size*-octree_extra_margin*2.0).encloses(p_triangle->aabb); + if (!encloses && !Face3(p_triangle->vertices[0],p_triangle->vertices[1],p_triangle->vertices[2]).intersects_aabb2(aabb)) + continue; + } else { + + Octant *child=&octants[child_idx]; + AABB aabb=child->aabb; + aabb.grow_by(cell_size*octree_extra_margin); + if (!aabb.intersects(p_triangle->aabb)) + continue; + encloses=aabb.grow(cell_size*-octree_extra_margin*2.0).encloses(p_triangle->aabb); + if (!encloses && !Face3(p_triangle->vertices[0],p_triangle->vertices[1],p_triangle->vertices[2]).intersects_aabb2(aabb)) + continue; + + } + + if (encloses) + stack[stack_pos]=8; // quick and dirty opt + + if (!child_idx) { + + + if (octant_pool_size==octant_pool.size()) { + octant_pool.resize(octant_pool_size+OCTANT_POOL_CHUNK); + octants=octant_pool.ptr(); + octant=&octants[ptr_stack[stack_pos]]; + } + child_idx=octant_pool_size++; + octant->children[i]=child_idx; + Octant *child=&octants[child_idx]; + + child->aabb=octant->aabb; + child->texture_x=0; + child->texture_y=0; + + child->aabb.size*=0.5; + if (i&1) + child->aabb.pos.x+=child->aabb.size.x; + if (i&2) + child->aabb.pos.y+=child->aabb.size.y; + if (i&4) + child->aabb.pos.z+=child->aabb.size.z; + + + child->full_accum[0]=0; + child->full_accum[1]=0; + child->full_accum[2]=0; + child->sampler_ofs=0; + + + + if (stack_pos==octree_depth-1) { + child->leaf=true; + child->offset[0]=child->aabb.pos.x+child->aabb.size.x*0.5; + child->offset[1]=child->aabb.pos.y+child->aabb.size.y*0.5; + child->offset[2]=child->aabb.pos.z+child->aabb.size.z*0.5; + child->next_leaf=leaf_list; + + + for(int ci=0;ci<8;ci++) { + child->normal_accum[ci][0]=0; + child->normal_accum[ci][1]=0; + child->normal_accum[ci][2]=0; + + } + + child->bake_neighbour=0; + child->first_neighbour=true; + leaf_list=child_idx; + cell_count++; + + for(int ci=0;ci<8;ci++) { + child->light_accum[ci][0]=0; + child->light_accum[ci][1]=0; + child->light_accum[ci][2]=0; + } + + child->parent=ptr_stack[stack_pos]; + + } else { + + child->leaf=false; + for(int j=0;j<8;j++) { + child->children[j]=0; + } + } + } + + if (!octants[child_idx].leaf) { + stack_pos++; + stack[stack_pos]=0; + ptr_stack[stack_pos]=child_idx; + } else { + + Octant *child=&octants[child_idx]; + + Vector3 n = Plane(p_triangle->vertices[0],p_triangle->vertices[1],p_triangle->vertices[2]).normal; + + + for(int ci=0;ci<8;ci++) { + + Vector3 pos = child->aabb.pos; + + if (ci&1) + pos.x+=child->aabb.size.x; + if (ci&2) + pos.y+=child->aabb.size.y; + if (ci&4) + pos.z+=child->aabb.size.z; + + + pos.x=floor((pos.x+cell_size*0.5)/cell_size); + pos.y=floor((pos.y+cell_size*0.5)/cell_size); + pos.z=floor((pos.z+cell_size*0.5)/cell_size); + + { + Map<Vector3,Vector3>::Element *E=endpoint_normal.find(pos); + if (!E) { + endpoint_normal[pos]=n; + } else { + E->get()+=n; + } + } + + { + + uint64_t bit = get_uv_normal_bit(n); + + Map<Vector3,uint64_t>::Element *E=endpoint_normal_bits.find(pos); + if (!E) { + endpoint_normal_bits[pos]=(1<<bit); + } else { + E->get()|=(1<<bit); + } + + } + + } + + } + + + } else { + stack_pos--; + if (stack_pos<0) + break; + } + } + + +} + + +void BakedLightBaker::_make_octree() { + + + AABB base = bvh->aabb; + float lal=base.get_longest_axis_size(); + //must be square because we want square blocks + base.size.x=lal; + base.size.y=lal; + base.size.z=lal; + base.grow_by(lal*0.001); //for precision + octree_aabb=base; + + cell_size=base.size.x; + for(int i=0;i<octree_depth;i++) + cell_size/=2.0; + octant_stack = memnew_arr(uint32_t,octree_depth*2 ); + octantptr_stack = memnew_arr(uint32_t,octree_depth*2 ); + + octant_pool.resize(OCTANT_POOL_CHUNK); + octant_pool_size=1; + Octant *root=octant_pool.ptr(); + root->leaf=false; + root->aabb=octree_aabb; + root->parent=-1; + for(int i=0;i<8;i++) + root->children[i]=0; + + EditorProgress ep("bake_octree",vformat(TTR("Parsing %d Triangles:"), triangles.size()),triangles.size()); + + for(int i=0;i<triangles.size();i++) { + + _octree_insert(0,&triangles[i],octree_depth-1); + if ((i%1000)==0) { + + ep.step(TTR("Triangle #")+itos(i),i); + } + } + + { + uint32_t oct_idx=leaf_list; + Octant *octants=octant_pool.ptr(); + while(oct_idx) { + + BakedLightBaker::Octant *oct = &octants[oct_idx]; + for(int ci=0;ci<8;ci++) { + + + Vector3 pos = oct->aabb.pos; + + if (ci&1) + pos.x+=oct->aabb.size.x; + if (ci&2) + pos.y+=oct->aabb.size.y; + if (ci&4) + pos.z+=oct->aabb.size.z; + + + pos.x=floor((pos.x+cell_size*0.5)/cell_size); + pos.y=floor((pos.y+cell_size*0.5)/cell_size); + pos.z=floor((pos.z+cell_size*0.5)/cell_size); + + { + Map<Vector3,Vector3>::Element *E=endpoint_normal.find(pos); + if (!E) { + //? + print_line("lolwut?"); + } else { + Vector3 n = E->get().normalized(); + oct->normal_accum[ci][0]=n.x; + oct->normal_accum[ci][1]=n.y; + oct->normal_accum[ci][2]=n.z; + + } + + } + + { + + Map<Vector3,uint64_t>::Element *E=endpoint_normal_bits.find(pos); + if (!E) { + //? + print_line("lolwut?"); + } else { + + float max_aper=0; + for(uint64_t i=0;i<62;i++) { + + if (!(E->get()&(1<<i))) + continue; + Vector3 ang_i = get_bit_normal(i); + + for(uint64_t j=0;j<62;j++) { + + if (i==j) + continue; + if (!(E->get()&(1<<j))) + continue; + Vector3 ang_j = get_bit_normal(j); + float ang = Math::acos(ang_i.dot(ang_j)); + if (ang>max_aper) + max_aper=ang; + } + } + if (max_aper>0.75*Math_PI) { + //angle too wide prevent problems and forget + oct->normal_accum[ci][0]=0; + oct->normal_accum[ci][1]=0; + oct->normal_accum[ci][2]=0; + } + } + } + + + } + + oct_idx=oct->next_leaf; + } + } + + +} + + + + + +void BakedLightBaker::_plot_light(ThreadStack& thread_stack,const Vector3& p_plot_pos, const AABB& p_plot_aabb, const Color& p_light,const Color& p_tint_light,bool p_only_full, const Plane& p_plane) { + + //stackless version + + uint32_t *stack=thread_stack.octant_stack; + uint32_t *ptr_stack=thread_stack.octantptr_stack; + Octant *octants=octant_pool.ptr(); + + stack[0]=0; + ptr_stack[0]=0; + + int stack_pos=0; + + + while(true) { + + Octant &octant=octants[ptr_stack[stack_pos]]; + + if (stack[stack_pos]==0) { + + + Vector3 pos = octant.aabb.pos + octant.aabb.size*0.5; + float md = 1<<(octree_depth - stack_pos ); + float r=cell_size*plot_size*md; + float div = 1.0/(md*md*md); + //div=1.0; + + + float d = p_plot_pos.distance_to(pos); + + if ((p_plane.distance_to(pos)>-cell_size*1.75*md) && d<=r) { + + + float intensity = 1.0 - (d/r)*(d/r); //not gauss but.. + + baked_light_baker_add_64f(&octant.full_accum[0],p_tint_light.r*intensity*div); + baked_light_baker_add_64f(&octant.full_accum[1],p_tint_light.g*intensity*div); + baked_light_baker_add_64f(&octant.full_accum[2],p_tint_light.b*intensity*div); + } + } + + if (octant.leaf) { + + + + //if (p_plane.normal.dot(octant.aabb.get_support(p_plane.normal)) < p_plane.d-CMP_EPSILON) { //octants behind are no go + + + if (!p_only_full) { + float r=cell_size*plot_size; + for(int i=0;i<8;i++) { + Vector3 pos=octant.aabb.pos; + if (i&1) + pos.x+=octant.aabb.size.x; + if (i&2) + pos.y+=octant.aabb.size.y; + if (i&4) + pos.z+=octant.aabb.size.z; + + + + float d = p_plot_pos.distance_to(pos); + + if ((p_plane.distance_to(pos)>-cell_size*1.75) && d<=r) { + + + float intensity = 1.0 - (d/r)*(d/r); //not gauss but.. + if (edge_damp>0) { + Vector3 normal = Vector3(octant.normal_accum[i][0],octant.normal_accum[i][1],octant.normal_accum[i][2]); + if (normal.x>0 || normal.y>0 || normal.z>0) { + + float damp = Math::abs(p_plane.normal.dot(normal)); + intensity*=pow(damp,edge_damp); + + } + } + + //intensity*=1.0-Math::abs(p_plane.distance_to(pos))/(plot_size*cell_size); + //intensity = Math::cos(d*Math_PI*0.5/r); + + baked_light_baker_add_64f(&octant.light_accum[i][0],p_light.r*intensity); + baked_light_baker_add_64f(&octant.light_accum[i][1],p_light.g*intensity); + baked_light_baker_add_64f(&octant.light_accum[i][2],p_light.b*intensity); + + + } + } + } + + stack_pos--; + } else if (stack[stack_pos]<8) { + + int i = stack[stack_pos]; + stack[stack_pos]++; + + if (!octant.children[i]) { + continue; + } + + Octant &child=octants[octant.children[i]]; + + if (!child.aabb.intersects(p_plot_aabb)) + continue; + + if (child.aabb.encloses(p_plot_aabb)) { + stack[stack_pos]=8; //don't test the rest + } + + stack_pos++; + stack[stack_pos]=0; + ptr_stack[stack_pos]=octant.children[i]; + } else { + stack_pos--; + if (stack_pos<0) + break; + } + } + + +} + + +float BakedLightBaker::_throw_ray(ThreadStack& thread_stack,bool p_bake_direct,const Vector3& p_begin, const Vector3& p_end,float p_rest,const Color& p_light,float *p_att_curve,float p_att_pos,int p_att_curve_len,int p_bounces,bool p_first_bounce,bool p_only_dist) { + + + uint32_t* stack = thread_stack.ray_stack; + BVH **bstack = thread_stack.bvh_stack; + + enum { + TEST_AABB_BIT=0, + VISIT_LEFT_BIT=1, + VISIT_RIGHT_BIT=2, + VISIT_DONE_BIT=3, + + + }; + + Vector3 n = (p_end-p_begin); + float len=n.length(); + if (len==0) + return 0; + n/=len; + + + + real_t d=1e10; + bool inters=false; + Vector3 r_normal; + Vector3 r_point; + Vector3 end=p_end; + + Triangle *triangle=NULL; + + /* + for(int i=0;i<max_depth;i++) + stack[i]=0; + */ + + int level=0; + //AABB ray_aabb; + //ray_aabb.pos=p_begin; + //ray_aabb.expand_to(p_end); + + + bstack[0]=bvh; + stack[0]=TEST_AABB_BIT; + + + while(true) { + + uint32_t mode = stack[level]; + const BVH &b = *bstack[level]; + bool done=false; + + switch(mode) { + case TEST_AABB_BIT: { + + if (b.leaf) { + + + Face3 f3(b.leaf->vertices[0],b.leaf->vertices[1],b.leaf->vertices[2]); + + + Vector3 res; + + if (f3.intersects_segment(p_begin,end,&res)) { + + + float nd = n.dot(res); + if (nd<d) { + + d=nd; + r_point=res; + end=res; + len=(p_begin-end).length(); + r_normal=f3.get_plane().get_normal(); + triangle=b.leaf; + inters=true; + } + + } + + stack[level]=VISIT_DONE_BIT; + } else { + + + bool valid = b.aabb.smits_intersect_ray(p_begin,n,0,len); + //bool valid = b.aabb.intersects_segment(p_begin,p_end); + //bool valid = b.aabb.intersects(ray_aabb); + + if (!valid) { + + stack[level]=VISIT_DONE_BIT; + + } else { + + stack[level]=VISIT_LEFT_BIT; + } + } + + } continue; + case VISIT_LEFT_BIT: { + + stack[level]=VISIT_RIGHT_BIT; + bstack[level+1]=b.children[0]; + stack[level+1]=TEST_AABB_BIT; + level++; + + } continue; + case VISIT_RIGHT_BIT: { + + stack[level]=VISIT_DONE_BIT; + bstack[level+1]=b.children[1]; + stack[level+1]=TEST_AABB_BIT; + level++; + } continue; + case VISIT_DONE_BIT: { + + if (level==0) { + done=true; + break; + } else + level--; + + } continue; + } + + + if (done) + break; + } + + + + if (inters) { + + if (p_only_dist) { + + return p_begin.distance_to(r_point); + } + + + //should check if there is normals first + Vector2 uv; + if (true) { + + triangle->get_uv_and_normal(r_point,uv,r_normal); + + } else { + + } + + if (n.dot(r_normal)>0) + return -1; + + if (n.dot(r_normal)>0) + r_normal=-r_normal; + + + //ok... + Color diffuse_at_point(0.8,0.8,0.8); + Color specular_at_point(0.0,0.0,0.0); + + + float dist = p_begin.distance_to(r_point); + + AABB aabb; + aabb.pos=r_point; + aabb.pos-=Vector3(1,1,1)*cell_size*plot_size; + aabb.size=Vector3(2,2,2)*cell_size*plot_size; + + Color res_light=p_light; + float att=1.0; + float dp=(1.0-normal_damp)*n.dot(-r_normal)+normal_damp; + + if (p_att_curve) { + + p_att_pos+=dist; + int cpos = Math::fast_ftoi((p_att_pos/p_att_curve_len)*ATTENUATION_CURVE_LEN); + cpos=CLAMP(cpos,0,ATTENUATION_CURVE_LEN-1); + att=p_att_curve[cpos]; + } + + + res_light.r*=dp; + res_light.g*=dp; + res_light.b*=dp; + + //light is plotted before multiplication with diffuse, this way + //the multiplication can happen with more detail in the shader + + + + if (triangle->material) { + + //triangle->get_uv(r_point); + + diffuse_at_point=triangle->material->diffuse.get_color(uv); + specular_at_point=triangle->material->specular.get_color(uv); + } + + + diffuse_at_point.r=res_light.r*diffuse_at_point.r; + diffuse_at_point.g=res_light.g*diffuse_at_point.g; + diffuse_at_point.b=res_light.b*diffuse_at_point.b; + + if (p_bounces>0) { + + + p_rest-=dist; + if (p_rest<CMP_EPSILON) + return 0; + + if (r_normal==-n) + return 0; //todo change a little + + r_point+=r_normal*0.01; + + + + + specular_at_point.r=res_light.r*specular_at_point.r; + specular_at_point.g=res_light.g*specular_at_point.g; + specular_at_point.b=res_light.b*specular_at_point.b; + + + + if (use_diffuse && (diffuse_at_point.r>CMP_EPSILON || diffuse_at_point.g>CMP_EPSILON || diffuse_at_point.b>CMP_EPSILON)) { + //diffuse bounce + + Vector3 c1=r_normal.cross(n).normalized(); + Vector3 c2=r_normal.cross(c1).normalized(); + double r1 = double(rand())/RAND_MAX; + double r2 = double(rand())/RAND_MAX; + double r3 = double(rand())/RAND_MAX; +#if 0 + Vector3 next = - ((c1*(r1-0.5)) + (c2*(r2-0.5)) + (r_normal*(r3-0.5))).normalized()*0.5 + r_normal*0.5; + + if (next==Vector3()) + next=r_normal; + Vector3 rn=next.normalized(); + +#else + Vector3 rn = ((c1*(r1-0.5)) + (c2*(r2-0.5)) + (r_normal*r3*0.5)).normalized(); +#endif + + + _throw_ray(thread_stack,p_bake_direct,r_point,r_point+rn*p_rest,p_rest,diffuse_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1); + } + + if (use_specular && (specular_at_point.r>CMP_EPSILON || specular_at_point.g>CMP_EPSILON || specular_at_point.b>CMP_EPSILON)) { + //specular bounce + + //Vector3 c1=r_normal.cross(n).normalized(); + //Vector3 c2=r_normal.cross(c1).normalized(); + + Vector3 rn = n - r_normal *r_normal.dot(n) * 2.0; + + _throw_ray(thread_stack,p_bake_direct,r_point,r_point+rn*p_rest,p_rest,specular_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1); + } + } + + //specular later + //_plot_light_point(r_point,octree,octree_aabb,p_light); + + + Color plot_light=res_light.linear_interpolate(diffuse_at_point,tint); + plot_light.r*=att; + plot_light.g*=att; + plot_light.b*=att; + Color tint_light=diffuse_at_point; + tint_light.r*=att; + tint_light.g*=att; + tint_light.b*=att; + + bool skip=false; + + if (!p_first_bounce || p_bake_direct) { + + + float r = plot_size * cell_size*2; + if (dist<r) { + //avoid accumulaiton of light on corners + //plot_light=plot_light.linear_interpolate(Color(0,0,0,0),1.0-sd/plot_size*plot_size); + skip=true; + + } else { + + + Vector3 c1=r_normal.cross(n).normalized(); + Vector3 c2=r_normal.cross(c1).normalized(); + double r1 = double(rand())/RAND_MAX; + double r2 = double(rand())/RAND_MAX; + double r3 = double(rand())/RAND_MAX; + Vector3 rn = ((c1*(r1-0.5)) + (c2*(r2-0.5)) + (r_normal*r3*0.25)).normalized(); + float d =_throw_ray(thread_stack,p_bake_direct,r_point,r_point+rn*p_rest,p_rest,diffuse_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1,false,true); + r = plot_size*cell_size*ao_radius; + if (d>0 && d<r) { + //avoid accumulaiton of light on corners + //plot_light=plot_light.linear_interpolate(Color(0,0,0,0),1.0-sd/plot_size*plot_size); + skip=true; + + } else { + //plot_light=Color(0,0,0,0); + } + } + } + + + Plane plane(r_point,r_normal); + if (!skip) + _plot_light(thread_stack,r_point,aabb,plot_light,tint_light,!(!p_first_bounce || p_bake_direct),plane); + + + return dist; + } + + return -1; + +} + + + + +void BakedLightBaker::_make_octree_texture() { + + + BakedLightBaker::Octant *octants=octant_pool.ptr(); + + //find neighbours first, to have a better idea of what amount of space is needed + { + + Vector<OctantHash> octant_hashing; + octant_hashing.resize(octant_pool_size); + Vector<uint32_t> hash_table; + int hash_table_size=Math::larger_prime(16384); + hash_table.resize(hash_table_size); + uint32_t*hashptr = hash_table.ptr(); + OctantHash*octhashptr = octant_hashing.ptr(); + + for(int i=0;i<hash_table_size;i++) + hashptr[i]=0; + + + //step 1 add to hash table + + uint32_t oct_idx=leaf_list; + + + while(oct_idx) { + + BakedLightBaker::Octant *oct = &octants[oct_idx]; + uint64_t base=0; + Vector3 pos = oct->aabb.pos - octree_aabb.pos; //make sure is always positive + base=int((pos.x+cell_size*0.5)/cell_size); + base<<=16; + base|=int((pos.y+cell_size*0.5)/cell_size); + base<<=16; + base|=int((pos.z+cell_size*0.5)/cell_size); + + uint32_t hash = HashMapHasherDefault::hash(base); + uint32_t idx = hash % hash_table_size; + octhashptr[oct_idx].next=hashptr[idx]; + octhashptr[oct_idx].hash=hash; + octhashptr[oct_idx].value=base; + hashptr[idx]=oct_idx; + + oct_idx=oct->next_leaf; + + } + + //step 2 find neighbours + oct_idx=leaf_list; + int neighbours=0; + + + while(oct_idx) { + + BakedLightBaker::Octant *oct = &octants[oct_idx]; + Vector3 pos = oct->aabb.pos - octree_aabb.pos; //make sure is always positive + pos.x+=cell_size; + uint64_t base=0; + base=int((pos.x+cell_size*0.5)/cell_size); + base<<=16; + base|=int((pos.y+cell_size*0.5)/cell_size); + base<<=16; + base|=int((pos.z+cell_size*0.5)/cell_size); + + uint32_t hash = HashMapHasherDefault::hash(base); + uint32_t idx = hash % hash_table_size; + + uint32_t bucket = hashptr[idx]; + + while(bucket) { + + if (octhashptr[bucket].value==base) { + + oct->bake_neighbour=bucket; + octants[bucket].first_neighbour=false; + neighbours++; + break; + } + + bucket = octhashptr[bucket].next; + } + + oct_idx=oct->next_leaf; + + } + + print_line("octant with neighbour: "+itos(neighbours)); + + } + + + //ok let's try to just create a texture + + int otex_w=256; + + while (true) { + + + + uint32_t oct_idx=leaf_list; + + int row=0; + + + print_line("begin at row "+itos(row)); + int longest_line_reused=0; + int col=0; + int processed=0; + + //reset + while(oct_idx) { + + BakedLightBaker::Octant *oct = &octants[oct_idx]; + oct->texture_x=0; + oct->texture_y=0; + oct_idx=oct->next_leaf; + + } + + oct_idx=leaf_list; + //assign + while(oct_idx) { + + BakedLightBaker::Octant *oct = &octants[oct_idx]; + if (oct->first_neighbour && oct->texture_x==0 && oct->texture_y==0) { + //was not processed + uint32_t current_idx=oct_idx; + int reused=0; + + while(current_idx) { + BakedLightBaker::Octant *o = &octants[current_idx]; + if (col+1 >= otex_w) { + col=0; + row+=4; + } + o->texture_x=col; + o->texture_y=row; + processed++; + + if (o->bake_neighbour) { + reused++; + } + col+=o->bake_neighbour ? 1 : 2; //reuse neighbour + current_idx=o->bake_neighbour; + } + + if (reused>longest_line_reused) { + longest_line_reused=reused; + } + } + oct_idx=oct->next_leaf; + } + + row+=4; + + if (otex_w < row) { + + otex_w*=2; + } else { + + baked_light_texture_w=otex_w; + baked_light_texture_h=nearest_power_of_2(row); + print_line("w: "+itos(otex_w)); + print_line("h: "+itos(row)); + break; + } + + + } + + + { + + otex_w=(1<<lattice_size)*(1<<lattice_size)*2; //make sure lattice fits horizontally + Vector3 lattice_cell_size=octree_aabb.size; + for(int i=0;i<lattice_size;i++) { + + lattice_cell_size*=0.5; + } + + + + while(true) { + + //let's plot the leafs first, given the octree is not so obvious which size it will have + int row=4+4*(1<<lattice_size); + int col=0; + + col=0; + row+=4; + print_line("end at row "+itos(row)); + + //put octree, no need for recursion, just loop backwards. + int regular_octants=0; + for(int i=octant_pool_size-1;i>=0;i--) { + + BakedLightBaker::Octant *oct = &octants[i]; + if (oct->leaf) //ignore leaf + continue; + if (oct->aabb.size.x>lattice_cell_size.x*1.1) { //bigger than latice, skip + oct->texture_x=0; + oct->texture_y=0; + } else if (oct->aabb.size.x>lattice_cell_size.x*0.8) { + //this is the initial lattice + Vector3 pos = oct->aabb.pos - octree_aabb.pos; //make sure is always positive + int x = int((pos.x+lattice_cell_size.x*0.5)/lattice_cell_size.x); + int y = int((pos.y+lattice_cell_size.y*0.5)/lattice_cell_size.y); + int z = int((pos.z+lattice_cell_size.z*0.5)/lattice_cell_size.z); + //bug net + ERR_FAIL_INDEX(x,(1<<lattice_size)); + ERR_FAIL_INDEX(y,(1<<lattice_size)); + ERR_FAIL_INDEX(z,(1<<lattice_size)); + + /*int ofs = z*(1<<lattice_size)*(1<<lattice_size)+y*(1<<lattice_size)+x; + ofs*=4; + oct->texture_x=ofs%otex_w; + oct->texture_y=(ofs/otex_w)*4+4; + */ + + oct->texture_x=(x+(1<<lattice_size)*z)*2; + oct->texture_y=4+y*4; + //print_line("pos: "+itos(x)+","+itos(y)+","+itos(z)+" - ofs"+itos(oct->texture_x)+","+itos(oct->texture_y)); + + + } else { + //an everyday regular octant + + if (col+2 > otex_w) { + col=0; + row+=4; + } + + oct->texture_x=col; + oct->texture_y=row; + col+=2; + regular_octants++; + + + } + } + print_line("octants end at row "+itos(row)+" totalling"+itos(regular_octants)); + + //ok evaluation. + + if (otex_w<=2048 && row>2048) { //too big upwards, try bigger texture + otex_w*=2; + continue; + } else { + baked_octree_texture_w=otex_w; + baked_octree_texture_h=row+4; + break; + } + + } + + + } + + + baked_octree_texture_h=nearest_power_of_2(baked_octree_texture_h); + print_line("RESULT! "+itos(baked_octree_texture_w)+","+itos(baked_octree_texture_h)); + +} + + + + + + + + +double BakedLightBaker::get_normalization(int p_light_idx) const { + + double nrg=0; + + const LightData &dl=lights[p_light_idx]; + double cell_area = cell_size*cell_size; + //nrg+= /*dl.energy */ (dl.rays_thrown * cell_area / dl.area); + nrg=dl.rays_thrown * cell_area; + nrg*=(Math_PI*plot_size*plot_size)*0.5; // damping of radial linear gradient kernel + nrg*=dl.constant; + //nrg*=5; + + + return nrg; +} + + + +double BakedLightBaker::get_modifier(int p_light_idx) const { + + double nrg=0; + + const LightData &dl=lights[p_light_idx]; + double cell_area = cell_size*cell_size; + //nrg+= /*dl.energy */ (dl.rays_thrown * cell_area / dl.area); + nrg=cell_area; + nrg*=(Math_PI*plot_size*plot_size)*0.5; // damping of radial linear gradient kernel + nrg*=dl.constant; + //nrg*=5; + + + return nrg; +} + +void BakedLightBaker::throw_rays(ThreadStack& thread_stack,int p_amount) { + + + + for(int i=0;i<lights.size();i++) { + + LightData &dl=lights[i]; + + + int amount = p_amount * total_light_area / dl.area; + double mod = 1.0/double(get_modifier(i)); + mod*=p_amount/float(amount); + + switch(dl.type) { + + case VS::LIGHT_DIRECTIONAL: { + + + for(int j=0;j<amount;j++) { + Vector3 from = dl.pos; + double r1 = double(rand())/RAND_MAX; + double r2 = double(rand())/RAND_MAX; + from+=dl.up*(r1*2.0-1.0); + from+=dl.left*(r2*2.0-1.0); + Vector3 to = from+dl.dir*dl.length; + Color col=dl.diffuse; + float m = mod*dl.energy; + col.r*=m; + col.g*=m; + col.b*=m; + + dl.rays_thrown++; + baked_light_baker_add_64i(&total_rays,1); + + _throw_ray(thread_stack,dl.bake_direct,from,to,dl.length,col,NULL,0,0,max_bounces,true); + } + } break; + case VS::LIGHT_OMNI: { + + + for(int j=0;j<amount;j++) { + Vector3 from = dl.pos; + + double r1 = double(rand())/RAND_MAX; + double r2 = double(rand())/RAND_MAX; + double r3 = double(rand())/RAND_MAX; + +#if 0 + //crap is not uniform.. + Vector3 dir = Vector3(r1*2.0-1.0,r2*2.0-1.0,r3*2.0-1.0).normalized(); + +#else + + double phi = r1*Math_PI*2.0; + double costheta = r2*2.0-1.0; + double u = r3; + + double theta = acos( costheta ); + double r = 1.0 * pow( u,1/3.0 ); + + Vector3 dir( + r * sin( theta) * cos( phi ), + r * sin( theta) * sin( phi ), + r * cos( theta ) + ); + dir.normalize(); + +#endif + Vector3 to = dl.pos+dir*dl.radius; + Color col=dl.diffuse; + float m = mod*dl.energy; + col.r*=m; + col.g*=m; + col.b*=m; + + dl.rays_thrown++; + baked_light_baker_add_64i(&total_rays,1); + _throw_ray(thread_stack,dl.bake_direct,from,to,dl.radius,col,dl.attenuation_table.ptr(),0,dl.radius,max_bounces,true); + //_throw_ray(i,from,to,dl.radius,col,NULL,0,dl.radius,max_bounces,true); + } + + } break; + case VS::LIGHT_SPOT: { + + for(int j=0;j<amount;j++) { + Vector3 from = dl.pos; + + double r1 = double(rand())/RAND_MAX; + //double r2 = double(rand())/RAND_MAX; + double r3 = double(rand())/RAND_MAX; + + float d=Math::tan(Math::deg2rad(dl.spot_angle)); + + float x = sin(r1*Math_PI*2.0)*d; + float y = cos(r1*Math_PI*2.0)*d; + + Vector3 dir = r3*(dl.dir + dl.up*y + dl.left*x) + (1.0-r3)*dl.dir; + dir.normalize(); + + + Vector3 to = dl.pos+dir*dl.radius; + Color col=dl.diffuse; + float m = mod*dl.energy; + col.r*=m; + col.g*=m; + col.b*=m; + + dl.rays_thrown++; + baked_light_baker_add_64i(&total_rays,1); + _throw_ray(thread_stack,dl.bake_direct,from,to,dl.radius,col,dl.attenuation_table.ptr(),0,dl.radius,max_bounces,true); + //_throw_ray(i,from,to,dl.radius,col,NULL,0,dl.radius,max_bounces,true); + } + + } break; + + } + } +} + + + + + + + + + + + + + +void BakedLightBaker::bake(const Ref<BakedLight> &p_light, Node* p_node) { + + if (baking) + return; + cell_count=0; + + base_inv=p_node->cast_to<Spatial>()->get_global_transform().affine_inverse(); + EditorProgress ep("bake",TTR("Light Baker Setup:"),5); + baked_light=p_light; + lattice_size=baked_light->get_initial_lattice_subdiv(); + octree_depth=baked_light->get_cell_subdivision(); + plot_size=baked_light->get_plot_size(); + max_bounces=baked_light->get_bounces(); + use_diffuse=baked_light->get_bake_flag(BakedLight::BAKE_DIFFUSE); + use_specular=baked_light->get_bake_flag(BakedLight::BAKE_SPECULAR); + use_translucency=baked_light->get_bake_flag(BakedLight::BAKE_TRANSLUCENT); + + edge_damp=baked_light->get_edge_damp(); + normal_damp=baked_light->get_normal_damp(); + octree_extra_margin=baked_light->get_cell_extra_margin(); + tint=baked_light->get_tint(); + ao_radius=baked_light->get_ao_radius(); + ao_strength=baked_light->get_ao_strength(); + linear_color=baked_light->get_bake_flag(BakedLight::BAKE_LINEAR_COLOR); + + baked_textures.clear(); + for(int i=0;i<baked_light->get_lightmaps_count();i++) { + BakeTexture bt; + bt.width=baked_light->get_lightmap_gen_size(i).x; + bt.height=baked_light->get_lightmap_gen_size(i).y; + baked_textures.push_back(bt); + } + + + ep.step(TTR("Parsing Geometry"),0); + _parse_geometry(p_node); + mat_map.clear(); + tex_map.clear(); + print_line("\ttotal triangles: "+itos(triangles.size())); + // no geometry + if (triangles.size() == 0) { + return; + } + ep.step(TTR("Fixing Lights"),1); + _fix_lights(); + ep.step(TTR("Making BVH"),2); + _make_bvh(); + ep.step(TTR("Creating Light Octree"),3); + _make_octree(); + ep.step(TTR("Creating Octree Texture"),4); + _make_octree_texture(); + baking=true; + _start_thread(); + +} + + +void BakedLightBaker::update_octree_sampler(PoolVector<int> &p_sampler) { + + BakedLightBaker::Octant *octants=octant_pool.ptr(); + double norm = 1.0/double(total_rays); + + + + if (p_sampler.size()==0 || first_bake_to_map) { + + Vector<int> tmp_smp; + tmp_smp.resize(32); //32 for header + + for(int i=0;i<32;i++) { + tmp_smp[i]=0; + } + + for(int i=octant_pool_size-1;i>=0;i--) { + + if (i==0) + tmp_smp[1]=tmp_smp.size(); + + Octant &octant=octants[i]; + octant.sampler_ofs = tmp_smp.size(); + int idxcol[2]={0,0}; + + int r = CLAMP((octant.full_accum[0]*norm)*2048,0,32767); + int g = CLAMP((octant.full_accum[1]*norm)*2048,0,32767); + int b = CLAMP((octant.full_accum[2]*norm)*2048,0,32767); + + idxcol[0]|=r; + idxcol[1]|=(g<<16)|b; + + if (octant.leaf) { + tmp_smp.push_back(idxcol[0]); + tmp_smp.push_back(idxcol[1]); + } else { + + for(int j=0;j<8;j++) { + if (octant.children[j]) { + idxcol[0]|=(1<<(j+16)); + } + } + tmp_smp.push_back(idxcol[0]); + tmp_smp.push_back(idxcol[1]); + for(int j=0;j<8;j++) { + if (octant.children[j]) { + tmp_smp.push_back(octants[octant.children[j]].sampler_ofs); + if (octants[octant.children[j]].sampler_ofs==0) { + print_line("FUUUUUUUUCK"); + } + } + } + } + + } + + p_sampler.resize(tmp_smp.size()); + PoolVector<int>::Write w = p_sampler.write(); + int ss = tmp_smp.size(); + for(int i=0;i<ss;i++) { + w[i]=tmp_smp[i]; + } + + first_bake_to_map=false; + + } + + double gamma = baked_light->get_gamma_adjust(); + double mult = baked_light->get_energy_multiplier(); + float saturation = baked_light->get_saturation(); + + PoolVector<int>::Write w = p_sampler.write(); + + encode_uint32(octree_depth,(uint8_t*)&w[2]); + encode_uint32(linear_color,(uint8_t*)&w[3]); + + encode_float(octree_aabb.pos.x,(uint8_t*)&w[4]); + encode_float(octree_aabb.pos.y,(uint8_t*)&w[5]); + encode_float(octree_aabb.pos.z,(uint8_t*)&w[6]); + encode_float(octree_aabb.size.x,(uint8_t*)&w[7]); + encode_float(octree_aabb.size.y,(uint8_t*)&w[8]); + encode_float(octree_aabb.size.z,(uint8_t*)&w[9]); + + //norm*=multiplier; + + for(int i=octant_pool_size-1;i>=0;i--) { + + Octant &octant=octants[i]; + int idxcol[2]={w[octant.sampler_ofs],w[octant.sampler_ofs+1]}; + + double rf=pow(octant.full_accum[0]*norm*mult,gamma); + double gf=pow(octant.full_accum[1]*norm*mult,gamma); + double bf=pow(octant.full_accum[2]*norm*mult,gamma); + + double gray = (rf+gf+bf)/3.0; + rf = gray + (rf-gray)*saturation; + gf = gray + (gf-gray)*saturation; + bf = gray + (bf-gray)*saturation; + + + int r = CLAMP((rf)*2048,0,32767); + int g = CLAMP((gf)*2048,0,32767); + int b = CLAMP((bf)*2048,0,32767); + + idxcol[0]=((idxcol[0]>>16)<<16)|r; + idxcol[1]=(g<<16)|b; + w[octant.sampler_ofs]=idxcol[0]; + w[octant.sampler_ofs+1]=idxcol[1]; + } + +} + +void BakedLightBaker::update_octree_images(PoolVector<uint8_t> &p_octree,PoolVector<uint8_t> &p_light) { + + + int len = baked_octree_texture_w*baked_octree_texture_h*4; + p_octree.resize(len); + + int ilen = baked_light_texture_w*baked_light_texture_h*4; + p_light.resize(ilen); + + + PoolVector<uint8_t>::Write w = p_octree.write(); + zeromem(w.ptr(),len); + + PoolVector<uint8_t>::Write iw = p_light.write(); + zeromem(iw.ptr(),ilen); + + float gamma = baked_light->get_gamma_adjust(); + float mult = baked_light->get_energy_multiplier(); + + for(int i=0;i<len;i+=4) { + w[i+0]=0xFF; + w[i+1]=0; + w[i+2]=0xFF; + w[i+3]=0xFF; + } + + for(int i=0;i<ilen;i+=4) { + iw[i+0]=0xFF; + iw[i+1]=0; + iw[i+2]=0xFF; + iw[i+3]=0xFF; + } + + float multiplier=1.0; + + if (baked_light->get_format()==BakedLight::FORMAT_HDR8) + multiplier=8; + encode_uint32(baked_octree_texture_w,&w[0]); + encode_uint32(baked_octree_texture_h,&w[4]); + encode_uint32(0,&w[8]); + encode_float(1<<lattice_size,&w[12]); + encode_uint32(octree_depth-lattice_size,&w[16]); + encode_uint32(multiplier,&w[20]); + encode_uint16(baked_light_texture_w,&w[24]); //if present, use the baked light texture + encode_uint16(baked_light_texture_h,&w[26]); + encode_uint32(0,&w[28]); //baked light texture format + + encode_float(octree_aabb.pos.x,&w[32]); + encode_float(octree_aabb.pos.y,&w[36]); + encode_float(octree_aabb.pos.z,&w[40]); + encode_float(octree_aabb.size.x,&w[44]); + encode_float(octree_aabb.size.y,&w[48]); + encode_float(octree_aabb.size.z,&w[52]); + + + BakedLightBaker::Octant *octants=octant_pool.ptr(); + int octant_count=octant_pool_size; + uint8_t *ptr = w.ptr(); + uint8_t *lptr = iw.ptr(); + + + int child_offsets[8]={ + 0, + 4, + baked_octree_texture_w*4, + baked_octree_texture_w*4+4, + baked_octree_texture_w*8+0, + baked_octree_texture_w*8+4, + baked_octree_texture_w*8+baked_octree_texture_w*4, + baked_octree_texture_w*8+baked_octree_texture_w*4+4, + }; + + int lchild_offsets[8]={ + 0, + 4, + baked_light_texture_w*4, + baked_light_texture_w*4+4, + baked_light_texture_w*8+0, + baked_light_texture_w*8+4, + baked_light_texture_w*8+baked_light_texture_w*4, + baked_light_texture_w*8+baked_light_texture_w*4+4, + }; + + /*Vector<double> norm_arr; + norm_arr.resize(lights.size()); + + for(int i=0;i<lights.size();i++) { + norm_arr[i] = 1.0/get_normalization(i); + } + + const double *normptr=norm_arr.ptr(); +*/ + double norm = 1.0/double(total_rays); + mult/=multiplier; + double saturation = baked_light->get_saturation(); + + for(int i=0;i<octant_count;i++) { + + Octant &oct=octants[i]; + if (oct.texture_x==0 && oct.texture_y==0) + continue; + + + if (oct.leaf) { + + int ofs = (oct.texture_y * baked_light_texture_w + oct.texture_x)<<2; + ERR_CONTINUE(ofs<0 || ofs >ilen); + //write colors + for(int j=0;j<8;j++) { + + /* + if (!oct.children[j]) + continue; + */ + uint8_t *iptr=&lptr[ofs+lchild_offsets[j]]; + + float r=oct.light_accum[j][0]*norm; + float g=oct.light_accum[j][1]*norm; + float b=oct.light_accum[j][2]*norm; + + r=pow(r*mult,gamma); + g=pow(g*mult,gamma); + b=pow(b*mult,gamma); + + double gray = (r+g+b)/3.0; + r = gray + (r-gray)*saturation; + g = gray + (g-gray)*saturation; + b = gray + (b-gray)*saturation; + + float ic[3]={ + r, + g, + b, + }; + iptr[0]=CLAMP(ic[0]*255.0,0,255); + iptr[1]=CLAMP(ic[1]*255.0,0,255); + iptr[2]=CLAMP(ic[2]*255.0,0,255); + iptr[3]=255; + } + + } else { + + int ofs = (oct.texture_y * baked_octree_texture_w + oct.texture_x)<<2; + ERR_CONTINUE(ofs<0 || ofs >len); + + //write indices + for(int j=0;j<8;j++) { + + if (!oct.children[j]) + continue; + Octant&choct=octants[oct.children[j]]; + uint8_t *iptr=&ptr[ofs+child_offsets[j]]; + + iptr[0]=choct.texture_x>>8; + iptr[1]=choct.texture_x&0xFF; + iptr[2]=choct.texture_y>>8; + iptr[3]=choct.texture_y&0xFF; + + } + } + + } + + +} + + +void BakedLightBaker::_free_bvh(BVH* p_bvh) { + + if (!p_bvh->leaf) { + if (p_bvh->children[0]) + _free_bvh(p_bvh->children[0]); + if (p_bvh->children[1]) + _free_bvh(p_bvh->children[1]); + } + + memdelete(p_bvh); + +} + + +bool BakedLightBaker::is_baking() { + + return baking; +} + +void BakedLightBaker::set_pause(bool p_pause){ + + if (paused==p_pause) + return; + + paused=p_pause; + + if (paused) { + _stop_thread(); + } else { + _start_thread(); + } +} +bool BakedLightBaker::is_paused() { + + return paused; + +} + +void BakedLightBaker::_bake_thread_func(void *arg) { + + BakedLightBaker *ble = (BakedLightBaker*)arg; + + + + ThreadStack thread_stack; + + thread_stack.ray_stack = memnew_arr(uint32_t,ble->bvh_depth); + thread_stack.bvh_stack = memnew_arr(BVH*,ble->bvh_depth); + thread_stack.octant_stack = memnew_arr(uint32_t,ble->octree_depth*2 ); + thread_stack.octantptr_stack = memnew_arr(uint32_t,ble->octree_depth*2 ); + + while(!ble->bake_thread_exit) { + + ble->throw_rays(thread_stack,1000); + } + + memdelete_arr(thread_stack.ray_stack ); + memdelete_arr(thread_stack.bvh_stack ); + memdelete_arr(thread_stack.octant_stack ); + memdelete_arr(thread_stack.octantptr_stack ); + +} + +void BakedLightBaker::_start_thread() { + + if (threads.size()!=0) + return; + bake_thread_exit=false; + + int thread_count = EDITOR_DEF("light_baker/custom_bake_threads",0); + if (thread_count<=0 || thread_count>64) + thread_count=OS::get_singleton()->get_processor_count(); + + //thread_count=1; + threads.resize(thread_count); + for(int i=0;i<threads.size();i++) { + threads[i]=Thread::create(_bake_thread_func,this); + } +} + +void BakedLightBaker::_stop_thread() { + + if (threads.size()==0) + return; + bake_thread_exit=true; + for(int i=0;i<threads.size();i++) { + Thread::wait_to_finish(threads[i]); + memdelete(threads[i]); + } + threads.clear(); +} + +void BakedLightBaker::_plot_pixel_to_lightmap(int x, int y, int width, int height, uint8_t *image, const Vector3& p_pos,const Vector3& p_normal,double *p_norm_ptr,float mult,float gamma) { + + + uint8_t *ptr = &image[(y*width+x)*4]; + //int lc = lights.size(); + double norm = 1.0/double(total_rays); + + + Color color; + + Octant *octants=octant_pool.ptr(); + + + int octant_idx=0; + + + while(true) { + + Octant &octant=octants[octant_idx]; + + if (octant.leaf) { + + Vector3 lpos = p_pos-octant.aabb.pos; + lpos/=octant.aabb.size; + + Vector3 cols[8]; + + for(int i=0;i<8;i++) { + + cols[i].x+=octant.light_accum[i][0]*norm; + cols[i].y+=octant.light_accum[i][1]*norm; + cols[i].z+=octant.light_accum[i][2]*norm; + } + + + /*Vector3 final = (cols[0] + (cols[1] - cols[0]) * lpos.y); + final = final + ((cols[2] + (cols[3] - cols[2]) * lpos.y) - final)*lpos.x; + + Vector3 final2 = (cols[4+0] + (cols[4+1] - cols[4+0]) * lpos.y); + final2 = final2 + ((cols[4+2] + (cols[4+3] - cols[4+2]) * lpos.y) - final2)*lpos.x;*/ + + Vector3 finala = cols[0].linear_interpolate(cols[1],lpos.x); + Vector3 finalb = cols[2].linear_interpolate(cols[3],lpos.x); + Vector3 final = finala.linear_interpolate(finalb,lpos.y); + + Vector3 final2a = cols[4+0].linear_interpolate(cols[4+1],lpos.x); + Vector3 final2b = cols[4+2].linear_interpolate(cols[4+3],lpos.x); + Vector3 final2 = final2a.linear_interpolate(final2b,lpos.y); + + final = final.linear_interpolate(final2,lpos.z); + if (baked_light->get_format()==BakedLight::FORMAT_HDR8) + final*=8.0; + + + color.r=pow(final.x*mult,gamma); + color.g=pow(final.y*mult,gamma); + color.b=pow(final.z*mult,gamma); + color.a=1.0; + + int lc = lights.size(); + LightData *lv = lights.ptr(); + for(int i=0;i<lc;i++) { + //shadow baking + if (!lv[i].bake_shadow) + continue; + Vector3 from = p_pos+p_normal*0.01; + Vector3 to; + float att=0; + switch(lv[i].type) { + case VS::LIGHT_DIRECTIONAL: { + to=from-lv[i].dir*lv[i].length; + } break; + case VS::LIGHT_OMNI: { + to=lv[i].pos; + float d = MIN(lv[i].radius,to.distance_to(from))/lv[i].radius; + att=d;//1.0-d; + } break; + default: continue; + } + + uint32_t* stack = ray_stack; + BVH **bstack = bvh_stack; + + enum { + TEST_RAY_BIT=0, + VISIT_LEFT_BIT=1, + VISIT_RIGHT_BIT=2, + VISIT_DONE_BIT=3, + + + }; + + bool intersected=false; + + int level=0; + + Vector3 n = (to-from); + float len=n.length(); + if (len==0) + continue; + n/=len; + + bstack[0]=bvh; + stack[0]=TEST_RAY_BIT; + + + while(!intersected) { + + uint32_t mode = stack[level]; + const BVH &b = *bstack[level]; + bool done=false; + + switch(mode) { + case TEST_RAY_BIT: { + + if (b.leaf) { + + + Face3 f3(b.leaf->vertices[0],b.leaf->vertices[1],b.leaf->vertices[2]); + + + Vector3 res; + + if (f3.intersects_segment(from,to)) { + intersected=true; + done=true; + } + + stack[level]=VISIT_DONE_BIT; + } else { + + + bool valid = b.aabb.smits_intersect_ray(from,n,0,len); + //bool valid = b.aabb.intersects_segment(p_begin,p_end); + //bool valid = b.aabb.intersects(ray_aabb); + + if (!valid) { + + stack[level]=VISIT_DONE_BIT; + + } else { + + stack[level]=VISIT_LEFT_BIT; + } + } + + } continue; + case VISIT_LEFT_BIT: { + + stack[level]=VISIT_RIGHT_BIT; + bstack[level+1]=b.children[0]; + stack[level+1]=TEST_RAY_BIT; + level++; + + } continue; + case VISIT_RIGHT_BIT: { + + stack[level]=VISIT_DONE_BIT; + bstack[level+1]=b.children[1]; + stack[level+1]=TEST_RAY_BIT; + level++; + } continue; + case VISIT_DONE_BIT: { + + if (level==0) { + done=true; + break; + } else + level--; + + } continue; + } + + + if (done) + break; + } + + + + if (intersected) { + + color.a=Math::lerp(MAX(0.01,lv[i].darkening),1.0,att); + } + + } + + break; + } else { + + Vector3 lpos = p_pos - octant.aabb.pos; + Vector3 half = octant.aabb.size * 0.5; + + int ofs=0; + + if (lpos.x >= half.x) + ofs|=1; + if (lpos.y >= half.y) + ofs|=2; + if (lpos.z >= half.z) + ofs|=4; + + octant_idx = octant.children[ofs]; + + if (octant_idx==0) + return; + + } + } + + ptr[0]=CLAMP(color.r*255.0,0,255); + ptr[1]=CLAMP(color.g*255.0,0,255); + ptr[2]=CLAMP(color.b*255.0,0,255); + ptr[3]=CLAMP(color.a*255.0,0,255); + +} + + +Error BakedLightBaker::transfer_to_lightmaps() { + + if (!triangles.size() || baked_textures.size()==0) + return ERR_UNCONFIGURED; + + EditorProgress ep("transfer_to_lightmaps",TTR("Transfer to Lightmaps:"),baked_textures.size()*2+triangles.size()); + + for(int i=0;i<baked_textures.size();i++) { + + ERR_FAIL_COND_V( baked_textures[i].width<=0 || baked_textures[i].height<=0,ERR_UNCONFIGURED ); + + baked_textures[i].data.resize( baked_textures[i].width*baked_textures[i].height*4 ); + zeromem(baked_textures[i].data.ptr(),baked_textures[i].data.size()); + ep.step(TTR("Allocating Texture #")+itos(i+1),i); + } + + Vector<double> norm_arr; + norm_arr.resize(lights.size()); + + for(int i=0;i<lights.size();i++) { + norm_arr[i] = 1.0/get_normalization(i); + } + float gamma = baked_light->get_gamma_adjust(); + float mult = baked_light->get_energy_multiplier(); + + for(int i=0;i<triangles.size();i++) { + + if (i%200==0) { + ep.step(TTR("Baking Triangle #")+itos(i),i+baked_textures.size()); + } + Triangle &t=triangles[i]; + if (t.baked_texture<0 || t.baked_texture>=baked_textures.size()) + continue; + + BakeTexture &bt=baked_textures[t.baked_texture]; + Vector3 normal = Plane(t.vertices[0],t.vertices[1],t.vertices[2]).normal; + + + int x[3]; + int y[3]; + + Vector3 vertices[3]={ + t.vertices[0], + t.vertices[1], + t.vertices[2] + }; + + for(int j=0;j<3;j++) { + + x[j]=t.bake_uvs[j].x*bt.width; + y[j]=t.bake_uvs[j].y*bt.height; + x[j]=CLAMP(x[j],0,bt.width-1); + y[j]=CLAMP(y[j],0,bt.height-1); + } + + + { + + // sort the points vertically + if (y[1] > y[2]) { + SWAP(x[1], x[2]); + SWAP(y[1], y[2]); + SWAP(vertices[1],vertices[2]); + } + if (y[0] > y[1]) { + SWAP(x[0], x[1]); + SWAP(y[0], y[1]); + SWAP(vertices[0],vertices[1]); + } + if (y[1] > y[2]) { + SWAP(x[1], x[2]); + SWAP(y[1], y[2]); + SWAP(vertices[1],vertices[2]); + } + + double dx_far = double(x[2] - x[0]) / (y[2] - y[0] + 1); + double dx_upper = double(x[1] - x[0]) / (y[1] - y[0] + 1); + double dx_low = double(x[2] - x[1]) / (y[2] - y[1] + 1); + double xf = x[0]; + double xt = x[0] + dx_upper; // if y[0] == y[1], special case + for (int yi = y[0]; yi <= (y[2] > bt.height-1 ? bt.height-1 : y[2]); yi++) + { + if (yi >= 0) { + for (int xi = (xf > 0 ? int(xf) : 0); xi <= (xt < bt.width ? xt : bt.width-1) ; xi++) { + //pixels[int(x + y * width)] = color; + + Vector2 v0 = Vector2(x[1]-x[0],y[1]-y[0]); + Vector2 v1 = Vector2(x[2]-x[0],y[2]-y[0]); + //vertices[2] - vertices[0]; + Vector2 v2 = Vector2(xi-x[0],yi-y[0]); + float d00 = v0.dot( v0); + float d01 = v0.dot( v1); + float d11 = v1.dot( v1); + float d20 = v2.dot( v0); + float d21 = v2.dot( v1); + float denom = (d00 * d11 - d01 * d01); + Vector3 pos; + if (denom==0) { + pos=t.vertices[0]; + } else { + float v = (d11 * d20 - d01 * d21) / denom; + float w = (d00 * d21 - d01 * d20) / denom; + float u = 1.0f - v - w; + pos = vertices[0]*u + vertices[1]*v + vertices[2]*w; + } + _plot_pixel_to_lightmap(xi,yi,bt.width,bt.height,bt.data.ptr(),pos,normal,norm_arr.ptr(),mult,gamma); + + } + + for (int xi = (xf < bt.width ? int(xf) : bt.width-1); xi >= (xt > 0 ? xt : 0); xi--) { + //pixels[int(x + y * width)] = color; + Vector2 v0 = Vector2(x[1]-x[0],y[1]-y[0]); + Vector2 v1 = Vector2(x[2]-x[0],y[2]-y[0]); + //vertices[2] - vertices[0]; + Vector2 v2 = Vector2(xi-x[0],yi-y[0]); + float d00 = v0.dot( v0); + float d01 = v0.dot( v1); + float d11 = v1.dot( v1); + float d20 = v2.dot( v0); + float d21 = v2.dot( v1); + float denom = (d00 * d11 - d01 * d01); + Vector3 pos; + if (denom==0) { + pos=t.vertices[0]; + } else { + float v = (d11 * d20 - d01 * d21) / denom; + float w = (d00 * d21 - d01 * d20) / denom; + float u = 1.0f - v - w; + pos = vertices[0]*u + vertices[1]*v + vertices[2]*w; + } + + _plot_pixel_to_lightmap(xi,yi,bt.width,bt.height,bt.data.ptr(),pos,normal,norm_arr.ptr(),mult,gamma); + + } + } + xf += dx_far; + if (yi < y[1]) + xt += dx_upper; + else + xt += dx_low; + } + } + + } + + + for(int i=0;i<baked_textures.size();i++) { + + + { + + ep.step(TTR("Post-Processing Texture #")+itos(i),i+baked_textures.size()+triangles.size()); + + BakeTexture &bt=baked_textures[i]; + + Vector<uint8_t> copy_data=bt.data; + uint8_t *data=bt.data.ptr(); + const int max_radius=8; + const int shadow_radius=2; + const int max_dist=0x7FFFFFFF; + + for(int x=0;x<bt.width;x++) { + + for(int y=0;y<bt.height;y++) { + + + uint8_t a = copy_data[(y*bt.width+x)*4+3]; + + if (a>0) { + //blur shadow + + int from_x = MAX(0,x-shadow_radius); + int to_x = MIN(bt.width-1,x+shadow_radius); + int from_y = MAX(0,y-shadow_radius); + int to_y = MIN(bt.height-1,y+shadow_radius); + + int sum=0; + int sumc=0; + + for(int k=from_y;k<=to_y;k++) { + for(int l=from_x;l<=to_x;l++) { + + const uint8_t * rp = ©_data[(k*bt.width+l)<<2]; + + sum+=rp[3]; + sumc++; + } + } + + sum/=sumc; + data[(y*bt.width+x)*4+3]=sum; + + } else { + + int closest_dist=max_dist; + uint8_t closest_color[4]; + + int from_x = MAX(0,x-max_radius); + int to_x = MIN(bt.width-1,x+max_radius); + int from_y = MAX(0,y-max_radius); + int to_y = MIN(bt.height-1,y+max_radius); + + for(int k=from_y;k<=to_y;k++) { + for(int l=from_x;l<=to_x;l++) { + + int dy = y-k; + int dx = x-l; + int dist = dy*dy+dx*dx; + if (dist>=closest_dist) + continue; + + const uint8_t * rp = ©_data[(k*bt.width+l)<<2]; + + if (rp[3]==0) + continue; + + closest_dist=dist; + closest_color[0]=rp[0]; + closest_color[1]=rp[1]; + closest_color[2]=rp[2]; + closest_color[3]=rp[3]; + } + } + + + if (closest_dist!=max_dist) { + + data[(y*bt.width+x)*4+0]=closest_color[0]; + data[(y*bt.width+x)*4+1]=closest_color[1]; + data[(y*bt.width+x)*4+2]=closest_color[2]; + data[(y*bt.width+x)*4+3]=closest_color[3]; + } + } + } + } + } + + PoolVector<uint8_t> dv; + dv.resize(baked_textures[i].data.size()); + { + PoolVector<uint8_t>::Write w = dv.write(); + copymem(w.ptr(),baked_textures[i].data.ptr(),baked_textures[i].data.size()); + } + + Image img(baked_textures[i].width,baked_textures[i].height,0,Image::FORMAT_RGBA8,dv); + Ref<ImageTexture> tex = memnew( ImageTexture ); + tex->create_from_image(img); + baked_light->set_lightmap_texture(i,tex); + } + + + return OK; +} + +void BakedLightBaker::clear() { + + + + _stop_thread(); + + if (bvh) + _free_bvh(bvh); + + if (ray_stack) + memdelete_arr(ray_stack); + if (octant_stack) + memdelete_arr(octant_stack); + if (octantptr_stack) + memdelete_arr(octantptr_stack); + if (bvh_stack) + memdelete_arr(bvh_stack); +/* + * ??? + for(int i=0;i<octant_pool.size();i++) { + /* + if (octant_pool[i].leaf) { + memdelete_arr( octant_pool[i].light ); + } + Vector<double> norm_arr; + norm_arr.resize(lights.size()); + */ + + for(int i=0;i<lights.size();i++) { + norm_arr[i] = 1.0/get_normalization(i); + } + + const double *normptr=norm_arr.ptr(); + } +*/ + octant_pool.clear(); + octant_pool_size=0; + bvh=NULL; + leaf_list=0; + cell_count=0; + ray_stack=NULL; + octant_stack=NULL; + octantptr_stack=NULL; + bvh_stack=NULL; + materials.clear(); + materials.clear(); + textures.clear(); + lights.clear(); + triangles.clear(); + endpoint_normal.clear(); + endpoint_normal_bits.clear(); + baked_octree_texture_w=0; + baked_octree_texture_h=0; + paused=false; + baking=false; + + bake_thread_exit=false; + first_bake_to_map=true; + baked_light=Ref<BakedLight>(); + total_rays=0; + +} + +BakedLightBaker::BakedLightBaker() { + octree_depth=9; + lattice_size=4; + octant_pool.clear(); + octant_pool_size=0; + bvh=NULL; + leaf_list=0; + cell_count=0; + ray_stack=NULL; + bvh_stack=NULL; + octant_stack=NULL; + octantptr_stack=NULL; + plot_size=2.5; + max_bounces=2; + materials.clear(); + baked_octree_texture_w=0; + baked_octree_texture_h=0; + paused=false; + baking=false; + + bake_thread_exit=false; + total_rays=0; + first_bake_to_map=true; + linear_color=false; + +} + +BakedLightBaker::~BakedLightBaker() { + + clear(); +} +#endif diff --git a/tools/editor/plugins/baked_light_baker.h b/editor/plugins/baked_light_baker.h index 89788338d9..89788338d9 100644 --- a/tools/editor/plugins/baked_light_baker.h +++ b/editor/plugins/baked_light_baker.h diff --git a/tools/editor/plugins/baked_light_baker_cmpxchg.cpp b/editor/plugins/baked_light_baker_cmpxchg.cpp index 5e9228b7de..5e9228b7de 100644 --- a/tools/editor/plugins/baked_light_baker_cmpxchg.cpp +++ b/editor/plugins/baked_light_baker_cmpxchg.cpp diff --git a/tools/editor/plugins/baked_light_editor_plugin.cpp b/editor/plugins/baked_light_editor_plugin.cpp index 6a7e708b85..6a7e708b85 100644 --- a/tools/editor/plugins/baked_light_editor_plugin.cpp +++ b/editor/plugins/baked_light_editor_plugin.cpp diff --git a/editor/plugins/baked_light_editor_plugin.h b/editor/plugins/baked_light_editor_plugin.h new file mode 100644 index 0000000000..a71de12bcc --- /dev/null +++ b/editor/plugins/baked_light_editor_plugin.h @@ -0,0 +1,120 @@ +/*************************************************************************/ +/* baked_light_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef BAKED_LIGHT_EDITOR_PLUGIN_H +#define BAKED_LIGHT_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "editor/plugins/baked_light_baker.h" +#include "scene/gui/spin_box.h" + + + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +#if 0 + +class MeshInstance; + +class BakedLightEditor : public Control { + + GDCLASS(BakedLightEditor, Control ); + + + float update_timeout; + PoolVector<uint8_t> octree_texture; + PoolVector<uint8_t> light_texture; + PoolVector<int> octree_sampler; + + BakedLightBaker *baker; + AcceptDialog *err_dialog; + + HBoxContainer *bake_hbox; + Button *button_bake; + Button *button_reset; + Button *button_make_lightmaps; + Label *bake_info; + + uint64_t last_rays_time; + + + + BakedLightInstance *node; + + enum Menu { + + MENU_OPTION_BAKE, + MENU_OPTION_CLEAR + }; + + void _bake_lightmaps(); + + void _bake_pressed(); + void _clear_pressed(); + + void _end_baking(); + void _menu_option(int); + +friend class BakedLightEditorPlugin; +protected: + void _node_removed(Node *p_node); + static void _bind_methods(); + void _notification(int p_what); +public: + + void edit(BakedLightInstance *p_baked_light); + BakedLightEditor(); + ~BakedLightEditor(); +}; + +class BakedLightEditorPlugin : public EditorPlugin { + + GDCLASS( BakedLightEditorPlugin, EditorPlugin ); + + BakedLightEditor *baked_light_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "BakedLight"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + BakedLightEditorPlugin(EditorNode *p_node); + ~BakedLightEditorPlugin(); + +}; + +#endif // MULTIMESH_EDITOR_PLUGIN_H +#endif + diff --git a/tools/editor/plugins/camera_editor_plugin.cpp b/editor/plugins/camera_editor_plugin.cpp index 7073acd2c0..7073acd2c0 100644 --- a/tools/editor/plugins/camera_editor_plugin.cpp +++ b/editor/plugins/camera_editor_plugin.cpp diff --git a/editor/plugins/camera_editor_plugin.h b/editor/plugins/camera_editor_plugin.h new file mode 100644 index 0000000000..b5817b9960 --- /dev/null +++ b/editor/plugins/camera_editor_plugin.h @@ -0,0 +1,79 @@ +/*************************************************************************/ +/* camera_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef CAMERA_EDITOR_PLUGIN_H +#define CAMERA_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/3d/camera.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +class CameraEditor : public Control { + + GDCLASS(CameraEditor, Control ); + + Panel *panel; + Button * preview; + Node *node; + + void _pressed(); +protected: + void _notification(int p_what); + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + void edit(Node *p_camera); + CameraEditor(); +}; + +class CameraEditorPlugin : public EditorPlugin { + + GDCLASS( CameraEditorPlugin, EditorPlugin ); + + //CameraEditor *camera_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "Camera"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + CameraEditorPlugin(EditorNode *p_node); + ~CameraEditorPlugin(); + +}; + +#endif // CAMERA_EDITOR_PLUGIN_H diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp new file mode 100644 index 0000000000..1a0791d864 --- /dev/null +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -0,0 +1,4063 @@ +/*************************************************************************/ +/* canvas_item_editor_plugin.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 "canvas_item_editor_plugin.h" + +#include "print_string.h" +#include "editor/editor_node.h" +#include "os/keyboard.h" +#include "scene/main/viewport.h" +#include "scene/main/canvas_layer.h" +#include "scene/2d/sprite.h" +#include "scene/2d/light_2d.h" +#include "scene/2d/particles_2d.h" +#include "scene/2d/polygon_2d.h" +#include "scene/2d/screen_button.h" +#include "global_config.h" +#include "os/input.h" +#include "editor/editor_settings.h" +#include "scene/gui/grid_container.h" +#include "scene/gui/patch_9_rect.h" +#include "editor/animation_editor.h" +#include "editor/plugins/animation_player_editor_plugin.h" +#include "editor/script_editor_debugger.h" +#include "editor/plugins/script_editor_plugin.h" +#include "scene/resources/packed_scene.h" + + +#define MIN_ZOOM 0.01 +#define MAX_ZOOM 100 + + +class SnapDialog : public ConfirmationDialog { + + GDCLASS(SnapDialog,ConfirmationDialog); + +friend class CanvasItemEditor; + + SpinBox *grid_offset_x; + SpinBox *grid_offset_y; + SpinBox *grid_step_x; + SpinBox *grid_step_y; + SpinBox *rotation_offset; + SpinBox *rotation_step; + +public: + SnapDialog() : ConfirmationDialog() { + const int SPIN_BOX_GRID_RANGE = 256; + const int SPIN_BOX_ROTATION_RANGE = 360; + Label *label; + VBoxContainer *container; + GridContainer *child_container; + + set_title(TTR("Configure Snap")); + get_ok()->set_text(TTR("Close")); + + container = memnew( VBoxContainer ); + add_child(container); + //set_child_rect(container); + + child_container = memnew( GridContainer ); + child_container->set_columns(3); + container->add_child(child_container); + + label = memnew( Label ); + label->set_text(TTR("Grid Offset:")); + child_container->add_child(label); + label->set_h_size_flags(SIZE_EXPAND_FILL); + + grid_offset_x = memnew( SpinBox ); + grid_offset_x->set_min(-SPIN_BOX_GRID_RANGE); + grid_offset_x->set_max(SPIN_BOX_GRID_RANGE); + grid_offset_x->set_suffix("px"); + child_container->add_child(grid_offset_x); + + grid_offset_y = memnew( SpinBox ); + grid_offset_y->set_min(-SPIN_BOX_GRID_RANGE); + grid_offset_y->set_max(SPIN_BOX_GRID_RANGE); + grid_offset_y->set_suffix("px"); + child_container->add_child(grid_offset_y); + + label = memnew( Label ); + label->set_text(TTR("Grid Step:")); + child_container->add_child(label); + label->set_h_size_flags(SIZE_EXPAND_FILL); + + grid_step_x = memnew( SpinBox ); + grid_step_x->set_min(-SPIN_BOX_GRID_RANGE); + grid_step_x->set_max(SPIN_BOX_GRID_RANGE); + grid_step_x->set_suffix("px"); + child_container->add_child(grid_step_x); + + grid_step_y = memnew( SpinBox ); + grid_step_y->set_min(-SPIN_BOX_GRID_RANGE); + grid_step_y->set_max(SPIN_BOX_GRID_RANGE); + grid_step_y->set_suffix("px"); + child_container->add_child(grid_step_y); + + container->add_child( memnew( HSeparator ) ); + + child_container = memnew( GridContainer ); + child_container->set_columns(2); + container->add_child(child_container); + + label = memnew( Label ); + label->set_text(TTR("Rotation Offset:")); + child_container->add_child(label); + label->set_h_size_flags(SIZE_EXPAND_FILL); + + rotation_offset = memnew( SpinBox ); + rotation_offset->set_min(-SPIN_BOX_ROTATION_RANGE); + rotation_offset->set_max(SPIN_BOX_ROTATION_RANGE); + rotation_offset->set_suffix("deg"); + child_container->add_child(rotation_offset); + + label = memnew( Label ); + label->set_text(TTR("Rotation Step:")); + child_container->add_child(label); + label->set_h_size_flags(SIZE_EXPAND_FILL); + + rotation_step = memnew( SpinBox ); + rotation_step->set_min(-SPIN_BOX_ROTATION_RANGE); + rotation_step->set_max(SPIN_BOX_ROTATION_RANGE); + rotation_step->set_suffix("deg"); + child_container->add_child(rotation_step); + } + + void set_fields(const Point2 p_grid_offset, const Size2 p_grid_step, const float p_rotation_offset, const float p_rotation_step) { + grid_offset_x->set_value(p_grid_offset.x); + grid_offset_y->set_value(p_grid_offset.y); + grid_step_x->set_value(p_grid_step.x); + grid_step_y->set_value(p_grid_step.y); + rotation_offset->set_value(p_rotation_offset * (180 / Math_PI)); + rotation_step->set_value(p_rotation_step * (180 / Math_PI)); + } + + void get_fields(Point2 &p_grid_offset, Size2 &p_grid_step, float &p_rotation_offset, float &p_rotation_step) { + p_grid_offset.x = grid_offset_x->get_value(); + p_grid_offset.y = grid_offset_y->get_value(); + p_grid_step.x = grid_step_x->get_value(); + p_grid_step.y = grid_step_y->get_value(); + p_rotation_offset = rotation_offset->get_value() / (180 / Math_PI); + p_rotation_step = rotation_step->get_value() / (180 / Math_PI); + } +}; + +void CanvasItemEditor::_edit_set_pivot(const Vector2& mouse_pos) { + List<Node*> &selection = editor_selection->get_selected_node_list(); + + undo_redo->create_action(TTR("Move Pivot")); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Node2D *n2d = E->get()->cast_to<Node2D>(); + + if (n2d && n2d->edit_has_pivot()) { + + Vector2 offset = n2d->edit_get_pivot(); + Vector2 gpos = n2d->get_global_position(); + + Vector2 local_mouse_pos = n2d->get_canvas_transform().affine_inverse().xform(mouse_pos); + + Vector2 motion_ofs = gpos-local_mouse_pos; + + undo_redo->add_do_method(n2d,"set_global_pos",local_mouse_pos); + undo_redo->add_do_method(n2d,"edit_set_pivot",offset+n2d->get_global_transform().affine_inverse().basis_xform(motion_ofs)); + undo_redo->add_undo_method(n2d,"set_global_pos",gpos); + undo_redo->add_undo_method(n2d,"edit_set_pivot",offset); + for(int i=0;i<n2d->get_child_count();i++) { + Node2D *n2dc = n2d->get_child(i)->cast_to<Node2D>(); + if (!n2dc) + continue; + + undo_redo->add_do_method(n2dc,"set_global_pos",n2dc->get_global_position()); + undo_redo->add_undo_method(n2dc,"set_global_pos",n2dc->get_global_position()); + + } + + } + + } + + undo_redo->commit_action(); + +} + +void CanvasItemEditor::_unhandled_key_input(const InputEvent& p_ev) { + + if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack()) + return; + + if (p_ev.key.mod.control) + return; + + if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_V && drag==DRAG_NONE && can_move_pivot) { + + if (p_ev.key.mod.shift) { + //move drag pivot + drag=DRAG_PIVOT; + } else if (!Input::get_singleton()->is_mouse_button_pressed(0)) { + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + Vector2 mouse_pos = viewport->get_local_mouse_pos(); + if (selection.size() && viewport->get_rect().has_point(mouse_pos)) { + //just in case, make it work if over viewport + mouse_pos=transform.affine_inverse().xform(mouse_pos); + mouse_pos=snap_point(mouse_pos); + + _edit_set_pivot(mouse_pos); + } + + } + } + +} + +void CanvasItemEditor::_tool_select(int p_index) { + + + ToolButton *tb[TOOL_MAX]={select_button,list_select_button,move_button,rotate_button,pivot_button,pan_button}; + for(int i=0;i<TOOL_MAX;i++) { + + tb[i]->set_pressed(i==p_index); + } + + + viewport->update(); + tool=(Tool)p_index; + +} + +Object *CanvasItemEditor::_get_editor_data(Object *p_what) { + + CanvasItem *ci = p_what->cast_to<CanvasItem>(); + if (!ci) + return NULL; + + return memnew( CanvasItemEditorSelectedItem ); +} + +inline float _snap_scalar(float p_offset, float p_step, bool p_snap_relative, float p_target, float p_start) { + float offset = p_snap_relative ? p_start : p_offset; + return p_step != 0 ? Math::stepify(p_target - offset, p_step) + offset : p_target; +} + +Vector2 CanvasItemEditor::snap_point(Vector2 p_target, Vector2 p_start) const { + if (snap_grid) { + p_target.x = _snap_scalar(snap_offset.x, snap_step.x, snap_relative, p_target.x, p_start.x); + p_target.y = _snap_scalar(snap_offset.y, snap_step.y, snap_relative, p_target.y, p_start.y); + } + if (snap_pixel) + p_target = p_target.snapped(Size2(1, 1)); + + return p_target; +} + +float CanvasItemEditor::snap_angle(float p_target, float p_start) const { + return snap_rotation ? _snap_scalar(snap_rotation_offset, snap_rotation_step, snap_relative, p_target, p_start) : p_target; +} + +Dictionary CanvasItemEditor::get_state() const { + + Dictionary state; + state["zoom"]=zoom; + state["ofs"]=Point2(h_scroll->get_value(),v_scroll->get_value()); + //state["ofs"]=-transform.get_origin(); + state["snap_offset"]=snap_offset; + state["snap_step"]=snap_step; + state["snap_rotation_offset"]=snap_rotation_offset; + state["snap_rotation_step"]=snap_rotation_step; + state["snap_grid"]=snap_grid; + state["snap_show_grid"]=snap_show_grid; + state["snap_rotation"]=snap_rotation; + state["snap_relative"]=snap_relative; + state["snap_pixel"]=snap_pixel; + state["skeleton_show_bones"]=skeleton_show_bones; + return state; +} +void CanvasItemEditor::set_state(const Dictionary& p_state){ + + Dictionary state=p_state; + if (state.has("zoom")) { + zoom=p_state["zoom"]; + } + + if (state.has("ofs")) { + _update_scrollbars(); // i wonder how safe is calling this here.. + Point2 ofs=p_state["ofs"]; + h_scroll->set_value(ofs.x); + v_scroll->set_value(ofs.y); + } + + if (state.has("snap_step")) { + snap_step=state["snap_step"]; + } + + if (state.has("snap_offset")) { + snap_offset=state["snap_offset"]; + } + + if (state.has("snap_rotation_step")) { + snap_rotation_step=state["snap_rotation_step"]; + } + + if (state.has("snap_rotation_offset")) { + snap_rotation_offset=state["snap_rotation_offset"]; + } + + if (state.has("snap_grid")) { + snap_grid=state["snap_grid"]; + int idx = edit_menu->get_popup()->get_item_index(SNAP_USE); + edit_menu->get_popup()->set_item_checked(idx,snap_grid); + } + + if (state.has("snap_show_grid")) { + snap_show_grid=state["snap_show_grid"]; + int idx = edit_menu->get_popup()->get_item_index(SNAP_SHOW_GRID); + edit_menu->get_popup()->set_item_checked(idx,snap_show_grid); + } + + if (state.has("snap_rotation")) { + snap_rotation=state["snap_rotation"]; + int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_ROTATION); + edit_menu->get_popup()->set_item_checked(idx,snap_rotation); + } + + if (state.has("snap_relative")) { + snap_relative=state["snap_relative"]; + int idx = edit_menu->get_popup()->get_item_index(SNAP_RELATIVE); + edit_menu->get_popup()->set_item_checked(idx,snap_relative); + } + + if (state.has("snap_pixel")) { + snap_pixel=state["snap_pixel"]; + int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_PIXEL); + edit_menu->get_popup()->set_item_checked(idx,snap_pixel); + } + + if (state.has("skeleton_show_bones")) { + skeleton_show_bones=state["skeleton_show_bones"]; + int idx = skeleton_menu->get_item_index(SKELETON_SHOW_BONES); + skeleton_menu->set_item_checked(idx,skeleton_show_bones); + } +} + + +void CanvasItemEditor::_add_canvas_item(CanvasItem *p_canvas_item) { + + editor_selection->add_node(p_canvas_item); +#if 0 + if (canvas_items.has(p_canvas_item)) + return; + + canvas_items.insert(p_canvas_item,p_info); + p_canvas_item->connect("hide",this,"_visibility_changed",varray(p_canvas_item->get_instance_ID()),CONNECT_ONESHOT); +#endif +} + +void CanvasItemEditor::_remove_canvas_item(CanvasItem *p_canvas_item) { + + editor_selection->remove_node(p_canvas_item); +#if 0 + p_canvas_item->disconnect("hide",this,"_visibility_changed"); + canvas_items.erase(p_canvas_item); +#endif + +} +void CanvasItemEditor::_clear_canvas_items() { + + editor_selection->clear(); +#if 0 + while(canvas_items.size()) + _remove_canvas_item(canvas_items.front()->key()); +#endif +} + +void CanvasItemEditor::_visibility_changed(ObjectID p_canvas_item) { +#if 0 + Object *c = ObjectDB::get_instance(p_canvas_item); + if (!c) + return; + CanvasItem *ct = c->cast_to<CanvasItem>(); + if (!ct) + return; + canvas_items.erase(ct); + //_remove_canvas_item(ct); + update(); +#endif +} + + +void CanvasItemEditor::_node_removed(Node *p_node) { +#if 0 + CanvasItem *canvas_item = (CanvasItem*)p_node; //not a good cast, but safe + if (canvas_items.has(canvas_item)) + _remove_canvas_item(canvas_item); + + update(); +#endif +} + +void CanvasItemEditor::_keying_changed() { + + if (AnimationPlayerEditor::singleton->get_key_editor()->is_visible_in_tree()) + animation_hb->show(); + else + animation_hb->hide(); +} + +bool CanvasItemEditor::_is_part_of_subscene(CanvasItem *p_item) { + + Node* scene_node = get_tree()->get_edited_scene_root(); + Node* item_owner = p_item->get_owner(); + + return item_owner && item_owner!=scene_node && p_item!=scene_node && item_owner->get_filename()!=""; +} + +// slow but modern computers should have no problem +CanvasItem* CanvasItemEditor::_select_canvas_item_at_pos(const Point2& p_pos,Node* p_node,const Transform2D& p_parent_xform,const Transform2D& p_canvas_xform) { + + if (!p_node) + return NULL; + if (p_node->cast_to<Viewport>()) + return NULL; + + CanvasItem *c=p_node->cast_to<CanvasItem>(); + + + for (int i=p_node->get_child_count()-1;i>=0;i--) { + + CanvasItem *r=NULL; + + if (c && !c->is_set_as_toplevel()) + r=_select_canvas_item_at_pos(p_pos,p_node->get_child(i),p_parent_xform * c->get_transform(),p_canvas_xform); + else { + CanvasLayer *cl = p_node->cast_to<CanvasLayer>(); + r=_select_canvas_item_at_pos(p_pos,p_node->get_child(i),transform ,cl ? cl->get_transform() : p_canvas_xform); //use base transform + } + + if (r) + return r; + } + + if (c && c->is_visible_in_tree() && !c->has_meta("_edit_lock_") && !_is_part_of_subscene(c) && !c->cast_to<CanvasLayer>()) { + + Rect2 rect = c->get_item_rect(); + Point2 local_pos = (p_parent_xform * p_canvas_xform * c->get_transform()).affine_inverse().xform(p_pos); + + + if (rect.has_point(local_pos)) + return c; + + } + + return NULL; +} + +void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos,Node* p_node,const Transform2D& p_parent_xform,const Transform2D& p_canvas_xform, Vector<_SelectResult> &r_items) { + if (!p_node) + return; + if (p_node->cast_to<Viewport>()) + return; + + CanvasItem *c=p_node->cast_to<CanvasItem>(); + + for (int i=p_node->get_child_count()-1;i>=0;i--) { + + if (c && !c->is_set_as_toplevel()) + _find_canvas_items_at_pos(p_pos,p_node->get_child(i),p_parent_xform * c->get_transform(),p_canvas_xform, r_items); + else { + CanvasLayer *cl = p_node->cast_to<CanvasLayer>(); + _find_canvas_items_at_pos(p_pos,p_node->get_child(i),transform ,cl ? cl->get_transform() : p_canvas_xform, r_items); //use base transform + } + } + + + if (c && c->is_visible_in_tree() && !c->has_meta("_edit_lock_") && !c->cast_to<CanvasLayer>()) { + + Rect2 rect = c->get_item_rect(); + Point2 local_pos = (p_parent_xform * p_canvas_xform * c->get_transform()).affine_inverse().xform(p_pos); + + + if (rect.has_point(local_pos)) { + Node2D *node=c->cast_to<Node2D>(); + + _SelectResult res; + res.item=c; + res.z=node?node->get_z():0; + res.has_z=node; + r_items.push_back(res); + } + + } + + return; +} + +void CanvasItemEditor::_find_canvas_items_at_rect(const Rect2& p_rect,Node* p_node,const Transform2D& p_parent_xform,const Transform2D& p_canvas_xform,List<CanvasItem*> *r_items) { + + if (!p_node) + return; + if (p_node->cast_to<Viewport>()) + return; + + CanvasItem *c=p_node->cast_to<CanvasItem>(); + + + bool inherited=p_node!=get_tree()->get_edited_scene_root() && p_node->get_filename()!=""; + bool editable=false; + if (inherited){ + editable=EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node); + } + bool lock_children=p_node->has_meta("_edit_group_") && p_node->get_meta("_edit_group_"); + if (!lock_children && (!inherited || editable)) { + for (int i=p_node->get_child_count()-1;i>=0;i--) { + + if (c && !c->is_set_as_toplevel()) + _find_canvas_items_at_rect(p_rect,p_node->get_child(i),p_parent_xform * c->get_transform(),p_canvas_xform,r_items); + else { + CanvasLayer *cl = p_node->cast_to<CanvasLayer>(); + _find_canvas_items_at_rect(p_rect,p_node->get_child(i),transform,cl?cl->get_transform():p_canvas_xform,r_items); + } + } + } + + if (c && c->is_visible_in_tree() && !c->has_meta("_edit_lock_") && !c->cast_to<CanvasLayer>()) { + + Rect2 rect = c->get_item_rect(); + Transform2D xform = p_parent_xform * p_canvas_xform * c->get_transform(); + + if ( p_rect.has_point( xform.xform( rect.pos ) ) && + p_rect.has_point( xform.xform( rect.pos+Vector2(rect.size.x,0) ) ) && + p_rect.has_point( xform.xform( rect.pos+Vector2(rect.size.x,rect.size.y) ) ) && + p_rect.has_point( xform.xform( rect.pos+Vector2(0,rect.size.y) ) ) ) { + + r_items->push_back(c); + + } + } + + +} + +bool CanvasItemEditor::_select(CanvasItem *item, Point2 p_click_pos, bool p_append, bool p_drag) { + + if (p_append) { + //additive selection + + if (!item) { + + if (p_drag) { + drag_from=transform.affine_inverse().xform(p_click_pos); + + box_selecting=true; + box_selecting_to=drag_from; + } + + return false; //nothing to add + } + + if (editor_selection->is_selected(item)) { + //already in here, erase it + editor_selection->remove_node(item); + //_remove_canvas_item(c); + + viewport->update(); + return false; + + } + _append_canvas_item(item); + viewport->update(); + + return true; + + } else { + //regular selection + + if (!item) { + //clear because nothing clicked + editor_selection->clear(); + + if (p_drag) { + drag_from=transform.affine_inverse().xform(p_click_pos); + + box_selecting=true; + box_selecting_to=drag_from; + } + + viewport->update(); + return false; + } + + if (!editor_selection->is_selected(item)) { + //select a new one and clear previous selection + editor_selection->clear(); + editor_selection->add_node(item); + //reselect + if (get_tree()->is_editor_hint()) { + editor->call("edit_node",item); + } + + } + + if (p_drag) { + //prepare to move! + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + if (!se) + continue; + + se->undo_state=canvas_item->edit_get_state(); + if (canvas_item->cast_to<Node2D>()) + se->undo_pivot=canvas_item->cast_to<Node2D>()->edit_get_pivot(); + + } + + drag=DRAG_ALL; + drag_from=transform.affine_inverse().xform(p_click_pos); + drag_point_from=_find_topleftmost_point(); + } + + viewport->update(); + + return true; + + } +} + +void CanvasItemEditor::_key_move(const Vector2& p_dir, bool p_snap, KeyMoveMODE p_move_mode) { + + + if (drag!=DRAG_NONE) + return; + + if (editor_selection->get_selected_node_list().empty()) + return; + + undo_redo->create_action(TTR("Move Action"),UndoRedo::MERGE_ENDS); + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + if (!se) + continue; + + if (canvas_item->has_meta("_edit_lock_")) + continue; + + + Vector2 drag = p_dir; + if (p_snap) + drag*=snap_step; + + undo_redo->add_undo_method(canvas_item,"edit_set_state",canvas_item->edit_get_state()); + + if (p_move_mode == MOVE_VIEW_BASE) { + + // drag = transform.affine_inverse().basis_xform(p_dir); // zoom sensitive + drag = canvas_item->get_global_transform_with_canvas().affine_inverse().basis_xform(drag); + Rect2 local_rect = canvas_item->get_item_rect(); + local_rect.pos+=drag; + undo_redo->add_do_method(canvas_item,"edit_set_rect",local_rect); + + } else { // p_move_mode==MOVE_LOCAL_BASE || p_move_mode==MOVE_LOCAL_WITH_ROT + + if (Node2D *node_2d = canvas_item->cast_to<Node2D>()) { + + if (p_move_mode == MOVE_LOCAL_WITH_ROT) { + Transform2D m; + m.rotate( node_2d->get_rotation() ); + drag = m.xform(drag); + } + node_2d->set_position(node_2d->get_position() + drag); + + } else if (Control *control = canvas_item->cast_to<Control>()) { + + control->set_pos(control->get_pos()+drag); + } + } + } + + undo_redo->commit_action(); +} + +Point2 CanvasItemEditor::_find_topleftmost_point() { + + + + Vector2 tl=Point2(1e10,1e10); + Rect2 r2; + r2.pos=tl; + + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + + + + Rect2 rect=canvas_item->get_item_rect(); + Transform2D xform=canvas_item->get_global_transform_with_canvas(); + + r2.expand_to(xform.xform(rect.pos)); + r2.expand_to(xform.xform(rect.pos+Vector2(rect.size.x,0))); + r2.expand_to(xform.xform(rect.pos+rect.size)); + r2.expand_to(xform.xform(rect.pos+Vector2(0,rect.size.y))); + + } + + return r2.pos; +} + + + +int CanvasItemEditor::get_item_count() { + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + int ic=0; + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + ic++; + }; + + return ic; +} + +CanvasItem *CanvasItemEditor::get_single_item() { + + + Map<Node*,Object*> &selection = editor_selection->get_selection(); + + CanvasItem *single_item=NULL; + + for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->key()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + if (single_item) + return NULL; //morethan one + + single_item=canvas_item; + }; + + return single_item; +} + +CanvasItemEditor::DragType CanvasItemEditor::_find_drag_type(const Transform2D& p_xform, const Rect2& p_local_rect, const Point2& p_click, Vector2& r_point) { + + CanvasItem *canvas_item = get_single_item(); + + ERR_FAIL_COND_V(!canvas_item,DRAG_NONE); + + Rect2 rect=canvas_item->get_item_rect(); + Transform2D xforml=canvas_item->get_global_transform_with_canvas(); + Transform2D xform=transform * xforml; + + Vector2 endpoints[4]={ + + xform.xform(rect.pos), + xform.xform(rect.pos+Vector2(rect.size.x,0)), + xform.xform(rect.pos+rect.size), + xform.xform(rect.pos+Vector2(0,rect.size.y)) + }; + + Vector2 endpointsl[4]={ + + xforml.xform(rect.pos), + xforml.xform(rect.pos+Vector2(rect.size.x,0)), + xforml.xform(rect.pos+rect.size), + xforml.xform(rect.pos+Vector2(0,rect.size.y)) + }; + + DragType dragger[]={ + DRAG_TOP_LEFT, + DRAG_TOP, + DRAG_TOP_RIGHT, + DRAG_RIGHT, + DRAG_BOTTOM_RIGHT, + DRAG_BOTTOM, + DRAG_BOTTOM_LEFT, + DRAG_LEFT + }; + + float radius = (select_handle->get_size().width/2)*1.5; + + //try draggers + + for(int i=0;i<4;i++) { + + int prev = (i+3)%4; + int next = (i+1)%4; + + r_point=endpointsl[i]; + + Vector2 ofs = ((endpoints[i] - endpoints[prev]).normalized() + ((endpoints[i] - endpoints[next]).normalized())).normalized(); + ofs*=1.4144*(select_handle->get_size().width/2); + + ofs+=endpoints[i]; + + if (ofs.distance_to(p_click)<radius) + return dragger[i*2]; + + ofs = (endpoints[i]+endpoints[next])/2; + ofs += (endpoints[next]-endpoints[i]).tangent().normalized()*(select_handle->get_size().width/2); + + r_point=(endpointsl[i]+endpointsl[next])/2; + + + if (ofs.distance_to(p_click)<radius) + return dragger[i*2+1]; + + } + + /* + if (rect.has_point(xform.affine_inverse().xform(p_click))) { + r_point=_find_topleftmost_point(); + return DRAG_ALL; + }*/ + + //try draggers + + return DRAG_NONE; +} + +void CanvasItemEditor::incbeg(float& beg,float &end, float inc, float minsize,bool p_symmetric) { + + if (minsize<0) { + + beg+=inc; + if (p_symmetric) + end-=inc; + } else { + + if (p_symmetric) { + beg+=inc; + end-=inc; + if (end-beg < minsize) { + float center = (beg+end)/2.0; + beg=center-minsize/2.0; + end=center+minsize/2.0; + } + + } else { + if (end-(beg+inc) < minsize) + beg=end-minsize; + else + beg+=inc; + } + + } +} + +void CanvasItemEditor::incend(float &beg,float& end, float inc, float minsize,bool p_symmetric) { + + if (minsize<0) { + + end+=inc; + if (p_symmetric) + beg-=inc; + } else { + + if (p_symmetric) { + + end+=inc; + beg-=inc; + if (end-beg < minsize) { + float center = (beg+end)/2.0; + beg=center-minsize/2.0; + end=center+minsize/2.0; + } + + } else { + if ((end+inc)-beg < minsize) + end=beg+minsize; + else + end+=inc; + } + + } +} + +void CanvasItemEditor::_append_canvas_item(CanvasItem *c) { + + editor_selection->add_node(c); + +} + + +void CanvasItemEditor::_snap_changed() { + ((SnapDialog *)snap_dialog)->get_fields(snap_offset, snap_step, snap_rotation_offset, snap_rotation_step); + viewport->update(); +} + +void CanvasItemEditor::_dialog_value_changed(double) { + + if (updating_value_dialog) + return; + + switch(last_option) { + + case ZOOM_SET: { + + zoom=dialog_val->get_value()/100.0; + _update_scroll(0); + viewport->update(); + + } break; + default:{} + } +} + +void CanvasItemEditor::_selection_result_pressed(int p_result) { + + if (selection_results.size() <= p_result) + return; + + CanvasItem *item=selection_results[p_result].item; + + if (item) + _select(item, Point2(), additive_selection, false); +} + +void CanvasItemEditor::_selection_menu_hide() { + + selection_results.clear(); + selection_menu->clear(); + selection_menu->set_size(Vector2(0, 0)); +} + +bool CanvasItemEditor::get_remove_list(List<Node*> *p_list) { + + + return false;//!p_list->empty(); +} + + +void CanvasItemEditor::_list_select(const InputEventMouseButton& b) { + + Point2 click=Point2(b.x,b.y); + + Node* scene = editor->get_edited_scene(); + if (!scene) + return; + + _find_canvas_items_at_pos(click, scene,transform,Transform2D(), selection_results); + + for(int i=0;i<selection_results.size();i++) { + CanvasItem *item=selection_results[i].item; + if (item!=scene && item->get_owner()!=scene && !scene->is_editable_instance(item->get_owner())) { + //invalid result + selection_results.remove(i); + i--; + } + + } + + if (selection_results.size() == 1) { + + CanvasItem *item = selection_results[0].item; + selection_results.clear(); + + additive_selection=b.mod.shift; + if (!_select(item, click, additive_selection, false)) + return; + + } else if (!selection_results.empty()) { + + selection_results.sort(); + + NodePath root_path = get_tree()->get_edited_scene_root()->get_path(); + StringName root_name = root_path.get_name(root_path.get_name_count()-1); + + for (int i = 0; i < selection_results.size(); i++) { + + CanvasItem *item=selection_results[i].item; + + + Ref<Texture> icon; + if (item->has_meta("_editor_icon")) + icon=item->get_meta("_editor_icon"); + else + icon=get_icon( has_icon(item->get_class(),"EditorIcons")?item->get_class():String("Object"),"EditorIcons"); + + String node_path="/"+root_name+"/"+root_path.rel_path_to(item->get_path()); + + selection_menu->add_item(item->get_name()); + selection_menu->set_item_icon(i, icon ); + selection_menu->set_item_metadata(i, node_path); + selection_menu->set_item_tooltip(i,String(item->get_name())+ + "\nType: "+item->get_class()+"\nPath: "+node_path); + } + + additive_selection=b.mod.shift; + + selection_menu->set_global_pos(Vector2( b.global_x, b.global_y )); + selection_menu->popup(); + selection_menu->call_deferred("grab_click_focus"); + selection_menu->set_invalidate_click_until_motion(); + + + return; + } + +} + +void CanvasItemEditor::_viewport_gui_input(const InputEvent& p_event) { + + { + + EditorNode *en = editor; + EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); + + if (!over_plugin_list->empty()) { + bool discard = over_plugin_list->forward_gui_input(transform,p_event); + if (discard) { + accept_event(); + return; + } + } + } + + + if (p_event.type==InputEvent::MOUSE_BUTTON) { + + const InputEventMouseButton &b=p_event.mouse_button; + + + if (b.button_index==BUTTON_WHEEL_DOWN) { + + if (zoom<MIN_ZOOM) + return; + + float prev_zoom=zoom; + zoom=zoom*0.95; + { + Point2 ofs(b.x,b.y); + ofs = ofs/prev_zoom - ofs/zoom; + h_scroll->set_value( h_scroll->get_value() + ofs.x ); + v_scroll->set_value( v_scroll->get_value() + ofs.y ); + } + _update_scroll(0); + viewport->update(); + return; + } + + if (b.button_index==BUTTON_WHEEL_UP) { + + if (zoom>MAX_ZOOM) + return; + + float prev_zoom=zoom; + zoom=zoom*(1.0/0.95); + { + Point2 ofs(b.x,b.y); + ofs = ofs/prev_zoom - ofs/zoom; + h_scroll->set_value( h_scroll->get_value() + ofs.x ); + v_scroll->set_value( v_scroll->get_value() + ofs.y ); + } + + _update_scroll(0); + viewport->update(); + return; + } + + if (b.button_index==BUTTON_RIGHT) { + + + if (b.pressed && (tool==TOOL_SELECT && b.mod.alt)) { + + _list_select(b); + return; + } + + if (get_item_count() > 0 && drag!=DRAG_NONE) { + //cancel drag + + if (bone_ik_list.size()) { + + for(List<BoneIK>::Element *E=bone_ik_list.back();E;E=E->prev()) { + + E->get().node->edit_set_state(E->get().orig_state); + } + + bone_ik_list.clear(); + + } else { + + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + + CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + if (!se) + continue; + + canvas_item->edit_set_state(se->undo_state); + if (canvas_item->cast_to<Node2D>()) + canvas_item->cast_to<Node2D>()->edit_set_pivot(se->undo_pivot); + + } + } + + drag=DRAG_NONE; + viewport->update(); + can_move_pivot=false; + + } else if (box_selecting) { + box_selecting=false; + viewport->update(); + } else if (b.pressed) { +#if 0 + ref_item = NULL; + Node* scene = get_scene()->get_root_node()->cast_to<EditorNode>()->get_edited_scene(); + if ( scene ) ref_item =_select_canvas_item_at_pos( Point2( b.x, b.y ), scene, transform ); +#endif + //popup->set_pos(Point2(b.x,b.y)); + //popup->popup(); + } + return; + } + /* + if (!canvas_items.size()) + return; + */ + + if (b.button_index==BUTTON_LEFT && tool==TOOL_LIST_SELECT) { + if (b.pressed) + _list_select(b); + return; + } + + + if (b.button_index==BUTTON_LEFT && tool==TOOL_EDIT_PIVOT) { + if (b.pressed) { + + Point2 mouse_pos(b.x,b.y); + mouse_pos=transform.affine_inverse().xform(mouse_pos); + mouse_pos=snap_point(mouse_pos); + _edit_set_pivot(mouse_pos); + } + return; + } + + + + if (tool==TOOL_PAN || b.button_index!=BUTTON_LEFT || Input::get_singleton()->is_key_pressed(KEY_SPACE)) + return; + + if (!b.pressed) { + + if (drag!=DRAG_NONE) { + + if (undo_redo) { + + + if (bone_ik_list.size()) { + + + undo_redo->create_action(TTR("Edit IK Chain")); + + for(List<BoneIK>::Element *E=bone_ik_list.back();E;E=E->prev()) { + + undo_redo->add_do_method(E->get().node,"edit_set_state",E->get().node->edit_get_state()); + undo_redo->add_undo_method(E->get().node,"edit_set_state",E->get().orig_state); + } + + undo_redo->add_do_method(viewport,"update"); + undo_redo->add_undo_method(viewport,"update"); + + bone_ik_list.clear(); + + undo_redo->commit_action(); + } else { + + undo_redo->create_action(TTR("Edit CanvasItem")); + + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + if (!se) + continue; + + Variant state=canvas_item->edit_get_state(); + undo_redo->add_do_method(canvas_item,"edit_set_state",state); + undo_redo->add_undo_method(canvas_item,"edit_set_state",se->undo_state); + if (canvas_item->cast_to<Node2D>()) { + Node2D *pvt = canvas_item->cast_to<Node2D>(); + if (pvt->edit_has_pivot()) { + undo_redo->add_do_method(canvas_item,"edit_set_pivot",pvt->edit_get_pivot()); + undo_redo->add_undo_method(canvas_item,"edit_set_pivot",se->undo_pivot); + } + } + } + undo_redo->commit_action(); + } + } + + drag=DRAG_NONE; + viewport->update(); + can_move_pivot=false; + + } + + if (box_selecting) { +#if 0 + if ( ! b.mod.shift ) _clear_canvas_items(); + if ( box_selection_end() ) return; +#endif + + Node* scene = editor->get_edited_scene(); + if (scene) { + + List<CanvasItem*> selitems; + + Point2 bsfrom = transform.xform(drag_from); + Point2 bsto= transform.xform(box_selecting_to); + if (bsfrom.x>bsto.x) + SWAP(bsfrom.x,bsto.x); + if (bsfrom.y>bsto.y) + SWAP(bsfrom.y,bsto.y); + + _find_canvas_items_at_rect(Rect2(bsfrom,bsto-bsfrom),scene,transform,Transform2D(),&selitems); + + for(List<CanvasItem*>::Element *E=selitems.front();E;E=E->next()) { + + _append_canvas_item(E->get()); + } + + } + + box_selecting=false; + viewport->update(); + + } + return; + } + + + Map<ObjectID,BoneList>::Element *Cbone=NULL; //closest + + { + bone_ik_list.clear(); + float closest_dist=1e20; + int bone_width = EditorSettings::get_singleton()->get("editors/2d/bone_width"); + for(Map<ObjectID,BoneList>::Element *E=bone_list.front();E;E=E->next()) { + + if (E->get().from == E->get().to) + continue; + Vector2 s[2]={ + E->get().from, + E->get().to + }; + + Vector2 p = Geometry::get_closest_point_to_segment_2d(Vector2(b.x,b.y),s); + float d = p.distance_to(Vector2(b.x,b.y)); + if (d<bone_width && d<closest_dist) { + Cbone=E; + closest_dist=d; + } + } + + if (Cbone) { + Node2D *b=NULL; + Object* obj=ObjectDB::get_instance(Cbone->get().bone); + if (obj) + b=obj->cast_to<Node2D>(); + + if (b) { + + + bool ik_found=false; + bool first=true; + + + + while(b) { + + CanvasItem *pi=b->get_parent_item(); + if (!pi) + break; + + float len=pi->get_global_transform().get_origin().distance_to(b->get_global_position()); + b=pi->cast_to<Node2D>(); + if (!b) + break; + + if (first) { + + bone_orig_xform=b->get_global_transform(); + first=false; + } + + BoneIK bik; + bik.node=b; + bik.len=len; + bik.orig_state=b->edit_get_state(); + + bone_ik_list.push_back(bik); + + if (b->has_meta("_edit_ik_")) { + + ik_found=bone_ik_list.size()>1; + break; + } + + if (!pi->has_meta("_edit_bone_")) + break; + + } + + if (!ik_found) + bone_ik_list.clear(); + + } + } + } + + CanvasItem *single_item = get_single_item(); + + if (single_item) { + //try single canvas_item edit + + CanvasItem *canvas_item = single_item; + CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + ERR_FAIL_COND(!se); + + + Point2 click(b.x,b.y); + + if ((b.mod.control && tool==TOOL_SELECT) || tool==TOOL_ROTATE) { + + drag=DRAG_ROTATE; + drag_from=transform.affine_inverse().xform(click); + se->undo_state=canvas_item->edit_get_state(); + if (canvas_item->cast_to<Node2D>()) + se->undo_pivot=canvas_item->cast_to<Node2D>()->edit_get_pivot(); + if (canvas_item->cast_to<Control>()) + se->undo_pivot=Vector2(); + return; + } + + Transform2D xform = transform * canvas_item->get_global_transform_with_canvas(); + Rect2 rect=canvas_item->get_item_rect(); + //float handle_radius = handle_len * 1.4144; //magic number, guess what it means! + + if (tool==TOOL_SELECT) { + drag = _find_drag_type(xform,rect,click,drag_point_from); + + if (b.doubleclick) { + + if (canvas_item->get_filename()!="" && canvas_item!=editor->get_edited_scene()) { + + editor->open_request(canvas_item->get_filename()); + return; + } + } + + if (drag!=DRAG_NONE && (!Cbone || drag!=DRAG_ALL)) { + drag_from=transform.affine_inverse().xform(click); + se->undo_state=canvas_item->edit_get_state(); + if (canvas_item->cast_to<Node2D>()) + se->undo_pivot=canvas_item->cast_to<Node2D>()->edit_get_pivot(); + + return; + } + } else { + + drag=DRAG_NONE; + } + } + + //multi canvas_item edit + + + Point2 click=Point2(b.x,b.y); + + if ((b.mod.alt || tool==TOOL_MOVE) && get_item_count()) { + + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + if (!se) + continue; + + se->undo_state=canvas_item->edit_get_state(); + if (canvas_item->cast_to<Node2D>()) + se->undo_pivot=canvas_item->cast_to<Node2D>()->edit_get_pivot(); + + } + + + drag=DRAG_ALL; + drag_from=transform.affine_inverse().xform(click); + drag_point_from=_find_topleftmost_point(); + viewport->update(); + return; + + } + + Node* scene = editor->get_edited_scene(); + if (!scene) + return; + + /* + if (current_window) { + //no window.... ? + click-=current_window->get_scroll(); + }*/ + CanvasItem *c=NULL; + + if (Cbone) { + + Object* obj=ObjectDB::get_instance(Cbone->get().bone); + if (obj) + c=obj->cast_to<CanvasItem>(); + if (c) + c=c->get_parent_item(); + + + } + if (!c) { + c =_select_canvas_item_at_pos(click, scene,transform,Transform2D()); + + + CanvasItem* cn = c; + + while(cn) { + if (cn->has_meta("_edit_group_")) { + c=cn; + } + cn=cn->get_parent_item(); + } + } + + Node* n = c; + + while ((n && n != scene && n->get_owner() != scene) || (n && !n->is_class("CanvasItem"))) { + n = n->get_parent(); + }; + c = n->cast_to<CanvasItem>(); +#if 0 + if ( b.pressed ) box_selection_start( click ); +#endif + + additive_selection=b.mod.shift; + if (!_select(c, click, additive_selection)) + return; + + } + + if (p_event.type==InputEvent::MOUSE_MOTION) { + + if (!viewport->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) + viewport->call_deferred("grab_focus"); + + const InputEventMouseMotion &m=p_event.mouse_motion; + + if (box_selecting) { + + box_selecting_to=transform.affine_inverse().xform(Point2(m.x,m.y)); + viewport->update(); + return; + + } + + + if (drag==DRAG_NONE) { + + + if ( (m.button_mask&BUTTON_MASK_LEFT && tool == TOOL_PAN) || m.button_mask&BUTTON_MASK_MIDDLE || (m.button_mask&BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE))) { + h_scroll->set_value( h_scroll->get_value() - m.relative_x/zoom); + v_scroll->set_value( v_scroll->get_value() - m.relative_y/zoom); + } + + return; + + } + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + if (!se) + continue; + + bool dragging_bone = drag==DRAG_ALL && selection.size()==1 && bone_ik_list.size(); + + + if (!dragging_bone) { + canvas_item->edit_set_state(se->undo_state); //reset state and reapply + if (canvas_item->cast_to<Node2D>()) + canvas_item->cast_to<Node2D>()->edit_set_pivot(se->undo_pivot); + } + + + Vector2 dfrom = drag_from; + Vector2 dto = transform.affine_inverse().xform(Point2(m.x,m.y)); + if (canvas_item->has_meta("_edit_lock_")) + continue; + + + if (drag==DRAG_ROTATE) { + + Vector2 center = canvas_item->get_global_transform_with_canvas().get_origin(); + { + Node2D *node = canvas_item->cast_to<Node2D>(); + + + if (node) { + real_t angle = node->get_rotation(); + node->set_rotation(snap_angle( angle + (dfrom - center).angle_to(dto-center), angle )); + display_rotate_to = dto; + display_rotate_from = center; + viewport->update(); + } + } + + { + Control *node = canvas_item->cast_to<Control>(); + + + if (node) { + real_t angle = node->get_rotation(); + node->set_rotation(snap_angle( angle + (dfrom - center).angle_to(dto-center), angle )); + display_rotate_to = dto; + display_rotate_from = center; + viewport->update(); + } + } + + continue; + } + + + bool uniform = m.mod.shift; + bool symmetric=m.mod.alt; + + dto = dto - (drag == DRAG_ALL ? drag_from - drag_point_from : Vector2(0, 0)); + + if(uniform && drag == DRAG_ALL) { + if(ABS(dto.x - drag_point_from.x) > ABS(dto.y - drag_point_from.y)) { + dto.y = drag_point_from.y; + } else { + dto.x = drag_point_from.x; + } + } + + dfrom = drag_point_from; + dto = snap_point(dto, drag_point_from); + + Vector2 drag_vector = + canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dto) - + canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dfrom); + + Rect2 local_rect = canvas_item->get_item_rect(); + Vector2 begin=local_rect.pos; + Vector2 end=local_rect.pos+local_rect.size; + Vector2 minsize = canvas_item->edit_get_minimum_size(); + + if (uniform) { + float aspect = local_rect.size.aspect(); + switch(drag) { + case DRAG_BOTTOM_LEFT: + case DRAG_TOP_RIGHT: { + if (aspect > 1.0) { // width > height, take x as reference + drag_vector.y = -drag_vector.x/aspect; + } else { // height > width, take y as reference + drag_vector.x = -drag_vector.y*aspect; + } + } break; + case DRAG_BOTTOM_RIGHT: + case DRAG_TOP_LEFT: { + if (aspect > 1.0) { // width > height, take x as reference + drag_vector.y = drag_vector.x/aspect; + } else { // height > width, take y as reference + drag_vector.x = drag_vector.y*aspect; + } + } break; + default: {} + } + } + + switch(drag) { + case DRAG_ALL: { + begin+=drag_vector; + end+=drag_vector; + } break; + case DRAG_RIGHT: { + + incend(begin.x,end.x,drag_vector.x,minsize.x,symmetric); + + } break; + case DRAG_BOTTOM: { + + incend(begin.y,end.y,drag_vector.y,minsize.y,symmetric); + + } break; + case DRAG_BOTTOM_RIGHT: { + + incend(begin.x,end.x,drag_vector.x,minsize.x,symmetric); + incend(begin.y,end.y,drag_vector.y,minsize.y,symmetric); + } break; + case DRAG_TOP_LEFT: { + + incbeg(begin.x,end.x,drag_vector.x,minsize.x,symmetric); + incbeg(begin.y,end.y,drag_vector.y,minsize.y,symmetric); + } break; + case DRAG_TOP: { + + incbeg(begin.y,end.y,drag_vector.y,minsize.y,symmetric); + + } break; + case DRAG_LEFT: { + + incbeg(begin.x,end.x,drag_vector.x,minsize.x,symmetric); + + } break; + case DRAG_TOP_RIGHT: { + + incbeg(begin.y,end.y,drag_vector.y,minsize.y,symmetric); + incend(begin.x,end.x,drag_vector.x,minsize.x,symmetric); + + } break; + case DRAG_BOTTOM_LEFT: { + + incbeg(begin.x,end.x,drag_vector.x,minsize.x,symmetric); + incend(begin.y,end.y,drag_vector.y,minsize.y,symmetric); + } break; + case DRAG_PIVOT: { + + if (canvas_item->cast_to<Node2D>()) { + Node2D *n2d =canvas_item->cast_to<Node2D>(); + n2d->edit_set_pivot(se->undo_pivot+drag_vector); + + } + continue; + } break; + + default:{} + } + + + + if (!dragging_bone) { + + local_rect.pos=begin; + local_rect.size=end-begin; + canvas_item->edit_set_rect(local_rect); + + } else { + //ok, all that had to be done was done, now solve IK + + + + + Node2D *n2d = canvas_item->cast_to<Node2D>(); + Transform2D final_xform = bone_orig_xform; + + + + if (n2d) { + + float total_len = 0; + for (List<BoneIK>::Element *E=bone_ik_list.front();E;E=E->next()) { + if (E->prev()) + total_len+=E->get().len; + E->get().pos = E->get().node->get_global_transform().get_origin(); + } + + { + + final_xform.elements[2]+=dto-dfrom;//final_xform.affine_inverse().basis_xform_inv(drag_vector); + //n2d->set_global_transform(final_xform); + + } + + + CanvasItem *last = bone_ik_list.back()->get().node; + if (!last) + break; + + Vector2 root_pos = last->get_global_transform().get_origin(); + Vector2 leaf_pos = final_xform.get_origin(); + + if ((leaf_pos.distance_to(root_pos)) > total_len) { + //oops dude you went too far + //print_line("TOO FAR!"); + Vector2 rel = leaf_pos - root_pos; + rel = rel.normalized() * total_len; + leaf_pos=root_pos+rel; + + } + + bone_ik_list.front()->get().pos=leaf_pos; + + //print_line("BONE IK LIST "+itos(bone_ik_list.size())); + + + if (bone_ik_list.size()>2) { + int solver_iterations=64; + float solver_k=0.3; + + for(int i=0;i<solver_iterations;i++) { + + for (List<BoneIK>::Element *E=bone_ik_list.front();E;E=E->next()) { + + + + if (E==bone_ik_list.back()) { + + break; + } + + float len = E->next()->get().len; + + if (E->next()==bone_ik_list.back()) { + + //print_line("back"); + + Vector2 rel = E->get().pos - E->next()->get().pos; + //print_line("PREV "+E->get().pos); + Vector2 desired = E->next()->get().pos+rel.normalized()*len; + //print_line("DESIRED "+desired); + E->get().pos=E->get().pos.linear_interpolate(desired,solver_k); + //print_line("POST "+E->get().pos); + + + } else if (E==bone_ik_list.front()) { + //only adjust parent + //print_line("front"); + Vector2 rel = E->next()->get().pos - E->get().pos; + //print_line("PREV "+E->next()->get().pos); + Vector2 desired = E->get().pos+rel.normalized()*len; + //print_line("DESIRED "+desired); + E->next()->get().pos=E->next()->get().pos.linear_interpolate(desired,solver_k); + //print_line("POST "+E->next()->get().pos); + } else { + + Vector2 rel = E->next()->get().pos - E->get().pos; + Vector2 cen = (E->next()->get().pos + E->get().pos)*0.5; + rel=rel.linear_interpolate(rel.normalized()*len,solver_k); + rel*=0.5; + E->next()->get().pos=cen+rel; + E->get().pos=cen-rel; + //print_line("mid"); + + } + } + } + } + } + + for (List<BoneIK>::Element *E=bone_ik_list.back();E;E=E->prev()) { + + Node2D *n = E->get().node; + + if (!E->prev()) { + //last goes to what it was + final_xform.set_origin(n->get_global_position()); + n->set_global_transform(final_xform); + + } else { + Vector2 rel = (E->prev()->get().node->get_global_position() - n->get_global_position()).normalized(); + Vector2 rel2 = (E->prev()->get().pos - E->get().pos).normalized(); + float rot = rel.angle_to(rel2); + if (n->get_global_transform().basis_determinant()<0) { + //mirrored, rotate the other way + rot=-rot; + } + + n->rotate(rot); + } + + } + + + + break; + } + } + } + + if (p_event.type==InputEvent::KEY) { + + const InputEventKey &k=p_event.key; + + if (k.pressed && drag==DRAG_NONE) { + + KeyMoveMODE move_mode = MOVE_VIEW_BASE; + if (k.mod.alt) move_mode = MOVE_LOCAL_BASE; + if (k.mod.control || k.mod.meta) move_mode = MOVE_LOCAL_WITH_ROT; + + if (k.scancode==KEY_UP) + _key_move( Vector2(0,-1), k.mod.shift, move_mode ); + else if (k.scancode==KEY_DOWN) + _key_move( Vector2(0,1), k.mod.shift, move_mode ); + else if (k.scancode==KEY_LEFT) + _key_move( Vector2(-1,0), k.mod.shift, move_mode ); + else if (k.scancode==KEY_RIGHT) + _key_move( Vector2(1,0), k.mod.shift, move_mode ); + else if (k.scancode==KEY_ESCAPE) { + editor_selection->clear(); + viewport->update(); + } + else + return; + + accept_event(); + } + + } + + + + +} + +void CanvasItemEditor::_viewport_draw() { + + // TODO fetch the viewport? + + Ref<Texture> pivot = get_icon("EditorPivot","EditorIcons"); + _update_scrollbars(); + RID ci=viewport->get_canvas_item(); + + if (snap_show_grid) { + Size2 s = viewport->get_size(); + int last_cell; + Transform2D xform = transform.affine_inverse(); + + if (snap_step.x!=0) { + for(int i=0;i<s.width;i++) { + int cell = Math::fast_ftoi(Math::floor((xform.xform(Vector2(i,0)).x-snap_offset.x)/snap_step.x)); + if (i==0) + last_cell=cell; + if (last_cell!=cell) + viewport->draw_line(Point2(i,0),Point2(i,s.height),Color(0.3,0.7,1,0.3)); + last_cell=cell; + } + } + + if (snap_step.y!=0) { + for(int i=0;i<s.height;i++) { + int cell = Math::fast_ftoi(Math::floor((xform.xform(Vector2(0,i)).y-snap_offset.y)/snap_step.y)); + if (i==0) + last_cell=cell; + if (last_cell!=cell) + viewport->draw_line(Point2(0,i),Point2(s.width,i),Color(0.3,0.7,1,0.3)); + last_cell=cell; + } + } + } + + if (viewport->has_focus()) { + Size2 size = viewport->get_size(); + if (v_scroll->is_visible_in_tree()) + size.width-=v_scroll->get_size().width; + if (h_scroll->is_visible_in_tree()) + size.height-=h_scroll->get_size().height; + + get_stylebox("EditorFocus","EditorStyles")->draw(ci,Rect2(Point2(),size)); + } + + Ref<Texture> lock = get_icon("Lock","EditorIcons"); + Ref<Texture> group = get_icon("Group","EditorIcons"); + + + bool single = get_single_item()!=NULL; + + Map<Node*,Object*> &selection = editor_selection->get_selection(); + + bool pivot_found=false; + + for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { + + + CanvasItem *canvas_item = E->key()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + if (!se) + continue; + + + Rect2 rect=canvas_item->get_item_rect(); + + Transform2D xform=transform * canvas_item->get_global_transform_with_canvas(); + VisualServer::get_singleton()->canvas_item_add_set_transform(ci,xform); + + Vector2 endpoints[4]={ + + xform.xform(rect.pos), + xform.xform(rect.pos+Vector2(rect.size.x,0)), + xform.xform(rect.pos+rect.size), + xform.xform(rect.pos+Vector2(0,rect.size.y)) + }; + + Color c = Color(1,0.6,0.4,0.7); + + VisualServer::get_singleton()->canvas_item_add_set_transform(ci,Transform2D()); + + for(int i=0;i<4;i++) { + viewport->draw_line(endpoints[i],endpoints[(i+1)%4],c,2); + } + + if (single && (tool==TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_ROTATE || tool==TOOL_EDIT_PIVOT)) { //kind of sucks + + if (canvas_item->cast_to<Node2D>()) { + + + if (canvas_item->cast_to<Node2D>()->edit_has_pivot()) { + viewport->draw_texture(pivot,xform.get_origin()+(-pivot->get_size()/2).floor()); + can_move_pivot=true; + pivot_found=true; + } + + } + + + if (tool==TOOL_SELECT) { + + + for(int i=0;i<4;i++) { + + int prev = (i+3)%4; + int next = (i+1)%4; + + Vector2 ofs = ((endpoints[i] - endpoints[prev]).normalized() + ((endpoints[i] - endpoints[next]).normalized())).normalized(); + ofs*=1.4144*(select_handle->get_size().width/2); + + select_handle->draw(ci,(endpoints[i]+ofs-(select_handle->get_size()/2)).floor()); + + ofs = (endpoints[i]+endpoints[next])/2; + ofs += (endpoints[next]-endpoints[i]).tangent().normalized()*(select_handle->get_size().width/2); + + select_handle->draw(ci,(ofs-(select_handle->get_size()/2)).floor()); + + } + + } + } + + + + //DRAW_EMPTY_RECT( Rect2( current_window->get_scroll()-Point2(1,1), get_size()+Size2(2,2)), Color(0.8,0.8,1.0,0.8) ); + //E->get().last_rect = rect; + } + + pivot_button->set_disabled(!pivot_found); + VisualServer::get_singleton()->canvas_item_add_set_transform(ci,Transform2D()); + + + + Color x_axis_color(1.0,0.4,0.4,0.6); + Color y_axis_color(0.4,1.0,0.4,0.6); + Color area_axis_color(0.4,0.4,1.0,0.4); + Color rotate_color(0.4,0.7,1.0,0.8); + + VisualServer::get_singleton()->canvas_item_add_line(ci,Point2(h_scroll->get_min(),0)+transform.get_origin(),Point2(h_scroll->get_max(),0)+transform.get_origin(),x_axis_color); + VisualServer::get_singleton()->canvas_item_add_line(ci,Point2(0,v_scroll->get_min())+transform.get_origin(),Point2(0,v_scroll->get_max())+transform.get_origin(),y_axis_color); + + + if (box_selecting) { + + Point2 bsfrom = transform.xform(drag_from); + Point2 bsto= transform.xform(box_selecting_to); + + + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(bsfrom,bsto-bsfrom),Color(0.7,0.7,1.0,0.3)); + } + + if (drag==DRAG_ROTATE) { + VisualServer::get_singleton()->canvas_item_add_line(ci,transform.xform(display_rotate_from), transform.xform(display_rotate_to),rotate_color); + } + + Size2 screen_size = Size2( GlobalConfig::get_singleton()->get("display/window/width"), GlobalConfig::get_singleton()->get("display/window/height") ); + + Vector2 screen_endpoints[4]= { + transform.xform(Vector2(0,0)), + transform.xform(Vector2(screen_size.width,0)), + transform.xform(Vector2(screen_size.width,screen_size.height)), + transform.xform(Vector2(0,screen_size.height)) + }; + + for(int i=0;i<4;i++) { + + VisualServer::get_singleton()->canvas_item_add_line(ci,screen_endpoints[i], screen_endpoints[(i+1)%4],area_axis_color); + + } + + for(List<LockList>::Element*E=lock_list.front();E;E=E->next()) { + + Vector2 ofs = transform.xform(E->get().pos); + if (E->get().lock) { + + lock->draw(ci,ofs); + ofs.x+=lock->get_width(); + } + if (E->get().group) { + + group->draw(ci,ofs); + } + + } + + { + + EditorNode *en = editor; + EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); + + if (!over_plugin_list->empty()) { + + over_plugin_list->forward_draw_over_canvas(transform,viewport); + + } + } + + if (skeleton_show_bones) { + int bone_width = EditorSettings::get_singleton()->get("editors/2d/bone_width"); + Color bone_color1 = EditorSettings::get_singleton()->get("editors/2d/bone_color1"); + Color bone_color2 = EditorSettings::get_singleton()->get("editors/2d/bone_color2"); + Color bone_ik_color = EditorSettings::get_singleton()->get("editors/2d/bone_ik_color"); + Color bone_selected_color = EditorSettings::get_singleton()->get("editors/2d/bone_selected_color"); + + for(Map<ObjectID,BoneList>::Element*E=bone_list.front();E;E=E->next()) { + + E->get().from=Vector2(); + E->get().to=Vector2(); + + Object *obj = ObjectDB::get_instance(E->get().bone); + if (!obj) + continue; + + Node2D* n2d = obj->cast_to<Node2D>(); + if (!n2d) + continue; + + if (!n2d->get_parent()) + continue; + + CanvasItem *pi = n2d->get_parent_item(); + + + Node2D* pn2d=n2d->get_parent()->cast_to<Node2D>(); + + if (!pn2d) + continue; + + Vector2 from = transform.xform(pn2d->get_global_position()); + Vector2 to = transform.xform(n2d->get_global_position()); + + E->get().from=from; + E->get().to=to; + + Vector2 rel = to-from; + Vector2 relt = rel.tangent().normalized()*bone_width; + + + + Vector<Vector2> bone_shape; + bone_shape.push_back(from); + bone_shape.push_back(from+rel*0.2+relt); + bone_shape.push_back(to); + bone_shape.push_back(from+rel*0.2-relt); + Vector<Color> colors; + if (pi->has_meta("_edit_ik_")) { + + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + } else { + colors.push_back(bone_color1); + colors.push_back(bone_color2); + colors.push_back(bone_color1); + colors.push_back(bone_color2); + } + + + VisualServer::get_singleton()->canvas_item_add_primitive(ci,bone_shape,colors,Vector<Vector2>(),RID()); + + if (editor_selection->is_selected(pi)) { + for(int i=0;i<bone_shape.size();i++) { + + VisualServer::get_singleton()->canvas_item_add_line(ci,bone_shape[i],bone_shape[(i+1)%bone_shape.size()],bone_selected_color,2); + } + } + + } + } +} + +void CanvasItemEditor::_notification(int p_what) { + + if (p_what==NOTIFICATION_FIXED_PROCESS) { + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + bool all_control=true; + bool has_control=false; + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + if (canvas_item->cast_to<Control>()) + has_control=true; + else + all_control=false; + + CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + if (!se) + continue; + + Rect2 r=canvas_item->get_item_rect(); + + Transform2D xform = canvas_item->get_transform(); + + if (r != se->prev_rect || xform!=se->prev_xform) { + viewport->update(); + se->prev_rect=r; + se->prev_xform=xform; + } + + } + + bool show_anchor = all_control && has_control; + if (show_anchor != anchor_menu->is_visible()) { + if (show_anchor) + anchor_menu->show(); + else + anchor_menu->hide(); + } + + for(Map<ObjectID,BoneList>::Element *E=bone_list.front();E;E=E->next()) { + + Object *b = ObjectDB::get_instance(E->get().bone); + if (!b) { + + viewport->update(); + break; + } + + Node2D *b2 = b->cast_to<Node2D>(); + if (!b2) { + continue; + } + + if (b2->get_global_transform()!=E->get().xform) { + + E->get().xform=b2->get_global_transform(); + viewport->update(); + } + } + } + + if (p_what==NOTIFICATION_ENTER_TREE) { + + select_sb->set_texture( get_icon("EditorRect2D","EditorIcons") ); + for(int i=0;i<4;i++) { + select_sb->set_margin_size(Margin(i),4); + select_sb->set_default_margin(Margin(i),4); + } + + select_button->set_icon( get_icon("ToolSelect","EditorIcons")); + list_select_button->set_icon( get_icon("ListSelect","EditorIcons")); + move_button->set_icon( get_icon("ToolMove","EditorIcons")); + rotate_button->set_icon( get_icon("ToolRotate","EditorIcons")); + pan_button->set_icon( get_icon("ToolPan", "EditorIcons")); + pivot_button->set_icon( get_icon("EditPivot", "EditorIcons")); + select_handle=get_icon("EditorHandle","EditorIcons"); + lock_button->set_icon(get_icon("Lock","EditorIcons")); + unlock_button->set_icon(get_icon("Unlock","EditorIcons")); + group_button->set_icon(get_icon("Group","EditorIcons")); + ungroup_button->set_icon(get_icon("Ungroup","EditorIcons")); + key_insert_button->set_icon(get_icon("Key","EditorIcons")); + + + //anchor_menu->add_icon_override("Align Top Left"); + anchor_menu->set_icon(get_icon("Anchor","EditorIcons")); + PopupMenu *p=anchor_menu->get_popup(); + + p->add_icon_item(get_icon("ControlAlignTopLeft","EditorIcons"),"Top Left",ANCHOR_ALIGN_TOP_LEFT); + p->add_icon_item(get_icon("ControlAlignTopRight","EditorIcons"),"Top Right",ANCHOR_ALIGN_TOP_RIGHT); + p->add_icon_item(get_icon("ControlAlignBottomRight","EditorIcons"),"Bottom Right",ANCHOR_ALIGN_BOTTOM_RIGHT); + p->add_icon_item(get_icon("ControlAlignBottomLeft","EditorIcons"),"Bottom Left",ANCHOR_ALIGN_BOTTOM_LEFT); + p->add_separator(); + p->add_icon_item(get_icon("ControlAlignLeftCenter","EditorIcons"),"Center Left",ANCHOR_ALIGN_CENTER_LEFT); + p->add_icon_item(get_icon("ControlAlignTopCenter","EditorIcons"),"Center Top",ANCHOR_ALIGN_CENTER_TOP); + p->add_icon_item(get_icon("ControlAlignRightCenter","EditorIcons"),"Center Right",ANCHOR_ALIGN_CENTER_RIGHT); + p->add_icon_item(get_icon("ControlAlignBottomCenter","EditorIcons"),"Center Bottom",ANCHOR_ALIGN_CENTER_BOTTOM); + p->add_icon_item(get_icon("ControlAlignCenter","EditorIcons"),"Center",ANCHOR_ALIGN_CENTER); + p->add_separator(); + p->add_icon_item(get_icon("ControlAlignLeftWide","EditorIcons"),"Left Wide",ANCHOR_ALIGN_LEFT_WIDE); + p->add_icon_item(get_icon("ControlAlignTopWide","EditorIcons"),"Top Wide",ANCHOR_ALIGN_TOP_WIDE); + p->add_icon_item(get_icon("ControlAlignRightWide","EditorIcons"),"Right Wide",ANCHOR_ALIGN_RIGHT_WIDE); + p->add_icon_item(get_icon("ControlAlignBottomWide","EditorIcons"),"Bottom Wide",ANCHOR_ALIGN_BOTTOM_WIDE); + p->add_icon_item(get_icon("ControlVcenterWide","EditorIcons"),"VCenter Wide ",ANCHOR_ALIGN_VCENTER_WIDE); + p->add_icon_item(get_icon("ControlHcenterWide","EditorIcons"),"HCenter Wide ",ANCHOR_ALIGN_HCENTER_WIDE); + p->add_separator(); + p->add_icon_item(get_icon("ControlAlignWide","EditorIcons"),"Full Rect",ANCHOR_ALIGN_WIDE); + + + AnimationPlayerEditor::singleton->get_key_editor()->connect("visibility_changed",this,"_keying_changed"); + _keying_changed(); + } + + if (p_what==NOTIFICATION_READY) { + + get_tree()->connect("node_removed",this,"_node_removed"); + } + + if (p_what==NOTIFICATION_DRAW) { + + + + } +} + +void CanvasItemEditor::edit(CanvasItem *p_canvas_item) { + + drag=DRAG_NONE; + + editor_selection->clear();//_clear_canvas_items(); + editor_selection->add_node(p_canvas_item); + //_add_canvas_item(p_canvas_item); + viewport->update(); + +} + + +void CanvasItemEditor::_find_canvas_items_span(Node *p_node, Rect2& r_rect, const Transform2D& p_xform) { + + + + if (!p_node) + return; + + CanvasItem *c=p_node->cast_to<CanvasItem>(); + + + for (int i=p_node->get_child_count()-1;i>=0;i--) { + + //CanvasItem *r=NULL; + + if (c && !c->is_set_as_toplevel()) + _find_canvas_items_span(p_node->get_child(i),r_rect,p_xform * c->get_transform()); + else + _find_canvas_items_span(p_node->get_child(i),r_rect,Transform2D()); + } + + + + if (c && c->is_visible_in_tree()) { + + Rect2 rect = c->get_item_rect(); + Transform2D xform = p_xform * c->get_transform(); + + + LockList lock; + lock.lock=c->has_meta("_edit_lock_"); + lock.group=c->has_meta("_edit_group_"); + + if (lock.group || lock.lock) { + lock.pos=xform.xform(rect.pos); + lock_list.push_back(lock); + } + + if (c->has_meta("_edit_bone_")) { + + ObjectID id = c->get_instance_ID(); + if (!bone_list.has(id)) { + BoneList bone; + bone.bone=id; + bone_list[id]=bone; + } + + bone_list[id].last_pass=bone_last_frame; + } + + r_rect.expand_to( xform.xform(rect.pos) ); + r_rect.expand_to( xform.xform(rect.pos+Point2(rect.size.x,0)) ); + r_rect.expand_to( xform.xform(rect.pos+Point2(0,rect.size.y)) ); + r_rect.expand_to( xform.xform(rect.pos+rect.size) ); + + } + +} + +void CanvasItemEditor::_update_scrollbars() { + + + updating_scroll=true; + + Size2 size = viewport->get_size(); + Size2 hmin = h_scroll->get_minimum_size(); + Size2 vmin = v_scroll->get_minimum_size(); + + v_scroll->set_begin( Point2(size.width - vmin.width, 0) ); + v_scroll->set_end( Point2(size.width, size.height) ); + + h_scroll->set_begin( Point2( 0, size.height - hmin.height) ); + h_scroll->set_end( Point2(size.width-vmin.width, size.height) ); + + + Size2 screen_rect = Size2( GlobalConfig::get_singleton()->get("display/window/width"), GlobalConfig::get_singleton()->get("display/window/height") ); + + + Rect2 local_rect = Rect2(Point2(),viewport->get_size()-Size2(vmin.width,hmin.height)); + + Rect2 canvas_item_rect=Rect2(Point2(),screen_rect); + + lock_list.clear(); + bone_last_frame++; + + + + if (editor->get_edited_scene()) + _find_canvas_items_span(editor->get_edited_scene(),canvas_item_rect,Transform2D()); + + List<Map<ObjectID,BoneList>::Element*> bone_to_erase; + + for(Map<ObjectID,BoneList>::Element*E=bone_list.front();E;E=E->next()) { + + if (E->get().last_pass!=bone_last_frame) { + bone_to_erase.push_back(E); + } + } + + while(bone_to_erase.size()) { + bone_list.erase(bone_to_erase.front()->get()); + bone_to_erase.pop_front(); + } + + //expand area so it's easier to do animations and stuff at 0,0 + canvas_item_rect.size+=screen_rect*2; + canvas_item_rect.pos-=screen_rect; + + Point2 ofs; + + + if (canvas_item_rect.size.height <= (local_rect.size.y/zoom)) { + + v_scroll->hide(); + ofs.y=canvas_item_rect.pos.y; + } else { + + v_scroll->show(); + v_scroll->set_min(canvas_item_rect.pos.y); + v_scroll->set_max(canvas_item_rect.pos.y+canvas_item_rect.size.y); + v_scroll->set_page(local_rect.size.y/zoom); + if (first_update) { + //so 0,0 is visible + v_scroll->set_value(-10); + h_scroll->set_value(-10); + first_update=false; + + } + + ofs.y=v_scroll->get_value(); + } + + if (canvas_item_rect.size.width <= (local_rect.size.x/zoom)) { + + h_scroll->hide(); + ofs.x=canvas_item_rect.pos.x; + } else { + + h_scroll->show(); + h_scroll->set_min(canvas_item_rect.pos.x); + h_scroll->set_max(canvas_item_rect.pos.x+canvas_item_rect.size.x); + h_scroll->set_page(local_rect.size.x/zoom); + ofs.x=h_scroll->get_value(); + } + + //transform=Matrix32(); + transform.elements[2]=-ofs*zoom; + + editor->get_scene_root()->set_global_canvas_transform(transform); + + + updating_scroll=false; + + //transform.scale_basis(Vector2(zoom,zoom)); + + +} + +void CanvasItemEditor::_update_scroll(float) { + + + if (updating_scroll) + return; + + Point2 ofs; + ofs.x=h_scroll->get_value(); + ofs.y=v_scroll->get_value(); + + //current_window->set_scroll(-ofs); + + transform=Transform2D(); + + transform.scale_basis(Size2(zoom,zoom)); + transform.elements[2]=-ofs; + + editor->get_scene_root()->set_global_canvas_transform(transform); + + + viewport->update(); + +} + +void CanvasItemEditor::_set_anchor(Control::AnchorType p_left,Control::AnchorType p_top,Control::AnchorType p_right,Control::AnchorType p_bottom) { + List<Node*> &selection = editor_selection->get_selected_node_list(); + + undo_redo->create_action(TTR("Change Anchors")); + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Control *c = E->get()->cast_to<Control>(); + + undo_redo->add_do_method(c,"set_anchor",MARGIN_LEFT,p_left); + undo_redo->add_do_method(c,"set_anchor",MARGIN_TOP,p_top); + undo_redo->add_do_method(c,"set_anchor",MARGIN_RIGHT,p_right); + undo_redo->add_do_method(c,"set_anchor",MARGIN_BOTTOM,p_bottom); + undo_redo->add_undo_method(c,"set_anchor",MARGIN_LEFT,c->get_anchor(MARGIN_LEFT)); + undo_redo->add_undo_method(c,"set_anchor",MARGIN_TOP,c->get_anchor(MARGIN_TOP)); + undo_redo->add_undo_method(c,"set_anchor",MARGIN_RIGHT,c->get_anchor(MARGIN_RIGHT)); + undo_redo->add_undo_method(c,"set_anchor",MARGIN_BOTTOM,c->get_anchor(MARGIN_BOTTOM)); + } + + undo_redo->commit_action(); + +} + +void CanvasItemEditor::_popup_callback(int p_op) { + + last_option=MenuOption(p_op); + switch(p_op) { + + case SNAP_USE: { + snap_grid = !snap_grid; + int idx = edit_menu->get_popup()->get_item_index(SNAP_USE); + edit_menu->get_popup()->set_item_checked(idx,snap_grid); + } break; + case SNAP_SHOW_GRID: { + snap_show_grid = !snap_show_grid; + int idx = edit_menu->get_popup()->get_item_index(SNAP_SHOW_GRID); + edit_menu->get_popup()->set_item_checked(idx,snap_show_grid); + viewport->update(); + } break; + case SNAP_USE_ROTATION: { + snap_rotation = !snap_rotation; + int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_ROTATION); + edit_menu->get_popup()->set_item_checked(idx,snap_rotation); + } break; + case SNAP_RELATIVE: { + snap_relative = !snap_relative; + int idx = edit_menu->get_popup()->get_item_index(SNAP_RELATIVE); + edit_menu->get_popup()->set_item_checked(idx,snap_relative); + } break; + case SNAP_USE_PIXEL: { + snap_pixel = !snap_pixel; + int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_PIXEL); + edit_menu->get_popup()->set_item_checked(idx,snap_pixel); + } break; + case SNAP_CONFIGURE: { + ((SnapDialog *)snap_dialog)->set_fields(snap_offset, snap_step, snap_rotation_offset, snap_rotation_step); + snap_dialog->popup_centered(Size2(220,160)); + } break; + case SKELETON_SHOW_BONES: { + skeleton_show_bones = !skeleton_show_bones; + int idx = skeleton_menu->get_item_index(SKELETON_SHOW_BONES); + skeleton_menu->set_item_checked(idx,skeleton_show_bones); + viewport->update(); + } break; + case ZOOM_IN: { + if (zoom>MAX_ZOOM) + return; + zoom=zoom*(1.0/0.5); + _update_scroll(0); + viewport->update(); + return; + } break; + case ZOOM_OUT: { + if (zoom<MIN_ZOOM) + return; + + zoom=zoom*0.5; + _update_scroll(0); + viewport->update(); + return; + + } break; + case ZOOM_RESET: { + + zoom=1; + _update_scroll(0); + viewport->update(); + return; + + } break; + case ZOOM_SET: { + + updating_value_dialog=true; + + dialog_label->set_text(TTR("Zoom (%):")); + dialog_val->set_min(0.1); + dialog_val->set_step(0.1); + dialog_val->set_max(800); + dialog_val->set_value(zoom*100); + value_dialog->popup_centered(Size2(200,85)); + updating_value_dialog=false; + + + } break; + case LOCK_SELECTED: { + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + canvas_item->set_meta("_edit_lock_",true); + emit_signal("item_lock_status_changed"); + } + viewport->update(); + } break; + case UNLOCK_SELECTED: { + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + + canvas_item->set_meta("_edit_lock_",Variant()); + emit_signal("item_lock_status_changed"); + } + + viewport->update(); + + } break; + case GROUP_SELECTED: { + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + canvas_item->set_meta("_edit_group_",true); + emit_signal("item_group_status_changed"); + } + viewport->update(); + } break; + case UNGROUP_SELECTED: { + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + canvas_item->set_meta("_edit_group_",Variant()); + emit_signal("item_group_status_changed"); + } + + viewport->update(); + + } break; + + case EXPAND_TO_PARENT: { + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + + Control *c = canvas_item->cast_to<Control>(); + if (!c) + continue; + c->set_area_as_parent_rect(); + + } + + viewport->update(); + + } break; + + case ALIGN_VERTICAL: { +#if 0 + if ( ref_item && canvas_items.size() > 1 ) { + Vector2 ref_pos = ref_item->get_global_transform().elements[2]; + Rect2 ref_r = ref_item->get_item_rect(); + for ( CanvasItemMap::Element *E = canvas_items.front(); E; E = E->next() ) { + CanvasItem *it_curr = E->key(); + if ( it_curr == ref_item ) continue; + Vector2 v = it_curr->get_global_transform().elements[2]; + Rect2 r = it_curr->get_item_rect(); + r.pos.x = ( ref_pos.x + ref_r.size.x / 2 ) - ( v.x + r.size.x / 2 ); + it_curr->edit_set_rect( r ); + } + viewport->update(); + } +#endif + } break; + + case ALIGN_HORIZONTAL: { +#if 0 + if ( ref_item && canvas_items.size() > 1 ) { + Vector2 ref_pos = ref_item->get_global_transform().elements[2]; + Rect2 ref_r = ref_item->get_item_rect(); + for ( CanvasItemMap::Element *E = canvas_items.front(); E; E = E->next() ) { + CanvasItem *it_curr = E->key(); + if ( it_curr == ref_item ) continue; + Vector2 v = it_curr->get_global_transform().elements[2]; + Rect2 r = it_curr->get_item_rect(); + r.pos.y = ( ref_pos.y + ref_r.size.y / 2 ) - ( v.y + r.size.y / 2 ); + it_curr->edit_set_rect( r ); + } + viewport->update(); + } +#endif + } break; + + case SPACE_HORIZONTAL: { + //space_selected_items< proj_vector2_x, compare_items_x >(); + } break; + + case SPACE_VERTICAL: { + //space_selected_items< proj_vector2_y, compare_items_y >(); + } break; + case ANCHOR_ALIGN_TOP_LEFT: { + _set_anchor(ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_BEGIN); + } break; + case ANCHOR_ALIGN_TOP_RIGHT: { + _set_anchor(ANCHOR_END,ANCHOR_BEGIN,ANCHOR_END,ANCHOR_BEGIN); + } break; + case ANCHOR_ALIGN_BOTTOM_LEFT: { + _set_anchor(ANCHOR_BEGIN,ANCHOR_END,ANCHOR_BEGIN,ANCHOR_END); + } break; + case ANCHOR_ALIGN_BOTTOM_RIGHT: { + _set_anchor(ANCHOR_END,ANCHOR_END,ANCHOR_END,ANCHOR_END); + } break; + case ANCHOR_ALIGN_CENTER_LEFT: { + _set_anchor(ANCHOR_BEGIN,ANCHOR_CENTER,ANCHOR_BEGIN,ANCHOR_CENTER); + } break; + case ANCHOR_ALIGN_CENTER_RIGHT: { + + _set_anchor(ANCHOR_END,ANCHOR_CENTER,ANCHOR_END,ANCHOR_CENTER); + } break; + case ANCHOR_ALIGN_CENTER_TOP: { + _set_anchor(ANCHOR_CENTER,ANCHOR_BEGIN,ANCHOR_CENTER,ANCHOR_BEGIN); + } break; + case ANCHOR_ALIGN_CENTER_BOTTOM: { + _set_anchor(ANCHOR_CENTER,ANCHOR_END,ANCHOR_CENTER,ANCHOR_END); + } break; + case ANCHOR_ALIGN_CENTER: { + _set_anchor(ANCHOR_CENTER,ANCHOR_CENTER,ANCHOR_CENTER,ANCHOR_CENTER); + } break; + case ANCHOR_ALIGN_TOP_WIDE: { + _set_anchor(ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_END,ANCHOR_BEGIN); + } break; + case ANCHOR_ALIGN_LEFT_WIDE: { + _set_anchor(ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_END); + } break; + case ANCHOR_ALIGN_RIGHT_WIDE: { + _set_anchor(ANCHOR_END,ANCHOR_BEGIN,ANCHOR_END,ANCHOR_END); + } break; + case ANCHOR_ALIGN_BOTTOM_WIDE: { + _set_anchor(ANCHOR_BEGIN,ANCHOR_END,ANCHOR_END,ANCHOR_END); + } break; + case ANCHOR_ALIGN_VCENTER_WIDE: { + _set_anchor(ANCHOR_CENTER,ANCHOR_BEGIN,ANCHOR_CENTER,ANCHOR_END); + } break; + case ANCHOR_ALIGN_HCENTER_WIDE: { + _set_anchor(ANCHOR_BEGIN,ANCHOR_CENTER,ANCHOR_END,ANCHOR_CENTER); + } break; + case ANCHOR_ALIGN_WIDE: { + _set_anchor(ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_END,ANCHOR_END); + } break; + + case ANIM_INSERT_KEY: + case ANIM_INSERT_KEY_EXISTING: { + + bool existing = p_op==ANIM_INSERT_KEY_EXISTING; + + Map<Node*,Object*> &selection = editor_selection->get_selection(); + + for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->key()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + if (canvas_item->cast_to<Node2D>()) { + Node2D *n2d = canvas_item->cast_to<Node2D>(); + + if (key_pos) + AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(n2d,"transform/pos",n2d->get_position(),existing); + if (key_rot) + AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(n2d,"transform/rot",Math::rad2deg(n2d->get_rotation()),existing); + if (key_scale) + AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(n2d,"transform/scale",n2d->get_scale(),existing); + + + if (n2d->has_meta("_edit_bone_") && n2d->get_parent_item()) { + //look for an IK chain + List<Node2D*> ik_chain; + + Node2D *n = n2d->get_parent_item()->cast_to<Node2D>(); + bool has_chain=false; + + while(n) { + + ik_chain.push_back(n); + if (n->has_meta("_edit_ik_")) { + has_chain=true; + break; + } + + if (!n->get_parent_item()) + break; + n=n->get_parent_item()->cast_to<Node2D>(); + } + + if (has_chain && ik_chain.size()) { + + for(List<Node2D*>::Element *F=ik_chain.front();F;F=F->next()) { + + if (key_pos) + AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(F->get(),"transform/pos",F->get()->get_position(),existing); + if (key_rot) + AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(F->get(),"transform/rot",Math::rad2deg(F->get()->get_rotation()),existing); + if (key_scale) + AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(F->get(),"transform/scale",F->get()->get_scale(),existing); + + + } + } + } + + } else if (canvas_item->cast_to<Control>()) { + + Control *ctrl = canvas_item->cast_to<Control>(); + + if (key_pos) + AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(ctrl,"rect/pos",ctrl->get_pos(),existing); + if (key_scale) + AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(ctrl,"rect/size",ctrl->get_size(),existing); + } + + } + + } break; + case ANIM_INSERT_POS: { + + key_pos = key_loc_button->is_pressed(); + } break; + case ANIM_INSERT_ROT: { + + key_rot = key_rot_button->is_pressed(); + } break; + case ANIM_INSERT_SCALE: { + + key_scale = key_scale_button->is_pressed(); + } break; + /* + case ANIM_INSERT_POS_ROT + case ANIM_INSERT_POS_SCALE: + case ANIM_INSERT_ROT_SCALE: + case ANIM_INSERT_POS_ROT_SCALE: { + + static const bool key_toggles[7][3]={ + {true,false,false}, + {false,true,false}, + {false,false,true}, + {true,true,false}, + {true,false,true}, + {false,true,true}, + {true,true,true} + }; + key_pos=key_toggles[p_op-ANIM_INSERT_POS][0]; + key_rot=key_toggles[p_op-ANIM_INSERT_POS][1]; + key_scale=key_toggles[p_op-ANIM_INSERT_POS][2]; + + for(int i=ANIM_INSERT_POS;i<=ANIM_INSERT_POS_ROT_SCALE;i++) { + int idx = animation_menu->get_popup()->get_item_index(i); + animation_menu->get_popup()->set_item_checked(idx,i==p_op); + } + + } break;*/ + case ANIM_COPY_POSE: { + + pose_clipboard.clear(); + + + Map<Node*,Object*> &selection = editor_selection->get_selection(); + + for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->key()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + + if (canvas_item->cast_to<Node2D>()) { + + Node2D *n2d = canvas_item->cast_to<Node2D>(); + PoseClipboard pc; + pc.pos=n2d->get_position(); + pc.rot=n2d->get_rotation(); + pc.scale=n2d->get_scale(); + pc.id=n2d->get_instance_ID(); + pose_clipboard.push_back(pc); + } + } + + + } break; + case ANIM_PASTE_POSE: { + + if (!pose_clipboard.size()) + break; + + undo_redo->create_action(TTR("Paste Pose")); + for (List<PoseClipboard>::Element *E=pose_clipboard.front();E;E=E->next()) { + + Object *o = ObjectDB::get_instance(E->get().id); + if (!o) + continue; + Node2D *n2d = o->cast_to<Node2D>(); + if (!n2d) + continue; + undo_redo->add_do_method(n2d,"set_pos",E->get().pos); + undo_redo->add_do_method(n2d,"set_rot",E->get().rot); + undo_redo->add_do_method(n2d,"set_scale",E->get().scale); + undo_redo->add_undo_method(n2d,"set_pos",n2d->get_position()); + undo_redo->add_undo_method(n2d,"set_rot",n2d->get_rotation()); + undo_redo->add_undo_method(n2d,"set_scale",n2d->get_scale()); + } + undo_redo->commit_action(); + + } break; + case ANIM_CLEAR_POSE: { + + Map<Node*,Object*> &selection = editor_selection->get_selection(); + + for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->key()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + if (canvas_item->cast_to<Node2D>()) { + Node2D *n2d = canvas_item->cast_to<Node2D>(); + + if (key_pos) + n2d->set_position(Vector2()); + if (key_rot) + n2d->set_rotation(0); + if (key_scale) + n2d->set_scale(Vector2(1,1)); + } else if (canvas_item->cast_to<Control>()) { + + Control *ctrl = canvas_item->cast_to<Control>(); + + if (key_pos) + ctrl->set_pos(Point2()); + /* + if (key_scale) + AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(ctrl,"rect/size",ctrl->get_size()); + */ + } + + } + + + } break; + case VIEW_CENTER_TO_SELECTION: + case VIEW_FRAME_TO_SELECTION: { + + _focus_selection(p_op); + + } break; + case SKELETON_MAKE_BONES: { + + + + Map<Node*,Object*> &selection = editor_selection->get_selection(); + + for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { + + Node2D *n2d = E->key()->cast_to<Node2D>(); + if (!n2d) + continue; + if (!n2d->is_visible_in_tree()) + continue; + if (!n2d->get_parent_item()) + continue; + + n2d->set_meta("_edit_bone_",true); + if (!skeleton_show_bones) + skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES)); + + } + viewport->update(); + + } break; + case SKELETON_CLEAR_BONES: { + + Map<Node*,Object*> &selection = editor_selection->get_selection(); + + for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { + + Node2D *n2d = E->key()->cast_to<Node2D>(); + if (!n2d) + continue; + if (!n2d->is_visible_in_tree()) + continue; + + n2d->set_meta("_edit_bone_",Variant()); + if (!skeleton_show_bones) + skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES)); + + } + viewport->update(); + + } break; + case SKELETON_SET_IK_CHAIN: { + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); + if (!canvas_item || !canvas_item->is_visible_in_tree()) + continue; + + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + canvas_item->set_meta("_edit_ik_",true); + if (!skeleton_show_bones) + skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES)); + + } + + viewport->update(); + + } break; + case SKELETON_CLEAR_IK_CHAIN: { + + Map<Node*,Object*> &selection = editor_selection->get_selection(); + + for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { + + CanvasItem *n2d = E->key()->cast_to<CanvasItem>(); + if (!n2d) + continue; + if (!n2d->is_visible_in_tree()) + continue; + + n2d->set_meta("_edit_ik_",Variant()); + if (!skeleton_show_bones) + skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES)); + + } + viewport->update(); + + } break; + + } +} +#if 0 +template< class P, class C > void CanvasItemEditor::space_selected_items() { + P p; + if ( canvas_items.size() > 2 ) { + Vector< CanvasItem * > items; + for ( CanvasItemMap::Element *E = canvas_items.front(); E; E = E->next() ) { + CanvasItem *it_curr = E->key(); + items.push_back( it_curr ); + } + items.sort_custom< C >(); + + float width_s = p.get( items[0]->get_item_rect().size ); + float width_e = p.get( items[ items.size() - 1 ]->get_item_rect().size ); + float start_x = p.get( items[0]->get_global_transform().elements[2] ) + ( width_s / 2 ); + float end_x = p.get( items[ items.size() - 1 ]->get_global_transform().elements[2] ) + ( width_e / 2 ); + float sp = ( end_x - start_x ) / ( items.size() - 1 ); + + for ( int i = 0; i < items.size(); i++ ) { + CanvasItem *it_curr = items[i]; + Vector2 v = it_curr->get_global_transform().elements[2]; + Rect2 r = it_curr->get_item_rect(); + p.set( r.pos, ( start_x + sp * i ) - ( p.get( v ) + p.get( r.size ) / 2 ) ); + it_curr->edit_set_rect( r ); + } + viewport->update(); + } +} +#endif + + +void CanvasItemEditor::_focus_selection(int p_op) { + Vector2 center(0.f, 0.f); + Rect2 rect; + int count = 0; + + Map<Node*,Object*> &selection = editor_selection->get_selection(); + for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { + CanvasItem *canvas_item = E->key()->cast_to<CanvasItem>(); + if (!canvas_item) continue; + if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) + continue; + + + // counting invisible items, for now + //if (!canvas_item->is_visible_in_tree()) continue; + ++count; + + Rect2 item_rect = canvas_item->get_item_rect(); + + Vector2 pos = canvas_item->get_global_transform().get_origin(); + Vector2 scale = canvas_item->get_global_transform().get_scale(); + real_t angle = canvas_item->get_global_transform().get_rotation(); + + Transform2D t(angle, Vector2(0.f,0.f)); + item_rect = t.xform(item_rect); + Rect2 canvas_item_rect(pos + scale*item_rect.pos, scale*item_rect.size); + if (count == 1) { + rect = canvas_item_rect; + } else { + rect = rect.merge(canvas_item_rect); + } + }; + if (count==0) return; + + if (p_op == VIEW_CENTER_TO_SELECTION) { + + center = rect.pos + rect.size/2; + Vector2 offset = viewport->get_size()/2 - editor->get_scene_root()->get_global_canvas_transform().xform(center); + h_scroll->set_value(h_scroll->get_value() - offset.x/zoom); + v_scroll->set_value(v_scroll->get_value() - offset.y/zoom); + + } else { // VIEW_FRAME_TO_SELECTION + + if (rect.size.x > CMP_EPSILON && rect.size.y > CMP_EPSILON) { + float scale_x = viewport->get_size().x/rect.size.x; + float scale_y = viewport->get_size().y/rect.size.y; + zoom = scale_x < scale_y? scale_x:scale_y; + zoom *= 0.90; + _update_scroll(0); + call_deferred("_popup_callback", VIEW_CENTER_TO_SELECTION); + } + } +} + + +void CanvasItemEditor::_bind_methods() { + + ClassDB::bind_method("_node_removed",&CanvasItemEditor::_node_removed); + ClassDB::bind_method("_update_scroll",&CanvasItemEditor::_update_scroll); + ClassDB::bind_method("_popup_callback",&CanvasItemEditor::_popup_callback); + ClassDB::bind_method("_visibility_changed",&CanvasItemEditor::_visibility_changed); + ClassDB::bind_method("_dialog_value_changed",&CanvasItemEditor::_dialog_value_changed); + ClassDB::bind_method("_get_editor_data",&CanvasItemEditor::_get_editor_data); + ClassDB::bind_method("_tool_select",&CanvasItemEditor::_tool_select); + ClassDB::bind_method("_keying_changed",&CanvasItemEditor::_keying_changed); + ClassDB::bind_method("_unhandled_key_input",&CanvasItemEditor::_unhandled_key_input); + ClassDB::bind_method("_viewport_draw",&CanvasItemEditor::_viewport_draw); + ClassDB::bind_method("_viewport_gui_input",&CanvasItemEditor::_viewport_gui_input); + ClassDB::bind_method("_snap_changed",&CanvasItemEditor::_snap_changed); + ClassDB::bind_method(D_METHOD("_selection_result_pressed"),&CanvasItemEditor::_selection_result_pressed); + ClassDB::bind_method(D_METHOD("_selection_menu_hide"),&CanvasItemEditor::_selection_menu_hide); + + ADD_SIGNAL( MethodInfo("item_lock_status_changed") ); + ADD_SIGNAL( MethodInfo("item_group_status_changed") ); + +} + +#if 0 +void CanvasItemEditor::end_drag() { + print_line( "end drag" ); + + if (undo_redo) { + + undo_redo->create_action("Edit CanvasItem"); + for(CanvasItemMap::Element *E=canvas_items.front();E;E=E->next()) { + CanvasItem *canvas_item = E->key(); + Variant state=canvas_item->edit_get_state(); + undo_redo->add_do_method(canvas_item,"edit_set_state",state); + undo_redo->add_undo_method(canvas_item,"edit_set_state",E->get().undo_state); + } + undo_redo->commit_action(); + } + + drag=DRAG_NONE; + viewport->update(); +} + +void CanvasItemEditor::box_selection_start( Point2 &click ) { + print_line( "box selection start" ); + + drag_from=transform.affine_inverse().xform(click); + + box_selecting=true; + box_selecting_to=drag_from; + viewport->update(); +} + +bool CanvasItemEditor::box_selection_end() { + print_line( "box selection end" ); + + Node* scene = get_scene()->get_root_node()->cast_to<EditorNode>()->get_edited_scene(); + if (scene) { + + List<CanvasItem*> selitems; + + Point2 bsfrom = transform.xform(drag_from); + Point2 bsto= transform.xform(box_selecting_to); + if (bsfrom.x>bsto.x) + SWAP(bsfrom.x,bsto.x); + if (bsfrom.y>bsto.y) + SWAP(bsfrom.y,bsto.y); + + if ( bsfrom.distance_to( bsto ) < 3 ) { + print_line( "box selection too small" ); + box_selecting=false; + viewport->update(); + return false; + } + + _find_canvas_items_at_rect(Rect2(bsfrom,bsto-bsfrom),scene,transform,&selitems); + + for(List<CanvasItem*>::Element *E=selitems.front();E;E=E->next()) { + + _append_canvas_item(E->get()); + } + + } + + box_selecting=false; + viewport->update(); + + return true; +} +#endif + +void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) { + + hb->add_child(p_control); +} + +HSplitContainer *CanvasItemEditor::get_palette_split() { + + return palette_split; +} + +VSplitContainer *CanvasItemEditor::get_bottom_split() { + + return bottom_split; +} + + +void CanvasItemEditor::focus_selection() { + _focus_selection(VIEW_CENTER_TO_SELECTION); +} + + +CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { + + tool = TOOL_SELECT; + undo_redo=p_editor->get_undo_redo(); + editor=p_editor; + editor_selection=p_editor->get_editor_selection(); + editor_selection->add_editor_plugin(this); + editor_selection->connect("selection_changed",this,"update"); + + + hb = memnew( HBoxContainer ); + add_child( hb ); + hb->set_area_as_parent_rect(); + + bottom_split = memnew( VSplitContainer ); + bottom_split->set_v_size_flags(SIZE_EXPAND_FILL); + add_child(bottom_split); + + palette_split = memnew( HSplitContainer); + palette_split->set_v_size_flags(SIZE_EXPAND_FILL); + bottom_split->add_child(palette_split); + + Control *vp_base = memnew (Control); + vp_base->set_v_size_flags(SIZE_EXPAND_FILL); + palette_split->add_child(vp_base); + + ViewportContainer *vp = memnew (ViewportContainer); + vp->set_stretch(true); + vp_base->add_child(vp); + vp->set_area_as_parent_rect(); + vp->add_child(p_editor->get_scene_root()); + + + viewport = memnew( CanvasItemEditorViewport(p_editor, this) ); + vp_base->add_child(viewport); + viewport->set_area_as_parent_rect(); + viewport->set_clip_contents(true); + + h_scroll = memnew( HScrollBar ); + v_scroll = memnew( VScrollBar ); + + viewport->add_child(h_scroll); + viewport->add_child(v_scroll); + viewport->connect("draw",this,"_viewport_draw"); + viewport->connect("gui_input",this,"_viewport_gui_input"); + + + h_scroll->connect("value_changed", this,"_update_scroll",Vector<Variant>(),Object::CONNECT_DEFERRED); + v_scroll->connect("value_changed", this,"_update_scroll",Vector<Variant>(),Object::CONNECT_DEFERRED); + + h_scroll->hide(); + v_scroll->hide(); + updating_scroll=false; + viewport->set_focus_mode(FOCUS_ALL); + handle_len=10; + first_update=true; + + + select_button = memnew( ToolButton ); + select_button->set_toggle_mode(true); + hb->add_child(select_button); + select_button->connect("pressed",this,"_tool_select",make_binds(TOOL_SELECT)); + select_button->set_pressed(true); + select_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/select_mode",TTR("Select Mode"),KEY_Q)); + select_button->set_tooltip(TTR("Select Mode")+" $sc\n"+keycode_get_string(KEY_MASK_CMD)+TTR("Drag: Rotate")+"\n"+TTR("Alt+Drag: Move")+"\n"+TTR("Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving).")+"\n"+TTR("Alt+RMB: Depth list selection")); + + + move_button = memnew( ToolButton ); + move_button->set_toggle_mode(true); + hb->add_child(move_button); + move_button->connect("pressed",this,"_tool_select",make_binds(TOOL_MOVE)); + move_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/move_mode",TTR("Move Mode"),KEY_W)); + move_button->set_tooltip(TTR("Move Mode")); + + rotate_button = memnew( ToolButton ); + rotate_button->set_toggle_mode(true); + hb->add_child(rotate_button); + rotate_button->connect("pressed",this,"_tool_select",make_binds(TOOL_ROTATE)); + rotate_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/rotate_mode",TTR("Rotate Mode"),KEY_E)); + rotate_button->set_tooltip(TTR("Rotate Mode")); + + hb->add_child(memnew(VSeparator)); + + list_select_button = memnew( ToolButton ); + list_select_button->set_toggle_mode(true); + hb->add_child(list_select_button); + list_select_button->connect("pressed",this,"_tool_select",make_binds(TOOL_LIST_SELECT)); + list_select_button->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode).")); + + pivot_button = memnew( ToolButton ); + pivot_button->set_toggle_mode(true); + hb->add_child(pivot_button); + pivot_button->connect("pressed",this,"_tool_select",make_binds(TOOL_EDIT_PIVOT)); + pivot_button->set_tooltip(TTR("Click to change object's rotation pivot.")); + + pan_button = memnew( ToolButton ); + pan_button->set_toggle_mode(true); + hb->add_child(pan_button); + pan_button->connect("pressed",this,"_tool_select",make_binds(TOOL_PAN)); + pan_button->set_tooltip(TTR("Pan Mode")); + + hb->add_child(memnew(VSeparator)); + + lock_button = memnew( ToolButton ); + hb->add_child(lock_button); + + lock_button->connect("pressed",this,"_popup_callback",varray(LOCK_SELECTED)); + lock_button->set_tooltip(TTR("Lock the selected object in place (can't be moved).")); + + unlock_button = memnew( ToolButton ); + hb->add_child(unlock_button); + unlock_button->connect("pressed",this,"_popup_callback",varray(UNLOCK_SELECTED)); + unlock_button->set_tooltip(TTR("Unlock the selected object (can be moved).")); + + group_button = memnew( ToolButton ); + hb->add_child(group_button); + group_button->connect("pressed",this,"_popup_callback",varray(GROUP_SELECTED)); + group_button->set_tooltip(TTR("Makes sure the object's children are not selectable.")); + + ungroup_button = memnew( ToolButton ); + hb->add_child(ungroup_button); + ungroup_button->connect("pressed",this,"_popup_callback",varray(UNGROUP_SELECTED)); + ungroup_button->set_tooltip(TTR("Restores the object's children's ability to be selected.")); + + hb->add_child(memnew(VSeparator)); + + edit_menu = memnew( MenuButton ); + edit_menu->set_text(TTR("Edit")); + hb->add_child(edit_menu); + edit_menu->get_popup()->connect("id_pressed", this,"_popup_callback"); + + PopupMenu *p; + p = edit_menu->get_popup(); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_snap", TTR("Use Snap")), SNAP_USE); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_grid", TTR("Show Grid")), SNAP_SHOW_GRID); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_relative", TTR("Snap Relative")), SNAP_RELATIVE); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/configure_snap", TTR("Configure Snap..")), SNAP_CONFIGURE); + p->add_separator(); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL); + p->add_separator(); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/expand_to_parent", TTR("Expand to Parent"), KEY_MASK_CMD | KEY_P), EXPAND_TO_PARENT); + p->add_separator(); + p->add_submenu_item(TTR("Skeleton.."),"skeleton"); + skeleton_menu = memnew(PopupMenu); + p->add_child(skeleton_menu); + skeleton_menu->set_name("skeleton"); + skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Bones"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B ),SKELETON_MAKE_BONES); + skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_bones", TTR("Clear Bones")), SKELETON_CLEAR_BONES); + skeleton_menu->add_separator(); + skeleton_menu->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_show_bones", TTR("Show Bones")), SKELETON_SHOW_BONES); + skeleton_menu->add_separator(); + skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_set_ik_chain", TTR("Make IK Chain")), SKELETON_SET_IK_CHAIN); + skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_ik_chain", TTR("Clear IK Chain")), SKELETON_CLEAR_IK_CHAIN); + skeleton_menu->connect("id_pressed", this,"_popup_callback"); + + + /* + p->add_item("Align Horizontal",ALIGN_HORIZONTAL); + p->add_item("Align Vertical",ALIGN_VERTICAL); + p->add_item("Space Horizontal",SPACE_HORIZONTAL); + p->add_item("Space Vertical",SPACE_VERTICAL);*/ + + view_menu = memnew( MenuButton ); + view_menu->set_text(TTR("View")); + hb->add_child(view_menu); + view_menu->get_popup()->connect("id_pressed", this,"_popup_callback"); + + p = view_menu->get_popup(); + + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_in", TTR("Zoom In")), ZOOM_IN); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_out", TTR("Zoom Out")), ZOOM_OUT); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", TTR("Zoom Reset")), ZOOM_RESET); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_set", TTR("Zoom Set..")), ZOOM_SET); + p->add_separator(); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/center_selection", TTR("Center Selection"), KEY_F), VIEW_CENTER_TO_SELECTION); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTR("Frame Selection"), KEY_MASK_SHIFT | KEY_F), VIEW_FRAME_TO_SELECTION); + + anchor_menu = memnew( MenuButton ); + anchor_menu->set_text(TTR("Anchor")); + hb->add_child(anchor_menu); + anchor_menu->get_popup()->connect("id_pressed", this,"_popup_callback"); + anchor_menu->hide(); + + //p = anchor_menu->get_popup(); + + + + animation_hb = memnew( HBoxContainer ); + hb->add_child(animation_hb); + animation_hb->add_child( memnew( VSeparator )); + animation_hb->hide(); + + key_loc_button = memnew( Button("loc")); + key_loc_button->set_toggle_mode(true); + key_loc_button->set_pressed(true); + key_loc_button->set_focus_mode(FOCUS_NONE); + key_loc_button->add_color_override("font_color",Color(1,0.6,0.6)); + key_loc_button->add_color_override("font_color_pressed",Color(0.6,1,0.6)); + key_loc_button->connect("pressed",this,"_popup_callback",varray(ANIM_INSERT_POS)); + animation_hb->add_child(key_loc_button); + key_rot_button = memnew( Button("rot")); + key_rot_button->set_toggle_mode(true); + key_rot_button->set_pressed(true); + key_rot_button->set_focus_mode(FOCUS_NONE); + key_rot_button->add_color_override("font_color",Color(1,0.6,0.6)); + key_rot_button->add_color_override("font_color_pressed",Color(0.6,1,0.6)); + key_rot_button->connect("pressed",this,"_popup_callback",varray(ANIM_INSERT_ROT)); + animation_hb->add_child(key_rot_button); + key_scale_button = memnew( Button("scl")); + key_scale_button->set_toggle_mode(true); + key_scale_button->set_focus_mode(FOCUS_NONE); + key_scale_button->add_color_override("font_color",Color(1,0.6,0.6)); + key_scale_button->add_color_override("font_color_pressed",Color(0.6,1,0.6)); + key_scale_button->connect("pressed",this,"_popup_callback",varray(ANIM_INSERT_SCALE)); + animation_hb->add_child(key_scale_button); + key_insert_button = memnew( Button ); + key_insert_button->set_focus_mode(FOCUS_NONE); + key_insert_button->connect("pressed",this,"_popup_callback",varray(ANIM_INSERT_KEY)); + key_insert_button->set_tooltip(TTR("Insert Keys")); + key_insert_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/anim_insert_key", TTR("Insert Key"), KEY_INSERT)); + + animation_hb->add_child(key_insert_button); + + animation_menu = memnew( MenuButton ); + animation_menu->set_text(TTR("Animation")); + animation_hb->add_child(animation_menu); + animation_menu->get_popup()->connect("id_pressed", this,"_popup_callback"); + + p = animation_menu->get_popup(); + + p->add_shortcut(ED_GET_SHORTCUT("canvas_item_editor/anim_insert_key"), ANIM_INSERT_KEY); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_insert_key_existing_tracks", TTR("Insert Key (Existing Tracks)"), KEY_MASK_CMD+KEY_INSERT), ANIM_INSERT_KEY_EXISTING); + p->add_separator(); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_copy_pose", TTR("Copy Pose")), ANIM_COPY_POSE); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_paste_pose", TTR("Paste Pose")), ANIM_PASTE_POSE); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_clear_pose", TTR("Clear Pose"), KEY_MASK_SHIFT | KEY_K), ANIM_CLEAR_POSE); + + snap_dialog = memnew( SnapDialog ); + snap_dialog->connect("confirmed",this,"_snap_changed"); + add_child(snap_dialog); + + value_dialog = memnew( AcceptDialog ); + value_dialog->set_title(TTR("Set a Value")); + value_dialog->get_ok()->set_text(TTR("Close")); + add_child(value_dialog); + + Label *l = memnew(Label); + l->set_text(TTR("Snap (Pixels):")); + l->set_pos(Point2(5,5)); + value_dialog->add_child(l); + dialog_label=l; + + dialog_val=memnew(SpinBox); + dialog_val->set_anchor(MARGIN_RIGHT,ANCHOR_END); + dialog_val->set_begin(Point2(15,25)); + dialog_val->set_end(Point2(10,25)); + value_dialog->add_child(dialog_val); + dialog_val->connect("value_changed",this,"_dialog_value_changed"); + select_sb = Ref<StyleBoxTexture>( memnew( StyleBoxTexture) ); + + selection_menu = memnew( PopupMenu ); + add_child(selection_menu); + selection_menu->set_custom_minimum_size(Vector2(100, 0)); + selection_menu->connect("id_pressed", this, "_selection_result_pressed"); + selection_menu->connect("popup_hide", this, "_selection_menu_hide"); + + key_pos=true; + key_rot=true; + key_scale=false; + + zoom=1; + snap_offset=Vector2(0, 0); + snap_step=Vector2(10, 10); + snap_rotation_offset=0; + snap_rotation_step=15 / (180 / Math_PI); + snap_grid=false; + snap_show_grid=false; + snap_rotation=false; + snap_pixel=false; + skeleton_show_bones=true; + skeleton_menu->set_item_checked(skeleton_menu->get_item_index(SKELETON_SHOW_BONES),true); + updating_value_dialog=false; + box_selecting=false; + //zoom=0.5; + singleton=this; + + set_process_unhandled_key_input(true); + can_move_pivot=false; + drag=DRAG_NONE; + bone_last_frame=0; + additive_selection=false; +} + +CanvasItemEditor *CanvasItemEditor::singleton=NULL; + +void CanvasItemEditorPlugin::edit(Object *p_object) { + + canvas_item_editor->set_undo_redo(&get_undo_redo()); + canvas_item_editor->edit(p_object->cast_to<CanvasItem>()); +} + +bool CanvasItemEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("CanvasItem"); +} + +void CanvasItemEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + canvas_item_editor->show(); + canvas_item_editor->set_fixed_process(true); + VisualServer::get_singleton()->viewport_set_hide_canvas(editor->get_scene_root()->get_viewport_rid(),false); + canvas_item_editor->viewport->grab_focus(); + + } else { + + canvas_item_editor->hide(); + canvas_item_editor->set_fixed_process(false); + VisualServer::get_singleton()->viewport_set_hide_canvas(editor->get_scene_root()->get_viewport_rid(),true); + } + +} + +Dictionary CanvasItemEditorPlugin::get_state() const { + + return canvas_item_editor->get_state(); +} +void CanvasItemEditorPlugin::set_state(const Dictionary& p_state) { + + canvas_item_editor->set_state(p_state); +} + +CanvasItemEditorPlugin::CanvasItemEditorPlugin(EditorNode *p_node) { + + editor=p_node; + canvas_item_editor = memnew( CanvasItemEditor(editor) ); + canvas_item_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); + editor->get_viewport()->add_child(canvas_item_editor); + canvas_item_editor->set_area_as_parent_rect(); + canvas_item_editor->hide(); + +} + + +CanvasItemEditorPlugin::~CanvasItemEditorPlugin() +{ +} + + +void CanvasItemEditorViewport::_on_mouse_exit() { + if (!selector->is_visible()){ + _remove_preview(); + } +} + +void CanvasItemEditorViewport::_on_select_type(Object* selected) { + CheckBox* check = selected->cast_to<CheckBox>(); + String type = check->get_text(); + selector_label->set_text(vformat(TTR("Add %s"),type)); + label->set_text(vformat(TTR("Adding %s..."),type)); +} + +void CanvasItemEditorViewport::_on_change_type() { + if (!button_group->get_pressed_button()) + return; + + CheckBox* check=button_group->get_pressed_button()->cast_to<CheckBox>(); + default_type=check->get_text(); + _perform_drop_data(); + selector->hide(); +} + +void CanvasItemEditorViewport::_create_preview(const Vector<String>& files) const { + label->set_pos(get_global_pos()+Point2(14,14)); + label_desc->set_pos(label->get_pos()+Point2(0,label->get_size().height)); + for (int i=0;i<files.size();i++) { + String path=files[i]; + RES res=ResourceLoader::load(path); + String type=res->get_class(); + if (type=="ImageTexture" || type=="PackedScene") { + if (type=="ImageTexture") { + Ref<ImageTexture> texture=Ref<ImageTexture> ( ResourceCache::get(path)->cast_to<ImageTexture>() ); + Sprite* sprite=memnew(Sprite); + sprite->set_texture(texture); + sprite->set_modulate(Color(1,1,1,0.7f)); + preview->add_child(sprite); + label->show(); + label_desc->show(); + } else if (type=="PackedScene") { + Ref<PackedScene> scn=ResourceLoader::load(path); + if (scn.is_valid()){ + Node* instance=scn->instance(); + if (instance){ + preview->add_child(instance); + } + } + } + editor->get_scene_root()->add_child(preview); + } + } +} + +void CanvasItemEditorViewport::_remove_preview() { + if (preview->get_parent()){ + editor->get_scene_root()->remove_child(preview); + for (int i=preview->get_child_count()-1;i>=0;i--){ + Node* node=preview->get_child(i); + memdelete(node); + } + label->hide(); + label_desc->hide(); + } +} + +bool CanvasItemEditorViewport::_cyclical_dependency_exists(const String& p_target_scene_path, Node* p_desired_node) { + if (p_desired_node->get_filename()==p_target_scene_path) { + return true; + } + + int childCount=p_desired_node->get_child_count(); + for (int i=0;i<childCount;i++) { + Node* child=p_desired_node->get_child(i); + if(_cyclical_dependency_exists(p_target_scene_path,child)) { + return true; + } + } + return false; +} + +void CanvasItemEditorViewport::_create_nodes(Node* parent, Node* child, String& path, const Point2& p_point) { + child->set_name(path.get_file().get_basename()); + Ref<ImageTexture> texture=Ref<ImageTexture> ( ResourceCache::get(path)->cast_to<ImageTexture>() ); + Size2 texture_size = texture->get_size(); + + editor_data->get_undo_redo().add_do_method(parent,"add_child",child); + editor_data->get_undo_redo().add_do_method(child,"set_owner",editor->get_edited_scene()); + editor_data->get_undo_redo().add_do_reference(child); + editor_data->get_undo_redo().add_undo_method(parent,"remove_child",child); + + String new_name=parent->validate_child_name(child); + ScriptEditorDebugger *sed=ScriptEditor::get_singleton()->get_debugger(); + editor_data->get_undo_redo().add_do_method(sed,"live_debug_create_node",editor->get_edited_scene()->get_path_to(parent),child->get_class(),new_name); + editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(editor->get_edited_scene()->get_path_to(parent))+"/"+new_name)); + + // handle with different property for texture + String property = "texture"; + List<PropertyInfo> props; + child->get_property_list(&props); + for(const List<PropertyInfo>::Element *E=props.front();E;E=E->next() ) { + if (E->get().name=="config/texture") { // Particles2D + property="config/texture"; + break; + } else if (E->get().name=="texture/texture") { // Polygon2D + property="texture/texture"; + break; + } else if (E->get().name=="normal") { // TouchScreenButton + property="normal"; + break; + } + } + editor_data->get_undo_redo().add_do_property(child,property,texture); + + // make visible for certain node type + if (default_type=="Patch9Rect") { + editor_data->get_undo_redo().add_do_property(child,"rect/size",texture_size); + } else if (default_type=="Polygon2D") { + PoolVector<Vector2> list; + list.push_back(Vector2(0,0)); + list.push_back(Vector2(texture_size.width,0)); + list.push_back(Vector2(texture_size.width,texture_size.height)); + list.push_back(Vector2(0,texture_size.height)); + editor_data->get_undo_redo().add_do_property(child,"polygon",list); + } + + // locate at preview position + Point2 pos; + if (parent->has_method("get_global_pos")) { + pos=parent->call("get_global_pos"); + } + Transform2D trans=canvas->get_canvas_transform(); + Point2 target_pos = (p_point-trans.get_origin())/trans.get_scale().x-pos; + if (default_type=="Polygon2D" || default_type=="TouchScreenButton" || default_type=="TextureRect" || default_type=="Patch9Rect") { + target_pos -= texture_size/2; + } + editor_data->get_undo_redo().add_do_method(child,"set_pos",target_pos); +} + +bool CanvasItemEditorViewport::_create_instance(Node* parent, String& path, const Point2& p_point) { + Ref<PackedScene> sdata=ResourceLoader::load(path); + if (!sdata.is_valid()) { // invalid scene + return false; + } + + Node* instanced_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); + if (!instanced_scene) { // error on instancing + return false; + } + + if (editor->get_edited_scene()->get_filename()!="") { // cyclical instancing + if (_cyclical_dependency_exists(editor->get_edited_scene()->get_filename(), instanced_scene)) { + memdelete(instanced_scene); + return false; + } + } + + instanced_scene->set_filename( GlobalConfig::get_singleton()->localize_path(path) ); + + editor_data->get_undo_redo().add_do_method(parent,"add_child",instanced_scene); + editor_data->get_undo_redo().add_do_method(instanced_scene,"set_owner",editor->get_edited_scene()); + editor_data->get_undo_redo().add_do_reference(instanced_scene); + editor_data->get_undo_redo().add_undo_method(parent,"remove_child",instanced_scene); + + String new_name=parent->validate_child_name(instanced_scene); + ScriptEditorDebugger *sed=ScriptEditor::get_singleton()->get_debugger(); + editor_data->get_undo_redo().add_do_method(sed,"live_debug_instance_node",editor->get_edited_scene()->get_path_to(parent),path,new_name); + editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(editor->get_edited_scene()->get_path_to(parent))+"/"+new_name)); + + Point2 pos; + Node2D* parent_node2d=parent->cast_to<Node2D>(); + if (parent_node2d) { + pos=parent_node2d->get_global_position(); + } else { + Control* parent_control=parent->cast_to<Control>(); + if (parent_control) { + pos=parent_control->get_global_pos(); + } + } + Transform2D trans=canvas->get_canvas_transform(); + editor_data->get_undo_redo().add_do_method(instanced_scene,"set_pos",(p_point-trans.get_origin())/trans.get_scale().x-pos); + + return true; +} + +void CanvasItemEditorViewport::_perform_drop_data(){ + _remove_preview(); + + Vector<String> error_files; + + editor_data->get_undo_redo().create_action(TTR("Create Node")); + + for (int i=0;i<selected_files.size();i++) { + String path=selected_files[i]; + RES res=ResourceLoader::load(path); + if (res.is_null()) { + continue; + } + String type=res->get_class(); + if (type=="ImageTexture") { + Node* child; + if (default_type=="Light2D") child=memnew(Light2D); + else if (default_type=="Particles2D") child=memnew(Particles2D); + else if (default_type=="Polygon2D") child=memnew(Polygon2D); + else if (default_type=="TouchScreenButton") child=memnew(TouchScreenButton); + else if (default_type=="TextureRect") child=memnew(TextureRect); + else if (default_type=="Patch9Rect") child=memnew(NinePatchRect); + else child=memnew(Sprite); // default + + _create_nodes(target_node, child, path, drop_pos); + } else if (type=="PackedScene") { + bool success=_create_instance(target_node, path, drop_pos); + if (!success) { + error_files.push_back(path); + } + } + } + + editor_data->get_undo_redo().commit_action(); + + if (error_files.size()>0) { + String files_str; + for (int i=0;i<error_files.size();i++) { + files_str += error_files[i].get_file().get_basename() + ","; + } + files_str=files_str.substr(0,files_str.length()-1); + accept->get_ok()->set_text(TTR("Ugh")); + accept->set_text(vformat(TTR("Error instancing scene from %s"),files_str.c_str())); + accept->popup_centered_minsize(); + } +} + +bool CanvasItemEditorViewport::can_drop_data(const Point2& p_point,const Variant& p_data) const { + Dictionary d=p_data; + if (d.has("type")) { + if (String(d["type"])=="files") { + Vector<String> files=d["files"]; + bool can_instance=false; + for (int i=0;i<files.size();i++) { // check if dragged files contain resource or scene can be created at least one + RES res=ResourceLoader::load(files[i]); + if (res.is_null()) { + continue; + } + String type=res->get_class(); + if (type=="PackedScene") { + Ref<PackedScene> sdata=ResourceLoader::load(files[i]); + Node* instanced_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); + if (!instanced_scene) { + continue; + } + memdelete(instanced_scene); + } + can_instance=true; + break; + } + if (can_instance) { + if (!preview->get_parent()){ // create preview only once + _create_preview(files); + } + Transform2D trans=canvas->get_canvas_transform(); + preview->set_position((p_point-trans.get_origin())/trans.get_scale().x); + label->set_text(vformat(TTR("Adding %s..."),default_type)); + } + return can_instance; + } + } + label->hide(); + return false; +} + +void CanvasItemEditorViewport::drop_data(const Point2& p_point,const Variant& p_data) { + bool is_shift=Input::get_singleton()->is_key_pressed(KEY_SHIFT); + bool is_alt=Input::get_singleton()->is_key_pressed(KEY_ALT); + + selected_files.clear(); + Dictionary d=p_data; + if (d.has("type") && String(d["type"])=="files"){ + selected_files=d["files"]; + } + + List<Node*> list=editor->get_editor_selection()->get_selected_node_list(); + if (list.size()==0) { + accept->get_ok()->set_text(TTR("OK :(")); + accept->set_text(TTR("No parent to instance a child at.")); + accept->popup_centered_minsize(); + _remove_preview(); + return; + } + if (list.size()!=1) { + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("This operation requires a single selected node.")); + accept->popup_centered_minsize(); + _remove_preview(); + return; + } + + target_node=list[0]; + if (is_shift && target_node!=editor->get_edited_scene()) { + target_node=target_node->get_parent(); + } + drop_pos=p_point; + + if (is_alt) { + List<BaseButton*> btn_list; + button_group->get_buttons(&btn_list); + + for (int i=0;i<btn_list.size();i++) { + CheckBox* check=btn_list[i]->cast_to<CheckBox>(); + check->set_pressed(check->get_text()==default_type); + } + selector_label->set_text(vformat(TTR("Add %s"),default_type)); + selector->popup_centered_minsize(); + } else { + _perform_drop_data(); + } +} + +void CanvasItemEditorViewport::_notification(int p_what) { + if (p_what==NOTIFICATION_ENTER_TREE) { + connect("mouse_exited",this,"_on_mouse_exit"); + } else if (p_what==NOTIFICATION_EXIT_TREE) { + disconnect("mouse_exited",this,"_on_mouse_exit"); + } +} + +void CanvasItemEditorViewport::_bind_methods() { + ClassDB::bind_method(D_METHOD("_on_select_type"),&CanvasItemEditorViewport::_on_select_type); + ClassDB::bind_method(D_METHOD("_on_change_type"),&CanvasItemEditorViewport::_on_change_type); + ClassDB::bind_method(D_METHOD("_on_mouse_exit"),&CanvasItemEditorViewport::_on_mouse_exit); +} + +CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasItemEditor* p_canvas) { + default_type="Sprite"; + // Node2D + types.push_back("Sprite"); + types.push_back("Light2D"); + types.push_back("Particles2D"); + types.push_back("Polygon2D"); + types.push_back("TouchScreenButton"); + // Control + types.push_back("TextureRect"); + types.push_back("Patch9Rect"); + + target_node=NULL; + editor=p_node; + editor_data=editor->get_scene_tree_dock()->get_editor_data(); + canvas=p_canvas; + preview=memnew( Node2D ); + accept=memnew( AcceptDialog ); + editor->get_gui_base()->add_child(accept); + + selector=memnew( WindowDialog ); + selector->set_title(TTR("Change default type")); + + VBoxContainer* vbc=memnew(VBoxContainer); + vbc->add_constant_override("separation",10*EDSCALE); + vbc->set_custom_minimum_size(Size2(200,260)*EDSCALE); + + selector_label=memnew(Label); + selector_label->set_align(Label::ALIGN_CENTER); + selector_label->set_valign(Label::VALIGN_BOTTOM); + selector_label->set_custom_minimum_size(Size2(0,30)*EDSCALE); + vbc->add_child(selector_label); + + button_group.instance(); + + btn_group=memnew( VBoxContainer ); + btn_group->set_h_size_flags(0); + btn_group->connect("button_selected", this, "_on_select_type"); + + for (int i=0;i<types.size();i++) { + CheckBox* check=memnew(CheckBox); + check->set_text(types[i]); + btn_group->add_child(check); + check->set_button_group(button_group); + } + vbc->add_child(btn_group); + + Button* ok=memnew(Button); + ok->set_text(TTR("OK")); + ok->set_h_size_flags(0); + vbc->add_child(ok); + ok->connect("pressed", this, "_on_change_type"); + + selector->add_child(vbc); + editor->get_gui_base()->add_child(selector); + + label=memnew(Label); + label->add_color_override("font_color", Color(1,1,0,1)); + label->add_color_override("font_color_shadow", Color(0,0,0,1)); + label->add_constant_override("shadow_as_outline", 1*EDSCALE); + label->hide(); + editor->get_gui_base()->add_child(label); + + label_desc=memnew(Label); + label_desc->set_text(TTR("Drag & drop + Shift : Add node as sibling\nDrag & drop + Alt : Change node type")); + label_desc->add_color_override("font_color", Color(0.6,0.6,0.6,1)); + label_desc->add_color_override("font_color_shadow", Color(0.2,0.2,0.2,1)); + label_desc->add_constant_override("shadow_as_outline", 1*EDSCALE); + label_desc->add_constant_override("line_spacing", 0); + label_desc->hide(); + editor->get_gui_base()->add_child(label_desc); +} diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h new file mode 100644 index 0000000000..0c2dcdff3d --- /dev/null +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -0,0 +1,503 @@ +/*************************************************************************/ +/* canvas_item_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef CONTROL_EDITOR_PLUGIN_H +#define CONTROL_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/gui/button_group.h" +#include "scene/gui/check_box.h" +#include "scene/gui/label.h" +#include "scene/gui/spin_box.h" +#include "scene/gui/panel_container.h" +#include "scene/gui/box_container.h" +#include "scene/2d/canvas_item.h" +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +class CanvasItemEditorViewport; + +class CanvasItemEditorSelectedItem : public Object { + + GDCLASS(CanvasItemEditorSelectedItem,Object); +public: + Variant undo_state; + Vector2 undo_pivot; + + Transform2D prev_xform; + float prev_rot; + Rect2 prev_rect; + + CanvasItemEditorSelectedItem() { prev_rot=0; } +}; + +class CanvasItemEditor : public VBoxContainer { + + GDCLASS(CanvasItemEditor, VBoxContainer ); + + EditorNode *editor; + + + enum Tool { + + TOOL_SELECT, + TOOL_LIST_SELECT, + TOOL_MOVE, + TOOL_ROTATE, + TOOL_EDIT_PIVOT, + TOOL_PAN, + TOOL_MAX + }; + + enum MenuOption { + SNAP_USE, + SNAP_SHOW_GRID, + SNAP_USE_ROTATION, + SNAP_RELATIVE, + SNAP_CONFIGURE, + SNAP_USE_PIXEL, + ZOOM_IN, + ZOOM_OUT, + ZOOM_RESET, + ZOOM_SET, + LOCK_SELECTED, + UNLOCK_SELECTED, + GROUP_SELECTED, + UNGROUP_SELECTED, + ALIGN_HORIZONTAL, + ALIGN_VERTICAL, + ANCHOR_ALIGN_TOP_LEFT, + ANCHOR_ALIGN_TOP_RIGHT, + ANCHOR_ALIGN_BOTTOM_LEFT, + ANCHOR_ALIGN_BOTTOM_RIGHT, + ANCHOR_ALIGN_CENTER_LEFT, + ANCHOR_ALIGN_CENTER_RIGHT, + ANCHOR_ALIGN_CENTER_TOP, + ANCHOR_ALIGN_CENTER_BOTTOM, + ANCHOR_ALIGN_CENTER, + ANCHOR_ALIGN_TOP_WIDE, + ANCHOR_ALIGN_LEFT_WIDE, + ANCHOR_ALIGN_RIGHT_WIDE, + ANCHOR_ALIGN_BOTTOM_WIDE, + ANCHOR_ALIGN_VCENTER_WIDE, + ANCHOR_ALIGN_HCENTER_WIDE, + ANCHOR_ALIGN_WIDE, + + SPACE_HORIZONTAL, + SPACE_VERTICAL, + EXPAND_TO_PARENT, + ANIM_INSERT_KEY, + ANIM_INSERT_KEY_EXISTING, + ANIM_INSERT_POS, + ANIM_INSERT_ROT, + ANIM_INSERT_SCALE, + ANIM_COPY_POSE, + ANIM_PASTE_POSE, + ANIM_CLEAR_POSE, + VIEW_CENTER_TO_SELECTION, + VIEW_FRAME_TO_SELECTION, + SKELETON_MAKE_BONES, + SKELETON_CLEAR_BONES, + SKELETON_SHOW_BONES, + SKELETON_SET_IK_CHAIN, + SKELETON_CLEAR_IK_CHAIN + + }; + + enum DragType { + DRAG_NONE, + DRAG_LEFT, + DRAG_TOP_LEFT, + DRAG_TOP, + DRAG_TOP_RIGHT, + DRAG_RIGHT, + DRAG_BOTTOM_RIGHT, + DRAG_BOTTOM, + DRAG_BOTTOM_LEFT, + DRAG_ALL, + DRAG_ROTATE, + DRAG_PIVOT, + + }; + + enum KeyMoveMODE { + MOVE_VIEW_BASE, + MOVE_LOCAL_BASE, + MOVE_LOCAL_WITH_ROT + }; + + EditorSelection *editor_selection; + bool additive_selection; + + Tool tool; + bool first_update; + Control *viewport; + + bool can_move_pivot; + + HScrollBar *h_scroll; + VScrollBar *v_scroll; + HBoxContainer *hb; + + Transform2D transform; + float zoom; + Vector2 snap_offset; + Vector2 snap_step; + float snap_rotation_step; + float snap_rotation_offset; + bool snap_grid; + bool snap_show_grid; + bool snap_rotation; + bool snap_relative; + bool snap_pixel; + bool skeleton_show_bones; + bool box_selecting; + Point2 box_selecting_to; + bool key_pos; + bool key_rot; + bool key_scale; + + void _tool_select(int p_index); + + + MenuOption last_option; + + struct _SelectResult { + + CanvasItem* item; + float z; + bool has_z; + _FORCE_INLINE_ bool operator<(const _SelectResult& p_rr) const { + return has_z && p_rr.has_z ? p_rr.z < z : p_rr.has_z; + } + }; + + Vector<_SelectResult> selection_results; + + struct LockList { + Point2 pos; + bool lock; + bool group; + LockList() { lock=false; group=false; } + }; + + List<LockList> lock_list; + + struct BoneList { + + Transform2D xform; + Vector2 from; + Vector2 to; + ObjectID bone; + uint64_t last_pass; + }; + + uint64_t bone_last_frame; + Map<ObjectID,BoneList> bone_list; + + Transform2D bone_orig_xform; + + struct BoneIK { + + Variant orig_state; + Vector2 pos; + float len; + Node2D *node; + }; + + List<BoneIK> bone_ik_list; + + struct PoseClipboard { + + Vector2 pos; + Vector2 scale; + float rot; + ObjectID id; + }; + + List<PoseClipboard> pose_clipboard; + + ToolButton *select_button; + ToolButton *list_select_button; + ToolButton *move_button; + ToolButton *rotate_button; + + ToolButton *pivot_button; + ToolButton *pan_button; + + ToolButton *lock_button; + ToolButton *unlock_button; + + ToolButton *group_button; + ToolButton *ungroup_button; + + MenuButton *edit_menu; + PopupMenu *skeleton_menu; + MenuButton *view_menu; + HBoxContainer *animation_hb; + MenuButton *animation_menu; + MenuButton *anchor_menu; + + Button *key_loc_button; + Button *key_rot_button; + Button *key_scale_button; + Button *key_insert_button; + + PopupMenu *selection_menu; + + + //PopupMenu *popup; + DragType drag; + Point2 drag_from; + Point2 drag_point_from; + bool updating_value_dialog; + Point2 display_rotate_from; + Point2 display_rotate_to; +#if 0 + struct EditInfo { + + Variant undo_state; + + Matrix32 prev_xform; + float prev_rot; + Rect2 prev_rect; + EditInfo() { prev_rot=0; } + }; + + typedef Map<CanvasItem*,EditInfo> CanvasItemMap; + CanvasItemMap canvas_items; +#endif + Ref<StyleBoxTexture> select_sb; + Ref<Texture> select_handle; + + + int handle_len; + bool _is_part_of_subscene(CanvasItem *p_item); + CanvasItem* _select_canvas_item_at_pos(const Point2 &p_pos,Node* p_node,const Transform2D& p_parent_xform,const Transform2D& p_canvas_xform); + void _find_canvas_items_at_pos(const Point2 &p_pos,Node* p_node,const Transform2D& p_parent_xform,const Transform2D& p_canvas_xform, Vector<_SelectResult> &r_items); + void _find_canvas_items_at_rect(const Rect2& p_rect,Node* p_node,const Transform2D& p_parent_xform,const Transform2D& p_canvas_xform,List<CanvasItem*> *r_items); + + bool _select(CanvasItem *item, Point2 p_click_pos, bool p_append, bool p_drag=true); + + ConfirmationDialog *snap_dialog; + + AcceptDialog *value_dialog; + Label *dialog_label; + SpinBox *dialog_val; + + CanvasItem *ref_item; + + void _edit_set_pivot(const Vector2& mouse_pos); + void _add_canvas_item(CanvasItem *p_canvas_item); + void _remove_canvas_item(CanvasItem *p_canvas_item); + void _clear_canvas_items(); + void _visibility_changed(ObjectID p_canvas_item); + void _key_move(const Vector2& p_dir, bool p_snap, KeyMoveMODE p_move_mode); + void _list_select(const InputEventMouseButton& b); + + DragType _find_drag_type(const Transform2D& p_xform, const Rect2& p_local_rect, const Point2& p_click, Vector2& r_point); + + void _popup_callback(int p_op); + bool updating_scroll; + void _update_scroll(float); + void _update_scrollbars(); + void incbeg(float& beg,float& end, float inc, float minsize,bool p_symmetric); + void incend(float& beg,float& end, float inc, float minsize,bool p_symmetric); + + void _append_canvas_item(CanvasItem *p_item); + void _dialog_value_changed(double); + void _snap_changed(); + void _selection_result_pressed(int); + void _selection_menu_hide(); + + UndoRedo *undo_redo; + + Point2 _find_topleftmost_point(); + + + void _find_canvas_items_span(Node *p_node, Rect2& r_rect, const Transform2D& p_xform); + + + Object *_get_editor_data(Object *p_what); + + CanvasItem *get_single_item(); + int get_item_count(); + void _keying_changed(); + + void _unhandled_key_input(const InputEvent& p_ev); + + void _viewport_gui_input(const InputEvent& p_event); + void _viewport_draw(); + + void _focus_selection(int p_op); + + void _set_anchor(Control::AnchorType p_left,Control::AnchorType p_top,Control::AnchorType p_right,Control::AnchorType p_bottom); + + HSplitContainer *palette_split; + VSplitContainer *bottom_split; + +friend class CanvasItemEditorPlugin; +protected: + + + void _notification(int p_what); + + void _node_removed(Node *p_node); + static void _bind_methods(); + void end_drag(); + void box_selection_start( Point2 &click ); + bool box_selection_end(); + + HBoxContainer *get_panel_hb() { return hb; } + + struct compare_items_x { + bool operator()( const CanvasItem *a, const CanvasItem *b ) const { + return a->get_global_transform().elements[2].x < b->get_global_transform().elements[2].x; + } + }; + + struct compare_items_y { + bool operator()( const CanvasItem *a, const CanvasItem *b ) const { + return a->get_global_transform().elements[2].y < b->get_global_transform().elements[2].y; + } + }; + + struct proj_vector2_x { + float get( const Vector2 &v ) { return v.x; } + void set( Vector2 &v, float f ) { v.x = f; } + }; + + struct proj_vector2_y { + float get( const Vector2 &v ) { return v.y; } + void set( Vector2 &v, float f ) { v.y = f; } + }; + + template< class P, class C > void space_selected_items(); + + static CanvasItemEditor *singleton; +public: + + Vector2 snap_point(Vector2 p_target, Vector2 p_start = Vector2(0, 0)) const; + float snap_angle(float p_target, float p_start = 0) const; + + Transform2D get_canvas_transform() const { return transform; } + + static CanvasItemEditor *get_singleton() { return singleton; } + Dictionary get_state() const; + void set_state(const Dictionary& p_state); + + void add_control_to_menu_panel(Control *p_control); + + HSplitContainer *get_palette_split(); + VSplitContainer *get_bottom_split(); + + Control *get_viewport_control() { return viewport; } + + bool get_remove_list(List<Node*> *p_list); + void set_undo_redo(UndoRedo *p_undo_redo) {undo_redo=p_undo_redo; } + void edit(CanvasItem *p_canvas_item); + + void focus_selection(); + + CanvasItemEditor(EditorNode *p_editor); +}; + +class CanvasItemEditorPlugin : public EditorPlugin { + + GDCLASS( CanvasItemEditorPlugin, EditorPlugin ); + + CanvasItemEditor *canvas_item_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "2D"; } + bool has_main_screen() const { return true; } + virtual void edit(Object *p_object); + virtual bool handles(Object *p_object) const; + virtual void make_visible(bool p_visible); + virtual bool get_remove_list(List<Node*> *p_list) { return canvas_item_editor->get_remove_list(p_list); } + virtual Dictionary get_state() const; + virtual void set_state(const Dictionary& p_state); + + CanvasItemEditor *get_canvas_item_editor() { return canvas_item_editor; } + + CanvasItemEditorPlugin(EditorNode *p_node); + ~CanvasItemEditorPlugin(); + +}; + +class CanvasItemEditorViewport : public Control { + GDCLASS( CanvasItemEditorViewport, Control ); + + String default_type; + Vector<String> types; + + Vector<String> selected_files; + Node* target_node; + Point2 drop_pos; + + EditorNode* editor; + EditorData* editor_data; + CanvasItemEditor* canvas; + Node2D* preview; + AcceptDialog* accept; + WindowDialog* selector; + Label* selector_label; + Label* label; + Label* label_desc; + VBoxContainer* btn_group; + Ref<ButtonGroup> button_group; + + void _on_mouse_exit(); + void _on_select_type(Object* selected); + void _on_change_type(); + + void _create_preview(const Vector<String>& files) const; + void _remove_preview(); + + bool _cyclical_dependency_exists(const String& p_target_scene_path, Node* p_desired_node); + void _create_nodes(Node* parent, Node* child, String& path, const Point2& p_point); + bool _create_instance(Node* parent, String& path, const Point2& p_point); + void _perform_drop_data(); + + static void _bind_methods(); + +protected: + void _notification(int p_what); + +public: + virtual bool can_drop_data(const Point2& p_point,const Variant& p_data) const; + virtual void drop_data(const Point2& p_point,const Variant& p_data); + + CanvasItemEditorViewport(EditorNode *p_node, CanvasItemEditor* p_canvas); +}; + +#endif diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/editor/plugins/collision_polygon_2d_editor_plugin.cpp new file mode 100644 index 0000000000..5a45267c85 --- /dev/null +++ b/editor/plugins/collision_polygon_2d_editor_plugin.cpp @@ -0,0 +1,482 @@ +/*************************************************************************/ +/* collision_polygon_2d_editor_plugin.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 "collision_polygon_2d_editor_plugin.h" + +#include "canvas_item_editor_plugin.h" +#include "os/file_access.h" +#include "editor/editor_settings.h" + + +void CollisionPolygon2DEditor::_notification(int p_what) { + + switch(p_what) { + + case NOTIFICATION_READY: { + + button_create->set_icon( get_icon("Edit","EditorIcons")); + button_edit->set_icon( get_icon("MovePoint","EditorIcons")); + button_edit->set_pressed(true); + get_tree()->connect("node_removed",this,"_node_removed"); + + } break; + case NOTIFICATION_FIXED_PROCESS: { + + + } break; + } + +} +void CollisionPolygon2DEditor::_node_removed(Node *p_node) { + + if(p_node==node) { + node=NULL; + hide(); + canvas_item_editor->get_viewport_control()->update(); + } + +} + + +void CollisionPolygon2DEditor::_menu_option(int p_option) { + + switch(p_option) { + + case MODE_CREATE: { + + mode=MODE_CREATE; + button_create->set_pressed(true); + button_edit->set_pressed(false); + } break; + case MODE_EDIT: { + + mode=MODE_EDIT; + button_create->set_pressed(false); + button_edit->set_pressed(true); + } break; + + } +} + +void CollisionPolygon2DEditor::_wip_close() { + + undo_redo->create_action(TTR("Create Poly")); + undo_redo->add_undo_method(node,"set_polygon",node->get_polygon()); + undo_redo->add_do_method(node,"set_polygon",wip); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + wip.clear(); + wip_active=false; + mode=MODE_EDIT; + button_edit->set_pressed(true); + button_create->set_pressed(false); + edited_point=-1; +} + +bool CollisionPolygon2DEditor::forward_gui_input(const InputEvent& p_event) { + + + if (!node) + return false; + + switch(p_event.type) { + + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &mb=p_event.mouse_button; + + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + + + Vector2 gpoint = Point2(mb.x,mb.y); + Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); + cpoint=canvas_item_editor->snap_point(cpoint); + cpoint = node->get_global_transform().affine_inverse().xform(cpoint); + + Vector<Vector2> poly = node->get_polygon(); + + //first check if a point is to be added (segment split) + real_t grab_treshold=EDITOR_DEF("editors/poly_editor/point_grab_radius",8); + + switch(mode) { + + + case MODE_CREATE: { + + if (mb.button_index==BUTTON_LEFT && mb.pressed) { + + + if (!wip_active) { + + wip.clear(); + wip.push_back( cpoint ); + wip_active=true; + edited_point_pos=cpoint; + canvas_item_editor->get_viewport_control()->update(); + edited_point=1; + return true; + } else { + + + if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) { + //wip closed + _wip_close(); + + return true; + } else { + + wip.push_back( cpoint ); + edited_point=wip.size(); + canvas_item_editor->get_viewport_control()->update(); + return true; + + //add wip point + } + } + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { + _wip_close(); + } + + + + } break; + + case MODE_EDIT: { + + if (mb.button_index==BUTTON_LEFT) { + if (mb.pressed) { + + if (mb.mod.control) { + + + if (poly.size() < 3) { + + undo_redo->create_action(TTR("Edit Poly")); + undo_redo->add_undo_method(node,"set_polygon",poly); + poly.push_back(cpoint); + undo_redo->add_do_method(node,"set_polygon",poly); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + return true; + } + + //search edges + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 points[2] ={ xform.xform(poly[i]), + xform.xform(poly[(i+1)%poly.size()]) }; + + Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points); + if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2) + continue; //not valid to reuse point + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + + } + + if (closest_idx>=0) { + + pre_move_edit=poly; + poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos)); + edited_point=closest_idx+1; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + node->set_polygon(poly); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } else { + + //look for points to move + + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 cp =xform.xform(poly[i]); + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + } + + if (closest_idx>=0) { + + pre_move_edit=poly; + edited_point=closest_idx; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } + } else { + + if (edited_point!=-1) { + + //apply + + ERR_FAIL_INDEX_V(edited_point,poly.size(),false); + poly[edited_point]=edited_point_pos; + undo_redo->create_action(TTR("Edit Poly")); + undo_redo->add_do_method(node,"set_polygon",poly); + undo_redo->add_undo_method(node,"set_polygon",pre_move_edit); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + + edited_point=-1; + return true; + } + } + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { + + + + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 cp =xform.xform(poly[i]); + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + } + + if (closest_idx>=0) { + + + undo_redo->create_action(TTR("Edit Poly (Remove Point)")); + undo_redo->add_undo_method(node,"set_polygon",poly); + poly.remove(closest_idx); + undo_redo->add_do_method(node,"set_polygon",poly); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + return true; + } + + } + + + + } break; + } + + + + } break; + case InputEvent::MOUSE_MOTION: { + + const InputEventMouseMotion &mm=p_event.mouse_motion; + + if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { + + Vector2 gpoint = Point2(mm.x,mm.y); + Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); + cpoint=canvas_item_editor->snap_point(cpoint); + edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint); + + canvas_item_editor->get_viewport_control()->update(); + + } + + } break; + } + + return false; +} +void CollisionPolygon2DEditor::_canvas_draw() { + + if (!node) + return; + + Control *vpc = canvas_item_editor->get_viewport_control(); + + Vector<Vector2> poly; + + if (wip_active) + poly=wip; + else + poly=node->get_polygon(); + + + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + Ref<Texture> handle= get_icon("EditorHandle","EditorIcons"); + + for(int i=0;i<poly.size();i++) { + + + Vector2 p,p2; + p = i==edited_point ? edited_point_pos : poly[i]; + if ((wip_active && i==poly.size()-1) || (((i+1)%poly.size())==edited_point)) + p2=edited_point_pos; + else + p2 = poly[(i+1)%poly.size()]; + + Vector2 point = xform.xform(p); + Vector2 next_point = xform.xform(p2); + + Color col=Color(1,0.3,0.1,0.8); + vpc->draw_line(point,next_point,col,2); + vpc->draw_texture(handle,point-handle->get_size()*0.5); + } +} + + + +void CollisionPolygon2DEditor::edit(Node *p_collision_polygon) { + + if (!canvas_item_editor) { + canvas_item_editor=CanvasItemEditor::get_singleton(); + } + + if (p_collision_polygon) { + + node=p_collision_polygon->cast_to<CollisionPolygon2D>(); + if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw"); + wip.clear(); + wip_active=false; + edited_point=-1; + canvas_item_editor->get_viewport_control()->update(); + + } else { + node=NULL; + + if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw"); + + } + +} + +void CollisionPolygon2DEditor::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_menu_option"),&CollisionPolygon2DEditor::_menu_option); + ClassDB::bind_method(D_METHOD("_canvas_draw"),&CollisionPolygon2DEditor::_canvas_draw); + ClassDB::bind_method(D_METHOD("_node_removed"),&CollisionPolygon2DEditor::_node_removed); + +} + +CollisionPolygon2DEditor::CollisionPolygon2DEditor(EditorNode *p_editor) { + + node=NULL; + canvas_item_editor=NULL; + editor=p_editor; + undo_redo = editor->get_undo_redo(); + + add_child( memnew( VSeparator )); + button_create = memnew( ToolButton ); + add_child(button_create); + button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE)); + button_create->set_toggle_mode(true); + button_create->set_tooltip(TTR("Create a new polygon from scratch.")); + + button_edit = memnew( ToolButton ); + add_child(button_edit); + button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT)); + button_edit->set_toggle_mode(true); + button_edit->set_tooltip("Edit existing polygon:\nLMB: Move Point.\nCtrl+LMB: Split Segment.\nRMB: Erase Point."); + + //add_constant_override("separation",0); + +#if 0 + options = memnew( MenuButton ); + add_child(options); + options->set_area_as_parent_rect(); + options->set_text("Polygon"); + //options->get_popup()->add_item("Parse BBCode",PARSE_BBCODE); + options->get_popup()->connect("id_pressed", this,"_menu_option"); +#endif + + mode = MODE_EDIT; + wip_active=false; + +} + + +void CollisionPolygon2DEditorPlugin::edit(Object *p_object) { + + collision_polygon_editor->edit(p_object->cast_to<Node>()); +} + +bool CollisionPolygon2DEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("CollisionPolygon2D"); +} + +void CollisionPolygon2DEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + collision_polygon_editor->show(); + } else { + + collision_polygon_editor->hide(); + collision_polygon_editor->edit(NULL); + } + +} + +CollisionPolygon2DEditorPlugin::CollisionPolygon2DEditorPlugin(EditorNode *p_node) { + + editor=p_node; + collision_polygon_editor = memnew( CollisionPolygon2DEditor(p_node) ); + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); + + collision_polygon_editor->hide(); + + + +} + + +CollisionPolygon2DEditorPlugin::~CollisionPolygon2DEditorPlugin() +{ +} + diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.h b/editor/plugins/collision_polygon_2d_editor_plugin.h new file mode 100644 index 0000000000..796328753d --- /dev/null +++ b/editor/plugins/collision_polygon_2d_editor_plugin.h @@ -0,0 +1,111 @@ +/*************************************************************************/ +/* collision_polygon_2d_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef COLLISION_POLYGON_2D_EDITOR_PLUGIN_H +#define COLLISION_POLYGON_2D_EDITOR_PLUGIN_H + + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/2d/collision_polygon_2d.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/button_group.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ +class CanvasItemEditor; + +class CollisionPolygon2DEditor : public HBoxContainer { + + GDCLASS(CollisionPolygon2DEditor, HBoxContainer ); + + UndoRedo *undo_redo; + enum Mode { + + MODE_CREATE, + MODE_EDIT, + + }; + + Mode mode; + + ToolButton *button_create; + ToolButton *button_edit; + + CanvasItemEditor *canvas_item_editor; + EditorNode *editor; + Panel *panel; + CollisionPolygon2D *node; + MenuButton *options; + + int edited_point; + Vector2 edited_point_pos; + Vector<Vector2> pre_move_edit; + Vector<Vector2> wip; + bool wip_active; + + + void _wip_close(); + void _canvas_draw(); + void _menu_option(int p_option); + +protected: + void _notification(int p_what); + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + bool forward_gui_input(const InputEvent& p_event); + void edit(Node *p_collision_polygon); + CollisionPolygon2DEditor(EditorNode *p_editor); +}; + +class CollisionPolygon2DEditorPlugin : public EditorPlugin { + + GDCLASS( CollisionPolygon2DEditorPlugin, EditorPlugin ); + + CollisionPolygon2DEditor *collision_polygon_editor; + EditorNode *editor; + +public: + + virtual bool forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); } + + virtual String get_name() const { return "CollisionPolygon2D"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + CollisionPolygon2DEditorPlugin(EditorNode *p_node); + ~CollisionPolygon2DEditorPlugin(); + +}; + +#endif // COLLISION_POLYGON_2D_EDITOR_PLUGIN_H diff --git a/editor/plugins/collision_polygon_editor_plugin.cpp b/editor/plugins/collision_polygon_editor_plugin.cpp new file mode 100644 index 0000000000..3aad53b420 --- /dev/null +++ b/editor/plugins/collision_polygon_editor_plugin.cpp @@ -0,0 +1,648 @@ +/*************************************************************************/ +/* collision_polygon_editor_plugin.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 "collision_polygon_editor_plugin.h" + +#include "spatial_editor_plugin.h" +#include "os/file_access.h" +#include "editor/editor_settings.h" +#include "scene/3d/camera.h" +#include "canvas_item_editor_plugin.h" + +#if 0 + +void CollisionPolygonEditor::_notification(int p_what) { + + switch(p_what) { + + case NOTIFICATION_READY: { + + button_create->set_icon( get_icon("Edit","EditorIcons")); + button_edit->set_icon( get_icon("MovePoint","EditorIcons")); + button_edit->set_pressed(true); + get_tree()->connect("node_removed",this,"_node_removed"); + + + } break; + case NOTIFICATION_PROCESS: { + + if (node->get_depth() != prev_depth) { + _polygon_draw(); + prev_depth=node->get_depth(); + } + + } break; + } + +} +void CollisionPolygonEditor::_node_removed(Node *p_node) { + + if(p_node==node) { + node=NULL; + if (imgeom->get_parent()==p_node) + p_node->remove_child(imgeom); + hide(); + set_process(false); + } + +} + + +void CollisionPolygonEditor::_menu_option(int p_option) { + + switch(p_option) { + + case MODE_CREATE: { + + mode=MODE_CREATE; + button_create->set_pressed(true); + button_edit->set_pressed(false); + } break; + case MODE_EDIT: { + + mode=MODE_EDIT; + button_create->set_pressed(false); + button_edit->set_pressed(true); + } break; + + } +} + +void CollisionPolygonEditor::_wip_close() { + + undo_redo->create_action(TTR("Create Poly3D")); + undo_redo->add_undo_method(node,"set_polygon",node->get_polygon()); + undo_redo->add_do_method(node,"set_polygon",wip); + undo_redo->add_do_method(this,"_polygon_draw"); + undo_redo->add_undo_method(this,"_polygon_draw"); + wip.clear(); + wip_active=false; + mode=MODE_EDIT; + button_edit->set_pressed(true); + button_create->set_pressed(false); + edited_point=-1; + undo_redo->commit_action(); + +} + +bool CollisionPolygonEditor::forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event) { + + if (!node) + return false; + + Transform gt = node->get_global_transform(); + Transform gi = gt.affine_inverse(); + float depth = node->get_depth()*0.5; + Vector3 n = gt.basis.get_axis(2).normalized(); + Plane p(gt.origin+n*depth,n); + + + switch(p_event.type) { + + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &mb=p_event.mouse_button; + + + + Vector2 gpoint=Point2(mb.x,mb.y); + Vector3 ray_from = p_camera->project_ray_origin(gpoint); + Vector3 ray_dir = p_camera->project_ray_normal(gpoint); + + Vector3 spoint; + + if (!p.intersects_ray(ray_from,ray_dir,&spoint)) + break; + + spoint = gi.xform(spoint); + + Vector2 cpoint(spoint.x,spoint.y); + + cpoint=CanvasItemEditor::get_singleton()->snap_point(cpoint); + + Vector<Vector2> poly = node->get_polygon(); + + //first check if a point is to be added (segment split) + real_t grab_treshold=EDITOR_DEF("editors/poly_editor/point_grab_radius",8); + + switch(mode) { + + + case MODE_CREATE: { + + if (mb.button_index==BUTTON_LEFT && mb.pressed) { + + + if (!wip_active) { + + wip.clear(); + wip.push_back( cpoint ); + wip_active=true; + edited_point_pos=cpoint; + _polygon_draw(); + edited_point=1; + return true; + } else { + + + if (wip.size()>1 && p_camera->unproject_position(gt.xform(Vector3(wip[0].x,wip[0].y,depth))).distance_to(gpoint)<grab_treshold) { + //wip closed + _wip_close(); + + return true; + } else { + + wip.push_back( cpoint ); + edited_point=wip.size(); + _polygon_draw(); + return true; + + //add wip point + } + } + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { + _wip_close(); + } + + + + } break; + + case MODE_EDIT: { + + if (mb.button_index==BUTTON_LEFT) { + if (mb.pressed) { + + if (mb.mod.control) { + + + if (poly.size() < 3) { + + undo_redo->create_action(TTR("Edit Poly")); + undo_redo->add_undo_method(node,"set_polygon",poly); + poly.push_back(cpoint); + undo_redo->add_do_method(node,"set_polygon",poly); + undo_redo->add_do_method(this,"_polygon_draw"); + undo_redo->add_undo_method(this,"_polygon_draw"); + undo_redo->commit_action(); + return true; + } + + //search edges + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 points[2] ={ + p_camera->unproject_position(gt.xform(Vector3(poly[i].x,poly[i].y,depth))), + p_camera->unproject_position(gt.xform(Vector3(poly[(i+1)%poly.size()].x,poly[(i+1)%poly.size()].y,depth))) + }; + + Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points); + if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2) + continue; //not valid to reuse point + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + + } + + if (closest_idx>=0) { + + pre_move_edit=poly; + poly.insert(closest_idx+1,cpoint); + edited_point=closest_idx+1; + edited_point_pos=cpoint; + node->set_polygon(poly); + _polygon_draw(); + return true; + } + } else { + + //look for points to move + + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x,poly[i].y,depth))); + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + } + + if (closest_idx>=0) { + + pre_move_edit=poly; + edited_point=closest_idx; + edited_point_pos=poly[closest_idx]; + _polygon_draw(); + return true; + } + } + } else { + + if (edited_point!=-1) { + + //apply + + ERR_FAIL_INDEX_V(edited_point,poly.size(),false); + poly[edited_point]=edited_point_pos; + undo_redo->create_action(TTR("Edit Poly")); + undo_redo->add_do_method(node,"set_polygon",poly); + undo_redo->add_undo_method(node,"set_polygon",pre_move_edit); + undo_redo->add_do_method(this,"_polygon_draw"); + undo_redo->add_undo_method(this,"_polygon_draw"); + undo_redo->commit_action(); + + edited_point=-1; + return true; + } + } + } if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { + + + + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x,poly[i].y,depth))); + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + } + + if (closest_idx>=0) { + + + undo_redo->create_action(TTR("Edit Poly (Remove Point)")); + undo_redo->add_undo_method(node,"set_polygon",poly); + poly.remove(closest_idx); + undo_redo->add_do_method(node,"set_polygon",poly); + undo_redo->add_do_method(this,"_polygon_draw"); + undo_redo->add_undo_method(this,"_polygon_draw"); + undo_redo->commit_action(); + return true; + } + + } + + + + } break; + } + + + + } break; + case InputEvent::MOUSE_MOTION: { + + const InputEventMouseMotion &mm=p_event.mouse_motion; + + if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { + + Vector2 gpoint = Point2(mm.x,mm.y); + + Vector3 ray_from = p_camera->project_ray_origin(gpoint); + Vector3 ray_dir = p_camera->project_ray_normal(gpoint); + + Vector3 spoint; + + if (!p.intersects_ray(ray_from,ray_dir,&spoint)) + break; + + spoint = gi.xform(spoint); + + Vector2 cpoint(spoint.x,spoint.y); + + cpoint=CanvasItemEditor::get_singleton()->snap_point(cpoint); + edited_point_pos = cpoint; + + _polygon_draw(); + + } + + } break; + } + + return false; +} +void CollisionPolygonEditor::_polygon_draw() { + + if (!node) + return; + + Vector<Vector2> poly; + + if (wip_active) + poly=wip; + else + poly=node->get_polygon(); + + + float depth = node->get_depth()*0.5; + + imgeom->clear(); + imgeom->set_material_override(line_material); + imgeom->begin(Mesh::PRIMITIVE_LINES,Ref<Texture>()); + + + Rect2 rect; + + for(int i=0;i<poly.size();i++) { + + + Vector2 p,p2; + p = i==edited_point ? edited_point_pos : poly[i]; + if ((wip_active && i==poly.size()-1) || (((i+1)%poly.size())==edited_point)) + p2=edited_point_pos; + else + p2 = poly[(i+1)%poly.size()]; + + if (i==0) + rect.pos=p; + else + rect.expand_to(p); + + Vector3 point = Vector3(p.x,p.y,depth); + Vector3 next_point = Vector3(p2.x,p2.y,depth); + + imgeom->set_color(Color(1,0.3,0.1,0.8)); + imgeom->add_vertex(point); + imgeom->set_color(Color(1,0.3,0.1,0.8)); + imgeom->add_vertex(next_point); + + //Color col=Color(1,0.3,0.1,0.8); + //vpc->draw_line(point,next_point,col,2); + //vpc->draw_texture(handle,point-handle->get_size()*0.5); + } + + rect=rect.grow(1); + + AABB r; + r.pos.x=rect.pos.x; + r.pos.y=rect.pos.y; + r.pos.z=depth; + r.size.x=rect.size.x; + r.size.y=rect.size.y; + r.size.z=0; + + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos); + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos+Vector3(0.3,0,0)); + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos); + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos+Vector3(0.0,0.3,0)); + + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0)); + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0)-Vector3(0.3,0,0)); + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0)); + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0)+Vector3(0,0.3,0)); + + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0)); + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0)-Vector3(0,0.3,0)); + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0)); + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0)+Vector3(0.3,0,0)); + + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos+r.size); + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos+r.size-Vector3(0.3,0,0)); + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos+r.size); + imgeom->set_color(Color(0.8,0.8,0.8,0.2)); + imgeom->add_vertex(r.pos+r.size-Vector3(0.0,0.3,0)); + + imgeom->end(); + + + while(m->get_surface_count()) { + m->surface_remove(0); + } + + if (poly.size()==0) + return; + + Array a; + a.resize(Mesh::ARRAY_MAX); + PoolVector<Vector3> va; + { + + va.resize(poly.size()); + PoolVector<Vector3>::Write w=va.write(); + for(int i=0;i<poly.size();i++) { + + + Vector2 p,p2; + p = i==edited_point ? edited_point_pos : poly[i]; + + Vector3 point = Vector3(p.x,p.y,depth); + w[i]=point; + } + } + a[Mesh::ARRAY_VERTEX]=va; + m->add_surface(Mesh::PRIMITIVE_POINTS,a); + m->surface_set_material(0,handle_material); + +} + + + +void CollisionPolygonEditor::edit(Node *p_collision_polygon) { + + + + if (p_collision_polygon) { + + node=p_collision_polygon->cast_to<CollisionPolygon>(); + wip.clear(); + wip_active=false; + edited_point=-1; + p_collision_polygon->add_child(imgeom); + _polygon_draw(); + set_process(true); + prev_depth=-1; + + } else { + node=NULL; + + if (imgeom->get_parent()) + imgeom->get_parent()->remove_child(imgeom); + + set_process(false); + } + +} + +void CollisionPolygonEditor::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_menu_option"),&CollisionPolygonEditor::_menu_option); + ClassDB::bind_method(D_METHOD("_polygon_draw"),&CollisionPolygonEditor::_polygon_draw); + ClassDB::bind_method(D_METHOD("_node_removed"),&CollisionPolygonEditor::_node_removed); + +} + +CollisionPolygonEditor::CollisionPolygonEditor(EditorNode *p_editor) { + + + node=NULL; + editor=p_editor; + undo_redo = editor->get_undo_redo(); + + add_child( memnew( VSeparator )); + button_create = memnew( ToolButton ); + add_child(button_create); + button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE)); + button_create->set_toggle_mode(true); + + button_edit = memnew( ToolButton ); + add_child(button_edit); + button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT)); + button_edit->set_toggle_mode(true); + + //add_constant_override("separation",0); + +#if 0 + options = memnew( MenuButton ); + add_child(options); + options->set_area_as_parent_rect(); + options->set_text("Polygon"); + //options->get_popup()->add_item("Parse BBCode",PARSE_BBCODE); + options->get_popup()->connect("id_pressed", this,"_menu_option"); +#endif + + mode = MODE_EDIT; + wip_active=false; + imgeom = memnew( ImmediateGeometry ); + imgeom->set_transform(Transform(Matrix3(),Vector3(0,0,0.00001))); + + + line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial )); + line_material->set_flag(Material::FLAG_UNSHADED, true); + line_material->set_line_width(3.0); + line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true); + line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true); + line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1)); + + + + + handle_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial )); + handle_material->set_flag(Material::FLAG_UNSHADED, true); + handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_POINT_SIZE, true); + handle_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1)); + handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true); + handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, false); + Ref<Texture> handle=editor->get_gui_base()->get_icon("Editor3DHandle","EditorIcons"); + handle_material->set_point_size(handle->get_width()); + handle_material->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,handle); + + pointsm = memnew( MeshInstance ); + imgeom->add_child(pointsm); + m = Ref<Mesh>( memnew( Mesh ) ); + pointsm->set_mesh(m); + pointsm->set_transform(Transform(Matrix3(),Vector3(0,0,0.00001))); + + +} + +CollisionPolygonEditor::~CollisionPolygonEditor() { + + memdelete( imgeom ); +} + + +void CollisionPolygonEditorPlugin::edit(Object *p_object) { + + collision_polygon_editor->edit(p_object->cast_to<Node>()); +} + +bool CollisionPolygonEditorPlugin::handles(Object *p_object) const { + + return p_object->is_type("CollisionPolygon"); +} + +void CollisionPolygonEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + collision_polygon_editor->show(); + } else { + + collision_polygon_editor->hide(); + collision_polygon_editor->edit(NULL); + } + +} + +CollisionPolygonEditorPlugin::CollisionPolygonEditorPlugin(EditorNode *p_node) { + + editor=p_node; + collision_polygon_editor = memnew( CollisionPolygonEditor(p_node) ); + SpatialEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); + + collision_polygon_editor->hide(); + + + +} + + +CollisionPolygonEditorPlugin::~CollisionPolygonEditorPlugin() +{ +} + +#endif diff --git a/editor/plugins/collision_polygon_editor_plugin.h b/editor/plugins/collision_polygon_editor_plugin.h new file mode 100644 index 0000000000..aaad2174fe --- /dev/null +++ b/editor/plugins/collision_polygon_editor_plugin.h @@ -0,0 +1,123 @@ +/*************************************************************************/ +/* collision_polygon_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef COLLISION_POLYGON_EDITOR_PLUGIN_H +#define COLLISION_POLYGON_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/3d/collision_polygon.h" +#include "scene/3d/immediate_geometry.h" +#include "scene/3d/mesh_instance.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/button_group.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +#if 0 +class CanvasItemEditor; + +class CollisionPolygonEditor : public HBoxContainer { + + GDCLASS(CollisionPolygonEditor, HBoxContainer ); + + UndoRedo *undo_redo; + enum Mode { + + MODE_CREATE, + MODE_EDIT, + + }; + + Mode mode; + + ToolButton *button_create; + ToolButton *button_edit; + + + Ref<FixedSpatialMaterial> line_material; + Ref<FixedSpatialMaterial> handle_material; + + EditorNode *editor; + Panel *panel; + CollisionPolygon *node; + ImmediateGeometry *imgeom; + MeshInstance *pointsm; + Ref<Mesh> m; + + MenuButton *options; + + int edited_point; + Vector2 edited_point_pos; + Vector<Vector2> pre_move_edit; + Vector<Vector2> wip; + bool wip_active; + + float prev_depth; + + void _wip_close(); + void _polygon_draw(); + void _menu_option(int p_option); + +protected: + void _notification(int p_what); + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + virtual bool forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event); + void edit(Node *p_collision_polygon); + CollisionPolygonEditor(EditorNode *p_editor); + ~CollisionPolygonEditor(); +}; + +class CollisionPolygonEditorPlugin : public EditorPlugin { + + GDCLASS( CollisionPolygonEditorPlugin, EditorPlugin ); + + CollisionPolygonEditor *collision_polygon_editor; + EditorNode *editor; + +public: + + virtual bool forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event) { return collision_polygon_editor->forward_spatial_gui_input(p_camera,p_event); } + + virtual String get_name() const { return "CollisionPolygon"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + CollisionPolygonEditorPlugin(EditorNode *p_node); + ~CollisionPolygonEditorPlugin(); + +}; +#endif +#endif // COLLISION_POLYGON_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index a05eeb7a27..a05eeb7a27 100644 --- a/tools/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h new file mode 100644 index 0000000000..f7e6da8b4e --- /dev/null +++ b/editor/plugins/collision_shape_2d_editor_plugin.h @@ -0,0 +1,101 @@ +/*************************************************************************/ +/* collision_shape_2d_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef COLLISION_SHAPE_2D_EDITOR_PLUGIN_H +#define COLLISION_SHAPE_2D_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" + +#include "scene/2d/collision_shape_2d.h" + +class CanvasItemEditor; + +class CollisionShape2DEditor : public Control { + GDCLASS(CollisionShape2DEditor, Control); + + enum ShapeType { + CAPSULE_SHAPE, + CIRCLE_SHAPE, + CONCAVE_POLYGON_SHAPE, + CONVEX_POLYGON_SHAPE, + LINE_SHAPE, + RAY_SHAPE, + RECTANGLE_SHAPE, + SEGMENT_SHAPE + }; + + EditorNode* editor; + UndoRedo* undo_redo; + CanvasItemEditor* canvas_item_editor; + CollisionShape2D* node; + + Vector<Point2> handles; + + int shape_type; + int edit_handle; + bool pressed; + Variant original; + + Variant get_handle_value(int idx) const; + void set_handle(int idx, Point2& p_point); + void commit_handle(int idx, Variant& p_org); + + void _get_current_shape_type(); + void _canvas_draw(); + +protected: + static void _bind_methods(); + +public: + bool forward_gui_input(const InputEvent& p_event); + void edit(Node* p_node); + + CollisionShape2DEditor(EditorNode* p_editor); +}; + +class CollisionShape2DEditorPlugin : public EditorPlugin { + GDCLASS(CollisionShape2DEditorPlugin, EditorPlugin); + + CollisionShape2DEditor* collision_shape_2d_editor; + EditorNode* editor; + +public: + virtual bool forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return collision_shape_2d_editor->forward_gui_input(p_event); } + + virtual String get_name() const { return "CollisionShape2D"; } + bool has_main_screen() const { return false; } + virtual void edit(Object* p_obj); + virtual bool handles(Object* p_obj) const; + virtual void make_visible(bool visible); + + CollisionShape2DEditorPlugin(EditorNode* p_editor); + ~CollisionShape2DEditorPlugin(); +}; + +#endif //COLLISION_SHAPE_2D_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/color_ramp_editor_plugin.cpp b/editor/plugins/color_ramp_editor_plugin.cpp index 82674fabb8..82674fabb8 100644 --- a/tools/editor/plugins/color_ramp_editor_plugin.cpp +++ b/editor/plugins/color_ramp_editor_plugin.cpp diff --git a/editor/plugins/color_ramp_editor_plugin.h b/editor/plugins/color_ramp_editor_plugin.h new file mode 100644 index 0000000000..0323bd7a46 --- /dev/null +++ b/editor/plugins/color_ramp_editor_plugin.h @@ -0,0 +1,62 @@ +/*************************************************************************/ +/* color_ramp_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_ +#define TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_ + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/gui/color_ramp_edit.h" + +class ColorRampEditorPlugin : public EditorPlugin { + + GDCLASS( ColorRampEditorPlugin, EditorPlugin ); + + bool _2d; + Ref<ColorRamp> color_ramp_ref; + ColorRampEdit *ramp_editor; + EditorNode *editor; + +protected: + static void _bind_methods(); + void _ramp_changed(); + void _undo_redo_color_ramp(const Vector<float>& offsets, const Vector<Color>& colors); + +public: + virtual String get_name() const { return "ColorRamp"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + ColorRampEditorPlugin(EditorNode *p_node); + ~ColorRampEditorPlugin(); + +}; + +#endif /* TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_ */ diff --git a/editor/plugins/cube_grid_theme_editor_plugin.cpp b/editor/plugins/cube_grid_theme_editor_plugin.cpp new file mode 100644 index 0000000000..b8abd2e9cc --- /dev/null +++ b/editor/plugins/cube_grid_theme_editor_plugin.cpp @@ -0,0 +1,357 @@ +/*************************************************************************/ +/* cube_grid_theme_editor_plugin.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 "cube_grid_theme_editor_plugin.h" + +#if 0 +#include "scene/3d/mesh_instance.h" +#include "scene/3d/physics_body.h" +#include "scene/main/viewport.h" +#include "scene/resources/packed_scene.h" +#include "editor/editor_node.h" +#include "main/main.h" +#include "editor/editor_settings.h" +#include "scene/3d/navigation_mesh.h" + +void MeshLibraryEditor::edit(const Ref<MeshLibrary>& p_theme) { + + theme=p_theme; + if (theme.is_valid()) + menu->get_popup()->set_item_disabled(menu->get_popup()->get_item_index(MENU_OPTION_UPDATE_FROM_SCENE),!theme->has_meta("_editor_source_scene")); + +} + +void MeshLibraryEditor::_menu_confirm() { + + + switch(option) { + + case MENU_OPTION_REMOVE_ITEM: { + + theme->remove_item(to_erase); + } break; + case MENU_OPTION_UPDATE_FROM_SCENE: { + String existing = theme->get_meta("_editor_source_scene"); + ERR_FAIL_COND(existing==""); + _import_scene_cbk(existing); + + } break; + default: {}; + } + +} + + +void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, bool p_merge) { + + if (!p_merge) + p_library->clear(); + + + for(int i=0;i<p_scene->get_child_count();i++) { + + + Node *child = p_scene->get_child(i); + + if (!child->cast_to<MeshInstance>()) { + if (child->get_child_count()>0) { + child=child->get_child(0); + if (!child->cast_to<MeshInstance>()) { + continue; + } + + } else + continue; + + + } + + MeshInstance *mi = child->cast_to<MeshInstance>(); + Ref<Mesh> mesh=mi->get_mesh(); + if (mesh.is_null()) + continue; + + int id = p_library->find_item_name(mi->get_name()); + if (id<0) { + + id=p_library->get_last_unused_item_id(); + p_library->create_item(id); + p_library->set_item_name(id,mi->get_name()); + } + + + p_library->set_item_mesh(id,mesh); + + Ref<Shape> collision; + + + for(int j=0;j<mi->get_child_count();j++) { +#if 1 + Node *child2 = mi->get_child(j); + if (!child2->cast_to<StaticBody>()) + continue; + StaticBody *sb = child2->cast_to<StaticBody>(); + if (sb->get_shape_count()==0) + continue; + collision=sb->get_shape(0); + if (!collision.is_null()) + break; +#endif + } + + if (!collision.is_null()) { + + p_library->set_item_shape(id,collision); + } + Ref<NavigationMesh> navmesh; + for(int j=0;j<mi->get_child_count();j++) { + Node *child2 = mi->get_child(j); + if (!child2->cast_to<NavigationMeshInstance>()) + continue; + NavigationMeshInstance *sb = child2->cast_to<NavigationMeshInstance>(); + navmesh=sb->get_navigation_mesh(); + if (!navmesh.is_null()) + break; + } + if(!navmesh.is_null()){ + p_library->set_item_navmesh(id, navmesh); + } + } + + //generate previews! + + if (1) { + Vector<int> ids = p_library->get_item_list(); + RID vp = VS::get_singleton()->viewport_create(); + VS::ViewportRect vr; + vr.x=0; + vr.y=0; + vr.width=EditorSettings::get_singleton()->get("editors/grid_map/preview_size"); + vr.height=EditorSettings::get_singleton()->get("editors/grid_map/preview_size"); + VS::get_singleton()->viewport_set_rect(vp,vr); + VS::get_singleton()->viewport_set_as_render_target(vp,true); + VS::get_singleton()->viewport_set_render_target_update_mode(vp,VS::RENDER_TARGET_UPDATE_ALWAYS); + RID scen = VS::get_singleton()->scenario_create(); + VS::get_singleton()->viewport_set_scenario(vp,scen); + RID cam = VS::get_singleton()->camera_create(); + VS::get_singleton()->camera_set_transform(cam, Transform() ); + VS::get_singleton()->viewport_attach_camera(vp,cam); + RID light = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); + RID lightinst = VS::get_singleton()->instance_create2(light,scen); + VS::get_singleton()->camera_set_orthogonal(cam,1.0,0.01,1000.0); + + + EditorProgress ep("mlib",TTR("Creating Mesh Library"),ids.size()); + + for(int i=0;i<ids.size();i++) { + + int id=ids[i]; + Ref<Mesh> mesh = p_library->get_item_mesh(id); + if (!mesh.is_valid()) + continue; + AABB aabb= mesh->get_aabb(); + print_line("aabb: "+aabb); + Vector3 ofs = aabb.pos + aabb.size*0.5; + aabb.pos-=ofs; + Transform xform; + xform.basis=Matrix3().rotated(Vector3(0,1,0),-Math_PI*0.25); + xform.basis = Matrix3().rotated(Vector3(1,0,0),Math_PI*0.25)*xform.basis; + AABB rot_aabb = xform.xform(aabb); + print_line("rot_aabb: "+rot_aabb); + float m = MAX(rot_aabb.size.x,rot_aabb.size.y)*0.5; + if (m==0) + continue; + m=1.0/m; + m*=0.5; + print_line("scale: "+rtos(m)); + xform.basis.scale(Vector3(m,m,m)); + xform.origin=-xform.basis.xform(ofs); //-ofs*m; + xform.origin.z-=rot_aabb.size.z*2; + RID inst = VS::get_singleton()->instance_create2(mesh->get_rid(),scen); + VS::get_singleton()->instance_set_transform(inst,xform); + ep.step(TTR("Thumbnail.."),i); + VS::get_singleton()->viewport_queue_screen_capture(vp); + Main::iteration(); + Image img = VS::get_singleton()->viewport_get_screen_capture(vp); + ERR_CONTINUE(img.empty()); + Ref<ImageTexture> it( memnew( ImageTexture )); + it->create_from_image(img); + p_library->set_item_preview(id,it); + + //print_line("loaded image, size: "+rtos(m)+" dist: "+rtos(dist)+" empty?"+itos(img.empty())+" w: "+itos(it->get_width())+" h: "+itos(it->get_height())); + VS::get_singleton()->free(inst); + } + + VS::get_singleton()->free(lightinst); + VS::get_singleton()->free(light); + VS::get_singleton()->free(vp); + VS::get_singleton()->free(cam); + VS::get_singleton()->free(scen); + } + + +} + + +void MeshLibraryEditor::_import_scene_cbk(const String& p_str) { + + + print_line("Impot Callback!"); + + Ref<PackedScene> ps = ResourceLoader::load(p_str,"PackedScene"); + ERR_FAIL_COND(ps.is_null()); + Node *scene = ps->instance(); + + _import_scene(scene,theme,option==MENU_OPTION_UPDATE_FROM_SCENE); + + memdelete(scene); + theme->set_meta("_editor_source_scene",p_str); + menu->get_popup()->set_item_disabled(menu->get_popup()->get_item_index(MENU_OPTION_UPDATE_FROM_SCENE),false); + +} + +Error MeshLibraryEditor::update_library_file(Node *p_base_scene, Ref<MeshLibrary> ml,bool p_merge) { + + _import_scene(p_base_scene,ml,p_merge); + return OK; +} + + +void MeshLibraryEditor::_menu_cbk(int p_option) { + + option=p_option; + switch(p_option) { + + case MENU_OPTION_ADD_ITEM: { + + theme->create_item(theme->get_last_unused_item_id()); + } break; + case MENU_OPTION_REMOVE_ITEM: { + + String p = editor->get_property_editor()->get_selected_path(); + if (p.begins_with("/MeshLibrary/item") && p.get_slice_count("/")>=3) { + + to_erase = p.get_slice("/",3).to_int(); + cd->set_text(vformat(TTR("Remove item %d?"),to_erase)); + cd->popup_centered(Size2(300,60)); + } + } break; + case MENU_OPTION_IMPORT_FROM_SCENE: { + + file->popup_centered_ratio(); + } break; + case MENU_OPTION_UPDATE_FROM_SCENE: { + + cd->set_text("Update from existing scene?:\n"+String(theme->get_meta("_editor_source_scene"))); + cd->popup_centered(Size2(500,60)); + } break; + } +} + + +void MeshLibraryEditor::_bind_methods() { + + ClassDB::bind_method("_menu_cbk",&MeshLibraryEditor::_menu_cbk); + ClassDB::bind_method("_menu_confirm",&MeshLibraryEditor::_menu_confirm); + ClassDB::bind_method("_import_scene_cbk",&MeshLibraryEditor::_import_scene_cbk); +} + +MeshLibraryEditor::MeshLibraryEditor(EditorNode *p_editor) { + + file = memnew( EditorFileDialog ); + file->set_mode(EditorFileDialog::MODE_OPEN_FILE); + //not for now? + List<String> extensions; + ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions); + file->clear_filters(); + file->set_title(TTR("Import Scene")); + for(int i=0;i<extensions.size();i++) { + + file->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); + } + add_child(file); + file->connect("file_selected",this,"_import_scene_cbk"); + + Panel *panel = memnew( Panel ); + panel->set_area_as_parent_rect(); + add_child(panel); + MenuButton * options = memnew( MenuButton ); + panel->add_child(options); + options->set_pos(Point2(1,1)); + options->set_text("Theme"); + options->get_popup()->add_item(TTR("Add Item"),MENU_OPTION_ADD_ITEM); + options->get_popup()->add_item(TTR("Remove Selected Item"),MENU_OPTION_REMOVE_ITEM); + options->get_popup()->add_separator(); + options->get_popup()->add_item(TTR("Import from Scene"),MENU_OPTION_IMPORT_FROM_SCENE); + options->get_popup()->add_item(TTR("Update from Scene"),MENU_OPTION_UPDATE_FROM_SCENE); + options->get_popup()->set_item_disabled(options->get_popup()->get_item_index(MENU_OPTION_UPDATE_FROM_SCENE),true); + options->get_popup()->connect("id_pressed", this,"_menu_cbk"); + menu=options; + editor=p_editor; + cd = memnew(ConfirmationDialog); + add_child(cd); + cd->get_ok()->connect("pressed", this,"_menu_confirm"); + +} + +void MeshLibraryEditorPlugin::edit(Object *p_node) { + + if (p_node && p_node->cast_to<MeshLibrary>()) { + theme_editor->edit( p_node->cast_to<MeshLibrary>() ); + theme_editor->show(); + } else + theme_editor->hide(); +} + +bool MeshLibraryEditorPlugin::handles(Object *p_node) const{ + + return p_node->is_type("MeshLibrary"); +} + +void MeshLibraryEditorPlugin::make_visible(bool p_visible){ + + if (p_visible) + theme_editor->show(); + else + theme_editor->hide(); +} + +MeshLibraryEditorPlugin::MeshLibraryEditorPlugin(EditorNode *p_node) { + + EDITOR_DEF("editors/grid_map/preview_size",64); + theme_editor = memnew( MeshLibraryEditor(p_node) ); + + p_node->get_viewport()->add_child(theme_editor); + theme_editor->set_area_as_parent_rect(); + theme_editor->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END ); + theme_editor->set_anchor( MARGIN_BOTTOM, Control::ANCHOR_BEGIN ); + theme_editor->set_end( Point2(0,22) ); + theme_editor->hide(); + +} +#endif diff --git a/editor/plugins/cube_grid_theme_editor_plugin.h b/editor/plugins/cube_grid_theme_editor_plugin.h new file mode 100644 index 0000000000..07e7c7cadd --- /dev/null +++ b/editor/plugins/cube_grid_theme_editor_plugin.h @@ -0,0 +1,96 @@ +/*************************************************************************/ +/* cube_grid_theme_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef CUBE_GRID_THEME_EDITOR_PLUGIN_H +#define CUBE_GRID_THEME_EDITOR_PLUGIN_H + +#include "scene/resources/mesh_library.h" +#include "editor/editor_node.h" + +#if 0 +class MeshLibraryEditor : public Control { + + GDCLASS( MeshLibraryEditor, Control ); + + Ref<MeshLibrary> theme; + + EditorNode *editor; + MenuButton *menu; + ConfirmationDialog *cd; + EditorFileDialog *file; + int to_erase; + + enum { + + MENU_OPTION_ADD_ITEM, + MENU_OPTION_REMOVE_ITEM, + MENU_OPTION_UPDATE_FROM_SCENE, + MENU_OPTION_IMPORT_FROM_SCENE + }; + + int option; + void _import_scene_cbk(const String& p_str); + void _menu_cbk(int p_option); + void _menu_confirm(); + + static void _import_scene(Node *p_scene, Ref<MeshLibrary> p_library, bool p_merge); + +protected: + static void _bind_methods(); +public: + + void edit(const Ref<MeshLibrary>& p_theme); + static Error update_library_file(Node *p_base_scene, Ref<MeshLibrary> ml,bool p_merge=true); + + MeshLibraryEditor(EditorNode *p_editor); +}; + + + +class MeshLibraryEditorPlugin : public EditorPlugin { + + GDCLASS( MeshLibraryEditorPlugin, EditorPlugin ); + + MeshLibraryEditor *theme_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "MeshLibrary"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + MeshLibraryEditorPlugin(EditorNode *p_node); + +}; + + +#endif // CUBE_GRID_THEME_EDITOR_PLUGIN_H +#endif diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp new file mode 100644 index 0000000000..3f31f1e0f1 --- /dev/null +++ b/editor/plugins/editor_preview_plugins.cpp @@ -0,0 +1,907 @@ +/*************************************************************************/ +/* editor_preview_plugins.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 "editor_preview_plugins.h" + +#include "io/resource_loader.h" +#include "editor/editor_settings.h" +#include "io/file_access_memory.h" +#include "os/os.h" +#include "scene/resources/material.h" +//#include "scene/resources/sample.h" +#include "scene/resources/mesh.h" +#include "scene/resources/bit_mask.h" +#include "editor/editor_scale.h" + +#if 0 +bool EditorTexturePreviewPlugin::handles(const String& p_type) const { + + return (ClassDB::is_type(p_type,"ImageTexture") || ClassDB::is_type(p_type, "AtlasTexture")); +} + +Ref<Texture> EditorTexturePreviewPlugin::generate(const RES& p_from) { + + Image img; + Ref<AtlasTexture> atex = p_from; + if (atex.is_valid()) { + Ref<ImageTexture> tex = atex->get_atlas(); + if (!tex.is_valid()) { + return Ref<Texture>(); + } + Image atlas = tex->get_data(); + img = atlas.get_rect(atex->get_region()); + } + else { + Ref<ImageTexture> tex = p_from; + img = tex->get_data(); + } + + if (img.empty()) + return Ref<Texture>(); + + img.clear_mipmaps(); + + int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + thumbnail_size*=EDSCALE; + if (img.is_compressed()) { + if (img.decompress()!=OK) + return Ref<Texture>(); + } else if (img.get_format()!=Image::FORMAT_RGB8 && img.get_format()!=Image::FORMAT_RGBA8) { + img.convert(Image::FORMAT_RGBA8); + } + + int width,height; + if (img.get_width() > thumbnail_size && img.get_width() >= img.get_height()) { + + width=thumbnail_size; + height = img.get_height() * thumbnail_size / img.get_width(); + } else if (img.get_height() > thumbnail_size && img.get_height() >= img.get_width()) { + + height=thumbnail_size; + width = img.get_width() * thumbnail_size / img.get_height(); + } else { + + width=img.get_width(); + height=img.get_height(); + } + + img.resize(width,height); + + Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); + + ptex->create_from_image(img,0); + return ptex; + +} + +EditorTexturePreviewPlugin::EditorTexturePreviewPlugin() { + + +} + +//////////////////////////////////////////////////////////////////////////// + +bool EditorBitmapPreviewPlugin::handles(const String& p_type) const { + + return ClassDB::is_type(p_type,"BitMap"); +} + +Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES& p_from) { + + Ref<BitMap> bm =p_from; + + if (bm->get_size()==Size2()) { + return Ref<Texture>(); + } + + PoolVector<uint8_t> data; + + data.resize(bm->get_size().width*bm->get_size().height); + + { + PoolVector<uint8_t>::Write w=data.write(); + + for(int i=0;i<bm->get_size().width;i++) { + for(int j=0;j<bm->get_size().height;j++) { + if (bm->get_bit(Point2i(i,j))) { + w[j*bm->get_size().width+i]=255; + } else { + w[j*bm->get_size().width+i]=0; + + } + } + + } + } + + + Image img(bm->get_size().width,bm->get_size().height,0,Image::FORMAT_L8,data); + + int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + thumbnail_size*=EDSCALE; + if (img.is_compressed()) { + if (img.decompress()!=OK) + return Ref<Texture>(); + } else if (img.get_format()!=Image::FORMAT_RGB8 && img.get_format()!=Image::FORMAT_RGBA8) { + img.convert(Image::FORMAT_RGBA8); + } + + int width,height; + if (img.get_width() > thumbnail_size && img.get_width() >= img.get_height()) { + + width=thumbnail_size; + height = img.get_height() * thumbnail_size / img.get_width(); + } else if (img.get_height() > thumbnail_size && img.get_height() >= img.get_width()) { + + height=thumbnail_size; + width = img.get_width() * thumbnail_size / img.get_height(); + } else { + + width=img.get_width(); + height=img.get_height(); + } + + img.resize(width,height); + + Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); + + ptex->create_from_image(img,0); + return ptex; + +} + +EditorBitmapPreviewPlugin::EditorBitmapPreviewPlugin() { + + +} + +/////////////////////////////////////////////////////////////////////////// + + +Ref<Texture> EditorPackedScenePreviewPlugin::_gen_from_imd(Ref<ResourceImportMetadata> p_imd) { + + if (p_imd.is_null()) { + return Ref<Texture>(); + } + + if (!p_imd->has_option("thumbnail")) + return Ref<Texture>(); + + Variant tn = p_imd->get_option("thumbnail"); + //print_line(Variant::get_type_name(tn.get_type())); + PoolVector<uint8_t> thumbnail = tn; + + int len = thumbnail.size(); + if (len==0) + return Ref<Texture>(); + + + PoolVector<uint8_t>::Read r = thumbnail.read(); + + Image img(r.ptr(),len); + if (img.empty()) + return Ref<Texture>(); + + Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); + ptex->create_from_image(img,0); + return ptex; + +} + +bool EditorPackedScenePreviewPlugin::handles(const String& p_type) const { + + return ClassDB::is_type(p_type,"PackedScene"); +} +Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES& p_from) { + + Ref<ResourceImportMetadata> imd = p_from->get_import_metadata(); + return _gen_from_imd(imd); +} + +Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String& p_path) { + + Ref<ResourceImportMetadata> imd = ResourceLoader::load_import_metadata(p_path); + return _gen_from_imd(imd); +} + +EditorPackedScenePreviewPlugin::EditorPackedScenePreviewPlugin() { + +} + +////////////////////////////////////////////////////////////////// + +bool EditorMaterialPreviewPlugin::handles(const String& p_type) const { + + return ClassDB::is_type(p_type,"Material"); //any material +} + +Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES& p_from) { + + Ref<Material> material = p_from; + ERR_FAIL_COND_V(material.is_null(),Ref<Texture>()); + + VS::get_singleton()->mesh_surface_set_material(sphere,0,material->get_rid()); + + VS::get_singleton()->viewport_queue_screen_capture(viewport); + VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_ONCE); //once used for capture + //print_line("queue capture!"); + Image img; + + int timeout=1000; + while(timeout) { + //print_line("try capture?"); + OS::get_singleton()->delay_usec(10); + img = VS::get_singleton()->viewport_get_screen_capture(viewport); + if (!img.empty()) + break; + timeout--; + } + + //print_line("captured!"); + VS::get_singleton()->mesh_surface_set_material(sphere,0,RID()); + + int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + thumbnail_size*=EDSCALE; + img.resize(thumbnail_size,thumbnail_size); + + Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); + ptex->create_from_image(img,0); + return ptex; +} + +EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() { + + scenario = VS::get_singleton()->scenario_create(); + + viewport = VS::get_singleton()->viewport_create(); + VS::get_singleton()->viewport_set_as_render_target(viewport,true); + VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_DISABLED); + VS::get_singleton()->viewport_set_scenario(viewport,scenario); + VS::ViewportRect vr; + vr.x=0; + vr.y=0; + vr.width=128; + vr.height=128; + VS::get_singleton()->viewport_set_rect(viewport,vr); + + camera = VS::get_singleton()->camera_create(); + VS::get_singleton()->viewport_attach_camera(viewport,camera); + VS::get_singleton()->camera_set_transform(camera,Transform(Matrix3(),Vector3(0,0,3))); + VS::get_singleton()->camera_set_perspective(camera,45,0.1,10); + + light = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); + light_instance = VS::get_singleton()->instance_create2(light,scenario); + VS::get_singleton()->instance_set_transform(light_instance,Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0))); + + light2 = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); + VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_DIFFUSE,Color(0.7,0.7,0.7)); + VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_SPECULAR,Color(0.0,0.0,0.0)); + light_instance2 = VS::get_singleton()->instance_create2(light2,scenario); + + VS::get_singleton()->instance_set_transform(light_instance2,Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1))); + + sphere = VS::get_singleton()->mesh_create(); + sphere_instance = VS::get_singleton()->instance_create2(sphere,scenario); + + int lats=32; + int lons=32; + float radius=1.0; + + PoolVector<Vector3> vertices; + PoolVector<Vector3> normals; + PoolVector<Vector2> uvs; + PoolVector<float> tangents; + Matrix3 tt = Matrix3(Vector3(0,1,0),Math_PI*0.5); + + for(int i = 1; i <= lats; i++) { + double lat0 = Math_PI * (-0.5 + (double) (i - 1) / lats); + double z0 = Math::sin(lat0); + double zr0 = Math::cos(lat0); + + double lat1 = Math_PI * (-0.5 + (double) i / lats); + double z1 = Math::sin(lat1); + double zr1 = Math::cos(lat1); + + for(int j = lons; j >= 1; j--) { + + double lng0 = 2 * Math_PI * (double) (j - 1) / lons; + double x0 = Math::cos(lng0); + double y0 = Math::sin(lng0); + + double lng1 = 2 * Math_PI * (double) (j) / lons; + double x1 = Math::cos(lng1); + double y1 = Math::sin(lng1); + + + Vector3 v[4]={ + Vector3(x1 * zr0, z0, y1 *zr0), + Vector3(x1 * zr1, z1, y1 *zr1), + Vector3(x0 * zr1, z1, y0 *zr1), + Vector3(x0 * zr0, z0, y0 *zr0) + }; + +#define ADD_POINT(m_idx) \ + normals.push_back(v[m_idx]);\ + vertices.push_back(v[m_idx]*radius);\ + { Vector2 uv(Math::atan2(v[m_idx].x,v[m_idx].z),Math::atan2(-v[m_idx].y,v[m_idx].z));\ + uv/=Math_PI;\ + uv*=4.0;\ + uv=uv*0.5+Vector2(0.5,0.5);\ + uvs.push_back(uv);\ + }\ + { Vector3 t = tt.xform(v[m_idx]);\ + tangents.push_back(t.x);\ + tangents.push_back(t.y);\ + tangents.push_back(t.z);\ + tangents.push_back(1.0);\ + } + + + + ADD_POINT(0); + ADD_POINT(1); + ADD_POINT(2); + + ADD_POINT(2); + ADD_POINT(3); + ADD_POINT(0); + } + } + + Array arr; + arr.resize(VS::ARRAY_MAX); + arr[VS::ARRAY_VERTEX]=vertices; + arr[VS::ARRAY_NORMAL]=normals; + arr[VS::ARRAY_TANGENT]=tangents; + arr[VS::ARRAY_TEX_UV]=uvs; + VS::get_singleton()->mesh_add_surface(sphere,VS::PRIMITIVE_TRIANGLES,arr); + +} + +EditorMaterialPreviewPlugin::~EditorMaterialPreviewPlugin() { + + VS::get_singleton()->free(sphere); + VS::get_singleton()->free(sphere_instance); + VS::get_singleton()->free(viewport); + VS::get_singleton()->free(light); + VS::get_singleton()->free(light_instance); + VS::get_singleton()->free(light2); + VS::get_singleton()->free(light_instance2); + VS::get_singleton()->free(camera); + VS::get_singleton()->free(scenario); + +} + +/////////////////////////////////////////////////////////////////////////// + +static bool _is_text_char(CharType c) { + + return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_'; +} + +bool EditorScriptPreviewPlugin::handles(const String& p_type) const { + + return ClassDB::is_type(p_type,"Script"); +} + +Ref<Texture> EditorScriptPreviewPlugin::generate(const RES& p_from) { + + + Ref<Script> scr = p_from; + if (scr.is_null()) + return Ref<Texture>(); + + String code = scr->get_source_code().strip_edges(); + if (code=="") + return Ref<Texture>(); + + List<String> kwors; + scr->get_language()->get_reserved_words(&kwors); + + Set<String> keywords; + + for(List<String>::Element *E=kwors.front();E;E=E->next()) { + + keywords.insert(E->get()); + + } + + + int line = 0; + int col=0; + int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + thumbnail_size*=EDSCALE; + Image img(thumbnail_size,thumbnail_size,0,Image::FORMAT_RGBA8); + + + + Color bg_color = EditorSettings::get_singleton()->get("text_editor/highlighting/background_color"); + bg_color.a=1.0; + Color keyword_color = EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"); + Color text_color = EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"); + Color symbol_color = EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"); + + + for(int i=0;i<thumbnail_size;i++) { + for(int j=0;j<thumbnail_size;j++) { + img.put_pixel(i,j,bg_color); + } + + } + + bool prev_is_text=false; + bool in_keyword=false; + for(int i=0;i<code.length();i++) { + + CharType c = code[i]; + if (c>32) { + if (col<thumbnail_size) { + Color color = text_color; + + if (c!='_' && ((c>='!' && c<='/') || (c>=':' && c<='@') || (c>='[' && c<='`') || (c>='{' && c<='~') || c=='\t')) { + //make symbol a little visible + color=symbol_color; + in_keyword=false; + } else if (!prev_is_text && _is_text_char(c)) { + int pos = i; + + while(_is_text_char(code[pos])) { + pos++; + } + ///print_line("from "+itos(i)+" to "+itos(pos)); + String word = code.substr(i,pos-i); + //print_line("found word: "+word); + if (keywords.has(word)) + in_keyword=true; + + } else if (!_is_text_char(c)) { + in_keyword=false; + } + + if (in_keyword) + color=keyword_color; + + Color ul=color; + ul.a*=0.5; + img.put_pixel(col,line*2,bg_color.blend(ul)); + img.put_pixel(col,line*2+1,color); + + prev_is_text=_is_text_char(c); + } + } else { + + prev_is_text=false; + in_keyword=false; + + if (c=='\n') { + col=0; + line++; + if (line>=thumbnail_size/2) + break; + } else if (c=='\t') { + col+=3; + } + } + col++; + } + + Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture)); + + ptex->create_from_image(img,0); + return ptex; + +} + +EditorScriptPreviewPlugin::EditorScriptPreviewPlugin() { + + +} +/////////////////////////////////////////////////////////////////// +#if 0 +bool EditorSamplePreviewPlugin::handles(const String& p_type) const { + + return ClassDB::is_type(p_type,"Sample"); +} + +Ref<Texture> EditorSamplePreviewPlugin::generate(const RES& p_from) { + + Ref<Sample> smp =p_from; + ERR_FAIL_COND_V(smp.is_null(),Ref<Texture>()); + + + int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + thumbnail_size*=EDSCALE; + PoolVector<uint8_t> img; + int w = thumbnail_size; + int h = thumbnail_size; + img.resize(w*h*3); + + PoolVector<uint8_t>::Write imgdata = img.write(); + uint8_t * imgw = imgdata.ptr(); + PoolVector<uint8_t> data = smp->get_data(); + PoolVector<uint8_t>::Read sampledata = data.read(); + const uint8_t *sdata=sampledata.ptr(); + + bool stereo = smp->is_stereo(); + bool _16=smp->get_format()==Sample::FORMAT_PCM16; + int len = smp->get_length(); + + if (len<1) + return Ref<Texture>(); + + if (smp->get_format()==Sample::FORMAT_IMA_ADPCM) { + + struct IMA_ADPCM_State { + + int16_t step_index; + int32_t predictor; + /* values at loop point */ + int16_t loop_step_index; + int32_t loop_predictor; + int32_t last_nibble; + int32_t loop_pos; + int32_t window_ofs; + const uint8_t *ptr; + } ima_adpcm; + + ima_adpcm.step_index=0; + ima_adpcm.predictor=0; + ima_adpcm.loop_step_index=0; + ima_adpcm.loop_predictor=0; + ima_adpcm.last_nibble=-1; + ima_adpcm.loop_pos=0x7FFFFFFF; + ima_adpcm.window_ofs=0; + ima_adpcm.ptr=NULL; + + + for(int i=0;i<w;i++) { + + float max[2]={-1e10,-1e10}; + float min[2]={1e10,1e10}; + int from = i*len/w; + int to = (i+1)*len/w; + if (to>=len) + to=len-1; + + for(int j=from;j<to;j++) { + + while(j>ima_adpcm.last_nibble) { + + static const int16_t _ima_adpcm_step_table[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 + }; + + static const int8_t _ima_adpcm_index_table[16] = { + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8 + }; + + int16_t nibble,diff,step; + + ima_adpcm.last_nibble++; + const uint8_t *src_ptr=sdata; + + int ofs = ima_adpcm.last_nibble>>1; + + if (stereo) + ofs*=2; + + + nibble = (ima_adpcm.last_nibble&1)? + (src_ptr[ofs]>>4):(src_ptr[ofs]&0xF); + step=_ima_adpcm_step_table[ima_adpcm.step_index]; + + ima_adpcm.step_index += _ima_adpcm_index_table[nibble]; + if (ima_adpcm.step_index<0) + ima_adpcm.step_index=0; + if (ima_adpcm.step_index>88) + ima_adpcm.step_index=88; + + diff = step >> 3 ; + if (nibble & 1) + diff += step >> 2 ; + if (nibble & 2) + diff += step >> 1 ; + if (nibble & 4) + diff += step ; + if (nibble & 8) + diff = -diff ; + + ima_adpcm.predictor+=diff; + if (ima_adpcm.predictor<-0x8000) + ima_adpcm.predictor=-0x8000; + else if (ima_adpcm.predictor>0x7FFF) + ima_adpcm.predictor=0x7FFF; + + + /* store loop if there */ + if (ima_adpcm.last_nibble==ima_adpcm.loop_pos) { + + ima_adpcm.loop_step_index = ima_adpcm.step_index; + ima_adpcm.loop_predictor = ima_adpcm.predictor; + } + + } + + float v=ima_adpcm.predictor/32767.0; + if (v>max[0]) + max[0]=v; + if (v<min[0]) + min[0]=v; + } + max[0]*=0.8; + min[0]*=0.8; + + for(int j=0;j<h;j++) { + float v = (j/(float)h) * 2.0 - 1.0; + uint8_t* imgofs = &imgw[(uint64_t(j)*w+i)*3]; + if (v>min[0] && v<max[0]) { + imgofs[0]=255; + imgofs[1]=150; + imgofs[2]=80; + } else { + imgofs[0]=0; + imgofs[1]=0; + imgofs[2]=0; + } + } + } + } else { + for(int i=0;i<w;i++) { + // i trust gcc will optimize this loop + float max[2]={-1e10,-1e10}; + float min[2]={1e10,1e10}; + int c=stereo?2:1; + int from = uint64_t(i)*len/w; + int to = (uint64_t(i)+1)*len/w; + if (to>=len) + to=len-1; + + if (_16) { + const int16_t*src =(const int16_t*)sdata; + + for(int j=0;j<c;j++) { + + for(int k=from;k<=to;k++) { + + float v = src[uint64_t(k)*c+j]/32768.0; + if (v>max[j]) + max[j]=v; + if (v<min[j]) + min[j]=v; + } + + } + } else { + + const int8_t*src =(const int8_t*)sdata; + + for(int j=0;j<c;j++) { + + for(int k=from;k<=to;k++) { + + float v = src[uint64_t(k)*c+j]/128.0; + if (v>max[j]) + max[j]=v; + if (v<min[j]) + min[j]=v; + } + + } + } + + max[0]*=0.8; + max[1]*=0.8; + min[0]*=0.8; + min[1]*=0.8; + + if (!stereo) { + for(int j=0;j<h;j++) { + float v = (j/(float)h) * 2.0 - 1.0; + uint8_t* imgofs = &imgw[(j*w+i)*3]; + if (v>min[0] && v<max[0]) { + imgofs[0]=255; + imgofs[1]=150; + imgofs[2]=80; + } else { + imgofs[0]=0; + imgofs[1]=0; + imgofs[2]=0; + } + } + } else { + + for(int j=0;j<h;j++) { + + int half; + float v; + if (j<(h/2)) { + half=0; + v = (j/(float)(h/2)) * 2.0 - 1.0; + } else { + half=1; + if( (float)(h/2) != 0 ) { + v = ((j-(h/2))/(float)(h/2)) * 2.0 - 1.0; + } else { + v = ((j-(h/2))/(float)(1/2)) * 2.0 - 1.0; + } + } + + uint8_t* imgofs = &imgw[(j*w+i)*3]; + if (v>min[half] && v<max[half]) { + imgofs[0]=255; + imgofs[1]=150; + imgofs[2]=80; + } else { + imgofs[0]=0; + imgofs[1]=0; + imgofs[2]=0; + } + } + + } + + } + } + + imgdata = PoolVector<uint8_t>::Write(); + + Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture)); + ptex->create_from_image(Image(w,h,0,Image::FORMAT_RGB8,img),0); + return ptex; + +} + +EditorSamplePreviewPlugin::EditorSamplePreviewPlugin() { + + +} +#endif +/////////////////////////////////////////////////////////////////////////// + +bool EditorMeshPreviewPlugin::handles(const String& p_type) const { + + return ClassDB::is_type(p_type,"Mesh"); //any Mesh +} + +Ref<Texture> EditorMeshPreviewPlugin::generate(const RES& p_from) { + + Ref<Mesh> mesh = p_from; + ERR_FAIL_COND_V(mesh.is_null(),Ref<Texture>()); + + VS::get_singleton()->instance_set_base(mesh_instance,mesh->get_rid()); + + AABB aabb= mesh->get_aabb(); + Vector3 ofs = aabb.pos + aabb.size*0.5; + aabb.pos-=ofs; + Transform xform; + xform.basis=Matrix3().rotated(Vector3(0,1,0),-Math_PI*0.125); + xform.basis = Matrix3().rotated(Vector3(1,0,0),Math_PI*0.125)*xform.basis; + AABB rot_aabb = xform.xform(aabb); + float m = MAX(rot_aabb.size.x,rot_aabb.size.y)*0.5; + if (m==0) + return Ref<Texture>(); + m=1.0/m; + m*=0.5; + //print_line("scale: "+rtos(m)); + xform.basis.scale(Vector3(m,m,m)); + xform.origin=-xform.basis.xform(ofs); //-ofs*m; + xform.origin.z-=rot_aabb.size.z*2; + VS::get_singleton()->instance_set_transform(mesh_instance,xform); + + + + VS::get_singleton()->viewport_queue_screen_capture(viewport); + VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_ONCE); //once used for capture + //print_line("queue capture!"); + Image img; + + int timeout=1000; + while(timeout) { + //print_line("try capture?"); + OS::get_singleton()->delay_usec(10); + img = VS::get_singleton()->viewport_get_screen_capture(viewport); + if (!img.empty()) + break; + timeout--; + } + + //print_line("captured!"); + VS::get_singleton()->instance_set_base(mesh_instance,RID()); + + int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + thumbnail_size*=EDSCALE; + img.resize(thumbnail_size,thumbnail_size); + + Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); + ptex->create_from_image(img,0); + return ptex; +} + +EditorMeshPreviewPlugin::EditorMeshPreviewPlugin() { + + scenario = VS::get_singleton()->scenario_create(); + viewport = VS::get_singleton()->viewport_create(); + VS::get_singleton()->viewport_set_as_render_target(viewport,true); + VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_DISABLED); + VS::get_singleton()->viewport_set_scenario(viewport,scenario); + VS::ViewportRect vr; + vr.x=0; + vr.y=0; + vr.width=128; + vr.height=128; + VS::get_singleton()->viewport_set_rect(viewport,vr); + + camera = VS::get_singleton()->camera_create(); + VS::get_singleton()->viewport_attach_camera(viewport,camera); + VS::get_singleton()->camera_set_transform(camera,Transform(Matrix3(),Vector3(0,0,3))); + //VS::get_singleton()->camera_set_perspective(camera,45,0.1,10); + VS::get_singleton()->camera_set_orthogonal(camera,1.0,0.01,1000.0); + + light = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); + light_instance = VS::get_singleton()->instance_create2(light,scenario); + VS::get_singleton()->instance_set_transform(light_instance,Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0))); + + light2 = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); + VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_DIFFUSE,Color(0.7,0.7,0.7)); + VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_SPECULAR,Color(0.0,0.0,0.0)); + light_instance2 = VS::get_singleton()->instance_create2(light2,scenario); + + VS::get_singleton()->instance_set_transform(light_instance2,Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1))); + + //sphere = VS::get_singleton()->mesh_create(); + mesh_instance = VS::get_singleton()->instance_create(); + VS::get_singleton()->instance_set_scenario(mesh_instance,scenario); + + + +} + + +EditorMeshPreviewPlugin::~EditorMeshPreviewPlugin() { + + //VS::get_singleton()->free(sphere); + VS::get_singleton()->free(mesh_instance); + VS::get_singleton()->free(viewport); + VS::get_singleton()->free(light); + VS::get_singleton()->free(light_instance); + VS::get_singleton()->free(light2); + VS::get_singleton()->free(light_instance2); + VS::get_singleton()->free(camera); + VS::get_singleton()->free(scenario); + +} +#endif diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h new file mode 100644 index 0000000000..b1d4fa0b38 --- /dev/null +++ b/editor/plugins/editor_preview_plugins.h @@ -0,0 +1,128 @@ +/*************************************************************************/ +/* editor_preview_plugins.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef EDITORPREVIEWPLUGINS_H +#define EDITORPREVIEWPLUGINS_H + +#include "editor/editor_resource_preview.h" + +#if 0 +class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator { +public: + + virtual bool handles(const String& p_type) const; + virtual Ref<Texture> generate(const RES& p_from); + + EditorTexturePreviewPlugin(); +}; + + +class EditorBitmapPreviewPlugin : public EditorResourcePreviewGenerator { +public: + + virtual bool handles(const String& p_type) const; + virtual Ref<Texture> generate(const RES& p_from); + + EditorBitmapPreviewPlugin(); +}; + + + +class EditorPackedScenePreviewPlugin : public EditorResourcePreviewGenerator { + + Ref<Texture> _gen_from_imd(Ref<ResourceImportMetadata> p_imd); +public: + + virtual bool handles(const String& p_type) const; + virtual Ref<Texture> generate(const RES& p_from); + virtual Ref<Texture> generate_from_path(const String& p_path); + + EditorPackedScenePreviewPlugin(); +}; + +class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator { + + RID scenario; + RID sphere; + RID sphere_instance; + RID viewport; + RID light; + RID light_instance; + RID light2; + RID light_instance2; + RID camera; +public: + + virtual bool handles(const String& p_type) const; + virtual Ref<Texture> generate(const RES& p_from); + + EditorMaterialPreviewPlugin(); + ~EditorMaterialPreviewPlugin(); +}; + +class EditorScriptPreviewPlugin : public EditorResourcePreviewGenerator { +public: + + virtual bool handles(const String& p_type) const; + virtual Ref<Texture> generate(const RES& p_from); + + EditorScriptPreviewPlugin(); +}; + +#if 0 +class EditorSamplePreviewPlugin : public EditorResourcePreviewGenerator { +public: + + virtual bool handles(const String& p_type) const; + virtual Ref<Texture> generate(const RES& p_from); + + EditorSamplePreviewPlugin(); +}; + +#endif +class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator { + + RID scenario; + RID mesh_instance; + RID viewport; + RID light; + RID light_instance; + RID light2; + RID light_instance2; + RID camera; +public: + + virtual bool handles(const String& p_type) const; + virtual Ref<Texture> generate(const RES& p_from); + + EditorMeshPreviewPlugin(); + ~EditorMeshPreviewPlugin(); +}; + +#endif +#endif // EDITORPREVIEWPLUGINS_H diff --git a/tools/editor/plugins/gi_probe_editor_plugin.cpp b/editor/plugins/gi_probe_editor_plugin.cpp index 925ac8ef11..925ac8ef11 100644 --- a/tools/editor/plugins/gi_probe_editor_plugin.cpp +++ b/editor/plugins/gi_probe_editor_plugin.cpp diff --git a/editor/plugins/gi_probe_editor_plugin.h b/editor/plugins/gi_probe_editor_plugin.h new file mode 100644 index 0000000000..982a549368 --- /dev/null +++ b/editor/plugins/gi_probe_editor_plugin.h @@ -0,0 +1,65 @@ +/*************************************************************************/ +/* gi_probe_editor_plugin.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. */ +/*************************************************************************/ +#ifndef GIPROBEEDITORPLUGIN_H +#define GIPROBEEDITORPLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/resources/material.h" +#include "scene/3d/gi_probe.h" + + + +class GIProbeEditorPlugin : public EditorPlugin { + + GDCLASS( GIProbeEditorPlugin, EditorPlugin ); + + GIProbe *gi_probe; + + Button *bake; + EditorNode *editor; + + void _bake(); +protected: + + static void _bind_methods(); +public: + + virtual String get_name() const { return "GIProbe"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + GIProbeEditorPlugin(EditorNode *p_node); + ~GIProbeEditorPlugin(); + +}; + +#endif // GIPROBEEDITORPLUGIN_H diff --git a/tools/editor/plugins/item_list_editor_plugin.cpp b/editor/plugins/item_list_editor_plugin.cpp index f31074a9dc..f31074a9dc 100644 --- a/tools/editor/plugins/item_list_editor_plugin.cpp +++ b/editor/plugins/item_list_editor_plugin.cpp diff --git a/editor/plugins/item_list_editor_plugin.h b/editor/plugins/item_list_editor_plugin.h new file mode 100644 index 0000000000..25d6ed6757 --- /dev/null +++ b/editor/plugins/item_list_editor_plugin.h @@ -0,0 +1,230 @@ +/*************************************************************************/ +/* item_list_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef ITEM_LIST_EDITOR_PLUGIN_H +#define ITEM_LIST_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "canvas_item_editor_plugin.h" + +#include "scene/gui/option_button.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/popup_menu.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + + +class ItemListPlugin : public Object { + + GDCLASS(ItemListPlugin,Object); + +protected: + + bool _set(const StringName& p_name, const Variant& p_value); + bool _get(const StringName& p_name,Variant &r_ret) const; + void _get_property_list( List<PropertyInfo> *p_list) const; + +public: + + enum Flags { + + FLAG_ICON=1, + FLAG_CHECKABLE=2, + FLAG_ID=4, + FLAG_ENABLE=8, + FLAG_SEPARATOR=16 + }; + + virtual void set_object(Object *p_object)=0; + virtual bool handles(Object *p_object) const=0; + + virtual int get_flags() const=0; + + virtual void set_item_text(int p_idx, const String& p_text) {} + virtual String get_item_text(int p_idx) const{ return ""; }; + + virtual void set_item_icon(int p_idx, const Ref<Texture>& p_tex) {} + virtual Ref<Texture> get_item_icon(int p_idx) const{ return Ref<Texture>(); }; + + virtual void set_item_checkable(int p_idx, bool p_check) {} + virtual bool is_item_checkable(int p_idx) const{ return false; }; + + virtual void set_item_checked(int p_idx, bool p_checked) {} + virtual bool is_item_checked(int p_idx) const{ return false; }; + + virtual void set_item_enabled(int p_idx, int p_enabled) {} + virtual bool is_item_enabled(int p_idx) const{ return false; }; + + virtual void set_item_id(int p_idx, int p_id) {} + virtual int get_item_id(int p_idx) const{ return -1; }; + + virtual void set_item_separator(int p_idx, bool p_separator) {} + virtual bool is_item_separator(int p_idx) const { return false; }; + + virtual void add_item()=0; + virtual int get_item_count() const=0; + virtual void erase(int p_idx)=0; + + ItemListPlugin() {} +}; + +/////////////////////////////////////////////////////////////// + +class ItemListOptionButtonPlugin : public ItemListPlugin { + + GDCLASS(ItemListOptionButtonPlugin,ItemListPlugin); + + OptionButton *ob; +public: + + virtual void set_object(Object *p_object); + virtual bool handles(Object *p_object) const; + virtual int get_flags() const; + + virtual void set_item_text(int p_idx, const String& p_text) { ob->set_item_text(p_idx,p_text); } + virtual String get_item_text(int p_idx) const { return ob->get_item_text(p_idx); } + + virtual void set_item_icon(int p_idx, const Ref<Texture>& p_tex) { ob->set_item_icon(p_idx, p_tex); } + virtual Ref<Texture> get_item_icon(int p_idx) const { return ob->get_item_icon(p_idx); } + + virtual void set_item_enabled(int p_idx, int p_enabled) { ob->set_item_disabled(p_idx, !p_enabled); } + virtual bool is_item_enabled(int p_idx) const { return !ob->is_item_disabled(p_idx); } + + virtual void set_item_id(int p_idx, int p_id) { ob->set_item_ID(p_idx,p_id); } + virtual int get_item_id(int p_idx) const { return ob->get_item_ID(p_idx); } + + virtual void add_item(); + virtual int get_item_count() const; + virtual void erase(int p_idx); + + ItemListOptionButtonPlugin(); +}; + +class ItemListPopupMenuPlugin : public ItemListPlugin { + + GDCLASS(ItemListPopupMenuPlugin,ItemListPlugin); + + PopupMenu *pp; +public: + + virtual void set_object(Object *p_object); + virtual bool handles(Object *p_object) const; + virtual int get_flags() const; + + virtual void set_item_text(int p_idx, const String& p_text) { pp->set_item_text(p_idx,p_text); } + virtual String get_item_text(int p_idx) const { return pp->get_item_text(p_idx); } + + virtual void set_item_icon(int p_idx, const Ref<Texture>& p_tex) { pp->set_item_icon(p_idx,p_tex); } + virtual Ref<Texture> get_item_icon(int p_idx) const { return pp->get_item_icon(p_idx); } + + virtual void set_item_checkable(int p_idx, bool p_check) { pp->set_item_as_checkable(p_idx,p_check); } + virtual bool is_item_checkable(int p_idx) const { return pp->is_item_checkable(p_idx); } + + virtual void set_item_checked(int p_idx, bool p_checked) { pp->set_item_checked(p_idx,p_checked); } + virtual bool is_item_checked(int p_idx) const { return pp->is_item_checked(p_idx); } + + virtual void set_item_enabled(int p_idx, int p_enabled) { pp->set_item_disabled(p_idx,!p_enabled); } + virtual bool is_item_enabled(int p_idx) const { return !pp->is_item_disabled(p_idx); } + + virtual void set_item_id(int p_idx, int p_id) { pp->set_item_ID(p_idx,p_idx); } + virtual int get_item_id(int p_idx) const { return pp->get_item_ID(p_idx); } + + virtual void set_item_separator(int p_idx, bool p_separator) { pp->set_item_as_separator(p_idx,p_separator); } + virtual bool is_item_separator(int p_idx) const { return pp->is_item_separator(p_idx); } + + virtual void add_item(); + virtual int get_item_count() const; + virtual void erase(int p_idx); + + ItemListPopupMenuPlugin(); +}; + +/////////////////////////////////////////////////////////////// + +class ItemListEditor : public HBoxContainer { + + GDCLASS(ItemListEditor,HBoxContainer); + + Node *item_list; + + ToolButton *toolbar_button; + + AcceptDialog *dialog; + PropertyEditor *property_editor; + Tree *tree; + Button *add_button; + Button *del_button; + + int selected_idx; + + Vector<ItemListPlugin*> item_plugins; + + void _edit_items(); + + void _add_pressed(); + void _delete_pressed(); + + void _node_removed(Node *p_node); + +protected: + + void _notification(int p_notification); + static void _bind_methods(); +public: + + void edit(Node *p_item_list); + bool handles(Object *p_object) const; + void add_plugin(ItemListPlugin* p_plugin) { item_plugins.push_back(p_plugin); } + ItemListEditor(); + ~ItemListEditor(); +}; + +class ItemListEditorPlugin : public EditorPlugin { + + GDCLASS(ItemListEditorPlugin,EditorPlugin); + + ItemListEditor *item_list_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "ItemList"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + ItemListEditorPlugin(EditorNode *p_node); + ~ItemListEditorPlugin(); + +}; + +#endif // ITEM_LIST_EDITOR_PLUGIN_H diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp new file mode 100644 index 0000000000..be9e52e241 --- /dev/null +++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp @@ -0,0 +1,518 @@ +/*************************************************************************/ +/* light_occluder_2d_editor_plugin.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 "light_occluder_2d_editor_plugin.h" + +#include "canvas_item_editor_plugin.h" +#include "os/file_access.h" +#include "editor/editor_settings.h" + +void LightOccluder2DEditor::_notification(int p_what) { + + switch(p_what) { + + case NOTIFICATION_READY: { + + button_create->set_icon( get_icon("Edit","EditorIcons")); + button_edit->set_icon( get_icon("MovePoint","EditorIcons")); + button_edit->set_pressed(true); + get_tree()->connect("node_removed",this,"_node_removed"); + create_poly->connect("confirmed",this,"_create_poly"); + + } break; + case NOTIFICATION_FIXED_PROCESS: { + + + } break; + } + +} +void LightOccluder2DEditor::_node_removed(Node *p_node) { + + if(p_node==node) { + node=NULL; + hide(); + canvas_item_editor->get_viewport_control()->update(); + } + +} + + +void LightOccluder2DEditor::_menu_option(int p_option) { + + switch(p_option) { + + case MODE_CREATE: { + + mode=MODE_CREATE; + button_create->set_pressed(true); + button_edit->set_pressed(false); + } break; + case MODE_EDIT: { + + mode=MODE_EDIT; + button_create->set_pressed(false); + button_edit->set_pressed(true); + } break; + + } +} + +void LightOccluder2DEditor::_wip_close(bool p_closed) { + + undo_redo->create_action(TTR("Create Poly")); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",node->get_occluder_polygon()->get_polygon()); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",wip); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_closed",node->get_occluder_polygon()->is_closed()); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_closed",p_closed); + + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + wip.clear(); + wip_active=false; + mode=MODE_EDIT; + button_edit->set_pressed(true); + button_create->set_pressed(false); + edited_point=-1; +} + +bool LightOccluder2DEditor::forward_gui_input(const InputEvent& p_event) { + + + if (!node) + return false; + + if (node->get_occluder_polygon().is_null()) { + if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { + create_poly->set_text("No OccluderPolygon2D resource on this node.\nCreate and assign one?"); + create_poly->popup_centered_minsize(); + } + return (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1); + } + switch(p_event.type) { + + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &mb=p_event.mouse_button; + + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + + + Vector2 gpoint = Point2(mb.x,mb.y); + Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); + cpoint=canvas_item_editor->snap_point(cpoint); + cpoint = node->get_global_transform().affine_inverse().xform(cpoint); + + Vector<Vector2> poly = Variant(node->get_occluder_polygon()->get_polygon()); + + //first check if a point is to be added (segment split) + real_t grab_treshold=EDITOR_DEF("editors/poly_editor/point_grab_radius",8); + + switch(mode) { + + + case MODE_CREATE: { + + if (mb.button_index==BUTTON_LEFT && mb.pressed) { + + + if (!wip_active) { + + wip.clear(); + wip.push_back( cpoint ); + wip_active=true; + edited_point_pos=cpoint; + canvas_item_editor->get_viewport_control()->update(); + edited_point=1; + return true; + } else { + + + if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) { + //wip closed + _wip_close(true); + + return true; + } else if (wip.size()>1 && xform.xform(wip[wip.size()-1]).distance_to(gpoint)<grab_treshold) { + //wip closed + _wip_close(false); + return true; + + } else { + + wip.push_back( cpoint ); + edited_point=wip.size(); + canvas_item_editor->get_viewport_control()->update(); + return true; + + //add wip point + } + } + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { + _wip_close(true); + } + + + + } break; + + case MODE_EDIT: { + + if (mb.button_index==BUTTON_LEFT) { + if (mb.pressed) { + + if (mb.mod.control) { + + + if (poly.size() < 3) { + + undo_redo->create_action(TTR("Edit Poly")); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + poly.push_back(cpoint); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + return true; + } + + //search edges + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 points[2] ={ xform.xform(poly[i]), + xform.xform(poly[(i+1)%poly.size()]) }; + + Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points); + if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2) + continue; //not valid to reuse point + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + + } + + if (closest_idx>=0) { + + pre_move_edit=poly; + poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos)); + edited_point=closest_idx+1; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + node->get_occluder_polygon()->set_polygon(Variant(poly)); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } else { + + //look for points to move + + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 cp =xform.xform(poly[i]); + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + } + + if (closest_idx>=0) { + + pre_move_edit=poly; + edited_point=closest_idx; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } + } else { + + if (edited_point!=-1) { + + //apply + + ERR_FAIL_INDEX_V(edited_point,poly.size(),false); + poly[edited_point]=edited_point_pos; + undo_redo->create_action(TTR("Edit Poly")); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",pre_move_edit); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + + edited_point=-1; + return true; + } + } + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { + + + + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 cp =xform.xform(poly[i]); + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + } + + if (closest_idx>=0) { + + + undo_redo->create_action(TTR("Edit Poly (Remove Point)")); + undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + poly.remove(closest_idx); + undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + return true; + } + + } + + + + } break; + } + + + + } break; + case InputEvent::MOUSE_MOTION: { + + const InputEventMouseMotion &mm=p_event.mouse_motion; + + if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { + + Vector2 gpoint = Point2(mm.x,mm.y); + Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); + cpoint=canvas_item_editor->snap_point(cpoint); + edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint); + + canvas_item_editor->get_viewport_control()->update(); + + } + + } break; + } + + return false; +} +void LightOccluder2DEditor::_canvas_draw() { + + if (!node || !node->get_occluder_polygon().is_valid()) + return; + + Control *vpc = canvas_item_editor->get_viewport_control(); + + Vector<Vector2> poly; + + if (wip_active) + poly=wip; + else + poly=Variant(node->get_occluder_polygon()->get_polygon()); + + + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + Ref<Texture> handle= get_icon("EditorHandle","EditorIcons"); + + for(int i=0;i<poly.size();i++) { + + + Vector2 p,p2; + p = i==edited_point ? edited_point_pos : poly[i]; + if ((wip_active && i==poly.size()-1) || (((i+1)%poly.size())==edited_point)) + p2=edited_point_pos; + else + p2 = poly[(i+1)%poly.size()]; + + Vector2 point = xform.xform(p); + Vector2 next_point = xform.xform(p2); + + Color col=Color(1,0.3,0.1,0.8); + + if (i==poly.size()-1 && (!node->get_occluder_polygon()->is_closed() || wip_active)) { + + } else { + vpc->draw_line(point,next_point,col,2); + } + vpc->draw_texture(handle,point-handle->get_size()*0.5); + } +} + + + +void LightOccluder2DEditor::edit(Node *p_collision_polygon) { + + if (!canvas_item_editor) { + canvas_item_editor=CanvasItemEditor::get_singleton(); + } + + if (p_collision_polygon) { + + node=p_collision_polygon->cast_to<LightOccluder2D>(); + if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw"); + wip.clear(); + wip_active=false; + edited_point=-1; + canvas_item_editor->get_viewport_control()->update(); + } else { + node=NULL; + + if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw"); + + } + +} + +void LightOccluder2DEditor::_create_poly() { + + if (!node) + return; + undo_redo->create_action(TTR("Create Occluder Polygon")); + undo_redo->add_do_method(node,"set_occluder_polygon",Ref<OccluderPolygon2D>(memnew( OccluderPolygon2D))); + undo_redo->add_undo_method(node,"set_occluder_polygon",Variant(REF())); + undo_redo->commit_action(); +} + +void LightOccluder2DEditor::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_menu_option"),&LightOccluder2DEditor::_menu_option); + ClassDB::bind_method(D_METHOD("_canvas_draw"),&LightOccluder2DEditor::_canvas_draw); + ClassDB::bind_method(D_METHOD("_node_removed"),&LightOccluder2DEditor::_node_removed); + ClassDB::bind_method(D_METHOD("_create_poly"),&LightOccluder2DEditor::_create_poly); + +} + + +LightOccluder2DEditor::LightOccluder2DEditor(EditorNode *p_editor) { + + node=NULL; + canvas_item_editor=NULL; + editor=p_editor; + undo_redo = editor->get_undo_redo(); + + add_child( memnew( VSeparator )); + button_create = memnew( ToolButton ); + add_child(button_create); + button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE)); + button_create->set_toggle_mode(true); + button_create->set_tooltip(TTR("Create a new polygon from scratch.")); + + button_edit = memnew( ToolButton ); + add_child(button_edit); + button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT)); + button_edit->set_toggle_mode(true); + button_edit->set_tooltip(TTR("Edit existing polygon:")+"\n"+TTR("LMB: Move Point.")+"\n"+TTR("Ctrl+LMB: Split Segment.")+"\n"+TTR("RMB: Erase Point.")); + + create_poly = memnew( ConfirmationDialog ); + add_child(create_poly); + create_poly->get_ok()->set_text(TTR("Create")); + + + //add_constant_override("separation",0); + +#if 0 + options = memnew( MenuButton ); + add_child(options); + options->set_area_as_parent_rect(); + options->set_text("Polygon"); + //options->get_popup()->add_item("Parse BBCode",PARSE_BBCODE); + options->get_popup()->connect("id_pressed", this,"_menu_option"); +#endif + + mode = MODE_EDIT; + wip_active=false; + +} + + +void LightOccluder2DEditorPlugin::edit(Object *p_object) { + + collision_polygon_editor->edit(p_object->cast_to<Node>()); +} + +bool LightOccluder2DEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("LightOccluder2D"); +} + +void LightOccluder2DEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + collision_polygon_editor->show(); + } else { + + collision_polygon_editor->hide(); + collision_polygon_editor->edit(NULL); + } + +} + +LightOccluder2DEditorPlugin::LightOccluder2DEditorPlugin(EditorNode *p_node) { + + editor=p_node; + collision_polygon_editor = memnew( LightOccluder2DEditor(p_node) ); + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); + + collision_polygon_editor->hide(); + + + +} + + +LightOccluder2DEditorPlugin::~LightOccluder2DEditorPlugin() +{ +} + diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h new file mode 100644 index 0000000000..1f1c6e86eb --- /dev/null +++ b/editor/plugins/light_occluder_2d_editor_plugin.h @@ -0,0 +1,115 @@ +/*************************************************************************/ +/* light_occluder_2d_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H +#define LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H + + + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/2d/light_occluder_2d.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/button_group.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ +class CanvasItemEditor; + +class LightOccluder2DEditor : public HBoxContainer { + + GDCLASS(LightOccluder2DEditor, HBoxContainer ); + + UndoRedo *undo_redo; + enum Mode { + + MODE_CREATE, + MODE_EDIT, + + }; + + Mode mode; + + ToolButton *button_create; + ToolButton *button_edit; + + CanvasItemEditor *canvas_item_editor; + EditorNode *editor; + Panel *panel; + LightOccluder2D *node; + MenuButton *options; + + int edited_point; + Vector2 edited_point_pos; + Vector<Vector2> pre_move_edit; + Vector<Vector2> wip; + bool wip_active; + + ConfirmationDialog *create_poly; + + void _wip_close(bool p_closed); + void _canvas_draw(); + void _menu_option(int p_option); + void _create_poly(); + +protected: + void _notification(int p_what); + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + Vector2 snap_point(const Vector2& p_point) const; + bool forward_gui_input(const InputEvent& p_event); + void edit(Node *p_collision_polygon); + LightOccluder2DEditor(EditorNode *p_editor); +}; + +class LightOccluder2DEditorPlugin : public EditorPlugin { + + GDCLASS( LightOccluder2DEditorPlugin, EditorPlugin ); + + LightOccluder2DEditor *collision_polygon_editor; + EditorNode *editor; + +public: + + virtual bool forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); } + + virtual String get_name() const { return "LightOccluder2D"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + LightOccluder2DEditorPlugin(EditorNode *p_node); + ~LightOccluder2DEditorPlugin(); + +}; + +#endif // LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H diff --git a/editor/plugins/line_2d_editor_plugin.cpp b/editor/plugins/line_2d_editor_plugin.cpp new file mode 100644 index 0000000000..d00165d3ff --- /dev/null +++ b/editor/plugins/line_2d_editor_plugin.cpp @@ -0,0 +1,283 @@ +#include "line_2d_editor_plugin.h" + +#include "canvas_item_editor_plugin.h" +#include "os/file_access.h" +#include "editor/editor_settings.h" +#include "os/keyboard.h" + + +//---------------------------------------------------------------------------- +// Line2DEditor +//---------------------------------------------------------------------------- + +void Line2DEditor::_node_removed(Node *p_node) { + if(p_node == node) { + node=NULL; + hide(); + } +} + +void Line2DEditor::_notification(int p_what) { + switch(p_what) { + case NOTIFICATION_VISIBILITY_CHANGED: + // This widget is not a child but should have the same visibility state + base_hb->set_visible(is_visible()); + break; + } +} + +Vector2 Line2DEditor::mouse_to_local_pos(Vector2 gpoint, bool alt) { + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + return !alt? canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)) + : node->get_global_transform().affine_inverse().xform( + canvas_item_editor->snap_point( + canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)) ); +} + +int Line2DEditor::get_point_index_at(Vector2 gpos) { + ERR_FAIL_COND_V(node == 0, -1); + + real_t grab_treshold = EDITOR_DEF("poly_editor/point_grab_radius", 8); + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + + for(int i = 0; i < node->get_point_count(); ++i) { + Point2 p = xform.xform( node->get_point_pos(i) ); + if(gpos.distance_to(p) < grab_treshold) { + return i; + } + } + + return -1; +} + +bool Line2DEditor::forward_gui_input(const InputEvent& p_event) { + + if (!node) + return false; + + if (!node->is_visible()) + return false; + + switch(p_event.type) { + + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &mb = p_event.mouse_button; + + Vector2 gpoint = Point2(mb.x,mb.y); + Vector2 cpoint = mouse_to_local_pos(gpoint, mb.mod.alt); + + if(mb.pressed && _dragging == false) { + int i = get_point_index_at(gpoint); + if(i != -1) { + if (mb.button_index == BUTTON_LEFT && !mb.mod.shift && mode == MODE_EDIT) { + _dragging = true; + action_point = i; + moving_from = node->get_point_pos(i); + moving_screen_from = gpoint; + } + else if((mb.button_index == BUTTON_RIGHT && mode == MODE_EDIT) || (mb.button_index == BUTTON_LEFT && mode == MODE_DELETE)) { + undo_redo->create_action(TTR("Remove Point from Line2D")); + undo_redo->add_do_method(node, "remove_point", i); + undo_redo->add_undo_method(node, "add_point", node->get_point_pos(i), i); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update"); + undo_redo->commit_action(); + } + return true; + } + } + + if(mb.pressed && mb.button_index == BUTTON_LEFT && ((mb.mod.command && mode == MODE_EDIT) || mode == MODE_CREATE)) { + + undo_redo->create_action(TTR("Add Point to Line2D")); + undo_redo->add_do_method(node, "add_point", cpoint); + undo_redo->add_undo_method(node, "remove_point", node->get_point_count()); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update"); + undo_redo->commit_action(); + + _dragging = true; + action_point = node->get_point_count()-1; + moving_from = node->get_point_pos(action_point); + moving_screen_from = gpoint; + + canvas_item_editor->get_viewport_control()->update(); + + return true; + } + + if(!mb.pressed && mb.button_index == BUTTON_LEFT && _dragging) { + undo_redo->create_action(TTR("Move Point in Line2D")); + undo_redo->add_do_method(node, "set_point_pos", action_point, cpoint); + undo_redo->add_undo_method(node, "set_point_pos", action_point, moving_from); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update"); + undo_redo->commit_action(); + _dragging = false; + return true; + } + } + break; + + case InputEvent::MOUSE_MOTION: { + if (_dragging) { + const InputEventMouseMotion &mm = p_event.mouse_motion; + Vector2 cpoint = mouse_to_local_pos(Vector2(mm.x, mm.y), mm.mod.alt); + node->set_point_pos(action_point,cpoint); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } + break; + } + + return false; +} + +void Line2DEditor::_canvas_draw() { + + if (!node) + return; + + if (!node->is_visible()) + return; + + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons"); + Size2 handle_size = handle->get_size(); + + int len = node->get_point_count(); + Control *vpc = canvas_item_editor->get_viewport_control(); + + for(int i=0; i < len; ++i) { + Vector2 point = xform.xform(node->get_point_pos(i)); + vpc->draw_texture_rect(handle, Rect2(point - handle_size * 0.5, handle_size), false); + } +} + +void Line2DEditor::_node_visibility_changed() { + if (!node) + return; + canvas_item_editor->get_viewport_control()->update(); +} + +void Line2DEditor::edit(Node *p_line2d) { + + if (!canvas_item_editor) + canvas_item_editor = CanvasItemEditor::get_singleton(); + + if (p_line2d) { + node = p_line2d->cast_to<Line2D>(); + if (!canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw")) + canvas_item_editor->get_viewport_control()->connect("draw", this, "_canvas_draw"); + if (!node->is_connected("visibility_changed", this, "_node_visibility_changed")) + node->connect("visibility_changed", this, "_node_visibility_changed"); + } + else { + if (canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw")) + canvas_item_editor->get_viewport_control()->disconnect("draw", this, "_canvas_draw"); + // node may have been deleted at this point + if (node && node->is_connected("visibility_changed", this, "_node_visibility_changed")) + node->disconnect("visibility_changed", this, "_node_visibility_changed"); + node = NULL; + } +} + +void Line2DEditor::_bind_methods() { + ClassDB::bind_method(D_METHOD("_canvas_draw"), &Line2DEditor::_canvas_draw); + ClassDB::bind_method(D_METHOD("_node_visibility_changed"), &Line2DEditor::_node_visibility_changed); + ClassDB::bind_method(D_METHOD("_mode_selected"), &Line2DEditor::_mode_selected); +} + +void Line2DEditor::_mode_selected(int p_mode) { + for(unsigned int i = 0; i < _MODE_COUNT; ++i) { + toolbar_buttons[i]->set_pressed(i == p_mode); + } + mode = Mode(p_mode); +} + +Line2DEditor::Line2DEditor(EditorNode *p_editor) { + + canvas_item_editor = NULL; + editor = p_editor; + undo_redo = editor->get_undo_redo(); + + _dragging = false; + + base_hb = memnew( HBoxContainer ); + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(base_hb); + + sep = memnew( VSeparator); + base_hb->add_child(sep); + + { + ToolButton * b = memnew(ToolButton); + b->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveEdit", "EditorIcons")); + b->set_toggle_mode(true); + b->set_focus_mode(Control::FOCUS_NONE); + b->set_tooltip( + TTR("Select Points")+"\n" + + TTR("Shift+Drag: Select Control Points")+"\n" + + keycode_get_string(KEY_MASK_CMD) + + TTR("Click: Add Point")+"\n" + + TTR("Right Click: Delete Point")); + b->connect("pressed", this, "_mode_selected", varray(MODE_EDIT)); + toolbar_buttons[MODE_EDIT] = b; + base_hb->add_child(b); + } + + { + ToolButton * b = memnew(ToolButton); + b->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveCreate", "EditorIcons")); + b->set_toggle_mode(true); + b->set_focus_mode(Control::FOCUS_NONE); + b->set_tooltip(TTR("Add Point (in empty space)")+"\n"+TTR("Split Segment (in line)")); + b->connect("pressed", this, "_mode_selected", varray(MODE_CREATE)); + toolbar_buttons[MODE_CREATE] = b; + base_hb->add_child(b); + } + + { + ToolButton * b = memnew( ToolButton ); + b->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveDelete", "EditorIcons")); + b->set_toggle_mode(true); + b->set_focus_mode(Control::FOCUS_NONE); + b->set_tooltip(TTR("Delete Point")); + b->connect("pressed", this, "_mode_selected", varray(MODE_DELETE)); + toolbar_buttons[MODE_DELETE] = b; + base_hb->add_child(b); + } + + base_hb->hide(); + hide(); + + _mode_selected(MODE_CREATE); +} + +//---------------------------------------------------------------------------- +// Line2DEditorPlugin +//---------------------------------------------------------------------------- + +void Line2DEditorPlugin::edit(Object *p_object) { + line2d_editor->edit(p_object->cast_to<Node>()); +} + +bool Line2DEditorPlugin::handles(Object *p_object) const { + return p_object->is_class("Line2D"); +} + +void Line2DEditorPlugin::make_visible(bool p_visible) { + line2d_editor->set_visible(p_visible); + if(p_visible == false) + line2d_editor->edit(NULL); +} + +Line2DEditorPlugin::Line2DEditorPlugin(EditorNode *p_node) { + editor=p_node; + line2d_editor = memnew( Line2DEditor(p_node) ); + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(line2d_editor); + line2d_editor->hide(); +} + + diff --git a/editor/plugins/line_2d_editor_plugin.h b/editor/plugins/line_2d_editor_plugin.h new file mode 100644 index 0000000000..8c6aed1d2d --- /dev/null +++ b/editor/plugins/line_2d_editor_plugin.h @@ -0,0 +1,90 @@ +#ifndef LINE_2D_EDITOR_PLUGIN_H +#define LINE_2D_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/2d/path_2d.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/button_group.h" +#include "scene/2d/line_2d.h" + + +class CanvasItemEditor; + +class Line2DEditor : public HBoxContainer { + GDCLASS(Line2DEditor, HBoxContainer) + +public: + bool forward_gui_input(const InputEvent& p_event); + void edit(Node *p_line2d); + Line2DEditor(EditorNode *p_editor); + +protected: + void _node_removed(Node *p_node); + void _notification(int p_what); + + Vector2 mouse_to_local_pos(Vector2 mpos); + + static void _bind_methods(); + +private: + void _mode_selected(int p_mode); + void _canvas_draw(); + void _node_visibility_changed(); + + int get_point_index_at(Vector2 gpos); + Vector2 mouse_to_local_pos(Vector2 gpos, bool alt); + + UndoRedo *undo_redo; + + CanvasItemEditor *canvas_item_editor; + EditorNode *editor; + Panel *panel; + Line2D *node; + + HBoxContainer *base_hb; + Separator *sep; + + enum Mode { + MODE_CREATE = 0, + MODE_EDIT, + MODE_DELETE, + _MODE_COUNT + }; + + Mode mode; + ToolButton* toolbar_buttons[_MODE_COUNT]; + + bool _dragging; + int action_point; + Point2 moving_from; + Point2 moving_screen_from; +}; + +class Line2DEditorPlugin : public EditorPlugin { + GDCLASS( Line2DEditorPlugin, EditorPlugin ) + +public: + virtual bool forward_canvas_gui_input( + const Transform2D& p_canvas_xform, + const InputEvent& p_event) + { + return line2d_editor->forward_gui_input(p_event); + } + + virtual String get_name() const { return "Line2D"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + Line2DEditorPlugin(EditorNode *p_node); + +private: + Line2DEditor *line2d_editor; + EditorNode *editor; + +}; + +#endif // LINE_2D_EDITOR_PLUGIN_H + diff --git a/tools/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index cdf7c70d39..cdf7c70d39 100644 --- a/tools/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h new file mode 100644 index 0000000000..604e7e61bd --- /dev/null +++ b/editor/plugins/material_editor_plugin.h @@ -0,0 +1,100 @@ +/*************************************************************************/ +/* material_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef MATERIAL_EDITOR_PLUGIN_H +#define MATERIAL_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/resources/material.h" +#include "scene/3d/light.h" +#include "scene/3d/mesh_instance.h" +#include "scene/3d/camera.h" + +#if 0 +class MaterialEditor : public Control { + + GDCLASS(MaterialEditor, Control); + + + Viewport *viewport; + MeshInstance *sphere_instance; + MeshInstance *box_instance; + DirectionalLight *light1; + DirectionalLight *light2; + Camera *camera; + + Ref<Mesh> sphere_mesh; + Ref<Mesh> box_mesh; + + TextureButton *sphere_switch; + TextureButton *box_switch; + + TextureButton *light_1_switch; + TextureButton *light_2_switch; + + + Ref<Material> material; + + + void _button_pressed(Node* p_button); + bool first_enter; + +protected: + void _notification(int p_what); + void _gui_input(InputEvent p_event); + static void _bind_methods(); +public: + + void edit(Ref<Material> p_material); + MaterialEditor(); +}; + + +class MaterialEditorPlugin : public EditorPlugin { + + GDCLASS( MaterialEditorPlugin, EditorPlugin ); + + MaterialEditor *material_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "Material"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + MaterialEditorPlugin(EditorNode *p_node); + ~MaterialEditorPlugin(); + +}; + +#endif // MATERIAL_EDITOR_PLUGIN_H +#endif diff --git a/tools/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp index 93f417247e..93f417247e 100644 --- a/tools/editor/plugins/mesh_editor_plugin.cpp +++ b/editor/plugins/mesh_editor_plugin.cpp diff --git a/editor/plugins/mesh_editor_plugin.h b/editor/plugins/mesh_editor_plugin.h new file mode 100644 index 0000000000..80504ae445 --- /dev/null +++ b/editor/plugins/mesh_editor_plugin.h @@ -0,0 +1,98 @@ +/*************************************************************************/ +/* mesh_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef MESH_EDITOR_PLUGIN_H +#define MESH_EDITOR_PLUGIN_H + +#if 0 + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/resources/material.h" +#include "scene/3d/light.h" +#include "scene/3d/mesh_instance.h" +#include "scene/3d/camera.h" + +class MeshEditor : public Control { + + GDCLASS(MeshEditor, Control); + + + + float rot_x; + float rot_y; + + Viewport *viewport; + MeshInstance *mesh_instance; + DirectionalLight *light1; + DirectionalLight *light2; + Camera *camera; + + Ref<Mesh> mesh; + + + TextureButton *light_1_switch; + TextureButton *light_2_switch; + + void _button_pressed(Node* p_button); + bool first_enter; + + void _update_rotation(); +protected: + void _notification(int p_what); + void _gui_input(InputEvent p_event); + static void _bind_methods(); +public: + + void edit(Ref<Mesh> p_mesh); + MeshEditor(); +}; + + +class MeshEditorPlugin : public EditorPlugin { + + GDCLASS( MeshEditorPlugin, EditorPlugin ); + + MeshEditor *mesh_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "Mesh"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + MeshEditorPlugin(EditorNode *p_node); + ~MeshEditorPlugin(); + +}; + +#endif // MESH_EDITOR_PLUGIN_H +#endif diff --git a/tools/editor/plugins/mesh_instance_editor_plugin.cpp b/editor/plugins/mesh_instance_editor_plugin.cpp index 322e212534..322e212534 100644 --- a/tools/editor/plugins/mesh_instance_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_editor_plugin.cpp diff --git a/editor/plugins/mesh_instance_editor_plugin.h b/editor/plugins/mesh_instance_editor_plugin.h new file mode 100644 index 0000000000..de5be2fbbb --- /dev/null +++ b/editor/plugins/mesh_instance_editor_plugin.h @@ -0,0 +1,97 @@ +/*************************************************************************/ +/* mesh_instance_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef MESH_INSTANCE_EDITOR_PLUGIN_H +#define MESH_INSTANCE_EDITOR_PLUGIN_H + + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/3d/mesh_instance.h" +#include "scene/gui/spin_box.h" + + +class MeshInstanceEditor : public Node { + + GDCLASS(MeshInstanceEditor, Node ); + + + enum Menu { + + MENU_OPTION_CREATE_STATIC_TRIMESH_BODY, + MENU_OPTION_CREATE_STATIC_CONVEX_BODY, + MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE, + MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE, + MENU_OPTION_CREATE_NAVMESH, + MENU_OPTION_CREATE_OUTLINE_MESH, + }; + + MeshInstance *node; + + MenuButton *options; + + ConfirmationDialog *outline_dialog; + SpinBox *outline_size; + + AcceptDialog *err_dialog; + + void _menu_option(int p_option); + void _create_outline_mesh(); + +friend class MeshInstanceEditorPlugin; + +protected: + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + void edit(MeshInstance *p_mesh); + MeshInstanceEditor(); +}; + +class MeshInstanceEditorPlugin : public EditorPlugin { + + GDCLASS( MeshInstanceEditorPlugin, EditorPlugin ); + + MeshInstanceEditor *mesh_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "MeshInstance"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + MeshInstanceEditorPlugin(EditorNode *p_node); + ~MeshInstanceEditorPlugin(); + +}; + +#endif // MESH_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp index 6259ddf473..6259ddf473 100644 --- a/tools/editor/plugins/multimesh_editor_plugin.cpp +++ b/editor/plugins/multimesh_editor_plugin.cpp diff --git a/editor/plugins/multimesh_editor_plugin.h b/editor/plugins/multimesh_editor_plugin.h new file mode 100644 index 0000000000..a97b3758a1 --- /dev/null +++ b/editor/plugins/multimesh_editor_plugin.h @@ -0,0 +1,107 @@ +/*************************************************************************/ +/* multimesh_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef MULTIMESH_EDITOR_PLUGIN_H +#define MULTIMESH_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/3d/multimesh_instance.h" +#include "scene/gui/spin_box.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +class MultiMeshEditor : public Control { + + GDCLASS(MultiMeshEditor, Control ); + +friend class MultiMeshEditorPlugin; + + AcceptDialog *err_dialog; + MenuButton * options; + MultiMeshInstance *_last_pp_node; + bool browsing_source; + + Panel *panel; + MultiMeshInstance *node; + + LineEdit *surface_source; + LineEdit *mesh_source; + + SceneTreeDialog *std; + + ConfirmationDialog *populate_dialog; + OptionButton *populate_axis; + HSlider *populate_rotate_random; + HSlider *populate_tilt_random; + SpinBox *populate_scale_random; + SpinBox *populate_scale; + SpinBox *populate_amount; + + enum Menu { + + MENU_OPTION_POPULATE + }; + + void _browsed(const NodePath& p_path); + void _menu_option(int); + void _populate(); + void _browse(bool p_source); + +protected: + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + void edit(MultiMeshInstance *p_multimesh); + MultiMeshEditor(); +}; + +class MultiMeshEditorPlugin : public EditorPlugin { + + GDCLASS( MultiMeshEditorPlugin, EditorPlugin ); + + MultiMeshEditor *multimesh_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "MultiMesh"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + MultiMeshEditorPlugin(EditorNode *p_node); + ~MultiMeshEditorPlugin(); + +}; + +#endif // MULTIMESH_EDITOR_PLUGIN_H diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp new file mode 100644 index 0000000000..654afb754e --- /dev/null +++ b/editor/plugins/navigation_polygon_editor_plugin.cpp @@ -0,0 +1,566 @@ +/*************************************************************************/ +/* navigation_polygon_editor_plugin.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 "navigation_polygon_editor_plugin.h" + +#include "canvas_item_editor_plugin.h" +#include "os/file_access.h" +#include "editor/editor_settings.h" + +void NavigationPolygonEditor::_notification(int p_what) { + + switch(p_what) { + + case NOTIFICATION_READY: { + + button_create->set_icon( get_icon("Edit","EditorIcons")); + button_edit->set_icon( get_icon("MovePoint","EditorIcons")); + button_edit->set_pressed(true); + get_tree()->connect("node_removed",this,"_node_removed"); + create_nav->connect("confirmed",this,"_create_nav"); + + } break; + case NOTIFICATION_FIXED_PROCESS: { + + + } break; + } + +} +void NavigationPolygonEditor::_node_removed(Node *p_node) { + + if(p_node==node) { + node=NULL; + hide(); + canvas_item_editor->get_viewport_control()->update(); + } + +} + +void NavigationPolygonEditor::_create_nav() { + + if (!node) + return; + + undo_redo->create_action(TTR("Create Navigation Polygon")); + undo_redo->add_do_method(node,"set_navigation_polygon",Ref<NavigationPolygon>(memnew( NavigationPolygon))); + undo_redo->add_undo_method(node,"set_navigation_polygon",Variant(REF())); + undo_redo->commit_action(); +} + +void NavigationPolygonEditor::_menu_option(int p_option) { + + switch(p_option) { + + case MODE_CREATE: { + + mode=MODE_CREATE; + button_create->set_pressed(true); + button_edit->set_pressed(false); + } break; + case MODE_EDIT: { + + mode=MODE_EDIT; + button_create->set_pressed(false); + button_edit->set_pressed(true); + } break; + + } +} + +void NavigationPolygonEditor::_wip_close() { + + + if (wip.size()>=3) { + + undo_redo->create_action(TTR("Create Poly")); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"remove_outline",node->get_navigation_polygon()->get_outline_count()); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"add_outline",wip); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + mode=MODE_EDIT; + button_edit->set_pressed(true); + button_create->set_pressed(false); + } + + wip.clear(); + wip_active=false; + edited_point=-1; +} + +bool NavigationPolygonEditor::forward_gui_input(const InputEvent& p_event) { + + + if (!node) + return false; + + if (node->get_navigation_polygon().is_null()) { + if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { + create_nav->set_text("No NavigationPolygon resource on this node.\nCreate and assign one?"); + create_nav->popup_centered_minsize(); + } + return (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1); + } + + + switch(p_event.type) { + + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &mb=p_event.mouse_button; + + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + + + Vector2 gpoint = Point2(mb.x,mb.y); + Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); + cpoint=canvas_item_editor->snap_point(cpoint); + cpoint = node->get_global_transform().affine_inverse().xform(cpoint); + + + + //first check if a point is to be added (segment split) + real_t grab_treshold=EDITOR_DEF("editors/poly_editor/point_grab_radius",8); + + switch(mode) { + + + case MODE_CREATE: { + + if (mb.button_index==BUTTON_LEFT && mb.pressed) { + + + if (!wip_active) { + + wip.clear(); + wip.push_back( cpoint ); + wip_active=true; + edited_point_pos=cpoint; + edited_outline=-1; + canvas_item_editor->get_viewport_control()->update(); + edited_point=1; + return true; + } else { + + + if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) { + //wip closed + _wip_close(); + + return true; + } else { + + wip.push_back( cpoint ); + edited_point=wip.size(); + canvas_item_editor->get_viewport_control()->update(); + return true; + + //add wip point + } + } + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { + _wip_close(); + } + + + + } break; + + case MODE_EDIT: { + + if (mb.button_index==BUTTON_LEFT) { + if (mb.pressed) { + + if (mb.mod.control) { + + + //search edges + int closest_outline=-1; + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + + for(int j=0;j<node->get_navigation_polygon()->get_outline_count();j++) { + + + PoolVector<Vector2> points=node->get_navigation_polygon()->get_outline(j); + + int pc=points.size(); + PoolVector<Vector2>::Read poly=points.read(); + + for(int i=0;i<pc;i++) { + + Vector2 points[2] ={ xform.xform(poly[i]), + xform.xform(poly[(i+1)%pc]) }; + + Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points); + if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2) + continue; //not valid to reuse point + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_outline=j; + closest_pos=cp; + closest_idx=i; + } + + + } + } + + if (closest_idx>=0) { + + pre_move_edit=node->get_navigation_polygon()->get_outline(closest_outline); + PoolVector<Point2> poly = pre_move_edit; + poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos)); + edited_point=closest_idx+1; + edited_outline=closest_outline; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + node->get_navigation_polygon()->set_outline(closest_outline,poly); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } else { + + //look for points to move + int closest_outline=-1; + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + + for(int j=0;j<node->get_navigation_polygon()->get_outline_count();j++) { + + + PoolVector<Vector2> points=node->get_navigation_polygon()->get_outline(j); + + int pc=points.size(); + PoolVector<Vector2>::Read poly=points.read(); + + for(int i=0;i<pc;i++) { + + + Vector2 cp =xform.xform(poly[i]); + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_outline=j; + closest_idx=i; + } + } + } + + if (closest_idx>=0) { + + pre_move_edit=node->get_navigation_polygon()->get_outline(closest_outline); + edited_point=closest_idx; + edited_outline=closest_outline; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } + } else { + + if (edited_point!=-1) { + + //apply + + PoolVector<Vector2> poly = node->get_navigation_polygon()->get_outline(edited_outline); + ERR_FAIL_INDEX_V(edited_point,poly.size(),false); + poly.set(edited_point,edited_point_pos); + undo_redo->create_action(TTR("Edit Poly")); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"set_outline",edited_outline,poly); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"set_outline",edited_outline,pre_move_edit); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + + edited_point=-1; + return true; + } + } + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { + + int closest_outline=-1; + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + + for(int j=0;j<node->get_navigation_polygon()->get_outline_count();j++) { + + + PoolVector<Vector2> points=node->get_navigation_polygon()->get_outline(j); + + int pc=points.size(); + PoolVector<Vector2>::Read poly=points.read(); + + for(int i=0;i<pc;i++) { + + + Vector2 cp =xform.xform(poly[i]); + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_outline=j; + closest_idx=i; + } + } + } + + if (closest_idx>=0) { + + + PoolVector<Vector2> poly = node->get_navigation_polygon()->get_outline(closest_outline); + + if (poly.size()>3) { + undo_redo->create_action(TTR("Edit Poly (Remove Point)")); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"set_outline",closest_outline,poly); + poly.remove(closest_idx); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"set_outline",closest_outline,poly); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + } else { + + undo_redo->create_action(TTR("Remove Poly And Point")); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"add_outline_at_index",poly,closest_outline); + poly.remove(closest_idx); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"remove_outline",closest_outline); + undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + + } + return true; + } + } + + + + } break; + } + + + + } break; + case InputEvent::MOUSE_MOTION: { + + const InputEventMouseMotion &mm=p_event.mouse_motion; + + if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { + + Vector2 gpoint = Point2(mm.x,mm.y); + Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); + cpoint=canvas_item_editor->snap_point(cpoint); + edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint); + + canvas_item_editor->get_viewport_control()->update(); + + } + + } break; + } + + return false; +} +void NavigationPolygonEditor::_canvas_draw() { + + if (!node) + return; + + Control *vpc = canvas_item_editor->get_viewport_control(); + if (node->get_navigation_polygon().is_null()) + return; + + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + Ref<Texture> handle= get_icon("EditorHandle","EditorIcons"); + + + + for(int j=-1;j<node->get_navigation_polygon()->get_outline_count();j++) { + Vector<Vector2> poly; + + if (wip_active && j==edited_outline) { + poly=wip; + } else { + if (j==-1) + continue; + poly = Variant(node->get_navigation_polygon()->get_outline(j)); + } + + for(int i=0;i<poly.size();i++) { + + + Vector2 p,p2; + p = (j==edited_outline && i==edited_point) ? edited_point_pos : poly[i]; + if (j==edited_outline && ((wip_active && i==poly.size()-1) || (((i+1)%poly.size())==edited_point))) + p2=edited_point_pos; + else + p2 = poly[(i+1)%poly.size()]; + + Vector2 point = xform.xform(p); + Vector2 next_point = xform.xform(p2); + + Color col=Color(1,0.3,0.1,0.8); + vpc->draw_line(point,next_point,col,2); + vpc->draw_texture(handle,point-handle->get_size()*0.5); + } + } +} + + + +void NavigationPolygonEditor::edit(Node *p_collision_polygon) { + + if (!canvas_item_editor) { + canvas_item_editor=CanvasItemEditor::get_singleton(); + } + + if (p_collision_polygon) { + + node=p_collision_polygon->cast_to<NavigationPolygonInstance>(); + if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw"); + wip.clear(); + wip_active=false; + edited_point=-1; + canvas_item_editor->get_viewport_control()->update(); + + } else { + node=NULL; + + if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw"); + + } + +} + +void NavigationPolygonEditor::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_menu_option"),&NavigationPolygonEditor::_menu_option); + ClassDB::bind_method(D_METHOD("_canvas_draw"),&NavigationPolygonEditor::_canvas_draw); + ClassDB::bind_method(D_METHOD("_node_removed"),&NavigationPolygonEditor::_node_removed); + ClassDB::bind_method(D_METHOD("_create_nav"),&NavigationPolygonEditor::_create_nav); + +} + +NavigationPolygonEditor::NavigationPolygonEditor(EditorNode *p_editor) { + node=NULL; + canvas_item_editor=NULL; + editor=p_editor; + undo_redo = editor->get_undo_redo(); + + add_child( memnew( VSeparator )); + button_create = memnew( ToolButton ); + add_child(button_create); + button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE)); + button_create->set_toggle_mode(true); + button_create->set_tooltip(TTR("Create a new polygon from scratch.")); + + button_edit = memnew( ToolButton ); + add_child(button_edit); + button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT)); + button_edit->set_toggle_mode(true); + button_edit->set_tooltip(TTR("Edit existing polygon:")+"\n"+TTR("LMB: Move Point.")+"\n"+TTR("Ctrl+LMB: Split Segment.")+"\n"+TTR("RMB: Erase Point.")); + create_nav = memnew( ConfirmationDialog ); + add_child(create_nav); + create_nav->get_ok()->set_text(TTR("Create")); + + + //add_constant_override("separation",0); + +#if 0 + options = memnew( MenuButton ); + add_child(options); + options->set_area_as_parent_rect(); + options->set_text("Polygon"); + //options->get_popup()->add_item("Parse BBCode",PARSE_BBCODE); + options->get_popup()->connect("id_pressed", this,"_menu_option"); +#endif + + mode = MODE_EDIT; + wip_active=false; + edited_outline=-1; + +} + + +void NavigationPolygonEditorPlugin::edit(Object *p_object) { + + collision_polygon_editor->edit(p_object->cast_to<Node>()); +} + +bool NavigationPolygonEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("NavigationPolygonInstance"); +} + +void NavigationPolygonEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + collision_polygon_editor->show(); + } else { + + collision_polygon_editor->hide(); + collision_polygon_editor->edit(NULL); + } + +} + +NavigationPolygonEditorPlugin::NavigationPolygonEditorPlugin(EditorNode *p_node) { + + editor=p_node; + collision_polygon_editor = memnew( NavigationPolygonEditor(p_node) ); + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); + + collision_polygon_editor->hide(); + + + +} + + +NavigationPolygonEditorPlugin::~NavigationPolygonEditorPlugin() +{ +} + diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h new file mode 100644 index 0000000000..0d5e67e352 --- /dev/null +++ b/editor/plugins/navigation_polygon_editor_plugin.h @@ -0,0 +1,118 @@ +/*************************************************************************/ +/* navigation_polygon_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef NAVIGATIONPOLYGONEDITORPLUGIN_H +#define NAVIGATIONPOLYGONEDITORPLUGIN_H + + + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/2d/navigation_polygon.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/button_group.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ +class CanvasItemEditor; + +class NavigationPolygonEditor : public HBoxContainer { + + GDCLASS(NavigationPolygonEditor, HBoxContainer ); + + UndoRedo *undo_redo; + enum Mode { + + MODE_CREATE, + MODE_EDIT, + + }; + + Mode mode; + + ToolButton *button_create; + ToolButton *button_edit; + + ConfirmationDialog *create_nav; + + CanvasItemEditor *canvas_item_editor; + EditorNode *editor; + Panel *panel; + NavigationPolygonInstance *node; + MenuButton *options; + + int edited_outline; + int edited_point; + Vector2 edited_point_pos; + PoolVector<Vector2> pre_move_edit; + Vector<Vector2> wip; + bool wip_active; + + + void _wip_close(); + void _canvas_draw(); + void _create_nav(); + + void _menu_option(int p_option); + +protected: + void _notification(int p_what); + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + bool forward_gui_input(const InputEvent& p_event); + void edit(Node *p_collision_polygon); + NavigationPolygonEditor(EditorNode *p_editor); +}; + +class NavigationPolygonEditorPlugin : public EditorPlugin { + + GDCLASS( NavigationPolygonEditorPlugin, EditorPlugin ); + + NavigationPolygonEditor *collision_polygon_editor; + EditorNode *editor; + +public: + + virtual bool forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); } + + virtual String get_name() const { return "NavigationPolygonInstance"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + NavigationPolygonEditorPlugin(EditorNode *p_node); + ~NavigationPolygonEditorPlugin(); + +}; + + +#endif // NAVIGATIONPOLYGONEDITORPLUGIN_H diff --git a/tools/editor/plugins/particles_2d_editor_plugin.cpp b/editor/plugins/particles_2d_editor_plugin.cpp index 1efdbe9e68..1efdbe9e68 100644 --- a/tools/editor/plugins/particles_2d_editor_plugin.cpp +++ b/editor/plugins/particles_2d_editor_plugin.cpp diff --git a/editor/plugins/particles_2d_editor_plugin.h b/editor/plugins/particles_2d_editor_plugin.h new file mode 100644 index 0000000000..ea71c739f3 --- /dev/null +++ b/editor/plugins/particles_2d_editor_plugin.h @@ -0,0 +1,82 @@ +/*************************************************************************/ +/* particles_2d_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef PARTICLES_2D_EDITOR_PLUGIN_H +#define PARTICLES_2D_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/2d/collision_polygon_2d.h" + +#include "scene/gui/box_container.h" +#include "scene/gui/file_dialog.h" +#include "scene/2d/particles_2d.h" + +class Particles2DEditorPlugin : public EditorPlugin { + + GDCLASS( Particles2DEditorPlugin, EditorPlugin ); + + enum { + + MENU_LOAD_EMISSION_MASK, + MENU_CLEAR_EMISSION_MASK + }; + + Particles2D *particles; + + EditorFileDialog *file; + EditorNode *editor; + + HBoxContainer *toolbar; + MenuButton *menu; + + SpinBox *epoints; + + UndoRedo *undo_redo; + void _file_selected(const String& p_file); + void _menu_callback(int p_idx); +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + + + virtual String get_name() const { return "Particles2D"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + Particles2DEditorPlugin(EditorNode *p_node); + ~Particles2DEditorPlugin(); + +}; + + +#endif // PARTICLES_2D_EDITOR_PLUGIN_H diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp new file mode 100644 index 0000000000..4ce1f5eb54 --- /dev/null +++ b/editor/plugins/particles_editor_plugin.cpp @@ -0,0 +1,461 @@ +/*************************************************************************/ +/* particles_editor_plugin.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. */ +/*************************************************************************/ + +#if 0 +#include "particles_editor_plugin.h" +#include "io/resource_loader.h" +#include "servers/visual/particle_system_sw.h" +#include "editor/plugins/spatial_editor_plugin.h" + + +void ParticlesEditor::_node_removed(Node *p_node) { + + if(p_node==node) { + node=NULL; + hide(); + } + +} + + +void ParticlesEditor::_resource_seleted(const String& p_res) { + + //print_line("selected resource path: "+p_res); +} + +void ParticlesEditor::_node_selected(const NodePath& p_path){ + + + Node *sel = get_node(p_path); + if (!sel) + return; + + VisualInstance *vi = sel->cast_to<VisualInstance>(); + if (!vi) { + + err_dialog->set_text(TTR("Node does not contain geometry.")); + err_dialog->popup_centered_minsize(); + return; + } + + geometry = vi->get_faces(VisualInstance::FACES_SOLID); + + if (geometry.size()==0) { + + err_dialog->set_text(TTR("Node does not contain geometry (faces).")); + err_dialog->popup_centered_minsize(); + return; + + } + + Transform geom_xform = node->get_global_transform().affine_inverse() * vi->get_global_transform(); + + int gc = geometry.size(); + PoolVector<Face3>::Write w = geometry.write(); + + + for(int i=0;i<gc;i++) { + for(int j=0;j<3;j++) { + w[i].vertex[j] = geom_xform.xform( w[i].vertex[j] ); + } + } + + + w = PoolVector<Face3>::Write(); + + emission_dialog->popup_centered(Size2(300,130)); +} + + +/* + +void ParticlesEditor::_populate() { + + if(!node) + return; + + + if (node->get_particles().is_null()) + return; + + node->get_particles()->set_instance_count(populate_amount->get_text().to_int()); + node->populate_parent(populate_rotate_random->get_val(),populate_tilt_random->get_val(),populate_scale_random->get_text().to_double(),populate_scale->get_text().to_double()); + +} +*/ + +void ParticlesEditor::_notification(int p_notification) { + + if (p_notification==NOTIFICATION_ENTER_TREE) { + options->set_icon(options->get_popup()->get_icon("Particles","EditorIcons")); + + } +} + + +void ParticlesEditor::_menu_option(int p_option) { + + + switch(p_option) { + + case MENU_OPTION_GENERATE_AABB: { + + Transform globalizer = node->get_global_transform(); + ParticleSystemSW pssw; + for(int i=0;i<VS::PARTICLE_VAR_MAX;i++) { + + pssw.particle_vars[i]=node->get_variable((Particles::Variable)i); + pssw.particle_randomness[i]=node->get_randomness((Particles::Variable)i); + } + + pssw.emission_half_extents=node->get_emission_half_extents(); + pssw.emission_points=node->get_emission_points(); + pssw.emission_base_velocity=node->get_emission_base_velocity(); + pssw.amount=node->get_amount(); + pssw.gravity_normal=node->get_gravity_normal(); + pssw.emitting=true; + pssw.height_from_velocity=node->has_height_from_velocity(); + pssw.color_phase_count=1; + + + ParticleSystemProcessSW pp; + float delta=0.01; + float lifetime=pssw.particle_vars[VS::PARTICLE_LIFETIME]; + + + Transform localizer = globalizer.affine_inverse(); + AABB aabb; + for(float t=0;t<lifetime;t+=delta) { + + pp.process(&pssw,globalizer,delta); + for(int i=0;i<pp.particle_data.size();i++) { + + Vector3 p = localizer.xform(pp.particle_data[i].pos); + + if (t==0 && i==0) + aabb.pos=p; + else + aabb.expand_to(p); + } + } + + aabb.grow_by( aabb.get_longest_axis_size()*0.2); + + node->set_visibility_aabb(aabb); + + + } break; + case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH: { + + + emission_file_dialog->popup_centered_ratio(); + + } break; + + case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE: { +/* + Node *root = get_scene()->get_root_node(); + ERR_FAIL_COND(!root); + EditorNode *en = root->cast_to<EditorNode>(); + ERR_FAIL_COND(!en); + Node * node = en->get_edited_scene(); +*/ + emission_tree_dialog->popup_centered_ratio(); + + } break; + } +} + + +void ParticlesEditor::edit(Particles *p_particles) { + + node=p_particles; + +} + +void ParticlesEditor::_generate_emission_points() { + + /// hacer codigo aca + PoolVector<Vector3> points; + + if (emission_fill->get_selected()==0) { + + float area_accum=0; + Map<float,int> triangle_area_map; + print_line("geometry size: "+itos(geometry.size())); + + for(int i=0;i<geometry.size();i++) { + + float area = geometry[i].get_area(); + if (area<CMP_EPSILON) + continue; + triangle_area_map[area_accum]=i; + area_accum+=area; + } + + if (!triangle_area_map.size() || area_accum==0) { + + err_dialog->set_text(TTR("Faces contain no area!")); + err_dialog->popup_centered_minsize(); + return; + } + + int emissor_count=emission_amount->get_val(); + + for(int i=0;i<emissor_count;i++) { + + float areapos = Math::random(0,area_accum); + + Map<float,int>::Element *E = triangle_area_map.find_closest(areapos); + ERR_FAIL_COND(!E) + int index = E->get(); + ERR_FAIL_INDEX(index,geometry.size()); + + // ok FINALLY get face + Face3 face = geometry[index]; + //now compute some position inside the face... + + Vector3 pos = face.get_random_point_inside(); + + points.push_back(pos); + } + } else { + + int gcount = geometry.size(); + + if (gcount==0) { + + err_dialog->set_text(TTR("No faces!")); + err_dialog->popup_centered_minsize(); + return; + } + + PoolVector<Face3>::Read r = geometry.read(); + + AABB aabb; + + for(int i=0;i<gcount;i++) { + + for(int j=0;j<3;j++) { + + if (i==0 && j==0) + aabb.pos=r[i].vertex[j]; + else + aabb.expand_to(r[i].vertex[j]); + } + } + + int emissor_count=emission_amount->get_val(); + + for(int i=0;i<emissor_count;i++) { + + int attempts=5; + + for(int j=0;j<attempts;j++) { + + Vector3 dir; + dir[Math::rand()%3]=1.0; + Vector3 ofs = Vector3(1,1,1)-dir; + ofs=(Vector3(1,1,1)-dir)*Vector3(Math::randf(),Math::randf(),Math::randf())*aabb.size; + ofs+=aabb.pos; + + Vector3 ofsv = ofs + aabb.size * dir; + + //space it a little + ofs -= dir; + ofsv += dir; + + float max=-1e7,min=1e7; + + for(int k=0;k<gcount;k++) { + + const Face3& f3 = r[k]; + + Vector3 res; + if (f3.intersects_segment(ofs,ofsv,&res)) { + + res-=ofs; + float d = dir.dot(res); + + if (d<min) + min=d; + if (d>max) + max=d; + + } + } + + + if (max<min) + continue; //lost attempt + + float val = min + (max-min)*Math::randf(); + + Vector3 point = ofs + dir * val; + + points.push_back(point); + break; + } + } + } + + //print_line("point count: "+itos(points.size())); + node->set_emission_points(points); + +} + +void ParticlesEditor::_bind_methods() { + + ClassDB::bind_method("_menu_option",&ParticlesEditor::_menu_option); + ClassDB::bind_method("_resource_seleted",&ParticlesEditor::_resource_seleted); + ClassDB::bind_method("_node_selected",&ParticlesEditor::_node_selected); + ClassDB::bind_method("_generate_emission_points",&ParticlesEditor::_generate_emission_points); + + //ClassDB::bind_method("_populate",&ParticlesEditor::_populate); + +} + +ParticlesEditor::ParticlesEditor() { + + particles_editor_hb = memnew ( HBoxContainer ); + SpatialEditor::get_singleton()->add_control_to_menu_panel(particles_editor_hb); + options = memnew( MenuButton ); + particles_editor_hb->add_child(options); + particles_editor_hb->hide(); + + options->set_text("Particles"); + options->get_popup()->add_item(TTR("Generate AABB"),MENU_OPTION_GENERATE_AABB); + options->get_popup()->add_separator(); + options->get_popup()->add_item(TTR("Create Emitter From Mesh"),MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH); + options->get_popup()->add_item(TTR("Create Emitter From Node"),MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE); + options->get_popup()->add_item(TTR("Clear Emitter"),MENU_OPTION_CLEAR_EMISSION_VOLUME); + + options->get_popup()->connect("id_pressed", this,"_menu_option"); + + emission_dialog = memnew( ConfirmationDialog ); + emission_dialog->set_title(TTR("Create Emitter")); + add_child(emission_dialog); + Label *l = memnew(Label); + l->set_pos(Point2(5,5)); + l->set_text(TTR("Emission Positions:")); + emission_dialog->add_child(l); + + + emission_amount = memnew( SpinBox ); + emission_amount->set_anchor(MARGIN_RIGHT,ANCHOR_END); + emission_amount->set_begin( Point2(20,23)); + emission_amount->set_end( Point2(5,25)); + emission_amount->set_min(1); + emission_amount->set_max(65536); + emission_amount->set_val(512); + emission_dialog->add_child(emission_amount); + emission_dialog->get_ok()->set_text(TTR("Create")); + emission_dialog->connect("confirmed",this,"_generate_emission_points"); + + l = memnew(Label); + l->set_pos(Point2(5,50)); + l->set_text(TTR("Emission Fill:")); + emission_dialog->add_child(l); + + emission_fill = memnew( OptionButton ); + emission_fill->set_anchor(MARGIN_RIGHT,ANCHOR_END); + emission_fill->set_begin( Point2(20,70)); + emission_fill->set_end( Point2(5,75)); + emission_fill->add_item(TTR("Surface")); + emission_fill->add_item(TTR("Volume")); + emission_dialog->add_child(emission_fill); + + err_dialog = memnew( ConfirmationDialog ); + //err_dialog->get_cancel()->hide(); + add_child(err_dialog); + + + emission_file_dialog = memnew( EditorFileDialog ); + add_child(emission_file_dialog); + emission_file_dialog->connect("file_selected",this,"_resource_seleted"); + emission_tree_dialog = memnew( SceneTreeDialog ); + add_child(emission_tree_dialog); + emission_tree_dialog->connect("selected",this,"_node_selected"); + + List<String> extensions; + ResourceLoader::get_recognized_extensions_for_type("Mesh",&extensions); + + emission_file_dialog->clear_filters(); + for(int i=0;i<extensions.size();i++) { + + emission_file_dialog->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); + } + + emission_file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE); + + //options->set_anchor(MARGIN_LEFT,Control::ANCHOR_END); + //options->set_anchor(MARGIN_RIGHT,Control::ANCHOR_END); + +} + + +void ParticlesEditorPlugin::edit(Object *p_object) { + + particles_editor->edit(p_object->cast_to<Particles>()); +} + +bool ParticlesEditorPlugin::handles(Object *p_object) const { + + return p_object->is_type("Particles"); +} + +void ParticlesEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + particles_editor->show(); + particles_editor->particles_editor_hb->show(); + } else { + particles_editor->particles_editor_hb->hide(); + particles_editor->hide(); + particles_editor->edit(NULL); + } + +} + +ParticlesEditorPlugin::ParticlesEditorPlugin(EditorNode *p_node) { + + editor=p_node; + particles_editor = memnew( ParticlesEditor ); + editor->get_viewport()->add_child(particles_editor); + + particles_editor->hide(); +} + + +ParticlesEditorPlugin::~ParticlesEditorPlugin() +{ +} + + +#endif diff --git a/editor/plugins/particles_editor_plugin.h b/editor/plugins/particles_editor_plugin.h new file mode 100644 index 0000000000..06134ddef2 --- /dev/null +++ b/editor/plugins/particles_editor_plugin.h @@ -0,0 +1,116 @@ +/*************************************************************************/ +/* particles_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef PARTICLES_EDITOR_PLUGIN_H +#define PARTICLES_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/3d/particles.h" +#include "scene/gui/spin_box.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ +#if 0 +class ParticlesEditor : public Control { + + GDCLASS(ParticlesEditor, Control ); + + Panel *panel; + MenuButton *options; + HBoxContainer *particles_editor_hb; + Particles *node; + + + EditorFileDialog *emission_file_dialog; + SceneTreeDialog *emission_tree_dialog; + + ConfirmationDialog *err_dialog; + + ConfirmationDialog *emission_dialog; + SpinBox *emission_amount; + OptionButton *emission_fill; + + + + + enum Menu { + + MENU_OPTION_GENERATE_AABB, + MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE, + MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH, + MENU_OPTION_CLEAR_EMISSION_VOLUME, + + }; + + PoolVector<Face3> geometry; + + void _generate_emission_points(); + void _resource_seleted(const String& p_res); + void _node_selected(const NodePath& p_path); + + void _menu_option(int); + + void _populate(); + +friend class ParticlesEditorPlugin; + +protected: + + void _notification(int p_notification); + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + void edit(Particles *p_particles); + ParticlesEditor(); +}; + +class ParticlesEditorPlugin : public EditorPlugin { + + GDCLASS( ParticlesEditorPlugin, EditorPlugin ); + + ParticlesEditor *particles_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "Particles"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + ParticlesEditorPlugin(EditorNode *p_node); + ~ParticlesEditorPlugin(); + +}; + +#endif // PARTICLES_EDITOR_PLUGIN_H +#endif diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp new file mode 100644 index 0000000000..00b026e25b --- /dev/null +++ b/editor/plugins/path_2d_editor_plugin.cpp @@ -0,0 +1,718 @@ +/*************************************************************************/ +/* path_2d_editor_plugin.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 "path_2d_editor_plugin.h" + +#include "canvas_item_editor_plugin.h" +#include "os/file_access.h" +#include "editor/editor_settings.h" +#include "os/keyboard.h" +void Path2DEditor::_notification(int p_what) { + + switch(p_what) { + + case NOTIFICATION_READY: { + + //button_create->set_icon( get_icon("Edit","EditorIcons")); + //button_edit->set_icon( get_icon("MovePoint","EditorIcons")); + //set_pressed_button(button_edit); + //button_edit->set_pressed(true); + + + } break; + case NOTIFICATION_FIXED_PROCESS: { + + + } break; + } + +} +void Path2DEditor::_node_removed(Node *p_node) { + + if(p_node==node) { + node=NULL; + hide(); + } + +} + + +bool Path2DEditor::forward_gui_input(const InputEvent& p_event) { + + if (!node) + return false; + + if (!node->is_visible_in_tree()) + return false; + + if (!node->get_curve().is_valid()) + return false; + + switch(p_event.type) { + + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &mb=p_event.mouse_button; + + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + + Vector2 gpoint = Point2(mb.x,mb.y); + Vector2 cpoint = !mb.mod.alt? canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)) + : node->get_global_transform().affine_inverse().xform( canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)) ); + + //first check if a point is to be added (segment split) + real_t grab_treshold=EDITOR_DEF("editors/poly_editor/point_grab_radius",8); + + + + // Test move point!! + + if ( mb.pressed && action==ACTION_NONE ) { + + Ref<Curve2D> curve = node->get_curve(); + + for(int i=0;i<curve->get_point_count();i++) { + + bool pointunder=false; + + { + Point2 p = xform.xform( curve->get_point_pos(i) ); + if (gpoint.distance_to(p) < grab_treshold ) { + + if (mb.button_index==BUTTON_LEFT && !mb.mod.shift && mode==MODE_EDIT) { + + action=ACTION_MOVING_POINT; + action_point=i; + moving_from=curve->get_point_pos(i); + moving_screen_from=gpoint; + return true; + } else if ((mb.button_index==BUTTON_RIGHT && mode==MODE_EDIT) || (mb.button_index==BUTTON_LEFT && mode==MODE_DELETE)) { + + undo_redo->create_action(TTR("Remove Point from Curve")); + undo_redo->add_do_method(curve.ptr(),"remove_point",i); + undo_redo->add_undo_method(curve.ptr(),"add_point",curve->get_point_pos(i),curve->get_point_in(i),curve->get_point_out(i),i); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + return true; + } else + pointunder=true; + } + } + + if (mb.button_index==BUTTON_LEFT && i<(curve->get_point_count()-1)) { + Point2 p = xform.xform( curve->get_point_pos(i)+curve->get_point_out(i) ); + if (gpoint.distance_to(p) < grab_treshold && (mode == MODE_EDIT || mode==MODE_EDIT_CURVE) ) { + + action=ACTION_MOVING_OUT; + action_point=i; + moving_from=curve->get_point_out(i); + moving_screen_from=gpoint; + return true; + } + } + + if (mb.button_index==BUTTON_LEFT && i>0) { + Point2 p = xform.xform( curve->get_point_pos(i)+curve->get_point_in(i) ); + if (gpoint.distance_to(p) < grab_treshold && (mode == MODE_EDIT || mode==MODE_EDIT_CURVE)) { + + action=ACTION_MOVING_IN; + action_point=i; + moving_from=curve->get_point_in(i); + moving_screen_from=gpoint; + return true; + } + } + + if (pointunder) + return true; + + } + + } + + // Test add point in empty space! + + if ( mb.pressed && mb.button_index==BUTTON_LEFT && ((mb.mod.command && mode == MODE_EDIT) || mode == MODE_CREATE)) { + + Ref<Curve2D> curve = node->get_curve(); + + undo_redo->create_action(TTR("Add Point to Curve")); + undo_redo->add_do_method(curve.ptr(),"add_point",cpoint); + undo_redo->add_undo_method(curve.ptr(),"remove_point",curve->get_point_count()); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + + action=ACTION_MOVING_POINT; + action_point=curve->get_point_count()-1; + moving_from=curve->get_point_pos(action_point); + moving_screen_from=gpoint; + + canvas_item_editor->get_viewport_control()->update(); + + return true; + } + + if ( !mb.pressed && mb.button_index==BUTTON_LEFT && action!=ACTION_NONE) { + + + Ref<Curve2D> curve = node->get_curve(); + + Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from); + switch(action) { + + case ACTION_MOVING_POINT: { + + + undo_redo->create_action(TTR("Move Point in Curve")); + undo_redo->add_do_method(curve.ptr(),"set_point_pos",action_point,cpoint); + undo_redo->add_undo_method(curve.ptr(),"set_point_pos",action_point,moving_from); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + + } break; + case ACTION_MOVING_IN: { + + undo_redo->create_action(TTR("Move In-Control in Curve")); + undo_redo->add_do_method(curve.ptr(),"set_point_in",action_point,new_pos); + undo_redo->add_undo_method(curve.ptr(),"set_point_in",action_point,moving_from); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + + } break; + case ACTION_MOVING_OUT: { + + undo_redo->create_action(TTR("Move Out-Control in Curve")); + undo_redo->add_do_method(curve.ptr(),"set_point_out",action_point,new_pos); + undo_redo->add_undo_method(curve.ptr(),"set_point_out",action_point,moving_from); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + + } break; + + } + + action=ACTION_NONE; + + return true; + } + + +#if 0 + switch(mode) { + + + case MODE_CREATE: { + + if (mb.button_index==BUTTON_LEFT && mb.pressed) { + + + if (!wip_active) { + + wip.clear(); + wip.push_back( canvas_item_editor->snap_point(cpoint) ); + wip_active=true; + edited_point_pos=canvas_item_editor->snap_point(cpoint); + canvas_item_editor->update(); + edited_point=1; + return true; + } else { + + if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) { + //wip closed + _wip_close(); + + return true; + } else { + + wip.push_back( canvas_item_editor->snap_point(cpoint) ); + edited_point=wip.size(); + canvas_item_editor->update(); + return true; + + //add wip point + } + } + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { + _wip_close(); + } + + + + } break; + + case MODE_EDIT: { + + if (mb.button_index==BUTTON_LEFT) { + if (mb.pressed) { + + if (mb.mod.control) { + + + if (poly.size() < 3) { + + undo_redo->create_action(TTR("Edit Poly")); + undo_redo->add_undo_method(node,"set_polygon",poly); + poly.push_back(cpoint); + undo_redo->add_do_method(node,"set_polygon",poly); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + return true; + } + + //search edges + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 points[2] ={ xform.xform(poly[i]), + xform.xform(poly[(i+1)%poly.size()]) }; + + Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points); + if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2) + continue; //not valid to reuse point + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + + } + + if (closest_idx>=0) { + + pre_move_edit=poly; + poly.insert(closest_idx+1,canvas_item_editor->snap_point(xform.affine_inverse().xform(closest_pos))); + edited_point=closest_idx+1; + edited_point_pos=canvas_item_editor->snap_point(xform.affine_inverse().xform(closest_pos)); + node->set_polygon(poly); + canvas_item_editor->update(); + return true; + } + } else { + + //look for points to move + + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 cp =xform.xform(poly[i]); + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + } + + if (closest_idx>=0) { + + pre_move_edit=poly; + edited_point=closest_idx; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + canvas_item_editor->update(); + return true; + } + } + } else { + + if (edited_point!=-1) { + + //apply + + ERR_FAIL_INDEX_V(edited_point,poly.size(),false); + poly[edited_point]=edited_point_pos; + undo_redo->create_action(TTR("Edit Poly")); + undo_redo->add_do_method(node,"set_polygon",poly); + undo_redo->add_undo_method(node,"set_polygon",pre_move_edit); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + + edited_point=-1; + return true; + } + } + } if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { + + + + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 cp =xform.xform(poly[i]); + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + } + + if (closest_idx>=0) { + + + undo_redo->create_action(TTR("Edit Poly (Remove Point)")); + undo_redo->add_undo_method(node,"set_polygon",poly); + poly.remove(closest_idx); + undo_redo->add_do_method(node,"set_polygon",poly); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + return true; + } + + } + + + + } break; + } + + +#endif + } break; + case InputEvent::MOUSE_MOTION: { + + const InputEventMouseMotion &mm=p_event.mouse_motion; + + + if ( action!=ACTION_NONE) { + + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + Vector2 gpoint = Point2(mm.x,mm.y); + Vector2 cpoint = !mm.mod.alt? canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)) + : node->get_global_transform().affine_inverse().xform( canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)) ); + + Ref<Curve2D> curve = node->get_curve(); + + Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from); + + switch(action) { + + case ACTION_MOVING_POINT: { + + curve->set_point_pos(action_point,cpoint); + } break; + case ACTION_MOVING_IN: { + + curve->set_point_in(action_point,new_pos); + + } break; + case ACTION_MOVING_OUT: { + + curve->set_point_out(action_point,new_pos); + + } break; + } + + + canvas_item_editor->get_viewport_control()->update(); + return true; + } + +#if 0 + if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { + + + Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + + Vector2 gpoint = Point2(mm.x,mm.y); + edited_point_pos = canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)); + canvas_item_editor->update(); + + } +#endif + } break; + } + + return false; +} +void Path2DEditor::_canvas_draw() { + + if (!node) + return ; + + if (!node->is_visible_in_tree()) + return; + + if (!node->get_curve().is_valid()) + return ; + + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + Ref<Texture> handle= get_icon("EditorHandle","EditorIcons"); + Size2 handle_size = handle->get_size(); + + Ref<Curve2D> curve = node->get_curve(); + + int len = curve->get_point_count(); + Control *vpc = canvas_item_editor->get_viewport_control(); + + + for(int i=0;i<len;i++) { + + + Vector2 point = xform.xform(curve->get_point_pos(i)); + vpc->draw_texture_rect(handle,Rect2(point-handle_size*0.5,handle_size),false,Color(1,1,1,1)); + + if (i<len-1) { + Vector2 pointout = xform.xform(curve->get_point_pos(i)+curve->get_point_out(i)); + vpc->draw_line(point,pointout,Color(0.5,0.5,1.0,0.8),1.0); + vpc->draw_texture_rect(handle, Rect2(pointout-handle_size*0.5,handle_size),false,Color(1,0.5,1,0.3)); + } + + if (i>0) { + Vector2 pointin = xform.xform(curve->get_point_pos(i)+curve->get_point_in(i)); + vpc->draw_line(point,pointin,Color(0.5,0.5,1.0,0.8),1.0); + vpc->draw_texture_rect(handle, Rect2(pointin-handle_size*0.5,handle_size),false,Color(1,0.5,1,0.3)); + } + + } + +} + +void Path2DEditor::_node_visibility_changed() { + if (!node) + return; + + canvas_item_editor->get_viewport_control()->update(); +} + +void Path2DEditor::edit(Node *p_path2d) { + + if (!canvas_item_editor) { + canvas_item_editor=CanvasItemEditor::get_singleton(); + } + + if (p_path2d) { + + node=p_path2d->cast_to<Path2D>(); + if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw"); + if (!node->is_connected("visibility_changed", this, "_node_visibility_changed")) + node->connect("visibility_changed", this, "_node_visibility_changed"); + + + } else { + + if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw"); + + // node may have been deleted at this point + if (node && node->is_connected("visibility_changed", this, "_node_visibility_changed")) + node->disconnect("visibility_changed", this, "_node_visibility_changed"); + node=NULL; + } + +} + +void Path2DEditor::_bind_methods() { + + //ClassDB::bind_method(D_METHOD("_menu_option"),&Path2DEditor::_menu_option); + ClassDB::bind_method(D_METHOD("_canvas_draw"),&Path2DEditor::_canvas_draw); + ClassDB::bind_method(D_METHOD("_node_visibility_changed"),&Path2DEditor::_node_visibility_changed); + ClassDB::bind_method(D_METHOD("_mode_selected"),&Path2DEditor::_mode_selected); +} + +void Path2DEditor::_mode_selected(int p_mode) { + + if (p_mode==MODE_CREATE) { + + curve_create->set_pressed(true); + curve_edit->set_pressed(false); + curve_edit_curve->set_pressed(false); + curve_del->set_pressed(false); + } else if (p_mode==MODE_EDIT) { + + curve_create->set_pressed(false); + curve_edit->set_pressed(true); + curve_edit_curve->set_pressed(false); + curve_del->set_pressed(false); + } else if (p_mode==MODE_EDIT_CURVE) { + + curve_create->set_pressed(false); + curve_edit->set_pressed(false); + curve_edit_curve->set_pressed(true); + curve_del->set_pressed(false); + } else if (p_mode==MODE_DELETE) { + + curve_create->set_pressed(false); + curve_edit->set_pressed(false); + curve_edit_curve->set_pressed(false); + curve_del->set_pressed(true); + } else if (p_mode==ACTION_CLOSE) { + + //? + + if (!node->get_curve().is_valid()) + return ; + if (node->get_curve()->get_point_count()<3) + return; + + Vector2 begin = node->get_curve()->get_point_pos(0); + Vector2 end = node->get_curve()->get_point_pos( node->get_curve()->get_point_count() -1 ); + if (begin.distance_to(end)<CMP_EPSILON) + return; + + undo_redo->create_action(TTR("Remove Point from Curve")); + undo_redo->add_do_method(node->get_curve().ptr(),"add_point",begin); + undo_redo->add_undo_method(node->get_curve().ptr(),"remove_point",node->get_curve()->get_point_count()); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + return; + } + + mode=Mode(p_mode); + +} + +Path2DEditor::Path2DEditor(EditorNode *p_editor) { + + canvas_item_editor=NULL; + editor=p_editor; + undo_redo = editor->get_undo_redo(); + + mode=MODE_EDIT; + + action=ACTION_NONE; +#if 0 + options = memnew( MenuButton ); + add_child(options); + options->set_area_as_parent_rect(); + options->set_text("Polygon"); + //options->get_popup()->add_item("Parse BBCode",PARSE_BBCODE); + options->get_popup()->connect("id_pressed", this,"_menu_option"); +#endif + + base_hb = memnew( HBoxContainer ); + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(base_hb); + + sep = memnew( VSeparator); + base_hb->add_child(sep); + curve_edit = memnew( ToolButton ); + curve_edit->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveEdit","EditorIcons")); + curve_edit->set_toggle_mode(true); + curve_edit->set_focus_mode(Control::FOCUS_NONE); + curve_edit->set_tooltip(TTR("Select Points")+"\n"+TTR("Shift+Drag: Select Control Points")+"\n"+keycode_get_string(KEY_MASK_CMD)+TTR("Click: Add Point")+"\n"+TTR("Right Click: Delete Point")); + curve_edit->connect("pressed",this,"_mode_selected",varray(MODE_EDIT)); + base_hb->add_child(curve_edit); + curve_edit_curve = memnew( ToolButton ); + curve_edit_curve->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveCurve","EditorIcons")); + curve_edit_curve->set_toggle_mode(true); + curve_edit_curve->set_focus_mode(Control::FOCUS_NONE); + curve_edit_curve->set_tooltip(TTR("Select Control Points (Shift+Drag)")); + curve_edit_curve->connect("pressed",this,"_mode_selected",varray(MODE_EDIT_CURVE)); + base_hb->add_child(curve_edit_curve); + curve_create = memnew( ToolButton ); + curve_create->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveCreate","EditorIcons")); + curve_create->set_toggle_mode(true); + curve_create->set_focus_mode(Control::FOCUS_NONE); + curve_create->set_tooltip(TTR("Add Point (in empty space)")+"\n"+TTR("Split Segment (in curve)")); + curve_create->connect("pressed",this,"_mode_selected",varray(MODE_CREATE)); + base_hb->add_child(curve_create); + curve_del = memnew( ToolButton ); + curve_del->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveDelete","EditorIcons")); + curve_del->set_toggle_mode(true); + curve_del->set_focus_mode(Control::FOCUS_NONE); + curve_del->set_tooltip(TTR("Delete Point")); + curve_del->connect("pressed",this,"_mode_selected",varray(MODE_DELETE)); + base_hb->add_child(curve_del); + curve_close = memnew( ToolButton ); + curve_close->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveClose","EditorIcons")); + curve_close->set_focus_mode(Control::FOCUS_NONE); + curve_close->set_tooltip(TTR("Close Curve")); + curve_close->connect("pressed",this,"_mode_selected",varray(ACTION_CLOSE)); + base_hb->add_child(curve_close); + base_hb->hide(); + + + + curve_edit->set_pressed(true); + + +} + + +void Path2DEditorPlugin::edit(Object *p_object) { + + path2d_editor->edit(p_object->cast_to<Node>()); +} + +bool Path2DEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("Path2D"); +} + +void Path2DEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + path2d_editor->show(); + path2d_editor->base_hb->show(); + + } else { + + path2d_editor->hide(); + path2d_editor->base_hb->hide(); + path2d_editor->edit(NULL); + } + +} + +Path2DEditorPlugin::Path2DEditorPlugin(EditorNode *p_node) { + + editor=p_node; + path2d_editor = memnew( Path2DEditor(p_node) ); + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(path2d_editor); + path2d_editor->hide(); + + +} + + +Path2DEditorPlugin::~Path2DEditorPlugin() +{ +} + diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h new file mode 100644 index 0000000000..89f42d94cc --- /dev/null +++ b/editor/plugins/path_2d_editor_plugin.h @@ -0,0 +1,126 @@ +/*************************************************************************/ +/* path_2d_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef PATH_2D_EDITOR_PLUGIN_H +#define PATH_2D_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/2d/path_2d.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/button_group.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ +class CanvasItemEditor; + +class Path2DEditor : public HBoxContainer { + + GDCLASS(Path2DEditor, HBoxContainer); + + UndoRedo *undo_redo; + + CanvasItemEditor *canvas_item_editor; + EditorNode *editor; + Panel *panel; + Path2D *node; + + HBoxContainer *base_hb; + Separator *sep; + + enum Mode { + MODE_CREATE, + MODE_EDIT, + MODE_EDIT_CURVE, + MODE_DELETE, + ACTION_CLOSE + }; + + Mode mode; + ToolButton *curve_create; + ToolButton *curve_edit; + ToolButton *curve_edit_curve; + ToolButton *curve_del; + ToolButton *curve_close; + + enum Action { + + ACTION_NONE, + ACTION_MOVING_POINT, + ACTION_MOVING_IN, + ACTION_MOVING_OUT, + }; + + + Action action; + int action_point; + Point2 moving_from; + Point2 moving_screen_from; + + void _mode_selected(int p_mode); + + void _canvas_draw(); + void _node_visibility_changed(); +friend class Path2DEditorPlugin; +protected: + void _notification(int p_what); + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + bool forward_gui_input(const InputEvent& p_event); + void edit(Node *p_path2d); + Path2DEditor(EditorNode *p_editor); +}; + +class Path2DEditorPlugin : public EditorPlugin { + + GDCLASS( Path2DEditorPlugin, EditorPlugin ); + + Path2DEditor *path2d_editor; + EditorNode *editor; + +public: + + virtual bool forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return path2d_editor->forward_gui_input(p_event); } + + virtual String get_name() const { return "Path2D"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + Path2DEditorPlugin(EditorNode *p_node); + ~Path2DEditorPlugin(); + +}; + + + +#endif // PATH_2D_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp index a3df39fdaa..a3df39fdaa 100644 --- a/tools/editor/plugins/path_editor_plugin.cpp +++ b/editor/plugins/path_editor_plugin.cpp diff --git a/editor/plugins/path_editor_plugin.h b/editor/plugins/path_editor_plugin.h new file mode 100644 index 0000000000..fe1c5ad159 --- /dev/null +++ b/editor/plugins/path_editor_plugin.h @@ -0,0 +1,100 @@ +/*************************************************************************/ +/* path_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef PATH_EDITOR_PLUGIN_H +#define PATH_EDITOR_PLUGIN_H + + +#include "editor/spatial_editor_gizmos.h" +#include "scene/3d/path.h" +# if 0 +class PathSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(PathSpatialGizmo,EditorSpatialGizmo); + + Path* path; + mutable Vector3 original; + +public: + + virtual String get_handle_name(int p_idx) const; + virtual Variant get_handle_value(int p_idx) const; + virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); + virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); + + void redraw(); + PathSpatialGizmo(Path* p_path=NULL); + +}; + +class PathEditorPlugin : public EditorPlugin { + + GDCLASS( PathEditorPlugin, EditorPlugin ); + + + Separator *sep; + ToolButton *curve_create; + ToolButton *curve_edit; + ToolButton *curve_del; + ToolButton *curve_close; + + EditorNode *editor; + + + Path *path; + + void _mode_changed(int p_idx); + void _close_curve(); +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + + Path *get_edited_path() { return path; } + + static PathEditorPlugin* singleton; + Ref<FixedSpatialMaterial> path_material; + Ref<FixedSpatialMaterial> path_thin_material; + virtual bool forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event); + + //virtual bool forward_gui_input(const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); } + virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial* p_spatial); + virtual String get_name() const { return "Path"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + PathEditorPlugin(EditorNode *p_node); + ~PathEditorPlugin(); + +}; + +#endif +#endif // PATH_EDITOR_PLUGIN_H diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp new file mode 100644 index 0000000000..3a41b2cb6b --- /dev/null +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -0,0 +1,1028 @@ +/*************************************************************************/ +/* polygon_2d_editor_plugin.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 "polygon_2d_editor_plugin.h" + +#include "canvas_item_editor_plugin.h" +#include "os/file_access.h" +#include "editor/editor_settings.h" +#include "os/keyboard.h" +#include "os/input.h" + +void Polygon2DEditor::_notification(int p_what) { + + switch(p_what) { + + case NOTIFICATION_READY: { + + button_create->set_icon( get_icon("Edit","EditorIcons")); + button_edit->set_icon( get_icon("MovePoint","EditorIcons")); + button_edit->set_pressed(true); + button_uv->set_icon( get_icon("Uv","EditorIcons")); + + uv_button[UV_MODE_EDIT_POINT]->set_icon(get_icon("ToolSelect","EditorIcons")); + uv_button[UV_MODE_MOVE]->set_icon(get_icon("ToolMove","EditorIcons")); + uv_button[UV_MODE_ROTATE]->set_icon(get_icon("ToolRotate","EditorIcons")); + uv_button[UV_MODE_SCALE]->set_icon(get_icon("ToolScale","EditorIcons")); + + b_snap_grid->set_icon( get_icon("Grid", "EditorIcons")); + b_snap_enable->set_icon( get_icon("Snap", "EditorIcons")); + uv_icon_zoom->set_texture( get_icon("Zoom", "EditorIcons")); + + get_tree()->connect("node_removed", this, "_node_removed"); + + } break; + case NOTIFICATION_FIXED_PROCESS: { + + + } break; + } + +} +void Polygon2DEditor::_node_removed(Node *p_node) { + + if(p_node==node) { + edit(NULL); + hide(); + + canvas_item_editor->get_viewport_control()->update(); + } + +} + + +void Polygon2DEditor::_menu_option(int p_option) { + + switch(p_option) { + + case MODE_CREATE: { + + mode=MODE_CREATE; + button_create->set_pressed(true); + button_edit->set_pressed(false); + } break; + case MODE_EDIT: { + + mode=MODE_EDIT; + button_create->set_pressed(false); + button_edit->set_pressed(true); + } break; + case MODE_EDIT_UV: { + + if (node->get_texture().is_null()) { + + error->set_text("No texture in this polygon.\nSet a texture to be able to edit UV."); + error->popup_centered_minsize(); + return; + } + + + PoolVector<Vector2> points = node->get_polygon(); + PoolVector<Vector2> uvs = node->get_uv(); + if (uvs.size()!=points.size()) { + undo_redo->create_action(TTR("Create UV Map")); + undo_redo->add_do_method(node,"set_uv",points); + undo_redo->add_undo_method(node,"set_uv",uvs); + undo_redo->add_do_method(uv_edit_draw,"update"); + undo_redo->add_undo_method(uv_edit_draw,"update"); + undo_redo->commit_action(); + + } + + + uv_edit->popup_centered_ratio(0.85); + } break; + case UVEDIT_POLYGON_TO_UV: { + + PoolVector<Vector2> points = node->get_polygon(); + if (points.size()==0) + break; + PoolVector<Vector2> uvs = node->get_uv(); + undo_redo->create_action(TTR("Create UV Map")); + undo_redo->add_do_method(node,"set_uv",points); + undo_redo->add_undo_method(node,"set_uv",uvs); + undo_redo->add_do_method(uv_edit_draw,"update"); + undo_redo->add_undo_method(uv_edit_draw,"update"); + undo_redo->commit_action(); + + + } break; + case UVEDIT_UV_TO_POLYGON: { + + PoolVector<Vector2> points = node->get_polygon(); + PoolVector<Vector2> uvs = node->get_uv(); + if (uvs.size()==0) + break; + + undo_redo->create_action(TTR("Create UV Map")); + undo_redo->add_do_method(node,"set_polygon",uvs); + undo_redo->add_undo_method(node,"set_polygon",points); + undo_redo->add_do_method(uv_edit_draw,"update"); + undo_redo->add_undo_method(uv_edit_draw,"update"); + undo_redo->commit_action(); + + } break; + case UVEDIT_UV_CLEAR: { + + PoolVector<Vector2> uvs = node->get_uv(); + if (uvs.size()==0) + break; + undo_redo->create_action(TTR("Create UV Map")); + undo_redo->add_do_method(node,"set_uv",PoolVector<Vector2>()); + undo_redo->add_undo_method(node,"set_uv",uvs); + undo_redo->add_do_method(uv_edit_draw,"update"); + undo_redo->add_undo_method(uv_edit_draw,"update"); + undo_redo->commit_action(); + + } break; + + + } +} + +void Polygon2DEditor::_set_use_snap(bool p_use) +{ + use_snap=p_use; +} + +void Polygon2DEditor::_set_show_grid(bool p_show) +{ + snap_show_grid=p_show; + uv_edit_draw->update(); +} + +void Polygon2DEditor::_set_snap_off_x(float p_val) +{ + snap_offset.x=p_val; + uv_edit_draw->update(); +} + +void Polygon2DEditor::_set_snap_off_y(float p_val) +{ + snap_offset.y=p_val; + uv_edit_draw->update(); +} + +void Polygon2DEditor::_set_snap_step_x(float p_val) +{ + snap_step.x=p_val; + uv_edit_draw->update(); +} + +void Polygon2DEditor::_set_snap_step_y(float p_val) +{ + snap_step.y=p_val; + uv_edit_draw->update(); +} + +void Polygon2DEditor::_wip_close() { + + undo_redo->create_action(TTR("Create Poly")); + undo_redo->add_undo_method(node,"set_polygon",node->get_polygon()); + undo_redo->add_do_method(node,"set_polygon",wip); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + wip.clear(); + wip_active=false; + mode=MODE_EDIT; + button_edit->set_pressed(true); + button_create->set_pressed(false); + edited_point=-1; +} + +bool Polygon2DEditor::forward_gui_input(const InputEvent& p_event) { + + if (node==NULL) + return false; + + switch(p_event.type) { + + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &mb=p_event.mouse_button; + + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + + + Vector2 gpoint = Point2(mb.x,mb.y); + Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); + cpoint=canvas_item_editor->snap_point(cpoint); + cpoint = node->get_global_transform().affine_inverse().xform(cpoint); + + + Vector<Vector2> poly = Variant(node->get_polygon()); + + //first check if a point is to be added (segment split) + real_t grab_treshold=EDITOR_DEF("editors/poly_editor/point_grab_radius",8); + + switch(mode) { + + + case MODE_CREATE: { + + if (mb.button_index==BUTTON_LEFT && mb.pressed) { + + + if (!wip_active) { + + wip.clear(); + wip.push_back( cpoint-node->get_offset() ); + wip_active=true; + edited_point_pos=cpoint; + canvas_item_editor->get_viewport_control()->update(); + edited_point=1; + return true; + } else { + + + if (wip.size()>1 && xform.xform(wip[0]+node->get_offset()).distance_to(gpoint)<grab_treshold) { + //wip closed + _wip_close(); + + return true; + } else { + + wip.push_back( cpoint-node->get_offset() ); + edited_point=wip.size(); + canvas_item_editor->get_viewport_control()->update(); + return true; + + //add wip point + } + } + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { + _wip_close(); + } + + + + } break; + + case MODE_EDIT: { + + if (mb.button_index==BUTTON_LEFT) { + if (mb.pressed) { + + if (mb.mod.control) { + + + if (poly.size() < 3) { + + undo_redo->create_action(TTR("Edit Poly")); + undo_redo->add_undo_method(node,"set_polygon",poly); + poly.push_back(cpoint); + undo_redo->add_do_method(node,"set_polygon",poly); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + return true; + } + + //search edges + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 points[2] ={ xform.xform(poly[i]+node->get_offset()), + xform.xform(poly[(i+1)%poly.size()]+node->get_offset()) }; + + Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points); + if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2) + continue; //not valid to reuse point + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + + } + + if (closest_idx>=0) { + + pre_move_edit=poly; + poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos)-node->get_offset()); + edited_point=closest_idx+1; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + node->set_polygon(Variant(poly)); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } else { + + //look for points to move + + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 cp =xform.xform(poly[i]+node->get_offset()); + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + } + + if (closest_idx>=0) { + + pre_move_edit=poly; + edited_point=closest_idx; + edited_point_pos=xform.affine_inverse().xform(closest_pos); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } + } else { + + if (edited_point!=-1) { + + //apply + + ERR_FAIL_INDEX_V(edited_point,poly.size(),false); + poly[edited_point]=edited_point_pos-node->get_offset(); + undo_redo->create_action(TTR("Edit Poly")); + undo_redo->add_do_method(node,"set_polygon",poly); + undo_redo->add_undo_method(node,"set_polygon",pre_move_edit); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + + edited_point=-1; + return true; + } + } + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { + + + + int closest_idx=-1; + Vector2 closest_pos; + real_t closest_dist=1e10; + for(int i=0;i<poly.size();i++) { + + Vector2 cp =xform.xform(poly[i]+node->get_offset()); + + real_t d = cp.distance_to(gpoint); + if (d<closest_dist && d<grab_treshold) { + closest_dist=d; + closest_pos=cp; + closest_idx=i; + } + + } + + if (closest_idx>=0) { + + + undo_redo->create_action(TTR("Edit Poly (Remove Point)")); + undo_redo->add_undo_method(node,"set_polygon",poly); + poly.remove(closest_idx); + undo_redo->add_do_method(node,"set_polygon",poly); + undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); + undo_redo->commit_action(); + return true; + } + + } + + + + } break; + } + + + + } break; + case InputEvent::MOUSE_MOTION: { + + const InputEventMouseMotion &mm=p_event.mouse_motion; + + if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { + + Vector2 gpoint = Point2(mm.x,mm.y); + Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); + cpoint=canvas_item_editor->snap_point(cpoint); + edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint); + + canvas_item_editor->get_viewport_control()->update(); + + } + + } break; + } + + return false; +} +void Polygon2DEditor::_canvas_draw() { + + if (!node) + return; + + Control *vpc = canvas_item_editor->get_viewport_control(); + + Vector<Vector2> poly; + + if (wip_active) + poly=wip; + else + poly=Variant(node->get_polygon()); + + + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + Ref<Texture> handle= get_icon("EditorHandle","EditorIcons"); + + for(int i=0;i<poly.size();i++) { + + + Vector2 p,p2; + p = i==edited_point ? edited_point_pos : (poly[i]+node->get_offset()); + if ((wip_active && i==poly.size()-1) || (((i+1)%poly.size())==edited_point)) + p2=edited_point_pos; + else + p2 = poly[(i+1)%poly.size()]+node->get_offset(); + + Vector2 point = xform.xform(p); + Vector2 next_point = xform.xform(p2); + + Color col=Color(1,0.3,0.1,0.8); + vpc->draw_line(point,next_point,col,2); + vpc->draw_texture(handle,point-handle->get_size()*0.5); + } +} + + +void Polygon2DEditor::_uv_mode(int p_mode) { + + + uv_mode=UVMode(p_mode); + for(int i=0;i<UV_MODE_MAX;i++) { + uv_button[i]->set_pressed(p_mode==i); + } +} + + +void Polygon2DEditor::_uv_input(const InputEvent& p_input) { + + + Transform2D mtx; + mtx.elements[2]=-uv_draw_ofs; + mtx.scale_basis(Vector2(uv_draw_zoom,uv_draw_zoom)); + + if (p_input.type==InputEvent::MOUSE_BUTTON) { + + + const InputEventMouseButton &mb=p_input.mouse_button; + + if (mb.button_index==BUTTON_LEFT) { + + + if (mb.pressed) { + + uv_drag_from=Vector2(mb.x,mb.y); + uv_drag=true; + uv_prev=node->get_uv(); + uv_move_current=uv_mode; + if (uv_move_current==UV_MODE_EDIT_POINT) { + + if (mb.mod.shift && mb.mod.command) + uv_move_current=UV_MODE_SCALE; + else if (mb.mod.shift) + uv_move_current=UV_MODE_MOVE; + else if (mb.mod.command) + uv_move_current=UV_MODE_ROTATE; + } + + if (uv_move_current==UV_MODE_EDIT_POINT) { + + uv_drag_index=-1; + for(int i=0;i<uv_prev.size();i++) { + + Vector2 tuv=mtx.xform(uv_prev[i]); + if (tuv.distance_to(Vector2(mb.x,mb.y))<8) { + uv_drag_from=tuv; + uv_drag_index=i; + } + } + + if (uv_drag_index==-1) { + uv_drag=false; + } + + } + } else if (uv_drag) { + + undo_redo->create_action(TTR("Transform UV Map")); + undo_redo->add_do_method(node,"set_uv",node->get_uv()); + undo_redo->add_undo_method(node,"set_uv",uv_prev); + undo_redo->add_do_method(uv_edit_draw,"update"); + undo_redo->add_undo_method(uv_edit_draw,"update"); + undo_redo->commit_action(); + + uv_drag=false; + } + + } else if (mb.button_index==BUTTON_RIGHT && mb.pressed) { + + if (uv_drag) { + + uv_drag=false; + node->set_uv(uv_prev); + uv_edit_draw->update(); + } + + } else if (mb.button_index==BUTTON_WHEEL_UP && mb.pressed) { + + uv_zoom->set_value( uv_zoom->get_value()/0.9 ); + } else if (mb.button_index==BUTTON_WHEEL_DOWN && mb.pressed) { + + uv_zoom->set_value( uv_zoom->get_value()*0.9); + } + + } else if (p_input.type==InputEvent::MOUSE_MOTION) { + + const InputEventMouseMotion &mm=p_input.mouse_motion; + + if (mm.button_mask&BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { + + Vector2 drag(mm.relative_x,mm.relative_y); + uv_hscroll->set_value( uv_hscroll->get_value()-drag.x ); + uv_vscroll->set_value( uv_vscroll->get_value()-drag.y ); + + } else if (uv_drag) { + + Vector2 uv_drag_to=snap_point(Vector2(mm.x,mm.y)); + Vector2 drag = mtx.affine_inverse().xform(uv_drag_to) - mtx.affine_inverse().xform(uv_drag_from); + + + switch(uv_move_current) { + + case UV_MODE_EDIT_POINT: { + + PoolVector<Vector2> uv_new=uv_prev; + uv_new.set( uv_drag_index, uv_new[uv_drag_index]+drag ); + node->set_uv(uv_new); + } break; + case UV_MODE_MOVE: { + + PoolVector<Vector2> uv_new=uv_prev; + for(int i=0;i<uv_new.size();i++) + uv_new.set( i, uv_new[i]+drag ); + + node->set_uv(uv_new); + + + } break; + case UV_MODE_ROTATE: { + + Vector2 center; + PoolVector<Vector2> uv_new=uv_prev; + + for(int i=0;i<uv_new.size();i++) + center+=uv_prev[i]; + center/=uv_new.size(); + + float angle = (uv_drag_from - mtx.xform(center)).normalized().angle_to( (uv_drag_to - mtx.xform(center)).normalized() ); + + for(int i=0;i<uv_new.size();i++) { + Vector2 rel = uv_prev[i] - center; + rel=rel.rotated(angle); + uv_new.set(i,center+rel); + } + + node->set_uv(uv_new); + + } break; + case UV_MODE_SCALE: { + + Vector2 center; + PoolVector<Vector2> uv_new=uv_prev; + + for(int i=0;i<uv_new.size();i++) + center+=uv_prev[i]; + center/=uv_new.size(); + + float from_dist = uv_drag_from.distance_to(mtx.xform(center)); + float to_dist = uv_drag_to.distance_to(mtx.xform(center)); + if (from_dist<2) + break; + + float scale = to_dist/from_dist; + + + for(int i=0;i<uv_new.size();i++) { + Vector2 rel = uv_prev[i] - center; + rel=rel*scale; + uv_new.set(i,center+rel); + } + + node->set_uv(uv_new); + } break; + + + } + uv_edit_draw->update(); + } + + } + +} + + +void Polygon2DEditor::_uv_scroll_changed(float) { + + if (updating_uv_scroll) + return; + + uv_draw_ofs.x=uv_hscroll->get_value(); + uv_draw_ofs.y=uv_vscroll->get_value(); + uv_draw_zoom=uv_zoom->get_value(); + uv_edit_draw->update(); +} + +void Polygon2DEditor::_uv_draw() { + + Ref<Texture> base_tex = node->get_texture(); + if (base_tex.is_null()) + return; + + Transform2D mtx; + mtx.elements[2]=-uv_draw_ofs; + mtx.scale_basis(Vector2(uv_draw_zoom,uv_draw_zoom)); + + VS::get_singleton()->canvas_item_add_set_transform(uv_edit_draw->get_canvas_item(),mtx); + uv_edit_draw->draw_texture(base_tex,Point2()); + VS::get_singleton()->canvas_item_add_set_transform(uv_edit_draw->get_canvas_item(),Transform2D()); + + if (snap_show_grid) { + Size2 s = uv_edit_draw->get_size(); + int last_cell; + + if (snap_step.x!=0) { + for(int i=0;i<s.width;i++) { + int cell = Math::fast_ftoi(Math::floor((mtx.affine_inverse().xform(Vector2(i,0)).x-snap_offset.x)/snap_step.x)); + if (i==0) + last_cell=cell; + if (last_cell!=cell) + uv_edit_draw->draw_line(Point2(i,0),Point2(i,s.height),Color(0.3,0.7,1,0.3)); + last_cell=cell; + } + } + + if (snap_step.y!=0) { + for(int i=0;i<s.height;i++) { + int cell = Math::fast_ftoi(Math::floor((mtx.affine_inverse().xform(Vector2(0,i)).y-snap_offset.y)/snap_step.y)); + if (i==0) + last_cell=cell; + if (last_cell!=cell) + uv_edit_draw->draw_line(Point2(0,i),Point2(s.width,i),Color(0.3,0.7,1,0.3)); + last_cell=cell; + } + } + } + + PoolVector<Vector2> uvs = node->get_uv(); + Ref<Texture> handle = get_icon("EditorHandle","EditorIcons"); + + Rect2 rect(Point2(),mtx.basis_xform(base_tex->get_size())); + rect.expand_to(mtx.basis_xform(uv_edit_draw->get_size())); + + for(int i=0;i<uvs.size();i++) { + + int next = (i+1)%uvs.size(); + uv_edit_draw->draw_line(mtx.xform(uvs[i]),mtx.xform(uvs[next]),Color(0.9,0.5,0.5),2); + uv_edit_draw->draw_texture(handle,mtx.xform(uvs[i])-handle->get_size()*0.5); + rect.expand_to(mtx.basis_xform(uvs[i])); + } + + rect=rect.grow(200); + updating_uv_scroll=true; + uv_hscroll->set_min(rect.pos.x); + uv_hscroll->set_max(rect.pos.x+rect.size.x); + uv_hscroll->set_page(uv_edit_draw->get_size().x); + uv_hscroll->set_value(uv_draw_ofs.x); + uv_hscroll->set_step(0.001); + + uv_vscroll->set_min(rect.pos.y); + uv_vscroll->set_max(rect.pos.y+rect.size.y); + uv_vscroll->set_page(uv_edit_draw->get_size().y); + uv_vscroll->set_value(uv_draw_ofs.y); + uv_vscroll->set_step(0.001); + updating_uv_scroll=false; + +} + +void Polygon2DEditor::edit(Node *p_collision_polygon) { + + if (!canvas_item_editor) { + canvas_item_editor=CanvasItemEditor::get_singleton(); + } + + if (p_collision_polygon) { + + node=p_collision_polygon->cast_to<Polygon2D>(); + if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw"); + + wip.clear(); + wip_active=false; + edited_point=-1; + + } else { + + node=NULL; + + if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw"); + + } + +} + +void Polygon2DEditor::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_menu_option"),&Polygon2DEditor::_menu_option); + ClassDB::bind_method(D_METHOD("_canvas_draw"),&Polygon2DEditor::_canvas_draw); + ClassDB::bind_method(D_METHOD("_uv_mode"),&Polygon2DEditor::_uv_mode); + ClassDB::bind_method(D_METHOD("_uv_draw"),&Polygon2DEditor::_uv_draw); + ClassDB::bind_method(D_METHOD("_uv_input"),&Polygon2DEditor::_uv_input); + ClassDB::bind_method(D_METHOD("_uv_scroll_changed"),&Polygon2DEditor::_uv_scroll_changed); + ClassDB::bind_method(D_METHOD("_node_removed"),&Polygon2DEditor::_node_removed); + ClassDB::bind_method(D_METHOD("_set_use_snap"),&Polygon2DEditor::_set_use_snap); + ClassDB::bind_method(D_METHOD("_set_show_grid"),&Polygon2DEditor::_set_show_grid); + ClassDB::bind_method(D_METHOD("_set_snap_off_x"),&Polygon2DEditor::_set_snap_off_x); + ClassDB::bind_method(D_METHOD("_set_snap_off_y"),&Polygon2DEditor::_set_snap_off_y); + ClassDB::bind_method(D_METHOD("_set_snap_step_x"),&Polygon2DEditor::_set_snap_step_x); + ClassDB::bind_method(D_METHOD("_set_snap_step_y"),&Polygon2DEditor::_set_snap_step_y); + + +} + +inline float _snap_scalar(float p_offset, float p_step, float p_target) { + return p_step != 0 ? Math::stepify(p_target - p_offset, p_step) + p_offset : p_target; +} + +Vector2 Polygon2DEditor::snap_point(Vector2 p_target) const { + if (use_snap) { + p_target.x = _snap_scalar(snap_offset.x*uv_draw_zoom-uv_draw_ofs.x, snap_step.x*uv_draw_zoom, p_target.x); + p_target.y = _snap_scalar(snap_offset.y*uv_draw_zoom-uv_draw_ofs.y, snap_step.y*uv_draw_zoom, p_target.y); + } + + return p_target; +} + +Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) { + + node=NULL; + canvas_item_editor=NULL; + editor=p_editor; + undo_redo = editor->get_undo_redo(); + + snap_step=Vector2(10,10); + use_snap=false; + snap_show_grid=false; + + add_child( memnew( VSeparator )); + button_create = memnew( ToolButton ); + add_child(button_create); + button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE)); + button_create->set_toggle_mode(true); + + button_edit = memnew( ToolButton ); + add_child(button_edit); + button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT)); + button_edit->set_toggle_mode(true); + + button_uv = memnew( ToolButton ); + add_child(button_uv); + button_uv->connect("pressed",this,"_menu_option",varray(MODE_EDIT_UV)); + + //add_constant_override("separation",0); + +#if 0 + options = memnew( MenuButton ); + add_child(options); + options->set_area_as_parent_rect(); + options->set_text("Polygon"); + //options->get_popup()->add_item("Parse BBCode",PARSE_BBCODE); + options->get_popup()->connect("id_pressed", this,"_menu_option"); +#endif + + mode = MODE_EDIT; + wip_active=false; + + uv_mode=UV_MODE_EDIT_POINT; + uv_edit = memnew( AcceptDialog ); + add_child(uv_edit); + uv_edit->set_title(TTR("Polygon 2D UV Editor")); + uv_edit->set_self_modulate(Color(1,1,1,0.9)); + + VBoxContainer *uv_main_vb = memnew( VBoxContainer ); + uv_edit->add_child(uv_main_vb); + //uv_edit->set_child_rect(uv_main_vb); + HBoxContainer *uv_mode_hb = memnew( HBoxContainer ); + uv_main_vb->add_child(uv_mode_hb); + for(int i=0;i<UV_MODE_MAX;i++) { + + uv_button[i]=memnew( ToolButton ); + uv_button[i]->set_toggle_mode(true); + uv_mode_hb->add_child(uv_button[i]); + uv_button[i]->connect("pressed",this,"_uv_mode",varray(i)); + uv_button[i]->set_focus_mode(FOCUS_NONE); + } + + uv_button[0]->set_tooltip(TTR("Move Point")+"\n"+TTR("Ctrl: Rotate")+"\n"+TTR("Shift: Move All")+"\n"+TTR("Shift+Ctrl: Scale")); + uv_button[1]->set_tooltip(TTR("Move Polygon")); + uv_button[2]->set_tooltip(TTR("Rotate Polygon")); + uv_button[3]->set_tooltip(TTR("Scale Polygon")); + + uv_button[0]->set_pressed(true); + HBoxContainer *uv_main_hb = memnew( HBoxContainer ); + uv_main_vb->add_child(uv_main_hb); + uv_edit_draw = memnew( Control ); + uv_main_hb->add_child(uv_edit_draw); + uv_main_hb->set_v_size_flags(SIZE_EXPAND_FILL); + uv_edit_draw->set_h_size_flags(SIZE_EXPAND_FILL); + uv_menu = memnew( MenuButton ); + uv_mode_hb->add_child(uv_menu); + uv_menu->set_text(TTR("Edit")); + uv_menu->get_popup()->add_item(TTR("Polygon->UV"),UVEDIT_POLYGON_TO_UV); + uv_menu->get_popup()->add_item(TTR("UV->Polygon"),UVEDIT_UV_TO_POLYGON); + uv_menu->get_popup()->add_separator(); + uv_menu->get_popup()->add_item(TTR("Clear UV"),UVEDIT_UV_CLEAR); + uv_menu->get_popup()->connect("id_pressed",this,"_menu_option"); + + uv_mode_hb->add_child( memnew( VSeparator )); + + b_snap_enable = memnew( ToolButton ); + uv_mode_hb->add_child(b_snap_enable); + b_snap_enable->set_text(TTR("Snap")); + b_snap_enable->set_focus_mode(FOCUS_NONE); + b_snap_enable->set_toggle_mode(true); + b_snap_enable->set_pressed(use_snap); + b_snap_enable->set_tooltip(TTR("Enable Snap")); + b_snap_enable->connect("toggled",this,"_set_use_snap"); + + b_snap_grid = memnew( ToolButton ); + uv_mode_hb->add_child(b_snap_grid); + b_snap_grid->set_text(TTR("Grid")); + b_snap_grid->set_focus_mode(FOCUS_NONE); + b_snap_grid->set_toggle_mode(true); + b_snap_grid->set_pressed(snap_show_grid); + b_snap_grid->set_tooltip(TTR("Show Grid")); + b_snap_grid->connect("toggled",this,"_set_show_grid"); + + uv_mode_hb->add_child( memnew( VSeparator )); + uv_mode_hb->add_child( memnew( Label(TTR("Grid Offset:")) ) ); + + SpinBox *sb_off_x = memnew( SpinBox ); + sb_off_x->set_min(-256); + sb_off_x->set_max(256); + sb_off_x->set_step(1); + sb_off_x->set_value(snap_offset.x); + sb_off_x->set_suffix("px"); + sb_off_x->connect("value_changed", this, "_set_snap_off_x"); + uv_mode_hb->add_child(sb_off_x); + + SpinBox *sb_off_y = memnew( SpinBox ); + sb_off_y->set_min(-256); + sb_off_y->set_max(256); + sb_off_y->set_step(1); + sb_off_y->set_value(snap_offset.y); + sb_off_y->set_suffix("px"); + sb_off_y->connect("value_changed", this, "_set_snap_off_y"); + uv_mode_hb->add_child(sb_off_y); + + uv_mode_hb->add_child( memnew( VSeparator )); + uv_mode_hb->add_child( memnew( Label(TTR("Grid Step:")) ) ); + + SpinBox *sb_step_x = memnew( SpinBox ); + sb_step_x->set_min(-256); + sb_step_x->set_max(256); + sb_step_x->set_step(1); + sb_step_x->set_value(snap_step.x); + sb_step_x->set_suffix("px"); + sb_step_x->connect("value_changed", this, "_set_snap_step_x"); + uv_mode_hb->add_child(sb_step_x); + + SpinBox *sb_step_y = memnew( SpinBox ); + sb_step_y->set_min(-256); + sb_step_y->set_max(256); + sb_step_y->set_step(1); + sb_step_y->set_value(snap_step.y); + sb_step_y->set_suffix("px"); + sb_step_y->connect("value_changed", this, "_set_snap_step_y"); + uv_mode_hb->add_child(sb_step_y); + + uv_mode_hb->add_child( memnew( VSeparator )); + uv_icon_zoom = memnew( TextureRect ); + uv_mode_hb->add_child( uv_icon_zoom ); + uv_zoom = memnew( HSlider ); + uv_zoom->set_min(0.01); + uv_zoom->set_max(4); + uv_zoom->set_value(1); + uv_zoom->set_step(0.01); + uv_mode_hb->add_child(uv_zoom); + uv_zoom->set_custom_minimum_size(Size2(200,0)); + uv_zoom_value = memnew( SpinBox ); + uv_zoom->share(uv_zoom_value); + uv_zoom_value->set_custom_minimum_size(Size2(50,0)); + uv_mode_hb->add_child(uv_zoom_value); + uv_zoom->connect("value_changed",this,"_uv_scroll_changed"); + + + + uv_vscroll = memnew( VScrollBar); + uv_main_hb->add_child(uv_vscroll); + uv_vscroll->connect("value_changed",this,"_uv_scroll_changed"); + uv_hscroll = memnew( HScrollBar ); + uv_main_vb->add_child(uv_hscroll); + uv_hscroll->connect("value_changed",this,"_uv_scroll_changed"); + + uv_edit_draw->connect("draw",this,"_uv_draw"); + uv_edit_draw->connect("gui_input",this,"_uv_input"); + uv_draw_zoom=1.0; + uv_drag_index=-1; + uv_drag=false; + updating_uv_scroll=false; + + error = memnew( AcceptDialog); + add_child(error); + + uv_edit_draw->set_clip_contents(true); + +} + + +void Polygon2DEditorPlugin::edit(Object *p_object) { + + + collision_polygon_editor->edit(p_object->cast_to<Node>()); +} + +bool Polygon2DEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("Polygon2D"); +} + +void Polygon2DEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + collision_polygon_editor->show(); + } else { + + collision_polygon_editor->hide(); + collision_polygon_editor->edit(NULL); + } + +} + +Polygon2DEditorPlugin::Polygon2DEditorPlugin(EditorNode *p_node) { + + editor=p_node; + collision_polygon_editor = memnew( Polygon2DEditor(p_node) ); + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); + + collision_polygon_editor->hide(); + +} + + +Polygon2DEditorPlugin::~Polygon2DEditorPlugin() +{ +} + diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h new file mode 100644 index 0000000000..c994867705 --- /dev/null +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -0,0 +1,167 @@ +/*************************************************************************/ +/* polygon_2d_editor_plugin.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. */ +/*************************************************************************/ +#ifndef POLYGON_2D_EDITOR_PLUGIN_H +#define POLYGON_2D_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/2d/polygon_2d.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/button_group.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ +class CanvasItemEditor; + +class Polygon2DEditor : public HBoxContainer { + + GDCLASS(Polygon2DEditor, HBoxContainer ); + + UndoRedo *undo_redo; + enum Mode { + + MODE_CREATE, + MODE_EDIT, + MODE_EDIT_UV, + UVEDIT_POLYGON_TO_UV, + UVEDIT_UV_TO_POLYGON, + UVEDIT_UV_CLEAR + + }; + + enum UVMode { + UV_MODE_EDIT_POINT, + UV_MODE_MOVE, + UV_MODE_ROTATE, + UV_MODE_SCALE, + UV_MODE_MAX + }; + + Mode mode; + + UVMode uv_mode; + AcceptDialog *uv_edit; + ToolButton *uv_button[4]; + ToolButton *b_snap_enable; + ToolButton *b_snap_grid; + Control *uv_edit_draw; + HSlider *uv_zoom; + SpinBox *uv_zoom_value; + HScrollBar *uv_hscroll; + VScrollBar *uv_vscroll; + MenuButton *uv_menu; + TextureRect *uv_icon_zoom; + + Vector2 uv_draw_ofs; + float uv_draw_zoom; + PoolVector<Vector2> uv_prev; + int uv_drag_index; + bool uv_drag; + UVMode uv_move_current; + Vector2 uv_drag_from; + bool updating_uv_scroll; + + + + AcceptDialog *error; + + ToolButton *button_create; + ToolButton *button_edit; + ToolButton *button_uv; + + CanvasItemEditor *canvas_item_editor; + EditorNode *editor; + Panel *panel; + Polygon2D *node; + MenuButton *options; + + int edited_point; + Vector2 edited_point_pos; + Vector<Vector2> pre_move_edit; + Vector<Vector2> wip; + bool wip_active; + + bool use_snap; + bool snap_show_grid; + Vector2 snap_offset; + Vector2 snap_step; + + void _uv_scroll_changed(float); + void _uv_input(const InputEvent& p_input); + void _uv_draw(); + void _uv_mode(int p_mode); + void _wip_close(); + void _canvas_draw(); + void _menu_option(int p_option); + + void _set_use_snap(bool p_use); + void _set_show_grid(bool p_show); + void _set_snap_off_x(float p_val); + void _set_snap_off_y(float p_val); + void _set_snap_step_x(float p_val); + void _set_snap_step_y(float p_val); + +protected: + void _notification(int p_what); + void _node_removed(Node *p_node); + static void _bind_methods(); + + Vector2 snap_point(Vector2 p_target) const; + +public: + + bool forward_gui_input(const InputEvent& p_event); + void edit(Node *p_collision_polygon); + Polygon2DEditor(EditorNode *p_editor); +}; + +class Polygon2DEditorPlugin : public EditorPlugin { + + GDCLASS( Polygon2DEditorPlugin, EditorPlugin ); + + Polygon2DEditor *collision_polygon_editor; + EditorNode *editor; + +public: + + virtual bool forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); } + + virtual String get_name() const { return "Polygon2D"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + Polygon2DEditorPlugin(EditorNode *p_node); + ~Polygon2DEditorPlugin(); + +}; + +#endif // POLYGON_2D_EDITOR_PLUGIN_H diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp new file mode 100644 index 0000000000..e876fa55c6 --- /dev/null +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -0,0 +1,507 @@ +/*************************************************************************/ +/* resource_preloader_editor_plugin.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 "resource_preloader_editor_plugin.h" + +#include "io/resource_loader.h" +#include "global_config.h" +#include "editor/editor_settings.h" + + +void ResourcePreloaderEditor::_gui_input(InputEvent p_event) { + + +} + +void ResourcePreloaderEditor::_notification(int p_what) { + + if (p_what==NOTIFICATION_FIXED_PROCESS) { + + } + + if (p_what==NOTIFICATION_ENTER_TREE) { + load->set_icon( get_icon("Folder","EditorIcons") ); + _delete->set_icon( get_icon("Del","EditorIcons") ); + } + + if (p_what==NOTIFICATION_READY) { + + //NodePath("/root")->connect("node_removed", this,"_node_removed",Vector<Variant>(),true); + } + + if (p_what==NOTIFICATION_DRAW) { + + } +} + +void ResourcePreloaderEditor::_files_load_request(const Vector<String>& p_paths) { + + for(int i=0;i<p_paths.size();i++) { + + String path = p_paths[i]; + + RES resource; + resource = ResourceLoader::load(path); + + if (resource.is_null()) { + dialog->set_text(TTR("ERROR: Couldn't load resource!")); + dialog->set_title(TTR("Error!")); + //dialog->get_cancel()->set_text("Close"); + dialog->get_ok()->set_text(TTR("Close")); + dialog->popup_centered_minsize(); + return; ///beh should show an error i guess + } + + + String basename = path.get_file().get_basename(); + String name=basename; + int counter=1; + while(preloader->has_resource(name)) { + counter++; + name=basename+" "+itos(counter); + } + + undo_redo->create_action(TTR("Add Resource")); + undo_redo->add_do_method(preloader,"add_resource",name,resource); + undo_redo->add_undo_method(preloader,"remove_resource",name); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + } +} + +void ResourcePreloaderEditor::_load_pressed() { + + loading_scene=false; + + file->clear_filters(); + List<String> extensions; + ResourceLoader::get_recognized_extensions_for_type("",&extensions); + for(int i=0;i<extensions.size();i++) + file->add_filter("*."+extensions[i]); + + file->set_mode(EditorFileDialog::MODE_OPEN_FILES); + + file->popup_centered_ratio(); + +} + + +void ResourcePreloaderEditor::_item_edited() { + + if (!tree->get_selected()) + return; + + TreeItem *s = tree->get_selected(); + + if (tree->get_selected_column()==0) { + // renamed + String old_name=s->get_metadata(0); + String new_name=s->get_text(0); + if (old_name==new_name) + return; + + if (new_name=="" || new_name.find("\\")!=-1 || new_name.find("/")!=-1 || preloader->has_resource(new_name)) { + + s->set_text(0,old_name); + return; + } + + RES samp = preloader->get_resource(old_name); + undo_redo->create_action(TTR("Rename Resource")); + undo_redo->add_do_method(preloader,"remove_resource",old_name); + undo_redo->add_do_method(preloader,"add_resource",new_name,samp); + undo_redo->add_undo_method(preloader,"remove_resource",new_name); + undo_redo->add_undo_method(preloader,"add_resource",old_name,samp); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + + } + + +} + +void ResourcePreloaderEditor::_delete_confirm_pressed() { + + if (!tree->get_selected()) + return; + + String to_remove = tree->get_selected()->get_text(0); + undo_redo->create_action(TTR("Delete Resource")); + undo_redo->add_do_method(preloader,"remove_resource",to_remove); + undo_redo->add_undo_method(preloader,"add_resource",to_remove,preloader->get_resource(to_remove)); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); +} + + +void ResourcePreloaderEditor::_paste_pressed() { + + RES r=EditorSettings::get_singleton()->get_resource_clipboard(); + if (!r.is_valid()) { + dialog->set_text(TTR("Resource clipboard is empty!")); + dialog->set_title(TTR("Error!")); + //dialog->get_cancel()->set_text("Close"); + dialog->get_ok()->set_text(TTR("Close")); + dialog->popup_centered_minsize(); + return; ///beh should show an error i guess + } + + String name = r->get_name(); + if (name=="") + name=r->get_path().get_file(); + if (name=="") + name=r->get_class(); + + String basename = name; + int counter=1; + while(preloader->has_resource(name)) { + counter++; + name=basename+" "+itos(counter); + } + + undo_redo->create_action(TTR("Paste Resource")); + undo_redo->add_do_method(preloader,"add_resource",name,r); + undo_redo->add_undo_method(preloader,"remove_resource",name); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + +} + + +void ResourcePreloaderEditor::_delete_pressed() { + + + if (!tree->get_selected()) + return; + + _delete_confirm_pressed(); //it has undo.. why bother with a dialog.. + /* + dialog->set_title("Confirm..."); + dialog->set_text("Remove Resource '"+tree->get_selected()->get_text(0)+"' ?"); + //dialog->get_cancel()->set_text("Cancel"); + //dialog->get_ok()->show(); + dialog->get_ok()->set_text("Remove"); + dialog->popup_centered(Size2(300,60));*/ + +} + + +void ResourcePreloaderEditor::_update_library() { + + tree->clear(); + tree->set_hide_root(true); + TreeItem *root = tree->create_item(NULL); + + List<StringName> rnames; + preloader->get_resource_list(&rnames); + + List<String> names; + for(List<StringName>::Element *E=rnames.front();E;E=E->next()) { + names.push_back(E->get()); + } + + names.sort(); + + for(List<String>::Element *E=names.front();E;E=E->next()) { + + TreeItem *ti = tree->create_item(root); + ti->set_cell_mode(0,TreeItem::CELL_MODE_STRING); + ti->set_editable(0,true); + ti->set_selectable(0,true); + ti->set_text(0,E->get()); + ti->set_metadata(0,E->get()); + + + + RES r = preloader->get_resource(E->get()); + + ERR_CONTINUE(r.is_null()); + + ti->set_tooltip(0,r->get_path()); + String type = r->get_class(); + ti->set_text(1,type); + ti->set_selectable(1,false); + + if (has_icon(type,"EditorIcons")) + ti->set_icon( 1, get_icon(type,"EditorIcons") ); + + } + + //player->add_resource("default",resource); +} + + + +void ResourcePreloaderEditor::edit(ResourcePreloader* p_preloader) { + + preloader=p_preloader; + + + if (p_preloader) { + _update_library(); + } else { + + hide(); + set_fixed_process(false); + } + +} + + + +Variant ResourcePreloaderEditor::get_drag_data_fw(const Point2& p_point,Control* p_from) { + + TreeItem*ti =tree->get_item_at_pos(p_point); + if (!ti) + return Variant(); + + String name = ti->get_metadata(0); + + RES res = preloader->get_resource(name); + if (!res.is_valid()) + return Variant(); + + return EditorNode::get_singleton()->drag_resource(res,p_from); + +} + +bool ResourcePreloaderEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const { + + + + Dictionary d = p_data; + + if (!d.has("type")) + return false; + + if (d.has("from") && (Object*)(d["from"])==tree) + return false; + + if (String(d["type"])=="resource" && d.has("resource")) { + RES r=d["resource"]; + + return r.is_valid(); + } + + + if (String(d["type"])=="files") { + + Vector<String> files = d["files"]; + + if (files.size()==0) + return false; + + return true; + + } + return false; +} + +void ResourcePreloaderEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) { + + if (!can_drop_data_fw(p_point,p_data,p_from)) + return; + + Dictionary d = p_data; + + if (!d.has("type")) + return; + + + if (String(d["type"])=="resource" && d.has("resource")) { + RES r=d["resource"]; + + if (r.is_valid()) { + + String basename; + if (r->get_name()!="") { + basename=r->get_name(); + } else if (r->get_path().is_resource_file()) { + basename = r->get_path().get_basename(); + } else { + basename="Resource"; + } + + String name=basename; + int counter=0; + while(preloader->has_resource(name)) { + counter++; + name=basename+"_"+itos(counter); + } + + undo_redo->create_action(TTR("Add Resource")); + undo_redo->add_do_method(preloader,"add_resource",name,r); + undo_redo->add_undo_method(preloader,"remove_resource",name); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + } + } + + + if (String(d["type"])=="files") { + + Vector<String> files = d["files"]; + + _files_load_request(files); + } +} + + + +void ResourcePreloaderEditor::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_gui_input"),&ResourcePreloaderEditor::_gui_input); + ClassDB::bind_method(D_METHOD("_load_pressed"),&ResourcePreloaderEditor::_load_pressed); + ClassDB::bind_method(D_METHOD("_item_edited"),&ResourcePreloaderEditor::_item_edited); + ClassDB::bind_method(D_METHOD("_delete_pressed"),&ResourcePreloaderEditor::_delete_pressed); + ClassDB::bind_method(D_METHOD("_paste_pressed"),&ResourcePreloaderEditor::_paste_pressed); + ClassDB::bind_method(D_METHOD("_delete_confirm_pressed"),&ResourcePreloaderEditor::_delete_confirm_pressed); + ClassDB::bind_method(D_METHOD("_files_load_request"),&ResourcePreloaderEditor::_files_load_request); + ClassDB::bind_method(D_METHOD("_update_library"),&ResourcePreloaderEditor::_update_library); + + + ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &ResourcePreloaderEditor::get_drag_data_fw); + ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &ResourcePreloaderEditor::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("drop_data_fw"), &ResourcePreloaderEditor::drop_data_fw); + + +} + +ResourcePreloaderEditor::ResourcePreloaderEditor() { + + //add_style_override("panel", get_stylebox("panel","Panel")); + + VBoxContainer *vbc = memnew( VBoxContainer ); + add_child(vbc); + + HBoxContainer *hbc = memnew( HBoxContainer ); + vbc->add_child(hbc); + + load = memnew( Button ); + load->set_tooltip(TTR("Load Resource")); + hbc->add_child(load); + + + + _delete = memnew( Button ); + hbc->add_child(_delete); + + paste = memnew( Button ); + paste->set_text(TTR("Paste")); + hbc->add_child(paste); + + file = memnew( EditorFileDialog ); + add_child(file); + + + tree = memnew( Tree ); + tree->set_columns(2); + tree->set_column_min_width(0,3); + tree->set_column_min_width(1,1); + tree->set_column_expand(0,true); + tree->set_column_expand(1,true); + tree->set_v_size_flags(SIZE_EXPAND_FILL); + + tree->set_drag_forwarding(this); + vbc->add_child(tree); + + dialog = memnew( AcceptDialog ); + add_child( dialog ); + + load->connect("pressed", this,"_load_pressed"); + _delete->connect("pressed", this,"_delete_pressed"); + paste->connect("pressed", this,"_paste_pressed"); + file->connect("files_selected", this,"_files_load_request"); + //dialog->connect("confirmed", this,"_delete_confirm_pressed"); + tree->connect("item_edited", this,"_item_edited"); + loading_scene=false; + +} + + +void ResourcePreloaderEditorPlugin::edit(Object *p_object) { + + preloader_editor->set_undo_redo(&get_undo_redo()); + ResourcePreloader * s = p_object->cast_to<ResourcePreloader>(); + if (!s) + return; + + preloader_editor->edit(s); +} + +bool ResourcePreloaderEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("ResourcePreloader"); +} + +void ResourcePreloaderEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + //preloader_editor->show(); + button->show(); + editor->make_bottom_panel_item_visible(preloader_editor); + //preloader_editor->set_process(true); + } else { + + if (preloader_editor->is_visible_in_tree()) + editor->hide_bottom_panel(); + button->hide(); + //preloader_editor->hide(); + //preloader_editor->set_process(false); + } + +} + +ResourcePreloaderEditorPlugin::ResourcePreloaderEditorPlugin(EditorNode *p_node) { + + editor=p_node; + preloader_editor = memnew( ResourcePreloaderEditor ); + preloader_editor->set_custom_minimum_size(Size2(0,250)); + + button=editor->add_bottom_panel_item("ResourcePreloader",preloader_editor); + button->hide(); + + //preloader_editor->set_anchor( MARGIN_TOP, Control::ANCHOR_END); + //preloader_editor->set_margin( MARGIN_TOP, 120 ); + + + + +} + + +ResourcePreloaderEditorPlugin::~ResourcePreloaderEditorPlugin() +{ +} + + diff --git a/editor/plugins/resource_preloader_editor_plugin.h b/editor/plugins/resource_preloader_editor_plugin.h new file mode 100644 index 0000000000..54ccad4341 --- /dev/null +++ b/editor/plugins/resource_preloader_editor_plugin.h @@ -0,0 +1,108 @@ +/*************************************************************************/ +/* resource_preloader_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef RESOURCE_PRELOADER_EDITOR_PLUGIN_H +#define RESOURCE_PRELOADER_EDITOR_PLUGIN_H + + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/gui/tree.h" +#include "scene/main/resource_preloader.h" +#include "scene/gui/file_dialog.h" +#include "scene/gui/dialogs.h" + + +class ResourcePreloaderEditor : public PanelContainer { + + GDCLASS(ResourcePreloaderEditor, PanelContainer ); + + Button *load; + Button *_delete; + Button *paste; + Tree *tree; + bool loading_scene; + + + EditorFileDialog *file; + + AcceptDialog *dialog; + + ResourcePreloader *preloader; + + + void _load_pressed(); + void _load_scene_pressed(); + void _files_load_request(const Vector<String>& p_paths); + void _paste_pressed(); + void _delete_pressed(); + void _delete_confirm_pressed(); + void _update_library(); + void _item_edited(); + + UndoRedo *undo_redo; + + Variant get_drag_data_fw(const Point2& p_point,Control* p_from); + bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; + void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); + + +protected: + void _notification(int p_what); + void _gui_input(InputEvent p_event); + static void _bind_methods(); +public: + + void set_undo_redo(UndoRedo *p_undo_redo) {undo_redo=p_undo_redo; } + + void edit(ResourcePreloader* p_preloader); + ResourcePreloaderEditor(); +}; + +class ResourcePreloaderEditorPlugin : public EditorPlugin { + + GDCLASS( ResourcePreloaderEditorPlugin, EditorPlugin ); + + ResourcePreloaderEditor *preloader_editor; + EditorNode *editor; + Button *button; + +public: + + virtual String get_name() const { return "ResourcePreloader"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + ResourcePreloaderEditorPlugin(EditorNode *p_node); + ~ResourcePreloaderEditorPlugin(); + +}; + +#endif // RESOURCE_PRELOADER_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/rich_text_editor_plugin.cpp b/editor/plugins/rich_text_editor_plugin.cpp index 797ee8e8ea..797ee8e8ea 100644 --- a/tools/editor/plugins/rich_text_editor_plugin.cpp +++ b/editor/plugins/rich_text_editor_plugin.cpp diff --git a/editor/plugins/rich_text_editor_plugin.h b/editor/plugins/rich_text_editor_plugin.h new file mode 100644 index 0000000000..c7f95fb479 --- /dev/null +++ b/editor/plugins/rich_text_editor_plugin.h @@ -0,0 +1,91 @@ +/*************************************************************************/ +/* rich_text_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef RICH_TEXT_EDITOR_PLUGIN_H +#define RICH_TEXT_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/gui/rich_text_label.h" +#include "scene/gui/file_dialog.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +class RichTextEditor : public Control { + + GDCLASS(RichTextEditor, Control ); + + friend class RichTextEditorPlugin; + + enum { + + PARSE_BBCODE, + CLEAR + }; + + Panel *panel; + MenuButton *options; + RichTextLabel *node; + EditorFileDialog *file_dialog; + + void _file_selected(const String& p_path); + void _menu_option(int p_option); + +protected: + void _notification(int p_what); + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + void edit(Node *p_rich_text); + RichTextEditor(); +}; + +class RichTextEditorPlugin : public EditorPlugin { + + GDCLASS( RichTextEditorPlugin, EditorPlugin ); + + RichTextEditor *rich_text_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "RichText"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + RichTextEditorPlugin(EditorNode *p_node); + ~RichTextEditorPlugin(); + +}; + +#endif // RICH_TEXT_EDITOR_PLUGIN_H diff --git a/editor/plugins/sample_editor_plugin.cpp b/editor/plugins/sample_editor_plugin.cpp new file mode 100644 index 0000000000..b6b96c946e --- /dev/null +++ b/editor/plugins/sample_editor_plugin.cpp @@ -0,0 +1,451 @@ +/*************************************************************************/ +/* sample_editor_plugin.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 "sample_editor_plugin.h" + +#if 0 +#include "io/resource_loader.h" +#include "global_config.h" +#include "editor/editor_settings.h" + + + + +void SampleEditor::_gui_input(InputEvent p_event) { + + +} + +void SampleEditor::_notification(int p_what) { + + if (p_what==NOTIFICATION_FIXED_PROCESS) { + + } + + if (p_what==NOTIFICATION_ENTER_TREE) { + play->set_icon( get_icon("Play","EditorIcons") ); + stop->set_icon( get_icon("Stop","EditorIcons") ); + } + + if (p_what==NOTIFICATION_READY) { + + //get_scene()->connect("node_removed",this,"_node_removed"); + + } + + if (p_what==NOTIFICATION_DRAW) { + + } +} + +void SampleEditor::_play_pressed() { + + player->play("default",true); + stop->set_pressed(false); + play->set_pressed(true); +} +void SampleEditor::_stop_pressed() { + + player->stop_all(); + play->set_pressed(false); +} + +void SampleEditor::generate_preview_texture(const Ref<Sample>& p_sample,Ref<ImageTexture> &p_texture) { + + + PoolVector<uint8_t> data = p_sample->get_data(); + + PoolVector<uint8_t> img; + int w = p_texture->get_width(); + int h = p_texture->get_height(); + img.resize(w*h*3); + PoolVector<uint8_t>::Write imgdata = img.write(); + uint8_t * imgw = imgdata.ptr(); + PoolVector<uint8_t>::Read sampledata = data.read(); + const uint8_t *sdata=sampledata.ptr(); + + bool stereo = p_sample->is_stereo(); + bool _16=p_sample->get_format()==Sample::FORMAT_PCM16; + int len = p_sample->get_length(); + + if (len<1) + return; + + if (p_sample->get_format()==Sample::FORMAT_IMA_ADPCM) { + + + struct IMA_ADPCM_State { + + int16_t step_index; + int32_t predictor; + /* values at loop point */ + int16_t loop_step_index; + int32_t loop_predictor; + int32_t last_nibble; + int32_t loop_pos; + int32_t window_ofs; + const uint8_t *ptr; + } ima_adpcm; + + ima_adpcm.step_index=0; + ima_adpcm.predictor=0; + ima_adpcm.loop_step_index=0; + ima_adpcm.loop_predictor=0; + ima_adpcm.last_nibble=-1; + ima_adpcm.loop_pos=0x7FFFFFFF; + ima_adpcm.window_ofs=0; + ima_adpcm.ptr=NULL; + + + for(int i=0;i<w;i++) { + + float max[2]={-1e10,-1e10}; + float min[2]={1e10,1e10}; + int from = i*len/w; + int to = (i+1)*len/w; + if (to>=len) + to=len-1; + + for(int j=from;j<to;j++) { + + while(j>ima_adpcm.last_nibble) { + + static const int16_t _ima_adpcm_step_table[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 + }; + + static const int8_t _ima_adpcm_index_table[16] = { + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8 + }; + + int16_t nibble,diff,step; + + ima_adpcm.last_nibble++; + const uint8_t *src_ptr=sdata; + + int ofs = ima_adpcm.last_nibble>>1; + + if (stereo) + ofs*=2; + + nibble = (ima_adpcm.last_nibble&1)? + (src_ptr[ofs]>>4):(src_ptr[ofs]&0xF); + + step=_ima_adpcm_step_table[ima_adpcm.step_index]; + + ima_adpcm.step_index += _ima_adpcm_index_table[nibble]; + if (ima_adpcm.step_index<0) + ima_adpcm.step_index=0; + if (ima_adpcm.step_index>88) + ima_adpcm.step_index=88; + + diff = step >> 3 ; + if (nibble & 1) + diff += step >> 2 ; + if (nibble & 2) + diff += step >> 1 ; + if (nibble & 4) + diff += step ; + if (nibble & 8) + diff = -diff ; + + ima_adpcm.predictor+=diff; + if (ima_adpcm.predictor<-0x8000) + ima_adpcm.predictor=-0x8000; + else if (ima_adpcm.predictor>0x7FFF) + ima_adpcm.predictor=0x7FFF; + + + /* store loop if there */ + if (ima_adpcm.last_nibble==ima_adpcm.loop_pos) { + + ima_adpcm.loop_step_index = ima_adpcm.step_index; + ima_adpcm.loop_predictor = ima_adpcm.predictor; + } + + } + + float v=ima_adpcm.predictor/32767.0; + if (v>max[0]) + max[0]=v; + if (v<min[0]) + min[0]=v; + } + + for(int j=0;j<h;j++) { + float v = (j/(float)h) * 2.0 - 1.0; + uint8_t* imgofs = &imgw[(uint64_t(j)*w+i)*3]; + if (v>min[0] && v<max[0]) { + imgofs[0]=255; + imgofs[1]=150; + imgofs[2]=80; + } else { + imgofs[0]=0; + imgofs[1]=0; + imgofs[2]=0; + } + } + } + } else { + for(int i=0;i<w;i++) { + // i trust gcc will optimize this loop + float max[2]={-1e10,-1e10}; + float min[2]={1e10,1e10}; + int c=stereo?2:1; + int from = uint64_t(i)*len/w; + int to = (uint64_t(i)+1)*len/w; + if (to>=len) + to=len-1; + + if (_16) { + const int16_t*src =(const int16_t*)sdata; + + for(int j=0;j<c;j++) { + + for(int k=from;k<=to;k++) { + + float v = src[uint64_t(k)*c+j]/32768.0; + if (v>max[j]) + max[j]=v; + if (v<min[j]) + min[j]=v; + } + + } + } else { + + const int8_t*src =(const int8_t*)sdata; + + for(int j=0;j<c;j++) { + + for(int k=from;k<=to;k++) { + + float v = src[uint64_t(k)*c+j]/128.0; + if (v>max[j]) + max[j]=v; + if (v<min[j]) + min[j]=v; + } + + } + } + + if (!stereo) { + for(int j=0;j<h;j++) { + float v = (j/(float)h) * 2.0 - 1.0; + uint8_t* imgofs = &imgw[(uint64_t(j)*w+i)*3]; + if (v>min[0] && v<max[0]) { + imgofs[0]=255; + imgofs[1]=150; + imgofs[2]=80; + } else { + imgofs[0]=0; + imgofs[1]=0; + imgofs[2]=0; + } + } + } else { + + for(int j=0;j<h;j++) { + + int half; + float v; + if (j<(h/2)) { + half=0; + v = (j/(float)(h/2)) * 2.0 - 1.0; + } else { + half=1; + v = ((j-(h/2))/(float)(h/2)) * 2.0 - 1.0; + } + + uint8_t* imgofs = &imgw[(uint64_t(j)*w+i)*3]; + if (v>min[half] && v<max[half]) { + imgofs[0]=255; + imgofs[1]=150; + imgofs[2]=80; + } else { + imgofs[0]=0; + imgofs[1]=0; + imgofs[2]=0; + } + } + + } + + } + } + + imgdata = PoolVector<uint8_t>::Write(); + + + p_texture->set_data(Image(w,h,0,Image::FORMAT_RGB8,img)); + +} + +void SampleEditor::_update_sample() { + + player->stop_all(); + + generate_preview_texture(sample,peakdisplay); + info_label->set_text(TTR("Length:")+" "+String::num(sample->get_length()/(float)sample->get_mix_rate(),2)+"s"); + + if (library->has_sample("default")) + library->remove_sample("default"); + + library->add_sample("default",sample); +} + + + +void SampleEditor::edit(Ref<Sample> p_sample) { + + sample=p_sample; + + if (!sample.is_null()) + _update_sample(); + else { + + hide(); + set_fixed_process(false); + } + +} + + + +void SampleEditor::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_gui_input"),&SampleEditor::_gui_input); + ClassDB::bind_method(D_METHOD("_play_pressed"),&SampleEditor::_play_pressed); + ClassDB::bind_method(D_METHOD("_stop_pressed"),&SampleEditor::_stop_pressed); + +} + +SampleEditor::SampleEditor() { + + player = memnew(SamplePlayer); + add_child(player); + add_style_override("panel", get_stylebox("panel","Panel")); + library = Ref<SampleLibrary>(memnew(SampleLibrary)); + player->set_sample_library(library); + sample_texframe = memnew( TextureRect ); + add_child(sample_texframe); + sample_texframe->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,5); + sample_texframe->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,5); + sample_texframe->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,30); + sample_texframe->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,5); + + info_label = memnew( Label ); + sample_texframe->add_child(info_label); + info_label->set_area_as_parent_rect(); + info_label->set_anchor_and_margin(MARGIN_TOP,ANCHOR_END,15); + info_label->set_margin(MARGIN_BOTTOM,4); + info_label->set_margin(MARGIN_RIGHT,4); + info_label->set_align(Label::ALIGN_RIGHT); + + + play = memnew( Button ); + + play->set_pos(Point2( 5, 5 )); + play->set_size( Size2(1,1 ) ); + play->set_toggle_mode(true); + add_child(play); + + stop = memnew( Button ); + + stop->set_pos(Point2( 35, 5 )); + stop->set_size( Size2(1,1 ) ); + stop->set_toggle_mode(true); + add_child(stop); + + peakdisplay=Ref<ImageTexture>( memnew( ImageTexture) ); + peakdisplay->create( EDITOR_DEF("editors/sample_editor/preview_width",512),EDITOR_DEF("editors/sample_editor/preview_height",128),Image::FORMAT_RGB8); + sample_texframe->set_expand(true); + sample_texframe->set_texture(peakdisplay); + + play->connect("pressed", this,"_play_pressed"); + stop->connect("pressed", this,"_stop_pressed"); + + set_custom_minimum_size(Size2(1,150)*EDSCALE); + +} + + +void SampleEditorPlugin::edit(Object *p_object) { + + Sample * s = p_object->cast_to<Sample>(); + if (!s) + return; + + sample_editor->edit(Ref<Sample>(s)); +} + +bool SampleEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("Sample"); +} + +void SampleEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + sample_editor->show(); + //sample_editor->set_process(true); + } else { + + sample_editor->hide(); + //sample_editor->set_process(false); + } + +} + +SampleEditorPlugin::SampleEditorPlugin(EditorNode *p_node) { + + editor=p_node; + sample_editor = memnew( SampleEditor ); + add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,sample_editor); + sample_editor->hide(); + + + +} + + +SampleEditorPlugin::~SampleEditorPlugin() +{ +} + +#endif diff --git a/editor/plugins/sample_editor_plugin.h b/editor/plugins/sample_editor_plugin.h new file mode 100644 index 0000000000..dae9cef9f4 --- /dev/null +++ b/editor/plugins/sample_editor_plugin.h @@ -0,0 +1,92 @@ +/*************************************************************************/ +/* sample_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef SAMPLE_EDITOR_PLUGIN_H +#define SAMPLE_EDITOR_PLUGIN_H + +#if 0 +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/audio/sample_player.h" +#include "scene/resources/sample.h" +#include "scene/resources/sample_library.h" + + +class SampleEditor : public Panel { + + GDCLASS(SampleEditor, Panel ); + + + SamplePlayer *player; + Label *info_label; + Ref<ImageTexture> peakdisplay; + Ref<Sample> sample; + Ref<SampleLibrary> library; + TextureRect *sample_texframe; + Button *stop; + Button *play; + + void _play_pressed(); + void _stop_pressed(); + void _update_sample(); + +protected: + void _notification(int p_what); + void _gui_input(InputEvent p_event); + static void _bind_methods(); +public: + + static void generate_preview_texture(const Ref<Sample>& p_sample,Ref<ImageTexture> &p_texture); + void edit(Ref<Sample> p_sample); + SampleEditor(); +}; + + +class SampleEditorPlugin : public EditorPlugin { + + GDCLASS( SampleEditorPlugin, EditorPlugin ); + + SampleEditor *sample_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "Sample"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + SampleEditorPlugin(EditorNode *p_node); + ~SampleEditorPlugin(); + +}; + +#endif + +#endif // SAMPLE_EDITOR_PLUGIN_H diff --git a/editor/plugins/sample_library_editor_plugin.cpp b/editor/plugins/sample_library_editor_plugin.cpp new file mode 100644 index 0000000000..4ead1d2709 --- /dev/null +++ b/editor/plugins/sample_library_editor_plugin.cpp @@ -0,0 +1,546 @@ +/*************************************************************************/ +/* sample_library_editor_plugin.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. */ +/*************************************************************************/ + +#if 0 +#include "sample_library_editor_plugin.h" + +#include "io/resource_loader.h" +#include "global_config.h" +#include "editor/editor_settings.h" +#include "scene/main/viewport.h" +#include "sample_editor_plugin.h" + + +void SampleLibraryEditor::_gui_input(InputEvent p_event) { + + +} + +void SampleLibraryEditor::_notification(int p_what) { + + if (p_what==NOTIFICATION_PROCESS) { + if (is_playing && !player->is_active()) { + TreeItem *tl=last_sample_playing->cast_to<TreeItem>(); + tl->set_button(0,0,get_icon("Play","EditorIcons")); + is_playing = false; + set_process(false); + } + } + + if (p_what==NOTIFICATION_ENTER_TREE) { + load->set_icon( get_icon("Folder","EditorIcons") ); + load->set_tooltip(TTR("Open Sample File(s)")); + } + + if (p_what==NOTIFICATION_READY) { + + //NodePath("/root")->connect("node_removed", this,"_node_removed",Vector<Variant>(),true); + } + + if (p_what==NOTIFICATION_DRAW) { + + } +} + +void SampleLibraryEditor::_file_load_request(const PoolVector<String>& p_path) { + + + for(int i=0;i<p_path.size();i++) { + + String path = p_path[i]; + Ref<Sample> sample = ResourceLoader::load(path,"Sample"); + if (sample.is_null()) { + dialog->set_text(TTR("ERROR: Couldn't load sample!")); + dialog->set_title(TTR("Error!")); + //dialog->get_cancel()->set_text("Close"); + dialog->get_ok()->set_text(TTR("Close")); + dialog->popup_centered_minsize(); + return; ///beh should show an error i guess + } + String basename = path.get_file().get_basename(); + String name=basename; + int counter=0; + while(sample_library->has_sample(name)) { + counter++; + name=basename+"_"+itos(counter); + } + + undo_redo->create_action(TTR("Add Sample")); + undo_redo->add_do_method(sample_library.operator->(),"add_sample",name,sample); + undo_redo->add_undo_method(sample_library.operator->(),"remove_sample",name); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + } +} + +void SampleLibraryEditor::_load_pressed() { + + file->popup_centered_ratio(); + +} + +void SampleLibraryEditor::_button_pressed(Object *p_item,int p_column, int p_id) { + + TreeItem *ti=p_item->cast_to<TreeItem>(); + String name = ti->get_text(0); + + if (p_column==0) { // Play/Stop + + String btn_type; + if(!is_playing) { + is_playing = true; + btn_type = TTR("Stop"); + player->play(name,true); + last_sample_playing = p_item; + set_process(true); + } else { + player->stop_all(); + if(last_sample_playing != p_item){ + TreeItem *tl=last_sample_playing->cast_to<TreeItem>(); + tl->set_button(p_column,0,get_icon("Play","EditorIcons")); + btn_type = TTR("Stop"); + player->play(name,true); + last_sample_playing = p_item; + } else { + btn_type = TTR("Play"); + is_playing = false; + } + } + ti->set_button(p_column,0,get_icon(btn_type,"EditorIcons")); + } else if (p_column==1) { // Edit + + get_tree()->get_root()->get_child(0)->call("_resource_selected",sample_library->get_sample(name)); + } else if (p_column==5) { // Delete + + ti->select(0); + _delete_pressed(); + } + + +} + + + + + +void SampleLibraryEditor::_item_edited() { + + if (!tree->get_selected()) + return; + + TreeItem *s = tree->get_selected(); + + if (tree->get_selected_column()==0) { // Name + // renamed + String old_name=s->get_metadata(0); + String new_name=s->get_text(0); + if (old_name==new_name) + return; + + if (new_name=="" || new_name.find("\\")!=-1 || new_name.find("/")!=-1 || sample_library->has_sample(new_name)) { + + s->set_text(0,old_name); + return; + } + + Ref<Sample> samp = sample_library->get_sample(old_name); + undo_redo->create_action(TTR("Rename Sample")); + undo_redo->add_do_method(sample_library.operator->(),"remove_sample",old_name); + undo_redo->add_do_method(sample_library.operator->(),"add_sample",new_name,samp); + undo_redo->add_undo_method(sample_library.operator->(),"remove_sample",new_name); + undo_redo->add_undo_method(sample_library.operator->(),"add_sample",old_name,samp); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + + } else if (tree->get_selected_column()==3) { // Volume dB + + StringName n = s->get_text(0); + sample_library->sample_set_volume_db(n,s->get_range(3)); + + } else if (tree->get_selected_column()==4) { // Pitch scale + + StringName n = s->get_text(0); + sample_library->sample_set_pitch_scale(n,s->get_range(4)); + + } + + +} + +void SampleLibraryEditor::_delete_pressed() { + + if (!tree->get_selected()) + return; + + String to_remove = tree->get_selected()->get_text(0); + undo_redo->create_action(TTR("Delete Sample")); + undo_redo->add_do_method(sample_library.operator->(),"remove_sample",to_remove); + undo_redo->add_undo_method(sample_library.operator->(),"add_sample",to_remove,sample_library->get_sample(to_remove)); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); +} + + +void SampleLibraryEditor::_update_library() { + + player->stop_all(); + + tree->clear(); + tree->set_hide_root(true); + TreeItem *root = tree->create_item(NULL); + + List<StringName> names; + sample_library->get_sample_list(&names); + names.sort_custom<StringName::AlphCompare>(); + + for(List<StringName>::Element *E=names.front();E;E=E->next()) { + + TreeItem *ti = tree->create_item(root); + + // Name + Play/Stop + ti->set_cell_mode(0,TreeItem::CELL_MODE_STRING); + ti->set_editable(0,true); + ti->set_selectable(0,true); + ti->set_text(0,E->get()); + ti->set_metadata(0,E->get()); + ti->add_button(0,get_icon("Play","EditorIcons")); + + Ref<Sample> smp = sample_library->get_sample(E->get()); + + // Preview/edit + Ref<ImageTexture> preview( memnew( ImageTexture )); + preview->create(128,16,Image::FORMAT_RGB8); + SampleEditor::generate_preview_texture(smp,preview); + ti->set_cell_mode(1,TreeItem::CELL_MODE_ICON); + ti->set_selectable(1,false); + ti->set_editable(1,false); + ti->set_icon(1,preview); + ti->add_button(1,get_icon("Edit","EditorIcons")); + + // Format + ti->set_cell_mode(2,TreeItem::CELL_MODE_STRING); + ti->set_editable(2,false); + ti->set_selectable(2,false); + ti->set_text(2,String()+(smp->get_format()==Sample::FORMAT_PCM16?TTR("16 Bits")+", ":(smp->get_format()==Sample::FORMAT_PCM8?TTR("8 Bits")+", ":"IMA-ADPCM,"))+(smp->is_stereo()?TTR("Stereo"):TTR("Mono"))); + + // Volume dB + ti->set_cell_mode(3,TreeItem::CELL_MODE_RANGE); + ti->set_range_config(3,-60,24,0.01); + ti->set_selectable(3,true); + ti->set_editable(3,true); + ti->set_range(3,sample_library->sample_get_volume_db(E->get())); + + // Pitch scale + ti->set_cell_mode(4,TreeItem::CELL_MODE_RANGE); + ti->set_range_config(4,0.01,100,0.01); + ti->set_selectable(4,true); + ti->set_editable(4,true); + ti->set_range(4,sample_library->sample_get_pitch_scale(E->get())); + + // Delete + ti->set_cell_mode(5,TreeItem::CELL_MODE_STRING); + ti->add_button(5,get_icon("Remove","EditorIcons")); + + } + + //player->add_sample("default",sample); +} + + + +void SampleLibraryEditor::edit(Ref<SampleLibrary> p_sample_library) { + + sample_library=p_sample_library; + + + if (!sample_library.is_null()) { + player->set_sample_library(sample_library); + _update_library(); + } else { + + hide(); + } + +} + +Variant SampleLibraryEditor::get_drag_data_fw(const Point2& p_point,Control* p_from) { + + TreeItem*ti =tree->get_item_at_pos(p_point); + if (!ti) + return Variant(); + + String name = ti->get_metadata(0); + + RES res = sample_library->get_sample(name); + if (!res.is_valid()) + return Variant(); + + return EditorNode::get_singleton()->drag_resource(res,p_from); + + +} + +bool SampleLibraryEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const { + + + + Dictionary d = p_data; + + if (!d.has("type")) + return false; + + if (d.has("from") && (Object*)(d["from"])==tree) + return false; + + if (String(d["type"])=="resource" && d.has("resource")) { + RES r=d["resource"]; + + Ref<Sample> sample = r; + + if (sample.is_valid()) { + + return true; + } + } + + + if (String(d["type"])=="files") { + + Vector<String> files = d["files"]; + + if (files.size()==0) + return false; + + for(int i=0;i<files.size();i++) { + String file = files[0]; + String ftype = EditorFileSystem::get_singleton()->get_file_type(file); + + if (ftype!="Sample") { + return false; + } + + } + + return true; + + } + return false; +} + +void SampleLibraryEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) { + + if (!can_drop_data_fw(p_point,p_data,p_from)) + return; + + Dictionary d = p_data; + + if (!d.has("type")) + return; + + + if (String(d["type"])=="resource" && d.has("resource")) { + RES r=d["resource"]; + + Ref<Sample> sample = r; + + if (sample.is_valid()) { + + String basename; + if (sample->get_name()!="") { + basename=sample->get_name(); + } else if (sample->get_path().is_resource_file()) { + basename = sample->get_path().get_basename(); + } else { + basename="Sample"; + } + + String name=basename; + int counter=0; + while(sample_library->has_sample(name)) { + counter++; + name=basename+"_"+itos(counter); + } + + undo_redo->create_action(TTR("Add Sample")); + undo_redo->add_do_method(sample_library.operator->(),"add_sample",name,sample); + undo_redo->add_undo_method(sample_library.operator->(),"remove_sample",name); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + } + } + + + if (String(d["type"])=="files") { + + PoolVector<String> files = d["files"]; + + _file_load_request(files); + + } + +} + + +void SampleLibraryEditor::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_gui_input"),&SampleLibraryEditor::_gui_input); + ClassDB::bind_method(D_METHOD("_load_pressed"),&SampleLibraryEditor::_load_pressed); + ClassDB::bind_method(D_METHOD("_item_edited"),&SampleLibraryEditor::_item_edited); + ClassDB::bind_method(D_METHOD("_delete_pressed"),&SampleLibraryEditor::_delete_pressed); + ClassDB::bind_method(D_METHOD("_file_load_request"),&SampleLibraryEditor::_file_load_request); + ClassDB::bind_method(D_METHOD("_update_library"),&SampleLibraryEditor::_update_library); + ClassDB::bind_method(D_METHOD("_button_pressed"),&SampleLibraryEditor::_button_pressed); + + ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &SampleLibraryEditor::get_drag_data_fw); + ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SampleLibraryEditor::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("drop_data_fw"), &SampleLibraryEditor::drop_data_fw); + +} + +SampleLibraryEditor::SampleLibraryEditor() { + + player = memnew(SamplePlayer); + add_child(player); + add_style_override("panel", get_stylebox("panel","Panel")); + + + load = memnew( Button ); + load->set_pos(Point2( 5, 5 )); + load->set_size( Size2(1,1 ) ); + add_child(load); + + file = memnew( EditorFileDialog ); + add_child(file); + List<String> extensions; + ResourceLoader::get_recognized_extensions_for_type("Sample",&extensions); + for(int i=0;i<extensions.size();i++) + file->add_filter("*."+extensions[i]); + file->set_mode(EditorFileDialog::MODE_OPEN_FILES); + + tree = memnew( Tree ); + tree->set_columns(6); + add_child(tree); + tree->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,5); + tree->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,5); + tree->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,30); + tree->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,5); + tree->set_column_titles_visible(true); + tree->set_column_title(0,TTR("Name")); + tree->set_column_title(1,TTR("Preview")); + tree->set_column_title(2,TTR("Format")); + tree->set_column_title(3,"dB"); + tree->set_column_title(4,TTR("Pitch")); + tree->set_column_title(5,""); + + tree->set_column_min_width(1,150); + tree->set_column_min_width(2,100); + tree->set_column_min_width(3,50); + tree->set_column_min_width(4,50); + tree->set_column_min_width(5,32); + tree->set_column_expand(1,false); + tree->set_column_expand(2,false); + tree->set_column_expand(3,false); + tree->set_column_expand(4,false); + tree->set_column_expand(5,false); + + tree->set_drag_forwarding(this); + + dialog = memnew( ConfirmationDialog ); + add_child( dialog ); + + tree->connect("button_pressed",this,"_button_pressed"); + load->connect("pressed", this,"_load_pressed"); + file->connect("files_selected", this,"_file_load_request"); + tree->connect("item_edited", this,"_item_edited"); + + is_playing = false; +} + + +void SampleLibraryEditorPlugin::edit(Object *p_object) { + + sample_library_editor->set_undo_redo(&get_undo_redo()); + SampleLibrary * s = p_object->cast_to<SampleLibrary>(); + if (!s) + return; + + sample_library_editor->edit(Ref<SampleLibrary>(s)); +} + +bool SampleLibraryEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("SampleLibrary"); +} + +void SampleLibraryEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + //sample_library_editor->show(); + button->show(); + editor->make_bottom_panel_item_visible(sample_library_editor); + //sample_library_editor->set_process(true); + } else { + + if (sample_library_editor->is_visible_in_tree()) + editor->hide_bottom_panel(); + button->hide(); + + //sample_library_editor->set_process(false); + } + +} + +SampleLibraryEditorPlugin::SampleLibraryEditorPlugin(EditorNode *p_node) { + + editor=p_node; + sample_library_editor = memnew( SampleLibraryEditor ); + + //editor->get_viewport()->add_child(sample_library_editor); + sample_library_editor->set_custom_minimum_size(Size2(0,250)); + button=p_node->add_bottom_panel_item("SampleLibrary",sample_library_editor); + button->hide(); + + //sample_library_editor->set_area_as_parent_rect(); + //sample_library_editor->set_anchor( MARGIN_TOP, Control::ANCHOR_END); + //sample_library_editor->set_margin( MARGIN_TOP, 120 ); + //sample_library_editor->hide(); + + + +} + + +SampleLibraryEditorPlugin::~SampleLibraryEditorPlugin() +{ +} +#endif diff --git a/editor/plugins/sample_library_editor_plugin.h b/editor/plugins/sample_library_editor_plugin.h new file mode 100644 index 0000000000..4bbc29b147 --- /dev/null +++ b/editor/plugins/sample_library_editor_plugin.h @@ -0,0 +1,108 @@ +/*************************************************************************/ +/* sample_library_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef SAMPLE_LIBRARY_EDITOR_PLUGIN_H +#define SAMPLE_LIBRARY_EDITOR_PLUGIN_H + + +#if 0 +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/audio/sample_player.h" +#include "scene/resources/sample.h" +#include "scene/gui/tree.h" +#include "scene/gui/file_dialog.h" +#include "scene/gui/dialogs.h" + + +class SampleLibraryEditor : public Panel { + + GDCLASS(SampleLibraryEditor, Panel ); + + + + SamplePlayer *player; + Ref<SampleLibrary> sample_library; + Button *load; + Tree *tree; + bool is_playing; + Object *last_sample_playing; + + EditorFileDialog *file; + + ConfirmationDialog *dialog; + + + void _load_pressed(); + void _file_load_request(const PoolVector<String>& p_path); + void _delete_pressed(); + void _update_library(); + void _item_edited(); + + UndoRedo *undo_redo; + + void _button_pressed(Object *p_item,int p_column, int p_id); + + Variant get_drag_data_fw(const Point2& p_point,Control* p_from); + bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; + void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); + +protected: + void _notification(int p_what); + void _gui_input(InputEvent p_event); + static void _bind_methods(); +public: + + void set_undo_redo(UndoRedo *p_undo_redo) {undo_redo=p_undo_redo; } + void edit(Ref<SampleLibrary> p_sample); + SampleLibraryEditor(); +}; + +class SampleLibraryEditorPlugin : public EditorPlugin { + + GDCLASS( SampleLibraryEditorPlugin, EditorPlugin ); + + SampleLibraryEditor *sample_library_editor; + EditorNode *editor; + Button *button; + +public: + + virtual String get_name() const { return "SampleLibrary"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + SampleLibraryEditorPlugin(EditorNode *p_node); + ~SampleLibraryEditorPlugin(); + +}; + +#endif +#endif // SAMPLE_LIBRARY_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/sample_player_editor_plugin.cpp b/editor/plugins/sample_player_editor_plugin.cpp index 7e2683dedf..7e2683dedf 100644 --- a/tools/editor/plugins/sample_player_editor_plugin.cpp +++ b/editor/plugins/sample_player_editor_plugin.cpp diff --git a/editor/plugins/sample_player_editor_plugin.h b/editor/plugins/sample_player_editor_plugin.h new file mode 100644 index 0000000000..c1d599540a --- /dev/null +++ b/editor/plugins/sample_player_editor_plugin.h @@ -0,0 +1,90 @@ +/*************************************************************************/ +/* sample_player_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef SAMPLE_PLAYER_EDITOR_PLUGIN_H +#define SAMPLE_PLAYER_EDITOR_PLUGIN_H + +#if 0 + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/3d/spatial_sample_player.h" +#include "scene/gui/option_button.h" +#include "scene/audio/sample_player.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +class SamplePlayerEditor : public Control { + + GDCLASS(SamplePlayerEditor, Control ); + + Panel *panel; + Button * play; + Button * stop; + OptionButton *samples; + Node *node; + + + void _update_sample_library(); + void _play(); + void _stop(); + +protected: + void _notification(int p_what); + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + void edit(Node *p_sample_player); + SamplePlayerEditor(); +}; + +class SamplePlayerEditorPlugin : public EditorPlugin { + + GDCLASS( SamplePlayerEditorPlugin, EditorPlugin ); + + SamplePlayerEditor *sample_player_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "SamplePlayer"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + SamplePlayerEditorPlugin(EditorNode *p_node); + ~SamplePlayerEditorPlugin(); + +}; + +#endif +#endif // SAMPLE_PLAYER_EDITOR_PLUGIN_H diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp new file mode 100644 index 0000000000..3631d39f9a --- /dev/null +++ b/editor/plugins/script_editor_plugin.cpp @@ -0,0 +1,2491 @@ +/*************************************************************************/ +/* script_editor_plugin.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 "script_editor_plugin.h" + +#include "editor/editor_settings.h" +#include "io/resource_loader.h" +#include "io/resource_saver.h" +#include "os/keyboard.h" +#include "os/os.h" +#include "editor/editor_node.h" +#include "editor/script_editor_debugger.h" +#include "global_config.h" +#include "os/file_access.h" +#include "scene/main/viewport.h" +#include "os/keyboard.h" +#include "os/input.h" + +/*** SCRIPT EDITOR ****/ + + + +void ScriptEditorBase::_bind_methods() { + + ADD_SIGNAL(MethodInfo("name_changed")); + ADD_SIGNAL(MethodInfo("request_help_search",PropertyInfo(Variant::STRING,"topic"))); + ADD_SIGNAL(MethodInfo("request_open_script_at_line",PropertyInfo(Variant::OBJECT,"script"),PropertyInfo(Variant::INT,"line"))); + ADD_SIGNAL(MethodInfo("request_save_history")); + ADD_SIGNAL(MethodInfo("go_to_help",PropertyInfo(Variant::STRING,"what"))); + +} + +static bool _can_open_in_editor(Script* p_script) { + + String path = p_script->get_path(); + + if (path.find("::")!=-1) { + //refuse handling this if it can't be edited + + bool valid=false; + for(int i=0;i<EditorNode::get_singleton()->get_editor_data().get_edited_scene_count();i++) { + if (path.begins_with(EditorNode::get_singleton()->get_editor_data().get_scene_path(i))) { + valid=true; + break; + } + } + + return valid; + } + + return true; +} + + +class EditorScriptCodeCompletionCache : public ScriptCodeCompletionCache { + + + struct Cache { + uint64_t time_loaded; + RES cache; + }; + + Map<String,Cache> cached; + + +public: + + uint64_t max_time_cache; + int max_cache_size; + + void cleanup() { + + List< Map<String,Cache>::Element * > to_clean; + + + Map<String,Cache>::Element *I=cached.front(); + while(I) { + if ((OS::get_singleton()->get_ticks_msec()-I->get().time_loaded)>max_time_cache) { + to_clean.push_back(I); + } + I=I->next(); + } + + while(to_clean.front()) { + cached.erase(to_clean.front()->get()); + to_clean.pop_front(); + } + } + + RES get_cached_resource(const String& p_path) { + + Map<String,Cache>::Element *E=cached.find(p_path); + if (!E) { + + Cache c; + c.cache=ResourceLoader::load(p_path); + E=cached.insert(p_path,c); + } + + E->get().time_loaded=OS::get_singleton()->get_ticks_msec(); + + if (cached.size()>max_cache_size) { + uint64_t older; + Map<String,Cache>::Element *O=cached.front(); + older=O->get().time_loaded; + Map<String,Cache>::Element *I=O; + while(I) { + if (I->get().time_loaded<older) { + older = I->get().time_loaded; + O=I; + } + I=I->next(); + } + + if (O!=E) {//should never heppane.. + cached.erase(O); + } + } + + return E->get().cache; + } + + + EditorScriptCodeCompletionCache() { + + max_cache_size=128; + max_time_cache=5*60*1000; //minutes, five + } + +}; + +#define SORT_SCRIPT_LIST + +void ScriptEditorQuickOpen::popup(const Vector<String>& p_functions, bool p_dontclear) { + + popup_centered_ratio(0.6); + if (p_dontclear) + search_box->select_all(); + else + search_box->clear(); + search_box->grab_focus(); + functions=p_functions; + _update_search(); + + +} + + +void ScriptEditorQuickOpen::_text_changed(const String& p_newtext) { + + _update_search(); +} + +void ScriptEditorQuickOpen::_sbox_input(const InputEvent& p_ie) { + + if (p_ie.type==InputEvent::KEY && ( + p_ie.key.scancode == KEY_UP || + p_ie.key.scancode == KEY_DOWN || + p_ie.key.scancode == KEY_PAGEUP || + p_ie.key.scancode == KEY_PAGEDOWN ) ) { + + search_options->call("_gui_input",p_ie); + search_box->accept_event(); + } + +} + + + +void ScriptEditorQuickOpen::_update_search() { + + + search_options->clear(); + TreeItem *root = search_options->create_item(); + + for(int i=0;i<functions.size();i++) { + + String file = functions[i]; + if ((search_box->get_text()=="" || file.findn(search_box->get_text())!=-1)) { + + TreeItem *ti = search_options->create_item(root); + ti->set_text(0,file); + if (root->get_children()==ti) + ti->select(0); + + } + } + + get_ok()->set_disabled(root->get_children()==NULL); + +} + +void ScriptEditorQuickOpen::_confirmed() { + + TreeItem *ti = search_options->get_selected(); + if (!ti) + return; + int line = ti->get_text(0).get_slice(":",1).to_int(); + + emit_signal("goto_line",line-1); + hide(); +} + +void ScriptEditorQuickOpen::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + + connect("confirmed",this,"_confirmed"); + + + } +} + + + + +void ScriptEditorQuickOpen::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_text_changed"),&ScriptEditorQuickOpen::_text_changed); + ClassDB::bind_method(D_METHOD("_confirmed"),&ScriptEditorQuickOpen::_confirmed); + ClassDB::bind_method(D_METHOD("_sbox_input"),&ScriptEditorQuickOpen::_sbox_input); + + ADD_SIGNAL(MethodInfo("goto_line",PropertyInfo(Variant::INT,"line"))); + +} + + +ScriptEditorQuickOpen::ScriptEditorQuickOpen() { + + + VBoxContainer *vbc = memnew( VBoxContainer ); + add_child(vbc); + //set_child_rect(vbc); + search_box = memnew( LineEdit ); + vbc->add_margin_child(TTR("Search:"),search_box); + search_box->connect("text_changed",this,"_text_changed"); + search_box->connect("gui_input",this,"_sbox_input"); + search_options = memnew( Tree ); + vbc->add_margin_child(TTR("Matches:"),search_options,true); + get_ok()->set_text(TTR("Open")); + get_ok()->set_disabled(true); + register_text_enter(search_box); + set_hide_on_ok(false); + search_options->connect("item_activated",this,"_confirmed"); + search_options->set_hide_root(true); +} + + +///////////////////////////////// + +ScriptEditor *ScriptEditor::script_editor=NULL; + +/*** SCRIPT EDITOR ******/ + +String ScriptEditor::_get_debug_tooltip(const String&p_text,Node *_se) { + + //ScriptEditorBase *se=_se->cast_to<ScriptEditorBase>(); + + String val = debugger->get_var_value(p_text); + if (val!=String()) { + return p_text+": "+val; + } else { + + return String(); + } +} + +void ScriptEditor::_breaked(bool p_breaked,bool p_can_debug) { + + if (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) { + return; + } + + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_NEXT), !(p_breaked && p_can_debug)); + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_STEP), !(p_breaked && p_can_debug) ); + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_BREAK), p_breaked ); + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), !p_breaked ); + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (!se) { + + continue; + } + + se->set_debugger_active(p_breaked); + } + +} + +void ScriptEditor::_show_debugger(bool p_show) { + + //debug_menu->get_popup()->set_item_checked( debug_menu->get_popup()->get_item_index(DEBUG_SHOW), p_show); +} + +void ScriptEditor::_script_created(Ref<Script> p_script) { + editor->push_item(p_script.operator->()); +} + + +void ScriptEditor::_goto_script_line2(int p_line) { + + int selected = tab_container->get_current_tab(); + if (selected<0 || selected>=tab_container->get_child_count()) + return; + + ScriptEditorBase *current = tab_container->get_child(selected)->cast_to<ScriptEditorBase>(); + if (!current) + return; + + current->goto_line(p_line); + +} + +void ScriptEditor::_goto_script_line(REF p_script,int p_line) { + + + editor->push_item(p_script.ptr()); + + int selected = tab_container->get_current_tab(); + if (selected<0 || selected>=tab_container->get_child_count()) + return; + + ScriptEditorBase *current = tab_container->get_child(selected)->cast_to<ScriptEditorBase>(); + if (!current) + return; + + current->goto_line(p_line,true); + +} + + +void ScriptEditor::_update_history_arrows() { + + script_back->set_disabled( history_pos<=0 ); + script_forward->set_disabled( history_pos>=history.size()-1 ); +} + +void ScriptEditor::_save_history() { + + + if (history_pos>=0 && history_pos<history.size() && history[history_pos].control==tab_container->get_current_tab_control()) { + + Node *n = tab_container->get_current_tab_control(); + + if (n->cast_to<ScriptEditorBase>()) { + + history[history_pos].state=n->cast_to<ScriptEditorBase>()->get_edit_state(); + } + if (n->cast_to<EditorHelp>()) { + + history[history_pos].state=n->cast_to<EditorHelp>()->get_scroll(); + } + } + + history.resize(history_pos+1); + ScriptHistory sh; + sh.control=tab_container->get_current_tab_control(); + sh.state=Variant(); + + history.push_back(sh); + history_pos++; + + _update_history_arrows(); +} + + +void ScriptEditor::_go_to_tab(int p_idx) { + + Node *cn = tab_container->get_child(p_idx); + if (!cn) + return; + Control *c = cn->cast_to<Control>(); + if (!c) + return; + + if (history_pos>=0 && history_pos<history.size() && history[history_pos].control==tab_container->get_current_tab_control()) { + + Node *n = tab_container->get_current_tab_control(); + + if (n->cast_to<ScriptEditorBase>()) { + + history[history_pos].state=n->cast_to<ScriptEditorBase>()->get_edit_state(); + } + if (n->cast_to<EditorHelp>()) { + + history[history_pos].state=n->cast_to<EditorHelp>()->get_scroll(); + } + } + + history.resize(history_pos+1); + ScriptHistory sh; + sh.control=c; + sh.state=Variant(); + + history.push_back(sh); + history_pos++; + + + tab_container->set_current_tab(p_idx); + + c = tab_container->get_current_tab_control(); + + if (c->cast_to<ScriptEditorBase>()) { + + script_name_label->set_text(c->cast_to<ScriptEditorBase>()->get_name()); + script_icon->set_texture(c->cast_to<ScriptEditorBase>()->get_icon()); + if (is_visible_in_tree()) + c->cast_to<ScriptEditorBase>()->ensure_focus(); + } + if (c->cast_to<EditorHelp>()) { + + script_name_label->set_text(c->cast_to<EditorHelp>()->get_class()); + script_icon->set_texture(get_icon("Help","EditorIcons")); + if (is_visible_in_tree()) + c->cast_to<EditorHelp>()->set_focused(); + } + + + + c->set_meta("__editor_pass",++edit_pass); + _update_history_arrows(); + _update_script_colors(); + _update_selected_editor_menu(); +} + +void ScriptEditor::_close_tab(int p_idx, bool p_save) { + + int selected = p_idx; + if (selected<0 || selected>=tab_container->get_child_count()) + return; + + Node *tselected = tab_container->get_child(selected); + ScriptEditorBase *current = tab_container->get_child(selected)->cast_to<ScriptEditorBase>(); + if (current) { + if (p_save) { + apply_scripts(); + } + if (current->get_edit_menu()) { + memdelete(current->get_edit_menu()); + } + } + + //remove from history + history.resize(history_pos+1); + + for(int i=0;i<history.size();i++) { + if (history[i].control==tselected) { + history.remove(i); + i--; + history_pos--; + } + } + + if (history_pos>=history.size()) { + history_pos=history.size()-1; + } + + int idx = tab_container->get_current_tab(); + memdelete(tselected); + if (idx>=tab_container->get_child_count()) + idx=tab_container->get_child_count()-1; + if (idx>=0) { + + if (history_pos>=0) { + idx = history[history_pos].control->get_index(); + } + tab_container->set_current_tab(idx); + + //script_list->select(idx); + } + + + _update_history_arrows(); + + + + _update_script_names(); + _save_layout(); +} + +void ScriptEditor::_close_current_tab() { + + _close_tab(tab_container->get_current_tab()); + +} + +void ScriptEditor::_close_discard_current_tab(const String& p_str) { + _close_tab(tab_container->get_current_tab(), false); + erase_tab_confirm->hide(); +} + +void ScriptEditor::_close_docs_tab() { + + int child_count = tab_container->get_child_count(); + for (int i = child_count-1; i>=0; i--) { + + EditorHelp *se = tab_container->get_child(i)->cast_to<EditorHelp>(); + + if (se) { + _close_tab(i); + } + + } + +} + +void ScriptEditor::_close_all_tabs() { + + int child_count = tab_container->get_child_count(); + for (int i = child_count-1; i>=0; i--) { + + tab_container->set_current_tab(i); + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + + if (se) { + + // Maybe there are unsaved changes + if (se->is_unsaved()) { + _ask_close_current_unsaved_tab(se); + continue; + } + + } + + _close_current_tab(); + } + +} + +void ScriptEditor::_ask_close_current_unsaved_tab(ScriptEditorBase *current) { + erase_tab_confirm->set_text("Close and save changes?\n\""+current->get_name()+"\""); + erase_tab_confirm->popup_centered_minsize(); +} + + +void ScriptEditor::_resave_scripts(const String& p_str) { + + apply_scripts(); + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (!se) + continue; + + + Ref<Script> script = se->get_edited_script(); + + if (script->get_path()=="" || script->get_path().find("local://")!=-1 || script->get_path().find("::")!=-1) + continue; //internal script, who cares + + if (trim_trailing_whitespace_on_save) { + se->trim_trailing_whitespace(); + } + editor->save_resource(script); + se->tag_saved_version(); + } + + disk_changed->hide(); + +} + +void ScriptEditor::_reload_scripts(){ + + + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (!se) { + + continue; + } + + + Ref<Script> script = se->get_edited_script(); + + if (script->get_path()=="" || script->get_path().find("local://")!=-1 || script->get_path().find("::")!=-1) { + + continue; //internal script, who cares + } + + + uint64_t last_date = script->get_last_modified_time(); + uint64_t date = FileAccess::get_modified_time(script->get_path()); + + //printf("last date: %lli vs date: %lli\n",last_date,date); + if (last_date==date) { + continue; + } + + + Ref<Script> rel_script = ResourceLoader::load(script->get_path(),script->get_class(),true); + ERR_CONTINUE(!rel_script.is_valid()); + script->set_source_code( rel_script->get_source_code() ); + script->set_last_modified_time( rel_script->get_last_modified_time() ); + script->reload(); + se->reload_text(); + + + } + + disk_changed->hide(); + _update_script_names(); + +} + + + +void ScriptEditor::_res_saved_callback(const Ref<Resource>& p_res) { + + + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (!se) { + + continue; + } + + + Ref<Script> script = se->get_edited_script(); + + if (script->get_path()=="" || script->get_path().find("local://")!=-1 || script->get_path().find("::")!=-1) { + continue; //internal script, who cares + } + + if (script==p_res) { + + se->tag_saved_version(); + } + + } + + _update_script_names(); + + + if (!pending_auto_reload && auto_reload_running_scripts) { + call_deferred("_live_auto_reload_running_scripts"); + pending_auto_reload=true; + } +} + +void ScriptEditor::_live_auto_reload_running_scripts() { + pending_auto_reload=false; + debugger->reload_scripts(); +} + + +bool ScriptEditor::_test_script_times_on_disk(Ref<Script> p_for_script) { + + + disk_changed_list->clear(); + TreeItem *r = disk_changed_list->create_item(); + disk_changed_list->set_hide_root(true); + + bool need_ask=false; + bool need_reload=false; + bool use_autoreload=bool(EDITOR_DEF("text_editor/files/auto_reload_scripts_on_external_change",false)); + + + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (se) { + + Ref<Script> script = se->get_edited_script(); + + if (p_for_script.is_valid() && p_for_script!=script) + continue; + + if (script->get_path()=="" || script->get_path().find("local://")!=-1 || script->get_path().find("::")!=-1) + continue; //internal script, who cares + + + uint64_t last_date = script->get_last_modified_time(); + uint64_t date = FileAccess::get_modified_time(script->get_path()); + + //printf("last date: %lli vs date: %lli\n",last_date,date); + if (last_date!=date) { + + TreeItem *ti = disk_changed_list->create_item(r); + ti->set_text(0,script->get_path().get_file()); + + if (!use_autoreload || se->is_unsaved()) { + need_ask=true; + } + need_reload=true; + //r->set_metadata(0,); + } + } + } + + + + if (need_reload) { + if (!need_ask) { + script_editor->_reload_scripts(); + need_reload=false; + } else { + disk_changed->call_deferred("popup_centered_ratio",0.5); + } + } + + return need_reload; +} + + +void ScriptEditor::_file_dialog_action(String p_file) { + + switch (file_dialog_option) { + case FILE_SAVE_THEME_AS: { + if(!EditorSettings::get_singleton()->save_text_editor_theme_as(p_file)) { + editor->show_warning(TTR("Error while saving theme"), TTR("Error saving")); + } + } break; + case FILE_IMPORT_THEME: { + if(!EditorSettings::get_singleton()->import_text_editor_theme(p_file)) { + editor->show_warning(TTR("Error importing theme"), TTR("Error importing")); + } + } break; + } + file_dialog_option = -1; +} + +void ScriptEditor::_menu_option(int p_option) { + + + switch(p_option) { + case FILE_NEW: { + script_create_dialog->config("Node", ".gd"); + script_create_dialog->popup_centered(Size2(300, 300)*EDSCALE); + } break; + case FILE_OPEN: { + + editor->open_resource("Script"); + return; + } break; + case FILE_SAVE_ALL: { + + if (_test_script_times_on_disk()) + return; + + save_all_scripts(); + } break; + case FILE_IMPORT_THEME: { + file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE); + file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + file_dialog_option = FILE_IMPORT_THEME; + file_dialog->clear_filters(); + file_dialog->add_filter("*.tet"); + file_dialog->popup_centered_ratio(); + file_dialog->set_title(TTR("Import Theme")); + } break; + case FILE_RELOAD_THEME: { + EditorSettings::get_singleton()->load_text_editor_theme(); + } break; + case FILE_SAVE_THEME: { + if(!EditorSettings::get_singleton()->save_text_editor_theme()) { + editor->show_warning(TTR("Error while saving theme"), TTR("Error saving")); + } + } break; + case FILE_SAVE_THEME_AS: { + file_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE); + file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + file_dialog_option = FILE_SAVE_THEME_AS; + file_dialog->clear_filters(); + file_dialog->add_filter("*.tet"); + file_dialog->set_current_path(EditorSettings::get_singleton()->get_settings_path() + "/text_editor_themes/" + EditorSettings::get_singleton()->get("text_editor/theme/color_theme")); + file_dialog->popup_centered_ratio(); + file_dialog->set_title(TTR("Save Theme As..")); + } break; + case SEARCH_HELP: { + + help_search_dialog->popup(); + } break; + case SEARCH_CLASSES: { + + String current; + + if (tab_container->get_tab_count()>0) { + EditorHelp *eh = tab_container->get_child( tab_container->get_current_tab() )->cast_to<EditorHelp>(); + if (eh) { + current=eh->get_class(); + } + } + + help_index->popup(); + + if (current!="") { + help_index->call_deferred("select_class",current); + } + } break; + case SEARCH_WEBSITE: { + + OS::get_singleton()->shell_open("http://docs.godotengine.org/"); + } break; + + case WINDOW_NEXT: { + + _history_forward(); + } break; + case WINDOW_PREV: { + _history_back(); + } break; + case DEBUG_SHOW: { + if (debugger) { + bool visible = debug_menu->get_popup()->is_item_checked( debug_menu->get_popup()->get_item_index(DEBUG_SHOW) ); + debug_menu->get_popup()->set_item_checked( debug_menu->get_popup()->get_item_index(DEBUG_SHOW), !visible); + if (visible) + debugger->hide(); + else + debugger->show(); + } + } break; + case DEBUG_SHOW_KEEP_OPEN: { + bool visible = debug_menu->get_popup()->is_item_checked( debug_menu->get_popup()->get_item_index(DEBUG_SHOW_KEEP_OPEN) ); + if (debugger) + debugger->set_hide_on_stop(visible); + debug_menu->get_popup()->set_item_checked( debug_menu->get_popup()->get_item_index(DEBUG_SHOW_KEEP_OPEN), !visible); + } break; + } + + + int selected = tab_container->get_current_tab(); + if (selected<0 || selected>=tab_container->get_child_count()) + return; + + ScriptEditorBase *current = tab_container->get_child(selected)->cast_to<ScriptEditorBase>(); + if (current) { + + switch(p_option) { + case FILE_NEW: { + script_create_dialog->config("Node", ".gd"); + script_create_dialog->popup_centered(Size2(300, 300)*EDSCALE); + } break; + case FILE_SAVE: { + + if (_test_script_times_on_disk()) + return; + + if (trim_trailing_whitespace_on_save) + current->trim_trailing_whitespace(); + editor->save_resource( current->get_edited_script() ); + + } break; + case FILE_SAVE_AS: { + + current->trim_trailing_whitespace(); + editor->push_item(current->get_edited_script()->cast_to<Object>()); + editor->save_resource_as( current->get_edited_script() ); + + } break; + + case FILE_TOOL_RELOAD: + case FILE_TOOL_RELOAD_SOFT: { + + current->reload(p_option==FILE_TOOL_RELOAD_SOFT); + + } break; + + case FILE_CLOSE: { + if (current->is_unsaved()) { + _ask_close_current_unsaved_tab(current); + } else { + _close_current_tab(); + } + } break; + case CLOSE_DOCS: { + _close_docs_tab(); + } break; + case CLOSE_ALL: { + _close_all_tabs(); + } break; + case DEBUG_NEXT: { + + if (debugger) + debugger->debug_next(); + } break; + case DEBUG_STEP: { + + if (debugger) + debugger->debug_step(); + + } break; + case DEBUG_BREAK: { + + if (debugger) + debugger->debug_break(); + + } break; + case DEBUG_CONTINUE: { + + if (debugger) + debugger->debug_continue(); + + } break; + case WINDOW_MOVE_LEFT: { + + if (tab_container->get_current_tab()>0) { + tab_container->call_deferred("set_current_tab",tab_container->get_current_tab()-1); + script_list->call_deferred("select",tab_container->get_current_tab()-1); + tab_container->move_child(current,tab_container->get_current_tab()-1); + _update_script_names(); + } + } break; + case WINDOW_MOVE_RIGHT: { + + if (tab_container->get_current_tab()<tab_container->get_child_count()-1) { + tab_container->call_deferred("set_current_tab",tab_container->get_current_tab()+1); + script_list->call_deferred("select",tab_container->get_current_tab()+1); + tab_container->move_child(current,tab_container->get_current_tab()+1); + _update_script_names(); + } + + + } break; + + default: { + + if (p_option>=WINDOW_SELECT_BASE) { + + tab_container->set_current_tab(p_option-WINDOW_SELECT_BASE); + script_list->select(p_option-WINDOW_SELECT_BASE); + + } + } + } + } + + EditorHelp *help = tab_container->get_current_tab_control()->cast_to<EditorHelp>(); + if (help) { + + switch(p_option) { + + case HELP_SEARCH_FIND: { + help->popup_search(); + } break; + case HELP_SEARCH_FIND_NEXT: { + help->search_again(); + } break; + case FILE_CLOSE: { + _close_current_tab(); + } break; + case CLOSE_DOCS: { + _close_docs_tab(); + } break; + case CLOSE_ALL: { + _close_all_tabs(); + } break; + + + } + } + + +} + +void ScriptEditor::_tab_changed(int p_which) { + + ensure_select_current(); +} + +void ScriptEditor::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + + editor->connect("play_pressed",this,"_editor_play"); + editor->connect("pause_pressed",this,"_editor_pause"); + editor->connect("stop_pressed",this,"_editor_stop"); + editor->connect("script_add_function_request",this,"_add_callback"); + editor->connect("resource_saved",this,"_res_saved_callback"); + script_list->connect("item_selected",this,"_script_selected"); + script_split->connect("dragged",this,"_script_split_dragged"); + autosave_timer->connect("timeout",this,"_autosave_scripts"); + { + float autosave_time = EditorSettings::get_singleton()->get("text_editor/files/autosave_interval_secs"); + if (autosave_time>0) { + autosave_timer->set_wait_time(autosave_time); + autosave_timer->start(); + } else { + autosave_timer->stop(); + } + } + + EditorSettings::get_singleton()->connect("settings_changed",this,"_editor_settings_changed"); + help_search->set_icon(get_icon("Help","EditorIcons")); + site_search->set_icon(get_icon("Godot","EditorIcons")); + class_search->set_icon(get_icon("ClassList","EditorIcons")); + + script_forward->set_icon(get_icon("Forward","EditorIcons")); + script_back->set_icon(get_icon("Back","EditorIcons")); + + + + + } + + if (p_what==NOTIFICATION_READY) { + + get_tree()->connect("tree_changed",this,"_tree_changed"); + editor->connect("request_help",this,"_request_help"); + } + + if (p_what==NOTIFICATION_EXIT_TREE) { + + editor->disconnect("play_pressed",this,"_editor_play"); + editor->disconnect("pause_pressed",this,"_editor_pause"); + editor->disconnect("stop_pressed",this,"_editor_stop"); + + } + + if (p_what==MainLoop::NOTIFICATION_WM_FOCUS_IN) { + + _test_script_times_on_disk(); + _update_modified_scripts_for_external_editor(); + } + + if (p_what==NOTIFICATION_PROCESS) { + + } + +} + +bool ScriptEditor::can_take_away_focus() const { + + int selected = tab_container->get_current_tab(); + if (selected<0 || selected>=tab_container->get_child_count()) + return true; + + ScriptEditorBase *current = tab_container->get_child(selected)->cast_to<ScriptEditorBase>(); + if (!current) + return true; + + + return current->can_lose_focus_on_node_selection(); + +} + +void ScriptEditor::close_builtin_scripts_from_scene(const String& p_scene) { + + + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + + if (se) { + + Ref<Script> script = se->get_edited_script(); + if (!script.is_valid()) + continue; + + if (script->get_path().find("::")!=-1 && script->get_path().begins_with(p_scene)) { //is an internal script and belongs to scene being closed + _close_tab(i); + i--; + + } + } + + } + + +} + +void ScriptEditor::edited_scene_changed() { + + _update_modified_scripts_for_external_editor(); + +} + +static const Node * _find_node_with_script(const Node* p_node, const RefPtr & p_script) { + + if (p_node->get_script()==p_script) + return p_node; + + for(int i=0;i<p_node->get_child_count();i++) { + + const Node *result = _find_node_with_script(p_node->get_child(i),p_script); + if (result) + return result; + } + + return NULL; +} + +Dictionary ScriptEditor::get_state() const { + + + //apply_scripts(); + + Dictionary state; +#if 0 + Array paths; + int open=-1; + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptTextEditor *se = tab_container->get_child(i)->cast_to<ScriptTextEditor>(); + if (!se) + continue; + + + Ref<Script> script = se->get_edited_script(); + if (script->get_path()!="" && script->get_path().find("local://")==-1 && script->get_path().find("::")==-1) { + + paths.push_back(script->get_path()); + } else { + + + const Node *owner = _find_node_with_script(get_tree()->get_root(),script.get_ref_ptr()); + if (owner) + paths.push_back(owner->get_path()); + + } + + if (i==tab_container->get_current_tab()) + open=i; + } + + if (paths.size()) + state["sources"]=paths; + if (open!=-1) + state["current"]=open; + +#endif + return state; +} +void ScriptEditor::set_state(const Dictionary& p_state) { + +#if 0 + print_line("attempt set state: "+String(Variant(p_state))); + + if (!p_state.has("sources")) + return; //bleh + + Array sources = p_state["sources"]; + for(int i=0;i<sources.size();i++) { + + Variant source=sources[i]; + + Ref<Script> script; + + if (source.get_type()==Variant::NODE_PATH) { + + + Node *owner=get_tree()->get_root()->get_node(source); + if (!owner) + continue; + + script = owner->get_script(); + } else if (source.get_type()==Variant::STRING) { + + + script = ResourceLoader::load(source,"Script"); + } + + + if (script.is_null()) //ah well.. + continue; + + editor->call("_resource_selected",script); + } + + if (p_state.has("current")) { + tab_container->set_current_tab(p_state["current"]); + } +#endif + +} +void ScriptEditor::clear() { +#if 0 + List<ScriptTextEditor*> stes; + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptTextEditor *se = tab_container->get_child(i)->cast_to<ScriptTextEditor>(); + if (!se) + continue; + stes.push_back(se); + + } + + while(stes.size()) { + + memdelete(stes.front()->get()); + stes.pop_front(); + } + + int idx = tab_container->get_current_tab(); + if (idx>=tab_container->get_child_count()) + idx=tab_container->get_child_count()-1; + if (idx>=0) { + tab_container->set_current_tab(idx); + script_list->select( script_list->find_metadata(idx) ); + } + +#endif + + +} + + +void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) { + + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (!se) + continue; + + List<int> bpoints; + se->get_breakpoints(&bpoints); + Ref<Script> script = se->get_edited_script(); + String base = script->get_path(); + ERR_CONTINUE( base.begins_with("local://") || base=="" ); + + for(List<int>::Element *E=bpoints.front();E;E=E->next()) { + + p_breakpoints->push_back(base+":"+itos(E->get()+1)); + } + } + +} + + + + + +void ScriptEditor::ensure_focus_current() { + + if (!is_inside_tree()) + return; + + int cidx = tab_container->get_current_tab(); + if (cidx<0 || cidx>=tab_container->get_tab_count()); + Control *c = tab_container->get_child(cidx)->cast_to<Control>(); + if (!c) + return; + ScriptEditorBase *se = c->cast_to<ScriptEditorBase>(); + if (!se) + return; + se->ensure_focus(); +} + +void ScriptEditor::_script_selected(int p_idx) { + + grab_focus_block = !Input::get_singleton()->is_mouse_button_pressed(1); //amazing hack, simply amazing + + _go_to_tab(script_list->get_item_metadata(p_idx)); + grab_focus_block=false; +} + +void ScriptEditor::ensure_select_current() { + + + if (tab_container->get_child_count() && tab_container->get_current_tab()>=0) { + + Node *current = tab_container->get_child(tab_container->get_current_tab()); + + + ScriptEditorBase *se = current->cast_to<ScriptEditorBase>(); + if (se) { + + Ref<Script> script = se->get_edited_script(); + + if (!grab_focus_block && is_visible_in_tree()) + se->ensure_focus(); + + + //edit_menu->show(); + //search_menu->show(); + + + } + + EditorHelp *eh = current->cast_to<EditorHelp>(); + + if (eh) { + //edit_menu->hide(); + //search_menu->hide(); + //script_search_menu->show(); + + } + } + + _update_selected_editor_menu(); + + + +} + +void ScriptEditor::_find_scripts(Node* p_base, Node* p_current, Set<Ref<Script> > &used) { + if (p_current!=p_base && p_current->get_owner()!=p_base) + return; + + if (p_current->get_script_instance()) { + Ref<Script> scr = p_current->get_script(); + if (scr.is_valid()) + used.insert(scr); + } + + for(int i=0;i<p_current->get_child_count();i++) { + _find_scripts(p_base,p_current->get_child(i),used); + } + +} + +struct _ScriptEditorItemData { + + String name; + String sort_key; + Ref<Texture> icon; + int index; + String tooltip; + bool used; + int category; + + + bool operator<(const _ScriptEditorItemData& id) const { + + return category==id.category?sort_key<id.sort_key:category<id.category; + } + +}; + + +void ScriptEditor::_update_script_colors() { + + bool script_temperature_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_enabled"); + bool highlight_current = EditorSettings::get_singleton()->get("text_editor/open_scripts/highlight_current_script"); + + int hist_size = EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_history_size"); + Color hot_color=EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_hot_color"); + Color cold_color=EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_cold_color"); + + for(int i=0;i<script_list->get_item_count();i++) { + + int c = script_list->get_item_metadata(i); + Node *n = tab_container->get_child(c); + if (!n) + continue; + + script_list->set_item_custom_bg_color(i,Color(0,0,0,0)); + + bool current = tab_container->get_current_tab() == c; + if (current && highlight_current) { + script_list->set_item_custom_bg_color(i, EditorSettings::get_singleton()->get("text_editor/open_scripts/current_script_background_color")); + + } else if (script_temperature_enabled) { + + if (!n->has_meta("__editor_pass")) { + continue; + } + + int pass=n->get_meta("__editor_pass"); + int h = edit_pass - pass; + if (h>hist_size) { + continue; + } + int non_zero_hist_size = ( hist_size == 0 ) ? 1 : hist_size; + float v = Math::ease((edit_pass-pass)/float(non_zero_hist_size),0.4); + + script_list->set_item_custom_bg_color(i,hot_color.linear_interpolate(cold_color,v)); + } + } +} + +void ScriptEditor::_update_script_names() { + + if (restoring_layout) + return; + + waiting_update_names=false; + Set<Ref<Script> > used; + Node* edited = EditorNode::get_singleton()->get_edited_scene(); + if (edited) { + _find_scripts(edited,edited,used); + } + + script_list->clear(); + bool split_script_help = EditorSettings::get_singleton()->get("text_editor/open_scripts/group_help_pages"); + ScriptSortBy sort_by = (ScriptSortBy) (int) EditorSettings::get_singleton()->get("text_editor/open_scripts/sort_scripts_by"); + ScriptListName display_as = (ScriptListName) (int) EditorSettings::get_singleton()->get("text_editor/open_scripts/list_script_names_as"); + + Vector<_ScriptEditorItemData> sedata; + + for(int i=0;i<tab_container->get_child_count();i++) { + + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (se) { + + String name = se->get_name(); + Ref<Texture> icon = se->get_icon(); + String path = se->get_edited_script()->get_path(); + + _ScriptEditorItemData sd; + sd.icon=icon; + sd.name=name; + sd.tooltip=path; + sd.index=i; + sd.used=used.has(se->get_edited_script()); + sd.category=0; + + switch (sort_by) { + case SORT_BY_NAME: { + sd.sort_key=name.to_lower(); + } break; + case SORT_BY_PATH: { + sd.sort_key=path; + } break; + } + + switch (display_as) { + case DISPLAY_NAME: { + sd.name=name; + } break; + case DISPLAY_DIR_AND_NAME: { + if (!path.get_base_dir().get_file().empty()) { + sd.name=path.get_base_dir().get_file() + "/" + name; + } else { + sd.name=name; + } + } break; + case DISPLAY_FULL_PATH: { + sd.name=path; + } break; + } + + + sedata.push_back(sd); + } + + EditorHelp *eh = tab_container->get_child(i)->cast_to<EditorHelp>(); + if (eh) { + + String name = eh->get_class(); + Ref<Texture> icon = get_icon("Help","EditorIcons"); + String tooltip = name+" Class Reference"; + + _ScriptEditorItemData sd; + sd.icon=icon; + sd.name=name; + sd.sort_key=name; + sd.tooltip=tooltip; + sd.index=i; + sd.used=false; + sd.category=split_script_help?1:0; + sedata.push_back(sd); + + } + + } + + sedata.sort(); + + for(int i=0;i<sedata.size();i++) { + + script_list->add_item(sedata[i].name,sedata[i].icon); + int index = script_list->get_item_count()-1; + script_list->set_item_tooltip(index,sedata[i].tooltip); + script_list->set_item_metadata(index,sedata[i].index); + if (sedata[i].used) { + + script_list->set_item_custom_bg_color(index,Color(88/255.0,88/255.0,60/255.0)); + } + if (tab_container->get_current_tab()==sedata[i].index) { + script_list->select(index); + script_name_label->set_text(sedata[i].name); + script_icon->set_texture(sedata[i].icon); + + } + } + + _update_script_colors(); + + + + +} + + + +void ScriptEditor::edit(const Ref<Script>& p_script, bool p_grab_focus) { + + if (p_script.is_null()) + return; + + // refuse to open built-in if scene is not loaded + + + + + // see if already has it + + bool open_dominant = EditorSettings::get_singleton()->get("text_editor/files/open_dominant_script_on_scene_change"); + + if (p_script->get_path().is_resource_file() && bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) { + + String path = EditorSettings::get_singleton()->get("text_editor/external/exec_path"); + String flags = EditorSettings::get_singleton()->get("text_editor/external/exec_flags"); + List<String> args; + flags=flags.strip_edges(); + if (flags!=String()) { + Vector<String> flagss = flags.split(" ",false); + for(int i=0;i<flagss.size();i++) + args.push_back(flagss[i]); + } + + args.push_back(GlobalConfig::get_singleton()->globalize_path(p_script->get_path())); + Error err = OS::get_singleton()->execute(path,args,false); + if (err==OK) + return; + WARN_PRINT("Couldn't open external text editor, using internal"); + } + + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (!se) + continue; + + if (se->get_edited_script()==p_script) { + + if (open_dominant || !EditorNode::get_singleton()->is_changing_scene()) { + if (tab_container->get_current_tab()!=i) { + _go_to_tab(i); + script_list->select( script_list->find_metadata(i) ); + } + if (is_visible_in_tree()) + se->ensure_focus(); + } + return; + } + } + + // doesn't have it, make a new one + + ScriptEditorBase *se; + + for(int i=script_editor_func_count-1;i>=0;i--) { + se = script_editor_funcs[i](p_script); + if (se) + break; + } + ERR_FAIL_COND(!se); + tab_container->add_child(se); + + se->set_edited_script(p_script); + se->set_tooltip_request_func("_get_debug_tooltip",this); + if (se->get_edit_menu()) { + se->get_edit_menu()->hide(); + menu_hb->add_child(se->get_edit_menu()); + menu_hb->move_child(se->get_edit_menu(),1); + } + + + if (p_grab_focus) { + _go_to_tab(tab_container->get_tab_count()-1); + } + + + + + + _update_script_names(); + _save_layout(); + se->connect("name_changed",this,"_update_script_names"); + se->connect("request_help_search",this,"_help_search"); + se->connect("request_open_script_at_line",this,"_goto_script_line"); + se->connect("go_to_help",this,"_help_class_goto"); + se->connect("request_save_history",this,"_save_history"); + + + + + //test for modification, maybe the script was not edited but was loaded + + _test_script_times_on_disk(p_script); + _update_modified_scripts_for_external_editor(p_script); + +} + +void ScriptEditor::save_all_scripts() { + + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (!se) + continue; + + + if (!se->is_unsaved()) + continue; + + if (trim_trailing_whitespace_on_save) { + se->trim_trailing_whitespace(); + } + + Ref<Script> script = se->get_edited_script(); + if (script.is_valid()) + se->apply_code(); + + if (script->get_path()!="" && script->get_path().find("local://")==-1 &&script->get_path().find("::")==-1) { + //external script, save it + + editor->save_resource(script); + //ResourceSaver::save(script->get_path(),script); + + } + + } + + _update_script_names(); + +} + +void ScriptEditor::apply_scripts() const { + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (!se) + continue; + se->apply_code(); + } + +} + +void ScriptEditor::_editor_play() { + + debugger->start(); + debug_menu->get_popup()->grab_focus(); + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_NEXT), true ); + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_STEP), true ); + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_BREAK), false ); + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true ); + + //debugger_gui->start_listening(Globals::get_singleton()->get("debug/debug_port")); +} + +void ScriptEditor::_editor_pause() { + + +} +void ScriptEditor::_editor_stop() { + + debugger->stop(); + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_NEXT), true ); + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_STEP), true ); + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_BREAK), true ); + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true ); + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (!se) { + + continue; + } + + se->set_debugger_active(false); + } +} + + +void ScriptEditor::_add_callback(Object *p_obj, const String& p_function, const PoolStringArray& p_args) { + + //print_line("add callback! hohoho"); kinda sad to remove this + ERR_FAIL_COND(!p_obj); + Ref<Script> script = p_obj->get_script(); + ERR_FAIL_COND( !script.is_valid() ); + + editor->push_item(script.ptr()); + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (!se) + continue; + if (se->get_edited_script()!=script) + continue; + + se->add_callback(p_function,p_args); + + _go_to_tab(i); + + script_list->select( script_list->find_metadata(i) ); + + break; + + } + +} + +void ScriptEditor::_save_layout() { + + if (restoring_layout) { + return; + } + + editor->save_layout(); +} + +void ScriptEditor::_editor_settings_changed() { + + trim_trailing_whitespace_on_save = EditorSettings::get_singleton()->get("text_editor/files/trim_trailing_whitespace_on_save"); + float autosave_time = EditorSettings::get_singleton()->get("text_editor/files/autosave_interval_secs"); + if (autosave_time>0) { + autosave_timer->set_wait_time(autosave_time); + autosave_timer->start(); + } else { + autosave_timer->stop(); + } + + if (current_theme == "") { + current_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme"); + } else if (current_theme != EditorSettings::get_singleton()->get("text_editor/theme/color_theme")) { + current_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme"); + EditorSettings::get_singleton()->load_text_editor_theme(); + } + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (!se) + continue; + + se->update_settings(); + } + _update_script_colors(); + _update_script_names(); + + ScriptServer::set_reload_scripts_on_save(EDITOR_DEF("text_editor/files/auto_reload_and_parse_scripts_on_save",true)); + +} + +void ScriptEditor::_autosave_scripts() { + + save_all_scripts(); +} + +void ScriptEditor::_tree_changed() { + + if (waiting_update_names) + return; + + waiting_update_names=true; + call_deferred("_update_script_names"); +} + +void ScriptEditor::_script_split_dragged(float) { + + _save_layout(); +} + +void ScriptEditor::_unhandled_input(const InputEvent& p_event) { + if (p_event.key.pressed || !is_visible_in_tree()) return; + if (ED_IS_SHORTCUT("script_editor/next_script", p_event)) { + int next_tab = script_list->get_current() + 1; + next_tab %= script_list->get_item_count(); + _go_to_tab(script_list->get_item_metadata(next_tab)); + _update_script_names(); + } + if (ED_IS_SHORTCUT("script_editor/prev_script", p_event)) { + int next_tab = script_list->get_current() - 1; + next_tab = next_tab >= 0 ? next_tab : script_list->get_item_count() - 1; + _go_to_tab(script_list->get_item_metadata(next_tab)); + _update_script_names(); + } +} + +void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) { + + if (!bool(EDITOR_DEF("text_editor/files/restore_scripts_on_load",true))) { + return; + } + + if (!p_layout->has_section_key("ScriptEditor","open_scripts") && !p_layout->has_section_key("ScriptEditor","open_help")) + return; + + Array scripts = p_layout->get_value("ScriptEditor","open_scripts"); + Array helps; + if (p_layout->has_section_key("ScriptEditor","open_help")) + helps=p_layout->get_value("ScriptEditor","open_help"); + + restoring_layout=true; + + for(int i=0;i<scripts.size();i++) { + + String path = scripts[i]; + if (!FileAccess::exists(path)) + continue; + Ref<Script> scr = ResourceLoader::load(path); + if (scr.is_valid()) { + edit(scr); + } + } + + for(int i=0;i<helps.size();i++) { + + String path = helps[i]; + _help_class_open(path); + } + + for(int i=0;i<tab_container->get_child_count();i++) { + tab_container->get_child(i)->set_meta("__editor_pass",Variant()); + } + + + if (p_layout->has_section_key("ScriptEditor","split_offset")) { + script_split->set_split_offset(p_layout->get_value("ScriptEditor","split_offset")); + } + + restoring_layout=false; + + _update_script_names(); +} + +void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) { + + Array scripts; + Array helps; + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (se) { + + String path = se->get_edited_script()->get_path(); + if (!path.is_resource_file()) + continue; + + scripts.push_back(path); + } + + EditorHelp *eh = tab_container->get_child(i)->cast_to<EditorHelp>(); + + if (eh) { + + helps.push_back(eh->get_class()); + } + + + } + + p_layout->set_value("ScriptEditor","open_scripts",scripts); + p_layout->set_value("ScriptEditor","open_help",helps); + p_layout->set_value("ScriptEditor","split_offset",script_split->get_split_offset()); +} + + +void ScriptEditor::_help_class_open(const String& p_class) { + + if (p_class=="") + return; + + for(int i=0;i<tab_container->get_child_count();i++) { + + EditorHelp *eh = tab_container->get_child(i)->cast_to<EditorHelp>(); + + if (eh && eh->get_class()==p_class) { + + _go_to_tab(i); + _update_script_names(); + return; + } + } + + EditorHelp * eh = memnew( EditorHelp ); + + + eh->set_name(p_class); + tab_container->add_child(eh); + _go_to_tab(tab_container->get_tab_count()-1); + eh->go_to_class(p_class,0); + eh->connect("go_to_help",this,"_help_class_goto"); + _update_script_names(); + _save_layout(); +} + +void ScriptEditor::_help_class_goto(const String& p_desc) { + + String cname=p_desc.get_slice(":",1); + + for(int i=0;i<tab_container->get_child_count();i++) { + + EditorHelp *eh = tab_container->get_child(i)->cast_to<EditorHelp>(); + + if (eh && eh->get_class()==cname) { + + _go_to_tab(i); + eh->go_to_help(p_desc); + _update_script_names(); + return; + } + } + + EditorHelp * eh = memnew( EditorHelp ); + + eh->set_name(cname); + tab_container->add_child(eh); + _go_to_tab(tab_container->get_tab_count()-1); + eh->go_to_help(p_desc); + eh->connect("go_to_help",this,"_help_class_goto"); + _update_script_names(); + _save_layout(); +} + +void ScriptEditor::_update_selected_editor_menu() { + + for(int i=0;i<tab_container->get_child_count();i++) { + + bool current = tab_container->get_current_tab() == i; + + ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + if (se && se->get_edit_menu()) { + + if (current) + se->get_edit_menu()->show(); + else + se->get_edit_menu()->hide(); + } + + } + + EditorHelp *eh=tab_container->get_current_tab_control()->cast_to<EditorHelp>(); + if (eh) { + script_search_menu->show(); + } else { + script_search_menu->hide(); + } +} + +void ScriptEditor::_update_history_pos(int p_new_pos) { + + Node *n = tab_container->get_current_tab_control(); + + if (n->cast_to<ScriptEditorBase>()) { + + history[history_pos].state=n->cast_to<ScriptEditorBase>()->get_edit_state(); + } + if (n->cast_to<EditorHelp>()) { + + history[history_pos].state=n->cast_to<EditorHelp>()->get_scroll(); + } + + history_pos=p_new_pos; + tab_container->set_current_tab(history[history_pos].control->get_index()); + + n = history[history_pos].control; + + if (n->cast_to<ScriptEditorBase>()) { + + n->cast_to<ScriptEditorBase>()->set_edit_state(history[history_pos].state); + n->cast_to<ScriptEditorBase>()->ensure_focus(); + } + + if (n->cast_to<EditorHelp>()) { + + n->cast_to<EditorHelp>()->set_scroll(history[history_pos].state); + n->cast_to<EditorHelp>()->set_focused(); + } + + n->set_meta("__editor_pass",++edit_pass); + _update_script_names(); + _update_history_arrows(); + _update_selected_editor_menu(); + +} + +void ScriptEditor::_history_forward() { + + if (history_pos<history.size()-1) { + _update_history_pos(history_pos+1); + } +} + +void ScriptEditor::_history_back(){ + + if (history_pos>0) { + _update_history_pos(history_pos-1); + } + +} +void ScriptEditor::set_scene_root_script( Ref<Script> p_script ) { + + bool open_dominant = EditorSettings::get_singleton()->get("text_editor/files/open_dominant_script_on_scene_change"); + + if (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) + return; + + if (open_dominant && p_script.is_valid() && _can_open_in_editor(p_script.ptr())) { + edit(p_script); + } +} + +bool ScriptEditor::script_go_to_method(Ref<Script> p_script, const String& p_method) { + + + for (int i=0;i<tab_container->get_child_count();i++) { + ScriptEditorBase *current = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); + + if (current && current->get_edited_script()==p_script) { + if (current->goto_method(p_method)) { + edit(p_script); + return true; + } + break; + } + } + return false; +} + +void ScriptEditor::set_live_auto_reload_running_scripts(bool p_enabled) { + + auto_reload_running_scripts=p_enabled; +} + +void ScriptEditor::_help_search(String p_text) { + help_search_dialog->popup(p_text); +} + +void ScriptEditor::_open_script_request(const String& p_path) { + + Ref<Script> script = ResourceLoader::load(p_path); + if (script.is_valid()) { + script_editor->edit(script,false); + } +} + +int ScriptEditor::script_editor_func_count=0; +CreateScriptEditorFunc ScriptEditor::script_editor_funcs[ScriptEditor::SCRIPT_EDITOR_FUNC_MAX]; + +void ScriptEditor::register_create_script_editor_function(CreateScriptEditorFunc p_func) { + + ERR_FAIL_COND(script_editor_func_count==SCRIPT_EDITOR_FUNC_MAX); + script_editor_funcs[script_editor_func_count++]=p_func; +} + +void ScriptEditor::_bind_methods() { + + ClassDB::bind_method("_file_dialog_action",&ScriptEditor::_file_dialog_action); + ClassDB::bind_method("_tab_changed",&ScriptEditor::_tab_changed); + ClassDB::bind_method("_menu_option",&ScriptEditor::_menu_option); + ClassDB::bind_method("_close_current_tab",&ScriptEditor::_close_current_tab); + ClassDB::bind_method("_close_discard_current_tab", &ScriptEditor::_close_discard_current_tab); + ClassDB::bind_method("_close_docs_tab", &ScriptEditor::_close_docs_tab); + ClassDB::bind_method("_close_all_tabs", &ScriptEditor::_close_all_tabs); + ClassDB::bind_method("_editor_play",&ScriptEditor::_editor_play); + ClassDB::bind_method("_editor_pause",&ScriptEditor::_editor_pause); + ClassDB::bind_method("_editor_stop",&ScriptEditor::_editor_stop); + ClassDB::bind_method("_add_callback",&ScriptEditor::_add_callback); + ClassDB::bind_method("_reload_scripts",&ScriptEditor::_reload_scripts); + ClassDB::bind_method("_resave_scripts",&ScriptEditor::_resave_scripts); + ClassDB::bind_method("_res_saved_callback",&ScriptEditor::_res_saved_callback); + ClassDB::bind_method("_goto_script_line",&ScriptEditor::_goto_script_line); + ClassDB::bind_method("_goto_script_line2",&ScriptEditor::_goto_script_line2); + ClassDB::bind_method("_help_search",&ScriptEditor::_help_search); + ClassDB::bind_method("_save_history",&ScriptEditor::_save_history); + + + + ClassDB::bind_method("_breaked",&ScriptEditor::_breaked); + ClassDB::bind_method("_show_debugger",&ScriptEditor::_show_debugger); + ClassDB::bind_method("_get_debug_tooltip",&ScriptEditor::_get_debug_tooltip); + ClassDB::bind_method("_autosave_scripts",&ScriptEditor::_autosave_scripts); + ClassDB::bind_method("_editor_settings_changed",&ScriptEditor::_editor_settings_changed); + ClassDB::bind_method("_update_script_names",&ScriptEditor::_update_script_names); + ClassDB::bind_method("_tree_changed",&ScriptEditor::_tree_changed); + ClassDB::bind_method("_script_selected",&ScriptEditor::_script_selected); + ClassDB::bind_method("_script_created",&ScriptEditor::_script_created); + ClassDB::bind_method("_script_split_dragged",&ScriptEditor::_script_split_dragged); + ClassDB::bind_method("_help_class_open",&ScriptEditor::_help_class_open); + ClassDB::bind_method("_help_class_goto",&ScriptEditor::_help_class_goto); + ClassDB::bind_method("_request_help",&ScriptEditor::_help_class_open); + ClassDB::bind_method("_history_forward",&ScriptEditor::_history_forward); + ClassDB::bind_method("_history_back",&ScriptEditor::_history_back); + ClassDB::bind_method("_live_auto_reload_running_scripts",&ScriptEditor::_live_auto_reload_running_scripts); + ClassDB::bind_method("_unhandled_input",&ScriptEditor::_unhandled_input); + +} + +ScriptEditor::ScriptEditor(EditorNode *p_editor) { + + current_theme = ""; + + completion_cache = memnew( EditorScriptCodeCompletionCache ); + restoring_layout=false; + waiting_update_names=false; + pending_auto_reload=false; + auto_reload_running_scripts=false; + editor=p_editor; + + menu_hb = memnew( HBoxContainer ); + add_child(menu_hb); + + + script_split = memnew( HSplitContainer ); + add_child(script_split); + script_split->set_v_size_flags(SIZE_EXPAND_FILL); + + script_list = memnew( ItemList ); + script_split->add_child(script_list); + script_list->set_custom_minimum_size(Size2(0,0)); + script_split->set_split_offset(140); + + tab_container = memnew( TabContainer ); + tab_container->set_tabs_visible(false); + script_split->add_child(tab_container); + + + tab_container->set_h_size_flags(SIZE_EXPAND_FILL); + + ED_SHORTCUT("script_editor/next_script", TTR("Next script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_GREATER); + ED_SHORTCUT("script_editor/prev_script", TTR("Previous script"), KEY_MASK_CMD | KEY_LESS); + set_process_unhandled_input(true); + + file_menu = memnew( MenuButton ); + menu_hb->add_child(file_menu); + file_menu->set_text(TTR("File")); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new", TTR("New")), FILE_NEW); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/open", TTR("Open")), FILE_OPEN); + file_menu->get_popup()->add_separator(); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save", TTR("Save"), KEY_MASK_ALT|KEY_MASK_CMD|KEY_S), FILE_SAVE); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_as", TTR("Save As..")), FILE_SAVE_AS); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_all", TTR("Save All"), KEY_MASK_CMD|KEY_MASK_SHIFT|KEY_MASK_ALT|KEY_S), FILE_SAVE_ALL); + file_menu->get_popup()->add_separator(); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reload_script_soft", TTR("Soft Reload Script"), KEY_MASK_CMD|KEY_MASK_SHIFT|KEY_R), FILE_TOOL_RELOAD_SOFT); + file_menu->get_popup()->add_separator(); + + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_previous", TTR("History Prev"), KEY_MASK_ALT|KEY_LEFT), WINDOW_PREV); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_next", TTR("History Next"), KEY_MASK_ALT|KEY_RIGHT), WINDOW_NEXT); + file_menu->get_popup()->add_separator(); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/import_theme", TTR("Import Theme")), FILE_IMPORT_THEME); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reload_theme", TTR("Reload Theme")), FILE_RELOAD_THEME); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_theme", TTR("Save Theme")), FILE_SAVE_THEME); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_theme_as", TTR("Save Theme As")), FILE_SAVE_THEME_AS); + file_menu->get_popup()->add_separator(); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_docs", TTR("Close Docs")), CLOSE_DOCS); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_file", TTR("Close"), KEY_MASK_CMD | KEY_W), FILE_CLOSE); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_all", TTR("Close All")), CLOSE_ALL); + file_menu->get_popup()->connect("id_pressed", this,"_menu_option"); + + + + script_search_menu = memnew( MenuButton ); + menu_hb->add_child(script_search_menu); + script_search_menu->set_text(TTR("Search")); + script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find", TTR("Find.."), KEY_MASK_CMD|KEY_F), HELP_SEARCH_FIND); + script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_next", TTR("Find Next"), KEY_F3), HELP_SEARCH_FIND_NEXT); + script_search_menu->get_popup()->connect("id_pressed", this,"_menu_option"); + script_search_menu->hide(); + + + debug_menu = memnew( MenuButton ); + menu_hb->add_child(debug_menu); + debug_menu->set_text(TTR("Debug")); + debug_menu->get_popup()->add_separator(); + debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/step_over", TTR("Step Over"), KEY_F10), DEBUG_NEXT); + debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/step_into", TTR("Step Into"), KEY_F11), DEBUG_STEP); + debug_menu->get_popup()->add_separator(); + debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/break", TTR("Break")), DEBUG_BREAK); + debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/continue", TTR("Continue")), DEBUG_CONTINUE); + debug_menu->get_popup()->add_separator(); + //debug_menu->get_popup()->add_check_item("Show Debugger",DEBUG_SHOW); + debug_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("debugger/keep_debugger_open", TTR("Keep Debugger Open")), DEBUG_SHOW_KEEP_OPEN); + debug_menu->get_popup()->connect("id_pressed", this,"_menu_option"); + + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_NEXT), true); + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_STEP), true ); + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_BREAK), true ); + debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true ); + + +#if 0 + window_menu = memnew( MenuButton ); + menu_hb->add_child(window_menu); + window_menu->set_text(TTR("Window")); + window_menu->get_popup()->add_item(TTR("Close"),WINDOW_CLOSE,KEY_MASK_CMD|KEY_W); + window_menu->get_popup()->add_separator(); + window_menu->get_popup()->add_item(TTR("Move Left"),WINDOW_MOVE_LEFT,KEY_MASK_CMD|KEY_LEFT); + window_menu->get_popup()->add_item(TTR("Move Right"),WINDOW_MOVE_RIGHT,KEY_MASK_CMD|KEY_RIGHT); + window_menu->get_popup()->add_separator(); + window_menu->get_popup()->connect("id_pressed", this,"_menu_option"); + +#endif + + + menu_hb->add_spacer(); + + + script_icon = memnew( TextureRect ); + menu_hb->add_child(script_icon); + script_name_label = memnew( Label ); + menu_hb->add_child(script_name_label); + + script_icon->hide(); + script_name_label->hide(); + + menu_hb->add_spacer(); + + site_search = memnew( ToolButton ); + site_search->set_text(TTR("Tutorials")); + site_search->connect("pressed",this,"_menu_option",varray(SEARCH_WEBSITE)); + menu_hb->add_child(site_search); + site_search->set_tooltip(TTR("Open https://godotengine.org at tutorials section.")); + + class_search = memnew( ToolButton ); + class_search->set_text(TTR("Classes")); + class_search->connect("pressed",this,"_menu_option",varray(SEARCH_CLASSES)); + menu_hb->add_child(class_search); + class_search->set_tooltip(TTR("Search the class hierarchy.")); + + help_search = memnew( ToolButton ); + help_search->set_text(TTR("Search Help")); + help_search->connect("pressed",this,"_menu_option",varray(SEARCH_HELP)); + menu_hb->add_child(help_search); + help_search->set_tooltip(TTR("Search the reference documentation.")); + + menu_hb->add_child( memnew( VSeparator) ); + + script_back = memnew( ToolButton ); + script_back->connect("pressed",this,"_history_back"); + menu_hb->add_child(script_back); + script_back->set_disabled(true); + script_back->set_tooltip(TTR("Go to previous edited document.")); + + script_forward = memnew( ToolButton ); + script_forward->connect("pressed",this,"_history_forward"); + menu_hb->add_child(script_forward); + script_forward->set_disabled(true); + script_forward->set_tooltip(TTR("Go to next edited document.")); + + + + tab_container->connect("tab_changed", this,"_tab_changed"); + + erase_tab_confirm = memnew( ConfirmationDialog ); + erase_tab_confirm->get_ok()->set_text(TTR("Save")); + erase_tab_confirm->add_button(TTR("Discard"), OS::get_singleton()->get_swap_ok_cancel(), "discard"); + erase_tab_confirm->connect("confirmed", this,"_close_current_tab"); + erase_tab_confirm->connect("custom_action", this, "_close_discard_current_tab"); + add_child(erase_tab_confirm); + + script_create_dialog = memnew(ScriptCreateDialog); + script_create_dialog->set_title(TTR("Create Script")); + add_child(script_create_dialog); + script_create_dialog->connect("script_created", this, "_script_created"); + + file_dialog_option = -1; + file_dialog = memnew( EditorFileDialog ); + add_child(file_dialog); + file_dialog->connect("file_selected", this,"_file_dialog_action"); + + + debugger = memnew( ScriptEditorDebugger(editor) ); + debugger->connect("goto_script_line",this,"_goto_script_line"); + debugger->connect("show_debugger",this,"_show_debugger"); + + disk_changed = memnew( ConfirmationDialog ); + { + VBoxContainer *vbc = memnew( VBoxContainer ); + disk_changed->add_child(vbc); + //disk_changed->set_child_rect(vbc); + + Label *dl = memnew( Label ); + dl->set_text(TTR("The following files are newer on disk.\nWhat action should be taken?:")); + vbc->add_child(dl); + + disk_changed_list = memnew( Tree ); + vbc->add_child(disk_changed_list); + disk_changed_list->set_v_size_flags(SIZE_EXPAND_FILL); + + disk_changed->connect("confirmed",this,"_reload_scripts"); + disk_changed->get_ok()->set_text(TTR("Reload")); + + disk_changed->add_button(TTR("Resave"),!OS::get_singleton()->get_swap_ok_cancel(),"resave"); + disk_changed->connect("custom_action",this,"_resave_scripts"); + + + } + + add_child(disk_changed); + + script_editor=this; + + + Button *db = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Debugger"),debugger); + debugger->set_tool_button(db); + + + debugger->connect("breaked",this,"_breaked"); + + autosave_timer = memnew( Timer ); + autosave_timer->set_one_shot(false); + add_child(autosave_timer); + + grab_focus_block=false; + + help_search_dialog = memnew( EditorHelpSearch ); + add_child(help_search_dialog); + help_search_dialog->connect("go_to_help",this,"_help_class_goto"); + + + help_index = memnew( EditorHelpIndex ); + add_child(help_index); + help_index->connect("open_class",this,"_help_class_open"); + + history_pos=-1; + //debugger_gui->hide(); + + edit_pass=0; + trim_trailing_whitespace_on_save = false; + + ScriptServer::edit_request_func=_open_script_request; +} + + +ScriptEditor::~ScriptEditor() { + + memdelete(completion_cache); +} + +void ScriptEditorPlugin::edit(Object *p_object) { + + if (!p_object->cast_to<Script>()) + return; + + script_editor->edit(p_object->cast_to<Script>()); + +} + +bool ScriptEditorPlugin::handles(Object *p_object) const { + + if (p_object->cast_to<Script>()) { + + bool valid = _can_open_in_editor(p_object->cast_to<Script>()); + + if (!valid) { //user tried to open it by clicking + EditorNode::get_singleton()->show_warning(TTR("Built-in scripts can only be edited when the scene they belong to is loaded")); + } + return valid; + } + + return p_object->is_class("Script"); +} + +void ScriptEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + script_editor->show(); + script_editor->set_process(true); + script_editor->ensure_select_current(); + } else { + + script_editor->hide(); + script_editor->set_process(false); + } + +} + +void ScriptEditorPlugin::selected_notify() { + + script_editor->ensure_select_current(); +} + +Dictionary ScriptEditorPlugin::get_state() const { + + return script_editor->get_state(); +} + +void ScriptEditorPlugin::set_state(const Dictionary& p_state) { + + script_editor->set_state(p_state); +} +void ScriptEditorPlugin::clear() { + + script_editor->clear(); +} + +void ScriptEditorPlugin::save_external_data() { + + script_editor->save_all_scripts(); +} + +void ScriptEditorPlugin::apply_changes() { + + script_editor->apply_scripts(); +} + +void ScriptEditorPlugin::restore_global_state() { + + +} + +void ScriptEditorPlugin::save_global_state() { + +} + +void ScriptEditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) { + + script_editor->set_window_layout(p_layout); +} + +void ScriptEditorPlugin::get_window_layout(Ref<ConfigFile> p_layout){ + + script_editor->get_window_layout(p_layout); +} + + +void ScriptEditorPlugin::get_breakpoints(List<String> *p_breakpoints) { + + + return script_editor->get_breakpoints(p_breakpoints); +} + +void ScriptEditorPlugin::edited_scene_changed() { + + script_editor->edited_scene_changed(); +} + + + +ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) { + + editor=p_node; + script_editor = memnew( ScriptEditor(p_node) ); + editor->get_viewport()->add_child(script_editor); + script_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); + + script_editor->hide(); + + EDITOR_DEF("text_editor/files/auto_reload_scripts_on_external_change",true); + ScriptServer::set_reload_scripts_on_save(EDITOR_DEF("text_editor/files/auto_reload_and_parse_scripts_on_save",true)); + EDITOR_DEF("text_editor/files/open_dominant_script_on_scene_change",true); + EDITOR_DEF("text_editor/external/use_external_editor",false); + EDITOR_DEF("text_editor/external/exec_path",""); + EDITOR_DEF("text_editor/open_scripts/script_temperature_enabled",true); + EDITOR_DEF("text_editor/open_scripts/highlight_current_script", true); + EDITOR_DEF("text_editor/open_scripts/script_temperature_history_size",15); + EDITOR_DEF("text_editor/open_scripts/script_temperature_hot_color",Color(1,0,0,0.3)); + EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color",Color(0,0,1,0.3)); + EDITOR_DEF("text_editor/open_scripts/current_script_background_color",Color(0.81,0.81,0.14,0.63)); + EDITOR_DEF("text_editor/open_scripts/group_help_pages",true); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT,"text_editor/open_scripts/sort_scripts_by",PROPERTY_HINT_ENUM,"Name,Path")); + EDITOR_DEF("text_editor/open_scripts/sort_scripts_by",0); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT,"text_editor/open_scripts/list_script_names_as",PROPERTY_HINT_ENUM,"Name,Parent Directory And Name,Full Path")); + EDITOR_DEF("text_editor/open_scripts/list_script_names_as",0); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"text_editor/external/exec_path",PROPERTY_HINT_GLOBAL_FILE)); + EDITOR_DEF("text_editor/external/exec_flags",""); + + +} + + +ScriptEditorPlugin::~ScriptEditorPlugin() +{ +} diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h new file mode 100644 index 0000000000..bf5316363c --- /dev/null +++ b/editor/plugins/script_editor_plugin.h @@ -0,0 +1,394 @@ +/*************************************************************************/ +/* script_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef SCRIPT_EDITOR_PLUGIN_H +#define SCRIPT_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/script_create_dialog.h" +#include "scene/gui/tab_container.h" +#include "scene/gui/text_edit.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/tree.h" +#include "scene/main/timer.h" +#include "script_language.h" +#include "editor/code_editor.h" +#include "scene/gui/split_container.h" +#include "scene/gui/item_list.h" +#include "editor/editor_help.h" + +class ScriptEditorQuickOpen : public ConfirmationDialog { + + GDCLASS(ScriptEditorQuickOpen,ConfirmationDialog ) + + LineEdit *search_box; + Tree *search_options; + String function; + + void _update_search(); + + void _sbox_input(const InputEvent& p_ie); + Vector<String> functions; + + + void _confirmed(); + void _text_changed(const String& p_newtext); + +protected: + + void _notification(int p_what); + static void _bind_methods(); +public: + + void popup(const Vector<String>& p_base,bool p_dontclear=false); + ScriptEditorQuickOpen(); +}; + + +class ScriptEditorDebugger; + + + +class ScriptEditorBase : public Control { + + GDCLASS( ScriptEditorBase, Control ); +protected: + static void _bind_methods(); +public: + + virtual void apply_code()=0; + virtual Ref<Script> get_edited_script() const=0; + virtual Vector<String> get_functions()=0; + virtual void set_edited_script(const Ref<Script>& p_script)=0; + virtual void reload_text()=0; + virtual String get_name()=0; + virtual Ref<Texture> get_icon()=0; + virtual bool is_unsaved()=0; + virtual Variant get_edit_state()=0; + virtual void set_edit_state(const Variant& p_state)=0; + virtual void goto_line(int p_line,bool p_with_error=false)=0; + virtual void trim_trailing_whitespace()=0; + virtual void ensure_focus()=0; + virtual void tag_saved_version()=0; + virtual void reload(bool p_soft)=0; + virtual void get_breakpoints(List<int> *p_breakpoints)=0; + virtual bool goto_method(const String& p_method)=0; + virtual void add_callback(const String& p_function,PoolStringArray p_args)=0; + virtual void update_settings()=0; + virtual void set_debugger_active(bool p_active)=0; + virtual bool can_lose_focus_on_node_selection() { return true; } + + virtual void set_tooltip_request_func(String p_method,Object* p_obj)=0; + virtual Control *get_edit_menu()=0; + + ScriptEditorBase() {} +}; + + +typedef ScriptEditorBase* (*CreateScriptEditorFunc)(const Ref<Script>& p_script); + + +class EditorScriptCodeCompletionCache; + +class ScriptEditor : public VBoxContainer { + + GDCLASS(ScriptEditor, VBoxContainer ); + + + EditorNode *editor; + enum { + FILE_NEW, + FILE_OPEN, + FILE_SAVE, + FILE_SAVE_AS, + FILE_SAVE_ALL, + FILE_IMPORT_THEME, + FILE_RELOAD_THEME, + FILE_SAVE_THEME, + FILE_SAVE_THEME_AS, + FILE_CLOSE, + CLOSE_DOCS, + CLOSE_ALL, + FILE_TOOL_RELOAD, + FILE_TOOL_RELOAD_SOFT, + DEBUG_NEXT, + DEBUG_STEP, + DEBUG_BREAK, + DEBUG_CONTINUE, + DEBUG_SHOW, + DEBUG_SHOW_KEEP_OPEN, + SEARCH_HELP, + SEARCH_CLASSES, + SEARCH_WEBSITE, + HELP_SEARCH_FIND, + HELP_SEARCH_FIND_NEXT, + WINDOW_MOVE_LEFT, + WINDOW_MOVE_RIGHT, + WINDOW_NEXT, + WINDOW_PREV, + WINDOW_SELECT_BASE=100 + }; + + enum ScriptSortBy { + SORT_BY_NAME, + SORT_BY_PATH, + }; + + enum ScriptListName { + DISPLAY_NAME, + DISPLAY_DIR_AND_NAME, + DISPLAY_FULL_PATH, + }; + + HBoxContainer *menu_hb; + MenuButton *file_menu; + MenuButton *edit_menu; + MenuButton *script_search_menu; + MenuButton *debug_menu; + Timer *autosave_timer; + uint64_t idle; + + Button *help_search; + Button *site_search; + Button *class_search; + EditorHelpSearch *help_search_dialog; + + ItemList *script_list; + HSplitContainer *script_split; + TabContainer *tab_container; + EditorFileDialog *file_dialog; + ConfirmationDialog *erase_tab_confirm; + ScriptCreateDialog *script_create_dialog; + ScriptEditorDebugger* debugger; + ToolButton *scripts_visible; + + String current_theme; + + TextureRect *script_icon; + Label *script_name_label; + + ToolButton *script_back; + ToolButton *script_forward; + + enum { + SCRIPT_EDITOR_FUNC_MAX=32 + }; + + static int script_editor_func_count; + static CreateScriptEditorFunc script_editor_funcs[SCRIPT_EDITOR_FUNC_MAX]; + + struct ScriptHistory { + + Control *control; + Variant state; + }; + + Vector<ScriptHistory> history; + int history_pos; + + + EditorHelpIndex *help_index; + + void _tab_changed(int p_which); + void _menu_option(int p_optin); + + Tree *disk_changed_list; + ConfirmationDialog *disk_changed; + + bool restoring_layout; + + String _get_debug_tooltip(const String&p_text,Node *_ste); + + void _resave_scripts(const String& p_str); + void _reload_scripts(); + + bool _test_script_times_on_disk(Ref<Script> p_for_script=Ref<Script>()); + + void _close_tab(int p_idx, bool p_save=true); + + void _close_current_tab(); + void _close_discard_current_tab(const String& p_str); + void _close_docs_tab(); + void _close_all_tabs(); + + void _ask_close_current_unsaved_tab(ScriptEditorBase *current); + + bool grab_focus_block; + + bool pending_auto_reload; + bool auto_reload_running_scripts; + void _live_auto_reload_running_scripts(); + + void _update_selected_editor_menu(); + + EditorScriptCodeCompletionCache *completion_cache; + + void _editor_play(); + void _editor_pause(); + void _editor_stop(); + + int edit_pass; + + void _add_callback(Object *p_obj, const String& p_function, const PoolStringArray& p_args); + void _res_saved_callback(const Ref<Resource>& p_res); + + bool trim_trailing_whitespace_on_save; + + void _trim_trailing_whitespace(TextEdit *tx); + + void _goto_script_line2(int p_line); + void _goto_script_line(REF p_script,int p_line); + void _breaked(bool p_breaked,bool p_can_debug); + void _show_debugger(bool p_show); + void _update_window_menu(); + void _script_created(Ref<Script> p_script); + + void _save_layout(); + void _editor_settings_changed(); + void _autosave_scripts(); + + void _update_script_names(); + + void _script_selected(int p_idx); + + void _find_scripts(Node* p_base, Node* p_current,Set<Ref<Script> >& used); + + void _tree_changed(); + + void _script_split_dragged(float); + + void _unhandled_input(const InputEvent& p_event); + + void _help_search(String p_text); + + void _history_forward(); + void _history_back(); + + bool waiting_update_names; + + void _help_class_open(const String& p_class); + void _help_class_goto(const String& p_desc); + void _update_history_arrows(); + void _save_history(); + void _go_to_tab(int p_idx); + void _update_history_pos(int p_new_pos); + void _update_script_colors(); + void _update_modified_scripts_for_external_editor(Ref<Script> p_for_script=Ref<Script>()); + + int file_dialog_option; + void _file_dialog_action(String p_file); + + static void _open_script_request(const String& p_path); + + static ScriptEditor *script_editor; +protected: + void _notification(int p_what); + static void _bind_methods(); +public: + + static ScriptEditor *get_singleton() { return script_editor; } + + void ensure_focus_current(); + void apply_scripts() const; + + void ensure_select_current(); + void edit(const Ref<Script>& p_script,bool p_grab_focus=true); + + Dictionary get_state() const; + void set_state(const Dictionary& p_state); + void clear(); + + void get_breakpoints(List<String> *p_breakpoints); + + //void swap_lines(TextEdit *tx, int line1, int line2); + + void save_all_scripts(); + + void set_window_layout(Ref<ConfigFile> p_layout); + void get_window_layout(Ref<ConfigFile> p_layout); + + void set_scene_root_script( Ref<Script> p_script ); + + bool script_go_to_method(Ref<Script> p_script, const String& p_method); + + virtual void edited_scene_changed(); + + void close_builtin_scripts_from_scene(const String& p_scene); + + void goto_help(const String& p_desc) { _help_class_goto(p_desc); } + + bool can_take_away_focus() const; + + ScriptEditorDebugger *get_debugger() { return debugger; } + void set_live_auto_reload_running_scripts(bool p_enabled); + + static void register_create_script_editor_function(CreateScriptEditorFunc p_func); + ScriptEditor(EditorNode *p_editor); + ~ScriptEditor(); +}; + +class ScriptEditorPlugin : public EditorPlugin { + + GDCLASS( ScriptEditorPlugin, EditorPlugin ); + + ScriptEditor *script_editor; + EditorNode *editor; +public: + + virtual String get_name() const { return "Script"; } + bool has_main_screen() const { return true; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + virtual void selected_notify(); + + Dictionary get_state() const; + virtual void set_state(const Dictionary& p_state); + virtual void clear(); + + virtual void save_external_data(); + virtual void apply_changes(); + + virtual void restore_global_state(); + virtual void save_global_state(); + + virtual void set_window_layout(Ref<ConfigFile> p_layout); + virtual void get_window_layout(Ref<ConfigFile> p_layout); + + virtual void get_breakpoints(List<String> *p_breakpoints); + + + virtual void edited_scene_changed(); + + ScriptEditorPlugin(EditorNode *p_node); + ~ScriptEditorPlugin(); + +}; + +#endif // SCRIPT_EDITOR_PLUGIN_H diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp new file mode 100644 index 0000000000..8723a863f0 --- /dev/null +++ b/editor/plugins/script_text_editor.cpp @@ -0,0 +1,1401 @@ +/*************************************************************************/ +/* script_text_editor.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 "script_text_editor.h" + +#include "editor/editor_settings.h" +#include "os/keyboard.h" +#include "editor/script_editor_debugger.h" +#include "editor/editor_node.h" + +Vector<String> ScriptTextEditor::get_functions() { + + + String errortxt; + int line=-1,col; + TextEdit *te=code_editor->get_text_edit(); + String text = te->get_text(); + List<String> fnc; + + if (script->get_language()->validate(text,line,col,errortxt,script->get_path(),&fnc)) { + + //if valid rewrite functions to latest + functions.clear(); + for (List<String>::Element *E=fnc.front();E;E=E->next()) { + + functions.push_back(E->get()); + } + + + } + + return functions; +} + +void ScriptTextEditor::apply_code() { + + if (script.is_null()) + return; + //print_line("applying code"); + script->set_source_code(code_editor->get_text_edit()->get_text()); + script->update_exports(); +} + +Ref<Script> ScriptTextEditor::get_edited_script() const { + + return script; +} + +bool ScriptTextEditor::goto_method(const String& p_method) { + + + Vector<String> functions = get_functions(); + + String method_search = p_method + ":"; + + for (int i=0;i<functions.size();i++) { + String function=functions[i]; + + if (function.begins_with(method_search)) { + + int line=function.get_slice(":",1).to_int(); + goto_line(line-1); + return true; + } + } + + return false; +} + +void ScriptTextEditor::_load_theme_settings() { + + TextEdit *text_edit = code_editor->get_text_edit(); + + text_edit->clear_colors(); + + /* keyword color */ + + + text_edit->add_color_override("background_color", EDITOR_DEF("text_editor/highlighting/background_color",Color(0,0,0,0))); + text_edit->add_color_override("completion_background_color", EDITOR_DEF("text_editor/highlighting/completion_background_color", Color(0,0,0,0))); + text_edit->add_color_override("completion_selected_color", EDITOR_DEF("text_editor/highlighting/completion_selected_color", Color::html("434244"))); + text_edit->add_color_override("completion_existing_color", EDITOR_DEF("text_editor/highlighting/completion_existing_color", Color::html("21dfdfdf"))); + text_edit->add_color_override("completion_scroll_color", EDITOR_DEF("text_editor/highlighting/completion_scroll_color", Color::html("ffffff"))); + text_edit->add_color_override("completion_font_color", EDITOR_DEF("text_editor/highlighting/completion_font_color", Color::html("aaaaaa"))); + text_edit->add_color_override("font_color",EDITOR_DEF("text_editor/highlighting/text_color",Color(0,0,0))); + text_edit->add_color_override("line_number_color",EDITOR_DEF("text_editor/highlighting/line_number_color",Color(0,0,0))); + text_edit->add_color_override("caret_color",EDITOR_DEF("text_editor/highlighting/caret_color",Color(0,0,0))); + text_edit->add_color_override("caret_background_color",EDITOR_DEF("text_editor/highlighting/caret_background_color",Color(0,0,0))); + text_edit->add_color_override("font_selected_color",EDITOR_DEF("text_editor/highlighting/text_selected_color",Color(1,1,1))); + text_edit->add_color_override("selection_color",EDITOR_DEF("text_editor/highlighting/selection_color",Color(0.2,0.2,1))); + text_edit->add_color_override("brace_mismatch_color",EDITOR_DEF("text_editor/highlighting/brace_mismatch_color",Color(1,0.2,0.2))); + text_edit->add_color_override("current_line_color",EDITOR_DEF("text_editor/highlighting/current_line_color",Color(0.3,0.5,0.8,0.15))); + text_edit->add_color_override("line_length_guideline_color", EDITOR_DEF("text_editor/highlighting/line_length_guideline_color", Color(0,0,0))); + text_edit->add_color_override("word_highlighted_color",EDITOR_DEF("text_editor/highlighting/word_highlighted_color",Color(0.8,0.9,0.9,0.15))); + text_edit->add_color_override("number_color",EDITOR_DEF("text_editor/highlighting/number_color",Color(0.9,0.6,0.0,2))); + text_edit->add_color_override("function_color",EDITOR_DEF("text_editor/highlighting/function_color",Color(0.4,0.6,0.8))); + text_edit->add_color_override("member_variable_color",EDITOR_DEF("text_editor/highlighting/member_variable_color",Color(0.9,0.3,0.3))); + text_edit->add_color_override("mark_color", EDITOR_DEF("text_editor/highlighting/mark_color", Color(1.0,0.4,0.4,0.4))); + text_edit->add_color_override("breakpoint_color", EDITOR_DEF("text_editor/highlighting/breakpoint_color", Color(0.8,0.8,0.4,0.2))); + text_edit->add_color_override("search_result_color",EDITOR_DEF("text_editor/highlighting/search_result_color",Color(0.05,0.25,0.05,1))); + text_edit->add_color_override("search_result_border_color",EDITOR_DEF("text_editor/highlighting/search_result_border_color",Color(0.1,0.45,0.1,1))); + text_edit->add_color_override("symbol_color",EDITOR_DEF("text_editor/highlighting/symbol_color",Color::hex(0x005291ff))); + text_edit->add_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing",4)); + + Color keyword_color= EDITOR_DEF("text_editor/highlighting/keyword_color",Color(0.5,0.0,0.2)); + + List<String> keywords; + script->get_language()->get_reserved_words(&keywords); + for(List<String>::Element *E=keywords.front();E;E=E->next()) { + + text_edit->add_keyword_color(E->get(),keyword_color); + } + + //colorize core types + Color basetype_color= EDITOR_DEF("text_editor/highlighting/base_type_color",Color(0.3,0.3,0.0)); + + text_edit->add_keyword_color("Vector2",basetype_color); + text_edit->add_keyword_color("Vector3",basetype_color); + text_edit->add_keyword_color("Plane",basetype_color); + text_edit->add_keyword_color("Quat",basetype_color); + text_edit->add_keyword_color("AABB",basetype_color); + text_edit->add_keyword_color("Matrix3",basetype_color); + text_edit->add_keyword_color("Transform",basetype_color); + text_edit->add_keyword_color("Color",basetype_color); + text_edit->add_keyword_color("Image",basetype_color); + text_edit->add_keyword_color("InputEvent",basetype_color); + text_edit->add_keyword_color("Rect2",basetype_color); + text_edit->add_keyword_color("NodePath",basetype_color); + + //colorize engine types + Color type_color= EDITOR_DEF("text_editor/highlighting/engine_type_color",Color(0.0,0.2,0.4)); + + List<StringName> types; + ClassDB::get_class_list(&types); + + for(List<StringName>::Element *E=types.front();E;E=E->next()) { + + String n = E->get(); + if (n.begins_with("_")) + n = n.substr(1, n.length()); + + text_edit->add_keyword_color(n,type_color); + } + + //colorize comments + Color comment_color = EDITOR_DEF("text_editor/highlighting/comment_color",Color::hex(0x797e7eff)); + List<String> comments; + script->get_language()->get_comment_delimiters(&comments); + + for(List<String>::Element *E=comments.front();E;E=E->next()) { + + String comment = E->get(); + String beg = comment.get_slice(" ",0); + String end = comment.get_slice_count(" ")>1?comment.get_slice(" ",1):String(); + + text_edit->add_color_region(beg,end,comment_color,end==""); + } + + //colorize strings + Color string_color = EDITOR_DEF("text_editor/highlighting/string_color",Color::hex(0x6b6f00ff)); + List<String> strings; + script->get_language()->get_string_delimiters(&strings); + + for (List<String>::Element *E=strings.front();E;E=E->next()) { + + String string = E->get(); + String beg = string.get_slice(" ",0); + String end = string.get_slice_count(" ")>1?string.get_slice(" ",1):String(); + text_edit->add_color_region(beg,end,string_color,end==""); + } +} + + +void ScriptTextEditor::reload_text() { + + ERR_FAIL_COND(script.is_null()) ; + + TextEdit *te = code_editor->get_text_edit(); + int column = te->cursor_get_column(); + int row = te->cursor_get_line(); + int h = te->get_h_scroll(); + int v = te->get_v_scroll(); + + te->set_text(script->get_source_code()); + te->clear_undo_history(); + te->cursor_set_line(row); + te->cursor_set_column(column); + te->set_h_scroll(h); + te->set_v_scroll(v); + + te->tag_saved_version(); + + code_editor->update_line_and_column(); + +} + +void ScriptTextEditor::_notification(int p_what) { + + if (p_what==NOTIFICATION_READY) { + + //emit_signal("name_changed"); + } +} + +void ScriptTextEditor::add_callback(const String& p_function,PoolStringArray p_args) { + + String code = code_editor->get_text_edit()->get_text(); + int pos = script->get_language()->find_function(p_function,code); + if (pos==-1) { + //does not exist + code_editor->get_text_edit()->deselect(); + pos=code_editor->get_text_edit()->get_line_count()+2; + String func = script->get_language()->make_function("",p_function,p_args); + //code=code+func; + code_editor->get_text_edit()->cursor_set_line(pos+1); + code_editor->get_text_edit()->cursor_set_column(1000000); //none shall be that big + code_editor->get_text_edit()->insert_text_at_cursor("\n\n"+func); + } + code_editor->get_text_edit()->cursor_set_line(pos); + code_editor->get_text_edit()->cursor_set_column(1); +} + +void ScriptTextEditor::update_settings() { + + code_editor->update_editor_settings(); +} + +bool ScriptTextEditor::is_unsaved() { + + return code_editor->get_text_edit()->get_version()!=code_editor->get_text_edit()->get_saved_version(); +} + +Variant ScriptTextEditor::get_edit_state() { + + Dictionary state; + + state["scroll_pos"]=code_editor->get_text_edit()->get_v_scroll(); + state["column"]=code_editor->get_text_edit()->cursor_get_column(); + state["row"]=code_editor->get_text_edit()->cursor_get_line(); + + return state; +} + +void ScriptTextEditor::trim_trailing_whitespace() { + + TextEdit *tx = code_editor->get_text_edit(); + + bool trimed_whitespace = false; + for (int i = 0; i < tx->get_line_count(); i++) { + String line = tx->get_line(i); + if (line.ends_with(" ") || line.ends_with("\t")) { + + if (!trimed_whitespace) { + tx->begin_complex_operation(); + trimed_whitespace = true; + } + + int end = 0; + for (int j = line.length() - 1; j > -1; j--) { + if (line[j] != ' ' && line[j] != '\t') { + end = j+1; + break; + } + } + tx->set_line(i, line.substr(0, end)); + } + } + if (trimed_whitespace) { + tx->end_complex_operation(); + tx->update(); + } +} + +void ScriptTextEditor::tag_saved_version() { + + code_editor->get_text_edit()->tag_saved_version(); +} + +void ScriptTextEditor::goto_line(int p_line, bool p_with_error) { + code_editor->get_text_edit()->cursor_set_line(p_line); +} + +void ScriptTextEditor::ensure_focus() { + + code_editor->get_text_edit()->grab_focus(); +} + +void ScriptTextEditor::set_edit_state(const Variant& p_state) { + + Dictionary state=p_state; + code_editor->get_text_edit()->set_v_scroll(state["scroll_pos"]); + code_editor->get_text_edit()->cursor_set_column( state["column"]); + code_editor->get_text_edit()->cursor_set_line( state["row"] ); + code_editor->get_text_edit()->grab_focus(); + + //int scroll_pos; + //int cursor_column; + //int cursor_row; +} + +String ScriptTextEditor::get_name() { + String name; + + if (script->get_path().find("local://")==-1 && script->get_path().find("::")==-1) { + name=script->get_path().get_file(); + if (is_unsaved()) { + name+="(*)"; + } + } else if (script->get_name()!="") + name=script->get_name(); + else + name=script->get_class()+"("+itos(script->get_instance_ID())+")"; + + return name; + +} + +Ref<Texture> ScriptTextEditor::get_icon() { + + if (get_parent_control() && get_parent_control()->has_icon(script->get_class(),"EditorIcons")) { + return get_parent_control()->get_icon(script->get_class(),"EditorIcons"); + } + + return Ref<Texture>(); +} + + + +void ScriptTextEditor::set_edited_script(const Ref<Script>& p_script) { + + ERR_FAIL_COND(!script.is_null()); + + script=p_script; + + + _load_theme_settings(); + + code_editor->get_text_edit()->set_text(script->get_source_code()); + code_editor->get_text_edit()->clear_undo_history(); + code_editor->get_text_edit()->tag_saved_version(); + + emit_signal("name_changed"); + code_editor->update_line_and_column(); +} + + +void ScriptTextEditor::_validate_script() { + + String errortxt; + int line=-1,col; + TextEdit *te=code_editor->get_text_edit(); + + String text = te->get_text(); + List<String> fnc; + + if (!script->get_language()->validate(text,line,col,errortxt,script->get_path(),&fnc)) { + String error_text="error("+itos(line)+","+itos(col)+"): "+errortxt; + code_editor->set_error(error_text); + } else { + code_editor->set_error(""); + line=-1; + if (!script->is_tool()) { + script->set_source_code(text); + script->update_exports(); + //script->reload(); //will update all the variables in property editors + } + + functions.clear(); + for (List<String>::Element *E=fnc.front();E;E=E->next()) { + + functions.push_back(E->get()); + } + + } + + line--; + for(int i=0;i<te->get_line_count();i++) { + te->set_line_as_marked(i,line==i); + } + + emit_signal("name_changed"); +} + + +static Node* _find_node_for_script(Node* p_base, Node*p_current, const Ref<Script>& p_script) { + + if (p_current->get_owner()!=p_base && p_base!=p_current) + return NULL; + Ref<Script> c = p_current->get_script(); + if (c==p_script) + return p_current; + for(int i=0;i<p_current->get_child_count();i++) { + Node *found = _find_node_for_script(p_base,p_current->get_child(i),p_script); + if (found) + return found; + } + + return NULL; +} + +static void _find_changed_scripts_for_external_editor(Node* p_base, Node*p_current, Set<Ref<Script> > &r_scripts) { + + if (p_current->get_owner()!=p_base && p_base!=p_current) + return; + Ref<Script> c = p_current->get_script(); + + if (c.is_valid()) + r_scripts.insert(c); + + for(int i=0;i<p_current->get_child_count();i++) { + _find_changed_scripts_for_external_editor(p_base,p_current->get_child(i),r_scripts); + } + +} + +void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_for_script) { + + if (!bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) + return; + + Set<Ref<Script> > scripts; + + Node *base = get_tree()->get_edited_scene_root(); + if (base) { + _find_changed_scripts_for_external_editor(base,base,scripts); + } + + for (Set<Ref<Script> >::Element *E=scripts.front();E;E=E->next()) { + + Ref<Script> script = E->get(); + + if (p_for_script.is_valid() && p_for_script!=script) + continue; + + if (script->get_path()=="" || script->get_path().find("local://")!=-1 || script->get_path().find("::")!=-1) { + + continue; //internal script, who cares, though weird + } + + uint64_t last_date = script->get_last_modified_time(); + uint64_t date = FileAccess::get_modified_time(script->get_path()); + + if (last_date!=date) { + + Ref<Script> rel_script = ResourceLoader::load(script->get_path(),script->get_class(),true); + ERR_CONTINUE(!rel_script.is_valid()); + script->set_source_code( rel_script->get_source_code() ); + script->set_last_modified_time( rel_script->get_last_modified_time() ); + script->update_exports(); + } + + } +} + + +void ScriptTextEditor::_code_complete_scripts(void* p_ud,const String& p_code, List<String>* r_options) { + + ScriptTextEditor *ste = (ScriptTextEditor *)p_ud; + ste->_code_complete_script(p_code,r_options); +} + +void ScriptTextEditor::_code_complete_script(const String& p_code, List<String>* r_options) { + + if (color_panel->is_visible_in_tree()) return; + Node *base = get_tree()->get_edited_scene_root(); + if (base) { + base = _find_node_for_script(base,base,script); + } + String hint; + Error err = script->get_language()->complete_code(p_code,script->get_path().get_base_dir(),base,r_options,hint); + if (hint!="") { + code_editor->get_text_edit()->set_code_hint(hint); + } + +} + +void ScriptTextEditor::_breakpoint_toggled(int p_row) { + + ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(script->get_path(),p_row+1,code_editor->get_text_edit()->is_line_set_as_breakpoint(p_row)); + +} + +static void swap_lines(TextEdit *tx, int line1, int line2) +{ + String tmp = tx->get_line(line1); + String tmp2 = tx->get_line(line2); + tx->set_line(line2, tmp); + tx->set_line(line1, tmp2); + + tx->cursor_set_line(line2); +} + +void ScriptTextEditor::_lookup_symbol(const String& p_symbol,int p_row, int p_column) { + + Node *base = get_tree()->get_edited_scene_root(); + if (base) { + base = _find_node_for_script(base,base,script); + } + + + ScriptLanguage::LookupResult result; + if (script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(),p_symbol,script->get_path().get_base_dir(),base,result)==OK) { + + _goto_line(p_row); + + switch(result.type) { + case ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION: { + + if (result.script.is_valid()) { + emit_signal("request_open_script_at_line",result.script,result.location-1); + } else { + emit_signal("request_save_history"); + _goto_line(result.location-1); + } + } break; + case ScriptLanguage::LookupResult::RESULT_CLASS: { + emit_signal("go_to_help","class_name:"+result.class_name); + } break; + case ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT: { + + StringName cname = result.class_name; + bool success; + while(true) { + ClassDB::get_integer_constant(cname,result.class_member,&success); + if (success) { + result.class_name=cname; + cname=ClassDB::get_parent_class(cname); + } else { + break; + } + } + + + emit_signal("go_to_help","class_constant:"+result.class_name+":"+result.class_member); + + } break; + case ScriptLanguage::LookupResult::RESULT_CLASS_PROPERTY: { + emit_signal("go_to_help","class_property:"+result.class_name+":"+result.class_member); + + } break; + case ScriptLanguage::LookupResult::RESULT_CLASS_METHOD: { + + StringName cname = result.class_name; + + while(true) { + if (ClassDB::has_method(cname,result.class_member)) { + result.class_name=cname; + cname=ClassDB::get_parent_class(cname); + } else { + break; + } + } + + emit_signal("go_to_help","class_method:"+result.class_name+":"+result.class_member); + + } break; + } + + } +} + +void ScriptTextEditor::_edit_option(int p_op) { + + switch(p_op) { + case EDIT_UNDO: { + code_editor->get_text_edit()->undo(); + code_editor->get_text_edit()->call_deferred("grab_focus"); + } break; + case EDIT_REDO: { + code_editor->get_text_edit()->redo(); + code_editor->get_text_edit()->call_deferred("grab_focus"); + } break; + case EDIT_CUT: { + + code_editor->get_text_edit()->cut(); + code_editor->get_text_edit()->call_deferred("grab_focus"); + } break; + case EDIT_COPY: { + code_editor->get_text_edit()->copy(); + code_editor->get_text_edit()->call_deferred("grab_focus"); + + } break; + case EDIT_PASTE: { + code_editor->get_text_edit()->paste(); + code_editor->get_text_edit()->call_deferred("grab_focus"); + + } break; + case EDIT_SELECT_ALL: { + + code_editor->get_text_edit()->select_all(); + code_editor->get_text_edit()->call_deferred("grab_focus"); + + } break; + case EDIT_MOVE_LINE_UP: { + + TextEdit *tx = code_editor->get_text_edit(); + Ref<Script> scr = script; + if (scr.is_null()) + return; + + tx->begin_complex_operation(); + if (tx->is_selection_active()) + { + int from_line = tx->get_selection_from_line(); + int from_col = tx->get_selection_from_column(); + int to_line = tx->get_selection_to_line(); + int to_column = tx->get_selection_to_column(); + + for (int i = from_line; i <= to_line; i++) + { + int line_id = i; + int next_id = i - 1; + + if (line_id == 0 || next_id < 0) + return; + + swap_lines(tx, line_id, next_id); + } + int from_line_up = from_line > 0 ? from_line-1 : from_line; + int to_line_up = to_line > 0 ? to_line-1 : to_line; + tx->select(from_line_up, from_col, to_line_up, to_column); + } + else + { + int line_id = tx->cursor_get_line(); + int next_id = line_id - 1; + + if (line_id == 0 || next_id < 0) + return; + + swap_lines(tx, line_id, next_id); + } + tx->end_complex_operation(); + tx->update(); + + } break; + case EDIT_MOVE_LINE_DOWN: { + + TextEdit *tx = code_editor->get_text_edit(); + Ref<Script> scr = get_edited_script(); + if (scr.is_null()) + return; + + tx->begin_complex_operation(); + if (tx->is_selection_active()) + { + int from_line = tx->get_selection_from_line(); + int from_col = tx->get_selection_from_column(); + int to_line = tx->get_selection_to_line(); + int to_column = tx->get_selection_to_column(); + + for (int i = to_line; i >= from_line; i--) + { + int line_id = i; + int next_id = i + 1; + + if (line_id == tx->get_line_count()-1 || next_id > tx->get_line_count()) + return; + + swap_lines(tx, line_id, next_id); + } + int from_line_down = from_line < tx->get_line_count() ? from_line+1 : from_line; + int to_line_down = to_line < tx->get_line_count() ? to_line+1 : to_line; + tx->select(from_line_down, from_col, to_line_down, to_column); + } + else + { + int line_id = tx->cursor_get_line(); + int next_id = line_id + 1; + + if (line_id == tx->get_line_count()-1 || next_id > tx->get_line_count()) + return; + + swap_lines(tx, line_id, next_id); + } + tx->end_complex_operation(); + tx->update(); + + } break; + case EDIT_INDENT_LEFT: { + + TextEdit *tx = code_editor->get_text_edit(); + Ref<Script> scr = get_edited_script(); + if (scr.is_null()) + return; + + tx->begin_complex_operation(); + if (tx->is_selection_active()) + { + tx->indent_selection_left(); + } + else + { + int begin = tx->cursor_get_line(); + String line_text = tx->get_line(begin); + // begins with tab + if (line_text.begins_with("\t")) + { + line_text = line_text.substr(1, line_text.length()); + tx->set_line(begin, line_text); + } + // begins with 4 spaces + else if (line_text.begins_with(" ")) + { + line_text = line_text.substr(4, line_text.length()); + tx->set_line(begin, line_text); + } + } + tx->end_complex_operation(); + tx->update(); + //tx->deselect(); + + } break; + case EDIT_INDENT_RIGHT: { + + TextEdit *tx = code_editor->get_text_edit(); + Ref<Script> scr = get_edited_script(); + if (scr.is_null()) + return; + + tx->begin_complex_operation(); + if (tx->is_selection_active()) + { + tx->indent_selection_right(); + } + else + { + int begin = tx->cursor_get_line(); + String line_text = tx->get_line(begin); + line_text = '\t' + line_text; + tx->set_line(begin, line_text); + } + tx->end_complex_operation(); + tx->update(); + //tx->deselect(); + + } break; + case EDIT_CLONE_DOWN: { + + TextEdit *tx = code_editor->get_text_edit(); + Ref<Script> scr = get_edited_script(); + if (scr.is_null()) + return; + + int from_line = tx->cursor_get_line(); + int to_line = tx->cursor_get_line(); + int column = tx->cursor_get_column(); + + if (tx->is_selection_active()) { + from_line = tx->get_selection_from_line(); + to_line = tx->get_selection_to_line(); + column = tx->cursor_get_column(); + } + int next_line = to_line + 1; + + tx->begin_complex_operation(); + for (int i = from_line; i <= to_line; i++) { + + if (i >= tx->get_line_count() - 1) { + tx->set_line(i, tx->get_line(i) + "\n"); + } + String line_clone = tx->get_line(i); + tx->insert_at(line_clone, next_line); + next_line++; + } + + tx->cursor_set_column(column); + if (tx->is_selection_active()) { + tx->select(to_line + 1, tx->get_selection_from_column(), next_line - 1, tx->get_selection_to_column()); + } + + tx->end_complex_operation(); + tx->update(); + + } break; + case EDIT_TOGGLE_COMMENT: { + + TextEdit *tx = code_editor->get_text_edit(); + Ref<Script> scr = get_edited_script(); + if (scr.is_null()) + return; + + + tx->begin_complex_operation(); + if (tx->is_selection_active()) + { + int begin = tx->get_selection_from_line(); + int end = tx->get_selection_to_line(); + + // End of selection ends on the first column of the last line, ignore it. + if(tx->get_selection_to_column() == 0) + end -= 1; + + for (int i = begin; i <= end; i++) + { + String line_text = tx->get_line(i); + + if (line_text.begins_with("#")) + line_text = line_text.substr(1, line_text.length()); + else + line_text = "#" + line_text; + tx->set_line(i, line_text); + } + } + else + { + int begin = tx->cursor_get_line(); + String line_text = tx->get_line(begin); + + if (line_text.begins_with("#")) + line_text = line_text.substr(1, line_text.length()); + else + line_text = "#" + line_text; + tx->set_line(begin, line_text); + } + tx->end_complex_operation(); + tx->update(); + //tx->deselect(); + + } break; + case EDIT_COMPLETE: { + + code_editor->get_text_edit()->query_code_comple(); + + } break; + case EDIT_AUTO_INDENT: { + + TextEdit *te = code_editor->get_text_edit(); + String text = te->get_text(); + Ref<Script> scr = get_edited_script(); + if (scr.is_null()) + return; + int begin,end; + if (te->is_selection_active()) { + begin=te->get_selection_from_line(); + end=te->get_selection_to_line(); + } else { + begin=0; + end=te->get_line_count()-1; + } + scr->get_language()->auto_indent_code(text,begin,end); + te->set_text(text); + + + } break; + case EDIT_TRIM_TRAILING_WHITESAPCE: { + trim_trailing_whitespace(); + } break; + case EDIT_PICK_COLOR: { + color_panel->popup(); + } break; + + + case SEARCH_FIND: { + + code_editor->get_find_replace_bar()->popup_search(); + } break; + case SEARCH_FIND_NEXT: { + + code_editor->get_find_replace_bar()->search_next(); + } break; + case SEARCH_FIND_PREV: { + + code_editor->get_find_replace_bar()->search_prev(); + } break; + case SEARCH_REPLACE: { + + code_editor->get_find_replace_bar()->popup_replace(); + } break; + case SEARCH_LOCATE_FUNCTION: { + + quick_open->popup(get_functions()); + } break; + case SEARCH_GOTO_LINE: { + + goto_line_dialog->popup_find_line(code_editor->get_text_edit()); + } break; + case DEBUG_TOGGLE_BREAKPOINT: { + int line=code_editor->get_text_edit()->cursor_get_line(); + bool dobreak = !code_editor->get_text_edit()->is_line_set_as_breakpoint(line); + code_editor->get_text_edit()->set_line_as_breakpoint(line,dobreak); + ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(get_edited_script()->get_path(),line+1,dobreak); + } break; + case DEBUG_REMOVE_ALL_BREAKPOINTS: { + List<int> bpoints; + code_editor->get_text_edit()->get_breakpoints(&bpoints); + + for(List<int>::Element *E=bpoints.front();E;E=E->next()) { + int line = E->get(); + bool dobreak = !code_editor->get_text_edit()->is_line_set_as_breakpoint(line); + code_editor->get_text_edit()->set_line_as_breakpoint(line,dobreak); + ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(get_edited_script()->get_path(),line+1,dobreak); + } + } + case DEBUG_GOTO_NEXT_BREAKPOINT: { + List<int> bpoints; + code_editor->get_text_edit()->get_breakpoints(&bpoints); + if (bpoints.size() <= 0) { + return; + } + + int line=code_editor->get_text_edit()->cursor_get_line(); + // wrap around + if (line >= bpoints[bpoints.size() - 1]) { + code_editor->get_text_edit()->cursor_set_line(bpoints[0]); + } else { + for(List<int>::Element *E=bpoints.front();E;E=E->next()) { + int bline = E->get(); + if (bline > line) { + code_editor->get_text_edit()->cursor_set_line(bline); + return; + } + } + } + + } break; + case DEBUG_GOTO_PREV_BREAKPOINT: { + List<int> bpoints; + code_editor->get_text_edit()->get_breakpoints(&bpoints); + if (bpoints.size() <= 0) { + return; + } + + int line=code_editor->get_text_edit()->cursor_get_line(); + // wrap around + if (line <= bpoints[0]) { + code_editor->get_text_edit()->cursor_set_line(bpoints[bpoints.size() - 1]); + } else { + for(List<int>::Element *E=bpoints.back();E;E=E->prev()) { + int bline = E->get(); + if (bline < line) { + code_editor->get_text_edit()->cursor_set_line(bline); + return; + } + } + } + + } break; + + case HELP_CONTEXTUAL: { + String text = code_editor->get_text_edit()->get_selection_text(); + if (text == "") + text = code_editor->get_text_edit()->get_word_under_cursor(); + if (text != "") { + emit_signal("request_help_search",text); + } + } break; + } +} + +void ScriptTextEditor::_bind_methods() { + + ClassDB::bind_method("_validate_script",&ScriptTextEditor::_validate_script); + ClassDB::bind_method("_load_theme_settings",&ScriptTextEditor::_load_theme_settings); + ClassDB::bind_method("_breakpoint_toggled",&ScriptTextEditor::_breakpoint_toggled); + ClassDB::bind_method("_edit_option",&ScriptTextEditor::_edit_option); + ClassDB::bind_method("_goto_line",&ScriptTextEditor::_goto_line); + ClassDB::bind_method("_lookup_symbol",&ScriptTextEditor::_lookup_symbol); + ClassDB::bind_method("_text_edit_gui_input", &ScriptTextEditor::_text_edit_gui_input); + ClassDB::bind_method("_color_changed", &ScriptTextEditor::_color_changed); + + + ClassDB::bind_method("get_drag_data_fw",&ScriptTextEditor::get_drag_data_fw); + ClassDB::bind_method("can_drop_data_fw",&ScriptTextEditor::can_drop_data_fw); + ClassDB::bind_method("drop_data_fw",&ScriptTextEditor::drop_data_fw); + +} + +Control *ScriptTextEditor::get_edit_menu() { + + return edit_hb; +} + +void ScriptTextEditor::reload(bool p_soft) { + + TextEdit *te = code_editor->get_text_edit(); + Ref<Script> scr = get_edited_script(); + if (scr.is_null()) + return; + scr->set_source_code(te->get_text()); + bool soft = p_soft || scr->get_instance_base_type()=="EditorPlugin"; //always soft-reload editor plugins + + scr->get_language()->reload_tool_script(scr,soft); +} + +void ScriptTextEditor::get_breakpoints(List<int> *p_breakpoints) { + + code_editor->get_text_edit()->get_breakpoints(p_breakpoints); + +} + +void ScriptTextEditor::set_tooltip_request_func(String p_method,Object* p_obj) { + + code_editor->get_text_edit()->set_tooltip_request_func(p_obj,p_method,this); +} + +void ScriptTextEditor::set_debugger_active(bool p_active) { + + +} + + +Variant ScriptTextEditor::get_drag_data_fw(const Point2& p_point,Control* p_from) { + + return Variant(); +} + +bool ScriptTextEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const{ + + Dictionary d = p_data; + if (d.has("type") && + ( + + String(d["type"])=="resource" || + String(d["type"])=="files" || + String(d["type"])=="nodes" + ) ) { + + + return true; + } + + + return false; + +} + +#ifdef TOOLS_ENABLED + +static Node* _find_script_node(Node* p_edited_scene,Node* p_current_node,const Ref<Script> &script) { + + if (p_edited_scene!=p_current_node && p_current_node->get_owner()!=p_edited_scene) + return NULL; + + Ref<Script> scr = p_current_node->get_script(); + + if (scr.is_valid() && scr==script) + return p_current_node; + + for(int i=0;i<p_current_node->get_child_count();i++) { + Node *n = _find_script_node(p_edited_scene,p_current_node->get_child(i),script); + if (n) + return n; + } + + return NULL; +} + +#else + +static Node* _find_script_node(Node* p_edited_scene,Node* p_current_node,const Ref<Script> &script) { + + return NULL; +} +#endif + + + + +void ScriptTextEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from){ + + Dictionary d = p_data; + + if (d.has("type") && String(d["type"])=="resource") { + + Ref<Resource> res = d["resource"]; + if (!res.is_valid()) { + return; + } + + if (res->get_path().is_resource_file()) { + EditorNode::get_singleton()->show_warning("Only resources from filesystem can be dropped."); + return; + } + + code_editor->get_text_edit()->insert_text_at_cursor(res->get_path()); + + } + + if (d.has("type") && String(d["type"])=="files") { + + + Array files = d["files"]; + + String text_to_drop; + for(int i=0;i<files.size();i++) { + + if (i>0) + text_to_drop+=","; + text_to_drop+="\""+String(files[i]).c_escape()+"\""; + + } + + code_editor->get_text_edit()->insert_text_at_cursor(text_to_drop); + + } + + if (d.has("type") && String(d["type"])=="nodes") { + + Node* sn = _find_script_node(get_tree()->get_edited_scene_root(),get_tree()->get_edited_scene_root(),script); + + + if (!sn) { + EditorNode::get_singleton()->show_warning("Can't drop nodes because script '"+get_name()+"' is not used in this scene."); + return; + } + + + Array nodes = d["nodes"]; + String text_to_drop; + for(int i=0;i<nodes.size();i++) { + + if (i>0) + text_to_drop+=","; + + NodePath np = nodes[i]; + Node *node = get_node(np); + if (!node) { + continue; + } + + + + String path = sn->get_path_to(node); + text_to_drop+="\""+path.c_escape()+"\""; + + + } + + code_editor->get_text_edit()->insert_text_at_cursor(text_to_drop); + + + } + + + +} + +void ScriptTextEditor::_text_edit_gui_input(const InputEvent& ev) { + if (ev.type == InputEvent::MOUSE_BUTTON) { + InputEventMouseButton mb = ev.mouse_button; + if (mb.button_index == BUTTON_RIGHT && !mb.pressed) { + + int col, row; + TextEdit* tx = code_editor->get_text_edit(); + tx->_get_mouse_pos(Point2i(mb.global_x, mb.global_y)-tx->get_global_pos(), row, col); + Vector2 mpos = Vector2(mb.global_x, mb.global_y)-tx->get_global_pos(); + bool have_selection = (tx->get_selection_text().length() > 0); + bool have_color = (tx->get_word_at_pos(mpos) == "Color"); + if (have_color) { + + String line = tx->get_line(row); + color_line = row; + int begin = 0; + int end = 0; + bool valid = false; + for (int i = col; i < line.length(); i++) { + if (line[i] == '(') { + begin = i; + continue; + } + else if (line[i] == ')') { + end = i+1; + valid = true; + break; + } + } + if (valid) { + color_args = line.substr(begin, end-begin); + String stripped = color_args.replace(" ", "").replace("(", "").replace(")", ""); + Vector<float> color = stripped.split_floats(","); + if (color.size() > 2) { + float alpha = color.size() > 3 ? color[3] : 1.0f; + color_picker->set_pick_color(Color(color[0], color[1], color[2], alpha)); + } + color_panel->set_pos(get_global_transform().xform(get_local_mouse_pos())); + Size2 ms = Size2(300, color_picker->get_combined_minimum_size().height+10); + color_panel->set_size(ms); + } else { + have_color = false; + } + } + _make_context_menu(have_selection, have_color); + } + } +} + +void ScriptTextEditor::_color_changed(const Color& p_color) { + String new_args; + if (p_color.a == 1.0f) { + new_args = String("("+rtos(p_color.r)+", "+rtos(p_color.g)+", "+rtos(p_color.b)+")"); + } else { + new_args = String("("+rtos(p_color.r)+", "+rtos(p_color.g)+", "+rtos(p_color.b)+", "+rtos(p_color.a)+")"); + } + + String line = code_editor->get_text_edit()->get_line(color_line); + String new_line = line.replace(color_args, new_args); + color_args = new_args; + code_editor->get_text_edit()->set_line(color_line, new_line); +} + +void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color) { + + context_menu->clear(); + if (p_selection) { + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); + } + + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + context_menu->add_separator(); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + + if (p_selection) { + context_menu->add_separator(); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); + } + if (p_color) { + context_menu->add_separator(); + context_menu->add_item(TTR("Pick Color"), EDIT_PICK_COLOR); + } + context_menu->set_pos(get_global_transform().xform(get_local_mouse_pos())); + context_menu->set_size(Vector2(1, 1)); + context_menu->popup(); +} + +ScriptTextEditor::ScriptTextEditor() { + + code_editor = memnew( CodeTextEditor ); + add_child(code_editor); + code_editor->set_area_as_parent_rect(); + code_editor->connect("validate_script",this,"_validate_script"); + code_editor->connect("load_theme_settings",this,"_load_theme_settings"); + code_editor->set_code_complete_func(_code_complete_scripts,this); + code_editor->get_text_edit()->connect("breakpoint_toggled", this, "_breakpoint_toggled"); + code_editor->get_text_edit()->connect("symbol_lookup", this, "_lookup_symbol"); + + update_settings(); + + code_editor->get_text_edit()->set_callhint_settings( + EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line"), + EditorSettings::get_singleton()->get("text_editor/completion/callhint_tooltip_offset")); + + code_editor->get_text_edit()->set_select_identifiers_on_hover(true); + code_editor->get_text_edit()->set_context_menu_enabled(false); + code_editor->get_text_edit()->connect("gui_input", this, "_text_edit_gui_input"); + + context_menu = memnew(PopupMenu); + add_child(context_menu); + context_menu->connect("id_pressed", this, "_edit_option"); + + color_panel = memnew(PopupPanel); + add_child(color_panel); + color_picker = memnew(ColorPicker); + color_panel->add_child(color_picker); + color_panel->set_child_rect(color_picker); //NOT + color_picker->connect("color_changed", this, "_color_changed"); + + edit_hb = memnew (HBoxContainer); + + edit_menu = memnew( MenuButton ); + edit_menu->set_text(TTR("Edit")); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + edit_menu->get_popup()->add_separator(); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + edit_menu->get_popup()->add_separator(); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); + edit_menu->get_popup()->add_separator(); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN); + edit_menu->get_popup()->add_separator(); +#ifdef OSX_ENABLED + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE); +#else + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE); +#endif + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/auto_indent"), EDIT_AUTO_INDENT); + edit_menu->get_popup()->connect("id_pressed", this,"_edit_option"); + edit_menu->get_popup()->add_separator(); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_breakpoint"), DEBUG_TOGGLE_BREAKPOINT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_breakpoints"), DEBUG_REMOVE_ALL_BREAKPOINTS); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_breakpoint"), DEBUG_GOTO_NEXT_BREAKPOINT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_breakpoint"), DEBUG_GOTO_PREV_BREAKPOINT); + + search_menu = memnew( MenuButton ); + edit_hb->add_child(search_menu); + search_menu->set_text(TTR("Search")); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE); + search_menu->get_popup()->add_separator(); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_function"), SEARCH_LOCATE_FUNCTION); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE); + search_menu->get_popup()->add_separator(); + search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/contextual_help"), HELP_CONTEXTUAL); + + search_menu->get_popup()->connect("id_pressed", this,"_edit_option"); + + edit_hb->add_child(edit_menu); + + quick_open = memnew( ScriptEditorQuickOpen ); + add_child(quick_open); + quick_open->connect("goto_line",this,"_goto_line"); + + goto_line_dialog = memnew(GotoLineDialog); + add_child(goto_line_dialog); + + + code_editor->get_text_edit()->set_drag_forwarding(this); +} + +static ScriptEditorBase * create_editor(const Ref<Script>& p_script) { + + if (p_script->has_source_code()) { + return memnew( ScriptTextEditor ); + } + + return NULL; +} + +void ScriptTextEditor::register_editor() { + + ED_SHORTCUT("script_text_editor/undo", TTR("Undo"), KEY_MASK_CMD|KEY_Z); + ED_SHORTCUT("script_text_editor/redo", TTR("Redo"), KEY_MASK_CMD|KEY_Y); + ED_SHORTCUT("script_text_editor/cut", TTR("Cut"), KEY_MASK_CMD|KEY_X); + ED_SHORTCUT("script_text_editor/copy", TTR("Copy"), KEY_MASK_CMD|KEY_C); + ED_SHORTCUT("script_text_editor/paste", TTR("Paste"), KEY_MASK_CMD|KEY_V); + ED_SHORTCUT("script_text_editor/select_all", TTR("Select All"), KEY_MASK_CMD|KEY_A); + ED_SHORTCUT("script_text_editor/move_up", TTR("Move Up"), KEY_MASK_ALT|KEY_UP); + ED_SHORTCUT("script_text_editor/move_down", TTR("Move Down"), KEY_MASK_ALT|KEY_DOWN); + + //leave these at zero, same can be accomplished with tab/shift-tab, including selection + //the next/previous in history shortcut in this case makes a lot more sene. + + ED_SHORTCUT("script_text_editor/indent_left", TTR("Indent Left"), 0); + ED_SHORTCUT("script_text_editor/indent_right", TTR("Indent Right"), 0); + ED_SHORTCUT("script_text_editor/toggle_comment", TTR("Toggle Comment"), KEY_MASK_CMD|KEY_K); + ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD|KEY_B); +#ifdef OSX_ENABLED + ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CTRL|KEY_SPACE); +#else + ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD|KEY_SPACE); +#endif + ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CTRL|KEY_MASK_ALT|KEY_T); + ED_SHORTCUT("script_text_editor/auto_indent", TTR("Auto Indent"), KEY_MASK_CMD|KEY_I); + + ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9); + ED_SHORTCUT("script_text_editor/remove_all_breakpoints", TTR("Remove All Breakpoints"), KEY_MASK_CTRL|KEY_MASK_SHIFT|KEY_F9); + ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Goto Next Breakpoint"), KEY_MASK_CTRL|KEY_PERIOD); + ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Goto Previous Breakpoint"), KEY_MASK_CTRL|KEY_COMMA); + + ED_SHORTCUT("script_text_editor/find", TTR("Find.."), KEY_MASK_CMD|KEY_F); + ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), KEY_F3); + ED_SHORTCUT("script_text_editor/find_previous", TTR("Find Previous"), KEY_MASK_SHIFT|KEY_F3); + ED_SHORTCUT("script_text_editor/replace", TTR("Replace.."), KEY_MASK_CMD|KEY_R); + + ED_SHORTCUT("script_text_editor/goto_function", TTR("Goto Function.."), KEY_MASK_SHIFT|KEY_MASK_CMD|KEY_F); + ED_SHORTCUT("script_text_editor/goto_line", TTR("Goto Line.."), KEY_MASK_CMD|KEY_L); + + ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_SHIFT|KEY_F1); + + ScriptEditor::register_create_script_editor_function(create_editor); +} diff --git a/tools/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index e30a78340e..e30a78340e 100644 --- a/tools/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp new file mode 100644 index 0000000000..c14d1650fd --- /dev/null +++ b/editor/plugins/shader_editor_plugin.cpp @@ -0,0 +1,584 @@ +/*************************************************************************/ +/* shader_editor_plugin.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 "shader_editor_plugin.h" + +#include "editor/editor_settings.h" +#include "spatial_editor_plugin.h" +#include "scene/resources/shader_graph.h" +#include "io/resource_loader.h" +#include "io/resource_saver.h" +#include "os/keyboard.h" +#include "editor/editor_node.h" +#include "editor/property_editor.h" +#include "os/os.h" +#include "servers/visual/shader_types.h" + +/*** SETTINGS EDITOR ****/ + + + + +/*** SCRIPT EDITOR ****/ + + +Ref<Shader> ShaderTextEditor::get_edited_shader() const { + + return shader; +} +void ShaderTextEditor::set_edited_shader(const Ref<Shader>& p_shader) { + + shader=p_shader; + + + _load_theme_settings(); + + get_text_edit()->set_text(p_shader->get_code()); + + _line_col_changed(); + + +} + + +void ShaderTextEditor::_load_theme_settings() { + + get_text_edit()->clear_colors(); + + /* keyword color */ + + get_text_edit()->add_color_override("background_color", EDITOR_DEF("text_editor/highlighting/background_color",Color(0,0,0,0))); + get_text_edit()->add_color_override("completion_background_color", EDITOR_DEF("text_editor/highlighting/completion_background_color", Color(0,0,0,0))); + get_text_edit()->add_color_override("completion_selected_color", EDITOR_DEF("text_editor/highlighting/completion_selected_color", Color::html("434244"))); + get_text_edit()->add_color_override("completion_existing_color", EDITOR_DEF("text_editor/highlighting/completion_existing_color", Color::html("21dfdfdf"))); + get_text_edit()->add_color_override("completion_scroll_color", EDITOR_DEF("text_editor/highlighting/completion_scroll_color", Color::html("ffffff"))); + get_text_edit()->add_color_override("completion_font_color", EDITOR_DEF("text_editor/highlighting/completion_font_color", Color::html("aaaaaa"))); + get_text_edit()->add_color_override("font_color",EDITOR_DEF("text_editor/highlighting/text_color",Color(0,0,0))); + get_text_edit()->add_color_override("line_number_color",EDITOR_DEF("text_editor/highlighting/line_number_color",Color(0,0,0))); + get_text_edit()->add_color_override("caret_color",EDITOR_DEF("text_editor/highlighting/caret_color",Color(0,0,0))); + get_text_edit()->add_color_override("caret_background_color",EDITOR_DEF("text_editor/highlighting/caret_background_color",Color(0,0,0))); + get_text_edit()->add_color_override("font_selected_color",EDITOR_DEF("text_editor/highlighting/text_selected_color",Color(1,1,1))); + get_text_edit()->add_color_override("selection_color",EDITOR_DEF("text_editor/highlighting/selection_color",Color(0.2,0.2,1))); + get_text_edit()->add_color_override("brace_mismatch_color",EDITOR_DEF("text_editor/highlighting/brace_mismatch_color",Color(1,0.2,0.2))); + get_text_edit()->add_color_override("current_line_color",EDITOR_DEF("text_editor/highlighting/current_line_color",Color(0.3,0.5,0.8,0.15))); + get_text_edit()->add_color_override("word_highlighted_color",EDITOR_DEF("text_editor/highlighting/word_highlighted_color",Color(0.8,0.9,0.9,0.15))); + get_text_edit()->add_color_override("number_color",EDITOR_DEF("text_editor/highlighting/number_color",Color(0.9,0.6,0.0,2))); + get_text_edit()->add_color_override("function_color",EDITOR_DEF("text_editor/highlighting/function_color",Color(0.4,0.6,0.8))); + get_text_edit()->add_color_override("member_variable_color",EDITOR_DEF("text_editor/highlighting/member_variable_color",Color(0.9,0.3,0.3))); + get_text_edit()->add_color_override("mark_color", EDITOR_DEF("text_editor/highlighting/mark_color", Color(1.0,0.4,0.4,0.4))); + get_text_edit()->add_color_override("breakpoint_color", EDITOR_DEF("text_editor/highlighting/breakpoint_color", Color(0.8,0.8,0.4,0.2))); + get_text_edit()->add_color_override("search_result_color",EDITOR_DEF("text_editor/highlighting/search_result_color",Color(0.05,0.25,0.05,1))); + get_text_edit()->add_color_override("search_result_border_color",EDITOR_DEF("text_editor/highlighting/search_result_border_color",Color(0.1,0.45,0.1,1))); + get_text_edit()->add_color_override("symbol_color",EDITOR_DEF("text_editor/highlighting/symbol_color",Color::hex(0x005291ff))); + + Color keyword_color= EDITOR_DEF("text_editor/highlighting/keyword_color",Color(0.5,0.0,0.2)); + + + List<String> keywords; + ShaderLanguage::get_keyword_list(&keywords); + + if (shader.is_valid()) { + + + for(const Map< StringName, Map<StringName,ShaderLanguage::DataType> >::Element *E=ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())).front();E;E=E->next()) { + + for (const Map<StringName,ShaderLanguage::DataType>::Element *F=E->get().front();F;F=F->next()) { + keywords.push_back(F->key()); + } + + } + + for(const Set<String>::Element *E =ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())).front();E;E=E->next()) { + + keywords.push_back(E->get()); + + } + } + + + for(List<String>::Element *E=keywords.front();E;E=E->next()) { + + get_text_edit()->add_keyword_color(E->get(),keyword_color); + } + + //colorize core types + //Color basetype_color= EDITOR_DEF("text_editor/base_type_color",Color(0.3,0.3,0.0)); + + + //colorize comments + Color comment_color = EDITOR_DEF("text_editor/highlighting/comment_color",Color::hex(0x797e7eff)); + + get_text_edit()->add_color_region("/*","*/",comment_color,false); + get_text_edit()->add_color_region("//","",comment_color,false); + + /*//colorize strings + Color string_color = EDITOR_DEF("text_editor/string_color",Color::hex(0x6b6f00ff)); + + List<String> strings; + shader->get_shader_mode()->get_string_delimiters(&strings); + + for (List<String>::Element *E=strings.front();E;E=E->next()) { + + String string = E->get(); + String beg = string.get_slice(" ",0); + String end = string.get_slice_count(" ")>1?string.get_slice(" ",1):String(); + get_text_edit()->add_color_region(beg,end,string_color,end==""); + }*/ +} + +void ShaderTextEditor::_code_complete_script(const String& p_code, List<String>* r_options) { + + print_line("code complete"); + + ShaderLanguage sl; + String calltip; + + Error err = sl.complete(p_code,ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())),ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())),r_options,calltip); + + if (calltip!="") { + get_text_edit()->set_code_hint(calltip); + } +} + +void ShaderTextEditor::_validate_script() { + + String code=get_text_edit()->get_text(); + //List<StringName> params; + //shader->get_param_list(¶ms); + + ShaderLanguage sl; + + Error err = sl.compile(code,ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())),ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode()))); + + if (err!=OK) { + String error_text="error("+itos(sl.get_error_line())+"): "+sl.get_error_text(); + set_error(error_text); + get_text_edit()->set_line_as_marked(sl.get_error_line(),true); + + } else { + for(int i=0;i<get_text_edit()->get_line_count();i++) + get_text_edit()->set_line_as_marked(i,false); + set_error(""); + } + + emit_signal("script_changed"); +} + +void ShaderTextEditor::_bind_methods() { + + + //ADD_SIGNAL( MethodInfo("script_changed") ); + +} + +ShaderTextEditor::ShaderTextEditor() { + + +} + +/*** SCRIPT EDITOR ******/ + + + +void ShaderEditor::_menu_option(int p_option) { + + + ShaderTextEditor *current = shader_editor; + + switch(p_option) { + case EDIT_UNDO: { + + + current->get_text_edit()->undo(); + } break; + case EDIT_REDO: { + current->get_text_edit()->redo(); + + } break; + case EDIT_CUT: { + + current->get_text_edit()->cut(); + } break; + case EDIT_COPY: { + current->get_text_edit()->copy(); + + } break; + case EDIT_PASTE: { + current->get_text_edit()->paste(); + + } break; + case EDIT_SELECT_ALL: { + + current->get_text_edit()->select_all(); + + } break; + case SEARCH_FIND: { + + current->get_find_replace_bar()->popup_search(); + } break; + case SEARCH_FIND_NEXT: { + + current->get_find_replace_bar()->search_next(); + } break; + case SEARCH_FIND_PREV: { + + current->get_find_replace_bar()->search_prev(); + } break; + case SEARCH_REPLACE: { + + current->get_find_replace_bar()->popup_replace(); + } break; + //case SEARCH_LOCATE_SYMBOL: { + + //} break; + case SEARCH_GOTO_LINE: { + + goto_line_dialog->popup_find_line(current->get_text_edit()); + } break; + + } +} + + +void ShaderEditor::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + + + } + if (p_what==NOTIFICATION_DRAW) { + + RID ci = get_canvas_item(); + Ref<StyleBox> style = get_stylebox("panel","Panel"); + style->draw( ci, Rect2( Point2(), get_size() ) ); + + } + +} + + + +Dictionary ShaderEditor::get_state() const { +#if 0 + apply_shaders(); + + Dictionary state; + + Array paths; + int open=-1; + + for(int i=0;i<tab_container->get_child_count();i++) { + + ShaderTextEditor *ste = tab_container->get_child(i)->cast_to<ShaderTextEditor>(); + if (!ste) + continue; + + + Ref<Shader> shader = ste->get_edited_shader(); + if (shader->get_path()!="" && shader->get_path().find("local://")==-1 && shader->get_path().find("::")==-1) { + + paths.push_back(shader->get_path()); + } else { + + + const Node *owner = _find_node_with_shader(get_root_node(),shader.get_ref_ptr()); + if (owner) + paths.push_back(owner->get_path()); + + } + + if (i==tab_container->get_current_tab()) + open=i; + } + + if (paths.size()) + state["sources"]=paths; + if (open!=-1) + state["current"]=open; + + + return state; +#endif + return Dictionary(); +} +void ShaderEditor::set_state(const Dictionary& p_state) { +#if 0 + print_line("setting state.."); + if (!p_state.has("sources")) + return; //bleh + + Array sources = p_state["sources"]; + for(int i=0;i<sources.size();i++) { + + Variant source=sources[i]; + + Ref<Shader> shader; + + if (source.get_type()==Variant::NODE_PATH) { + + print_line("cain find owner at path "+String(source)); + Node *owner=get_root_node()->get_node(source); + if (!owner) + continue; + + shader = owner->get_shader(); + } else if (source.get_type()==Variant::STRING) { + + print_line("loading at path "+String(source)); + shader = ResourceLoader::load(source,"Shader"); + } + + print_line("found shader at "+String(source)+"? - "+itos(shader.is_null())); + if (shader.is_null()) //ah well.. + continue; + + get_scene()->get_root_node()->call("_resource_selected",shader); + } + + if (p_state.has("current")) + tab_container->set_current_tab(p_state["current"]); +#endif +} +void ShaderEditor::clear() { + +} + +void ShaderEditor::_params_changed() { + + + shader_editor->_validate_script(); +} + +void ShaderEditor::_editor_settings_changed() { + + shader_editor->get_text_edit()->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/completion/auto_brace_complete")); + shader_editor->get_text_edit()->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file")); + shader_editor->get_text_edit()->set_tab_size(EditorSettings::get_singleton()->get("text_editor/indent/tab_size")); + shader_editor->get_text_edit()->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/indent/draw_tabs")); + shader_editor->get_text_edit()->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_numbers")); + shader_editor->get_text_edit()->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/highlighting/syntax_highlighting")); + shader_editor->get_text_edit()->set_highlight_all_occurrences(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_all_occurrences")); + shader_editor->get_text_edit()->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink")); + shader_editor->get_text_edit()->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed")); + shader_editor->get_text_edit()->add_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/theme/line_spacing")); + shader_editor->get_text_edit()->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret")); +} + +void ShaderEditor::_bind_methods() { + + ClassDB::bind_method("_editor_settings_changed",&ShaderEditor::_editor_settings_changed); + + ClassDB::bind_method("_menu_option",&ShaderEditor::_menu_option); + ClassDB::bind_method("_params_changed",&ShaderEditor::_params_changed); + ClassDB::bind_method("apply_shaders",&ShaderEditor::apply_shaders); + //ClassDB::bind_method("_close_current_tab",&ShaderEditor::_close_current_tab); +} + +void ShaderEditor::ensure_select_current() { + +/* + if (tab_container->get_child_count() && tab_container->get_current_tab()>=0) { + + ShaderTextEditor *ste = tab_container->get_child(tab_container->get_current_tab())->cast_to<ShaderTextEditor>(); + if (!ste) + return; + Ref<Shader> shader = ste->get_edited_shader(); + get_scene()->get_root_node()->call("_resource_selected",shader); + }*/ +} + +void ShaderEditor::edit(const Ref<Shader>& p_shader) { + + if (p_shader.is_null()) + return; + + + shader=p_shader; + + shader_editor->set_edited_shader(p_shader); + + //vertex_editor->set_edited_shader(shader,ShaderLanguage::SHADER_MATERIAL_VERTEX); + // see if already has it + + +} + +void ShaderEditor::save_external_data() { + + if (shader.is_null()) + return; + apply_shaders(); + + if (shader->get_path()!="" && shader->get_path().find("local://")==-1 &&shader->get_path().find("::")==-1) { + //external shader, save it + ResourceSaver::save(shader->get_path(),shader); + } +} + +void ShaderEditor::apply_shaders() { + + + if (shader.is_valid()) { + shader->set_code(shader_editor->get_text_edit()->get_text()); + shader->set_edited(true); + } +} + + +ShaderEditor::ShaderEditor() { + + + HBoxContainer *hbc = memnew( HBoxContainer); + + add_child(hbc); + + edit_menu = memnew( MenuButton ); + hbc->add_child(edit_menu); + edit_menu->set_pos(Point2(5,-1)); + edit_menu->set_text(TTR("Edit")); + edit_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/undo", TTR("Undo"), KEY_MASK_CMD|KEY_Z), EDIT_UNDO); + edit_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/redo", TTR("Redo"), KEY_MASK_CMD|KEY_Y), EDIT_REDO); + edit_menu->get_popup()->add_separator(); + edit_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/cut", TTR("Cut"), KEY_MASK_CMD|KEY_X), EDIT_CUT); + edit_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/copy", TTR("Copy"), KEY_MASK_CMD|KEY_C), EDIT_COPY); + edit_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/paste", TTR("Paste"), KEY_MASK_CMD|KEY_V), EDIT_PASTE); + edit_menu->get_popup()->add_separator(); + edit_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/select_all", TTR("Select All"), KEY_MASK_CMD|KEY_A), EDIT_SELECT_ALL); + edit_menu->get_popup()->connect("id_pressed", this,"_menu_option"); + + + search_menu = memnew( MenuButton ); + hbc->add_child(search_menu); + search_menu->set_pos(Point2(38,-1)); + search_menu->set_text(TTR("Search")); + search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find", TTR("Find.."), KEY_MASK_CMD|KEY_F), SEARCH_FIND); + search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_next", TTR("Find Next"), KEY_F3), SEARCH_FIND_NEXT); + search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_previous", TTR("Find Previous"), KEY_MASK_SHIFT|KEY_F3), SEARCH_FIND_PREV); + search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/replace", TTR("Replace.."), KEY_MASK_CMD|KEY_R), SEARCH_REPLACE); + search_menu->get_popup()->add_separator(); + //search_menu->get_popup()->add_item("Locate Symbol..",SEARCH_LOCATE_SYMBOL,KEY_MASK_CMD|KEY_K); + search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/goto_line", TTR("Goto Line.."), KEY_MASK_CMD|KEY_L), SEARCH_GOTO_LINE); + search_menu->get_popup()->connect("id_pressed", this,"_menu_option"); + + + goto_line_dialog = memnew(GotoLineDialog); + add_child(goto_line_dialog); + + shader_editor = memnew( ShaderTextEditor ); + add_child(shader_editor); + shader_editor->set_v_size_flags(SIZE_EXPAND_FILL); + + + shader_editor->connect("script_changed", this,"apply_shaders"); + EditorSettings::get_singleton()->connect("settings_changed",this,"_editor_settings_changed"); + + _editor_settings_changed(); +} + + +void ShaderEditorPlugin::edit(Object *p_object) { + + Shader* s = p_object->cast_to<Shader>(); + shader_editor->edit(s); + +} + +bool ShaderEditorPlugin::handles(Object *p_object) const { + + bool handles = true; + Shader *shader=p_object->cast_to<Shader>(); + /* + if (!shader || shader->cast_to<ShaderGraph>()) // Dont handle ShaderGraph's + handles = false; + */ + + return shader!=NULL; +} + +void ShaderEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + button->show(); + editor->make_bottom_panel_item_visible(shader_editor); + + } else { + + button->hide(); + if (shader_editor->is_visible_in_tree()) + editor->hide_bottom_panel(); + shader_editor->apply_shaders(); + + } + +} + +void ShaderEditorPlugin::selected_notify() { + + shader_editor->ensure_select_current(); +} + +Dictionary ShaderEditorPlugin::get_state() const { + + return shader_editor->get_state(); +} + +void ShaderEditorPlugin::set_state(const Dictionary& p_state) { + + shader_editor->set_state(p_state); +} +void ShaderEditorPlugin::clear() { + + shader_editor->clear(); +} + +void ShaderEditorPlugin::save_external_data() { + + shader_editor->save_external_data(); +} + +void ShaderEditorPlugin::apply_changes() { + + shader_editor->apply_shaders(); +} + +ShaderEditorPlugin::ShaderEditorPlugin(EditorNode *p_node) { + + + editor=p_node; + shader_editor = memnew( ShaderEditor ); + + shader_editor->set_custom_minimum_size(Size2(0,300)); + button=editor->add_bottom_panel_item("Shader",shader_editor); + +} + + +ShaderEditorPlugin::~ShaderEditorPlugin() { +} + + diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h new file mode 100644 index 0000000000..703913e431 --- /dev/null +++ b/editor/plugins/shader_editor_plugin.h @@ -0,0 +1,156 @@ +/*************************************************************************/ +/* shader_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef SHADER_EDITOR_PLUGIN_H +#define SHADER_EDITOR_PLUGIN_H + +#include "editor/code_editor.h" +#include "editor/editor_plugin.h" +#include "scene/gui/tab_container.h" +#include "scene/gui/text_edit.h" +#include "scene/gui/menu_button.h" +#include "scene/main/timer.h" +#include "scene/resources/shader.h" +#include "servers/visual/shader_language.h" + +class ShaderTextEditor : public CodeTextEditor { + + GDCLASS( ShaderTextEditor, CodeTextEditor ); + + Ref<Shader> shader; + +protected: + + static void _bind_methods(); + virtual void _load_theme_settings(); + + virtual void _code_complete_script(const String& p_code, List<String>* r_options); + +public: + + virtual void _validate_script(); + + + Ref<Shader> get_edited_shader() const; + void set_edited_shader(const Ref<Shader>& p_shader); + ShaderTextEditor(); + +}; + + +class ShaderEditor : public VBoxContainer { + + GDCLASS(ShaderEditor, VBoxContainer ); + + enum { + + EDIT_UNDO, + EDIT_REDO, + EDIT_CUT, + EDIT_COPY, + EDIT_PASTE, + EDIT_SELECT_ALL, + SEARCH_FIND, + SEARCH_FIND_NEXT, + SEARCH_FIND_PREV, + SEARCH_REPLACE, + //SEARCH_LOCATE_SYMBOL, + SEARCH_GOTO_LINE, + + }; + + MenuButton *edit_menu; + MenuButton *search_menu; + MenuButton *settings_menu; + uint64_t idle; + + GotoLineDialog *goto_line_dialog; + ConfirmationDialog *erase_tab_confirm; + + + ShaderTextEditor *shader_editor; + + + void _menu_option(int p_optin); + void _params_changed(); + mutable Ref<Shader> shader; + + + void _editor_settings_changed(); + +protected: + void _notification(int p_what); + static void _bind_methods(); +public: + + void apply_shaders(); + + void ensure_select_current(); + void edit(const Ref<Shader>& p_shader); + + Dictionary get_state() const; + void set_state(const Dictionary& p_state); + void clear(); + + virtual Size2 get_minimum_size() const { return Size2(0,200); } + void save_external_data(); + + ShaderEditor(); +}; + +class ShaderEditorPlugin : public EditorPlugin { + + GDCLASS( ShaderEditorPlugin, EditorPlugin ); + + bool _2d; + ShaderEditor *shader_editor; + EditorNode *editor; + Button *button; + +public: + + virtual String get_name() const { return "Shader"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + virtual void selected_notify(); + + Dictionary get_state() const; + virtual void set_state(const Dictionary& p_state); + virtual void clear(); + + virtual void save_external_data(); + virtual void apply_changes(); + + ShaderEditorPlugin(EditorNode *p_node); + ~ShaderEditorPlugin(); + +}; + +#endif diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/editor/plugins/shader_graph_editor_plugin.cpp index dac63b4a9f..dac63b4a9f 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.cpp +++ b/editor/plugins/shader_graph_editor_plugin.cpp diff --git a/editor/plugins/shader_graph_editor_plugin.h b/editor/plugins/shader_graph_editor_plugin.h new file mode 100644 index 0000000000..5143722242 --- /dev/null +++ b/editor/plugins/shader_graph_editor_plugin.h @@ -0,0 +1,242 @@ +/*************************************************************************/ +/* shader_graph_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef SHADER_GRAPH_EDITOR_PLUGIN_H +#define SHADER_GRAPH_EDITOR_PLUGIN_H + + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/resources/shader.h" +#include "scene/gui/tree.h" +#include "scene/gui/button.h" +#include "scene/gui/graph_edit.h" +#include "scene/gui/popup.h" +#include "editor/property_editor.h" +#include "scene/resources/shader_graph.h" +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +#if 0 +class GraphColorRampEdit : public Control { + + GDCLASS(GraphColorRampEdit,Control); + + + struct Point { + + float offset; + Color color; + bool operator<(const Point& p_ponit) const { + return offset<p_ponit.offset; + } + }; + + PopupPanel *popup; + ColorPicker *picker; + + + bool grabbing; + int grabbed; + float grabbed_at; + Vector<Point> points; + + void _color_changed(const Color& p_color); + +protected: + void _gui_input(const InputEvent& p_event); + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_ramp(const Vector<float>& p_offsets,const Vector<Color>& p_colors); + Vector<float> get_offsets() const; + Vector<Color> get_colors() const; + virtual Size2 get_minimum_size() const; + GraphColorRampEdit(); +}; + + +class GraphCurveMapEdit : public Control { + + GDCLASS(GraphCurveMapEdit,Control); + + + struct Point { + + float offset; + float height; + bool operator<(const Point& p_ponit) const { + return offset<p_ponit.offset; + } + }; + + + bool grabbing; + int grabbed; + Vector<Point> points; + + void _plot_curve(const Vector2& p_a,const Vector2& p_b,const Vector2& p_c,const Vector2& p_d); +protected: + void _gui_input(const InputEvent& p_event); + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_points(const Vector<Vector2>& p_points); + Vector<Vector2> get_points() const; + virtual Size2 get_minimum_size() const; + GraphCurveMapEdit(); +}; + +class ShaderGraphView : public Control { + + GDCLASS(ShaderGraphView,Control); + + + + CustomPropertyEditor *ped_popup; + bool block_update; + + Label *status; + GraphEdit *graph_edit; + Ref<ShaderGraph> graph; + int edited_id; + int edited_def; + + ShaderGraph::ShaderType type; + + void _update_graph(); + void _create_node(int p_id); + + + ToolButton *make_label(String text, Variant::Type v_type = Variant::NIL); + ToolButton *make_editor(String text, GraphNode* gn, int p_id, int param, Variant::Type type, String p_hint=""); + + void _connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); + void _disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); + + void _node_removed(int p_id); + void _begin_node_move(); + void _node_moved(const Vector2& p_from, const Vector2& p_to,int p_id); + void _end_node_move(); + void _move_node(int p_id,const Vector2& p_to); + void _duplicate_nodes_request(); + void _duplicate_nodes(const Array &p_nodes); + void _delete_nodes_request(); + + + void _default_changed(int p_id, Node* p_button, int p_param, int v_type, String p_hint); + + void _scalar_const_changed(double p_value,int p_id); + void _vec_const_changed(double p_value, int p_id, Array p_arr); + void _rgb_const_changed(const Color& p_color, int p_id); + void _xform_const_changed(int p_id,Node* p_button); + void _scalar_op_changed(int p_op, int p_id); + void _vec_op_changed(int p_op, int p_id); + void _vec_scalar_op_changed(int p_op, int p_id); + void _rgb_op_changed(int p_op, int p_id); + void _xform_inv_rev_changed(bool p_enabled, int p_id); + void _scalar_func_changed(int p_func, int p_id); + void _vec_func_changed(int p_func, int p_id); + void _scalar_input_changed(double p_value,int p_id); + void _vec_input_changed(double p_value, int p_id, Array p_arr); + void _xform_input_changed(int p_id,Node* p_button); + void _rgb_input_changed(const Color& p_color, int p_id); + void _tex_input_change(int p_id,Node* p_button); + void _cube_input_change(int p_id); + void _input_name_changed(const String& p_name,int p_id,Node* p_line_edit); + void _tex_edited(int p_id,Node* p_button); + void _cube_edited(int p_id,Node* p_button); + void _variant_edited(); + void _comment_edited(int p_id,Node* p_button); + void _color_ramp_changed(int p_id,Node* p_ramp); + void _curve_changed(int p_id,Node* p_curve); + void _sg_updated(); + Map<int,GraphNode*> node_map; + + Variant get_drag_data_fw(const Point2& p_point,Control* p_from); + bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; + void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); +protected: + void _notification(int p_what); + static void _bind_methods(); +public: + + void add_node(int p_type, const Vector2 &location); + GraphEdit *get_graph_edit() { return graph_edit; } + void set_graph(Ref<ShaderGraph> p_graph); + + ShaderGraphView(ShaderGraph::ShaderType p_type=ShaderGraph::SHADER_TYPE_FRAGMENT); +}; + +class ShaderGraphEditor : public VBoxContainer { + + GDCLASS(ShaderGraphEditor,VBoxContainer); + + PopupMenu *popup; + TabContainer *tabs; + ShaderGraphView *graph_edits[ShaderGraph::SHADER_TYPE_MAX]; + static const char* node_names[ShaderGraph::NODE_TYPE_MAX]; + Vector2 next_location; + + bool _2d; + void _add_node(int p_type); + void _popup_requested(const Vector2 &p_position); +protected: + void _notification(int p_what); + static void _bind_methods(); +public: + + void edit(Ref<ShaderGraph> p_shader); + ShaderGraphEditor(bool p_2d); +}; + +class ShaderGraphEditorPlugin : public EditorPlugin { + + GDCLASS( ShaderGraphEditorPlugin, EditorPlugin ); + + bool _2d; + ShaderGraphEditor *shader_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "ShaderGraph"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + ShaderGraphEditorPlugin(EditorNode *p_node,bool p_2d); + ~ShaderGraphEditorPlugin(); + +}; +#endif +#endif diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp new file mode 100644 index 0000000000..8a7969c71b --- /dev/null +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -0,0 +1,4131 @@ +/*************************************************************************/ +/* spatial_editor_plugin.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 "spatial_editor_plugin.h" + +#include "print_string.h" +#include "os/keyboard.h" +#include "scene/3d/visual_instance.h" +#include "scene/3d/camera.h" +#include "camera_matrix.h" +#include "sort.h" +#include "editor/editor_node.h" +#include "editor/editor_settings.h" +#include "scene/resources/surface_tool.h" +#include "editor/spatial_editor_gizmos.h" +#include "global_config.h" +#include "editor/plugins/animation_player_editor_plugin.h" +#include "editor/animation_editor.h" + +#define DISTANCE_DEFAULT 4 + + +#define GIZMO_ARROW_SIZE 0.3 +#define GIZMO_RING_HALF_WIDTH 0.1 +//#define GIZMO_SCALE_DEFAULT 0.28 +#define GIZMO_SCALE_DEFAULT 0.15 + + +void SpatialEditorViewport::_update_camera() { + if (orthogonal) { + //camera->set_orthogonal(size.width*cursor.distance,get_znear(),get_zfar()); + camera->set_orthogonal(2 * cursor.distance, 0.1, 8192); + } + else + camera->set_perspective(get_fov(), get_znear(), get_zfar()); + + Transform camera_transform; + camera_transform.translate(cursor.pos); + camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot); + camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot); + + if (orthogonal) + camera_transform.translate(0, 0, 4096); + else + camera_transform.translate(0, 0, cursor.distance); + + if (camera->get_global_transform() != camera_transform) { + camera->set_global_transform(camera_transform); + update_transform_gizmo_view(); + } +} + +String SpatialEditorGizmo::get_handle_name(int p_idx) const { + + if (get_script_instance() && get_script_instance()->has_method("get_handle_name")) + return get_script_instance()->call("get_handle_name", p_idx); + + return ""; +} + +Variant SpatialEditorGizmo::get_handle_value(int p_idx) const{ + + if (get_script_instance() && get_script_instance()->has_method("get_handle_value")) + return get_script_instance()->call("get_handle_value", p_idx); + + return Variant(); +} + +void SpatialEditorGizmo::set_handle(int p_idx,Camera *p_camera, const Point2& p_point) { + + if (get_script_instance() && get_script_instance()->has_method("set_handle")) + get_script_instance()->call("set_handle", p_idx, p_camera, p_point); +} + +void SpatialEditorGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){ + + if (get_script_instance() && get_script_instance()->has_method("commit_handle")) + get_script_instance()->call("commit_handle", p_idx, p_restore, p_cancel); +} + +bool SpatialEditorGizmo::intersect_frustum(const Camera *p_camera,const Vector<Plane> &p_frustum) { + + return false; +} + +bool SpatialEditorGizmo::intersect_ray(const Camera *p_camera, const Point2 &p_point, Vector3& r_pos, Vector3& r_normal,int *r_gizmo_handle,bool p_sec_first) { + + return false; +} + +SpatialEditorGizmo::SpatialEditorGizmo(){ + + selected=false; +} + + + +int SpatialEditorViewport::get_selected_count() const { + + + Map<Node*,Object*> &selection = editor_selection->get_selection(); + + int count=0; + + for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { + + Spatial *sp = E->key()->cast_to<Spatial>(); + if (!sp) + continue; + + SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); + if (!se) + continue; + + count++; + } + + return count; +} + + + +float SpatialEditorViewport::get_znear() const { + + float val = spatial_editor->get_znear(); + if (val<0.001) + val=0.001; + return val; +} +float SpatialEditorViewport::get_zfar() const{ + + float val = spatial_editor->get_zfar(); + if (val<0.001) + val=0.001; + return val; + +} +float SpatialEditorViewport::get_fov() const{ + + float val = spatial_editor->get_fov(); + if (val<0.001) + val=0.001; + if (val>89) + val=89; + return val; + +} + + + +Transform SpatialEditorViewport::_get_camera_transform() const { + + return camera->get_global_transform(); +} + +Vector3 SpatialEditorViewport::_get_camera_pos() const { + + return _get_camera_transform().origin; +} + +Point2 SpatialEditorViewport::_point_to_screen(const Vector3& p_point) { + + return camera->unproject_position(p_point); + +} + +Vector3 SpatialEditorViewport::_get_ray_pos(const Vector2& p_pos) const { + + return camera->project_ray_origin(p_pos); +} + + +Vector3 SpatialEditorViewport::_get_camera_normal() const { + + return -_get_camera_transform().basis.get_axis(2); +} + +Vector3 SpatialEditorViewport::_get_ray(const Vector2& p_pos) { + + + return camera->project_ray_normal(p_pos); + + +} +/* +void SpatialEditorViewport::_clear_id(Spatial *p_node) { + + + editor_selection->remove_node(p_node); + + +} +*/ +void SpatialEditorViewport::_clear_selected() { + + editor_selection->clear(); +} + + + +void SpatialEditorViewport::_select_clicked(bool p_append,bool p_single) { + + if (!clicked) + return; + + Object *obj = ObjectDB::get_instance(clicked); + if (!obj) + return; + + + Spatial *sp = obj->cast_to<Spatial>(); + if (!sp) + return; + + _select(sp, clicked_wants_append,true); +} + + + +void SpatialEditorViewport::_select(Spatial *p_node, bool p_append,bool p_single) { + + + if (!p_append) { + + // should not modify the selection.. + + editor_selection->clear(); + editor_selection->add_node(p_node); + + } else { + + if (editor_selection->is_selected(p_node) && p_single) { + //erase + editor_selection->remove_node(p_node); + } else { + + editor_selection->add_node(p_node); + } + + } + +} + +ObjectID SpatialEditorViewport::_select_ray(const Point2& p_pos, bool p_append,bool &r_includes_current,int *r_gizmo_handle,bool p_alt_select) { + + if (r_gizmo_handle) + *r_gizmo_handle=-1; + + Vector3 ray=_get_ray(p_pos); + Vector3 pos=_get_ray_pos(p_pos); + + Vector<ObjectID> instances=VisualServer::get_singleton()->instances_cull_ray(pos,ray,get_tree()->get_root()->get_world()->get_scenario() ); + Set<Ref<SpatialEditorGizmo> > found_gizmos; + + ObjectID closest=0; + Spatial *item=NULL; + float closest_dist=1e20; + int selected_handle=-1; + + for (int i=0;i<instances.size();i++) { + + Object *obj=ObjectDB::get_instance(instances[i]); + if (!obj) + continue; + + Spatial *spat=obj->cast_to<Spatial>(); + + if (!spat) + continue; + + Ref<SpatialEditorGizmo> seg = spat->get_gizmo(); + + if (!seg.is_valid()) + continue; + + if (found_gizmos.has(seg)) + continue; + + found_gizmos.insert(seg); + Vector3 point; + Vector3 normal; + + int handle=-1; + bool inters = seg->intersect_ray(camera,p_pos,point,normal,NULL,p_alt_select); + + if (!inters) + continue; + + float dist = pos.distance_to(point); + + if (dist<0) + continue; + + if (dist < closest_dist) { + closest=instances[i]; + closest_dist=dist; + selected_handle=handle; + item=spat; + } + + // if (editor_selection->is_selected(spat)) + // r_includes_current=true; + + } + + + if (!item) + return 0; + + if (!editor_selection->is_selected(item) || (r_gizmo_handle && selected_handle>=0)) { + + if (r_gizmo_handle) + *r_gizmo_handle=selected_handle; + + } + + return closest; + +} + +void SpatialEditorViewport::_find_items_at_pos(const Point2& p_pos,bool &r_includes_current,Vector<_RayResult> &results,bool p_alt_select) { + + Vector3 ray=_get_ray(p_pos); + Vector3 pos=_get_ray_pos(p_pos); + + Vector<ObjectID> instances=VisualServer::get_singleton()->instances_cull_ray(pos,ray,get_tree()->get_root()->get_world()->get_scenario() ); + Set<Ref<SpatialEditorGizmo> > found_gizmos; + + r_includes_current=false; + + for (int i=0;i<instances.size();i++) { + + Object *obj=ObjectDB::get_instance(instances[i]); + + if (!obj) + continue; + + Spatial *spat=obj->cast_to<Spatial>(); + + if (!spat) + continue; + + Ref<SpatialEditorGizmo> seg = spat->get_gizmo(); + + if (!seg.is_valid()) + continue; + + if (found_gizmos.has(seg)) + continue; + + found_gizmos.insert(seg); + Vector3 point; + Vector3 normal; + + int handle=-1; + bool inters = seg->intersect_ray(camera,p_pos,point,normal,NULL,p_alt_select); + + if (!inters) + continue; + + float dist = pos.distance_to(point); + + if (dist<0) + continue; + + + + if (editor_selection->is_selected(spat)) + r_includes_current=true; + + _RayResult res; + res.item=spat; + res.depth=dist; + res.handle=handle; + results.push_back(res); + } + + + if (results.empty()) + return; + + results.sort(); +} + + +Vector3 SpatialEditorViewport::_get_screen_to_space(const Vector3& p_pos) { + + + CameraMatrix cm; + cm.set_perspective(get_fov(),get_size().aspect(),get_znear(),get_zfar()); + float screen_w,screen_h; + cm.get_viewport_size(screen_w,screen_h); + + Transform camera_transform; + camera_transform.translate( cursor.pos ); + camera_transform.basis.rotate(Vector3(1,0,0),-cursor.x_rot); + camera_transform.basis.rotate(Vector3(0,1,0),-cursor.y_rot); + camera_transform.translate(0,0,cursor.distance); + + return camera_transform.xform(Vector3( ((p_pos.x/get_size().width)*2.0-1.0)*screen_w, ((1.0-(p_pos.y/get_size().height))*2.0-1.0)*screen_h,-get_znear())); + +} + + +void SpatialEditorViewport::_select_region() { + + if (cursor.region_begin==cursor.region_end) + return; //nothing really + + Vector3 box[4]={ + Vector3( + MIN( cursor.region_begin.x, cursor.region_end.x), + MIN( cursor.region_begin.y, cursor.region_end.y), + 0 + ), + Vector3( + MAX( cursor.region_begin.x, cursor.region_end.x), + MIN( cursor.region_begin.y, cursor.region_end.y), + 0 + ), + Vector3( + MAX( cursor.region_begin.x, cursor.region_end.x), + MAX( cursor.region_begin.y, cursor.region_end.y), + 0 + ), + Vector3( + MIN( cursor.region_begin.x, cursor.region_end.x), + MAX( cursor.region_begin.y, cursor.region_end.y), + 0 + ) + }; + + Vector<Plane> frustum; + + Vector3 cam_pos=_get_camera_pos(); + Set<Ref<SpatialEditorGizmo> > found_gizmos; + + for(int i=0;i<4;i++) { + + Vector3 a=_get_screen_to_space(box[i]); + Vector3 b=_get_screen_to_space(box[(i+1)%4]); + frustum.push_back( Plane(a,b,cam_pos) ); + } + + Plane near( cam_pos, -_get_camera_normal() ); + near.d-=get_znear(); + + frustum.push_back( near ); + + Plane far=-near; + far.d+=500.0; + + frustum.push_back( far ); + + Vector<ObjectID> instances=VisualServer::get_singleton()->instances_cull_convex(frustum,get_tree()->get_root()->get_world()->get_scenario()); + + + for (int i=0;i<instances.size();i++) { + + Object *obj=ObjectDB::get_instance(instances[i]); + if (!obj) + continue; + Spatial *sp = obj->cast_to<Spatial>(); + if (!sp) + continue; + + Ref<SpatialEditorGizmo> seg = sp->get_gizmo(); + + if (!seg.is_valid()) + continue; + + if (found_gizmos.has(seg)) + continue; + + if (seg->intersect_frustum(camera,frustum)) + _select(sp,true,false); + } + +} + +void SpatialEditorViewport::_update_name() { + + String ortho = orthogonal?TTR("Orthogonal"):TTR("Perspective"); + + if (name!="") + view_menu->set_text("[ "+name+" "+ortho+" ]"); + else + view_menu->set_text("[ "+ortho+" ]"); +} + + +void SpatialEditorViewport::_compute_edit(const Point2& p_point) { + + _edit.click_ray=_get_ray( Vector2( p_point.x, p_point.y ) ); + _edit.click_ray_pos=_get_ray_pos( Vector2( p_point.x, p_point.y ) ); + _edit.plane=TRANSFORM_VIEW; + spatial_editor->update_transform_gizmo(); + _edit.center=spatial_editor->get_gizmo_transform().origin; + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + //Vector3 center; + //int nc=0; + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Spatial *sp = E->get()->cast_to<Spatial>(); + if (!sp) + continue; + + SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); + if (!se) + continue; + + se->original=se->sp->get_global_transform(); + //center+=se->original.origin; + //nc++; + } + + /* + if (nc) + _edit.center=center/float(nc); + */ +} + +static int _get_key_modifier(const String& p_property) { + + switch(EditorSettings::get_singleton()->get(p_property).operator int()) { + + case 0: return 0; + case 1: return KEY_SHIFT; + case 2: return KEY_ALT; + case 3: return KEY_META; + case 4: return KEY_CONTROL; + } + return 0; +} + +bool SpatialEditorViewport::_gizmo_select(const Vector2& p_screenpos,bool p_hilite_only) { + + if (!spatial_editor->is_gizmo_visible()) + return false; + if (get_selected_count()==0) { + if (p_hilite_only) + spatial_editor->select_gizmo_hilight_axis(-1); + return false; + } + + + Vector3 ray_pos=_get_ray_pos( Vector2( p_screenpos.x, p_screenpos.y ) ); + Vector3 ray=_get_ray( Vector2( p_screenpos.x, p_screenpos.y ) ); + + Transform gt = spatial_editor->get_gizmo_transform(); + float gs=gizmo_scale; + + if (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_MOVE) { + + int col_axis=-1; + float col_d=1e20; + + for(int i=0;i<3;i++) { + + Vector3 grabber_pos = gt.origin+gt.basis.get_axis(i)*gs; + float grabber_radius = gs*GIZMO_ARROW_SIZE; + + Vector3 r; + if (Geometry::segment_intersects_sphere(ray_pos,ray_pos+ray*10000.0,grabber_pos,grabber_radius,&r)) { + float d = r.distance_to(ray_pos); + if (d<col_d) { + col_d=d; + col_axis=i; + } + } + } + + if (col_axis!=-1) { + + + if (p_hilite_only) { + + spatial_editor->select_gizmo_hilight_axis(col_axis); + + + } else { + //handle rotate + _edit.mode=TRANSFORM_TRANSLATE; + _compute_edit(Point2(p_screenpos.x,p_screenpos.y)); + _edit.plane=TransformPlane(TRANSFORM_X_AXIS+col_axis); + } + return true; + + + } + + } + + + if (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_ROTATE) { + + int col_axis=-1; + float col_d=1e20; + + for(int i=0;i<3;i++) { + + Plane plane(gt.origin,gt.basis.get_axis(i).normalized()); + Vector3 r; + if (!plane.intersects_ray(ray_pos,ray,&r)) + continue; + + float dist = r.distance_to(gt.origin); + + + + if (dist > gs*(1-GIZMO_RING_HALF_WIDTH) && dist < gs *(1+GIZMO_RING_HALF_WIDTH)) { + + float d = ray_pos.distance_to(r); + if (d<col_d) { + col_d=d; + col_axis=i; + } + } + } + + if (col_axis!=-1) { + + if (p_hilite_only) { + + spatial_editor->select_gizmo_hilight_axis(col_axis+3); + } else { + //handle rotate + _edit.mode=TRANSFORM_ROTATE; + _compute_edit(Point2(p_screenpos.x,p_screenpos.y)); + _edit.plane=TransformPlane(TRANSFORM_X_AXIS+col_axis); + } + return true; + } + } + + + if (p_hilite_only) + spatial_editor->select_gizmo_hilight_axis(-1); + + return false; + +} + + +void SpatialEditorViewport::_smouseenter() { + + if (!surface->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) + surface->grab_focus(); +} + +void SpatialEditorViewport::_list_select(InputEventMouseButton b) { + + _find_items_at_pos(Vector2( b.x, b.y ),clicked_includes_current,selection_results,b.mod.shift); + + Node *scene=editor->get_edited_scene(); + + for(int i=0;i<selection_results.size();i++) { + Spatial *item=selection_results[i].item; + if (item!=scene && item->get_owner()!=scene && !scene->is_editable_instance(item->get_owner())) { + //invalid result + selection_results.remove(i); + i--; + } + + } + + + clicked_wants_append=b.mod.shift; + + if (selection_results.size() == 1) { + + clicked=selection_results[0].item->get_instance_ID(); + selection_results.clear(); + + if (clicked) { + _select_clicked(clicked_wants_append,true); + clicked=0; + } + + } else if (!selection_results.empty()) { + + NodePath root_path = get_tree()->get_edited_scene_root()->get_path(); + StringName root_name = root_path.get_name(root_path.get_name_count()-1); + + for (int i = 0; i < selection_results.size(); i++) { + + Spatial *spat=selection_results[i].item; + + Ref<Texture> icon; + if (spat->has_meta("_editor_icon")) + icon=spat->get_meta("_editor_icon"); + else + icon=get_icon( has_icon(spat->get_class(),"EditorIcons")?spat->get_class():String("Object"),"EditorIcons"); + + String node_path="/"+root_name+"/"+root_path.rel_path_to(spat->get_path()); + + selection_menu->add_item(spat->get_name()); + selection_menu->set_item_icon(i, icon ); + selection_menu->set_item_metadata(i, node_path); + selection_menu->set_item_tooltip(i,String(spat->get_name())+ + "\nType: "+spat->get_class()+"\nPath: "+node_path); + } + + selection_menu->set_global_pos(Vector2( b.global_x, b.global_y )); + selection_menu->popup(); + selection_menu->call_deferred("grab_click_focus"); + selection_menu->set_invalidate_click_until_motion(); + + + + } +} +void SpatialEditorViewport::_sinput(const InputEvent &p_event) { + + if (previewing) + return; //do NONE + + + { + + EditorNode *en = editor; + EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); + + if (!over_plugin_list->empty()) { + bool discard = over_plugin_list->forward_spatial_gui_input(camera,p_event); + if (discard) + return; + } + } + + switch(p_event.type) { + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &b=p_event.mouse_button; + + switch(b.button_index) { + + case BUTTON_WHEEL_UP: { + + + cursor.distance/=1.08; + if (cursor.distance<0.001) + cursor.distance=0.001; + + } break; + case BUTTON_WHEEL_DOWN: { + + if (cursor.distance<0.001) + cursor.distance=0.001; + cursor.distance*=1.08; + + } break; + case BUTTON_RIGHT: { + + NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int(); + + if (b.pressed && _edit.gizmo.is_valid()) { + //restore + _edit.gizmo->commit_handle(_edit.gizmo_handle,_edit.gizmo_initial_value,true); + _edit.gizmo=Ref<SpatialEditorGizmo>(); + } + + if (_edit.mode==TRANSFORM_NONE && b.pressed) { + + Plane cursor_plane(cursor.cursor_pos,_get_camera_normal()); + + Vector3 ray_origin = _get_ray_pos(Vector2(b.x,b.y)); + Vector3 ray_dir = _get_ray(Vector2(b.x,b.y)); + + + //gizmo modify + + if (b.mod.control) { + + Vector<ObjectID> instances=VisualServer::get_singleton()->instances_cull_ray(ray_origin,ray_dir,get_tree()->get_root()->get_world()->get_scenario() ); + + Plane p(ray_origin,_get_camera_normal()); + + float min_d=1e10; + bool found=false; + + for (int i=0;i<instances.size();i++) { + + + Object *obj=ObjectDB::get_instance(instances[i]); + + if (!obj) + continue; + + VisualInstance *vi=obj->cast_to<VisualInstance>(); + if (!vi) + continue; + + //optimize by checking AABB (although should pre sort by distance) + Rect3 aabb = vi->get_global_transform().xform(vi->get_aabb()); + if (p.distance_to(aabb.get_support(-ray_dir))>min_d) + continue; + + PoolVector<Face3> faces = vi->get_faces(VisualInstance::FACES_SOLID); + int c = faces.size(); + if (c>0) { + PoolVector<Face3>::Read r = faces.read(); + + for(int j=0;j<c;j++) { + + Vector3 inters; + if (r[j].intersects_ray(ray_origin,ray_dir,&inters)) { + + float d = p.distance_to(inters); + if (d<0) + continue; + + if (d<min_d) { + min_d=d; + found=true; + } + } + + } + } + + } + + if (found) { + + //cursor.cursor_pos=ray_origin+ray_dir*min_d; + //VisualServer::get_singleton()->instance_set_transform(cursor_instance,Transform(Matrix3(),cursor.cursor_pos)); + + } + + } else { + Vector3 new_pos; + if (cursor_plane.intersects_ray(ray_origin,ray_dir,&new_pos)) { + + //cursor.cursor_pos=new_pos; + //VisualServer::get_singleton()->instance_set_transform(cursor_instance,Transform(Matrix3(),cursor.cursor_pos)); + } + } + + if (b.mod.alt) { + + if (nav_scheme == NAVIGATION_MAYA) + break; + + _list_select(b); + return; + + } + } + + if (_edit.mode!=TRANSFORM_NONE && b.pressed) { + //cancel motion + _edit.mode=TRANSFORM_NONE; + //_validate_selection(); + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Spatial *sp = E->get()->cast_to<Spatial>(); + if (!sp) + continue; + + SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); + if (!se) + continue; + + sp->set_global_transform( se->original ); + + } + surface->update(); + //VisualServer::get_singleton()->poly_clear(indicators); + set_message(TTR("Transform Aborted."),3); + } + } break; + case BUTTON_MIDDLE: { + + if (b.pressed && _edit.mode!=TRANSFORM_NONE) { + + switch(_edit.plane ) { + + case TRANSFORM_VIEW: { + + _edit.plane=TRANSFORM_X_AXIS; + set_message(TTR("X-Axis Transform."),2); + name=""; + _update_name(); + } break; + case TRANSFORM_X_AXIS: { + + _edit.plane=TRANSFORM_Y_AXIS; + set_message(TTR("Y-Axis Transform."),2); + + } break; + case TRANSFORM_Y_AXIS: { + + _edit.plane=TRANSFORM_Z_AXIS; + set_message(TTR("Z-Axis Transform."),2); + + } break; + case TRANSFORM_Z_AXIS: { + + _edit.plane=TRANSFORM_VIEW; + set_message(TTR("View Plane Transform."),2); + + } break; + } + + } + } break; + case BUTTON_LEFT: { + + if (b.pressed) { + + NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int(); + if ( (nav_scheme==NAVIGATION_MAYA || nav_scheme==NAVIGATION_MODO) && b.mod.alt) { + break; + } + + if (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_LIST_SELECT) { + _list_select(b); + break; + } + + _edit.mouse_pos=Point2(b.x,b.y); + _edit.snap=false; + _edit.mode=TRANSFORM_NONE; + + + //gizmo has priority over everything + + bool can_select_gizmos=true; + + { + int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS); + can_select_gizmos = view_menu->get_popup()->is_item_checked( idx ); + } + + + + if (can_select_gizmos && spatial_editor->get_selected()) { + + Ref<SpatialEditorGizmo> seg = spatial_editor->get_selected()->get_gizmo(); + if (seg.is_valid()) { + int handle=-1; + Vector3 point; + Vector3 normal; + bool inters = seg->intersect_ray(camera,_edit.mouse_pos,point,normal,&handle,b.mod.shift); + if (inters && handle!=-1) { + + _edit.gizmo=seg; + _edit.gizmo_handle=handle; + //_edit.gizmo_initial_pos=seg->get_handle_pos(gizmo_handle); + _edit.gizmo_initial_value=seg->get_handle_value(handle); + break; + + } + } + } + + + + if (_gizmo_select(_edit.mouse_pos)) + break; + + clicked=0; + clicked_includes_current=false; + + + if ((spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT && b.mod.control) || spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_ROTATE) { + + /* HANDLE ROTATION */ + if (get_selected_count()==0) + break; //bye + //handle rotate + _edit.mode=TRANSFORM_ROTATE; + _compute_edit(Point2(b.x,b.y)); + break; + + } + + if (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_MOVE) { + + if (get_selected_count()==0) + break; //bye + //handle rotate + _edit.mode=TRANSFORM_TRANSLATE; + _compute_edit(Point2(b.x,b.y)); + break; + + + } + + + if (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SCALE) { + + if (get_selected_count()==0) + break; //bye + //handle rotate + _edit.mode=TRANSFORM_SCALE; + _compute_edit(Point2(b.x,b.y)); + break; + + + } + + + + // todo scale + + int gizmo_handle=-1; + + clicked=_select_ray(Vector2( b.x, b.y ),b.mod.shift,clicked_includes_current,&gizmo_handle,b.mod.shift); + + //clicking is always deferred to either move or release + + clicked_wants_append=b.mod.shift; + + if (!clicked) { + + if (!clicked_wants_append) + _clear_selected(); + + //default to regionselect + cursor.region_select=true; + cursor.region_begin=Point2(b.x,b.y); + cursor.region_end=Point2(b.x,b.y); + } + + if (clicked && gizmo_handle>=0) { + + Object *obj=ObjectDB::get_instance(clicked); + if (obj) { + + Spatial *spa = obj->cast_to<Spatial>(); + if (spa) { + + Ref<SpatialEditorGizmo> seg=spa->get_gizmo(); + if (seg.is_valid()) { + + _edit.gizmo=seg; + _edit.gizmo_handle=gizmo_handle; + //_edit.gizmo_initial_pos=seg->get_handle_pos(gizmo_handle); + _edit.gizmo_initial_value=seg->get_handle_value(gizmo_handle); + //print_line("GIZMO: "+itos(gizmo_handle)+" FROMPOS: "+_edit.orig_gizmo_pos); + break; + + } + } + + } + //_compute_edit(Point2(b.x,b.y)); //in case a motion happens.. + } + + + + surface->update(); + } else { + + + if (_edit.gizmo.is_valid()) { + + _edit.gizmo->commit_handle(_edit.gizmo_handle,_edit.gizmo_initial_value,false); + _edit.gizmo=Ref<SpatialEditorGizmo>(); + break; + } + if (clicked) { + _select_clicked(clicked_wants_append,true); + //clickd processing was deferred + clicked=0; + + + } + + if (cursor.region_select) { + _select_region(); + cursor.region_select=false; + surface->update(); + } + + + if (_edit.mode!=TRANSFORM_NONE) { + + + static const char* _transform_name[4]={"None","Rotate","Translate","Scale"}; + undo_redo->create_action(_transform_name[_edit.mode]); + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Spatial *sp = E->get()->cast_to<Spatial>(); + if (!sp) + continue; + + SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); + if (!se) + continue; + + undo_redo->add_do_method(sp,"set_global_transform",sp->get_global_transform()); + undo_redo->add_undo_method(sp,"set_global_transform",se->original); + } + undo_redo->commit_action(); + _edit.mode=TRANSFORM_NONE; + //VisualServer::get_singleton()->poly_clear(indicators); + set_message(""); + } + + + surface->update(); + } + } break; + } + } break; + case InputEvent::MOUSE_MOTION: { + const InputEventMouseMotion &m=p_event.mouse_motion; + _edit.mouse_pos=Point2(p_event.mouse_motion.x,p_event.mouse_motion.y); + + if (spatial_editor->get_selected()) { + + + Ref<SpatialEditorGizmo> seg = spatial_editor->get_selected()->get_gizmo(); + if (seg.is_valid()) { + + int selected_handle=-1; + + int handle=-1; + Vector3 point; + Vector3 normal; + bool inters = seg->intersect_ray(camera,_edit.mouse_pos,point,normal,&handle,false); + if (inters && handle!=-1) { + + selected_handle=handle; + + } + + if (selected_handle!=spatial_editor->get_over_gizmo_handle()) { + spatial_editor->set_over_gizmo_handle(selected_handle); + spatial_editor->get_selected()->update_gizmo(); + if (selected_handle!=-1) + spatial_editor->select_gizmo_hilight_axis(-1); + } + } + } + + if (spatial_editor->get_over_gizmo_handle()==-1 && !(m.button_mask&1) && !_edit.gizmo.is_valid()) { + + _gizmo_select(_edit.mouse_pos,true); + + } + + NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int(); + NavigationMode nav_mode = NAVIGATION_NONE; + + if (_edit.gizmo.is_valid()) { + + _edit.gizmo->set_handle(_edit.gizmo_handle,camera,Vector2(m.x,m.y)); + Variant v = _edit.gizmo->get_handle_value(_edit.gizmo_handle); + String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle); + set_message(n+": "+String(v)); + + } else if (m.button_mask&1) { + + if (nav_scheme == NAVIGATION_MAYA && m.mod.alt) { + nav_mode = NAVIGATION_ORBIT; + } else if (nav_scheme == NAVIGATION_MODO && m.mod.alt && m.mod.shift) { + nav_mode = NAVIGATION_PAN; + } else if (nav_scheme == NAVIGATION_MODO && m.mod.alt && m.mod.control) { + nav_mode = NAVIGATION_ZOOM; + } else if (nav_scheme == NAVIGATION_MODO && m.mod.alt) { + nav_mode = NAVIGATION_ORBIT; + } else { + if (clicked) { + + if (!clicked_includes_current) { + + _select_clicked(clicked_wants_append,true); + //clickd processing was deferred + } + + + _compute_edit(_edit.mouse_pos); + clicked=0; + + _edit.mode=TRANSFORM_TRANSLATE; + + } + + if (cursor.region_select && nav_mode == NAVIGATION_NONE) { + + cursor.region_end=Point2(m.x,m.y); + surface->update(); + return; + } + + if (_edit.mode==TRANSFORM_NONE && nav_mode == NAVIGATION_NONE) + break; + + + Vector3 ray_pos=_get_ray_pos( Vector2( m.x, m.y ) ); + Vector3 ray=_get_ray( Vector2( m.x, m.y ) ); + + + switch(_edit.mode) { + + case TRANSFORM_SCALE: { + + + Plane plane=Plane(_edit.center,_get_camera_normal()); + + + Vector3 intersection; + if (!plane.intersects_ray(ray_pos,ray,&intersection)) + break; + + Vector3 click; + if (!plane.intersects_ray(_edit.click_ray_pos,_edit.click_ray,&click)) + break; + + float center_click_dist = click.distance_to(_edit.center); + float center_inters_dist = intersection.distance_to(_edit.center); + if (center_click_dist==0) + break; + + float scale = (center_inters_dist / center_click_dist)*100.0; + + if (_edit.snap || spatial_editor->is_snap_enabled()) { + + scale = Math::stepify(scale,spatial_editor->get_scale_snap()); + } + + set_message(vformat(TTR("Scaling to %s%%."),String::num(scale,1))); + scale/=100.0; + + Transform r; + r.basis.scale(Vector3(scale,scale,scale)); + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Spatial *sp = E->get()->cast_to<Spatial>(); + if (!sp) + continue; + + SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); + if (!se) + continue; + + + Transform original=se->original; + + Transform base=Transform( Basis(), _edit.center); + Transform t=base * (r * (base.inverse() * original)); + + sp->set_global_transform(t); + } + + surface->update(); + + } break; + + case TRANSFORM_TRANSLATE: { + + + Vector3 motion_mask; + Plane plane; + + switch( _edit.plane ) { + case TRANSFORM_VIEW: + motion_mask=Vector3(0,0,0); + plane=Plane(_edit.center,_get_camera_normal()); + break; + case TRANSFORM_X_AXIS: + motion_mask=spatial_editor->get_gizmo_transform().basis.get_axis(0); + plane=Plane(_edit.center,motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized()); + break; + case TRANSFORM_Y_AXIS: + motion_mask=spatial_editor->get_gizmo_transform().basis.get_axis(1); + plane=Plane(_edit.center,motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized()); + break; + case TRANSFORM_Z_AXIS: + motion_mask=spatial_editor->get_gizmo_transform().basis.get_axis(2); + plane=Plane(_edit.center,motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized()); + break; + } + + Vector3 intersection; + if (!plane.intersects_ray(ray_pos,ray,&intersection)) + break; + + Vector3 click; + if (!plane.intersects_ray(_edit.click_ray_pos,_edit.click_ray,&click)) + break; + + //_validate_selection(); + Vector3 motion = intersection-click; + if (motion_mask!=Vector3()) { + motion=motion_mask.dot(motion)*motion_mask; + } + + float snap=0; + + if (_edit.snap || spatial_editor->is_snap_enabled()) { + + snap = spatial_editor->get_translate_snap(); + motion.snap(snap); + } + + //set_message("Translating: "+motion); + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Spatial *sp = E->get()->cast_to<Spatial>(); + if (!sp) { + continue; + } + + SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); + if (!se) { + continue; + } + + Transform t=se->original; + t.origin+=motion; + sp->set_global_transform(t); + } + } break; + + case TRANSFORM_ROTATE: { + + + Plane plane; + + switch( _edit.plane ) { + case TRANSFORM_VIEW: + plane=Plane(_edit.center,_get_camera_normal()); + break; + case TRANSFORM_X_AXIS: + plane=Plane(_edit.center,spatial_editor->get_gizmo_transform().basis.get_axis(0)); + break; + case TRANSFORM_Y_AXIS: + plane=Plane(_edit.center,spatial_editor->get_gizmo_transform().basis.get_axis(1)); + break; + case TRANSFORM_Z_AXIS: + plane=Plane(_edit.center,spatial_editor->get_gizmo_transform().basis.get_axis(2)); + break; + } + + Vector3 intersection; + if (!plane.intersects_ray(ray_pos,ray,&intersection)) + break; + + Vector3 click; + if (!plane.intersects_ray(_edit.click_ray_pos,_edit.click_ray,&click)) + break; + + + Vector3 y_axis=(click-_edit.center).normalized(); + Vector3 x_axis=plane.normal.cross(y_axis).normalized(); + + float angle=Math::atan2( x_axis.dot(intersection-_edit.center), y_axis.dot(intersection-_edit.center) ); + if (_edit.snap || spatial_editor->is_snap_enabled()) { + + float snap = spatial_editor->get_rotate_snap(); + + if (snap) { + angle=Math::rad2deg(angle)+snap*0.5; //else it wont reach +180 + angle-=Math::fmod(angle,snap); + set_message(vformat(TTR("Rotating %s degrees."),rtos(angle))); + angle=Math::deg2rad(angle); + } else + set_message(vformat(TTR("Rotating %s degrees."),rtos(Math::rad2deg(angle)))); + + } else { + set_message(vformat(TTR("Rotating %s degrees."),rtos(Math::rad2deg(angle)))); + } + + + + + Transform r; + r.basis.rotate(plane.normal,angle); + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Spatial *sp = E->get()->cast_to<Spatial>(); + if (!sp) + continue; + + SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); + if (!se) + continue; + + + Transform original=se->original; + + Transform base=Transform( Basis(), _edit.center); + Transform t=base * r * base.inverse() * original; + + sp->set_global_transform(t); + } + + surface->update(); + /* + VisualServer::get_singleton()->poly_clear(indicators); + + Vector<Vector3> points; + Vector<Vector3> empty; + Vector<Color> colors; + points.push_back(intersection); + points.push_back(_edit.original.origin); + colors.push_back( Color(255,155,100) ); + colors.push_back( Color(255,155,100) ); + VisualServer::get_singleton()->poly_add_primitive(indicators,points,empty,colors,empty); + */ + } break; + default:{} + } + + } + + } else if (m.button_mask&2) { + + if (nav_scheme == NAVIGATION_MAYA && m.mod.alt) { + nav_mode = NAVIGATION_ZOOM; + } + + } else if (m.button_mask&4) { + + if (nav_scheme == NAVIGATION_GODOT) { + + int mod = 0; + if (m.mod.shift) + mod=KEY_SHIFT; + if (m.mod.alt) + mod=KEY_ALT; + if (m.mod.control) + mod=KEY_CONTROL; + if (m.mod.meta) + mod=KEY_META; + + if (mod == _get_key_modifier("editors/3d/pan_modifier")) + nav_mode = NAVIGATION_PAN; + else if (mod == _get_key_modifier("editors/3d/zoom_modifier")) + nav_mode = NAVIGATION_ZOOM; + else if (mod == _get_key_modifier("editors/3d/orbit_modifier")) + nav_mode = NAVIGATION_ORBIT; + + } else if (nav_scheme == NAVIGATION_MAYA) { + if (m.mod.alt) + nav_mode = NAVIGATION_PAN; + } + + } else if (EditorSettings::get_singleton()->get("editors/3d/emulate_3_button_mouse")) { + // Handle trackpad (no external mouse) use case + int mod = 0; + if (m.mod.shift) + mod=KEY_SHIFT; + if (m.mod.alt) + mod=KEY_ALT; + if (m.mod.control) + mod=KEY_CONTROL; + if (m.mod.meta) + mod=KEY_META; + + if(mod){ + if (mod == _get_key_modifier("editors/3d/pan_modifier")) + nav_mode = NAVIGATION_PAN; + else if (mod == _get_key_modifier("editors/3d/zoom_modifier")) + nav_mode = NAVIGATION_ZOOM; + else if (mod == _get_key_modifier("editors/3d/orbit_modifier")) + nav_mode = NAVIGATION_ORBIT; + } + } + + switch(nav_mode) { + case NAVIGATION_PAN:{ + + real_t pan_speed = 1/150.0; + int pan_speed_modifier = 10; + if (nav_scheme==NAVIGATION_MAYA && m.mod.shift) + pan_speed *= pan_speed_modifier; + + Transform camera_transform; + + camera_transform.translate(cursor.pos); + camera_transform.basis.rotate(Vector3(1,0,0),-cursor.x_rot); + camera_transform.basis.rotate(Vector3(0,1,0),-cursor.y_rot); + Vector3 translation(-m.relative_x*pan_speed,m.relative_y*pan_speed,0); + translation*=cursor.distance/DISTANCE_DEFAULT; + camera_transform.translate(translation); + cursor.pos=camera_transform.origin; + + } break; + + case NAVIGATION_ZOOM: { + real_t zoom_speed = 1/80.0; + int zoom_speed_modifier = 10; + if (nav_scheme==NAVIGATION_MAYA && m.mod.shift) + zoom_speed *= zoom_speed_modifier; + + NavigationZoomStyle zoom_style = (NavigationZoomStyle)EditorSettings::get_singleton()->get("editors/3d/zoom_style").operator int(); + if (zoom_style == NAVIGATION_ZOOM_HORIZONTAL) { + if ( m.relative_x > 0) + cursor.distance*=1-m.relative_x*zoom_speed; + else if (m.relative_x < 0) + cursor.distance/=1+m.relative_x*zoom_speed; + } + else { + if ( m.relative_y > 0) + cursor.distance*=1+m.relative_y*zoom_speed; + else if (m.relative_y < 0) + cursor.distance/=1-m.relative_y*zoom_speed; + } + + } break; + + case NAVIGATION_ORBIT: { + cursor.x_rot+=m.relative_y/80.0; + cursor.y_rot+=m.relative_x/80.0; + if (cursor.x_rot>Math_PI/2.0) + cursor.x_rot=Math_PI/2.0; + if (cursor.x_rot<-Math_PI/2.0) + cursor.x_rot=-Math_PI/2.0; + name=""; + _update_name(); + } break; + + default: {} + } + } break; + case InputEvent::KEY: { + const InputEventKey &k = p_event.key; + if (!k.pressed) + break; + + if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) { + if (_edit.mode != TRANSFORM_NONE) { + _edit.snap=true; + } + } + if (ED_IS_SHORTCUT("spatial_editor/bottom_view", p_event)) { + cursor.y_rot = 0; + cursor.x_rot = -Math_PI/2.0; + set_message(TTR("Bottom View."),2); + name = TTR("Bottom"); + _update_name(); + } + if (ED_IS_SHORTCUT("spatial_editor/top_view", p_event)) { + cursor.y_rot = 0; + cursor.x_rot = Math_PI/2.0; + set_message(TTR("Top View."),2); + name = TTR("Top"); + _update_name(); + } + if (ED_IS_SHORTCUT("spatial_editor/rear_view", p_event)) { + cursor.x_rot = 0; + cursor.y_rot = Math_PI; + set_message(TTR("Rear View."),2); + name = TTR("Rear"); + _update_name(); + } + if (ED_IS_SHORTCUT("spatial_editor/front_view", p_event)) { + cursor.x_rot = 0; + cursor.y_rot=0; + set_message(TTR("Front View."),2); + name=TTR("Front"); + _update_name(); + } + if (ED_IS_SHORTCUT("spatial_editor/left_view", p_event)) { + cursor.x_rot=0; + cursor.y_rot = Math_PI/2.0; + set_message(TTR("Left View."),2); + name = TTR("Left"); + _update_name(); + } + if (ED_IS_SHORTCUT("spatial_editor/right_view", p_event)) { + cursor.x_rot=0; + cursor.y_rot = -Math_PI/2.0; + set_message(TTR("Right View."),2); + name = TTR("Right"); + _update_name(); + } + if (ED_IS_SHORTCUT("spatial_editor/switch_perspective_orthogonal", p_event)) { + _menu_option(orthogonal?VIEW_PERSPECTIVE:VIEW_ORTHOGONAL); + _update_name(); + } + if (ED_IS_SHORTCUT("spatial_editor/insert_anim_key", p_event)) { + if (!get_selected_count() || _edit.mode!=TRANSFORM_NONE) + break; + + if (!AnimationPlayerEditor::singleton->get_key_editor()->has_keying()) { + set_message(TTR("Keying is disabled (no key inserted).")); + break; + } + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Spatial *sp = E->get()->cast_to<Spatial>(); + if (!sp) + continue; + + emit_signal("transform_key_request",sp,"",sp->get_transform()); + } + + + set_message(TTR("Animation Key Inserted.")); + } + + if (k.scancode == KEY_SPACE) { + if (!k.pressed) emit_signal("toggle_maximize_view", this); + } + + } break; + + } + +} + +void SpatialEditorViewport::set_message(String p_message,float p_time) { + + message=p_message; + message_time=p_time; + +} + + + +void SpatialEditorViewport::_notification(int p_what) { + + + if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { + + bool visible=is_visible_in_tree(); + + set_process(visible); + + if (visible) + _update_camera(); + + call_deferred("update_transform_gizmo_view"); + } + + if (p_what==NOTIFICATION_RESIZED) { + + call_deferred("update_transform_gizmo_view"); + + } + + if (p_what==NOTIFICATION_PROCESS) { + + + //force editr camera + /* + current_camera=get_root_node()->get_current_camera(); + if (current_camera!=camera) { + + + } + */ + + _update_camera(); + + Map<Node*,Object*> &selection = editor_selection->get_selection(); + + bool changed=false; + bool exist=false; + + for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { + + Spatial *sp = E->key()->cast_to<Spatial>(); + if (!sp) + continue; + + SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); + if (!se) + continue; + + + VisualInstance *vi=sp->cast_to<VisualInstance>(); + + + if (se->aabb.has_no_surface()) { + + se->aabb=vi?vi->get_aabb():Rect3( Vector3(-0.2,-0.2,-0.2),Vector3(0.4,0.4,0.4)); + } + + Transform t=sp->get_global_transform(); + t.translate(se->aabb.pos); + t.basis.scale( se->aabb.size ); + + exist=true; + if (se->last_xform==t) + continue; + changed=true; + se->last_xform=t; + VisualServer::get_singleton()->instance_set_transform(se->sbox_instance,t); + + } + + if (changed || (spatial_editor->is_gizmo_visible() && !exist)) { + spatial_editor->update_transform_gizmo(); + } + + if (message_time>0) { + + if (message!=last_message) { + surface->update(); + last_message=message; + } + + message_time-=get_fixed_process_delta_time(); + if (message_time<0) + surface->update(); + } + + //update shadow atlas if changed + + int shadowmap_size = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/size"); + int atlas_q0 = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/quadrant_0_subdiv"); + int atlas_q1 = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/quadrant_1_subdiv"); + int atlas_q2 = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/quadrant_2_subdiv"); + int atlas_q3 = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/quadrant_3_subdiv"); + + + viewport->set_shadow_atlas_size(shadowmap_size); + viewport->set_shadow_atlas_quadrant_subdiv(0,Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0)); + viewport->set_shadow_atlas_quadrant_subdiv(1,Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1)); + viewport->set_shadow_atlas_quadrant_subdiv(2,Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2)); + viewport->set_shadow_atlas_quadrant_subdiv(3,Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3)); + + //update msaa if changed + + int msaa_mode = GlobalConfig::get_singleton()->get("rendering/quality/msaa"); + viewport->set_msaa(Viewport::MSAA(msaa_mode)); + + bool hdr = GlobalConfig::get_singleton()->get("rendering/quality/hdr"); + viewport->set_hdr(hdr); + + + } + + if (p_what==NOTIFICATION_ENTER_TREE) { + + surface->connect("draw",this,"_draw"); + surface->connect("gui_input",this,"_sinput"); + surface->connect("mouse_entered",this,"_smouseenter"); + preview_camera->set_icon(get_icon("Camera","EditorIcons")); + _init_gizmo_instance(index); + } + if (p_what==NOTIFICATION_EXIT_TREE) { + + + _finish_gizmo_instances(); + + } + + if (p_what==NOTIFICATION_MOUSE_ENTER) { + + + } + + + if (p_what==NOTIFICATION_DRAW) { + + + + } + +} + +void SpatialEditorViewport::_draw() { + + if (surface->has_focus()) { + Size2 size = surface->get_size(); + Rect2 r =Rect2(Point2(),size); + get_stylebox("EditorFocus","EditorStyles")->draw(surface->get_canvas_item(),r); + } + + + RID ci=surface->get_canvas_item(); + + if (cursor.region_select) { + + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor.region_begin,cursor.region_end-cursor.region_begin),Color(0.7,0.7,1.0,0.3)); + } + + if (message_time>0) { + Ref<Font> font = get_font("font","Label"); + Point2 msgpos=Point2(5,get_size().y-20); + font->draw(ci,msgpos+Point2(1,1),message,Color(0,0,0,0.8)); + font->draw(ci,msgpos+Point2(-1,-1),message,Color(0,0,0,0.8)); + font->draw(ci,msgpos,message,Color(1,1,1,1)); + } + + + if (_edit.mode==TRANSFORM_ROTATE) { + + Point2 center = _point_to_screen(_edit.center); + VisualServer::get_singleton()->canvas_item_add_line(ci,_edit.mouse_pos, center, Color(0.4,0.7,1.0,0.8)); + + + } + + if (previewing) { + + + Size2 ss = Size2( GlobalConfig::get_singleton()->get("display/width"), GlobalConfig::get_singleton()->get("display/height") ); + float aspect = ss.aspect(); + Size2 s = get_size(); + + Rect2 draw_rect; + + + switch(previewing->get_keep_aspect_mode()) { + case Camera::KEEP_WIDTH: { + + draw_rect.size = Size2(s.width,s.width/aspect); + draw_rect.pos.x=0; + draw_rect.pos.y=(s.height-draw_rect.size.y)*0.5; + + } break; + case Camera::KEEP_HEIGHT: { + + draw_rect.size = Size2(s.height*aspect,s.height); + draw_rect.pos.y=0; + draw_rect.pos.x=(s.width-draw_rect.size.x)*0.5; + + } break; + } + + draw_rect = Rect2(Vector2(),s).clip(draw_rect); + + surface->draw_line(draw_rect.pos,draw_rect.pos+Vector2(draw_rect.size.x,0),Color(0.6,0.6,0.1,0.5),2.0); + surface->draw_line(draw_rect.pos+Vector2(draw_rect.size.x,0),draw_rect.pos+draw_rect.size,Color(0.6,0.6,0.1,0.5),2.0); + surface->draw_line(draw_rect.pos+draw_rect.size,draw_rect.pos+Vector2(0,draw_rect.size.y),Color(0.6,0.6,0.1,0.5),2.0); + surface->draw_line(draw_rect.pos,draw_rect.pos+Vector2(0,draw_rect.size.y),Color(0.6,0.6,0.1,0.5),2.0); + } + +} + + +void SpatialEditorViewport::_menu_option(int p_option) { + + switch(p_option) { + + case VIEW_TOP: { + + cursor.x_rot=Math_PI/2.0; + cursor.y_rot=0; + name=TTR("Top"); + _update_name(); + } break; + case VIEW_BOTTOM: { + + cursor.x_rot=-Math_PI/2.0; + cursor.y_rot=0; + name=TTR("Bottom"); + _update_name(); + + } break; + case VIEW_LEFT: { + + cursor.y_rot=Math_PI/2.0; + cursor.x_rot=0; + name=TTR("Left"); + _update_name(); + + } break; + case VIEW_RIGHT: { + + cursor.y_rot=-Math_PI/2.0; + cursor.x_rot=0; + name=TTR("Right"); + _update_name(); + + } break; + case VIEW_FRONT: { + + cursor.y_rot=0; + cursor.x_rot=0; + name=TTR("Front"); + _update_name(); + + } break; + case VIEW_REAR: { + + cursor.y_rot=Math_PI; + cursor.x_rot=0; + name=TTR("Rear"); + _update_name(); + + } break; + case VIEW_CENTER_TO_ORIGIN: { + + cursor.pos = Vector3(0,0,0); + + } break; + case VIEW_CENTER_TO_SELECTION: { + + focus_selection(); + + } break; + case VIEW_ALIGN_SELECTION_WITH_VIEW: { + + if (!get_selected_count()) + break; + + Transform camera_transform = camera->get_global_transform(); + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + undo_redo->create_action(TTR("Align with view")); + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Spatial *sp = E->get()->cast_to<Spatial>(); + if (!sp) + continue; + + SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); + if (!se) + continue; + + Transform xform = camera_transform; + xform.scale_basis(sp->get_scale()); + + undo_redo->add_do_method(sp,"set_global_transform",xform); + undo_redo->add_undo_method(sp,"set_global_transform",sp->get_global_transform()); + } + undo_redo->commit_action(); + } break; + case VIEW_ENVIRONMENT: { + + int idx = view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT); + bool current = view_menu->get_popup()->is_item_checked( idx ); + current=!current; + if (current) { + + camera->set_environment(RES()); + } else { + + camera->set_environment(SpatialEditor::get_singleton()->get_viewport_environment()); + } + + view_menu->get_popup()->set_item_checked( idx, current ); + + + } break; + case VIEW_PERSPECTIVE: { + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), true ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL), false ); + orthogonal=false; + call_deferred("update_transform_gizmo_view"); + _update_name(); + + } break; + case VIEW_ORTHOGONAL: { + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL), true ); + orthogonal=true; + call_deferred("update_transform_gizmo_view"); + _update_name(); + + } break; + case VIEW_AUDIO_LISTENER: { + + int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER); + bool current = view_menu->get_popup()->is_item_checked( idx ); + current=!current; + viewport->set_as_audio_listener(current); + view_menu->get_popup()->set_item_checked( idx, current ); + + } break; + case VIEW_GIZMOS: { + + int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS); + bool current = view_menu->get_popup()->is_item_checked( idx ); + current=!current; + if (current) + camera->set_cull_mask( ((1<<20)-1)|(1<<(GIZMO_BASE_LAYER+index))|(1<<GIZMO_EDIT_LAYER)|(1<<GIZMO_GRID_LAYER) ); + else + camera->set_cull_mask( ((1<<20)-1)|(1<<(GIZMO_BASE_LAYER+index))|(1<<GIZMO_GRID_LAYER) ); + view_menu->get_popup()->set_item_checked( idx, current ); + + } break; + + } + +} + + +void SpatialEditorViewport::_preview_exited_scene() { + + preview_camera->set_pressed(false); + _toggle_camera_preview(false); + view_menu->show(); +} + + +void SpatialEditorViewport::_init_gizmo_instance(int p_idx) { + + uint32_t layer=1<<(GIZMO_BASE_LAYER+p_idx);//|(1<<GIZMO_GRID_LAYER); + + for(int i=0;i<3;i++) { + move_gizmo_instance[i]=VS::get_singleton()->instance_create(); + VS::get_singleton()->instance_set_base(move_gizmo_instance[i],spatial_editor->get_move_gizmo(i)->get_rid()); + VS::get_singleton()->instance_set_scenario(move_gizmo_instance[i],get_tree()->get_root()->get_world()->get_scenario()); + VS::get_singleton()->instance_set_visible(move_gizmo_instance[i],false); + //VS::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true); + VS::get_singleton()->instance_geometry_set_cast_shadows_setting(move_gizmo_instance[i], VS::SHADOW_CASTING_SETTING_OFF); + VS::get_singleton()->instance_set_layer_mask(move_gizmo_instance[i],layer); + + rotate_gizmo_instance[i]=VS::get_singleton()->instance_create(); + VS::get_singleton()->instance_set_base(rotate_gizmo_instance[i],spatial_editor->get_rotate_gizmo(i)->get_rid()); + VS::get_singleton()->instance_set_scenario(rotate_gizmo_instance[i],get_tree()->get_root()->get_world()->get_scenario()); + VS::get_singleton()->instance_set_visible(rotate_gizmo_instance[i],false); + //VS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true); + VS::get_singleton()->instance_geometry_set_cast_shadows_setting(rotate_gizmo_instance[i], VS::SHADOW_CASTING_SETTING_OFF); + VS::get_singleton()->instance_set_layer_mask(rotate_gizmo_instance[i],layer); + } + +} + + +void SpatialEditorViewport::_finish_gizmo_instances() { + + + for(int i=0;i<3;i++) { + VS::get_singleton()->free(move_gizmo_instance[i]); + VS::get_singleton()->free(rotate_gizmo_instance[i]); + } + +} +void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) { + + + ERR_FAIL_COND(p_activate && !preview); + ERR_FAIL_COND(!p_activate && !previewing); + + if (!p_activate) { + + previewing->disconnect("tree_exited",this,"_preview_exited_scene"); + previewing=NULL; + VS::get_singleton()->viewport_attach_camera( viewport->get_viewport_rid(), camera->get_camera() ); //restore + if (!preview) + preview_camera->hide(); + view_menu->show(); + surface->update(); + + } else { + + previewing=preview; + previewing->connect("tree_exited",this,"_preview_exited_scene"); + VS::get_singleton()->viewport_attach_camera( viewport->get_viewport_rid(), preview->get_camera() ); //replace + view_menu->hide(); + surface->update(); + + } +} + +void SpatialEditorViewport::_selection_result_pressed(int p_result) { + + if (selection_results.size() <= p_result) + return; + + clicked=selection_results[p_result].item->get_instance_ID(); + + if (clicked) { + _select_clicked(clicked_wants_append,true); + clicked=0; + } +} + +void SpatialEditorViewport::_selection_menu_hide() { + + selection_results.clear(); + selection_menu->clear(); + selection_menu->set_size(Vector2(0, 0)); +} + +void SpatialEditorViewport::set_can_preview(Camera* p_preview) { + + preview=p_preview; + + if (!preview_camera->is_pressed()) { + + if (p_preview) { + preview_camera->show(); + } else { + preview_camera->hide(); + } + } +} + +void SpatialEditorViewport::update_transform_gizmo_view() { + + if (!is_visible_in_tree()) + return; + + Transform xform = spatial_editor->get_gizmo_transform(); + + + Transform camera_xform = camera->get_transform(); + Vector3 camz = -camera_xform.get_basis().get_axis(2).normalized(); + Vector3 camy = -camera_xform.get_basis().get_axis(1).normalized(); + Plane p(camera_xform.origin,camz); + float gizmo_d = Math::abs( p.distance_to(xform.origin )); + float d0 = camera->unproject_position(camera_xform.origin+camz*gizmo_d).y; + float d1 = camera->unproject_position(camera_xform.origin+camz*gizmo_d+camy).y; + float dd = Math::abs(d0-d1); + if (dd==0) + dd=0.0001; + + float gsize = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size"); + gizmo_scale=(gsize/Math::abs(dd)); + Vector3 scale = Vector3(1,1,1) * gizmo_scale; + + xform.basis.scale(scale); + + //xform.basis.scale(GIZMO_SCALE_DEFAULT*Vector3(1,1,1)); + + + for(int i=0;i<3;i++) { + VisualServer::get_singleton()->instance_set_transform(move_gizmo_instance[i], xform ); + VisualServer::get_singleton()->instance_set_visible(move_gizmo_instance[i],spatial_editor->is_gizmo_visible()&& (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_MOVE) ); + VisualServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[i], xform ); + VisualServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[i],spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_ROTATE) ); + } + +} + +void SpatialEditorViewport::set_state(const Dictionary& p_state) { + + cursor.pos=p_state["pos"]; + cursor.x_rot=p_state["x_rot"]; + cursor.y_rot=p_state["y_rot"]; + cursor.distance=p_state["distance"]; + bool env = p_state["use_environment"]; + bool orth = p_state["use_orthogonal"]; + if (orth) + _menu_option(VIEW_ORTHOGONAL); + else + _menu_option(VIEW_PERSPECTIVE); + if (env != camera->get_environment().is_valid()) + _menu_option(VIEW_ENVIRONMENT); + if (p_state.has("listener")) { + bool listener = p_state["listener"]; + + int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER); + viewport->set_as_audio_listener(listener); + view_menu->get_popup()->set_item_checked( idx, listener ); + } + + if (p_state.has("previewing")) { + Node *pv = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["previewing"]); + if (pv && pv->cast_to<Camera>()) { + previewing=pv->cast_to<Camera>(); + previewing->connect("tree_exited",this,"_preview_exited_scene"); + VS::get_singleton()->viewport_attach_camera( viewport->get_viewport_rid(), previewing->get_camera() ); //replace + view_menu->hide(); + surface->update(); + preview_camera->set_pressed(true); + preview_camera->show(); + } + } +} + +Dictionary SpatialEditorViewport::get_state() const { + + Dictionary d; + d["pos"]=cursor.pos; + d["x_rot"]=cursor.x_rot; + d["y_rot"]=cursor.y_rot; + d["distance"]=cursor.distance; + d["use_environment"]=camera->get_environment().is_valid(); + d["use_orthogonal"]=camera->get_projection()==Camera::PROJECTION_ORTHOGONAL; + d["listener"]=viewport->is_audio_listener(); + if (previewing) { + d["previewing"]=EditorNode::get_singleton()->get_edited_scene()->get_path_to(previewing); + } + + return d; +} + + +void SpatialEditorViewport::_bind_methods(){ + + ClassDB::bind_method(D_METHOD("_draw"),&SpatialEditorViewport::_draw); + ClassDB::bind_method(D_METHOD("_smouseenter"),&SpatialEditorViewport::_smouseenter); + ClassDB::bind_method(D_METHOD("_sinput"),&SpatialEditorViewport::_sinput); + ClassDB::bind_method(D_METHOD("_menu_option"),&SpatialEditorViewport::_menu_option); + ClassDB::bind_method(D_METHOD("_toggle_camera_preview"),&SpatialEditorViewport::_toggle_camera_preview); + ClassDB::bind_method(D_METHOD("_preview_exited_scene"),&SpatialEditorViewport::_preview_exited_scene); + ClassDB::bind_method(D_METHOD("update_transform_gizmo_view"),&SpatialEditorViewport::update_transform_gizmo_view); + ClassDB::bind_method(D_METHOD("_selection_result_pressed"),&SpatialEditorViewport::_selection_result_pressed); + ClassDB::bind_method(D_METHOD("_selection_menu_hide"),&SpatialEditorViewport::_selection_menu_hide); + + ADD_SIGNAL( MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport")) ); +} + + +void SpatialEditorViewport::reset() { + + orthogonal=false; + message_time=0; + message=""; + last_message=""; + name=""; + + cursor.x_rot=0.5; + cursor.y_rot=0.5; + cursor.distance=4; + cursor.region_select=false; + _update_name(); +} + + +void SpatialEditorViewport::focus_selection() { + if (!get_selected_count()) + return; + + Vector3 center; + int count=0; + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Spatial *sp = E->get()->cast_to<Spatial>(); + if (!sp) + continue; + + SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); + if (!se) + continue; + + center+=sp->get_global_transform().origin; + count++; + } + + if( count != 0 ) { + center/=float(count); + } + + cursor.pos=center; +} + + +SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index) { + + _edit.mode=TRANSFORM_NONE; + _edit.plane=TRANSFORM_VIEW; + _edit.edited_gizmo=0; + _edit.snap=1; + _edit.gizmo_handle=0; + + + + index=p_index; + editor=p_editor; + editor_selection=editor->get_editor_selection(); + undo_redo=editor->get_undo_redo(); + clicked=0; + clicked_includes_current=false; + orthogonal=false; + message_time=0; + + spatial_editor=p_spatial_editor; + ViewportContainer *c=memnew(ViewportContainer); + c->set_stretch(true); + add_child(c); + c->set_area_as_parent_rect(); + viewport = memnew( Viewport ); + viewport->set_disable_input(true); + + c->add_child(viewport); + surface = memnew( Control ); + add_child(surface); + surface->set_area_as_parent_rect(); + camera = memnew(Camera); + camera->set_disable_gizmo(true); + camera->set_cull_mask( ((1<<20)-1)|(1<<(GIZMO_BASE_LAYER+p_index))|(1<<GIZMO_EDIT_LAYER)|(1<<GIZMO_GRID_LAYER) ); + //camera->set_environment(SpatialEditor::get_singleton()->get_viewport_environment()); + viewport->add_child(camera); + camera->make_current(); + surface->set_focus_mode(FOCUS_ALL); + + view_menu = memnew( MenuButton ); + surface->add_child(view_menu); + view_menu->set_pos( Point2(4,4)); + view_menu->set_self_modulate(Color(1,1,1,0.5)); + view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/top_view"), VIEW_TOP); + view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/bottom_view"), VIEW_BOTTOM); + view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/left_view"), VIEW_LEFT); + view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/right_view"), VIEW_RIGHT); + view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/front_view"), VIEW_FRONT); + view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/rear_view"), VIEW_REAR); + view_menu->get_popup()->add_separator(); + view_menu->get_popup()->add_check_item(TTR("Perspective") + " (" + ED_GET_SHORTCUT("spatial_editor/switch_perspective_orthogonal")->get_as_text() + ")", VIEW_PERSPECTIVE); + view_menu->get_popup()->add_check_item(TTR("Orthogonal") + " (" + ED_GET_SHORTCUT("spatial_editor/switch_perspective_orthogonal")->get_as_text() + ")", VIEW_ORTHOGONAL); + view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE),true); + view_menu->get_popup()->add_separator(); + view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_environment", TTR("Environment")), VIEW_ENVIRONMENT); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT),true); + view_menu->get_popup()->add_separator(); + view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_listener", TTR("Audio Listener")), VIEW_AUDIO_LISTENER); + view_menu->get_popup()->add_separator(); + view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_gizmos", TTR("Gizmos")),VIEW_GIZMOS); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_GIZMOS),true); + + view_menu->get_popup()->add_separator(); + view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/focus_origin"), VIEW_CENTER_TO_ORIGIN); + view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/focus_selection"), VIEW_CENTER_TO_SELECTION); + view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/align_selection_with_view"), VIEW_ALIGN_SELECTION_WITH_VIEW); + view_menu->get_popup()->connect("id_pressed",this,"_menu_option"); + + preview_camera = memnew( Button ); + preview_camera->set_toggle_mode(true); + preview_camera->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,90); + preview_camera->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,10); + preview_camera->set_text("preview"); + surface->add_child(preview_camera); + preview_camera->hide(); + preview_camera->connect("toggled",this,"_toggle_camera_preview"); + previewing=NULL; + preview=NULL; + gizmo_scale=1.0; + + selection_menu = memnew( PopupMenu ); + add_child(selection_menu); + selection_menu->set_custom_minimum_size(Vector2(100, 0)); + selection_menu->connect("id_pressed", this, "_selection_result_pressed"); + selection_menu->connect("popup_hide", this, "_selection_menu_hide"); + + if (p_index==0) { + view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER),true); + viewport->set_as_audio_listener(true); + } + + + name=TTR("Top"); + _update_name(); + + EditorSettings::get_singleton()->connect("settings_changed",this,"update_transform_gizmo_view"); + +} + + + + + + + +SpatialEditor *SpatialEditor::singleton=NULL; + +SpatialEditorSelectedItem::~SpatialEditorSelectedItem() { + + if (sbox_instance.is_valid()) + VisualServer::get_singleton()->free(sbox_instance); +} + + + +void SpatialEditor::select_gizmo_hilight_axis(int p_axis) { + + + for(int i=0;i<3;i++) { + + move_gizmo[i]->surface_set_material(0,i==p_axis?gizmo_hl:gizmo_color[i]); + rotate_gizmo[i]->surface_set_material(0,(i+3)==p_axis?gizmo_hl:gizmo_color[i]); + } + +} + +void SpatialEditor::update_transform_gizmo() { + + List<Node*> &selection = editor_selection->get_selected_node_list(); + Rect3 center; + bool first=true; + + Basis gizmo_basis; + bool local_gizmo_coords = transform_menu->get_popup()->is_item_checked( transform_menu->get_popup()->get_item_index(MENU_TRANSFORM_LOCAL_COORDS) ); + + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Spatial *sp = E->get()->cast_to<Spatial>(); + if (!sp) + continue; + + SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); + if (!se) + continue; + + Transform xf = se->sp->get_global_transform(); + if (first) { + center.pos=xf.origin; + first=false; + if (local_gizmo_coords) { + gizmo_basis=xf.basis; + gizmo_basis.orthonormalize(); + } + } else { + center.expand_to(xf.origin); + gizmo_basis=Basis(); + } + //count++; + } + + Vector3 pcenter = center.pos+center.size*0.5; + gizmo.visible=!first; + gizmo.transform.origin=pcenter; + gizmo.transform.basis=gizmo_basis; + + for(int i=0;i<4;i++) { + viewports[i]->update_transform_gizmo_view(); + } + +} + + +Object *SpatialEditor::_get_editor_data(Object *p_what) { + + Spatial *sp = p_what->cast_to<Spatial>(); + if (!sp) + return NULL; + + + SpatialEditorSelectedItem *si = memnew( SpatialEditorSelectedItem ); + + si->sp=sp; + si->sbox_instance=VisualServer::get_singleton()->instance_create2(selection_box->get_rid(),sp->get_world()->get_scenario()); + VS::get_singleton()->instance_geometry_set_cast_shadows_setting(si->sbox_instance, VS::SHADOW_CASTING_SETTING_OFF); + + if (get_tree()->is_editor_hint()) + editor->call("edit_node",sp); + + return si; +} + +void SpatialEditor::_generate_selection_box() { + + Rect3 aabb( Vector3(), Vector3(1,1,1) ); + aabb.grow_by( aabb.get_longest_axis_size()/20.0 ); + + Ref<SurfaceTool> st = memnew( SurfaceTool ); + + st->begin(Mesh::PRIMITIVE_LINES); + for (int i=0;i<12;i++) { + + Vector3 a,b; + aabb.get_edge(i,a,b); + + /*Vector<Vector3> points; + Vector<Color> colors; + points.push_back(a); + points.push_back(b);*/ + + st->add_color( Color(1.0,1.0,0.8,0.8) ); + st->add_vertex(a); + st->add_color( Color(1.0,1.0,0.8,0.4) ); + st->add_vertex(a.linear_interpolate(b,0.2)); + + st->add_color( Color(1.0,1.0,0.8,0.4) ); + st->add_vertex(a.linear_interpolate(b,0.8)); + st->add_color( Color(1.0,1.0,0.8,0.8) ); + st->add_vertex(b); + + } + + Ref<FixedSpatialMaterial> mat = memnew( FixedSpatialMaterial ); + mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED,true); + mat->set_albedo(Color(1,1,1)); + mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT,true); + mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR,true); + mat->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR,true); + st->set_material(mat); + selection_box = st->commit(); +} + + +Dictionary SpatialEditor::get_state() const { + + + Dictionary d; + + d["snap_enabled"]=snap_enabled; + d["translate_snap"]=get_translate_snap(); + d["rotate_snap"]=get_rotate_snap(); + d["scale_snap"]=get_scale_snap(); + + int local_coords_index=transform_menu->get_popup()->get_item_index(MENU_TRANSFORM_LOCAL_COORDS); + d["local_coords"]=transform_menu->get_popup()->is_item_checked( local_coords_index ); + + int vc=0; + if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT) )) + vc=1; + else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS) )) + vc=2; + else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS) )) + vc=3; + else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS) )) + vc=4; + else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT) )) + vc=5; + else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT) )) + vc=6; + + d["viewport_mode"]=vc; + Array vpdata; + for(int i=0;i<4;i++) { + vpdata.push_back( viewports[i]->get_state() ); + } + + d["viewports"]=vpdata; + + d["default_light"]=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_LIGHT) ); + d["ambient_light_color"]=settings_ambient_color->get_pick_color(); + + d["default_srgb"]=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_SRGB) ); + d["show_grid"]=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_GRID) ); + d["show_origin"]=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN) ); + d["fov"]=get_fov(); + d["znear"]=get_znear(); + d["zfar"]=get_zfar(); + d["deflight_rot_x"]=settings_default_light_rot_x; + d["deflight_rot_y"]=settings_default_light_rot_y; + + return d; +} +void SpatialEditor::set_state(const Dictionary& p_state) { + + Dictionary d = p_state; + + if (d.has("snap_enabled")) { + snap_enabled=d["snap_enabled"]; + int snap_enabled_idx=transform_menu->get_popup()->get_item_index(MENU_TRANSFORM_USE_SNAP); + transform_menu->get_popup()->set_item_checked( snap_enabled_idx, snap_enabled ); + } + + if (d.has("translate_snap")) + snap_translate->set_text(d["translate_snap"]); + + if (d.has("rotate_snap")) + snap_rotate->set_text(d["rotate_snap"]); + + if (d.has("scale_snap")) + snap_scale->set_text(d["scale_snap"]); + + if (d.has("local_coords")) { + int local_coords_idx=transform_menu->get_popup()->get_item_index(MENU_TRANSFORM_LOCAL_COORDS); + transform_menu->get_popup()->set_item_checked( local_coords_idx, d["local_coords"] ); + update_transform_gizmo(); + } + + if (d.has("viewport_mode")) { + int vc = d["viewport_mode"]; + + if (vc==1) + _menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT); + else if (vc==2) + _menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS); + else if (vc==3) + _menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS); + else if (vc==4) + _menu_item_pressed(MENU_VIEW_USE_4_VIEWPORTS); + else if (vc==5) + _menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS_ALT); + else if (vc==6) + _menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS_ALT); + } + + if (d.has("viewports")) { + Array vp = d["viewports"]; + ERR_FAIL_COND(vp.size()>4); + + for(int i=0;i<4;i++) { + viewports[i]->set_state(vp[i]); + } + } + + if (d.has("zfar")) + settings_zfar->set_value(float(d["zfar"])); + if (d.has("znear")) + settings_znear->set_value(float(d["znear"])); + if (d.has("fov")) + settings_fov->set_value(float(d["fov"])); + + if (d.has("default_light")) { + bool use = d["default_light"]; + + bool existing = light_instance.is_valid(); + if (use!=existing) { + if (existing) { + VisualServer::get_singleton()->free(light_instance); + light_instance=RID(); + } else { + light_instance=VisualServer::get_singleton()->instance_create2(light,get_tree()->get_root()->get_world()->get_scenario()); + VisualServer::get_singleton()->instance_set_transform(light_instance,light_transform); + + } + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_LIGHT), light_instance.is_valid() ); + } + + } + if (d.has("ambient_light_color")) { + settings_ambient_color->set_pick_color(d["ambient_light_color"]); + //viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,d["ambient_light_color"]); + } + + if (d.has("default_srgb")) { + bool use = d["default_srgb"]; + + //viewport_environment->set_enable_fx(Environment::FX_SRGB,use); + //view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_SRGB), use ); + } + if (d.has("show_grid")) { + bool use = d["show_grid"]; + + if (use!=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_GRID))) { + _menu_item_pressed(MENU_VIEW_GRID); + } + } + + if (d.has("show_origin")) { + bool use = d["show_origin"]; + + if (use!=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN))) { + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN), use ); + VisualServer::get_singleton()->instance_set_visible(origin_instance,use); + } + } + + if (d.has("deflight_rot_x")) + settings_default_light_rot_x=d["deflight_rot_x"]; + if (d.has("deflight_rot_y")) + settings_default_light_rot_y=d["deflight_rot_y"]; + + _update_default_light_angle(); + + +} + + +void SpatialEditor::edit(Spatial *p_spatial) { + + if (p_spatial!=selected) { + if (selected) { + + Ref<SpatialEditorGizmo> seg = selected->get_gizmo(); + if (seg.is_valid()) { + seg->set_selected(false); + selected->update_gizmo(); + } + } + + selected=p_spatial; + over_gizmo_handle=-1; + + if (selected) { + + Ref<SpatialEditorGizmo> seg = selected->get_gizmo(); + if (seg.is_valid()) { + seg->set_selected(true); + selected->update_gizmo(); + } + } + } + + /* + if (p_spatial) { + _validate_selection(); + if (selected.has(p_spatial->get_instance_ID()) && selected.size()==1) + return; + _select(p_spatial->get_instance_ID(),false,true); + + // should become the selection + } + */ +} + +void SpatialEditor::_xform_dialog_action() { + + Transform t; + //translation + Vector3 scale; + Vector3 rotate; + Vector3 translate; + + for(int i=0;i<3;i++) { + translate[i]=xform_translate[i]->get_text().to_double(); + rotate[i]=Math::deg2rad(xform_rotate[i]->get_text().to_double()); + scale[i]=xform_scale[i]->get_text().to_double(); + } + + t.basis.scale(scale); + t.basis.rotate(rotate); + t.origin=translate; + + + undo_redo->create_action(TTR("XForm Dialog")); + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Spatial *sp = E->get()->cast_to<Spatial>(); + if (!sp) + continue; + + SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); + if (!se) + continue; + + bool post = xform_type->get_selected()>0; + + Transform tr = sp->get_global_transform(); + if (post) + tr = tr * t; + else { + + tr.basis = t.basis * tr.basis; + tr.origin+=t.origin; + } + + undo_redo->add_do_method(sp,"set_global_transform",tr); + undo_redo->add_undo_method(sp,"set_global_transform",sp->get_global_transform()); + } + undo_redo->commit_action(); +} + +void SpatialEditor::_menu_item_pressed(int p_option) { + + switch(p_option) { + + case MENU_TOOL_SELECT: + case MENU_TOOL_MOVE: + case MENU_TOOL_ROTATE: + case MENU_TOOL_SCALE: + case MENU_TOOL_LIST_SELECT: { + + for(int i=0;i<TOOL_MAX;i++) + tool_button[i]->set_pressed(i==p_option); + tool_mode=(ToolMode)p_option; + + //static const char *_mode[]={"Selection Mode.","Translation Mode.","Rotation Mode.","Scale Mode.","List Selection Mode."}; + //set_message(_mode[p_option],3); + update_transform_gizmo(); + + } break; + case MENU_TRANSFORM_USE_SNAP: { + + bool is_checked = transform_menu->get_popup()->is_item_checked( transform_menu->get_popup()->get_item_index(p_option) ); + snap_enabled=!is_checked; + transform_menu->get_popup()->set_item_checked( transform_menu->get_popup()->get_item_index(p_option), snap_enabled ); + } break; + case MENU_TRANSFORM_CONFIGURE_SNAP: { + + snap_dialog->popup_centered(Size2(200,180)); + } break; + case MENU_TRANSFORM_LOCAL_COORDS: { + + bool is_checked = transform_menu->get_popup()->is_item_checked( transform_menu->get_popup()->get_item_index(p_option) ); + transform_menu->get_popup()->set_item_checked( transform_menu->get_popup()->get_item_index(p_option), !is_checked ); + update_transform_gizmo(); + + } break; + case MENU_TRANSFORM_DIALOG: { + + for(int i=0;i<3;i++) { + + + xform_translate[i]->set_text("0"); + xform_rotate[i]->set_text("0"); + xform_scale[i]->set_text("1"); + + } + + xform_dialog->popup_centered(Size2(200,200)); + + } break; + case MENU_VIEW_USE_DEFAULT_LIGHT: { + + bool is_checked = view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(p_option) ); + + if (is_checked) { + VisualServer::get_singleton()->free(light_instance); + light_instance=RID(); + } else { + light_instance=VisualServer::get_singleton()->instance_create2(light,get_tree()->get_root()->get_world()->get_scenario()); + VisualServer::get_singleton()->instance_set_transform(light_instance,light_transform); + + _update_default_light_angle(); + } + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(p_option), light_instance.is_valid() ); + + } break; + case MENU_VIEW_USE_DEFAULT_SRGB: { + + bool is_checked = view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(p_option) ); + + if (is_checked) { + //viewport_environment->set_enable_fx(Environment::FX_SRGB,false); + } else { + //viewport_environment->set_enable_fx(Environment::FX_SRGB,true); + } + + is_checked = ! is_checked; + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(p_option), is_checked ); + + + } break; + case MENU_VIEW_USE_1_VIEWPORT: { + + for(int i=1;i<4;i++) { + + viewports[i]->hide(); + } + + viewports[0]->set_area_as_parent_rect(); + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), true ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); + + } break; + case MENU_VIEW_USE_2_VIEWPORTS: { + + for(int i=1;i<4;i++) { + + if (i==1 || i==3) + viewports[i]->hide(); + else + viewports[i]->show(); + + + } + viewports[0]->set_area_as_parent_rect(); + //viewports[0]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5); + viewports[2]->set_area_as_parent_rect(); + //viewports[2]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5); + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), true ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); + + } break; + case MENU_VIEW_USE_2_VIEWPORTS_ALT: { + + for(int i=1;i<4;i++) { + + if (i==1 || i==3) + viewports[i]->hide(); + else + viewports[i]->show(); + + + } + viewports[0]->set_area_as_parent_rect(); + //viewports[0]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); + viewports[2]->set_area_as_parent_rect(); + //viewports[2]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5); + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), true ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); + + } break; + case MENU_VIEW_USE_3_VIEWPORTS: { + + for(int i=1;i<4;i++) { + + if (i==1) + viewports[i]->hide(); + else + viewports[i]->show(); + } + viewports[0]->set_area_as_parent_rect(); + //viewports[0]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5); + viewports[2]->set_area_as_parent_rect(); + //viewports[2]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); + //viewports[2]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5); + viewports[3]->set_area_as_parent_rect(); + //viewports[3]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5); + //viewports[3]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5); + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), true ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); + + } break; + case MENU_VIEW_USE_3_VIEWPORTS_ALT: { + + for(int i=1;i<4;i++) { + + if (i==1) + viewports[i]->hide(); + else + viewports[i]->show(); + } + viewports[0]->set_area_as_parent_rect(); + //viewports[0]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5); + //viewports[0]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); + viewports[2]->set_area_as_parent_rect(); + //viewports[2]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5); + //viewports[2]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); + viewports[3]->set_area_as_parent_rect(); + //viewports[3]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5); + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), true ); + + } break; + case MENU_VIEW_USE_4_VIEWPORTS: { + + for(int i=1;i<4;i++) { + + viewports[i]->show(); + } + viewports[0]->set_area_as_parent_rect(); + //viewports[0]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); + //viewports[0]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5); + viewports[1]->set_area_as_parent_rect(); + //viewports[1]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5); + //viewports[1]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5); + viewports[2]->set_area_as_parent_rect(); + //viewports[2]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); + //viewports[2]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5); + viewports[3]->set_area_as_parent_rect(); + //viewports[3]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5); + //viewports[3]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5); + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), true ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); + + } break; + case MENU_VIEW_DISPLAY_NORMAL: { + + + VisualServer::get_singleton()->scenario_set_debug( get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_DISABLED ); + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), true ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), false ); + + } break; + case MENU_VIEW_DISPLAY_WIREFRAME: { + + VisualServer::get_singleton()->scenario_set_debug( get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_WIREFRAME ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), true ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), false ); + + } break; + case MENU_VIEW_DISPLAY_OVERDRAW: { + + VisualServer::get_singleton()->scenario_set_debug( get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_OVERDRAW ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), true ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), false ); + + } break; + case MENU_VIEW_DISPLAY_SHADELESS: { + + VisualServer::get_singleton()->scenario_set_debug( get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_SHADELESS ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), false ); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), true ); + + } break; + case MENU_VIEW_ORIGIN: { + + bool is_checked = view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(p_option) ); + + is_checked=!is_checked; + VisualServer::get_singleton()->instance_set_visible(origin_instance,is_checked); + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(p_option), is_checked); + } break; + case MENU_VIEW_GRID: { + + bool is_checked = view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(p_option) ); + + grid_enabled=!is_checked; + + for(int i=0;i<3;++i) { + if (grid_enable[i]) { + VisualServer::get_singleton()->instance_set_visible(grid_instance[i],grid_enabled); + grid_visible[i]=grid_enabled; + } + } + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(p_option), grid_enabled ); + + + } break; + case MENU_VIEW_CAMERA_SETTINGS: { + + settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size()+Size2(50,50)); + } break; + + } +} + + +void SpatialEditor::_init_indicators() { + + //make sure that the camera indicator is not selectable + light=VisualServer::get_singleton()->light_create( VisualServer::LIGHT_DIRECTIONAL ); + //VisualServer::get_singleton()->light_set_shadow( light, true ); + light_instance=VisualServer::get_singleton()->instance_create2(light,get_tree()->get_root()->get_world()->get_scenario()); + + + + light_transform.rotate(Vector3(1,0,0),-Math_PI/5.0); + VisualServer::get_singleton()->instance_set_transform(light_instance,light_transform); + + + //RID mat = VisualServer::get_singleton()->fixed_material_create(); + ///VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA,true); + //VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true); + + + { + + indicator_mat.instance(); + indicator_mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED,true); + //indicator_mat->set_flag(FixedSpatialMaterial::FLAG_ONTOP,true); + indicator_mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR,true); + indicator_mat->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR,true); + + indicator_mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT,true); + + PoolVector<Color> grid_colors[3]; + PoolVector<Vector3> grid_points[3]; + Vector<Color> origin_colors; + Vector<Vector3> origin_points; + + Color grid_color = EditorSettings::get_singleton()->get("editors/3d/grid_color"); + + for(int i=0;i<3;i++) { + Vector3 axis; + axis[i]=1; + Vector3 axis_n1; + axis_n1[(i+1)%3]=1; + Vector3 axis_n2; + axis_n2[(i+2)%3]=1; + + origin_colors.push_back(Color(axis.x,axis.y,axis.z)); + origin_colors.push_back(Color(axis.x,axis.y,axis.z)); + origin_points.push_back(axis*4096); + origin_points.push_back(axis*-4096); +#define ORIGIN_GRID_SIZE 25 + + for(int j=-ORIGIN_GRID_SIZE;j<=ORIGIN_GRID_SIZE;j++) { + + + grid_colors[i].push_back(grid_color); + grid_colors[i].push_back(grid_color); + grid_colors[i].push_back(grid_color); + grid_colors[i].push_back(grid_color); + grid_points[i].push_back(axis_n1*ORIGIN_GRID_SIZE+axis_n2*j); + grid_points[i].push_back(-axis_n1*ORIGIN_GRID_SIZE+axis_n2*j); + grid_points[i].push_back(axis_n2*ORIGIN_GRID_SIZE+axis_n1*j); + grid_points[i].push_back(-axis_n2*ORIGIN_GRID_SIZE+axis_n1*j); + + } + + grid[i] = VisualServer::get_singleton()->mesh_create(); + Array d; + d.resize(VS::ARRAY_MAX); + d[VisualServer::ARRAY_VERTEX]=grid_points[i]; + d[VisualServer::ARRAY_COLOR]=grid_colors[i]; + VisualServer::get_singleton()->mesh_add_surface_from_arrays(grid[i],VisualServer::PRIMITIVE_LINES,d); + VisualServer::get_singleton()->mesh_surface_set_material(grid[i],0,indicator_mat->get_rid()); + grid_instance[i] = VisualServer::get_singleton()->instance_create2(grid[i],get_tree()->get_root()->get_world()->get_scenario()); + + grid_visible[i]=false; + grid_enable[i]=false; + VisualServer::get_singleton()->instance_set_visible(grid_instance[i],false); + VisualServer::get_singleton()->instance_geometry_set_cast_shadows_setting(grid_instance[i], VS::SHADOW_CASTING_SETTING_OFF); + VS::get_singleton()->instance_set_layer_mask(grid_instance[i], 1 << SpatialEditorViewport::GIZMO_GRID_LAYER); + + + } + + origin = VisualServer::get_singleton()->mesh_create(); + Array d; + d.resize(VS::ARRAY_MAX); + d[VisualServer::ARRAY_VERTEX]=origin_points; + d[VisualServer::ARRAY_COLOR]=origin_colors; + + VisualServer::get_singleton()->mesh_add_surface_from_arrays(origin,VisualServer::PRIMITIVE_LINES,d); + VisualServer::get_singleton()->mesh_surface_set_material(origin,0,indicator_mat->get_rid()); + + + //origin = VisualServer::get_singleton()->poly_create(); + //VisualServer::get_singleton()->poly_add_primitive(origin,origin_points,Vector<Vector3>(),origin_colors,Vector<Vector3>()); + //VisualServer::get_singleton()->poly_set_material(origin,indicator_mat,true); + origin_instance = VisualServer::get_singleton()->instance_create2(origin,get_tree()->get_root()->get_world()->get_scenario()); + VS::get_singleton()->instance_set_layer_mask(origin_instance,1<<SpatialEditorViewport::GIZMO_GRID_LAYER); + + VisualServer::get_singleton()->instance_geometry_set_cast_shadows_setting(origin_instance, VS::SHADOW_CASTING_SETTING_OFF); + + + + VisualServer::get_singleton()->instance_set_visible(grid_instance[1],true); + grid_enable[1]=true; + grid_visible[1]=true; + grid_enabled=true; + last_grid_snap=1; + + } + + { + cursor_mesh = VisualServer::get_singleton()->mesh_create(); + PoolVector<Vector3> cursor_points; + float cs = 0.25; + cursor_points.push_back(Vector3(+cs,0,0)); + cursor_points.push_back(Vector3(-cs,0,0)); + cursor_points.push_back(Vector3(0,+cs,0)); + cursor_points.push_back(Vector3(0,-cs,0)); + cursor_points.push_back(Vector3(0,0,+cs)); + cursor_points.push_back(Vector3(0,0,-cs)); + cursor_material.instance(); + cursor_material->set_albedo(Color(0,1,1)); + cursor_material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED,true); + + Array d; + d.resize(VS::ARRAY_MAX); + d[VS::ARRAY_VERTEX]=cursor_points; + VisualServer::get_singleton()->mesh_add_surface_from_arrays(cursor_mesh,VS::PRIMITIVE_LINES,d); + VisualServer::get_singleton()->mesh_surface_set_material(cursor_mesh,0,cursor_material->get_rid()); + + cursor_instance = VisualServer::get_singleton()->instance_create2(cursor_mesh,get_tree()->get_root()->get_world()->get_scenario()); + VS::get_singleton()->instance_set_layer_mask(cursor_instance,1<<SpatialEditorViewport::GIZMO_GRID_LAYER); + + VisualServer::get_singleton()->instance_geometry_set_cast_shadows_setting(cursor_instance, VS::SHADOW_CASTING_SETTING_OFF); + + + } + + + { + + //move gizmo + + + float gizmo_alph = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_opacity"); + + gizmo_hl = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ) ); + gizmo_hl->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true); + gizmo_hl->set_flag(FixedSpatialMaterial::FLAG_ONTOP, true); + gizmo_hl->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true); + gizmo_hl->set_albedo(Color(1,1,1,gizmo_alph+0.2f)); + + for(int i=0;i<3;i++) { + + move_gizmo[i]=Ref<Mesh>( memnew( Mesh ) ); + rotate_gizmo[i]=Ref<Mesh>( memnew( Mesh ) ); + + + Ref<FixedSpatialMaterial> mat = memnew( FixedSpatialMaterial ); + mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true); + mat->set_flag(FixedSpatialMaterial::FLAG_ONTOP, true); + mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true); + Color col; + col[i]=1.0; + col.a= gizmo_alph; + mat->set_albedo(col); + gizmo_color[i]=mat; + + + + + Vector3 ivec; + ivec[i]=1; + Vector3 nivec; + nivec[(i+1)%3]=1; + nivec[(i+2)%3]=1; + Vector3 ivec2; + ivec2[(i+1)%3]=1; + Vector3 ivec3; + ivec3[(i+2)%3]=1; + + + { + + Ref<SurfaceTool> surftool = memnew( SurfaceTool ); + surftool->begin(Mesh::PRIMITIVE_TRIANGLES); + + //translate + + const int arrow_points=5; + Vector3 arrow[5]={ + nivec*0.0+ivec*0.0, + nivec*0.01+ivec*0.0, + nivec*0.01+ivec*1.0, + nivec*0.1+ivec*1.0, + nivec*0.0+ivec*(1+GIZMO_ARROW_SIZE), + }; + + int arrow_sides=6; + + + for(int k = 0; k < 7 ; k++) { + + + Basis ma(ivec,Math_PI*2*float(k)/arrow_sides); + Basis mb(ivec,Math_PI*2*float(k+1)/arrow_sides); + + + for(int j=0;j<arrow_points-1;j++) { + + Vector3 points[4]={ + ma.xform(arrow[j]), + mb.xform(arrow[j]), + mb.xform(arrow[j+1]), + ma.xform(arrow[j+1]), + }; + surftool->add_vertex(points[0]); + surftool->add_vertex(points[1]); + surftool->add_vertex(points[2]); + + surftool->add_vertex(points[0]); + surftool->add_vertex(points[2]); + surftool->add_vertex(points[3]); + } + + } + + surftool->set_material(mat); + surftool->commit(move_gizmo[i]); + } + + { + + + Ref<SurfaceTool> surftool = memnew( SurfaceTool ); + surftool->begin(Mesh::PRIMITIVE_TRIANGLES); + + Vector3 circle[5]={ + ivec*0.02+ivec2*0.02+ivec2*1.0, + ivec*-0.02+ivec2*0.02+ivec2*1.0, + ivec*-0.02+ivec2*-0.02+ivec2*1.0, + ivec*0.02+ivec2*-0.02+ivec2*1.0, + ivec*0.02+ivec2*0.02+ivec2*1.0, + }; + + + for(int k = 0; k < 33 ; k++) { + + + Basis ma(ivec,Math_PI*2*float(k)/32); + Basis mb(ivec,Math_PI*2*float(k+1)/32); + + + for(int j=0;j<4;j++) { + + Vector3 points[4]={ + ma.xform(circle[j]), + mb.xform(circle[j]), + mb.xform(circle[j+1]), + ma.xform(circle[j+1]), + }; + surftool->add_vertex(points[0]); + surftool->add_vertex(points[1]); + surftool->add_vertex(points[2]); + + surftool->add_vertex(points[0]); + surftool->add_vertex(points[2]); + surftool->add_vertex(points[3]); + } + + } + + surftool->set_material(mat); + surftool->commit(rotate_gizmo[i]); + + } + + + } + } + + /*for(int i=0;i<4;i++) { + + viewports[i]->init_gizmo_instance(i); + }*/ + + _generate_selection_box(); + + + //get_scene()->get_root_node()->cast_to<EditorNode>()->get_scene_root()->add_child(camera); + + //current_camera=camera; + +} + +void SpatialEditor::_finish_indicators() { + + VisualServer::get_singleton()->free(origin_instance); + VisualServer::get_singleton()->free(origin); + for(int i=0;i<3;i++) { + VisualServer::get_singleton()->free(grid_instance[i]); + VisualServer::get_singleton()->free(grid[i]); + } + VisualServer::get_singleton()->free(light_instance); + VisualServer::get_singleton()->free(light); + //VisualServer::get_singleton()->free(poly); + //VisualServer::get_singleton()->free(indicators_instance); + //VisualServer::get_singleton()->free(indicators); + + VisualServer::get_singleton()->free(cursor_instance); + VisualServer::get_singleton()->free(cursor_mesh); +} + +void SpatialEditor::_instance_scene() { +#if 0 + EditorNode *en = get_scene()->get_root_node()->cast_to<EditorNode>(); + ERR_FAIL_COND(!en); + String path = en->get_filesystem_dock()->get_selected_path(); + if (path=="") { + set_message(TTR("No scene selected to instance!")); + return; + } + + undo_redo->create_action(TTR("Instance at Cursor")); + + Node* scene = en->request_instance_scene(path); + + if (!scene) { + set_message(TTR("Could not instance scene!")); + undo_redo->commit_action(); //bleh + return; + } + + Spatial *s = scene->cast_to<Spatial>(); + if (s) { + + undo_redo->add_do_method(s,"set_global_transform",Transform(Matrix3(),cursor.cursor_pos)); + } + + undo_redo->commit_action(); +#endif +} + +void SpatialEditor::_unhandled_key_input(InputEvent p_event) { + + if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack()) + return; + +#if 0 +//i don't remember this being used, why was it here? + { + + EditorNode *en = editor; + EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); + + if (!over_plugin_list->empty() && over_plugin_list->forward_gui_input(p_event)) { + + return; //ate the over input event + } + + } +#endif + + switch(p_event.type) { + + case InputEvent::KEY: { + + + const InputEventKey &k=p_event.key; + + if (!k.pressed) + break; + + switch(k.scancode) { + + case KEY_Q: _menu_item_pressed(MENU_TOOL_SELECT); break; + case KEY_W: _menu_item_pressed(MENU_TOOL_MOVE); break; + case KEY_E: _menu_item_pressed(MENU_TOOL_ROTATE); break; + case KEY_R: _menu_item_pressed(MENU_TOOL_SCALE); break; + + case KEY_Z: { + if (k.mod.shift || k.mod.control || k.mod.command) + break; + + if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME))) { + _menu_item_pressed(MENU_VIEW_DISPLAY_NORMAL); + } else { + _menu_item_pressed(MENU_VIEW_DISPLAY_WIREFRAME); + } + } break; + +#if 0 +#endif + } + + } break; + } +} +void SpatialEditor::_notification(int p_what) { + + if (p_what==NOTIFICATION_READY) { + + tool_button[SpatialEditor::TOOL_MODE_SELECT]->set_icon( get_icon("ToolSelect","EditorIcons") ); + tool_button[SpatialEditor::TOOL_MODE_MOVE]->set_icon( get_icon("ToolMove","EditorIcons") ); + tool_button[SpatialEditor::TOOL_MODE_ROTATE]->set_icon( get_icon("ToolRotate","EditorIcons") ); + tool_button[SpatialEditor::TOOL_MODE_SCALE]->set_icon( get_icon("ToolScale","EditorIcons") ); + tool_button[SpatialEditor::TOOL_MODE_LIST_SELECT]->set_icon( get_icon("ListSelect","EditorIcons") ); + instance_button->set_icon( get_icon("SpatialAdd","EditorIcons") ); + instance_button->hide(); + + + view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT),get_icon("Panels1","EditorIcons")); + view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS),get_icon("Panels2","EditorIcons")); + view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT),get_icon("Panels2Alt","EditorIcons")); + view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS),get_icon("Panels3","EditorIcons")); + view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT),get_icon("Panels3Alt","EditorIcons")); + view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS),get_icon("Panels4","EditorIcons")); + + _menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT); + + get_tree()->connect("node_removed",this,"_node_removed"); + VS::get_singleton()->scenario_set_fallback_environment(get_viewport()->find_world()->get_scenario(),viewport_environment->get_rid()); + + } + + if (p_what==NOTIFICATION_ENTER_TREE) { + + gizmos = memnew( SpatialEditorGizmos ); + _init_indicators(); + _update_default_light_angle(); + } + + if (p_what==NOTIFICATION_EXIT_TREE) { + + _finish_indicators(); + memdelete( gizmos ); + + } +} + +void SpatialEditor::add_control_to_menu_panel(Control *p_control) { + + + hbc_menu->add_child(p_control); +} + +void SpatialEditor::set_can_preview(Camera* p_preview) { + + for(int i=0;i<4;i++) { + viewports[i]->set_can_preview(p_preview); + } +} + +VSplitContainer *SpatialEditor::get_shader_split() { + + return shader_split; +} + +HSplitContainer *SpatialEditor::get_palette_split() { + + return palette_split; +} + + +void SpatialEditor::_request_gizmo(Object* p_obj) { + + Spatial *sp=p_obj->cast_to<Spatial>(); + if (!sp) + return; + if (editor->get_edited_scene() && (sp==editor->get_edited_scene() || sp->get_owner()==editor->get_edited_scene() || editor->get_edited_scene()->is_editable_instance(sp->get_owner()))) { + + Ref<SpatialEditorGizmo> seg; + + for(int i=0;i<EditorNode::get_singleton()->get_editor_data().get_editor_plugin_count();i++) { + + seg = EditorNode::get_singleton()->get_editor_data().get_editor_plugin(i)->create_spatial_gizmo(sp); + if (seg.is_valid()) + break; + } + + if (!seg.is_valid()) { + seg = gizmos->get_gizmo(sp); + } + + if (seg.is_valid()) { + sp->set_gizmo(seg); + } + + + if (seg.is_valid() && sp==selected) { + seg->set_selected(true); + selected->update_gizmo(); + } + + } +} + +void SpatialEditor::_toggle_maximize_view(Object* p_viewport) { + if (!p_viewport) return; + SpatialEditorViewport *current_viewport = p_viewport->cast_to<SpatialEditorViewport>(); + if (!current_viewport) return; + + int index=-1; + bool maximized = false; + for(int i=0;i<4;i++) { + if (viewports[i]==current_viewport) { + index=i; + if ( current_viewport->get_global_rect() == viewport_base->get_global_rect() ) + maximized=true; + break; + } + } + if (index==-1) return; + + if (!maximized) { + + for(int i=0;i<4;i++) { + if (i==index) + viewports[i]->set_area_as_parent_rect(); + else + viewports[i]->hide(); + } + } else { + + for(int i=0;i<4;i++) + viewports[i]->show(); + + if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT) )) + _menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT); + else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS) )) + _menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS); + else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT) )) + _menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS_ALT); + else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS) )) + _menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS); + else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT) )) + _menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS_ALT); + else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS) )) + _menu_item_pressed(MENU_VIEW_USE_4_VIEWPORTS); + } + +} + + +void SpatialEditor::_node_removed(Node* p_node) { + + if (p_node==selected) + selected=NULL; +} + +void SpatialEditor::_bind_methods() { + + //ClassDB::bind_method("_gui_input",&SpatialEditor::_gui_input); + ClassDB::bind_method("_unhandled_key_input",&SpatialEditor::_unhandled_key_input); + ClassDB::bind_method("_node_removed",&SpatialEditor::_node_removed); + ClassDB::bind_method("_menu_item_pressed",&SpatialEditor::_menu_item_pressed); + ClassDB::bind_method("_xform_dialog_action",&SpatialEditor::_xform_dialog_action); + ClassDB::bind_method("_instance_scene",&SpatialEditor::_instance_scene); + ClassDB::bind_method("_get_editor_data",&SpatialEditor::_get_editor_data); + ClassDB::bind_method("_request_gizmo",&SpatialEditor::_request_gizmo); + ClassDB::bind_method("_default_light_angle_input",&SpatialEditor::_default_light_angle_input); + ClassDB::bind_method("_update_ambient_light_color",&SpatialEditor::_update_ambient_light_color); + ClassDB::bind_method("_toggle_maximize_view",&SpatialEditor::_toggle_maximize_view); + + ADD_SIGNAL( MethodInfo("transform_key_request") ); + + +} + +void SpatialEditor::clear() { + + settings_fov->set_value(EDITOR_DEF("editors/3d/default_fov",60.0)); + settings_znear->set_value(EDITOR_DEF("editors/3d/default_z_near",0.1)); + settings_zfar->set_value(EDITOR_DEF("editors/3d/default_z_far",1500.0)); + + for(int i=0;i<4;i++) { + viewports[i]->reset(); + } + + _menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT); + _menu_item_pressed(MENU_VIEW_DISPLAY_NORMAL); + + + VisualServer::get_singleton()->instance_set_visible(origin_instance,true); + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN), true); + for(int i=0;i<3;++i) { + if (grid_enable[i]) { + VisualServer::get_singleton()->instance_set_visible(grid_instance[i],true); + grid_visible[i]=true; + } + } + + for(int i=0;i<4;i++) { + + viewports[i]->view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(SpatialEditorViewport::VIEW_AUDIO_LISTENER),i==0); + viewports[i]->viewport->set_as_audio_listener(i==0); + } + + view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_GRID), true ); + + settings_default_light_rot_x=Math_PI*0.3; + settings_default_light_rot_y=Math_PI*0.2; + + //viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,Color(0.15,0.15,0.15)); + settings_ambient_color->set_pick_color(Color(0.15,0.15,0.15)); + if (!light_instance.is_valid()) + _menu_item_pressed(MENU_VIEW_USE_DEFAULT_LIGHT); + + _update_default_light_angle(); + + +} + + +void SpatialEditor::_update_ambient_light_color(const Color& p_color) { + + //viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,settings_ambient_color->get_color()); + +} + +void SpatialEditor::_update_default_light_angle() { + + Transform t; + t.basis.rotate(Vector3(1,0,0),-settings_default_light_rot_x); + t.basis.rotate(Vector3(0,1,0),-settings_default_light_rot_y); + settings_dlight->set_transform(t); + if (light_instance.is_valid()) { + VS::get_singleton()->instance_set_transform(light_instance,t); + } + +} + +void SpatialEditor::_default_light_angle_input(const InputEvent& p_event) { + + + if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&(0x1|0x2|0x4)) { + + settings_default_light_rot_y = Math::fposmod(settings_default_light_rot_y - p_event.mouse_motion.relative_x*0.01,Math_PI*2.0); + settings_default_light_rot_x = Math::fposmod(settings_default_light_rot_x - p_event.mouse_motion.relative_y*0.01,Math_PI*2.0); + _update_default_light_angle(); + } + +} + + +SpatialEditor::SpatialEditor(EditorNode *p_editor) { + + gizmo.visible=true; + gizmo.scale=1.0; + + viewport_environment = Ref<Environment>( memnew( Environment ) ); + undo_redo=p_editor->get_undo_redo(); + VBoxContainer *vbc = this; + + custom_camera=NULL; + singleton=this; + editor=p_editor; + editor_selection=editor->get_editor_selection(); + editor_selection->add_editor_plugin(this); + + snap_enabled=false; + tool_mode = TOOL_MODE_SELECT; + + //set_focus_mode(FOCUS_ALL); + + hbc_menu = memnew( HBoxContainer ); + vbc->add_child(hbc_menu); + + + Vector<Variant> button_binds; + button_binds.resize(1); + + tool_button[TOOL_MODE_SELECT] = memnew( ToolButton ); + hbc_menu->add_child( tool_button[TOOL_MODE_SELECT] ); + tool_button[TOOL_MODE_SELECT]->set_toggle_mode(true); + tool_button[TOOL_MODE_SELECT]->set_flat(true); + tool_button[TOOL_MODE_SELECT]->set_pressed(true); + button_binds[0]=MENU_TOOL_SELECT; + tool_button[TOOL_MODE_SELECT]->connect("pressed", this,"_menu_item_pressed",button_binds); + tool_button[TOOL_MODE_SELECT]->set_tooltip("Select Mode (Q)\n"+keycode_get_string(KEY_MASK_CMD)+"Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"); + + + tool_button[TOOL_MODE_MOVE] = memnew( ToolButton ); + + hbc_menu->add_child( tool_button[TOOL_MODE_MOVE] ); + tool_button[TOOL_MODE_MOVE]->set_toggle_mode(true); + tool_button[TOOL_MODE_MOVE]->set_flat(true); + button_binds[0]=MENU_TOOL_MOVE; + tool_button[TOOL_MODE_MOVE]->connect("pressed", this,"_menu_item_pressed",button_binds); + tool_button[TOOL_MODE_MOVE]->set_tooltip(TTR("Move Mode (W)")); + + tool_button[TOOL_MODE_ROTATE] = memnew( ToolButton ); + hbc_menu->add_child( tool_button[TOOL_MODE_ROTATE] ); + tool_button[TOOL_MODE_ROTATE]->set_toggle_mode(true); + tool_button[TOOL_MODE_ROTATE]->set_flat(true); + button_binds[0]=MENU_TOOL_ROTATE; + tool_button[TOOL_MODE_ROTATE]->connect("pressed", this,"_menu_item_pressed",button_binds); + tool_button[TOOL_MODE_ROTATE]->set_tooltip(TTR("Rotate Mode (E)")); + + tool_button[TOOL_MODE_SCALE] = memnew( ToolButton ); + hbc_menu->add_child( tool_button[TOOL_MODE_SCALE] ); + tool_button[TOOL_MODE_SCALE]->set_toggle_mode(true); + tool_button[TOOL_MODE_SCALE]->set_flat(true); + button_binds[0]=MENU_TOOL_SCALE; + tool_button[TOOL_MODE_SCALE]->connect("pressed", this,"_menu_item_pressed",button_binds); + tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)")); + + instance_button = memnew( Button ); + hbc_menu->add_child( instance_button ); + instance_button->set_flat(true); + instance_button->connect("pressed",this,"_instance_scene"); + instance_button->hide(); + + VSeparator *vs = memnew( VSeparator ); + hbc_menu->add_child(vs); + + tool_button[TOOL_MODE_LIST_SELECT] = memnew( ToolButton ); + hbc_menu->add_child( tool_button[TOOL_MODE_LIST_SELECT] ); + tool_button[TOOL_MODE_LIST_SELECT]->set_toggle_mode(true); + tool_button[TOOL_MODE_LIST_SELECT]->set_flat(true); + button_binds[0]=MENU_TOOL_LIST_SELECT; + tool_button[TOOL_MODE_LIST_SELECT]->connect("pressed", this,"_menu_item_pressed",button_binds); + tool_button[TOOL_MODE_LIST_SELECT]->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode).")); + + vs = memnew( VSeparator ); + hbc_menu->add_child(vs); + + + ED_SHORTCUT("spatial_editor/bottom_view", TTR("Bottom View"), KEY_MASK_ALT+KEY_KP_7); + ED_SHORTCUT("spatial_editor/top_view", TTR("Top View"), KEY_KP_7); + ED_SHORTCUT("spatial_editor/rear_view", TTR("Rear View"), KEY_MASK_ALT+KEY_KP_1); + ED_SHORTCUT("spatial_editor/front_view", TTR("Front View"), KEY_KP_1); + ED_SHORTCUT("spatial_editor/left_view", TTR("Left View"), KEY_MASK_ALT+KEY_KP_3); + ED_SHORTCUT("spatial_editor/right_view", TTR("Right View"), KEY_KP_3); + ED_SHORTCUT("spatial_editor/switch_perspective_orthogonal", TTR("Switch Perspective/Orthogonal view"), KEY_KP_5); + ED_SHORTCUT("spatial_editor/snap", TTR("Snap"), KEY_S); + ED_SHORTCUT("spatial_editor/insert_anim_key", TTR("Insert Animation Key"), KEY_K); + ED_SHORTCUT("spatial_editor/focus_origin", TTR("Focus Origin"), KEY_O); + ED_SHORTCUT("spatial_editor/focus_selection", TTR("Focus Selection"), KEY_F); + ED_SHORTCUT("spatial_editor/align_selection_with_view", TTR("Align Selection With View"), KEY_MASK_ALT+KEY_MASK_CMD+KEY_F); + + + PopupMenu *p; + + transform_menu = memnew( MenuButton ); + transform_menu->set_text(TTR("Transform")); + hbc_menu->add_child( transform_menu ); + + p = transform_menu->get_popup(); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/use_snap", TTR("Use Snap")), MENU_TRANSFORM_USE_SNAP); + p->add_shortcut(ED_SHORTCUT("spatial_editor/configure_snap", TTR("Configure Snap..")), MENU_TRANSFORM_CONFIGURE_SNAP); + p->add_separator(); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/local_coords", TTR("Local Coords")), MENU_TRANSFORM_LOCAL_COORDS); + //p->set_item_checked(p->get_item_count()-1,true); + p->add_separator(); + p->add_shortcut(ED_SHORTCUT("spatial_editor/transform_dialog", TTR("Transform Dialog..")), MENU_TRANSFORM_DIALOG); + + p->connect("id_pressed", this,"_menu_item_pressed"); + + view_menu = memnew( MenuButton ); + view_menu->set_text(TTR("View")); + view_menu->set_pos( Point2( 212,0) ); + hbc_menu->add_child( view_menu ); + + p = view_menu->get_popup(); + + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/use_default_light", TTR("Use Default Light")), MENU_VIEW_USE_DEFAULT_LIGHT); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/use_default_srgb", TTR("Use Default sRGB")), MENU_VIEW_USE_DEFAULT_SRGB); + p->add_separator(); + + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/1_viewport", TTR("1 Viewport"), KEY_MASK_CMD+KEY_1), MENU_VIEW_USE_1_VIEWPORT); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports", TTR("2 Viewports"), KEY_MASK_CMD+KEY_2), MENU_VIEW_USE_2_VIEWPORTS); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports_alt", TTR("2 Viewports (Alt)"), KEY_MASK_ALT+KEY_MASK_CMD+KEY_2), MENU_VIEW_USE_2_VIEWPORTS_ALT); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/3_viewports", TTR("3 Viewports"),KEY_MASK_CMD+KEY_3), MENU_VIEW_USE_3_VIEWPORTS); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/3_viewports_alt", TTR("3 Viewports (Alt)"), KEY_MASK_ALT+KEY_MASK_CMD+KEY_3), MENU_VIEW_USE_3_VIEWPORTS_ALT); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/4_viewports", TTR("4 Viewports"), KEY_MASK_CMD+KEY_4), MENU_VIEW_USE_4_VIEWPORTS); + p->add_separator(); + + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_normal", TTR("Display Normal")), MENU_VIEW_DISPLAY_NORMAL); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_wireframe", TTR("Display Wireframe")), MENU_VIEW_DISPLAY_WIREFRAME); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_overdraw", TTR("Display Overdraw")), MENU_VIEW_DISPLAY_OVERDRAW); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_shadeless", TTR("Display Shadeless")), MENU_VIEW_DISPLAY_SHADELESS); + p->add_separator(); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_origin", TTR("View Origin")), MENU_VIEW_ORIGIN); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_grid", TTR("View Grid")), MENU_VIEW_GRID); + p->add_separator(); + p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings")), MENU_VIEW_CAMERA_SETTINGS); + + + p->set_item_checked( p->get_item_index(MENU_VIEW_USE_DEFAULT_LIGHT), true ); + p->set_item_checked( p->get_item_index(MENU_VIEW_DISPLAY_NORMAL), true ); + p->set_item_checked( p->get_item_index(MENU_VIEW_ORIGIN), true ); + p->set_item_checked( p->get_item_index(MENU_VIEW_GRID), true ); + + + p->connect("id_pressed", this,"_menu_item_pressed"); + + + /* REST OF MENU */ + + palette_split = memnew( HSplitContainer); + palette_split->set_v_size_flags(SIZE_EXPAND_FILL); + vbc->add_child(palette_split); + + shader_split = memnew( VSplitContainer ); + shader_split->set_h_size_flags(SIZE_EXPAND_FILL); + palette_split->add_child(shader_split); + viewport_base = memnew( Control ); + shader_split->add_child(viewport_base); + viewport_base->set_v_size_flags(SIZE_EXPAND_FILL); + for(int i=0;i<4;i++) { + + viewports[i] = memnew( SpatialEditorViewport(this,editor,i) ); + viewports[i]->connect("toggle_maximize_view",this,"_toggle_maximize_view"); + viewport_base->add_child(viewports[i]); + } + //vbc->add_child(viewport_base); + + + + + /* SNAP DIALOG */ + + snap_dialog = memnew( ConfirmationDialog ); + snap_dialog->set_title(TTR("Snap Settings")); + add_child(snap_dialog); + + VBoxContainer *snap_dialog_vbc = memnew( VBoxContainer ); + snap_dialog->add_child(snap_dialog_vbc); + //snap_dialog->set_child_rect(snap_dialog_vbc); + + snap_translate = memnew( LineEdit ); + snap_translate->set_text("1"); + snap_dialog_vbc->add_margin_child(TTR("Translate Snap:"),snap_translate); + + snap_rotate = memnew( LineEdit ); + snap_rotate->set_text("5"); + snap_dialog_vbc->add_margin_child(TTR("Rotate Snap (deg.):"),snap_rotate); + + snap_scale = memnew( LineEdit ); + snap_scale->set_text("5"); + snap_dialog_vbc->add_margin_child(TTR("Scale Snap (%):"),snap_scale); + + /* SETTINGS DIALOG */ + + settings_dialog = memnew( ConfirmationDialog ); + settings_dialog->set_title(TTR("Viewport Settings")); + add_child(settings_dialog); + settings_vbc = memnew( VBoxContainer ); + settings_vbc->set_custom_minimum_size(Size2(200,0)); + settings_dialog->add_child(settings_vbc); + //settings_dialog->set_child_rect(settings_vbc); + + + + settings_light_base = memnew( ViewportContainer ); + settings_light_base->set_custom_minimum_size(Size2(128,128)); + settings_light_base->connect("gui_input",this,"_default_light_angle_input"); + settings_vbc->add_margin_child(TTR("Default Light Normal:"),settings_light_base); + settings_light_vp = memnew( Viewport ); + settings_light_vp->set_disable_input(true); + settings_light_vp->set_use_own_world(true); + settings_light_base->add_child(settings_light_vp); + + settings_dlight = memnew( DirectionalLight ); + settings_light_vp->add_child(settings_dlight); + settings_sphere = memnew( ImmediateGeometry ); + settings_sphere->begin(Mesh::PRIMITIVE_TRIANGLES,Ref<Texture>()); + settings_sphere->set_color(Color(1,1,1)); + settings_sphere->add_sphere(32,16,1); + settings_sphere->end(); + settings_light_vp->add_child(settings_sphere); + settings_camera = memnew( Camera ); + settings_light_vp->add_child(settings_camera); + settings_camera->set_translation(Vector3(0,0,2)); + settings_camera->set_orthogonal(2.1,0.1,5); + + settings_default_light_rot_x=Math_PI*0.3; + settings_default_light_rot_y=Math_PI*0.2; + + + + settings_ambient_color = memnew( ColorPickerButton ); + settings_vbc->add_margin_child(TTR("Ambient Light Color:"),settings_ambient_color); + settings_ambient_color->connect("color_changed",this,"_update_ambient_light_color"); + settings_ambient_color->set_pick_color(Color(0.15,0.15,0.15)); + + + settings_fov = memnew( SpinBox ); + settings_fov->set_max(179); + settings_fov->set_min(1); + settings_fov->set_step(0.01); + settings_fov->set_value(EDITOR_DEF("editors/3d/default_fov",60.0)); + settings_vbc->add_margin_child(TTR("Perspective FOV (deg.):"),settings_fov); + + settings_znear = memnew( SpinBox ); + settings_znear->set_max(10000); + settings_znear->set_min(0.1); + settings_znear->set_step(0.01); + settings_znear->set_value(EDITOR_DEF("editors/3d/default_z_near",0.1)); + settings_vbc->add_margin_child(TTR("View Z-Near:"),settings_znear); + + settings_zfar = memnew( SpinBox ); + settings_zfar->set_max(10000); + settings_zfar->set_min(0.1); + settings_zfar->set_step(0.01); + settings_zfar->set_value(EDITOR_DEF("editors/3d/default_z_far",1500)); + settings_vbc->add_margin_child(TTR("View Z-Far:"),settings_zfar); + + //settings_dialog->get_cancel()->hide(); + /* XFORM DIALOG */ + + xform_dialog = memnew( ConfirmationDialog ); + xform_dialog->set_title(TTR("Transform Change")); + add_child(xform_dialog); + Label *l = memnew(Label); + l->set_text(TTR("Translate:")); + l->set_pos(Point2(5,5)); + xform_dialog->add_child(l); + + for(int i=0;i<3;i++) { + + xform_translate[i] = memnew( LineEdit ); + xform_translate[i]->set_pos( Point2(15+i*60,22) ); + xform_translate[i]->set_size( Size2(50,12 ) ); + xform_dialog->add_child( xform_translate[i] ); + } + + l = memnew(Label); + l->set_text(TTR("Rotate (deg.):")); + l->set_pos(Point2(5,45)); + xform_dialog->add_child(l); + + for(int i=0;i<3;i++) { + xform_rotate[i] = memnew( LineEdit ); + xform_rotate[i]->set_pos( Point2(15+i*60,62) ); + xform_rotate[i]->set_size( Size2(50,22 ) ); + xform_dialog->add_child(xform_rotate[i]); + } + + l = memnew(Label); + l->set_text(TTR("Scale (ratio):")); + l->set_pos(Point2(5,85)); + xform_dialog->add_child(l); + + for(int i=0;i<3;i++) { + xform_scale[i] = memnew( LineEdit ); + xform_scale[i]->set_pos( Point2(15+i*60,102) ); + xform_scale[i]->set_size( Size2(50,22 ) ); + xform_dialog->add_child(xform_scale[i]); + } + + l = memnew(Label); + l->set_text(TTR("Transform Type")); + l->set_pos(Point2(5,125)); + xform_dialog->add_child(l); + + xform_type = memnew( OptionButton ); + xform_type->set_anchor( MARGIN_RIGHT, ANCHOR_END ); + xform_type->set_begin( Point2(15,142) ); + xform_type->set_end( Point2(15,75) ); + xform_type->add_item(TTR("Pre")); + xform_type->add_item(TTR("Post")); + xform_dialog->add_child(xform_type); + + xform_dialog->connect("confirmed", this,"_xform_dialog_action"); + + scenario_debug=VisualServer::SCENARIO_DEBUG_DISABLED; + + selected=NULL; + + set_process_unhandled_key_input(true); + add_to_group("_spatial_editor_group"); + + EDITOR_DEF("editors/3d/manipulator_gizmo_size",80); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT,"editors/3d/manipulator_gizmo_size",PROPERTY_HINT_RANGE,"16,1024,1")); + EDITOR_DEF("editors/3d/manipulator_gizmo_opacity",0.2); + + over_gizmo_handle=-1; +} + +SpatialEditor::~SpatialEditor() { + + +} + + + + +void SpatialEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + + + spatial_editor->show(); + spatial_editor->set_process(true); + //VisualServer::get_singleton()->viewport_set_hide_scenario(editor->get_scene_root()->get_viewport(),false); + spatial_editor->grab_focus(); + + } else { + + spatial_editor->hide(); + spatial_editor->set_process(false); + //VisualServer::get_singleton()->viewport_set_hide_scenario(editor->get_scene_root()->get_viewport(),true); + + } + +} +void SpatialEditorPlugin::edit(Object *p_object) { + + spatial_editor->edit(p_object->cast_to<Spatial>()); +} + +bool SpatialEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("Spatial"); +} + +Dictionary SpatialEditorPlugin::get_state() const { + return spatial_editor->get_state(); +} + +void SpatialEditorPlugin::set_state(const Dictionary& p_state) { + + spatial_editor->set_state(p_state); +} + +void SpatialEditor::snap_cursor_to_plane(const Plane& p_plane) { + + //cursor.pos=p_plane.project(cursor.pos); +} + +void SpatialEditorPlugin::_bind_methods() { + + ClassDB::bind_method("snap_cursor_to_plane",&SpatialEditorPlugin::snap_cursor_to_plane); + +} + +void SpatialEditorPlugin::snap_cursor_to_plane(const Plane& p_plane) { + + + spatial_editor->snap_cursor_to_plane(p_plane); +} + + + + +SpatialEditorPlugin::SpatialEditorPlugin(EditorNode *p_node) { + + editor=p_node; + spatial_editor = memnew( SpatialEditor(p_node) ); + spatial_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); + editor->get_viewport()->add_child(spatial_editor); + + //spatial_editor->set_area_as_parent_rect(); + spatial_editor->hide(); + spatial_editor->connect("transform_key_request",editor,"_transform_keyed"); + + //spatial_editor->set_process(true); +} + + +SpatialEditorPlugin::~SpatialEditorPlugin() { + +} diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h new file mode 100644 index 0000000000..44ce4a0281 --- /dev/null +++ b/editor/plugins/spatial_editor_plugin.h @@ -0,0 +1,574 @@ +/*************************************************************************/ +/* spatial_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef SPATIAL_EDITOR_PLUGIN_H +#define SPATIAL_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/3d/visual_instance.h" +#include "scene/3d/immediate_geometry.h" +#include "scene/3d/light.h" +#include "scene/gui/panel_container.h" +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +class Camera; +class SpatialEditor; +class SpatialEditorGizmos; + +class SpatialEditorGizmo : public SpatialGizmo { + + GDCLASS(SpatialEditorGizmo,SpatialGizmo); + + bool selected; +public: + + void set_selected(bool p_selected) { selected=p_selected; } + bool is_selected() const { return selected; } + + virtual String get_handle_name(int p_idx) const; + virtual Variant get_handle_value(int p_idx) const; + virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); + virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); + + virtual bool intersect_frustum(const Camera *p_camera,const Vector<Plane> &p_frustum); + virtual bool intersect_ray(const Camera *p_camera,const Point2& p_point, Vector3& r_pos, Vector3& r_normal,int *r_gizmo_handle=NULL,bool p_sec_first=false); + SpatialEditorGizmo(); +}; + + +class SpatialEditorViewport : public Control { + + GDCLASS( SpatialEditorViewport, Control ); +friend class SpatialEditor; + enum { + + VIEW_TOP, + VIEW_BOTTOM, + VIEW_LEFT, + VIEW_RIGHT, + VIEW_FRONT, + VIEW_REAR, + VIEW_CENTER_TO_ORIGIN, + VIEW_CENTER_TO_SELECTION, + VIEW_ALIGN_SELECTION_WITH_VIEW, + VIEW_PERSPECTIVE, + VIEW_ENVIRONMENT, + VIEW_ORTHOGONAL, + VIEW_AUDIO_LISTENER, + VIEW_GIZMOS, + }; +public: + enum { + GIZMO_BASE_LAYER=27, + GIZMO_EDIT_LAYER=26, + GIZMO_GRID_LAYER=25 + }; +private: + int index; + String name; + void _menu_option(int p_option); + Size2 prev_size; + + EditorNode *editor; + EditorSelection *editor_selection; + UndoRedo *undo_redo; + + Button *preview_camera; + + MenuButton *view_menu; + + Control *surface; + Viewport *viewport; + Camera *camera; + bool transforming; + bool orthogonal; + float gizmo_scale; + + struct _RayResult { + + Spatial* item; + float depth; + int handle; + _FORCE_INLINE_ bool operator<(const _RayResult& p_rr) const { return depth<p_rr.depth; } + }; + + void _update_name(); + void _compute_edit(const Point2& p_point); + void _clear_selected(); + void _select_clicked(bool p_append,bool p_single); + void _select(Spatial *p_node, bool p_append,bool p_single); + ObjectID _select_ray(const Point2& p_pos, bool p_append,bool &r_includes_current,int *r_gizmo_handle=NULL,bool p_alt_select=false); + void _find_items_at_pos(const Point2& p_pos,bool &r_includes_current,Vector<_RayResult> &results,bool p_alt_select=false); + Vector3 _get_ray_pos(const Vector2& p_pos) const; + Vector3 _get_ray(const Vector2& p_pos); + Point2 _point_to_screen(const Vector3& p_point); + Transform _get_camera_transform() const; + int get_selected_count() const; + + Vector3 _get_camera_pos() const; + Vector3 _get_camera_normal() const; + Vector3 _get_screen_to_space(const Vector3& p_vector3); + + void _select_region(); + bool _gizmo_select(const Vector2& p_screenpos,bool p_hilite_only=false); + + float get_znear() const; + float get_zfar() const; + float get_fov() const; + + ObjectID clicked; + Vector<_RayResult> selection_results; + bool clicked_includes_current; + bool clicked_wants_append; + + PopupMenu *selection_menu; + + enum NavigationScheme { + NAVIGATION_GODOT, + NAVIGATION_MAYA, + NAVIGATION_MODO, + }; + + enum NavigationZoomStyle { + NAVIGATION_ZOOM_VERTICAL, + NAVIGATION_ZOOM_HORIZONTAL + }; + + enum NavigationMode { + NAVIGATION_NONE, + NAVIGATION_PAN, + NAVIGATION_ZOOM, + NAVIGATION_ORBIT + }; + enum TransformMode { + TRANSFORM_NONE, + TRANSFORM_ROTATE, + TRANSFORM_TRANSLATE, + TRANSFORM_SCALE + + }; + enum TransformPlane { + TRANSFORM_VIEW, + TRANSFORM_X_AXIS, + TRANSFORM_Y_AXIS, + TRANSFORM_Z_AXIS, + }; + + struct EditData { + TransformMode mode; + TransformPlane plane; + Transform original; + Vector3 click_ray; + Vector3 click_ray_pos; + Vector3 center; + Vector3 orig_gizmo_pos; + int edited_gizmo; + Point2 mouse_pos; + bool snap; + Ref<SpatialEditorGizmo> gizmo; + int gizmo_handle; + Variant gizmo_initial_value; + Vector3 gizmo_initial_pos; + } _edit; + + struct Cursor { + + Vector3 cursor_pos; + + Vector3 pos; + float x_rot,y_rot,distance; + bool region_select; + Point2 region_begin,region_end; + + Cursor() { x_rot=y_rot=0.5; distance=4; region_select=false; } + } cursor; + + RID move_gizmo_instance[3], rotate_gizmo_instance[3]; + + + String last_message; + String message; + float message_time; + + void set_message(String p_message,float p_time=5); + + // + void _update_camera(); + void _draw(); + + void _smouseenter(); + void _sinput(const InputEvent& p_ie); + SpatialEditor *spatial_editor; + + Camera* previewing; + Camera* preview; + + void _preview_exited_scene(); + void _toggle_camera_preview(bool); + void _init_gizmo_instance(int p_idx); + void _finish_gizmo_instances(); + void _selection_result_pressed(int); + void _selection_menu_hide(); + void _list_select(InputEventMouseButton b); + + +protected: + + void _notification(int p_what); + static void _bind_methods(); +public: + + void update_transform_gizmo_view(); + + void set_can_preview(Camera* p_preview); + void set_state(const Dictionary& p_state); + Dictionary get_state() const; + void reset(); + + void focus_selection(); + + Viewport *get_viewport_node() { return viewport; } + + + SpatialEditorViewport(SpatialEditor *p_spatial_editor,EditorNode *p_editor,int p_index); +}; + + + +class SpatialEditorSelectedItem : public Object { + + GDCLASS(SpatialEditorSelectedItem,Object); + +public: + + Rect3 aabb; + Transform original; // original location when moving + Transform last_xform; // last transform + Spatial *sp; + RID sbox_instance; + + SpatialEditorSelectedItem() { sp=NULL; } + ~SpatialEditorSelectedItem(); +}; + +class SpatialEditor : public VBoxContainer { + + GDCLASS(SpatialEditor, VBoxContainer ); +public: + + enum ToolMode { + + TOOL_MODE_SELECT, + TOOL_MODE_MOVE, + TOOL_MODE_ROTATE, + TOOL_MODE_SCALE, + TOOL_MODE_LIST_SELECT, + TOOL_MAX + + }; + + +private: + EditorNode *editor; + EditorSelection *editor_selection; + + + + Control *viewport_base; + SpatialEditorViewport *viewports[4]; + VSplitContainer *shader_split; + HSplitContainer *palette_split; + + ///// + + ToolMode tool_mode; + bool orthogonal; + + + VisualServer::ScenarioDebugMode scenario_debug; + + RID light; + RID light_instance; + Transform light_transform; + + + RID origin; + RID origin_instance; + RID grid[3]; + RID grid_instance[3]; + bool grid_visible[3]; //currently visible + float last_grid_snap; + bool grid_enable[3]; //should be always visible if true + bool grid_enabled; + + Ref<Mesh> move_gizmo[3], rotate_gizmo[3]; + Ref<FixedSpatialMaterial> gizmo_color[3]; + Ref<FixedSpatialMaterial> gizmo_hl; + + + int over_gizmo_handle; + + + + Ref<Mesh> selection_box; + RID indicators; + RID indicators_instance; + RID cursor_mesh; + RID cursor_instance; + Ref<FixedSpatialMaterial> indicator_mat; + Ref<FixedSpatialMaterial> cursor_material; + +/* + struct Selected { + AABB aabb; + Transform original; // original location when moving + Transform last_xform; // last transform + Spatial *sp; + RID poly_instance; + }; + + Map<uint32_t,Selected> selected; +*/ + struct Gizmo { + + bool visible; + float scale; + Transform transform; + } gizmo; + + + + + enum MenuOption { + + MENU_TOOL_SELECT, + MENU_TOOL_MOVE, + MENU_TOOL_ROTATE, + MENU_TOOL_SCALE, + MENU_TOOL_LIST_SELECT, + MENU_TRANSFORM_USE_SNAP, + MENU_TRANSFORM_CONFIGURE_SNAP, + MENU_TRANSFORM_LOCAL_COORDS, + MENU_TRANSFORM_DIALOG, + MENU_VIEW_USE_1_VIEWPORT, + MENU_VIEW_USE_2_VIEWPORTS, + MENU_VIEW_USE_2_VIEWPORTS_ALT, + MENU_VIEW_USE_3_VIEWPORTS, + MENU_VIEW_USE_3_VIEWPORTS_ALT, + MENU_VIEW_USE_4_VIEWPORTS, + MENU_VIEW_USE_DEFAULT_LIGHT, + MENU_VIEW_USE_DEFAULT_SRGB, + MENU_VIEW_DISPLAY_NORMAL, + MENU_VIEW_DISPLAY_WIREFRAME, + MENU_VIEW_DISPLAY_OVERDRAW, + MENU_VIEW_DISPLAY_SHADELESS, + MENU_VIEW_ORIGIN, + MENU_VIEW_GRID, + MENU_VIEW_CAMERA_SETTINGS, + + }; + + + Button *tool_button[TOOL_MAX]; + Button *instance_button; + + + MenuButton* transform_menu; + MenuButton* view_menu; + + ConfirmationDialog *snap_dialog; + ConfirmationDialog *xform_dialog; + ConfirmationDialog *settings_dialog; + + bool snap_enabled; + LineEdit *snap_translate; + LineEdit *snap_rotate; + LineEdit *snap_scale; + PanelContainer* menu_panel; + + LineEdit *xform_translate[3]; + LineEdit *xform_rotate[3]; + LineEdit *xform_scale[3]; + OptionButton *xform_type; + + VBoxContainer *settings_vbc; + SpinBox *settings_fov; + SpinBox *settings_znear; + SpinBox *settings_zfar; + DirectionalLight *settings_dlight; + ImmediateGeometry *settings_sphere; + Camera *settings_camera; + float settings_default_light_rot_x; + float settings_default_light_rot_y; + + ViewportContainer *settings_light_base; + Viewport *settings_light_vp; + ColorPickerButton *settings_ambient_color; + Image settings_light_dir_image; + + + void _xform_dialog_action(); + void _menu_item_pressed(int p_option); + + HBoxContainer *hbc_menu; + + + +// +// + void _generate_selection_box(); + UndoRedo *undo_redo; + + void _instance_scene(); + void _init_indicators(); + void _finish_indicators(); + + void _toggle_maximize_view(Object* p_viewport); + + Node *custom_camera; + + Object *_get_editor_data(Object *p_what); + + Ref<Environment> viewport_environment; + + Spatial *selected; + + void _request_gizmo(Object* p_obj); + + static SpatialEditor *singleton; + + void _node_removed(Node* p_node); + SpatialEditorGizmos *gizmos; + SpatialEditor(); + + void _update_ambient_light_color(const Color& p_color); + void _update_default_light_angle(); + void _default_light_angle_input(const InputEvent& p_event); + +protected: + + + + + void _notification(int p_what); + //void _gui_input(InputEvent p_event); + void _unhandled_key_input(InputEvent p_event); + + static void _bind_methods(); +public: + + + static SpatialEditor *get_singleton() { return singleton; } + void snap_cursor_to_plane(const Plane& p_plane); + + float get_znear() const { return settings_znear->get_value(); } + float get_zfar() const { return settings_zfar->get_value(); } + float get_fov() const { return settings_fov->get_value(); } + + Transform get_gizmo_transform() const { return gizmo.transform; } + bool is_gizmo_visible() const { return gizmo.visible; } + + ToolMode get_tool_mode() const { return tool_mode; } + bool is_snap_enabled() const { return snap_enabled; } + float get_translate_snap() const { return snap_translate->get_text().to_double(); } + float get_rotate_snap() const { return snap_rotate->get_text().to_double(); } + float get_scale_snap() const { return snap_scale->get_text().to_double(); } + + Ref<Mesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; } + Ref<Mesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; } + + void update_transform_gizmo(); + + void select_gizmo_hilight_axis(int p_axis); + void set_custom_camera(Node *p_camera) { custom_camera=p_camera; } + + void set_undo_redo(UndoRedo *p_undo_redo) {undo_redo=p_undo_redo; } + Dictionary get_state() const; + void set_state(const Dictionary& p_state); + + Ref<Environment> get_viewport_environment() { return viewport_environment; } + + UndoRedo *get_undo_redo() { return undo_redo; } + + void add_control_to_menu_panel(Control *p_control); + + VSplitContainer *get_shader_split(); + HSplitContainer *get_palette_split(); + + Spatial *get_selected() { return selected; } + + int get_over_gizmo_handle() const { return over_gizmo_handle; } + void set_over_gizmo_handle(int idx) { over_gizmo_handle=idx; } + + void set_can_preview(Camera* p_preview); + + SpatialEditorViewport *get_editor_viewport(int p_idx) { + ERR_FAIL_INDEX_V(p_idx,4,NULL); + return viewports[p_idx]; + } + + Camera *get_camera() { return NULL; } + void edit(Spatial *p_spatial); + void clear(); + SpatialEditor(EditorNode *p_editor); + ~SpatialEditor(); +}; + +class SpatialEditorPlugin : public EditorPlugin { + + GDCLASS( SpatialEditorPlugin, EditorPlugin ); + + SpatialEditor *spatial_editor; + EditorNode *editor; +protected: + static void _bind_methods(); +public: + + void snap_cursor_to_plane(const Plane& p_plane); + + SpatialEditor *get_spatial_editor() { return spatial_editor; } + virtual String get_name() const { return "3D"; } + bool has_main_screen() const { return true; } + virtual void make_visible(bool p_visible); + virtual void edit(Object *p_object); + virtual bool handles(Object *p_object) const; + + virtual Dictionary get_state() const; + virtual void set_state(const Dictionary& p_state); + virtual void clear() { spatial_editor->clear(); } + + + SpatialEditorPlugin(EditorNode *p_node); + ~SpatialEditorPlugin(); + +}; + +#endif diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp new file mode 100644 index 0000000000..44d6d3c6e1 --- /dev/null +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -0,0 +1,969 @@ +/*************************************************************************/ +/* sprite_frames_editor_plugin.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 "sprite_frames_editor_plugin.h" + +#include "io/resource_loader.h" +#include "global_config.h" +#include "editor/editor_settings.h" +#include "scene/3d/sprite_3d.h" + + + +void SpriteFramesEditor::_gui_input(InputEvent p_event) { + + +} + +void SpriteFramesEditor::_notification(int p_what) { + + if (p_what==NOTIFICATION_FIXED_PROCESS) { + + } + + if (p_what==NOTIFICATION_ENTER_TREE) { + load->set_icon( get_icon("Folder","EditorIcons") ); + _delete->set_icon( get_icon("Del","EditorIcons") ); + new_anim->set_icon( get_icon("New","EditorIcons") ); + remove_anim->set_icon( get_icon("Del","EditorIcons") ); + + } + + if (p_what==NOTIFICATION_READY) { + + //NodePath("/root")->connect("node_removed", this,"_node_removed",Vector<Variant>(),true); + } + + if (p_what==NOTIFICATION_DRAW) { + + } +} + +void SpriteFramesEditor::_file_load_request(const PoolVector<String>& p_path,int p_at_pos) { + + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + + List< Ref<Texture> > resources; + + for(int i=0;i<p_path.size();i++) { + + Ref<Texture> resource; + resource = ResourceLoader::load(p_path[i]); + + if (resource.is_null()) { + dialog->set_text(TTR("ERROR: Couldn't load frame resource!")); + dialog->set_title(TTR("Error!")); + //dialog->get_cancel()->set_text("Close"); + dialog->get_ok()->set_text(TTR("Close")); + dialog->popup_centered_minsize(); + return; ///beh should show an error i guess + } + + resources.push_back(resource); + } + + + if (resources.empty()) { + //print_line("added frames!"); + return; + } + + undo_redo->create_action(TTR("Add Frame")); + int fc=frames->get_frame_count(edited_anim); + + int count=0; + + for(List< Ref<Texture> >::Element *E=resources.front();E;E=E->next() ) { + + undo_redo->add_do_method(frames,"add_frame",edited_anim,E->get(),p_at_pos==-1?-1:p_at_pos+count); + undo_redo->add_undo_method(frames,"remove_frame",edited_anim,p_at_pos==-1?fc:p_at_pos); + count++; + + } + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + + undo_redo->commit_action(); + //print_line("added frames!"); +} + +void SpriteFramesEditor::_load_pressed() { + + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + loading_scene=false; + + file->clear_filters(); + List<String> extensions; + ResourceLoader::get_recognized_extensions_for_type("Texture",&extensions); + for(int i=0;i<extensions.size();i++) + file->add_filter("*."+extensions[i]); + + file->set_mode(EditorFileDialog::MODE_OPEN_FILES); + + file->popup_centered_ratio(); + +} + + +void SpriteFramesEditor::_item_edited() { + +#if 0 + if (!tree->get_selected()) + return; + + TreeItem *s = tree->get_selected(); + + if (tree->get_selected_column()==0) { + // renamed + String old_name=s->get_metadata(0); + String new_name=s->get_text(0); + if (old_name==new_name) + return; + + if (new_name=="" || new_name.find("\\")!=-1 || new_name.find("/")!=-1 || frames->has_resource(new_name)) { + + s->set_text(0,old_name); + return; + } + + RES samp = frames->get_resource(old_name); + undo_redo->create_action("Rename Resource"); + undo_redo->add_do_method(frames,"remove_resource",old_name); + undo_redo->add_do_method(frames,"add_resource",new_name,samp); + undo_redo->add_undo_method(frames,"remove_resource",new_name); + undo_redo->add_undo_method(frames,"add_resource",old_name,samp); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + + } +#endif + +} + +void SpriteFramesEditor::_delete_confirm_pressed() { + + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + + if (tree->get_current()<0) + return; + + sel-=1; + if (sel<0 && frames->get_frame_count(edited_anim)) + sel=0; + + int to_remove = tree->get_current(); + sel=to_remove; + Ref<Texture> r = frames->get_frame(edited_anim,to_remove); + undo_redo->create_action(TTR("Delete Resource")); + undo_redo->add_do_method(frames,"remove_frame",edited_anim,to_remove); + undo_redo->add_undo_method(frames,"add_frame",edited_anim,r,to_remove); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + +} + + +void SpriteFramesEditor::_paste_pressed() { + + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + + Ref<Texture> r=EditorSettings::get_singleton()->get_resource_clipboard(); + if (!r.is_valid()) { + dialog->set_text(TTR("Resource clipboard is empty or not a texture!")); + dialog->set_title(TTR("Error!")); + //dialog->get_cancel()->set_text("Close"); + dialog->get_ok()->set_text(TTR("Close")); + dialog->popup_centered_minsize(); + return; ///beh should show an error i guess + } + + + undo_redo->create_action(TTR("Paste Frame")); + undo_redo->add_do_method(frames,"add_frame",edited_anim,r); + undo_redo->add_undo_method(frames,"remove_frame",edited_anim,frames->get_frame_count(edited_anim)); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + +} + +void SpriteFramesEditor::_empty_pressed() { + + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + + int from=-1; + + if (tree->get_current()>=0) { + + from = tree->get_current(); + sel=from; + + } else { + from=frames->get_frame_count(edited_anim); + } + + + + Ref<Texture> r; + + undo_redo->create_action(TTR("Add Empty")); + undo_redo->add_do_method(frames,"add_frame",edited_anim,r,from); + undo_redo->add_undo_method(frames,"remove_frame",edited_anim,from); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + +} + +void SpriteFramesEditor::_empty2_pressed() { + + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + + int from=-1; + + if (tree->get_current()>=0) { + + from = tree->get_current(); + sel=from; + + } else { + from=frames->get_frame_count(edited_anim); + } + + + + Ref<Texture> r; + + undo_redo->create_action(TTR("Add Empty")); + undo_redo->add_do_method(frames,"add_frame",edited_anim,r,from+1); + undo_redo->add_undo_method(frames,"remove_frame",edited_anim,from+1); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + +} + +void SpriteFramesEditor::_up_pressed() { + + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + + if (tree->get_current()<0) + return; + + int to_move = tree->get_current(); + if (to_move<1) + return; + + sel=to_move; + sel-=1; + + Ref<Texture> r = frames->get_frame(edited_anim,to_move); + undo_redo->create_action(TTR("Delete Resource")); + undo_redo->add_do_method(frames,"set_frame",edited_anim,to_move,frames->get_frame(edited_anim,to_move-1)); + undo_redo->add_do_method(frames,"set_frame",edited_anim,to_move-1,frames->get_frame(edited_anim,to_move)); + undo_redo->add_undo_method(frames,"set_frame",edited_anim,to_move,frames->get_frame(edited_anim,to_move)); + undo_redo->add_undo_method(frames,"set_frame",edited_anim,to_move-1,frames->get_frame(edited_anim,to_move-1)); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + +} + +void SpriteFramesEditor::_down_pressed() { + + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + + if (tree->get_current()<0) + return; + + int to_move = tree->get_current(); + if (to_move<0 || to_move>=frames->get_frame_count(edited_anim)-1) + return; + + sel=to_move; + sel+=1; + + Ref<Texture> r = frames->get_frame(edited_anim,to_move); + undo_redo->create_action(TTR("Delete Resource")); + undo_redo->add_do_method(frames,"set_frame",edited_anim,to_move,frames->get_frame(edited_anim,to_move+1)); + undo_redo->add_do_method(frames,"set_frame",edited_anim,to_move+1,frames->get_frame(edited_anim,to_move)); + undo_redo->add_undo_method(frames,"set_frame",edited_anim,to_move,frames->get_frame(edited_anim,to_move)); + undo_redo->add_undo_method(frames,"set_frame",edited_anim,to_move+1,frames->get_frame(edited_anim,to_move+1)); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + + + +} + + +void SpriteFramesEditor::_delete_pressed() { + + + if (tree->get_current()<0) + return; + + _delete_confirm_pressed(); //it has undo.. why bother with a dialog.. + /* + dialog->set_title("Confirm..."); + dialog->set_text("Remove Resource '"+tree->get_selected()->get_text(0)+"' ?"); + //dialog->get_cancel()->set_text("Cancel"); + //dialog->get_ok()->show(); + dialog->get_ok()->set_text("Remove"); + dialog->popup_centered(Size2(300,60));*/ + +} + + +void SpriteFramesEditor::_animation_select() { + + if (updating) + return; + + TreeItem *selected = animations->get_selected(); + ERR_FAIL_COND(!selected); + edited_anim=selected->get_text(0); + _update_library(true); + +} + + +static void _find_anim_sprites(Node* p_node,List<Node*> *r_nodes,Ref<SpriteFrames> p_sfames) { + + Node *edited = EditorNode::get_singleton()->get_edited_scene(); + if (!edited) + return; + if (p_node!=edited && p_node->get_owner()!=edited) + return; + + { + AnimatedSprite *as = p_node->cast_to<AnimatedSprite>(); + if (as && as->get_sprite_frames()==p_sfames) { + r_nodes->push_back(p_node); + } + } + + { + AnimatedSprite3D *as = p_node->cast_to<AnimatedSprite3D>(); + if (as && as->get_sprite_frames()==p_sfames) { + r_nodes->push_back(p_node); + } + } + + for(int i=0;i<p_node->get_child_count();i++) { + _find_anim_sprites(p_node->get_child(i),r_nodes,p_sfames); + } + +} + +void SpriteFramesEditor::_animation_name_edited(){ + + if (updating) + return; + + if (!frames->has_animation(edited_anim)) + return; + + TreeItem *edited = animations->get_edited(); + if (!edited) + return; + + String new_name = edited->get_text(0); + + if (new_name==String(edited_anim)) + return; + + new_name=new_name.replace("/","_").replace(","," "); + + String name=new_name; + int counter=0; + while(frames->has_animation(name)) { + counter++; + name=new_name+" "+itos(counter); + } + + List<Node*> nodes; + _find_anim_sprites(EditorNode::get_singleton()->get_edited_scene(),&nodes,Ref<SpriteFrames>(frames)); + + undo_redo->create_action(TTR("Rename Animation")); + undo_redo->add_do_method(frames,"rename_animation",edited_anim,name); + undo_redo->add_undo_method(frames,"rename_animation",name,edited_anim); + + for(List<Node*>::Element *E=nodes.front();E;E=E->next()) { + + String current = E->get()->call("get_animation"); + if (current!=edited_anim) + continue; + + undo_redo->add_do_method(E->get(),"set_animation",name); + undo_redo->add_undo_method(E->get(),"set_animation",edited_anim); + + } + + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + + edited_anim=new_name; + + undo_redo->commit_action(); + + + +} +void SpriteFramesEditor::_animation_add(){ + + + String new_name = "New Anim"; + + String name=new_name; + int counter=0; + while(frames->has_animation(name)) { + counter++; + name=new_name+" "+itos(counter); + } + + List<Node*> nodes; + _find_anim_sprites(EditorNode::get_singleton()->get_edited_scene(),&nodes,Ref<SpriteFrames>(frames)); + + + undo_redo->create_action(TTR("Add Animation")); + undo_redo->add_do_method(frames,"add_animation",name); + undo_redo->add_undo_method(frames,"remove_animation",name); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + + + for(List<Node*>::Element *E=nodes.front();E;E=E->next()) { + + String current = E->get()->call("get_animation"); + if (frames->has_animation(current)) + continue; + + undo_redo->add_do_method(E->get(),"set_animation",name); + undo_redo->add_undo_method(E->get(),"set_animation",current); + + } + + edited_anim=new_name; + + undo_redo->commit_action(); + +} +void SpriteFramesEditor::_animation_remove(){ + + //fuck everything + if (updating) + return; + + if (!frames->has_animation(edited_anim)) + return; + + + undo_redo->create_action(TTR("Remove Animation")); + undo_redo->add_do_method(frames,"remove_animation",edited_anim); + undo_redo->add_undo_method(frames,"add_animation",edited_anim); + undo_redo->add_undo_method(frames,"set_animation_speed",edited_anim,frames->get_animation_speed(edited_anim)); + undo_redo->add_undo_method(frames,"set_animation_loop",edited_anim,frames->get_animation_loop(edited_anim)); + int fc = frames->get_frame_count(edited_anim); + for(int i=0;i<fc;i++) { + Ref<Texture> frame = frames->get_frame(edited_anim,i); + undo_redo->add_undo_method(frames,"add_frame",edited_anim,frame); + } + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + + undo_redo->commit_action(); + +} + + +void SpriteFramesEditor::_animation_loop_changed() { + + if (updating) + return; + + undo_redo->create_action(TTR("Change Animation Loop")); + undo_redo->add_do_method(frames,"set_animation_loop",edited_anim,anim_loop->is_pressed()); + undo_redo->add_undo_method(frames,"set_animation_loop",edited_anim,frames->get_animation_loop(edited_anim)); + undo_redo->add_do_method(this,"_update_library",true); + undo_redo->add_undo_method(this,"_update_library",true); + undo_redo->commit_action(); + +} + +void SpriteFramesEditor::_animation_fps_changed(double p_value) { + + if (updating) + return; + + undo_redo->create_action(TTR("Change Animation FPS"),UndoRedo::MERGE_ENDS); + undo_redo->add_do_method(frames,"set_animation_speed",edited_anim,p_value); + undo_redo->add_undo_method(frames,"set_animation_speed",edited_anim,frames->get_animation_speed(edited_anim)); + undo_redo->add_do_method(this,"_update_library",true); + undo_redo->add_undo_method(this,"_update_library",true); + + undo_redo->commit_action(); + +} + +void SpriteFramesEditor::_update_library(bool p_skip_selector) { + + updating=true; + + if (!p_skip_selector) { + animations->clear(); + + TreeItem *anim_root=animations->create_item(); + + List<StringName> anim_names; + + anim_names.sort_custom<StringName::AlphCompare>(); + + frames->get_animation_list(&anim_names); + + anim_names.sort_custom<StringName::AlphCompare>(); + + for(List<StringName>::Element *E=anim_names.front();E;E=E->next()) { + + String name = E->get(); + + TreeItem *it = animations->create_item(anim_root); + + it->set_metadata(0,name); + + it->set_text(0,name); + it->set_editable(0,true); + + if (E->get()==edited_anim) { + it->select(0); + } + } + } + + + tree->clear(); + + if (!frames->has_animation(edited_anim)) { + updating=false; + return; + } + + + if (sel>=frames->get_frame_count(edited_anim)) + sel=frames->get_frame_count(edited_anim)-1; + else if (sel<0 && frames->get_frame_count(edited_anim)) + sel=0; + + for(int i=0;i<frames->get_frame_count(edited_anim);i++) { + + + String name; + Ref<Texture> icon; + + + if (frames->get_frame(edited_anim,i).is_null()) { + + name=itos(i)+": "+TTR("(empty)"); + + } else { + name=itos(i)+": "+frames->get_frame(edited_anim,i)->get_name(); + icon=frames->get_frame(edited_anim,i); + } + + tree->add_item(name,icon); + if (frames->get_frame(edited_anim,i).is_valid()) + tree->set_item_tooltip(tree->get_item_count()-1,frames->get_frame(edited_anim,i)->get_path()); + if (sel==i) + tree->select(tree->get_item_count()-1); + } + + anim_speed->set_value(frames->get_animation_speed(edited_anim)); + anim_loop->set_pressed(frames->get_animation_loop(edited_anim)); + + updating=false; + //player->add_resource("default",resource); +} + + + +void SpriteFramesEditor::edit(SpriteFrames* p_frames) { + + if (frames==p_frames) + return; + + frames=p_frames; + + + if (p_frames) { + + if (!p_frames->has_animation(edited_anim)) { + + List<StringName> anim_names; + frames->get_animation_list(&anim_names); + anim_names.sort_custom<StringName::AlphCompare>(); + if (anim_names.size()) { + edited_anim=anim_names.front()->get(); + } else { + edited_anim=StringName(); + } + + } + + _update_library(); + } else { + + hide(); + //set_fixed_process(false); + } + +} + + +Variant SpriteFramesEditor::get_drag_data_fw(const Point2& p_point,Control* p_from) { + + if (!frames->has_animation(edited_anim)) + return false; + + int idx = tree->get_item_at_pos(p_point,true); + + if (idx<0 || idx>=frames->get_frame_count(edited_anim)) + return Variant(); + + RES frame = frames->get_frame(edited_anim,idx); + + if (frame.is_null()) + return Variant(); + + return EditorNode::get_singleton()->drag_resource(frame,p_from); + + +} + +bool SpriteFramesEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const{ + + Dictionary d = p_data; + + if (!d.has("type")) + return false; + + if (d.has("from") && (Object*)(d["from"])==tree) + return false; + + if (String(d["type"])=="resource" && d.has("resource")) { + RES r=d["resource"]; + + Ref<Texture> texture = r; + + if (texture.is_valid()) { + + return true; + } + } + + + if (String(d["type"])=="files") { + + Vector<String> files = d["files"]; + + if (files.size()==0) + return false; + + for(int i=0;i<files.size();i++) { + String file = files[0]; + String ftype = EditorFileSystem::get_singleton()->get_file_type(file); + + if (!ClassDB::is_parent_class(ftype,"Texture")) { + return false; + } + + } + + return true; + + } + return false; +} + +void SpriteFramesEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from){ + + if (!can_drop_data_fw(p_point,p_data,p_from)) + return; + + Dictionary d = p_data; + + if (!d.has("type")) + return; + + int at_pos = tree->get_item_at_pos(p_point,true); + + if (String(d["type"])=="resource" && d.has("resource")) { + RES r=d["resource"]; + + Ref<Texture> texture = r; + + if (texture.is_valid()) { + + undo_redo->create_action(TTR("Add Frame")); + undo_redo->add_do_method(frames,"add_frame",edited_anim,texture,at_pos==-1?-1:at_pos); + undo_redo->add_undo_method(frames,"remove_frame",edited_anim,at_pos==-1?frames->get_frame_count(edited_anim):at_pos); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + + } + } + + + if (String(d["type"])=="files") { + + PoolVector<String> files = d["files"]; + + _file_load_request(files,at_pos); + } + +} + + +void SpriteFramesEditor::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_gui_input"),&SpriteFramesEditor::_gui_input); + ClassDB::bind_method(D_METHOD("_load_pressed"),&SpriteFramesEditor::_load_pressed); + ClassDB::bind_method(D_METHOD("_empty_pressed"),&SpriteFramesEditor::_empty_pressed); + ClassDB::bind_method(D_METHOD("_empty2_pressed"),&SpriteFramesEditor::_empty2_pressed); + ClassDB::bind_method(D_METHOD("_item_edited"),&SpriteFramesEditor::_item_edited); + ClassDB::bind_method(D_METHOD("_delete_pressed"),&SpriteFramesEditor::_delete_pressed); + ClassDB::bind_method(D_METHOD("_paste_pressed"),&SpriteFramesEditor::_paste_pressed); + ClassDB::bind_method(D_METHOD("_delete_confirm_pressed"),&SpriteFramesEditor::_delete_confirm_pressed); + ClassDB::bind_method(D_METHOD("_file_load_request","files","atpos"),&SpriteFramesEditor::_file_load_request,DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("_update_library","skipsel"),&SpriteFramesEditor::_update_library,DEFVAL(false)); + ClassDB::bind_method(D_METHOD("_up_pressed"),&SpriteFramesEditor::_up_pressed); + ClassDB::bind_method(D_METHOD("_down_pressed"),&SpriteFramesEditor::_down_pressed); + ClassDB::bind_method(D_METHOD("_animation_select"),&SpriteFramesEditor::_animation_select); + ClassDB::bind_method(D_METHOD("_animation_name_edited"),&SpriteFramesEditor::_animation_name_edited); + ClassDB::bind_method(D_METHOD("_animation_add"),&SpriteFramesEditor::_animation_add); + ClassDB::bind_method(D_METHOD("_animation_remove"),&SpriteFramesEditor::_animation_remove); + ClassDB::bind_method(D_METHOD("_animation_loop_changed"),&SpriteFramesEditor::_animation_loop_changed); + ClassDB::bind_method(D_METHOD("_animation_fps_changed"),&SpriteFramesEditor::_animation_fps_changed); + ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &SpriteFramesEditor::get_drag_data_fw); + ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SpriteFramesEditor::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("drop_data_fw"), &SpriteFramesEditor::drop_data_fw); + + +} + + +SpriteFramesEditor::SpriteFramesEditor() { + + //add_style_override("panel", get_stylebox("panel","Panel")); + + split = memnew( HSplitContainer ); + add_child(split); + + VBoxContainer *vbc_animlist = memnew( VBoxContainer ); + split->add_child(vbc_animlist); + vbc_animlist->set_custom_minimum_size(Size2(150,0)); + //vbc_animlist->set_v_size_flags(SIZE_EXPAND_FILL); + + + VBoxContainer *sub_vb = memnew( VBoxContainer ); + vbc_animlist->add_margin_child(TTR("Animations"),sub_vb,true); + sub_vb->set_v_size_flags(SIZE_EXPAND_FILL); + + HBoxContainer *hbc_animlist = memnew( HBoxContainer ); + sub_vb->add_child(hbc_animlist); + + new_anim = memnew( Button ); + hbc_animlist->add_child(new_anim); + new_anim->connect("pressed",this,"_animation_add"); + + + hbc_animlist->add_spacer(); + + remove_anim = memnew( Button ); + hbc_animlist->add_child(remove_anim); + remove_anim->connect("pressed",this,"_animation_remove"); + + animations = memnew( Tree ); + sub_vb->add_child(animations); + animations->set_v_size_flags(SIZE_EXPAND_FILL); + animations->set_hide_root(true); + animations->connect("cell_selected",this,"_animation_select"); + animations->connect("item_edited",this,"_animation_name_edited"); + animations->set_single_select_cell_editing_only_when_already_selected(true); + + + anim_speed = memnew( SpinBox); + vbc_animlist->add_margin_child(TTR("Speed (FPS):"),anim_speed); + anim_speed->set_min(0); + anim_speed->set_max(100); + anim_speed->set_step(0.01); + anim_speed->connect("value_changed",this,"_animation_fps_changed"); + + anim_loop = memnew( CheckButton ); + anim_loop->set_text(TTR("Loop")); + vbc_animlist->add_child(anim_loop); + anim_loop->connect("pressed",this,"_animation_loop_changed"); + + VBoxContainer *vbc = memnew( VBoxContainer ); + split->add_child(vbc); + vbc->set_h_size_flags(SIZE_EXPAND_FILL); + + sub_vb = memnew( VBoxContainer ); + vbc->add_margin_child(TTR("Animation Frames"),sub_vb,true); + + + HBoxContainer *hbc = memnew( HBoxContainer ); + sub_vb->add_child(hbc); + + //animations = memnew( ItemList ); + + + load = memnew( Button ); + load->set_tooltip(TTR("Load Resource")); + hbc->add_child(load); + + paste = memnew( Button ); + paste->set_text(TTR("Paste")); + hbc->add_child(paste); + + empty = memnew( Button ); + empty->set_text(TTR("Insert Empty (Before)")); + hbc->add_child(empty); + + empty2 = memnew( Button ); + empty2->set_text(TTR("Insert Empty (After)")); + hbc->add_child(empty2); + + move_up = memnew( Button ); + move_up->set_text(TTR("Up")); + hbc->add_child(move_up); + + move_down = memnew( Button ); + move_down->set_text(TTR("Down")); + hbc->add_child(move_down); + + _delete = memnew( Button ); + hbc->add_child(_delete); + + file = memnew( EditorFileDialog ); + add_child(file); + + + tree = memnew( ItemList ); + tree->set_v_size_flags(SIZE_EXPAND_FILL); + tree->set_icon_mode(ItemList::ICON_MODE_TOP); + + int thumbnail_size = 96; + tree->set_max_columns(0); + tree->set_icon_mode(ItemList::ICON_MODE_TOP); + tree->set_fixed_column_width(thumbnail_size*3/2); + tree->set_max_text_lines(2); + tree->set_fixed_icon_size(Size2(thumbnail_size,thumbnail_size)); + //tree->set_min_icon_size(Size2(thumbnail_size,thumbnail_size)); + tree->set_drag_forwarding(this); + + + + sub_vb->add_child(tree); + + dialog = memnew( AcceptDialog ); + add_child( dialog ); + + load->connect("pressed", this,"_load_pressed"); + _delete->connect("pressed", this,"_delete_pressed"); + paste->connect("pressed", this,"_paste_pressed"); + empty->connect("pressed", this,"_empty_pressed"); + empty2->connect("pressed", this,"_empty2_pressed"); + move_up->connect("pressed", this,"_up_pressed"); + move_down->connect("pressed", this,"_down_pressed"); + file->connect("files_selected", this,"_file_load_request"); + //dialog->connect("confirmed", this,"_delete_confirm_pressed"); + //tree->connect("item_selected", this,"_item_edited"); + loading_scene=false; + sel=-1; + + updating=false; + + edited_anim="default"; + +} + + +void SpriteFramesEditorPlugin::edit(Object *p_object) { + + frames_editor->set_undo_redo(&get_undo_redo()); + SpriteFrames * s = p_object->cast_to<SpriteFrames>(); + if (!s) + return; + + frames_editor->edit(s); +} + +bool SpriteFramesEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("SpriteFrames"); +} + +void SpriteFramesEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + button->show(); + editor->make_bottom_panel_item_visible(frames_editor); + //frames_editor->set_process(true); + } else { + + button->hide(); + if (frames_editor->is_visible_in_tree()) + editor->hide_bottom_panel(); + + //frames_editor->set_process(false); + } + +} + +SpriteFramesEditorPlugin::SpriteFramesEditorPlugin(EditorNode *p_node) { + + editor=p_node; + frames_editor = memnew( SpriteFramesEditor ); + frames_editor->set_custom_minimum_size(Size2(0,300)); + button=editor->add_bottom_panel_item("SpriteFrames",frames_editor); + button->hide(); + + + +} + + +SpriteFramesEditorPlugin::~SpriteFramesEditorPlugin() +{ +} + + diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h new file mode 100644 index 0000000000..11f545b443 --- /dev/null +++ b/editor/plugins/sprite_frames_editor_plugin.h @@ -0,0 +1,138 @@ +/*************************************************************************/ +/* sprite_frames_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef SPRITE_FRAMES_EDITOR_PLUGIN_H +#define SPRITE_FRAMES_EDITOR_PLUGIN_H + + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/gui/tree.h" +#include "scene/2d/animated_sprite.h" +#include "scene/gui/file_dialog.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/split_container.h" + + +class SpriteFramesEditor : public PanelContainer { + + GDCLASS(SpriteFramesEditor, PanelContainer ); + + Button *load; + Button *_delete; + Button *paste; + Button *empty; + Button *empty2; + Button *move_up; + Button *move_down; + ItemList *tree; + bool loading_scene; + int sel; + + HSplitContainer *split; + Button *new_anim; + Button *remove_anim; + + + Tree *animations; + SpinBox *anim_speed; + CheckButton *anim_loop; + + EditorFileDialog *file; + + AcceptDialog *dialog; + + SpriteFrames *frames; + + StringName edited_anim; + + void _load_pressed(); + void _load_scene_pressed(); + void _file_load_request(const PoolVector<String>& p_path, int p_at_pos=-1); + void _paste_pressed(); + void _empty_pressed(); + void _empty2_pressed(); + void _delete_pressed(); + void _delete_confirm_pressed(); + void _up_pressed(); + void _down_pressed(); + void _update_library(bool p_skip_selector=false); + void _item_edited(); + + + + void _animation_select(); + void _animation_name_edited(); + void _animation_add(); + void _animation_remove(); + void _animation_loop_changed(); + void _animation_fps_changed(double p_value); + + bool updating; + + UndoRedo *undo_redo; + + bool _is_drop_valid(const Dictionary& p_drag_data, const Dictionary& p_item_data) const; + Variant get_drag_data_fw(const Point2& p_point,Control* p_from); + bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; + void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); + +protected: + void _notification(int p_what); + void _gui_input(InputEvent p_event); + static void _bind_methods(); +public: + + void set_undo_redo(UndoRedo *p_undo_redo) {undo_redo=p_undo_redo; } + + void edit(SpriteFrames* p_frames); + SpriteFramesEditor(); +}; + +class SpriteFramesEditorPlugin : public EditorPlugin { + + GDCLASS( SpriteFramesEditorPlugin, EditorPlugin ); + + SpriteFramesEditor *frames_editor; + EditorNode *editor; + Button *button; + +public: + + virtual String get_name() const { return "SpriteFrames"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + SpriteFramesEditorPlugin(EditorNode *p_node); + ~SpriteFramesEditorPlugin(); + +}; + +#endif // SPRITE_FRAMES_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/stream_editor_plugin.cpp b/editor/plugins/stream_editor_plugin.cpp index 449f6f610e..449f6f610e 100644 --- a/tools/editor/plugins/stream_editor_plugin.cpp +++ b/editor/plugins/stream_editor_plugin.cpp diff --git a/editor/plugins/stream_editor_plugin.h b/editor/plugins/stream_editor_plugin.h new file mode 100644 index 0000000000..2ae3b7100e --- /dev/null +++ b/editor/plugins/stream_editor_plugin.h @@ -0,0 +1,84 @@ +/*************************************************************************/ +/* stream_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef STREAM_EDITOR_PLUGIN_H +#define STREAM_EDITOR_PLUGIN_H + +#if 0 +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/audio/stream_player.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +class StreamEditor : public Control { + + GDCLASS(StreamEditor, Control ); + + Button * play; + Button * stop; + + Panel *panel; + Node *node; + + void _play(); + void _stop(); +protected: + void _notification(int p_what); + void _node_removed(Node *p_node); + static void _bind_methods(); +public: + + void edit(Node *p_stream); + StreamEditor(); +}; + +class StreamEditorPlugin : public EditorPlugin { + + GDCLASS( StreamEditorPlugin, EditorPlugin ); + + StreamEditor *stream_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "Stream"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + StreamEditorPlugin(EditorNode *p_node); + ~StreamEditorPlugin(); + +}; + +#endif // STREAM_EDITOR_PLUGIN_H +#endif diff --git a/tools/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp index 396ebd0052..396ebd0052 100644 --- a/tools/editor/plugins/style_box_editor_plugin.cpp +++ b/editor/plugins/style_box_editor_plugin.cpp diff --git a/editor/plugins/style_box_editor_plugin.h b/editor/plugins/style_box_editor_plugin.h new file mode 100644 index 0000000000..01e636472b --- /dev/null +++ b/editor/plugins/style_box_editor_plugin.h @@ -0,0 +1,83 @@ +/*************************************************************************/ +/* style_box_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef STYLE_BOX_EDITOR_PLUGIN_H +#define STYLE_BOX_EDITOR_PLUGIN_H + +#include "scene/resources/style_box.h" +#include "scene/gui/texture_rect.h" +#include "scene/gui/option_button.h" +#include "editor/editor_node.h" + + +class StyleBoxEditor : public Control { + + GDCLASS( StyleBoxEditor, Control ); + + Panel *panel; + Panel *preview; + + Ref<StyleBox> stylebox; + + void _sb_changed(); + +protected: + + + static void _bind_methods(); +public: + + void edit(const Ref<StyleBox>& p_stylebox); + + StyleBoxEditor(); +}; + + + +class StyleBoxEditorPlugin : public EditorPlugin { + + GDCLASS( StyleBoxEditorPlugin, EditorPlugin ); + + StyleBoxEditor *stylebox_editor; + EditorNode *editor; + Button *button; + +public: + + virtual String get_name() const { return "StyleBox"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + StyleBoxEditorPlugin(EditorNode *p_node); + +}; + + +#endif // STYLE_BOX_EDITOR_PLUGIN_H diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp new file mode 100644 index 0000000000..af05094e5e --- /dev/null +++ b/editor/plugins/texture_editor_plugin.cpp @@ -0,0 +1,169 @@ +/*************************************************************************/ +/* texture_editor_plugin.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 "texture_editor_plugin.h" + +#include "io/resource_loader.h" +#include "global_config.h" +#include "editor/editor_settings.h" + +void TextureEditor::_gui_input(InputEvent p_event) { + + +} + +void TextureEditor::_notification(int p_what) { + + if (p_what==NOTIFICATION_FIXED_PROCESS) { + + } + + + if (p_what==NOTIFICATION_READY) { + + //get_scene()->connect("node_removed",this,"_node_removed"); + + } + + if (p_what==NOTIFICATION_DRAW) { + + + Ref<Texture> checkerboard = get_icon("Checkerboard","EditorIcons"); + Size2 size = get_size(); + + draw_texture_rect(checkerboard,Rect2(Point2(),size),true); + + int tex_width = texture->get_width() * size.height / texture ->get_height(); + int tex_height = size.height; + + if (tex_width>size.width) { + tex_width=size.width; + tex_height=texture->get_height() * tex_width / texture->get_width(); + } + + int ofs_x = (size.width - tex_width)/2; + int ofs_y = (size.height - tex_height)/2; + + draw_texture_rect(texture,Rect2(ofs_x,ofs_y,tex_width,tex_height)); + + Ref<Font> font = get_font("font","Label"); + + String format; + if (texture->cast_to<ImageTexture>()) { + format = Image::get_format_name(texture->cast_to<ImageTexture>()->get_format()); + } else { + format=texture->get_class(); + } + String text = itos(texture->get_width())+"x"+itos(texture->get_height())+" "+format; + + Size2 rect = font->get_string_size(text); + + Vector2 draw_from = size-rect+Size2(-2,font->get_ascent()-2); + if (draw_from.x<0) + draw_from.x=0; + + draw_string(font,draw_from+Vector2(2,2),text,Color(0,0,0,0.5),size.width); + draw_string(font,draw_from-Vector2(2,2),text,Color(0,0,0,0.5),size.width); + draw_string(font,draw_from,text,Color(1,1,1,1),size.width); + } +} + + + +void TextureEditor::edit(Ref<Texture> p_texture) { + + texture=p_texture; + + if (!texture.is_null()) + update(); + else { + + hide(); + } + +} + + + +void TextureEditor::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_gui_input"),&TextureEditor::_gui_input); + +} + +TextureEditor::TextureEditor() { + + set_custom_minimum_size(Size2(1,150)); + +} + + +void TextureEditorPlugin::edit(Object *p_object) { + + Texture * s = p_object->cast_to<Texture>(); + if (!s) + return; + + texture_editor->edit(Ref<Texture>(s)); +} + +bool TextureEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("Texture"); +} + +void TextureEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + texture_editor->show(); + //texture_editor->set_process(true); + } else { + + texture_editor->hide(); + //texture_editor->set_process(false); + } + +} + +TextureEditorPlugin::TextureEditorPlugin(EditorNode *p_node) { + + editor=p_node; + texture_editor = memnew( TextureEditor ); + add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,texture_editor); + texture_editor->hide(); + + + +} + + +TextureEditorPlugin::~TextureEditorPlugin() +{ +} + + diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h new file mode 100644 index 0000000000..7ad0e918cf --- /dev/null +++ b/editor/plugins/texture_editor_plugin.h @@ -0,0 +1,77 @@ +/*************************************************************************/ +/* texture_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef TEXTURE_EDITOR_PLUGIN_H +#define TEXTURE_EDITOR_PLUGIN_H + + + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/resources/texture.h" + + +class TextureEditor : public Control { + + GDCLASS(TextureEditor, Control); + + + Ref<Texture> texture; + +protected: + void _notification(int p_what); + void _gui_input(InputEvent p_event); + static void _bind_methods(); +public: + + void edit(Ref<Texture> p_texture); + TextureEditor(); +}; + + +class TextureEditorPlugin : public EditorPlugin { + + GDCLASS( TextureEditorPlugin, EditorPlugin ); + + TextureEditor *texture_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "Texture"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + TextureEditorPlugin(EditorNode *p_node); + ~TextureEditorPlugin(); + +}; + +#endif // TEXTURE_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index aabf938577..aabf938577 100644 --- a/tools/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h new file mode 100644 index 0000000000..8e88f0b707 --- /dev/null +++ b/editor/plugins/texture_region_editor_plugin.h @@ -0,0 +1,153 @@ +/*************************************************************************/ +/* texture_region_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Author: Mariano Suligoy */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef TEXTURE_REGION_EDITOR_PLUGIN_H +#define TEXTURE_REGION_EDITOR_PLUGIN_H + +#include "canvas_item_editor_plugin.h" +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" +#include "scene/2d/sprite.h" +#include "scene/gui/patch_9_rect.h" +#include "scene/resources/style_box.h" +#include "scene/resources/texture.h" + +class TextureRegionEditor : public Control { + + GDCLASS(TextureRegionEditor, Control ); + + enum SnapMode { + SNAP_NONE, + SNAP_PIXEL, + SNAP_GRID, + SNAP_AUTOSLICE + }; + + friend class TextureRegionEditorPlugin; + MenuButton *snap_mode_button; + TextureRect *icon_zoom; + ToolButton *zoom_in; + ToolButton *zoom_reset; + ToolButton *zoom_out; + HBoxContainer * hb_grid; //For showing/hiding the grid controls when changing the SnapMode + SpinBox *sb_step_y; + SpinBox *sb_step_x; + SpinBox *sb_off_y; + SpinBox *sb_off_x; + SpinBox *sb_sep_y; + SpinBox *sb_sep_x; + Control *edit_draw; + + VScrollBar *vscroll; + HScrollBar *hscroll; + + EditorNode *editor; + UndoRedo* undo_redo; + + Vector2 draw_ofs; + float draw_zoom; + bool updating_scroll; + + int snap_mode; + Vector2 snap_offset; + Vector2 snap_step; + Vector2 snap_separation; + + NinePatchRect *node_patch9; + Sprite *node_sprite; + Ref<StyleBoxTexture> obj_styleBox; + Ref<AtlasTexture> atlas_tex; + + Rect2 rect; + Rect2 rect_prev; + float prev_margin; + int edited_margin; + List<Rect2> autoslice_cache; + + bool drag; + bool creating; + Vector2 drag_from; + int drag_index; + + void _set_snap_mode(int p_mode); + void _set_snap_off_x(float p_val); + void _set_snap_off_y(float p_val); + void _set_snap_step_x(float p_val); + void _set_snap_step_y(float p_val); + void _set_snap_sep_x(float p_val); + void _set_snap_sep_y(float p_val); + void _zoom_in(); + void _zoom_reset(); + void _zoom_out(); + void apply_rect(const Rect2& rect); +protected: + + void _notification(int p_what); + void _node_removed(Object *p_obj); + static void _bind_methods(); + + Vector2 snap_point(Vector2 p_target) const; + + virtual void _changed_callback(Object *p_changed, const char *p_prop); + +public: + + void _edit_region(); + void _region_draw(); + void _region_input(const InputEvent &p_input); + void _scroll_changed(float); + + void edit(Object *p_obj); + TextureRegionEditor(EditorNode* p_editor); + +}; + +class TextureRegionEditorPlugin : public EditorPlugin +{ + GDCLASS( TextureRegionEditorPlugin, EditorPlugin ); + + Button *region_button; + TextureRegionEditor *region_editor; + EditorNode *editor; +public: + + virtual String get_name() const { return "TextureRegion"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + void set_state(const Dictionary &p_state); + Dictionary get_state() const; + + TextureRegionEditorPlugin(EditorNode *p_node); +}; + +#endif // TEXTURE_REGION_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 4b8fea5a45..4b8fea5a45 100644 --- a/tools/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h new file mode 100644 index 0000000000..f661da4cd5 --- /dev/null +++ b/editor/plugins/theme_editor_plugin.h @@ -0,0 +1,125 @@ +/*************************************************************************/ +/* theme_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef THEME_EDITOR_PLUGIN_H +#define THEME_EDITOR_PLUGIN_H + +#include "scene/resources/theme.h" +#include "scene/gui/texture_rect.h" +#include "scene/gui/option_button.h" +#include "scene/gui/file_dialog.h" +#include "scene/gui/check_box.h" +#include "scene/gui/button_group.h" +#include "scene/gui/scroll_container.h" + +#include "editor/editor_node.h" + + + + +class ThemeEditor : public Control { + + GDCLASS( ThemeEditor, Control ); + + + ScrollContainer *scroll; + VBoxContainer *main_vb; + Ref<Theme> theme; + + EditorFileDialog *file_dialog; + + double time_left; + + MenuButton *theme_menu; + ConfirmationDialog *add_del_dialog; + MenuButton *type_menu; + LineEdit *type_edit; + MenuButton *name_menu; + LineEdit *name_edit; + OptionButton *type_select; + Label * type_select_label; + Label * name_select_label; + Label * dtype_select_label; + + enum PopupMode { + POPUP_ADD, + POPUP_CLASS_ADD, + POPUP_REMOVE, + POPUP_CLASS_REMOVE, + POPUP_CREATE_EMPTY, + POPUP_CREATE_EDITOR_EMPTY + }; + + int popup_mode; + + Tree *test_tree; + + void _save_template_cbk(String fname); + void _dialog_cbk(); + void _type_menu_cbk(int p_option); + void _name_menu_about_to_show(); + void _name_menu_cbk(int p_option); + void _theme_menu_cbk(int p_option); + void _propagate_redraw(Control *p_at); + void _refresh_interval(); + + +protected: + void _notification(int p_what); + static void _bind_methods(); +public: + + void edit(const Ref<Theme>& p_theme); + + ThemeEditor(); +}; + + + +class ThemeEditorPlugin : public EditorPlugin { + + GDCLASS( ThemeEditorPlugin, EditorPlugin ); + + ThemeEditor *theme_editor; + EditorNode *editor; + Button *button; + +public: + + virtual String get_name() const { return "Theme"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + ThemeEditorPlugin(EditorNode *p_node); + +}; + + +#endif // THEME_EDITOR_PLUGIN_H diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp new file mode 100644 index 0000000000..fb6d5a786a --- /dev/null +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -0,0 +1,1593 @@ +/*************************************************************************/ +/* tile_map_editor_plugin.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 "tile_map_editor_plugin.h" + +#include "os/keyboard.h" +#include "os/input.h" +#include "canvas_item_editor_plugin.h" +#include "editor/editor_settings.h" +#include "editor/editor_scale.h" + +void TileMapEditor::_notification(int p_what) { + + switch(p_what) { + + case NOTIFICATION_ENTER_TREE: { + + transp->set_icon(get_icon("Transpose","EditorIcons")); + mirror_x->set_icon(get_icon("MirrorX","EditorIcons")); + mirror_y->set_icon(get_icon("MirrorY","EditorIcons")); + rotate_0->set_icon(get_icon("Rotate0","EditorIcons")); + rotate_90->set_icon(get_icon("Rotate90","EditorIcons")); + rotate_180->set_icon(get_icon("Rotate180","EditorIcons")); + rotate_270->set_icon(get_icon("Rotate270","EditorIcons")); + + } break; + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + + if (is_visible_in_tree()) { + _update_palette(); + } + } break; + } +} + +void TileMapEditor::_menu_option(int p_option) { + + switch(p_option) { + + case OPTION_BUCKET: { + + tool=TOOL_BUCKET; + + canvas_item_editor->update(); + } break; + case OPTION_PICK_TILE: { + + tool=TOOL_PICKING; + + canvas_item_editor->update(); + } break; + case OPTION_SELECT: { + + tool=TOOL_SELECTING; + selection_active=false; + + canvas_item_editor->update(); + } break; + case OPTION_DUPLICATE: { + + _update_copydata(); + + if (selection_active) { + tool=TOOL_DUPLICATING; + + canvas_item_editor->update(); + } + } break; + case OPTION_ERASE_SELECTION: { + + if (!selection_active) + return; + + undo_redo->create_action("Erase Selection"); + for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) { + for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) { + + _set_cell(Point2i(j, i), TileMap::INVALID_CELL, false, false, false, true); + } + } + undo_redo->commit_action(); + + selection_active=false; + copydata.clear(); + + canvas_item_editor->update(); + } break; + } +} + +void TileMapEditor::_canvas_mouse_enter() { + + mouse_over=true; + canvas_item_editor->update(); +} + +void TileMapEditor::_canvas_mouse_exit() { + + mouse_over=false; + canvas_item_editor->update(); +} + +int TileMapEditor::get_selected_tile() const { + + int item = palette->get_current(); + + if (item==-1) + return TileMap::INVALID_CELL; + + return palette->get_item_metadata(item); +} + +void TileMapEditor::set_selected_tile(int p_tile) { + + int idx = palette->find_metadata(p_tile); + + if (idx >= 0) { + palette->select(idx, true); + palette->ensure_current_is_visible(); + } +} + +void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose,bool p_with_undo) { + + ERR_FAIL_COND(!node); + + int prev_val=node->get_cell(p_pos.x,p_pos.y); + + bool prev_flip_h=node->is_cell_x_flipped(p_pos.x,p_pos.y); + bool prev_flip_v=node->is_cell_y_flipped(p_pos.x,p_pos.y); + bool prev_transpose=node->is_cell_transposed(p_pos.x,p_pos.y); + + if (p_value==prev_val && p_flip_h==prev_flip_h && p_flip_v==prev_flip_v && p_transpose==prev_transpose) + return; //check that it's actually different + + if (p_with_undo) { + + undo_redo->add_do_method(node,"set_cellv",Point2(p_pos),p_value,p_flip_h,p_flip_v,p_transpose); + undo_redo->add_undo_method(node,"set_cellv",Point2(p_pos),prev_val,prev_flip_h,prev_flip_v,prev_transpose); + } else { + + node->set_cell(p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v,p_transpose); + } + +} + +void TileMapEditor::_text_entered(const String& p_text) { + + canvas_item_editor->grab_focus(); +} + +void TileMapEditor::_text_changed(const String& p_text) { + + _update_palette(); +} + +void TileMapEditor::_sbox_input(const InputEvent& p_ie) { + + if (p_ie.type==InputEvent::KEY && ( + p_ie.key.scancode == KEY_UP || + p_ie.key.scancode == KEY_DOWN || + p_ie.key.scancode == KEY_PAGEUP || + p_ie.key.scancode == KEY_PAGEDOWN ) ) { + + palette->call("_gui_input", p_ie); + search_box->accept_event(); + } +} + +void TileMapEditor::_update_palette() { + + if (!node) + return; + + int selected = get_selected_tile(); + palette->clear(); + + Ref<TileSet> tileset=node->get_tileset(); + if (tileset.is_null()) + return; + + List<int> tiles; + tileset->get_tile_list(&tiles); + + if (tiles.empty()) + return; + + float min_size = EDITOR_DEF("editors/tile_map/preview_size", 64); + min_size *= EDSCALE; + int hseparation = EDITOR_DEF("editors/tile_map/palette_item_hseparation",8); + bool show_tile_names = bool(EDITOR_DEF("editors/tile_map/show_tile_names", true)); + + palette->add_constant_override("hseparation", hseparation*EDSCALE); + palette->add_constant_override("vseparation", 8*EDSCALE); + + palette->set_fixed_icon_size(Size2(min_size, min_size)); + palette->set_fixed_column_width(min_size * MAX(size_slider->get_value(), 1)); + + String filter = search_box->get_text().strip_edges(); + + for (List<int>::Element *E=tiles.front();E;E=E->next()) { + + String name; + + if (tileset->tile_get_name(E->get())!="") { + name = itos(E->get())+" - "+tileset->tile_get_name(E->get()); + } else { + name = "#"+itos(E->get()); + } + + if (filter != "" && !filter.is_subsequence_ofi(name)) + continue; + + if (show_tile_names) { + palette->add_item(name); + } else { + palette->add_item(String()); + } + + Ref<Texture> tex = tileset->tile_get_texture(E->get()); + + if (tex.is_valid()) { + Rect2 region = tileset->tile_get_region(E->get()); + + if (!region.has_no_area()) + palette->set_item_icon_region(palette->get_item_count()-1, region); + + palette->set_item_icon(palette->get_item_count()-1, tex); + } + + palette->set_item_metadata(palette->get_item_count()-1, E->get()); + } + + palette->set_same_column_width(true); + + if (selected != -1) + set_selected_tile(selected); + else + palette->select(0); +} + +void TileMapEditor::_pick_tile(const Point2& p_pos) { + + int id = node->get_cell(p_pos.x, p_pos.y); + + if (id==TileMap::INVALID_CELL) + return; + + if (search_box->get_text().strip_edges() != "") { + + search_box->set_text(""); + _update_palette(); + } + + set_selected_tile(id); + + mirror_x->set_pressed(node->is_cell_x_flipped(p_pos.x, p_pos.y)); + mirror_y->set_pressed(node->is_cell_y_flipped(p_pos.x, p_pos.y)); + transp->set_pressed(node->is_cell_transposed(p_pos.x, p_pos.y)); + + _update_transform_buttons(); + canvas_item_editor->update(); +} + +PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i& p_start, bool erase, bool preview) { + + int prev_id = node->get_cell(p_start.x, p_start.y); + int id = TileMap::INVALID_CELL; + if (!erase) { + id = get_selected_tile(); + + if (id == TileMap::INVALID_CELL) + return PoolVector<Vector2>(); + } + + Rect2i r = node->get_item_rect(); + r.pos = r.pos/node->get_cell_size(); + r.size = r.size/node->get_cell_size(); + + int area = r.get_area(); + if(preview) { + // Test if we can re-use the result from preview bucket fill + bool invalidate_cache = false; + // Area changed + if(r != bucket_cache_rect) + _clear_bucket_cache(); + // Cache grid is not initialized + if(bucket_cache_visited == 0) { + bucket_cache_visited = new bool[area]; + invalidate_cache = true; + } + // Tile ID changed or position wasn't visited by the previous fill + int loc = (p_start.x - r.get_pos().x) + (p_start.y - r.get_pos().y) * r.get_size().x; + if(prev_id != bucket_cache_tile || !bucket_cache_visited[loc]) { + invalidate_cache = true; + } + if(invalidate_cache) { + for(int i = 0; i < area; ++i) + bucket_cache_visited[i] = false; + bucket_cache = PoolVector<Vector2>(); + bucket_cache_tile = prev_id; + bucket_cache_rect = r; + } + else { + return bucket_cache; + } + } + + PoolVector<Vector2> points; + + List<Point2i> queue; + queue.push_back(p_start); + + while (queue.size()) { + + Point2i n = queue.front()->get(); + queue.pop_front(); + + if (!r.has_point(n)) + continue; + + if (node->get_cell(n.x, n.y) == prev_id) { + + if(preview) { + int loc = (n.x - r.get_pos().x) + (n.y - r.get_pos().y) * r.get_size().x; + if(bucket_cache_visited[loc]) + continue; + bucket_cache_visited[loc] = true; + bucket_cache.push_back(n); + } + else { + node->set_cellv(n, id, flip_h, flip_v, transpose); + points.push_back(n); + } + + queue.push_back(n + Point2i(0, 1)); + queue.push_back(n + Point2i(0, -1)); + queue.push_back(n + Point2i(1, 0)); + queue.push_back(n + Point2i(-1, 0)); + } + } + + return preview ? bucket_cache : points; +} + +void TileMapEditor::_fill_points(const PoolVector<Vector2> p_points, const Dictionary& p_op) { + + int len = p_points.size(); + PoolVector<Vector2>::Read pr = p_points.read(); + + int id = p_op["id"]; + bool xf = p_op["flip_h"]; + bool yf = p_op["flip_v"]; + bool tr = p_op["transpose"]; + + for (int i=0;i<len;i++) { + + _set_cell(pr[i], id, xf, yf, tr); + } +} + +void TileMapEditor::_erase_points(const PoolVector<Vector2> p_points) { + + int len = p_points.size(); + PoolVector<Vector2>::Read pr = p_points.read(); + + for (int i=0;i<len;i++) { + + _set_cell(pr[i], TileMap::INVALID_CELL); + } +} + +void TileMapEditor::_select(const Point2i& p_from, const Point2i& p_to) { + + Point2i begin=p_from; + Point2i end=p_to; + + if (begin.x > end.x) { + + SWAP( begin.x, end.x); + } + if (begin.y > end.y) { + + SWAP( begin.y, end.y); + } + + rectangle.pos=begin; + rectangle.size=end-begin; + + canvas_item_editor->update(); +} + +void TileMapEditor::_draw_cell(int p_cell, const Point2i& p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D& p_xform) { + + Ref<Texture> t = node->get_tileset()->tile_get_texture(p_cell); + + if (t.is_null()) + return; + + Vector2 tile_ofs = node->get_tileset()->tile_get_texture_offset(p_cell); + + Rect2 r = node->get_tileset()->tile_get_region(p_cell); + Size2 sc = p_xform.get_scale(); + + Rect2 rect = Rect2(); + rect.pos = node->map_to_world(p_point) + node->get_cell_draw_offset(); + + if (r.has_no_area()) { + rect.size = t->get_size(); + } else { + rect.size = r.size; + } + + if (rect.size.y > rect.size.x) { + if ((p_flip_h && (p_flip_v || p_transpose)) || (p_flip_v && !p_transpose)) + tile_ofs.y += rect.size.y - rect.size.x; + } else if (rect.size.y < rect.size.x) { + if ((p_flip_v && (p_flip_h || p_transpose)) || (p_flip_h && !p_transpose)) + tile_ofs.x += rect.size.x - rect.size.y; + } + + if (p_transpose) { + SWAP(tile_ofs.x, tile_ofs.y); + } + if (p_flip_h) { + sc.x*=-1.0; + tile_ofs.x*=-1.0; + } + if (p_flip_v) { + sc.y*=-1.0; + tile_ofs.y*=-1.0; + } + + if (node->get_tile_origin()==TileMap::TILE_ORIGIN_TOP_LEFT) { + + rect.pos+=tile_ofs; + } else if (node->get_tile_origin()==TileMap::TILE_ORIGIN_BOTTOM_LEFT) { + Size2 cell_size = node->get_cell_size(); + + rect.pos+=tile_ofs; + + if(p_transpose) + { + if(p_flip_h) + rect.pos.x-=cell_size.x; + else + rect.pos.x+=cell_size.x; + } else { + if(p_flip_v) + rect.pos.y-=cell_size.y; + else + rect.pos.y+=cell_size.y; + } + + } else if (node->get_tile_origin()==TileMap::TILE_ORIGIN_CENTER) { + rect.pos+=node->get_cell_size()/2; + Vector2 s = r.size; + + Vector2 center = (s/2) - tile_ofs; + + if (p_flip_h) + rect.pos.x-=s.x-center.x; + else + rect.pos.x-=center.x; + + if (p_flip_v) + rect.pos.y-=s.y-center.y; + else + rect.pos.y-=center.y; + } + + rect.pos=p_xform.xform(rect.pos); + rect.size*=sc; + + if (r.has_no_area()) + canvas_item_editor->draw_texture_rect(t, rect, false, Color(1,1,1,0.5), p_transpose); + else + canvas_item_editor->draw_texture_rect_region(t, rect, r, Color(1,1,1,0.5), p_transpose); +} + +void TileMapEditor::_draw_fill_preview(int p_cell, const Point2i& p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D& p_xform) { + + PoolVector<Vector2> points = _bucket_fill(p_point, false, true); + PoolVector<Vector2>::Read pr = points.read(); + int len = points.size(); + int time_after = OS::get_singleton()->get_ticks_msec(); + + for(int i = 0; i < len; ++i) { + _draw_cell(p_cell, pr[i], p_flip_h, p_flip_v, p_transpose, p_xform); + } +} + +void TileMapEditor::_clear_bucket_cache() { + if(bucket_cache_visited) { + delete[] bucket_cache_visited; + bucket_cache_visited = 0; + } +} + +void TileMapEditor::_update_copydata() { + + copydata.clear(); + + if (!selection_active) + return; + + for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) { + + for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) { + + TileData tcd; + + tcd.cell=node->get_cell(j, i); + + if (tcd.cell!=TileMap::INVALID_CELL) { + tcd.pos=Point2i(j, i); + tcd.flip_h=node->is_cell_x_flipped(j,i); + tcd.flip_v=node->is_cell_y_flipped(j,i); + tcd.transpose=node->is_cell_transposed(j,i); + } + + copydata.push_back(tcd); + } + } +} + +static inline Vector<Point2i> line(int x0, int x1, int y0, int y1) { + + Vector<Point2i> points; + + float dx = ABS(x1 - x0); + float dy = ABS(y1 - y0); + + int x = x0; + int y = y0; + + int sx = x0 > x1 ? -1 : 1; + int sy = y0 > y1 ? -1 : 1; + + if (dx > dy) { + float err = dx/2; + + for (; x != x1; x += sx) { + points.push_back(Vector2(x, y)); + + err -= dy; + if (err < 0) { + y += sy; + err += dx; + } + } + } else { + float err = dy/2; + + for (; y != y1; y += sy) { + points.push_back(Vector2(x, y)); + + err -= dx; + if (err < 0) { + x += sx; + err += dy; + } + } + } + + points.push_back(Vector2(x, y)); + + return points; +} + +bool TileMapEditor::forward_gui_input(const InputEvent& p_event) { + + if (!node || !node->get_tileset().is_valid() || !node->is_visible_in_tree()) + return false; + + Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform(); + Transform2D xform_inv = xform.affine_inverse(); + + switch(p_event.type) { + + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &mb=p_event.mouse_button; + + if (mb.button_index==BUTTON_LEFT) { + + if (mb.pressed) { + + if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) + return false; //drag + + if (tool==TOOL_NONE) { + + if (mb.mod.shift) { + + if (mb.mod.control) + tool=TOOL_RECTANGLE_PAINT; + else + tool=TOOL_LINE_PAINT; + + selection_active=false; + rectangle_begin=over_tile; + + return true; + } + + if (mb.mod.control) { + + tool=TOOL_PICKING; + _pick_tile(over_tile); + + return true; + } + + tool=TOOL_PAINTING; + } + + if (tool==TOOL_PAINTING) { + + int id = get_selected_tile(); + + if (id!=TileMap::INVALID_CELL) { + + tool=TOOL_PAINTING; + + paint_undo.clear(); + paint_undo[over_tile]=_get_op_from_cell(over_tile); + + _set_cell(over_tile, id, flip_h, flip_v, transpose); + } + } else if (tool==TOOL_PICKING) { + + _pick_tile(over_tile); + } else if (tool==TOOL_SELECTING) { + + selection_active=true; + rectangle_begin=over_tile; + } + + return true; + + } else { + + if (tool!=TOOL_NONE) { + + if (tool==TOOL_PAINTING) { + + int id=get_selected_tile(); + + if (id!=TileMap::INVALID_CELL && paint_undo.size()) { + + undo_redo->create_action(TTR("Paint TileMap")); + for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) { + + Point2 p=E->key(); + undo_redo->add_do_method(node,"set_cellv",p,id,flip_h,flip_v,transpose); + undo_redo->add_undo_method(node,"set_cellv",p,E->get().idx,E->get().xf,E->get().yf,E->get().tr); + } + undo_redo->commit_action(); + + paint_undo.clear(); + } + } else if (tool==TOOL_LINE_PAINT) { + + int id=get_selected_tile(); + + if (id!=TileMap::INVALID_CELL) { + + undo_redo->create_action("Line Draw"); + for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) { + + _set_cell(E->key(), id, flip_h, flip_v, transpose, true); + } + undo_redo->commit_action(); + + paint_undo.clear(); + + canvas_item_editor->update(); + } + } else if (tool==TOOL_RECTANGLE_PAINT) { + + int id=get_selected_tile(); + + if (id!=TileMap::INVALID_CELL) { + + undo_redo->create_action("Rectangle Paint"); + for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) { + for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) { + + _set_cell(Point2i(j, i), id, flip_h, flip_v, transpose, true); + } + } + undo_redo->commit_action(); + + canvas_item_editor->update(); + } + } else if (tool==TOOL_DUPLICATING) { + + Point2 ofs = over_tile-rectangle.pos; + + undo_redo->create_action(TTR("Duplicate")); + for (List<TileData>::Element *E=copydata.front();E;E=E->next()) { + + _set_cell(E->get().pos+ofs,E->get().cell,E->get().flip_h,E->get().flip_v,E->get().transpose,true); + } + undo_redo->commit_action(); + + copydata.clear(); + + canvas_item_editor->update(); + + } else if (tool==TOOL_SELECTING) { + + canvas_item_editor->update(); + + } else if (tool==TOOL_BUCKET) { + + Dictionary pop; + pop["id"] = node->get_cell(over_tile.x, over_tile.y); + pop["flip_h"] = node->is_cell_x_flipped(over_tile.x, over_tile.y); + pop["flip_v"] = node->is_cell_y_flipped(over_tile.x, over_tile.y); + pop["transpose"] = node->is_cell_transposed(over_tile.x, over_tile.y); + + PoolVector<Vector2> points = _bucket_fill(over_tile); + + if (points.size() == 0) + return false; + + Dictionary op; + op["id"] = get_selected_tile(); + op["flip_h"] = flip_h; + op["flip_v"] = flip_v; + op["transpose"] = transpose; + + undo_redo->create_action("Bucket Fill"); + + undo_redo->add_do_method(this, "_fill_points", points, op); + undo_redo->add_undo_method(this, "_fill_points", points, pop); + + undo_redo->commit_action(); + } + + tool=TOOL_NONE; + + return true; + } + } + } else if (mb.button_index==BUTTON_RIGHT) { + + if (mb.pressed) { + + if (tool==TOOL_SELECTING || selection_active) { + + tool=TOOL_NONE; + selection_active=false; + + canvas_item_editor->update(); + + return true; + } + + if (tool==TOOL_DUPLICATING) { + + tool=TOOL_NONE; + copydata.clear(); + + canvas_item_editor->update(); + + return true; + } + + if (tool==TOOL_NONE) { + + paint_undo.clear(); + + Point2 local = node->world_to_map(xform_inv.xform(Point2(mb.x, mb.y))); + + if (mb.mod.shift) { + + if (mb.mod.control) + tool=TOOL_RECTANGLE_ERASE; + else + tool=TOOL_LINE_ERASE; + + selection_active=false; + rectangle_begin=local; + } else { + + tool=TOOL_ERASING; + + paint_undo[local]=_get_op_from_cell(local); + _set_cell(local, TileMap::INVALID_CELL); + } + + return true; + } + + } else { + if (tool==TOOL_ERASING || tool==TOOL_RECTANGLE_ERASE || tool==TOOL_LINE_ERASE) { + + if (paint_undo.size()) { + undo_redo->create_action(TTR("Erase TileMap")); + for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) { + + Point2 p=E->key(); + undo_redo->add_do_method(node,"set_cellv",p,TileMap::INVALID_CELL,false,false,false); + undo_redo->add_undo_method(node,"set_cellv",p,E->get().idx,E->get().xf,E->get().yf,E->get().tr); + } + + undo_redo->commit_action(); + paint_undo.clear(); + } + + if (tool==TOOL_RECTANGLE_ERASE || tool==TOOL_LINE_ERASE) { + canvas_item_editor->update(); + } + + tool=TOOL_NONE; + + return true; + + } else if (tool==TOOL_BUCKET) { + + Dictionary pop; + pop["id"] = node->get_cell(over_tile.x, over_tile.y); + pop["flip_h"] = node->is_cell_x_flipped(over_tile.x, over_tile.y); + pop["flip_v"] = node->is_cell_y_flipped(over_tile.x, over_tile.y); + pop["transpose"] = node->is_cell_transposed(over_tile.x, over_tile.y); + + PoolVector<Vector2> points = _bucket_fill(over_tile, true); + + if (points.size() == 0) + return false; + + undo_redo->create_action("Bucket Fill"); + + undo_redo->add_do_method(this, "_erase_points", points); + undo_redo->add_undo_method(this, "_fill_points", points, pop); + + undo_redo->commit_action(); + } + } + } + } break; + case InputEvent::MOUSE_MOTION: { + + const InputEventMouseMotion &mm=p_event.mouse_motion; + + Point2i new_over_tile = node->world_to_map(xform_inv.xform(Point2(mm.x,mm.y))); + + if (new_over_tile!=over_tile) { + + over_tile=new_over_tile; + canvas_item_editor->update(); + } + + int tile_under = node->get_cell(over_tile.x, over_tile.y); + String tile_name = "none"; + + if (node->get_tileset()->has_tile(tile_under)) + tile_name = node->get_tileset()->tile_get_name(tile_under); + tile_info->set_text(String::num(over_tile.x)+", "+String::num(over_tile.y)+" ["+tile_name+"]"); + + if (tool==TOOL_PAINTING) { + + int id = get_selected_tile(); + if (id!=TileMap::INVALID_CELL) { + + if (!paint_undo.has(over_tile)) { + paint_undo[over_tile]=_get_op_from_cell(over_tile); + } + + _set_cell(over_tile, id, flip_h, flip_v, transpose); + + return true; + } + } + + if (tool==TOOL_SELECTING) { + + _select(rectangle_begin, over_tile); + + return true; + } + + if (tool==TOOL_LINE_PAINT || tool==TOOL_LINE_ERASE) { + + int id = get_selected_tile(); + bool erasing = (tool==TOOL_LINE_ERASE); + + if (erasing && paint_undo.size()) { + + for (Map<Point2i, CellOp>::Element *E=paint_undo.front();E;E=E->next()) { + + _set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr); + } + } + + paint_undo.clear(); + + if (id!=TileMap::INVALID_CELL) { + + Vector<Point2i> points = line(rectangle_begin.x, over_tile.x, rectangle_begin.y, over_tile.y); + + for (int i=0;i<points.size();i++) { + + paint_undo[points[i]]=_get_op_from_cell(points[i]); + + if (erasing) + _set_cell(points[i], TileMap::INVALID_CELL); + } + + canvas_item_editor->update(); + } + + return true; + } + if (tool==TOOL_RECTANGLE_PAINT || tool==TOOL_RECTANGLE_ERASE) { + + _select(rectangle_begin, over_tile); + + if (tool==TOOL_RECTANGLE_ERASE) { + + if (paint_undo.size()) { + + for (Map<Point2i, CellOp>::Element *E=paint_undo.front();E;E=E->next()) { + + _set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr); + } + } + + paint_undo.clear(); + + for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) { + for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) { + + Point2i tile = Point2i(j, i); + paint_undo[tile]=_get_op_from_cell(tile); + + _set_cell(tile, TileMap::INVALID_CELL); + } + } + } + + return true; + } + if (tool==TOOL_ERASING) { + + if (!paint_undo.has(over_tile)) { + paint_undo[over_tile]=_get_op_from_cell(over_tile); + } + + _set_cell(over_tile, TileMap::INVALID_CELL); + + return true; + } + if (tool==TOOL_PICKING && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { + + _pick_tile(over_tile); + + return true; + } + } break; + case InputEvent::KEY: { + + const InputEventKey &k = p_event.key; + + if (!k.pressed) + break; + + if (k.scancode==KEY_ESCAPE) { + + if (tool==TOOL_DUPLICATING) + copydata.clear(); + else if (tool==TOOL_SELECTING || selection_active) + selection_active=false; + + tool=TOOL_NONE; + + canvas_item_editor->update(); + + return true; + } + + if (tool!=TOOL_NONE || !mouse_over) + return false; + + if (ED_IS_SHORTCUT("tile_map_editor/erase_selection", p_event)) { + _menu_option(OPTION_ERASE_SELECTION); + + return true; + } + if (ED_IS_SHORTCUT("tile_map_editor/select", p_event)) { + tool=TOOL_SELECTING; + selection_active=false; + + canvas_item_editor->update(); + + return true; + } + if (ED_IS_SHORTCUT("tile_map_editor/duplicate_selection", p_event)) { + _update_copydata(); + + if (selection_active) { + tool=TOOL_DUPLICATING; + + canvas_item_editor->update(); + + return true; + } + } + if (ED_IS_SHORTCUT("tile_map_editor/find_tile", p_event)) { + search_box->select_all(); + search_box->grab_focus(); + + return true; + } + if (ED_IS_SHORTCUT("tile_map_editor/mirror_x", p_event)) { + flip_h=!flip_h; + mirror_x->set_pressed(flip_h); + canvas_item_editor->update(); + return true; + } + if (ED_IS_SHORTCUT("tile_map_editor/mirror_y", p_event)) { + flip_v=!flip_v; + mirror_y->set_pressed(flip_v); + canvas_item_editor->update(); + return true; + } + if (ED_IS_SHORTCUT("tile_map_editor/transpose", p_event)) { + transpose = !transpose; + transp->set_pressed(transpose); + canvas_item_editor->update(); + return true; + } + } break; + } + + return false; +} + +void TileMapEditor::_canvas_draw() { + + if (!node) + return; + + Transform2D cell_xf = node->get_cell_transform(); + + Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform(); + Transform2D xform_inv = xform.affine_inverse(); + + + Size2 screen_size=canvas_item_editor->get_size(); + { + Rect2 aabb; + aabb.pos=node->world_to_map(xform_inv.xform(Vector2())); + aabb.expand_to(node->world_to_map(xform_inv.xform(Vector2(0,screen_size.height)))); + aabb.expand_to(node->world_to_map(xform_inv.xform(Vector2(screen_size.width,0)))); + aabb.expand_to(node->world_to_map(xform_inv.xform(screen_size))); + Rect2i si=aabb.grow(1.0); + + if (node->get_half_offset()!=TileMap::HALF_OFFSET_X) { + + int max_lines=2000; //avoid crash if size too smal + + for (int i=(si.pos.x)-1;i<=(si.pos.x+si.size.x);i++) { + + Vector2 from = xform.xform(node->map_to_world(Vector2(i,si.pos.y))); + Vector2 to = xform.xform(node->map_to_world(Vector2(i,si.pos.y+si.size.y+1))); + + Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); + canvas_item_editor->draw_line(from,to,col,1); + if (max_lines--==0) + break; + } + } else { + + int max_lines=10000; //avoid crash if size too smal + + for (int i=(si.pos.x)-1;i<=(si.pos.x+si.size.x);i++) { + + for (int j=(si.pos.y)-1;j<=(si.pos.y+si.size.y);j++) { + + Vector2 ofs; + if (ABS(j)&1) { + ofs=cell_xf[0]*0.5; + } + + Vector2 from = xform.xform(node->map_to_world(Vector2(i,j),true)+ofs); + Vector2 to = xform.xform(node->map_to_world(Vector2(i,j+1),true)+ofs); + Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); + canvas_item_editor->draw_line(from,to,col,1); + + if (max_lines--==0) + break; + + } + + } + } + + int max_lines=10000; //avoid crash if size too smal + + if (node->get_half_offset()!=TileMap::HALF_OFFSET_Y) { + + for (int i=(si.pos.y)-1;i<=(si.pos.y+si.size.y);i++) { + + Vector2 from = xform.xform(node->map_to_world(Vector2(si.pos.x,i))); + Vector2 to = xform.xform(node->map_to_world(Vector2(si.pos.x+si.size.x+1,i))); + + Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); + canvas_item_editor->draw_line(from,to,col,1); + + if (max_lines--==0) + break; + + } + } else { + + + for (int i=(si.pos.y)-1;i<=(si.pos.y+si.size.y);i++) { + + for (int j=(si.pos.x)-1;j<=(si.pos.x+si.size.x);j++) { + + Vector2 ofs; + if (ABS(j)&1) { + ofs=cell_xf[1]*0.5; + } + + Vector2 from = xform.xform(node->map_to_world(Vector2(j,i),true)+ofs); + Vector2 to = xform.xform(node->map_to_world(Vector2(j+1,i),true)+ofs); + Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); + canvas_item_editor->draw_line(from,to,col,1); + + if (max_lines--==0) + break; + + } + } + } + } + + if (selection_active) { + + Vector<Vector2> points; + points.push_back( xform.xform( node->map_to_world(( rectangle.pos ) ))); + points.push_back( xform.xform( node->map_to_world((rectangle.pos+Point2(rectangle.size.x+1,0)) ) )); + points.push_back( xform.xform( node->map_to_world((rectangle.pos+Point2(rectangle.size.x+1,rectangle.size.y+1)) ) )); + points.push_back( xform.xform( node->map_to_world((rectangle.pos+Point2(0,rectangle.size.y+1)) ) )); + + canvas_item_editor->draw_colored_polygon(points, Color(0.2,0.8,1,0.4)); + } + + if (mouse_over){ + + Vector2 endpoints[4]={ + node->map_to_world(over_tile, true), + node->map_to_world((over_tile+Point2(1,0)), true), + node->map_to_world((over_tile+Point2(1,1)), true), + node->map_to_world((over_tile+Point2(0,1)), true) + }; + + for (int i=0;i<4;i++) { + if (node->get_half_offset()==TileMap::HALF_OFFSET_X && ABS(over_tile.y)&1) + endpoints[i]+=cell_xf[0]*0.5; + if (node->get_half_offset()==TileMap::HALF_OFFSET_Y && ABS(over_tile.x)&1) + endpoints[i]+=cell_xf[1]*0.5; + endpoints[i]=xform.xform(endpoints[i]); + } + Color col; + if (node->get_cell(over_tile.x,over_tile.y)!=TileMap::INVALID_CELL) + col=Color(0.2,0.8,1.0,0.8); + else + col=Color(1.0,0.4,0.2,0.8); + + for (int i=0;i<4;i++) + canvas_item_editor->draw_line(endpoints[i],endpoints[(i+1)%4],col,2); + + + bool bucket_preview = EditorSettings::get_singleton()->get("editors/tile_map/bucket_fill_preview"); + if (tool==TOOL_SELECTING || tool==TOOL_PICKING || !bucket_preview) { + return; + } + + if (tool==TOOL_LINE_PAINT) { + + if (paint_undo.empty()) + return; + + int id = get_selected_tile(); + + if (id==TileMap::INVALID_CELL) + return; + + for (Map<Point2i, CellOp>::Element *E=paint_undo.front();E;E=E->next()) { + + _draw_cell(id, E->key(), flip_h, flip_v, transpose, xform); + } + + } else if (tool==TOOL_RECTANGLE_PAINT) { + + int id = get_selected_tile(); + + if (id==TileMap::INVALID_CELL) + return; + + for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) { + for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) { + + _draw_cell(id, Point2i(j, i), flip_h, flip_v, transpose, xform); + } + } + } else if (tool==TOOL_DUPLICATING) { + + if (copydata.empty()) + return; + + Ref<TileSet> ts = node->get_tileset(); + + if (ts.is_null()) + return; + + Point2 ofs = over_tile-rectangle.pos; + + for (List<TileData>::Element *E=copydata.front();E;E=E->next()) { + + if (!ts->has_tile(E->get().cell)) + continue; + + TileData tcd = E->get(); + + _draw_cell(tcd.cell, tcd.pos+ofs, tcd.flip_h, tcd.flip_v, tcd.transpose, xform); + } + + Rect2i duplicate=rectangle; + duplicate.pos=over_tile; + + Vector<Vector2> points; + points.push_back( xform.xform( node->map_to_world(duplicate.pos ) )); + points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(duplicate.size.x+1,0)) ) )); + points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(duplicate.size.x+1,duplicate.size.y+1))) )); + points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(0,duplicate.size.y+1))) )); + + canvas_item_editor->draw_colored_polygon(points, Color(0.2,1.0,0.8,0.2)); + + } else if(tool == TOOL_BUCKET) { + + int tile = get_selected_tile(); + _draw_fill_preview(tile, over_tile, flip_h, flip_v, transpose, xform); + + } else { + + int st = get_selected_tile(); + + if (st==TileMap::INVALID_CELL) + return; + + _draw_cell(st, over_tile, flip_h, flip_v, transpose, xform); + } + } +} + +void TileMapEditor::edit(Node *p_tile_map) { + + search_box->set_text(""); + + if (!canvas_item_editor) { + canvas_item_editor=CanvasItemEditor::get_singleton()->get_viewport_control(); + } + + if (node) + node->disconnect("settings_changed",this,"_tileset_settings_changed"); + if (p_tile_map) { + + node=p_tile_map->cast_to<TileMap>(); + if (!canvas_item_editor->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->connect("draw",this,"_canvas_draw"); + if (!canvas_item_editor->is_connected("mouse_entered",this,"_canvas_mouse_enter")) + canvas_item_editor->connect("mouse_entered",this,"_canvas_mouse_enter"); + if (!canvas_item_editor->is_connected("mouse_exited",this,"_canvas_mouse_exit")) + canvas_item_editor->connect("mouse_exited",this,"_canvas_mouse_exit"); + + _update_palette(); + + } else { + node=NULL; + + if (canvas_item_editor->is_connected("draw",this,"_canvas_draw")) + canvas_item_editor->disconnect("draw",this,"_canvas_draw"); + if (canvas_item_editor->is_connected("mouse_entered",this,"_canvas_mouse_enter")) + canvas_item_editor->disconnect("mouse_entered",this,"_canvas_mouse_enter"); + if (canvas_item_editor->is_connected("mouse_exited",this,"_canvas_mouse_exit")) + canvas_item_editor->disconnect("mouse_exited",this,"_canvas_mouse_exit"); + + _update_palette(); + } + + if (node) + node->connect("settings_changed",this,"_tileset_settings_changed"); + + _clear_bucket_cache(); + +} + +void TileMapEditor::_tileset_settings_changed() { + + _update_palette(); + + if (canvas_item_editor) + canvas_item_editor->update(); +} + +void TileMapEditor::_icon_size_changed(float p_value) { + if (node) { + palette->set_icon_scale(p_value); + _update_palette(); + } +} + +void TileMapEditor::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_text_entered"),&TileMapEditor::_text_entered); + ClassDB::bind_method(D_METHOD("_text_changed"),&TileMapEditor::_text_changed); + ClassDB::bind_method(D_METHOD("_sbox_input"),&TileMapEditor::_sbox_input); + ClassDB::bind_method(D_METHOD("_menu_option"),&TileMapEditor::_menu_option); + ClassDB::bind_method(D_METHOD("_canvas_draw"),&TileMapEditor::_canvas_draw); + ClassDB::bind_method(D_METHOD("_canvas_mouse_enter"),&TileMapEditor::_canvas_mouse_enter); + ClassDB::bind_method(D_METHOD("_canvas_mouse_exit"),&TileMapEditor::_canvas_mouse_exit); + ClassDB::bind_method(D_METHOD("_tileset_settings_changed"),&TileMapEditor::_tileset_settings_changed); + ClassDB::bind_method(D_METHOD("_update_transform_buttons"),&TileMapEditor::_update_transform_buttons); + + ClassDB::bind_method(D_METHOD("_fill_points"),&TileMapEditor::_fill_points); + ClassDB::bind_method(D_METHOD("_erase_points"),&TileMapEditor::_erase_points); + + ClassDB::bind_method(D_METHOD("_icon_size_changed"), &TileMapEditor::_icon_size_changed); +} + +TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i& p_pos) +{ + CellOp op; + op.idx = node->get_cell(p_pos.x,p_pos.y); + if (op.idx!=TileMap::INVALID_CELL) { + if (node->is_cell_x_flipped(p_pos.x,p_pos.y)) + op.xf=true; + if (node->is_cell_y_flipped(p_pos.x,p_pos.y)) + op.yf=true; + if (node->is_cell_transposed(p_pos.x,p_pos.y)) + op.tr=true; + } + return op; +} + +void TileMapEditor::_update_transform_buttons(Object *p_button) { + //ERR_FAIL_NULL(p_button); + ToolButton *b=p_button->cast_to<ToolButton>(); + //ERR_FAIL_COND(!b); + + if (b == rotate_0) { + mirror_x->set_pressed(false); + mirror_y->set_pressed(false); + transp->set_pressed(false); + } + else if (b == rotate_90) { + mirror_x->set_pressed(true); + mirror_y->set_pressed(false); + transp->set_pressed(true); + } + else if (b == rotate_180) { + mirror_x->set_pressed(true); + mirror_y->set_pressed(true); + transp->set_pressed(false); + } + else if (b == rotate_270) { + mirror_x->set_pressed(false); + mirror_y->set_pressed(true); + transp->set_pressed(true); + } + + flip_h=mirror_x->is_pressed(); + flip_v=mirror_y->is_pressed(); + transpose=transp->is_pressed(); + + rotate_0->set_pressed(!flip_h && !flip_v && !transpose); + rotate_90->set_pressed(flip_h && !flip_v && transpose); + rotate_180->set_pressed(flip_h && flip_v && !transpose); + rotate_270->set_pressed(!flip_h && flip_v && transpose); +} + +TileMapEditor::TileMapEditor(EditorNode *p_editor) { + + node=NULL; + canvas_item_editor=NULL; + editor=p_editor; + undo_redo=editor->get_undo_redo(); + + tool=TOOL_NONE; + selection_active=false; + mouse_over=false; + + flip_h=false; + flip_v=false; + transpose=false; + + bucket_cache_tile = -1; + bucket_cache_visited = 0; + + ED_SHORTCUT("tile_map_editor/erase_selection", TTR("Erase selection"), KEY_DELETE); + ED_SHORTCUT("tile_map_editor/find_tile", TTR("Find tile"), KEY_MASK_CMD+KEY_F); + ED_SHORTCUT("tile_map_editor/transpose", TTR("Transpose")); + ED_SHORTCUT("tile_map_editor/mirror_x", TTR("Mirror X"), KEY_A); + ED_SHORTCUT("tile_map_editor/mirror_y", TTR("Mirror Y"), KEY_S); + + search_box = memnew( LineEdit ); + search_box->set_h_size_flags(SIZE_EXPAND_FILL); + search_box->connect("text_entered", this, "_text_entered"); + search_box->connect("text_changed", this, "_text_changed"); + search_box->connect("gui_input", this, "_sbox_input"); + add_child(search_box); + + size_slider = memnew( HSlider ); + size_slider->set_h_size_flags(SIZE_EXPAND_FILL); + size_slider->set_min(0.1f); + size_slider->set_max(4.0f); + size_slider->set_step(0.1f); + size_slider->set_value(1.0f); + size_slider->connect("value_changed", this, "_icon_size_changed"); + add_child(size_slider); + + int mw = EDITOR_DEF("editors/tile_map/palette_min_width", 80); + + // Add tile palette + palette = memnew( ItemList ); + palette->set_v_size_flags(SIZE_EXPAND_FILL); + palette->set_custom_minimum_size(Size2(mw,0)); + palette->set_max_columns(0); + palette->set_icon_mode(ItemList::ICON_MODE_TOP); + palette->set_max_text_lines(2); + add_child(palette); + + // Add menu items + toolbar = memnew( HBoxContainer ); + toolbar->set_h_size_flags(SIZE_EXPAND_FILL); + toolbar->set_alignment(BoxContainer::ALIGN_END); + CanvasItemEditor::get_singleton()->add_control_to_menu_panel(toolbar); + + // Tile position + tile_info = memnew( Label ); + toolbar->add_child(tile_info); + + options = memnew( MenuButton ); + options->set_text("Tile Map"); + options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("TileMap", "EditorIcons")); + options->set_process_unhandled_key_input(false); + + PopupMenu *p = options->get_popup(); + + p->add_item(TTR("Bucket"), OPTION_BUCKET); + p->add_separator(); + p->add_item(TTR("Pick Tile"), OPTION_PICK_TILE, KEY_CONTROL); + p->add_separator(); + p->add_shortcut(ED_SHORTCUT("tile_map_editor/select", TTR("Select"), KEY_MASK_CMD+KEY_B), OPTION_SELECT); + p->add_shortcut(ED_SHORTCUT("tile_map_editor/duplicate_selection", TTR("Duplicate Selection"), KEY_MASK_CMD+KEY_D), OPTION_DUPLICATE); + p->add_shortcut(ED_GET_SHORTCUT("tile_map_editor/erase_selection"), OPTION_ERASE_SELECTION); + + p->connect("id_pressed", this, "_menu_option"); + + toolbar->add_child(options); + + toolbar->add_child( memnew( VSeparator ) ); + + transp = memnew( ToolButton ); + transp->set_toggle_mode(true); + transp->set_tooltip(TTR("Transpose") + " ("+ED_GET_SHORTCUT("tile_map_editor/transpose")->get_as_text()+")"); + transp->set_focus_mode(FOCUS_NONE); + transp->connect("pressed", this, "_update_transform_buttons", make_binds(transp)); + toolbar->add_child(transp); + mirror_x = memnew( ToolButton ); + mirror_x->set_toggle_mode(true); + mirror_x->set_tooltip(TTR("Mirror X") + " ("+ED_GET_SHORTCUT("tile_map_editor/mirror_x")->get_as_text()+")"); + mirror_x->set_focus_mode(FOCUS_NONE); + mirror_x->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_x)); + toolbar->add_child(mirror_x); + mirror_y = memnew( ToolButton ); + mirror_y->set_toggle_mode(true); + mirror_y->set_tooltip(TTR("Mirror Y") + " ("+ED_GET_SHORTCUT("tile_map_editor/mirror_y")->get_as_text()+")"); + mirror_y->set_focus_mode(FOCUS_NONE); + mirror_y->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_y)); + toolbar->add_child(mirror_y); + + toolbar->add_child( memnew( VSeparator ) ); + + rotate_0 = memnew( ToolButton ); + rotate_0->set_toggle_mode(true); + rotate_0->set_tooltip(TTR("Rotate 0 degrees")); + rotate_0->set_focus_mode(FOCUS_NONE); + rotate_0->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_0)); + toolbar->add_child(rotate_0); + rotate_90 = memnew( ToolButton ); + rotate_90->set_toggle_mode(true); + rotate_90->set_tooltip(TTR("Rotate 90 degrees")); + rotate_90->set_focus_mode(FOCUS_NONE); + rotate_90->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_90)); + toolbar->add_child(rotate_90); + rotate_180 = memnew( ToolButton ); + rotate_180->set_toggle_mode(true); + rotate_180->set_tooltip(TTR("Rotate 180 degrees")); + rotate_180->set_focus_mode(FOCUS_NONE); + rotate_180->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_180)); + toolbar->add_child(rotate_180); + rotate_270 = memnew( ToolButton ); + rotate_270->set_toggle_mode(true); + rotate_270->set_tooltip(TTR("Rotate 270 degrees")); + rotate_270->set_focus_mode(FOCUS_NONE); + rotate_270->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_270)); + toolbar->add_child(rotate_270); + toolbar->hide(); + + rotate_0->set_pressed(true); +} + +TileMapEditor::~TileMapEditor() { + _clear_bucket_cache(); +} + +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// + +void TileMapEditorPlugin::edit(Object *p_object) { + + tile_map_editor->edit(p_object->cast_to<Node>()); +} + +bool TileMapEditorPlugin::handles(Object *p_object) const { + + return p_object->is_class("TileMap"); +} + +void TileMapEditorPlugin::make_visible(bool p_visible) { + + if (p_visible) { + + tile_map_editor->show(); + tile_map_editor->get_toolbar()->show(); + } else { + + tile_map_editor->hide(); + tile_map_editor->get_toolbar()->hide(); + tile_map_editor->edit(NULL); + } +} + +TileMapEditorPlugin::TileMapEditorPlugin(EditorNode *p_node) { + + EDITOR_DEF("editors/tile_map/preview_size",64); + EDITOR_DEF("editors/tile_map/palette_item_hseparation",8); + EDITOR_DEF("editors/tile_map/show_tile_names", true); + EDITOR_DEF("editors/tile_map/bucket_fill_preview", true); + + tile_map_editor = memnew( TileMapEditor(p_node) ); + add_control_to_container(CONTAINER_CANVAS_EDITOR_SIDE, tile_map_editor); + tile_map_editor->hide(); +} + +TileMapEditorPlugin::~TileMapEditorPlugin() +{ +} + diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h new file mode 100644 index 0000000000..82e2a396d1 --- /dev/null +++ b/editor/plugins/tile_map_editor_plugin.h @@ -0,0 +1,207 @@ +/*************************************************************************/ +/* tile_map_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef TILE_MAP_EDITOR_PLUGIN_H +#define TILE_MAP_EDITOR_PLUGIN_H + +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" + +#include "scene/2d/tile_map.h" +#include "scene/gui/line_edit.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/label.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +class TileMapEditor : public VBoxContainer { + + GDCLASS(TileMapEditor, VBoxContainer ); + + enum Tool { + + TOOL_NONE, + TOOL_PAINTING, + TOOL_ERASING, + TOOL_RECTANGLE_PAINT, + TOOL_RECTANGLE_ERASE, + TOOL_LINE_PAINT, + TOOL_LINE_ERASE, + TOOL_SELECTING, + TOOL_BUCKET, + TOOL_PICKING, + TOOL_DUPLICATING, + }; + + enum Options { + + OPTION_BUCKET, + OPTION_PICK_TILE, + OPTION_SELECT, + OPTION_DUPLICATE, + OPTION_ERASE_SELECTION + }; + + TileMap *node; + + EditorNode *editor; + UndoRedo *undo_redo; + Control *canvas_item_editor; + + LineEdit *search_box; + HSlider *size_slider; + ItemList *palette; + + HBoxContainer *toolbar; + + Label *tile_info; + MenuButton *options; + ToolButton *transp; + ToolButton *mirror_x; + ToolButton *mirror_y; + ToolButton *rotate_0; + ToolButton *rotate_90; + ToolButton *rotate_180; + ToolButton *rotate_270; + + Tool tool; + + bool selection_active; + bool mouse_over; + + bool flip_h; + bool flip_v; + bool transpose; + + Point2i rectangle_begin; + Rect2i rectangle; + + Point2i over_tile; + + bool * bucket_cache_visited; + Rect2i bucket_cache_rect; + int bucket_cache_tile; + PoolVector<Vector2> bucket_cache; + + struct CellOp { + int idx; + bool xf; + bool yf; + bool tr; + + CellOp() { idx=-1; xf=false; yf=false; tr=false; } + }; + + Map<Point2i, CellOp> paint_undo; + + struct TileData { + Point2i pos; + int cell; + bool flip_h; + bool flip_v; + bool transpose; + }; + + List<TileData> copydata; + + void _pick_tile(const Point2& p_pos); + + PoolVector<Vector2> _bucket_fill(const Point2i& p_start, bool erase=false, bool preview=false); + + void _fill_points(const PoolVector<Vector2> p_points, const Dictionary& p_op); + void _erase_points(const PoolVector<Vector2> p_points); + + void _select(const Point2i& p_from, const Point2i& p_to); + + void _draw_cell(int p_cell, const Point2i& p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D& p_xform); + void _draw_fill_preview(int p_cell, const Point2i& p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D& p_xform); + void _clear_bucket_cache(); + + void _update_copydata(); + + int get_selected_tile() const; + void set_selected_tile(int p_tile); + + void _text_entered(const String& p_text); + void _text_changed(const String& p_text); + void _sbox_input(const InputEvent& p_ie); + void _update_palette(); + void _canvas_draw(); + void _menu_option(int p_option); + + void _set_cell(const Point2i& p_pos, int p_value, bool p_flip_h=false, bool p_flip_v=false, bool p_transpose=false, bool p_with_undo=false); + + void _canvas_mouse_enter(); + void _canvas_mouse_exit(); + void _tileset_settings_changed(); + void _icon_size_changed(float p_value); + +protected: + + void _notification(int p_what); + static void _bind_methods(); + CellOp _get_op_from_cell(const Point2i& p_pos); + void _update_transform_buttons(Object *p_button=NULL); + +public: + + HBoxContainer *get_toolbar() const { return toolbar; } + + bool forward_gui_input(const InputEvent& p_event); + void edit(Node *p_tile_map); + + TileMapEditor(EditorNode *p_editor); + ~TileMapEditor(); +}; + +class TileMapEditorPlugin : public EditorPlugin { + + GDCLASS( TileMapEditorPlugin, EditorPlugin ); + + TileMapEditor *tile_map_editor; + +public: + + virtual bool forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return tile_map_editor->forward_gui_input(p_event); } + + virtual String get_name() const { return "TileMap"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + TileMapEditorPlugin(EditorNode *p_node); + ~TileMapEditorPlugin(); + +}; + + +#endif // TILE_MAP_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index 3db6c94917..3db6c94917 100644 --- a/tools/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h new file mode 100644 index 0000000000..02a82ebd6b --- /dev/null +++ b/editor/plugins/tile_set_editor_plugin.h @@ -0,0 +1,101 @@ +/*************************************************************************/ +/* tile_set_editor_plugin.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef TILE_SET_EDITOR_PLUGIN_H +#define TILE_SET_EDITOR_PLUGIN_H + + + +#include "scene/resources/tile_set.h" +#include "editor/editor_node.h" +#include "editor/editor_name_dialog.h" + + +class TileSetEditor : public Control { + + GDCLASS( TileSetEditor, Control ); + + Ref<TileSet> tileset; + + EditorNode *editor; + MenuButton *menu; + ConfirmationDialog *cd; + EditorNameDialog *nd; + AcceptDialog *err_dialog; + + enum { + + MENU_OPTION_ADD_ITEM, + MENU_OPTION_REMOVE_ITEM, + MENU_OPTION_CREATE_FROM_SCENE, + MENU_OPTION_MERGE_FROM_SCENE + }; + + int option; + void _menu_cbk(int p_option); + void _menu_confirm(); + void _name_dialog_confirm(const String& name); + + static void _import_scene(Node *p_scene, Ref<TileSet> p_library, bool p_merge); + + +protected: + static void _bind_methods(); +public: + + void edit(const Ref<TileSet>& p_tileset); + static Error update_library_file(Node *p_base_scene, Ref<TileSet> ml,bool p_merge=true); + + TileSetEditor(EditorNode *p_editor); +}; + + + +class TileSetEditorPlugin : public EditorPlugin { + + GDCLASS( TileSetEditorPlugin, EditorPlugin ); + + TileSetEditor *tileset_editor; + EditorNode *editor; + +public: + + virtual String get_name() const { return "TileSet"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + + + TileSetEditorPlugin(EditorNode *p_node); + +}; + + +#endif // TILE_SET_EDITOR_PLUGIN_H diff --git a/tools/editor/progress_dialog.cpp b/editor/progress_dialog.cpp index 76626c4556..76626c4556 100644 --- a/tools/editor/progress_dialog.cpp +++ b/editor/progress_dialog.cpp diff --git a/tools/editor/progress_dialog.h b/editor/progress_dialog.h index 60acf825a9..60acf825a9 100644 --- a/tools/editor/progress_dialog.h +++ b/editor/progress_dialog.h diff --git a/tools/editor/project_export.cpp b/editor/project_export.cpp index fc6d8793d8..fc6d8793d8 100644 --- a/tools/editor/project_export.cpp +++ b/editor/project_export.cpp diff --git a/editor/project_export.h b/editor/project_export.h new file mode 100644 index 0000000000..b58ce2dc9d --- /dev/null +++ b/editor/project_export.h @@ -0,0 +1,142 @@ +/*************************************************************************/ +/* project_export.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef PROJECT_EXPORT_SETTINGS_H +#define PROJECT_EXPORT_SETTINGS_H + +#include "scene/main/timer.h" +#include "scene/gui/control.h" +#include "scene/gui/tree.h" +#include "scene/gui/label.h" +#include "editor/editor_file_dialog.h" +#include "scene/gui/button.h" +#include "scene/gui/file_dialog.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/tab_container.h" +#include "os/dir_access.h" +#include "os/thread.h" +#include "scene/gui/option_button.h" + +#include "scene/gui/slider.h" +#include "editor/editor_file_system.h" +#include "property_editor.h" +#include "editor_export.h" + + +class EditorNode; + +class ProjectExportDialog : public ConfirmationDialog { + GDCLASS( ProjectExportDialog, ConfirmationDialog ); + +private: + + + TabContainer *sections; + + MenuButton *add_preset; + Button *delete_preset; + ItemList *presets; + + LineEdit *name; + PropertyEditor *parameters; + CheckButton *runnable; + + + EditorFileDialog *pck_export; + EditorFileDialog *file_export; + + Button *button_export; + bool updating; + + ConfirmationDialog *delete_confirm; + + OptionButton *export_filter; + LineEdit *include_filters; + LineEdit *exclude_filters; + Tree *include_files; + + Label* include_label; + MarginContainer *include_margin; + + StringName editor_icons; + + Tree *patches; + Button *patch_export; + int patch_index; + FileDialog *patch_dialog; + ConfirmationDialog *patch_erase; + + Button *export_button; + + void _patch_selected(const String& p_path); + void _patch_deleted(); + + void _runnable_pressed(); + void _name_changed(const String& p_string); + void _add_preset(int p_platform); + void _edit_preset(int p_index); + void _delete_preset(); + void _delete_preset_confirm(); + + void _update_presets(); + + void _export_type_changed(int p_which); + void _filter_changed(const String& p_filter); + void _fill_resource_tree(); + bool _fill_tree(EditorFileSystemDirectory *p_dir,TreeItem *p_item,Ref<EditorExportPreset> ¤t,bool p_only_scenes); + void _tree_changed(); + + void _patch_button_pressed(Object* p_item,int p_column,int p_id); + void _patch_edited(); + + + Variant get_drag_data_fw(const Point2& p_point,Control* p_from); + bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; + void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); + + FileDialog *export_pck_zip; + + void _export_pck_zip(); + void _export_pck_zip_selected(const String& p_path); + +protected: + void _notification(int p_what); + static void _bind_methods(); +public: + + void popup_export(); + + ProjectExportDialog(); + ~ProjectExportDialog(); +}; + + + + +#endif // PROJECT_EXPORT_SETTINGS_H + diff --git a/tools/editor/project_manager.cpp b/editor/project_manager.cpp index 34b2d3e82c..34b2d3e82c 100644 --- a/tools/editor/project_manager.cpp +++ b/editor/project_manager.cpp diff --git a/editor/project_manager.h b/editor/project_manager.h new file mode 100644 index 0000000000..cb6c0b7f26 --- /dev/null +++ b/editor/project_manager.h @@ -0,0 +1,148 @@ +/*************************************************************************/ +/* project_manager.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef PROJECT_MANAGER_H +#define PROJECT_MANAGER_H + +#include "scene/gui/dialogs.h" +#include "scene/gui/tree.h" +#include "scene/gui/scroll_container.h" +#include "scene/gui/file_dialog.h" +#include "scene/gui/tool_button.h" +#include "editor/asset_library_editor_plugin.h" + +class NewProjectDialog; +class ProjectListFilter; + +class ProjectManager : public Control { + GDCLASS( ProjectManager, Control ); + + Button *erase_btn; + Button *open_btn; + Button *run_btn; + + FileDialog *scan_dir; + + EditorAssetLibrary *asset_library; + + ProjectListFilter *project_filter; + + ConfirmationDialog *erase_ask; + ConfirmationDialog *multi_open_ask; + ConfirmationDialog *multi_run_ask; + ConfirmationDialog *multi_scan_ask; + NewProjectDialog *npdialog; + ScrollContainer *scroll; + VBoxContainer *scroll_childs; + Map<String, String> selected_list; // name -> main_scene + String last_clicked; + bool importing; + + HBoxContainer *projects_hb; + + TabContainer *tabs; + + Control *gui_base; + + + + void _scan_projects(); + void _run_project(); + void _run_project_confirm(); + void _open_project(); + void _open_project_confirm(); + void _import_project(); + void _new_project(); + void _erase_project(); + void _erase_project_confirm(); + void _update_project_buttons(); + void _exit_dialog(); + void _scan_begin(const String& p_base); + + void _load_recent_projects(); + void _on_project_created(const String& dir); + void _update_scroll_pos(const String& dir); + void _scan_dir(DirAccess *da,float pos, float total,List<String> *r_projects); + + void _install_project(const String& p_zip_path,const String& p_title); + + void _panel_draw(Node *p_hb); + void _panel_input(const InputEvent& p_ev,Node *p_hb); + void _unhandled_input(const InputEvent& p_ev); + void _favorite_pressed(Node *p_hb); + void _files_dropped(PoolStringArray p_files, int p_screen); + void _scan_multiple_folders(PoolStringArray p_files); + +protected: + + void _notification(int p_what); + static void _bind_methods(); +public: + ProjectManager(); + ~ProjectManager(); +}; + +class ProjectListFilter : public HBoxContainer { + + GDCLASS( ProjectListFilter, HBoxContainer ); + +private: + + friend class ProjectManager; + + enum Command { + CMD_CLEAR_FILTER, + }; + + OptionButton *filter_option; + LineEdit *search_box; + ToolButton *clear_search_button; + + enum FilterOption { + FILTER_NAME, + FILTER_PATH, + }; + FilterOption _current_filter; + + void _command(int p_command); + void _search_text_changed(const String& p_newtext); + void _setup_filters(); + void _filter_option_selected(int p_idx); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + + String get_search_term(); + FilterOption get_filter_option(); + ProjectListFilter(); +}; + +#endif // PROJECT_MANAGER_H diff --git a/tools/editor/project_settings.cpp b/editor/project_settings.cpp index 15019b8ca8..15019b8ca8 100644 --- a/tools/editor/project_settings.cpp +++ b/editor/project_settings.cpp diff --git a/tools/editor/project_settings.h b/editor/project_settings.h index 96ac2e2c11..96ac2e2c11 100644 --- a/tools/editor/project_settings.h +++ b/editor/project_settings.h diff --git a/tools/editor/property_editor.cpp b/editor/property_editor.cpp index 533a5b156b..533a5b156b 100644 --- a/tools/editor/property_editor.cpp +++ b/editor/property_editor.cpp diff --git a/editor/property_editor.h b/editor/property_editor.h new file mode 100644 index 0000000000..c9ae9a85cc --- /dev/null +++ b/editor/property_editor.h @@ -0,0 +1,352 @@ +/*************************************************************************/ +/* property_editor.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef PROPERTY_EDITOR_H +#define PROPERTY_EDITOR_H + +#include "scene/gui/tree.h" +#include "scene/gui/button.h" +#include "scene/gui/check_box.h" +#include "scene/gui/label.h" +#include "editor/editor_file_dialog.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/color_picker.h" +#include "scene/gui/menu_button.h" +#include "scene/gui/texture_rect.h" +#include "scene/gui/text_edit.h" +#include "scene/gui/check_button.h" +#include "scene/gui/split_container.h" +#include "scene/gui/grid_container.h" +#include "scene_tree_editor.h" + +/** + @author Juan Linietsky <reduzio@gmail.com> +*/ + +class PropertyValueEvaluator; +class CreateDialog; +class PropertySelector; + +class CustomPropertyEditor : public Popup { + + GDCLASS( CustomPropertyEditor, Popup ); + + enum { + MAX_VALUE_EDITORS=12, + MAX_ACTION_BUTTONS=5, + OBJ_MENU_LOAD=0, + OBJ_MENU_EDIT=1, + OBJ_MENU_CLEAR=2, + OBJ_MENU_MAKE_UNIQUE=3, + OBJ_MENU_COPY=4, + OBJ_MENU_PASTE=5, + OBJ_MENU_REIMPORT=6, + OBJ_MENU_NEW_SCRIPT=7, + OBJ_MENU_SHOW_IN_FILE_SYSTEM=8, + TYPE_BASE_ID=100 + }; + + enum { + EASING_LINEAR, + EASING_EASE_IN, + EASING_EASE_OUT, + EASING_ZERO, + EASING_IN_OUT, + EASING_OUT_IN + }; + + + PopupMenu *menu; + SceneTreeDialog *scene_tree; + EditorFileDialog *file; + ConfirmationDialog *error; + String name; + Variant::Type type; + Variant v; + List<String> field_names; + int hint; + String hint_text; + LineEdit *value_editor[MAX_VALUE_EDITORS]; + int focused_value_editor; + Label *value_label[MAX_VALUE_EDITORS]; + HScrollBar *scroll[4]; + Button *action_buttons[MAX_ACTION_BUTTONS]; + MenuButton *type_button; + Vector<String> inheritors_array; + TextureRect *texture_preview; + ColorPicker *color_picker; + TextEdit *text_edit; + bool read_only; + bool picking_viewport; + GridContainer *checks20gc; + CheckBox *checks20[20]; + SpinBox *spinbox; + HSlider *slider; + + + Control *easing_draw; + CreateDialog *create_dialog; + PropertySelector *property_select; + + Object* owner; + + bool updating; + + PropertyValueEvaluator *evaluator; + + void _text_edit_changed(); + void _file_selected(String p_file); + void _scroll_modified(double p_value); + void _modified(String p_string); + void _range_modified(double p_value); + void _focus_enter(); + void _focus_exit(); + void _action_pressed(int p_which); + void _type_create_selected(int p_idx); + void _create_dialog_callback(); + void _create_selected_property(const String &p_prop); + + + void _color_changed(const Color& p_color); + void _draw_easing(); + void _menu_option(int p_which); + + void _drag_easing(const InputEvent& p_ev); + + void _node_path_selected(NodePath p_path); + void show_value_editors(int p_amount); + void config_value_editors(int p_amount, int p_columns,int p_label_w,const List<String>& p_strings); + void config_action_buttons(const List<String>& p_strings); + + void _emit_changed_whole_or_field(); + + +protected: + + void _notification(int p_what); + static void _bind_methods(); + +public: + + + void hide_menu(); + + Variant get_variant() const; + String get_name() const; + + 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(); +}; + +class PropertyEditor : public Control { + + GDCLASS( PropertyEditor, Control ); + + Tree *tree; + Label *top_label; + //Object *object; + LineEdit *search_box; + + PropertyValueEvaluator *evaluator; + + Object* obj; + + + StringName _prop_edited; + + bool capitalize_paths; + bool changing; + bool update_tree_pending; + bool autoclear; + bool keying; + bool read_only; + bool show_categories; + bool show_type_icons; + float refresh_countdown; + bool use_doc_hints; + bool use_filter; + bool subsection_selectable; + bool hide_script; + + HashMap<String,String> pending; + String selected_property; + + Map<StringName,Map<StringName,String> > descr_cache; + Map<StringName,String > class_descr_cache; + + CustomPropertyEditor *custom_editor; + + void _resource_edit_request(); + void _custom_editor_edited(); + void _custom_editor_edited_field(const String& p_field_name); + void _custom_editor_request(bool p_arrow); + + void _item_selected(); + void _item_edited(); + TreeItem *get_parent_node(String p_path,HashMap<String,TreeItem*>& item_paths,TreeItem *root); + + void set_item_text(TreeItem *p_item, int p_type, const String& p_name, int p_hint=PROPERTY_HINT_NONE, const String& p_hint_text=""); + + TreeItem *find_item(TreeItem *p_item,const String& p_name); + + + virtual void _changed_callback(Object *p_changed,const char * p_what); + virtual void _changed_callbacks(Object *p_changed,const String& p_callback); + + void _check_reload_status(const String&p_name,TreeItem* item); + + void _edit_button(Object *p_item, int p_column, int p_button); + + void _node_removed(Node *p_node); + +friend class ProjectExportDialog; + void _edit_set(const String& p_name, const Variant& p_value,bool p_refresh_all=false, const String& p_changed_field=""); + void _draw_flags(Object *ti,const Rect2& p_rect); + + bool _might_be_in_instance(); + bool _get_instanced_node_original_property(const StringName& p_prop,Variant& value); + bool _is_property_different(const Variant& p_current, const Variant& p_orig,int p_usage=0); + + void _refresh_item(TreeItem *p_item); + void _set_range_def(Object *p_item, String prop, float p_frame); + + void _filter_changed(const String& p_text); + + void _mark_drop_fields(TreeItem* p_at); + void _clear_drop_fields(TreeItem* p_at); + + bool _is_drop_valid(const Dictionary& p_drag_data, const Dictionary& p_item_data) const; + Variant get_drag_data_fw(const Point2& p_point,Control* p_from); + bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; + void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); + + void _resource_preview_done(const String& p_path,const Ref<Texture>& p_preview,Variant p_ud); + void _draw_transparency(Object *t, const Rect2& p_rect); + + UndoRedo *undo_redo; +protected: + + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo=p_undo_redo; } + + String get_selected_path() const; + + Tree *get_scene_tree(); + Label* get_top_label(); + void hide_top_label(); + void update_tree(); + void update_property(const String& p_prop); + + void refresh(); + + void edit(Object* p_object); + + void set_keying(bool p_active); + void set_read_only(bool p_read_only) { read_only=p_read_only; custom_editor->set_read_only(p_read_only);} + + void set_capitalize_paths(bool p_capitalize); + void set_autoclear(bool p_enable); + + void set_show_categories(bool p_show); + void set_use_doc_hints(bool p_enable) { use_doc_hints=p_enable; } + void set_hide_script(bool p_hide) { hide_script=p_hide; } + + void set_use_filter(bool p_use); + void register_text_enter(Node *p_line_edit); + + void set_subsection_selectable(bool p_selectable); + + PropertyEditor(); + ~PropertyEditor(); + +}; + + +class SectionedPropertyEditorFilter; + +class SectionedPropertyEditor : public HBoxContainer { + + + GDCLASS(SectionedPropertyEditor,HBoxContainer); + + ObjectID obj; + + Tree *sections; + SectionedPropertyEditorFilter *filter; + + Map<String,TreeItem*> section_map; + PropertyEditor *editor; + + + static void _bind_methods(); + void _section_selected(); + +public: + + PropertyEditor *get_property_editor(); + void edit(Object* p_object); + String get_full_item_path(const String& p_item); + + void set_current_section(const String& p_section); + String get_current_section() const; + + void update_category_list(); + + SectionedPropertyEditor(); + ~SectionedPropertyEditor(); +}; + +class PropertyValueEvaluator : public ValueEvaluator { + GDCLASS( 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 diff --git a/tools/editor/property_selector.cpp b/editor/property_selector.cpp index 71ffae4729..71ffae4729 100644 --- a/tools/editor/property_selector.cpp +++ b/editor/property_selector.cpp diff --git a/editor/property_selector.h b/editor/property_selector.h new file mode 100644 index 0000000000..c2ce996be2 --- /dev/null +++ b/editor/property_selector.h @@ -0,0 +1,83 @@ +/*************************************************************************/ +/* property_selector.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef PROPERTYSELECTOR_H +#define PROPERTYSELECTOR_H + +#include "editor/property_editor.h" +#include "scene/gui/rich_text_label.h" +#include "editor_help.h" + +class PropertySelector : public ConfirmationDialog { + GDCLASS(PropertySelector,ConfirmationDialog ) + + + LineEdit *search_box; + Tree *search_options; + + void _update_search(); + + void _sbox_input(const InputEvent& p_ie); + + void _confirmed(); + void _text_changed(const String& p_newtext); + + EditorHelpBit *help_bit; + + bool properties; + String selected; + Variant::Type type; + InputEvent::Type event_type; + String base_type; + ObjectID script; + Object *instance; + + void _item_selected(); +protected: + void _notification(int p_what); + static void _bind_methods(); + + + +public: + + + void select_method_from_base_type(const String& p_base,const String& p_current=""); + void select_method_from_script(const Ref<Script>& p_script,const String& p_current=""); + void select_method_from_basic_type(Variant::Type p_type,const String& p_current=""); + void select_method_from_instance(Object* p_instance, const String &p_current=""); + + void select_property_from_base_type(const String& p_base,const String& p_current=""); + void select_property_from_script(const Ref<Script>& p_script,const String& p_current=""); + void select_property_from_basic_type(Variant::Type p_type,InputEvent::Type p_event_type,const String& p_current=""); + void select_property_from_instance(Object* p_instance, const String &p_current=""); + + PropertySelector(); +}; + +#endif // PROPERTYSELECTOR_H diff --git a/tools/editor/pvrtc_compress.cpp b/editor/pvrtc_compress.cpp index b130f6c773..b130f6c773 100644 --- a/tools/editor/pvrtc_compress.cpp +++ b/editor/pvrtc_compress.cpp diff --git a/tools/editor/pvrtc_compress.h b/editor/pvrtc_compress.h index 4ba29026c5..4ba29026c5 100644 --- a/tools/editor/pvrtc_compress.h +++ b/editor/pvrtc_compress.h diff --git a/tools/editor/quick_open.cpp b/editor/quick_open.cpp index f43189a7bf..f43189a7bf 100644 --- a/tools/editor/quick_open.cpp +++ b/editor/quick_open.cpp diff --git a/tools/editor/quick_open.h b/editor/quick_open.h index ef91d910b1..ef91d910b1 100644 --- a/tools/editor/quick_open.h +++ b/editor/quick_open.h diff --git a/tools/editor/register_exporters.h b/editor/register_exporters.h index 30ec522a00..30ec522a00 100644 --- a/tools/editor/register_exporters.h +++ b/editor/register_exporters.h diff --git a/tools/editor/reparent_dialog.cpp b/editor/reparent_dialog.cpp index c5b74d9006..c5b74d9006 100644 --- a/tools/editor/reparent_dialog.cpp +++ b/editor/reparent_dialog.cpp diff --git a/editor/reparent_dialog.h b/editor/reparent_dialog.h new file mode 100644 index 0000000000..200760314c --- /dev/null +++ b/editor/reparent_dialog.h @@ -0,0 +1,68 @@ +/*************************************************************************/ +/* reparent_dialog.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef REPARENT_DIALOG_H +#define REPARENT_DIALOG_H + +#include "scene/gui/dialogs.h" +#include "scene/gui/button.h" +#include "scene/gui/check_button.h" +#include "scene/gui/check_box.h" +#include "editor/scene_tree_editor.h" +#include "scene/gui/line_edit.h" +/** +@author Juan Linietsky <reduzio@gmail.com> +*/ +class ReparentDialog : public ConfirmationDialog { + + GDCLASS( ReparentDialog, ConfirmationDialog ); + + SceneTreeEditor *tree; + CheckBox *keep_transform; + + + void update_tree(); + void _reparent(); + void _cancel(); + + +protected: + + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_current(const Set<Node*>& p_selection); + String get_selected_type(); + + ReparentDialog(); + ~ReparentDialog(); + +}; + +#endif diff --git a/tools/editor/resources_dock.cpp b/editor/resources_dock.cpp index 8648361bae..8648361bae 100644 --- a/tools/editor/resources_dock.cpp +++ b/editor/resources_dock.cpp diff --git a/tools/editor/resources_dock.h b/editor/resources_dock.h index e225786583..e225786583 100644 --- a/tools/editor/resources_dock.h +++ b/editor/resources_dock.h diff --git a/tools/editor/run_settings_dialog.cpp b/editor/run_settings_dialog.cpp index 4d69c7ad84..4d69c7ad84 100644 --- a/tools/editor/run_settings_dialog.cpp +++ b/editor/run_settings_dialog.cpp diff --git a/tools/editor/run_settings_dialog.h b/editor/run_settings_dialog.h index 2efc18e43f..2efc18e43f 100644 --- a/tools/editor/run_settings_dialog.h +++ b/editor/run_settings_dialog.h diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp new file mode 100644 index 0000000000..47eb84ab79 --- /dev/null +++ b/editor/scene_tree_dock.cpp @@ -0,0 +1,2061 @@ +/*************************************************************************/ +/* scene_tree_dock.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 "scene_tree_dock.h" + +#include "editor_node.h" +#include "global_config.h" +#include "os/keyboard.h" +#include "scene/resources/packed_scene.h" +#include "editor_settings.h" +#include "editor/plugins/canvas_item_editor_plugin.h" +#include "editor/plugins/spatial_editor_plugin.h" +#include "script_editor_debugger.h" +#include "editor/plugins/script_editor_plugin.h" +#include "core/io/resource_saver.h" +#include "multi_node_edit.h" +#include "editor/plugins/animation_player_editor_plugin.h" +#include "animation_editor.h" +#include "scene/main/viewport.h" + + +void SceneTreeDock::_nodes_drag_begin() { + + + if (restore_script_editor_on_drag) { + EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT); + restore_script_editor_on_drag=false; + } + +} + +void SceneTreeDock::_input(InputEvent p_event) { + + if (p_event.type==InputEvent::MOUSE_BUTTON && !p_event.mouse_button.pressed && p_event.mouse_button.button_index==BUTTON_LEFT) { + restore_script_editor_on_drag=false; //lost chance + } +} + +void SceneTreeDock::_unhandled_key_input(InputEvent p_event) { + + if (get_viewport()->get_modal_stack_top()) + return; //ignore because of modal window + + if (!p_event.key.pressed || p_event.key.echo) + return; + + if (ED_IS_SHORTCUT("scene_tree/add_child_node", p_event)) { + _tool_selected(TOOL_NEW); + } + else if (ED_IS_SHORTCUT("scene_tree/instance_scene", p_event)) { + _tool_selected(TOOL_INSTANCE); + } + else if (ED_IS_SHORTCUT("scene_tree/change_node_type", p_event)) { + _tool_selected(TOOL_REPLACE); + } + else if (ED_IS_SHORTCUT("scene_tree/duplicate", p_event)) { + _tool_selected(TOOL_DUPLICATE); + } + else if (ED_IS_SHORTCUT("scene_tree/attach_script", p_event)) { + _tool_selected(TOOL_ATTACH_SCRIPT); + } + else if(ED_IS_SHORTCUT("scene_tree/clear_script", p_event)) { + _tool_selected(TOOL_CLEAR_SCRIPT); + } + else if (ED_IS_SHORTCUT("scene_tree/move_up", p_event)) { + _tool_selected(TOOL_MOVE_UP); + } + else if (ED_IS_SHORTCUT("scene_tree/move_down", p_event)) { + _tool_selected(TOOL_MOVE_DOWN); + } + else if (ED_IS_SHORTCUT("scene_tree/reparent", p_event)) { + _tool_selected(TOOL_REPARENT); + } + else if (ED_IS_SHORTCUT("scene_tree/merge_from_scene", p_event)) { + _tool_selected(TOOL_MERGE_FROM_SCENE); + } + else if (ED_IS_SHORTCUT("scene_tree/save_branch_as_scene", p_event)) { + _tool_selected(TOOL_NEW_SCENE_FROM); + } + else if (ED_IS_SHORTCUT("scene_tree/delete_no_confirm", p_event)) { + _tool_selected(TOOL_ERASE, true); + } + else if(ED_IS_SHORTCUT("scene_tree/copy_node_path", p_event)) { + _tool_selected(TOOL_COPY_NODE_PATH); + } + else if (ED_IS_SHORTCUT("scene_tree/delete", p_event)) { + _tool_selected(TOOL_ERASE); + } +} + +void SceneTreeDock::instance(const String& p_file) { + + Node *parent = scene_tree->get_selected(); + if (!parent || !edited_scene) { + + current_option=-1; + //accept->get_cancel()->hide(); + accept->get_ok()->set_text(TTR("OK :(")); + accept->set_text(TTR("No parent to instance a child at.")); + accept->popup_centered_minsize(); + return; + }; + + ERR_FAIL_COND(!parent); + + Vector<String> scenes; + scenes.push_back(p_file); + _perform_instance_scenes(scenes,parent,-1); + +} + +void SceneTreeDock::instance_scenes(const Vector<String>& p_files, Node *p_parent) { + + Node *parent = p_parent; + + if (!parent) { + parent = scene_tree->get_selected(); + } + + if (!parent || !edited_scene) { + + accept->get_ok()->set_text(TTR("OK")); + accept->set_text(TTR("No parent to instance the scenes at.")); + accept->popup_centered_minsize(); + return; + }; + + _perform_instance_scenes(p_files, parent, -1); +} + +void SceneTreeDock::_perform_instance_scenes(const Vector<String>& p_files,Node* parent,int p_pos) { + + + + ERR_FAIL_COND(!parent); + + + Vector<Node*> instances; + + bool error=false; + + for(int i=0;i<p_files.size();i++) { + + Ref<PackedScene> sdata = ResourceLoader::load(p_files[i]); + if (!sdata.is_valid()) { + current_option=-1; + //accept->get_cancel()->hide(); + accept->get_ok()->set_text(TTR("Ugh")); + accept->set_text(vformat(TTR("Error loading scene from %s"),p_files[i])); + accept->popup_centered_minsize(); + error=true; + break; + + } + + Node*instanced_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); + if (!instanced_scene) { + current_option=-1; + //accept->get_cancel()->hide(); + accept->get_ok()->set_text(TTR("Ugh")); + accept->set_text(vformat(TTR("Error instancing scene from %s"),p_files[i])); + accept->popup_centered_minsize(); + error=true; + break; + + } + + if (edited_scene->get_filename()!="") { + + if (_cyclical_dependency_exists(edited_scene->get_filename(), instanced_scene)) { + + accept->get_ok()->set_text(TTR("Ok")); + accept->set_text(vformat(TTR("Cannot instance the scene '%s' because the current scene exists within one of its nodes."),p_files[i])); + accept->popup_centered_minsize(); + error=true; + break; + } + } + + instanced_scene->set_filename( GlobalConfig::get_singleton()->localize_path(p_files[i]) ); + + instances.push_back(instanced_scene); + } + + if (error) { + for(int i=0;i<instances.size();i++) { + memdelete(instances[i]); + } + return; + } + + + + //instanced_scene->generate_instance_state(); + + editor_data->get_undo_redo().create_action(TTR("Instance Scene(s)")); + + for(int i=0;i<instances.size();i++) { + + Node* instanced_scene=instances[i]; + + editor_data->get_undo_redo().add_do_method(parent,"add_child",instanced_scene); + if (p_pos>=0) { + editor_data->get_undo_redo().add_do_method(parent,"move_child",instanced_scene,p_pos+i); + } + editor_data->get_undo_redo().add_do_method(instanced_scene,"set_owner",edited_scene); + editor_data->get_undo_redo().add_do_method(editor_selection,"clear"); + editor_data->get_undo_redo().add_do_method(editor_selection,"add_node",instanced_scene); + editor_data->get_undo_redo().add_do_reference(instanced_scene); + editor_data->get_undo_redo().add_undo_method(parent,"remove_child",instanced_scene); + + String new_name = parent->validate_child_name(instanced_scene); + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + editor_data->get_undo_redo().add_do_method(sed,"live_debug_instance_node",edited_scene->get_path_to(parent),p_files[i],new_name); + editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+new_name)); + } + + editor_data->get_undo_redo().commit_action(); + + +} + +void SceneTreeDock::_replace_with_branch_scene(const String& p_file,Node* base) { + Ref<PackedScene> sdata = ResourceLoader::load(p_file); + if (!sdata.is_valid()) { + accept->get_ok()->set_text(TTR("Ugh")); + accept->set_text(vformat(TTR("Error loading scene from %s"),p_file)); + accept->popup_centered_minsize(); + return; + } + + Node *instanced_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); + if (!instanced_scene) { + accept->get_ok()->set_text(TTR("Ugh")); + accept->set_text(vformat(TTR("Error instancing scene from %s"),p_file)); + accept->popup_centered_minsize(); + return; + } + + Node *parent = base->get_parent(); + int pos = base->get_index(); + memdelete(base); + parent->add_child(instanced_scene); + parent->move_child(instanced_scene, pos); + instanced_scene->set_owner(edited_scene); + editor_selection->clear(); + editor_selection->add_node(instanced_scene); + scene_tree->set_selected(instanced_scene); +} + +bool SceneTreeDock::_cyclical_dependency_exists(const String& p_target_scene_path, Node* p_desired_node) { + int childCount = p_desired_node->get_child_count(); + + if (p_desired_node->get_filename()==p_target_scene_path) { + return true; + } + + for (int i=0;i<childCount;i++) { + Node* child=p_desired_node->get_child(i); + + if(_cyclical_dependency_exists(p_target_scene_path,child)) { + return true; + } + } + + return false; +} + + +void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { + + current_option=p_tool; + + switch(p_tool) { + + case TOOL_NEW: { + /* + if (!_validate_no_foreign()) + break; + */ + create_dialog->popup(true); + } break; + case TOOL_INSTANCE: { + + Node *scene = edited_scene; + + if (!scene) { + + EditorNode::get_singleton()->new_inherited_scene(); + + /* should be legal now + current_option=-1; + //confirmation->get_cancel()->hide(); + accept->get_ok()->set_text("I see.."); + accept->set_text("This operation can't be done without a tree root."); + accept->popup_centered_minsize(); + */ + break; + } + + /* + if (!_validate_no_foreign()) + break; + */ + + file->set_mode(EditorFileDialog::MODE_OPEN_FILE); + List<String> extensions; + ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions); + file->clear_filters(); + for(int i=0;i<extensions.size();i++) { + + file->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); + } + + //file->set_current_path(current_path); + file->popup_centered_ratio(); + + } break; + case TOOL_REPLACE: { + + create_dialog->popup(false); + } break; + case TOOL_CONNECT: { + + Node *current = scene_tree->get_selected(); + if (!current) + break; + + /* + if (!_validate_no_foreign()) + break; + connect_dialog->popup_centered_ratio(); + connect_dialog->set_node(current); + */ + + } break; + case TOOL_GROUP: { + + Node *current = scene_tree->get_selected(); + if (!current) + break; + /* + if (!_validate_no_foreign()) + break; + groups_editor->set_current(current); + groups_editor->popup_centered_ratio(); + */ + } break; + case TOOL_ATTACH_SCRIPT: { + + Node *selected = scene_tree->get_selected(); + if (!selected) + break; + + /* + if (!_validate_no_foreign()) + break; + */ + + Ref<Script> existing = selected->get_script(); + if (existing.is_valid()) + editor->push_item(existing.ptr()); + else { + String path = selected->get_filename(); + script_create_dialog->config(selected->get_class(),path); + script_create_dialog->popup_centered(Size2(300,290)); + //script_create_dialog->popup_centered_minsize(); + + } + + } break; + case TOOL_CLEAR_SCRIPT: { + Node *selected = scene_tree->get_selected(); + if(!selected) + break; + + Ref<Script> existing = selected->get_script(); + if(existing.is_valid()) { + const RefPtr empty; + selected->set_script(empty); + button_create_script->show(); + button_clear_script->hide(); + } + + } break; + case TOOL_MOVE_UP: + case TOOL_MOVE_DOWN: { + + if (!scene_tree->get_selected()) + break; + + + if (scene_tree->get_selected()==edited_scene) { + + + current_option=-1; + //accept->get_cancel()->hide(); + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("This operation can't be done on the tree root.")); + accept->popup_centered_minsize(); + break; + } + + + if (!_validate_no_foreign()) + break; + + bool MOVING_DOWN = (p_tool == TOOL_MOVE_DOWN); + bool MOVING_UP = !MOVING_DOWN; + + Node *common_parent = scene_tree->get_selected()->get_parent(); + List<Node*> selection = editor_selection->get_selected_node_list(); + selection.sort_custom<Node::Comparator>(); // sort by index + if (MOVING_DOWN) + selection.invert(); + + int lowest_id = common_parent->get_child_count() - 1; + int highest_id = 0; + for (List<Node*>::Element *E = selection.front(); E; E = E->next()) { + int index = E->get()->get_index(); + + if (index > highest_id) highest_id = index; + if (index < lowest_id) lowest_id = index; + + if (E->get()->get_parent() != common_parent) + common_parent = NULL; + } + + if (!common_parent || (MOVING_DOWN && highest_id >= common_parent->get_child_count() - MOVING_DOWN) || (MOVING_UP && lowest_id == 0)) + break; // one or more nodes can not be moved + + if (selection.size() == 1) editor_data->get_undo_redo().create_action(TTR("Move Node In Parent")); + if (selection.size() > 1) editor_data->get_undo_redo().create_action(TTR("Move Nodes In Parent")); + + for (int i = 0; i < selection.size(); i++) { + Node *top_node = selection[i]; + Node *bottom_node = selection[selection.size() - 1 - i]; + + ERR_FAIL_COND(!top_node->get_parent()); + ERR_FAIL_COND(!bottom_node->get_parent()); + + int bottom_node_pos = bottom_node->get_index(); + int top_node_pos_next = top_node->get_index() + (MOVING_DOWN ? 1 : -1); + + editor_data->get_undo_redo().add_do_method(top_node->get_parent(), "move_child", top_node, top_node_pos_next); + editor_data->get_undo_redo().add_undo_method(bottom_node->get_parent(), "move_child", bottom_node, bottom_node_pos); + } + + editor_data->get_undo_redo().commit_action(); + + } break; + case TOOL_DUPLICATE: { + + if (!edited_scene) + break; + + + if (editor_selection->is_selected(edited_scene)) { + + + current_option=-1; + //accept->get_cancel()->hide(); + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("This operation can't be done on the tree root.")); + accept->popup_centered_minsize(); + break; + } + + if (!_validate_no_foreign()) + break; + + List<Node*> selection = editor_selection->get_selected_node_list(); + if (selection.size()==0) + break; + + List<Node*> reselect; + + editor_data->get_undo_redo().create_action(TTR("Duplicate Node(s)")); + editor_data->get_undo_redo().add_do_method(editor_selection,"clear"); + + Node *dupsingle=NULL; + + + for (List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Node *node = E->get(); + Node *parent = node->get_parent(); + + List<Node*> owned; + node->get_owned_by(node->get_owner(),&owned); + + Map<Node*,Node*> duplimap; + Node * dup = _duplicate(node,duplimap); + + ERR_CONTINUE(!dup); + + if (selection.size()==1) + dupsingle=dup; + + dup->set_name(parent->validate_child_name(dup)); + + editor_data->get_undo_redo().add_do_method(parent,"_add_child_below_node",node, dup); + for (List<Node*>::Element *F=owned.front();F;F=F->next()) { + + if (!duplimap.has(F->get())) { + + continue; + } + Node *d=duplimap[F->get()]; + editor_data->get_undo_redo().add_do_method(d,"set_owner",node->get_owner()); + } + editor_data->get_undo_redo().add_do_method(editor_selection,"add_node",dup); + editor_data->get_undo_redo().add_undo_method(parent,"remove_child",dup); + editor_data->get_undo_redo().add_do_reference(dup); + + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + + editor_data->get_undo_redo().add_do_method(sed,"live_debug_duplicate_node",edited_scene->get_path_to(node),dup->get_name()); + editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+dup->get_name())); + + //parent->add_child(dup); + //reselect.push_back(dup); + } + + editor_data->get_undo_redo().commit_action(); + + if (dupsingle) + editor->push_item(dupsingle); + + + + + + } break; + case TOOL_REPARENT: { + + + if (!scene_tree->get_selected()) + break; + + + if (editor_selection->is_selected(edited_scene)) { + + + current_option=-1; + //confirmation->get_cancel()->hide(); + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("This operation can't be done on the tree root.")); + accept->popup_centered_minsize(); + break; + } + + if (!_validate_no_foreign()) + break; + + List<Node*> nodes = editor_selection->get_selected_node_list(); + Set<Node*> nodeset; + for(List<Node*>::Element *E=nodes.front();E;E=E->next()) { + + nodeset.insert(E->get()); + } + reparent_dialog->popup_centered_ratio(); + reparent_dialog->set_current( nodeset ); + + } break; + case TOOL_MULTI_EDIT: { + + Node*root=EditorNode::get_singleton()->get_edited_scene(); + if (!root) + break; + Ref<MultiNodeEdit> mne = memnew( MultiNodeEdit ); + for (const Map<Node*,Object*>::Element *E=EditorNode::get_singleton()->get_editor_selection()->get_selection().front();E;E=E->next()) { + mne->add_node(root->get_path_to(E->key())); + } + + EditorNode::get_singleton()->push_item(mne.ptr()); + + } break; + + case TOOL_ERASE: { + + List<Node*> remove_list = editor_selection->get_selected_node_list(); + + if (remove_list.empty()) + return; + + if (!_validate_no_foreign()) + break; + + if (p_confirm_override) { + _delete_confirm(); + + // hack, force 2d editor viewport to refresh after deletion + if (CanvasItemEditor *editor = CanvasItemEditor::get_singleton()) + editor->get_viewport_control()->update(); + + } else { + delete_dialog->set_text(TTR("Delete Node(s)?")); + delete_dialog->popup_centered_minsize(); + } + + } break; + case TOOL_MERGE_FROM_SCENE: { + + EditorNode::get_singleton()->merge_from_scene(); + } break; + case TOOL_NEW_SCENE_FROM: { + + Node *scene = editor_data->get_edited_scene_root(); + + if (!scene) { + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("This operation can't be done without a scene.")); + accept->popup_centered_minsize(); + break; + } + + List<Node*> selection = editor_selection->get_selected_node_list(); + + if (selection.size()!=1) { + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("This operation requires a single selected node.")); + accept->popup_centered_minsize(); + break; + } + + Node *tocopy = selection.front()->get(); + + if (tocopy==scene){ + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("Can not perform with the root node.")); + accept->popup_centered_minsize(); + break; + } + + if (tocopy!=editor_data->get_edited_scene_root() && tocopy->get_filename()!="") { + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("This operation can't be done on instanced scenes.")); + accept->popup_centered_minsize(); + break; + } + + new_scene_from_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE); + + List<String> extensions; + Ref<PackedScene> sd = memnew( PackedScene ); + ResourceSaver::get_recognized_extensions(sd,&extensions); + new_scene_from_dialog->clear_filters(); + for(int i=0;i<extensions.size();i++) { + new_scene_from_dialog->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); + } + + String existing; + if (extensions.size()) { + String root_name(tocopy->get_name()); + existing=root_name+"."+extensions.front()->get().to_lower(); + } + new_scene_from_dialog->set_current_path(existing); + + new_scene_from_dialog->popup_centered_ratio(); + new_scene_from_dialog->set_title(TTR("Save New Scene As..")); + + } break; + case TOOL_COPY_NODE_PATH: { + List<Node*> selection = editor_selection->get_selected_node_list(); + + if(List<Node*>::Element *e = selection.front()) { + if(Node *node = e->get()) { + Node *root = EditorNode::get_singleton()->get_edited_scene(); + NodePath path = root->get_path().rel_path_to(node->get_path()); + OS::get_singleton()->set_clipboard(path); + } + } + } break; + } + +} + +void SceneTreeDock::_notification(int p_what) { + + switch(p_what) { + + case NOTIFICATION_READY: { + + if (!first_enter) + break; + first_enter=false; + + CanvasItemEditorPlugin *canvas_item_plugin = editor_data->get_editor("2D")->cast_to<CanvasItemEditorPlugin>(); + if (canvas_item_plugin) { + canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree"); + canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", scene_tree, "_update_tree"); + scene_tree->connect("node_changed", canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), "update"); + } + button_add->set_icon(get_icon("Add","EditorIcons")); + button_instance->set_icon(get_icon("Instance","EditorIcons")); + button_create_script->set_icon(get_icon("ScriptCreate","EditorIcons")); + button_clear_script->set_icon(get_icon("ScriptRemove", "EditorIcons")); + + + filter_icon->set_texture(get_icon("Zoom","EditorIcons")); + + EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed",this,"_selection_changed"); + + } break; + } +} + + +void SceneTreeDock::_load_request(const String& p_path) { + + editor->open_request(p_path); +} + +void SceneTreeDock::_script_open_request(const Ref<Script>& p_script) { + + editor->edit_resource(p_script); +} + +void SceneTreeDock::_node_selected() { + + + Node *node=scene_tree->get_selected(); + + if (!node) { + + editor->push_item(NULL); + return; + } + + if (ScriptEditor::get_singleton()->is_visible_in_tree()) { + restore_script_editor_on_drag=true; + } + + editor->push_item(node); + + +} + +void SceneTreeDock::_node_renamed() { + + _node_selected(); +} + +Node *SceneTreeDock::_duplicate(Node *p_node, Map<Node*,Node*> &duplimap) { + + Node *node=NULL; + + if (p_node->get_filename()!="") { //an instance + + Ref<PackedScene> sd = ResourceLoader::load( p_node->get_filename() ); + ERR_FAIL_COND_V(!sd.is_valid(),NULL); + node = sd->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); + ERR_FAIL_COND_V(!node,NULL); + node->set_scene_instance_load_placeholder(p_node->get_scene_instance_load_placeholder()); + //node->generate_instance_state(); + } else { + Object *obj = ClassDB::instance(p_node->get_class()); + ERR_FAIL_COND_V(!obj,NULL); + node = obj->cast_to<Node>(); + if (!node) + memdelete(obj); + ERR_FAIL_COND_V(!node,NULL); + + } + + List<PropertyInfo> plist; + + p_node->get_property_list(&plist); + + for(List<PropertyInfo>::Element *E=plist.front();E;E=E->next()) { + + if (!(E->get().usage&PROPERTY_USAGE_STORAGE)) + continue; + String name = E->get().name; + node->set( name, p_node->get(name) ); + + } + + + List<Node::GroupInfo> group_info; + p_node->get_groups(&group_info); + for (List<Node::GroupInfo>::Element *E=group_info.front();E;E=E->next()) { + + if (E->get().persistent) + node->add_to_group(E->get().name,true); + } + + + node->set_name(p_node->get_name()); + duplimap[p_node]=node; + + for(int i=0;i<p_node->get_child_count();i++) { + + Node *child = p_node->get_child(i); + if (p_node->get_owner()!=child->get_owner()) + continue; //don't bother with not in-scene nodes. + + Node *dup = _duplicate(child,duplimap); + if (!dup) { + memdelete(node); + return NULL; + } + + node->add_child(dup); + } + + return node; + +} + + +void SceneTreeDock::_set_owners(Node *p_owner, const Array& p_nodes) { + + for(int i=0;i<p_nodes.size();i++) { + + Object *obj=p_nodes[i]; + if (!obj) + continue; + + Node *n=obj->cast_to<Node>(); + if (!n) + continue; + n->set_owner(p_owner); + } +} + + +void SceneTreeDock::_fill_path_renames(Vector<StringName> base_path,Vector<StringName> new_base_path,Node * p_node, List<Pair<NodePath,NodePath> > *p_renames) { + + base_path.push_back(p_node->get_name()); + if (new_base_path.size()) + new_base_path.push_back(p_node->get_name()); + + NodePath from( base_path,true ); + NodePath to; + if (new_base_path.size()) + to=NodePath( new_base_path,true ); + + Pair<NodePath,NodePath> npp; + npp.first=from; + npp.second=to; + + p_renames->push_back(npp); + + for(int i=0;i<p_node->get_child_count();i++) { + + _fill_path_renames(base_path,new_base_path,p_node->get_child(i),p_renames); + } + + +} + +void SceneTreeDock::fill_path_renames(Node* p_node, Node *p_new_parent, List<Pair<NodePath,NodePath> > *p_renames) { + + if (!bool(EDITOR_DEF("editors/animation/autorename_animation_tracks",true))) + return; + + + Vector<StringName> base_path; + Node *n = p_node->get_parent(); + while(n) { + base_path.push_back(n->get_name()); + n=n->get_parent(); + } + base_path.invert(); + + Vector<StringName> new_base_path; + if (p_new_parent) { + n = p_new_parent; + while(n) { + new_base_path.push_back(n->get_name()); + n=n->get_parent(); + } + + new_base_path.invert(); + } + + _fill_path_renames(base_path,new_base_path,p_node,p_renames); +} + +void SceneTreeDock::perform_node_renames(Node* p_base,List<Pair<NodePath,NodePath> > *p_renames, Map<Ref<Animation>, Set<int> > *r_rem_anims) { + + Map<Ref<Animation>, Set<int> > rem_anims; + + if (!r_rem_anims) + r_rem_anims=&rem_anims; + + if (!bool(EDITOR_DEF("editors/animation/autorename_animation_tracks",true))) + return; + + if (!p_base) { + + p_base=edited_scene; + } + + if (!p_base) + return; + + + if (p_base->cast_to<AnimationPlayer>()) { + + AnimationPlayer *ap=p_base->cast_to<AnimationPlayer>(); + List<StringName> anims; + ap->get_animation_list(&anims); + Node *root = ap->get_node(ap->get_root()); + + + if (root) { + + + NodePath root_path=root->get_path(); + NodePath new_root_path=root_path; + + + for(List<Pair<NodePath,NodePath> >::Element* E=p_renames->front();E;E=E->next()) { + + if (E->get().first==root_path) { + new_root_path=E->get().second; + break; + } + } + + if (new_root_path!=NodePath()) { + //will not be erased + + for(List<StringName>::Element *E=anims.front();E;E=E->next()) { + + Ref<Animation> anim=ap->get_animation(E->get()); + if (!r_rem_anims->has(anim)) { + r_rem_anims->insert(anim,Set<int>()); + Set<int> &ran = r_rem_anims->find(anim)->get(); + for(int i=0;i<anim->get_track_count();i++) + ran.insert(i); + } + + Set<int> &ran = r_rem_anims->find(anim)->get(); + + if (anim.is_null()) + continue; + + for(int i=0;i<anim->get_track_count();i++) { + + NodePath track_np=anim->track_get_path(i); + Node *n = root->get_node(track_np); + if (!n) { + continue; + } + + NodePath old_np = n->get_path(); + + if (!ran.has(i)) + continue; //channel was removed + + for(List<Pair<NodePath,NodePath> >::Element* E=p_renames->front();E;E=E->next()) { + + if (E->get().first==old_np) { + + + if (E->get().second==NodePath()) { + //will be erased + + int idx=0; + Set<int>::Element *EI=ran.front(); + ERR_FAIL_COND(!EI); //bug + while(EI->get()!=i) { + idx++; + EI=EI->next(); + ERR_FAIL_COND(!EI); //another bug + + } + + editor_data->get_undo_redo().add_do_method(anim.ptr(),"remove_track",idx); + editor_data->get_undo_redo().add_undo_method(anim.ptr(),"add_track",anim->track_get_type(i),idx); + editor_data->get_undo_redo().add_undo_method(anim.ptr(),"track_set_path",idx,track_np); + editor_data->get_undo_redo().add_undo_method(anim.ptr(),"track_set_interpolation_type",idx,anim->track_get_interpolation_type(i)); + for(int j=0;j<anim->track_get_key_count(i);j++) { + + editor_data->get_undo_redo().add_undo_method(anim.ptr(),"track_insert_key",idx,anim->track_get_key_time(i,j),anim->track_get_key_value(i,j),anim->track_get_key_transition(i,j)); + } + + ran.erase(i); //byebye channel + + } else { + //will be renamed + NodePath rel_path = new_root_path.rel_path_to(E->get().second); + + NodePath new_path = NodePath( rel_path.get_names(), track_np.get_subnames(), false, track_np.get_property() ); + if (new_path==track_np) + continue; //bleh + editor_data->get_undo_redo().add_do_method(anim.ptr(),"track_set_path",i,new_path); + editor_data->get_undo_redo().add_undo_method(anim.ptr(),"track_set_path",i,track_np); + } + } + } + } + } + } + } + } + + + for(int i=0;i<p_base->get_child_count();i++) + perform_node_renames(p_base->get_child(i),p_renames,r_rem_anims); + +} + + +void SceneTreeDock::_node_prerenamed(Node* p_node, const String& p_new_name) { + + + List<Pair<NodePath,NodePath> > path_renames; + + Vector<StringName> base_path; + Node *n = p_node->get_parent(); + while(n) { + base_path.push_back(n->get_name()); + n=n->get_parent(); + } + base_path.invert(); + + + Vector<StringName> new_base_path=base_path; + base_path.push_back(p_node->get_name()); + + new_base_path.push_back(p_new_name); + + Pair<NodePath,NodePath> npp; + npp.first = NodePath(base_path,true); + npp.second = NodePath(new_base_path,true); + path_renames.push_back(npp); + + + for(int i=0;i<p_node->get_child_count();i++) + _fill_path_renames(base_path,new_base_path,p_node->get_child(i),&path_renames); + + perform_node_renames(NULL,&path_renames); + +} + +bool SceneTreeDock::_validate_no_foreign() { + + List<Node*> selection = editor_selection->get_selected_node_list(); + + for (List<Node*>::Element *E=selection.front();E;E=E->next()) { + + if (E->get()!=edited_scene && E->get()->get_owner()!=edited_scene) { + + accept->get_ok()->set_text(TTR("Makes Sense!")); + accept->set_text(TTR("Can't operate on nodes from a foreign scene!")); + accept->popup_centered_minsize(); + return false; + + } + + if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E->get()))>=0) { + + accept->get_ok()->set_text(TTR("Makes Sense!")); + accept->set_text(TTR("Can't operate on nodes the current scene inherits from!")); + accept->popup_centered_minsize(); + return false; + + } + + } + + return true; +} + +void SceneTreeDock::_node_reparent(NodePath p_path,bool p_keep_global_xform) { + + + Node *new_parent = scene_root->get_node(p_path); + ERR_FAIL_COND(!new_parent); + + //ok all valid + + List<Node*> selection = editor_selection->get_selected_node_list(); + + if (selection.empty()) + return; //nothing to reparent + + Vector<Node*> nodes; + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + nodes.push_back(E->get()); + } + + _do_reparent(new_parent,-1,nodes,p_keep_global_xform); + +} + + +void SceneTreeDock::_do_reparent(Node* p_new_parent,int p_position_in_parent,Vector<Node*> p_nodes,bool p_keep_global_xform) { + + + Node *new_parent = p_new_parent; + ERR_FAIL_COND(!new_parent); + + Node *validate=new_parent; + while(validate) { + + if (p_nodes.find(validate)!=-1) { + ERR_EXPLAIN("Selection changed at some point.. can't reparent"); + ERR_FAIL(); + return; + } + validate=validate->get_parent(); + } + + //ok all valid + + List<Node*> selection = editor_selection->get_selected_node_list(); + + if (p_nodes.size()==0) + return; //nothing to reparent + + //sort by tree order, so re-adding is easy + p_nodes.sort_custom<Node::Comparator>(); + + editor_data->get_undo_redo().create_action(TTR("Reparent Node")); + + List<Pair<NodePath,NodePath> > path_renames; + Vector<StringName> former_names; + + int inc=0; + + for(int ni=0;ni<p_nodes.size();ni++) { + + //no undo for now, sorry + Node *node = p_nodes[ni]; + + fill_path_renames(node,new_parent,&path_renames); + former_names.push_back(node->get_name()); + + List<Node*> owned; + node->get_owned_by(node->get_owner(),&owned); + Array owners; + for(List<Node*>::Element *E=owned.front();E;E=E->next()) { + + owners.push_back(E->get()); + } + + + if (new_parent==node->get_parent() && node->get_index() < p_position_in_parent+ni) { + //if child will generate a gap when moved, adjust + inc--; + } + + editor_data->get_undo_redo().add_do_method(node->get_parent(),"remove_child",node); + editor_data->get_undo_redo().add_do_method(new_parent,"add_child",node); + + if (p_position_in_parent>=0) + editor_data->get_undo_redo().add_do_method(new_parent,"move_child",node,p_position_in_parent+inc); + + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + String new_name = new_parent->validate_child_name(node); + editor_data->get_undo_redo().add_do_method(sed,"live_debug_reparent_node",edited_scene->get_path_to(node),edited_scene->get_path_to(new_parent),new_name,-1); + editor_data->get_undo_redo().add_undo_method(sed,"live_debug_reparent_node",NodePath(String(edited_scene->get_path_to(new_parent))+"/"+new_name),edited_scene->get_path_to(node->get_parent()),node->get_name(),node->get_index()); + + if (p_keep_global_xform) { + if (node->cast_to<Node2D>()) + editor_data->get_undo_redo().add_do_method(node,"set_global_transform",node->cast_to<Node2D>()->get_global_transform()); + if (node->cast_to<Spatial>()) + editor_data->get_undo_redo().add_do_method(node,"set_global_transform",node->cast_to<Spatial>()->get_global_transform()); + if (node->cast_to<Control>()) + editor_data->get_undo_redo().add_do_method(node,"set_global_pos",node->cast_to<Control>()->get_global_pos()); + } + + editor_data->get_undo_redo().add_do_method(this,"_set_owners",edited_scene,owners); + + if (AnimationPlayerEditor::singleton->get_key_editor()->get_root()==node) + editor_data->get_undo_redo().add_do_method(AnimationPlayerEditor::singleton->get_key_editor(),"set_root",node); + + editor_data->get_undo_redo().add_undo_method(new_parent,"remove_child",node); + editor_data->get_undo_redo().add_undo_method(node,"set_name",former_names[ni]); + + inc++; + + } + + //add and move in a second step.. (so old order is preserved) + + + + for(int ni=0;ni<p_nodes.size();ni++) { + + Node *node = p_nodes[ni]; + + List<Node*> owned; + node->get_owned_by(node->get_owner(),&owned); + Array owners; + for(List<Node*>::Element *E=owned.front();E;E=E->next()) { + + owners.push_back(E->get()); + } + + int child_pos = node->get_position_in_parent(); + + editor_data->get_undo_redo().add_undo_method(node->get_parent(),"add_child",node); + editor_data->get_undo_redo().add_undo_method(node->get_parent(),"move_child",node,child_pos); + editor_data->get_undo_redo().add_undo_method(this,"_set_owners",edited_scene,owners); + if (AnimationPlayerEditor::singleton->get_key_editor()->get_root()==node) + editor_data->get_undo_redo().add_undo_method(AnimationPlayerEditor::singleton->get_key_editor(),"set_root",node); + + if (p_keep_global_xform) { + if (node->cast_to<Node2D>()) + editor_data->get_undo_redo().add_undo_method(node,"set_transform",node->cast_to<Node2D>()->get_transform()); + if (node->cast_to<Spatial>()) + editor_data->get_undo_redo().add_undo_method(node,"set_transform",node->cast_to<Spatial>()->get_transform()); + if (node->cast_to<Control>()) + editor_data->get_undo_redo().add_undo_method(node,"set_pos",node->cast_to<Control>()->get_pos()); + } + + + + } + + perform_node_renames(NULL,&path_renames); + + editor_data->get_undo_redo().commit_action(); + //node->set_owner(owner); +} + +void SceneTreeDock::_script_created(Ref<Script> p_script) { + + Node *selected = scene_tree->get_selected(); + if (!selected) + return; + selected->set_script(p_script.get_ref_ptr()); + editor->push_item(p_script.operator->()); + button_create_script->hide(); + button_clear_script->show(); + +} + + +void SceneTreeDock::_delete_confirm() { + + List<Node*> remove_list = editor_selection->get_selected_node_list(); + + if (remove_list.empty()) + return; + + + editor->get_editor_plugins_over()->make_visible(false); + + editor_data->get_undo_redo().create_action(TTR("Remove Node(s)")); + + bool entire_scene=false; + + for(List<Node*>::Element *E=remove_list.front();E;E=E->next()) { + + if (E->get()==edited_scene) { + entire_scene=true; + } + } + + if (entire_scene) { + + editor_data->get_undo_redo().add_do_method(editor,"set_edited_scene",(Object*)NULL); + editor_data->get_undo_redo().add_undo_method(editor,"set_edited_scene",edited_scene); + editor_data->get_undo_redo().add_undo_method(edited_scene,"set_owner",edited_scene->get_owner()); + editor_data->get_undo_redo().add_undo_reference(edited_scene); + + } else { + + remove_list.sort_custom<Node::Comparator>(); //sort nodes to keep positions + List<Pair<NodePath,NodePath> > path_renames; + + + //delete from animation + for(List<Node*>::Element *E=remove_list.front();E;E=E->next()) { + Node *n = E->get(); + if (!n->is_inside_tree() || !n->get_parent()) + continue; + + fill_path_renames(n,NULL,&path_renames); + + } + + perform_node_renames(NULL,&path_renames); + //delete for read + for(List<Node*>::Element *E=remove_list.front();E;E=E->next()) { + Node *n = E->get(); + if (!n->is_inside_tree() || !n->get_parent()) + continue; + + List<Node*> owned; + n->get_owned_by(n->get_owner(),&owned); + Array owners; + for(List<Node*>::Element *E=owned.front();E;E=E->next()) { + + owners.push_back(E->get()); + } + + + editor_data->get_undo_redo().add_do_method(n->get_parent(),"remove_child",n); + editor_data->get_undo_redo().add_undo_method(n->get_parent(),"add_child",n); + editor_data->get_undo_redo().add_undo_method(n->get_parent(),"move_child",n,n->get_index()); + if (AnimationPlayerEditor::singleton->get_key_editor()->get_root()==n) + editor_data->get_undo_redo().add_undo_method(AnimationPlayerEditor::singleton->get_key_editor(),"set_root",n); + editor_data->get_undo_redo().add_undo_method(this,"_set_owners",edited_scene,owners); + //editor_data->get_undo_redo().add_undo_method(n,"set_owner",n->get_owner()); + editor_data->get_undo_redo().add_undo_reference(n); + + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + editor_data->get_undo_redo().add_do_method(sed,"live_debug_remove_and_keep_node",edited_scene->get_path_to(n),n->get_instance_ID()); + editor_data->get_undo_redo().add_undo_method(sed,"live_debug_restore_node",n->get_instance_ID(),edited_scene->get_path_to(n->get_parent()),n->get_index()); + + } + + + } + editor_data->get_undo_redo().commit_action(); + + +} + + + + +void SceneTreeDock::_selection_changed() { + + int selection_size = EditorNode::get_singleton()->get_editor_selection()->get_selection().size(); + if (selection_size>1) { + //automatically turn on multi-edit + _tool_selected(TOOL_MULTI_EDIT); + } + + if (selection_size==1) { + if(EditorNode::get_singleton()->get_editor_selection()->get_selection().front()->key()->get_script().is_null()) { + button_create_script->show(); + button_clear_script->hide(); + } + else { + button_create_script->hide(); + button_clear_script->show(); + } + } else { + button_create_script->hide(); + button_clear_script->hide(); + } + + //tool_buttons[TOOL_MULTI_EDIT]->set_disabled(EditorNode::get_singleton()->get_editor_selection()->get_selection().size()<2); + +} + + +void SceneTreeDock::_create() { + + + if (current_option==TOOL_NEW) { + + Node *parent=NULL; + + + if (edited_scene) { + // If root exists in edited scene + parent = scene_tree->get_selected(); + if( !parent ) + parent = edited_scene; + + } else { + // If no root exist in edited scene + parent = scene_root; + ERR_FAIL_COND(!parent); + } + + Object *c = create_dialog->instance_selected(); + + ERR_FAIL_COND(!c); + Node *child=c->cast_to<Node>(); + ERR_FAIL_COND(!child); + + editor_data->get_undo_redo().create_action(TTR("Create Node")); + + if (edited_scene) { + + editor_data->get_undo_redo().add_do_method(parent,"add_child",child); + editor_data->get_undo_redo().add_do_method(child,"set_owner",edited_scene); + editor_data->get_undo_redo().add_do_method(editor_selection,"clear"); + editor_data->get_undo_redo().add_do_method(editor_selection,"add_node",child); + editor_data->get_undo_redo().add_do_reference(child); + editor_data->get_undo_redo().add_undo_method(parent,"remove_child",child); + + + String new_name = parent->validate_child_name(child); + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + editor_data->get_undo_redo().add_do_method(sed,"live_debug_create_node",edited_scene->get_path_to(parent),child->get_class(),new_name); + editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+new_name)); + + } else { + + editor_data->get_undo_redo().add_do_method(editor,"set_edited_scene",child); + editor_data->get_undo_redo().add_do_reference(child); + editor_data->get_undo_redo().add_undo_method(editor,"set_edited_scene",(Object*)NULL); + + } + + editor_data->get_undo_redo().commit_action(); + editor->push_item(c); + + if (c->cast_to<Control>()) { + //make editor more comfortable, so some controls don't appear super shrunk + Control *ct = c->cast_to<Control>(); + + Size2 ms = ct->get_minimum_size(); + if (ms.width<4) + ms.width=40; + if (ms.height<4) + ms.height=40; + ct->set_size(ms); + } + + + } else if (current_option==TOOL_REPLACE) { + Node * n = scene_tree->get_selected(); + ERR_FAIL_COND(!n); + + Object *c = create_dialog->instance_selected(); + + ERR_FAIL_COND(!c); + Node *newnode=c->cast_to<Node>(); + ERR_FAIL_COND(!newnode); + + List<PropertyInfo> pinfo; + n->get_property_list(&pinfo); + + for(List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) { + if (!(E->get().usage&PROPERTY_USAGE_STORAGE)) + continue; + newnode->set(E->get().name,n->get(E->get().name)); + } + + editor->push_item(NULL); + + //reconnect signals + List<MethodInfo> sl; + + n->get_signal_list(&sl); + for (List<MethodInfo>::Element *E=sl.front();E;E=E->next()) { + + List<Object::Connection> cl; + n->get_signal_connection_list(E->get().name,&cl); + + for(List<Object::Connection>::Element *F=cl.front();F;F=F->next()) { + + Object::Connection &c=F->get(); + if (!(c.flags&Object::CONNECT_PERSIST)) + continue; + newnode->connect(c.signal,c.target,c.method,varray(),Object::CONNECT_PERSIST); + } + + } + + String newname=n->get_name(); + + List<Node*> to_erase; + for(int i=0;i<n->get_child_count();i++) { + if (n->get_child(i)->get_owner()==NULL && n->is_owned_by_parent()) { + to_erase.push_back(n->get_child(i)); + } + } + n->replace_by(newnode,true); + + if (n==edited_scene) { + edited_scene=newnode; + editor->set_edited_scene(newnode); + newnode->set_editable_instances(n->get_editable_instances()); + } + + //small hack to make collisionshapes and other kind of nodes to work + for(int i=0;i<newnode->get_child_count();i++) { + Node *c=newnode->get_child(i); + c->call("set_transform", c->call("get_transform") ); + } + editor_data->get_undo_redo().clear_history(); + newnode->set_name(newname); + + editor->push_item(newnode); + + memdelete(n); + + while(to_erase.front()) { + memdelete(to_erase.front()->get()); + to_erase.pop_front(); + } + + + + } + +} + + +void SceneTreeDock::set_edited_scene(Node* p_scene) { + + edited_scene=p_scene; +} + +void SceneTreeDock::set_selected(Node *p_node, bool p_emit_selected ) { + + scene_tree->set_selected(p_node,p_emit_selected); + +} + +void SceneTreeDock::import_subscene() { + + import_subscene_dialog->popup_centered_ratio(); +} + +void SceneTreeDock::_import_subscene() { + + Node* parent = scene_tree->get_selected(); + if (!parent) { + parent = editor_data->get_edited_scene_root(); + ERR_FAIL_COND(!parent); + } + + import_subscene_dialog->move(parent,edited_scene); + editor_data->get_undo_redo().clear_history(); //no undo for now.. + + +/* + editor_data->get_undo_redo().create_action("Import Subscene"); + editor_data->get_undo_redo().add_do_method(parent,"add_child",ss); + //editor_data->get_undo_redo().add_do_method(editor_selection,"clear"); + //editor_data->get_undo_redo().add_do_method(editor_selection,"add_node",child); + editor_data->get_undo_redo().add_do_reference(ss); + editor_data->get_undo_redo().add_undo_method(parent,"remove_child",ss); + editor_data->get_undo_redo().commit_action(); +*/ +} + +void SceneTreeDock::_new_scene_from(String p_file) { + + List<Node*> selection = editor_selection->get_selected_node_list(); + + if (selection.size()!=1) { + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("This operation requires a single selected node.")); + accept->popup_centered_minsize(); + return; + } + + Node *base = selection.front()->get(); + + Map<Node*,Node*> reown; + reown[editor_data->get_edited_scene_root()]=base; + Node *copy = base->duplicate_and_reown(reown); + if (copy) { + + Ref<PackedScene> sdata = memnew( PackedScene ); + Error err = sdata->pack(copy); + memdelete(copy); + + if (err!=OK) { + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("Couldn't save new scene. Likely dependencies (instances) couldn't be satisfied.")); + accept->popup_centered_minsize(); + return; + } + + int flg=0; + if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) + flg|=ResourceSaver::FLAG_COMPRESS; + /* + if (EditorSettings::get_singleton()->get("filesystem/on_save/save_paths_as_relative")) + flg|=ResourceSaver::FLAG_RELATIVE_PATHS; + */ + + + err = ResourceSaver::save(p_file,sdata,flg); + if (err!=OK) { + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("Error saving scene.")); + accept->popup_centered_minsize(); + return; + } + _replace_with_branch_scene(p_file, base); + } else { + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("Error duplicating scene to save it.")); + accept->popup_centered_minsize(); + return; + } + +} + +static bool _is_node_visible(Node* p_node) { + + if (!p_node->get_owner()) + return false; + if (p_node->get_owner()!=EditorNode::get_singleton()->get_edited_scene() && !EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node->get_owner())) + return false; + + return true; + +} + +static bool _has_visible_children(Node* p_node) { + + bool collapsed = p_node->is_displayed_folded(); + if (collapsed) + return false; + + for(int i=0;i<p_node->get_child_count();i++) { + + Node* child = p_node->get_child(i); + if (!_is_node_visible(child)) + continue; + + return true; + } + + return false; + +} + + + +static Node* _find_last_visible(Node* p_node) { + + Node* last=NULL; + + bool collapsed = p_node->is_displayed_folded(); + + if (!collapsed) { + for(int i=0;i<p_node->get_child_count();i++) { + if (_is_node_visible(p_node->get_child(i))) { + last=p_node->get_child(i); + } + } + } + + if (last) { + Node* lastc=_find_last_visible(last); + if (lastc) + last=lastc; + + + } else { + last=p_node; + } + + return last; +} + + +void SceneTreeDock::_normalize_drop(Node*& to_node, int &to_pos, int p_type) { + + to_pos=-1; + + if (p_type==-1) { + //drop at above selected node + if (to_node==EditorNode::get_singleton()->get_edited_scene()) { + to_node=NULL; + ERR_EXPLAIN("Cannot perform drop above the root node!"); + ERR_FAIL(); + } + + to_pos=to_node->get_index(); + to_node=to_node->get_parent(); + + } else if (p_type==1) { + //drop at below selected node + if (to_node==EditorNode::get_singleton()->get_edited_scene()) { + //if at lower sibling of root node + to_pos=0; //just insert at begining of root node + return; + } + + + Node* lower_sibling=NULL; + + + + if (_has_visible_children(to_node) ) { + to_pos=0; + } else { + + + for(int i=to_node->get_index()+1;i<to_node->get_parent()->get_child_count();i++) { + Node *c =to_node->get_parent()->get_child(i); + if (_is_node_visible(c)) { + lower_sibling=c; + break; + } + } + if (lower_sibling) { + to_pos=lower_sibling->get_index(); + } + + to_node=to_node->get_parent(); + + + } +#if 0 + //quite complicated, look for next visible in tree + upper_sibling=_find_last_visible(upper_sibling); + + if (upper_sibling->get_parent()==to_node->get_parent()) { + //just insert over this node because nothing is above at an upper level + to_pos=to_node->get_index(); + to_node=to_node->get_parent(); + } else { + to_pos=-1; //insert last in whathever is up + to_node=upper_sibling->get_parent(); //insert at a parent of whathever is up + } + + + } else { + //just insert over this node because nothing is above at the same level + to_pos=to_node->get_index(); + to_node=to_node->get_parent(); + } +#endif + + } + +} + +void SceneTreeDock::_files_dropped(Vector<String> p_files,NodePath p_to,int p_type) { + + Node *node = get_node(p_to); + ERR_FAIL_COND(!node); + + int to_pos=-1; + _normalize_drop(node,to_pos,p_type); + _perform_instance_scenes(p_files,node,to_pos); +} + +void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) { + Ref<Script> scr = ResourceLoader::load(p_file); + ERR_FAIL_COND(!scr.is_valid()); + Node *n = get_node(p_to); + if (n) { + n->set_script(scr.get_ref_ptr()); + } +} + +void SceneTreeDock::_nodes_dragged(Array p_nodes,NodePath p_to,int p_type) { + + Vector<Node*> nodes; + Node *to_node; + + for(int i=0;i<p_nodes.size();i++) { + Node *n=get_node((p_nodes[i])); + if (n) { + nodes.push_back(n); + } + } + + if (nodes.size()==0) + return; + + to_node=get_node(p_to); + if (!to_node) + return; + + int to_pos=-1; + + _normalize_drop(to_node,to_pos,p_type); + _do_reparent(to_node,to_pos,nodes,true); + +} + +void SceneTreeDock::_tree_rmb(const Vector2& p_menu_pos) { + if (!EditorNode::get_singleton()->get_edited_scene()) { + + menu->clear(); + menu->add_icon_shortcut(get_icon("Add","EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW); + menu->add_icon_shortcut(get_icon("Instance","EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE); + + menu->set_size(Size2(1,1)); + menu->set_pos(p_menu_pos); + menu->popup(); + return; + } + + List<Node*> selection = editor_selection->get_selected_node_list(); + + if (selection.size()==0) + return; + + menu->clear(); + + + if (selection.size()==1) { + menu->add_icon_shortcut(get_icon("Add","EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW); + menu->add_icon_shortcut(get_icon("Instance","EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE); + menu->add_separator(); + menu->add_icon_shortcut(get_icon("Reload","EditorIcons"),ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE); + //menu->add_separator(); moved to their own dock + //menu->add_icon_item(get_icon("Groups","EditorIcons"),TTR("Edit Groups"),TOOL_GROUP); + //menu->add_icon_item(get_icon("Connect","EditorIcons"),TTR("Edit Connections"),TOOL_CONNECT); + menu->add_separator(); + menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT); + menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT); + menu->add_separator(); + } + + menu->add_icon_shortcut(get_icon("Up","EditorIcons"),ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP); + menu->add_icon_shortcut(get_icon("Down","EditorIcons"),ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN); + menu->add_icon_shortcut(get_icon("Duplicate","EditorIcons"),ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE); + menu->add_icon_shortcut(get_icon("Reparent","EditorIcons"),ED_GET_SHORTCUT("scene_tree/reparent"), TOOL_REPARENT); + + if (selection.size()==1) { + menu->add_separator(); + menu->add_icon_shortcut(get_icon("Blend","EditorIcons"),ED_GET_SHORTCUT("scene_tree/merge_from_scene"), TOOL_MERGE_FROM_SCENE); + menu->add_icon_shortcut(get_icon("CreateNewSceneFrom","EditorIcons"),ED_GET_SHORTCUT("scene_tree/save_branch_as_scene"), TOOL_NEW_SCENE_FROM); + menu->add_separator(); + menu->add_icon_shortcut(get_icon("CopyNodePath","EditorIcons"), ED_GET_SHORTCUT("scene_tree/copy_node_path"), TOOL_COPY_NODE_PATH); + } + menu->add_separator(); + menu->add_icon_shortcut(get_icon("Remove","EditorIcons"), ED_SHORTCUT("scene_tree/delete", TTR("Delete Node(s)"), KEY_DELETE), TOOL_ERASE); + menu->set_size(Size2(1,1)); + menu->set_pos(p_menu_pos); + menu->popup(); + +} + + +void SceneTreeDock::_filter_changed(const String& p_filter) { + + scene_tree->set_filter(p_filter); +} + +String SceneTreeDock::get_filter() { + + return filter->get_text(); +} + +void SceneTreeDock::set_filter(const String& p_filter){ + + filter->set_text(p_filter); + scene_tree->set_filter(p_filter); +} + + +void SceneTreeDock::_focus_node() { + + Node *node = scene_tree->get_selected(); + ERR_FAIL_COND(!node); + + if (node->is_class("CanvasItem")) { + CanvasItemEditorPlugin *editor = editor_data->get_editor("2D")->cast_to<CanvasItemEditorPlugin>(); + editor->get_canvas_item_editor()->focus_selection(); + } else { + SpatialEditorPlugin *editor = editor_data->get_editor("3D")->cast_to<SpatialEditorPlugin>(); + editor->get_spatial_editor()->get_editor_viewport(0)->focus_selection(); + } +} + +void SceneTreeDock::open_script_dialog(Node* p_for_node) { + + scene_tree->set_selected(p_for_node,false); + _tool_selected(TOOL_ATTACH_SCRIPT); +} + +void SceneTreeDock::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_tool_selected"),&SceneTreeDock::_tool_selected,DEFVAL(false)); + ClassDB::bind_method(D_METHOD("_create"),&SceneTreeDock::_create); + //ClassDB::bind_method(D_METHOD("_script_created"),&SceneTreeDock::_script_created); + ClassDB::bind_method(D_METHOD("_node_reparent"),&SceneTreeDock::_node_reparent); + ClassDB::bind_method(D_METHOD("_set_owners"),&SceneTreeDock::_set_owners); + ClassDB::bind_method(D_METHOD("_node_selected"),&SceneTreeDock::_node_selected); + ClassDB::bind_method(D_METHOD("_node_renamed"),&SceneTreeDock::_node_renamed); + ClassDB::bind_method(D_METHOD("_script_created"),&SceneTreeDock::_script_created); + ClassDB::bind_method(D_METHOD("_load_request"),&SceneTreeDock::_load_request); + ClassDB::bind_method(D_METHOD("_script_open_request"),&SceneTreeDock::_script_open_request); + ClassDB::bind_method(D_METHOD("_unhandled_key_input"),&SceneTreeDock::_unhandled_key_input); + ClassDB::bind_method(D_METHOD("_input"),&SceneTreeDock::_input); + ClassDB::bind_method(D_METHOD("_nodes_drag_begin"),&SceneTreeDock::_nodes_drag_begin); + ClassDB::bind_method(D_METHOD("_delete_confirm"),&SceneTreeDock::_delete_confirm); + ClassDB::bind_method(D_METHOD("_node_prerenamed"),&SceneTreeDock::_node_prerenamed); + ClassDB::bind_method(D_METHOD("_import_subscene"),&SceneTreeDock::_import_subscene); + ClassDB::bind_method(D_METHOD("_selection_changed"),&SceneTreeDock::_selection_changed); + ClassDB::bind_method(D_METHOD("_new_scene_from"),&SceneTreeDock::_new_scene_from); + ClassDB::bind_method(D_METHOD("_nodes_dragged"),&SceneTreeDock::_nodes_dragged); + ClassDB::bind_method(D_METHOD("_files_dropped"),&SceneTreeDock::_files_dropped); + ClassDB::bind_method(D_METHOD("_script_dropped"),&SceneTreeDock::_script_dropped); + ClassDB::bind_method(D_METHOD("_tree_rmb"),&SceneTreeDock::_tree_rmb); + ClassDB::bind_method(D_METHOD("_filter_changed"),&SceneTreeDock::_filter_changed); + ClassDB::bind_method(D_METHOD("_focus_node"),&SceneTreeDock::_focus_node); + + + ClassDB::bind_method(D_METHOD("instance"),&SceneTreeDock::instance); +} + + + +SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelection *p_editor_selection,EditorData &p_editor_data) { + + editor=p_editor; + edited_scene=NULL; + editor_data=&p_editor_data; + editor_selection=p_editor_selection; + scene_root=p_scene_root; + + VBoxContainer *vbc = this; + + HBoxContainer *filter_hbc = memnew( HBoxContainer ); + ToolButton *tb; + + ED_SHORTCUT("scene_tree/add_child_node",TTR("Add Child Node"), KEY_MASK_CMD|KEY_A); + ED_SHORTCUT("scene_tree/instance_scene",TTR("Instance Child Scene")); + ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type")); + ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script")); + ED_SHORTCUT("scene_tree/clear_script", TTR("Clear Script")); + ED_SHORTCUT("scene_tree/move_up", TTR("Move Up"), KEY_MASK_CMD | KEY_UP); + ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KEY_MASK_CMD | KEY_DOWN); + ED_SHORTCUT("scene_tree/duplicate", TTR("Duplicate"),KEY_MASK_CMD | KEY_D); + ED_SHORTCUT("scene_tree/reparent", TTR("Reparent")); + ED_SHORTCUT("scene_tree/merge_from_scene", TTR("Merge From Scene")); + ED_SHORTCUT("scene_tree/save_branch_as_scene", TTR("Save Branch as Scene")); + ED_SHORTCUT("scene_tree/copy_node_path", TTR("Copy Node Path"), KEY_MASK_CMD|KEY_C); + ED_SHORTCUT("scene_tree/delete_no_confirm", TTR("Delete (No Confirm)"), KEY_MASK_SHIFT|KEY_DELETE); + ED_SHORTCUT("scene_tree/delete", TTR("Delete"), KEY_DELETE); + + tb = memnew( ToolButton ); + tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_NEW, false)); + tb->set_tooltip(TTR("Add/Create a New Node")); + tb->set_shortcut(ED_GET_SHORTCUT("scene_tree/add_child_node")); + filter_hbc->add_child(tb); + button_add=tb; + + tb = memnew( ToolButton ); + tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_INSTANCE, false)); + tb->set_tooltip(TTR("Instance a scene file as a Node. Creates an inherited scene if no root node exists.")); + tb->set_shortcut(ED_GET_SHORTCUT("scene_tree/instance_scene")); + filter_hbc->add_child(tb); + button_instance=tb; + + + + vbc->add_child(filter_hbc); + filter = memnew( LineEdit ); + filter->set_h_size_flags(SIZE_EXPAND_FILL); + filter_hbc->add_child(filter); + filter_icon = memnew( TextureRect ); + filter_hbc->add_child(filter_icon); + filter_icon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); + filter->connect("text_changed",this,"_filter_changed"); + + + tb = memnew( ToolButton ); + tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_ATTACH_SCRIPT, false)); + tb->set_tooltip(TTR("Attach a new or existing script for the selected node.")); + tb->set_shortcut(ED_GET_SHORTCUT("scene_tree/attach_script")); + filter_hbc->add_child(tb); + button_create_script=tb; + + tb = memnew(ToolButton); + tb->connect("pressed", this, "_tool_selected", make_binds(TOOL_CLEAR_SCRIPT, false)); + tb->set_tooltip(TTR("Clear a script for the selected node.")); + tb->set_shortcut(ED_GET_SHORTCUT("scene_tree/clear_script")); + filter_hbc->add_child(tb); + button_clear_script = tb; + + + scene_tree = memnew( SceneTreeEditor(false,true,true )); + vbc->add_child(scene_tree); + scene_tree->set_v_size_flags(SIZE_EXPAND|SIZE_FILL); + scene_tree->connect("rmb_pressed",this,"_tree_rmb"); + + scene_tree->connect("node_selected", this,"_node_selected",varray(),CONNECT_DEFERRED); + scene_tree->connect("node_renamed", this,"_node_renamed",varray(),CONNECT_DEFERRED); + scene_tree->connect("node_prerename", this,"_node_prerenamed"); + scene_tree->connect("open",this,"_load_request"); + scene_tree->connect("open_script",this,"_script_open_request"); + scene_tree->connect("nodes_rearranged",this,"_nodes_dragged"); + scene_tree->connect("files_dropped",this,"_files_dropped"); + scene_tree->connect("script_dropped",this,"_script_dropped"); + scene_tree->connect("nodes_dragged",this,"_nodes_drag_begin"); + + scene_tree->get_scene_tree()->connect("item_double_clicked", this, "_focus_node"); + + scene_tree->set_undo_redo(&editor_data->get_undo_redo()); + scene_tree->set_editor_selection(editor_selection); + + + create_dialog = memnew( CreateDialog ); + create_dialog->set_base_type("Node"); + add_child(create_dialog); + create_dialog->connect("create",this,"_create"); + + //groups_editor = memnew( GroupsEditor ); + //add_child(groups_editor); + //groups_editor->set_undo_redo(&editor_data->get_undo_redo()); + + //connect_dialog = memnew( ConnectionsDialog(p_editor) ); + //add_child(connect_dialog); + //connect_dialog->set_undoredo(&editor_data->get_undo_redo()); + + script_create_dialog = memnew( ScriptCreateDialog ); + add_child(script_create_dialog); + script_create_dialog->connect("script_created",this,"_script_created"); + + reparent_dialog = memnew( ReparentDialog ); + add_child(reparent_dialog); + reparent_dialog->connect("reparent",this,"_node_reparent"); + + accept = memnew( AcceptDialog ); + add_child(accept); + + file = memnew( EditorFileDialog ); + add_child(file); + file->connect("file_selected",this,"instance"); + set_process_unhandled_key_input(true); + + delete_dialog = memnew( ConfirmationDialog ); + add_child(delete_dialog); + delete_dialog->connect("confirmed",this,"_delete_confirm"); + + import_subscene_dialog = memnew( EditorSubScene ); + add_child(import_subscene_dialog); + import_subscene_dialog->connect("subscene_selected",this,"_import_subscene"); + + new_scene_from_dialog = memnew( EditorFileDialog ); + new_scene_from_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE); + add_child(new_scene_from_dialog); + new_scene_from_dialog->connect("file_selected",this,"_new_scene_from"); + + + menu = memnew( PopupMenu ); + add_child(menu); + menu->connect("id_pressed",this,"_tool_selected"); + first_enter=true; + restore_script_editor_on_drag=false; + + vbc->add_constant_override("separation",4); + set_process_input(true); +} diff --git a/tools/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 2ee7ba3d06..2ee7ba3d06 100644 --- a/tools/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp new file mode 100644 index 0000000000..fb21747ebb --- /dev/null +++ b/editor/scene_tree_editor.cpp @@ -0,0 +1,1316 @@ +/*************************************************************************/ +/* scene_tree_editor.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 "scene_tree_editor.h" + +#include "scene/gui/label.h" +#include "editor_node.h" +#include "print_string.h" +#include "message_queue.h" +#include "scene/main/viewport.h" +#include "editor/plugins/canvas_item_editor_plugin.h" +#include "scene/resources/packed_scene.h" + +Node *SceneTreeEditor::get_scene_node() { + + ERR_FAIL_COND_V(!is_inside_tree(),NULL); + + return get_tree()->get_edited_scene_root(); +} + + +void SceneTreeEditor::_subscene_option(int p_idx) { + + Object *obj = ObjectDB::get_instance(instance_node); + if (!obj) + return; + Node *node = obj->cast_to<Node>(); + if (!node) + return; + + switch(p_idx) { + + case SCENE_MENU_EDITABLE_CHILDREN: { + + bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node); + editable = !editable; + + //node->set_instance_children_editable(editable); + EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node,editable); + instance_menu->set_item_checked(0,editable); + if (editable) { + node->set_scene_instance_load_placeholder(false); + instance_menu->set_item_checked(1,false); + } + + _update_tree(); + + } break; + case SCENE_MENU_USE_PLACEHOLDER: { + + bool placeholder = node->get_scene_instance_load_placeholder(); + placeholder = !placeholder; + + //node->set_instance_children_editable(editable); + if (placeholder) { + EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node,false); + } + node->set_scene_instance_load_placeholder(placeholder); + instance_menu->set_item_checked(0,false); + instance_menu->set_item_checked(1,placeholder); + + _update_tree(); + + } break; + case SCENE_MENU_OPEN: { + + emit_signal("open",node->get_filename()); + } break; + case SCENE_MENU_CLEAR_INHERITANCE: { + clear_inherit_confirm->popup_centered_minsize(); + } break; + case SCENE_MENU_CLEAR_INSTANCING: { + + Node*root=EditorNode::get_singleton()->get_edited_scene(); + if (!root) + break; + + + ERR_FAIL_COND(node->get_filename()==String()); + + undo_redo->create_action("Discard Instancing"); + + undo_redo->add_do_method(node,"set_filename",""); + undo_redo->add_undo_method(node,"set_filename",node->get_filename()); + + _node_replace_owner(node,node,root); + + undo_redo->add_do_method(this,"update_tree"); + undo_redo->add_undo_method(this,"update_tree"); + + undo_redo->commit_action(); + + + } break; + case SCENE_MENU_OPEN_INHERITED: { + if (node && node->get_scene_inherited_state().is_valid()) { + emit_signal("open",node->get_scene_inherited_state()->get_path()); + } + } break; + case SCENE_MENU_CLEAR_INHERITANCE_CONFIRM: { + if (node && node->get_scene_inherited_state().is_valid()) { + node->set_scene_inherited_state(Ref<SceneState>()); + update_tree(); + EditorNode::get_singleton()->get_property_editor()->update_tree(); + } + + } break; + + + } + +} + + +void SceneTreeEditor::_node_replace_owner(Node* p_base,Node* p_node,Node* p_root) { + + if (p_base!=p_node) { + + if (p_node->get_owner()==p_base) { + + undo_redo->add_do_method(p_node,"set_owner",p_root); + undo_redo->add_undo_method(p_node,"set_owner",p_base); + } + } + + for(int i=0;i<p_node->get_child_count();i++) { + + _node_replace_owner(p_base,p_node->get_child(i),p_root); + } +} + + +void SceneTreeEditor::_cell_button_pressed(Object *p_item,int p_column,int p_id) { + + TreeItem *item=p_item->cast_to<TreeItem>(); + ERR_FAIL_COND(!item); + + NodePath np = item->get_metadata(0); + + Node *n=get_node(np); + ERR_FAIL_COND(!n); + + if (p_id==BUTTON_SUBSCENE) { + //open scene request + Rect2 item_rect = tree->get_item_rect(item,0); + item_rect.pos.y-=tree->get_scroll().y; + item_rect.pos+=tree->get_global_pos(); + + if (n==get_scene_node()) { + inheritance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y)); + inheritance_menu->set_size(Vector2(item_rect.size.x,0)); + inheritance_menu->popup(); + instance_node=n->get_instance_ID(); + + } else { + instance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y)); + instance_menu->set_size(Vector2(item_rect.size.x,0)); + if (EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(n)) + instance_menu->set_item_checked(0,true); + else + instance_menu->set_item_checked(0,false); + + if (n->get_owner()==get_scene_node()) { + instance_menu->set_item_checked(1,n->get_scene_instance_load_placeholder()); + instance_menu->set_item_disabled(1,false); + } else { + + instance_menu->set_item_checked(1,false); + instance_menu->set_item_disabled(1,true); + } + + instance_menu->popup(); + instance_node=n->get_instance_ID(); + } + //emit_signal("open",n->get_filename()); + } else if (p_id==BUTTON_SCRIPT) { + RefPtr script=n->get_script(); + if (!script.is_null()) + emit_signal("open_script",script); + + } else if (p_id==BUTTON_VISIBILITY) { + + + if (n->is_class("Spatial")) { + + bool v = bool(n->call("is_visible")); + undo_redo->create_action(TTR("Toggle Spatial Visible")); + undo_redo->add_do_method(n,"set_visible",!v); + undo_redo->add_undo_method(n,"set_visible",v); + undo_redo->commit_action(); + + } else if (n->is_class("CanvasItem")) { + + bool v = bool(n->call("is_visible")); + undo_redo->create_action(TTR("Toggle CanvasItem Visible")); + undo_redo->add_do_method(n,v?"hide":"show"); + undo_redo->add_undo_method(n,v?"show":"hide"); + undo_redo->commit_action(); + } + + } else if (p_id==BUTTON_LOCK) { + + if (n->is_class("CanvasItem")) { + n->set_meta("_edit_lock_", Variant()); + _update_tree(); + emit_signal("node_changed"); + } + + } else if (p_id==BUTTON_GROUP) { + if (n->is_class("CanvasItem")) { + n->set_meta("_edit_group_", Variant()); + _update_tree(); + emit_signal("node_changed"); + } + } else if (p_id==BUTTON_WARNING) { + + String config_err = n->get_configuration_warning(); + if (config_err==String()) + return; + config_err=config_err.word_wrap(80); + warning->set_text(config_err); + warning->popup_centered_minsize(); + + } else if (p_id==BUTTON_SIGNALS) { + + editor_selection->clear(); + editor_selection->add_node(n); + + set_selected(n); + + NodeDock::singleton->get_parent()->call("set_current_tab",NodeDock::singleton->get_index()); + NodeDock::singleton->show_connections(); + + } else if (p_id==BUTTON_GROUPS) { + + editor_selection->clear(); + editor_selection->add_node(n); + + set_selected(n); + + NodeDock::singleton->get_parent()->call("set_current_tab",NodeDock::singleton->get_index()); + NodeDock::singleton->show_groups(); + } +} + +bool SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) { + + if (!p_node) + return false; + + // only owned nodes are editable, since nodes can create their own (manually owned) child nodes, + // which the editor needs not to know about. + + bool part_of_subscene=false; + + if (!display_foreign && p_node->get_owner()!=get_scene_node() && p_node!=get_scene_node()) { + + if ((show_enabled_subscene || can_open_instance) && p_node->get_owner() && (get_scene_node()->is_editable_instance(p_node->get_owner()))) { + + part_of_subscene=true; + //allow + } else { + return false; + } + } else { + part_of_subscene = p_node!=get_scene_node() && get_scene_node()->get_scene_inherited_state().is_valid() && get_scene_node()->get_scene_inherited_state()->find_node_by_path(get_scene_node()->get_path_to(p_node))>=0; + } + + TreeItem *item = tree->create_item(p_parent); + item->set_text(0, p_node->get_name() ); + if (can_rename && !part_of_subscene /*(p_node->get_owner() == get_scene_node() || p_node==get_scene_node())*/) + item->set_editable(0, true); + + item->set_selectable(0,true); + if (can_rename) { +#ifdef ENABLE_DEPRECATED + if (p_node->has_meta("_editor_collapsed")) { + //remove previous way of storing folding, which did not get along with scene inheritance and instancing + if ((bool)p_node->get_meta("_editor_collapsed")) + p_node->set_display_folded(true); + p_node->set_meta("_editor_collapsed",Variant()); + } +#endif + bool collapsed = p_node->is_displayed_folded(); + if (collapsed) + item->set_collapsed(true); + } + + Ref<Texture> icon; + if (p_node->has_meta("_editor_icon")) + icon=p_node->get_meta("_editor_icon"); + else + icon=get_icon( (has_icon(p_node->get_class(),"EditorIcons")?p_node->get_class():String("Object")),"EditorIcons"); + item->set_icon(0, icon ); + item->set_metadata( 0,p_node->get_path() ); + + if (part_of_subscene) { + + //item->set_selectable(0,marked_selectable); + item->set_custom_color(0,Color(0.8,0.4,0.20)); + + } else if (marked.has(p_node)) { + + item->set_selectable(0,marked_selectable); + item->set_custom_color(0,Color(0.8,0.1,0.10)); + } else if (!marked_selectable && !marked_children_selectable) { + + Node *node=p_node; + while(node) { + if (marked.has(node)) { + item->set_selectable(0,false); + item->set_custom_color(0,Color(0.8,0.1,0.10)); + break; + } + node=node->get_parent(); + } + } + + + + if (can_rename) { //should be can edit.. + + String warning = p_node->get_configuration_warning(); + if (warning!=String()) { + item->add_button(0,get_icon("NodeWarning","EditorIcons"),BUTTON_WARNING); + } + + bool has_connections = p_node->has_persistent_signal_connections(); + bool has_groups = p_node->has_persistent_groups(); + + if (has_connections && has_groups) { + item->add_button(0,get_icon("ConnectionAndGroups","EditorIcons"),BUTTON_SIGNALS); + } else if (has_connections) { + item->add_button(0,get_icon("Connect","EditorIcons"),BUTTON_SIGNALS); + } else if (has_groups) { + item->add_button(0,get_icon("Groups","EditorIcons"),BUTTON_GROUPS); + } + } + + if (p_node==get_scene_node() && p_node->get_scene_inherited_state().is_valid()) { + item->add_button(0,get_icon("InstanceOptions","EditorIcons"),BUTTON_SUBSCENE); + item->set_tooltip(0,TTR("Inherits:")+" "+p_node->get_scene_inherited_state()->get_path()+"\n"+TTR("Type:")+" "+p_node->get_class()); + } else if (p_node!=get_scene_node() && p_node->get_filename()!="" && can_open_instance) { + + item->add_button(0,get_icon("InstanceOptions","EditorIcons"),BUTTON_SUBSCENE); + item->set_tooltip(0,TTR("Instance:")+" "+p_node->get_filename()+"\n"+TTR("Type:")+" "+p_node->get_class()); + } else { + item->set_tooltip(0,String(p_node->get_name())+"\n"+TTR("Type:")+" "+p_node->get_class()); + } + + if (can_open_instance) { + + if (!p_node->is_connected("script_changed",this,"_node_script_changed")) + p_node->connect("script_changed",this,"_node_script_changed",varray(p_node)); + + + if (!p_node->get_script().is_null()) { + + item->add_button(0,get_icon("Script","EditorIcons"),BUTTON_SCRIPT); + } + + if (p_node->is_class("CanvasItem")) { + + bool is_locked = p_node->has_meta("_edit_lock_");//_edit_group_ + if (is_locked) + item->add_button(0,get_icon("Lock", "EditorIcons"), BUTTON_LOCK); + + bool is_grouped = p_node->has_meta("_edit_group_"); + if (is_grouped) + item->add_button(0,get_icon("Group", "EditorIcons"), BUTTON_GROUP); + + bool v = p_node->call("is_visible"); + if (v) + item->add_button(0,get_icon("Visible","EditorIcons"),BUTTON_VISIBILITY); + else + item->add_button(0,get_icon("Hidden","EditorIcons"),BUTTON_VISIBILITY); + + if (!p_node->is_connected("visibility_changed",this,"_node_visibility_changed")) + p_node->connect("visibility_changed",this,"_node_visibility_changed",varray(p_node)); + + _update_visibility_color(p_node, item); + } else if (p_node->is_class("Spatial")) { + + bool v = p_node->call("is_visible"); + if (v) + item->add_button(0,get_icon("Visible","EditorIcons"),BUTTON_VISIBILITY); + else + item->add_button(0,get_icon("Hidden","EditorIcons"),BUTTON_VISIBILITY); + + if (!p_node->is_connected("visibility_changed",this,"_node_visibility_changed")) + p_node->connect("visibility_changed",this,"_node_visibility_changed",varray(p_node)); + + _update_visibility_color(p_node, item); + } + + } + + if (editor_selection) { + if (editor_selection->is_selected(p_node)) { + + item->select(0); + } + } + + if (selected==p_node) { + if (!editor_selection) + item->select(0); + item->set_as_cursor(0); + } + + bool keep= (filter.is_subsequence_ofi(String(p_node->get_name()))); + + for (int i=0;i<p_node->get_child_count();i++) { + + bool child_keep = _add_nodes(p_node->get_child(i),item); + + keep = keep || child_keep; + + } + + if (!keep) { + memdelete(item); + return false; + } else { + return true; + } + +} + + +void SceneTreeEditor::_node_visibility_changed(Node *p_node) { + + + if (p_node!=get_scene_node() && !p_node->get_owner()) { + + return; + } + TreeItem* item=p_node?_find(tree->get_root(),p_node->get_path()):NULL; + if (!item) { + + return; + } + int idx=item->get_button_by_id(0,BUTTON_VISIBILITY); + ERR_FAIL_COND(idx==-1); + + bool visible=false; + + if (p_node->is_class("CanvasItem")) { + visible = p_node->call("is_visible"); + CanvasItemEditor::get_singleton()->get_viewport_control()->update(); + } else if (p_node->is_class("Spatial")) { + visible = p_node->call("is_visible"); + } + + if (visible) + item->set_button(0,idx,get_icon("Visible","EditorIcons")); + else + item->set_button(0,idx,get_icon("Hidden","EditorIcons")); + + _update_visibility_color(p_node, item); +} + +void SceneTreeEditor::_update_visibility_color(Node *p_node, TreeItem *p_item) { + if (p_node->is_class("CanvasItem") || p_node->is_class("Spatial")) { + Color color(1,1,1,1); + bool visible_on_screen = p_node->call("is_visible"); + if (!visible_on_screen) { + color = Color(0.6,0.6,0.6,1); + } + int idx=p_item->get_button_by_id(0,BUTTON_VISIBILITY); + p_item->set_button_color(0,idx,color); + } +} + +void SceneTreeEditor::_node_script_changed(Node *p_node) { + + _update_tree(); + /* + changes the order :| + TreeItem* item=p_node?_find(tree->get_root(),p_node->get_path()):NULL; + if (p_node->get_script().is_null()) { + + int idx=item->get_button_by_id(0,2); + if (idx>=0) + item->erase_button(0,idx); + } else { + + int idx=item->get_button_by_id(0,2); + if (idx<0) + item->add_button(0,get_icon("Script","EditorIcons"),2); + + }*/ + +} + +void SceneTreeEditor::_node_removed(Node *p_node) { + + if (EditorNode::get_singleton()->is_exiting()) + return; //speed up exit + + if (p_node->is_connected("script_changed",this,"_node_script_changed")) + p_node->disconnect("script_changed",this,"_node_script_changed"); + + if (p_node->is_class("Spatial") || p_node->is_class("CanvasItem")) { + if (p_node->is_connected("visibility_changed",this,"_node_visibility_changed")) + p_node->disconnect("visibility_changed",this,"_node_visibility_changed"); + } + + if (p_node==selected) { + selected=NULL; + emit_signal("node_selected"); + } + + +} +void SceneTreeEditor::_update_tree() { + + + if (!is_inside_tree()) { + tree_dirty=false; + return; + } + + updating_tree=true; + tree->clear(); + if (get_scene_node()) { + _add_nodes( get_scene_node(), NULL ); + last_hash = hash_djb2_one_64(0); + _compute_hash(get_scene_node(),last_hash); + + } + updating_tree=false; + + tree_dirty=false; + +} + +void SceneTreeEditor::_compute_hash(Node *p_node,uint64_t &hash) { + + hash=hash_djb2_one_64(p_node->get_instance_ID(),hash); + if (p_node->get_parent()) + hash=hash_djb2_one_64(p_node->get_parent()->get_instance_ID(),hash); //so a reparent still produces a different hash + + + for(int i=0;i<p_node->get_child_count();i++) { + + _compute_hash(p_node->get_child(i),hash); + } +} + +void SceneTreeEditor::_test_update_tree() { + + pending_test_update=false; + + if (!is_inside_tree()) + return; + + if(tree_dirty) + return; // don't even bother + + uint64_t hash = hash_djb2_one_64(0); + if (get_scene_node()) + _compute_hash(get_scene_node(),hash); + //test hash + if (hash==last_hash) + return; // did not change + + MessageQueue::get_singleton()->push_call(this,"_update_tree"); + tree_dirty=true; +} + +void SceneTreeEditor::_tree_changed() { + + if (EditorNode::get_singleton()->is_exiting()) + return; //speed up exit + if (pending_test_update) + return; + if (tree_dirty) + return; + + MessageQueue::get_singleton()->push_call(this,"_test_update_tree"); + pending_test_update=true; + +} + +void SceneTreeEditor::_selected_changed() { + + + TreeItem *s = tree->get_selected(); + ERR_FAIL_COND(!s); + NodePath np = s->get_metadata(0); + + Node *n=get_node(np); + + + if (n==selected) + return; + + + selected = get_node(np); + + blocked++; + emit_signal("node_selected"); + blocked--; + + +} + + +void SceneTreeEditor::_cell_multi_selected(Object *p_object,int p_cell,bool p_selected) { + + TreeItem *item = p_object->cast_to<TreeItem>(); + ERR_FAIL_COND(!item); + + NodePath np = item->get_metadata(0); + + Node *n=get_node(np); + + if (!n) + return; + + if (!editor_selection) + return; + + if (p_selected) { + editor_selection->add_node(n); + + } else { + editor_selection->remove_node(n); + + } + +} + +void SceneTreeEditor::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + + get_tree()->connect("tree_changed",this,"_tree_changed"); + get_tree()->connect("node_removed",this,"_node_removed"); + get_tree()->connect("node_configuration_warning_changed",this,"_warning_changed"); + + instance_menu->set_item_icon(5,get_icon("Load","EditorIcons")); + tree->connect("item_collapsed",this,"_cell_collapsed"); + inheritance_menu->set_item_icon(2,get_icon("Load","EditorIcons")); + clear_inherit_confirm->connect("confirmed",this,"_subscene_option",varray(SCENE_MENU_CLEAR_INHERITANCE_CONFIRM)); + + EditorSettings::get_singleton()->connect("settings_changed",this,"_editor_settings_changed"); + + + //get_scene()->connect("tree_changed",this,"_tree_changed",Vector<Variant>(),CONNECT_DEFERRED); + //get_scene()->connect("node_removed",this,"_node_removed",Vector<Variant>(),CONNECT_DEFERRED); + _update_tree(); + } + if (p_what==NOTIFICATION_EXIT_TREE) { + + get_tree()->disconnect("tree_changed",this,"_tree_changed"); + get_tree()->disconnect("node_removed",this,"_node_removed"); + tree->disconnect("item_collapsed",this,"_cell_collapsed"); + clear_inherit_confirm->disconnect("confirmed",this,"_subscene_option"); + get_tree()->disconnect("node_configuration_warning_changed",this,"_warning_changed"); + EditorSettings::get_singleton()->disconnect("settings_changed",this,"_editor_settings_changed"); + } + +} + + +TreeItem* SceneTreeEditor::_find(TreeItem *p_node,const NodePath& p_path) { + + if (!p_node) + return NULL; + + NodePath np=p_node->get_metadata(0); + if (np==p_path) + return p_node; + + TreeItem *children=p_node->get_children(); + while(children) { + + TreeItem *n=_find(children,p_path); + if (n) + return n; + children=children->get_next(); + } + + return NULL; +} + +void SceneTreeEditor::set_selected(Node *p_node,bool p_emit_selected) { + + ERR_FAIL_COND(blocked>0); + + if (pending_test_update) + _test_update_tree(); + if (tree_dirty) + _update_tree(); + + if (selected==p_node) + return; + + + TreeItem* item=p_node?_find(tree->get_root(),p_node->get_path()):NULL; + + if (item) { + // make visible when it's collapsed + TreeItem* node=item->get_parent(); + while (node && node!=tree->get_root()) { + node->set_collapsed(false); + node=node->get_parent(); + } + item->select(0); + item->set_as_cursor(0); + selected=p_node; + tree->ensure_cursor_is_visible(); + } else { + if (!p_node) + selected=NULL; + _update_tree(); + selected=p_node; + if (p_emit_selected) + emit_signal("node_selected"); + } + +} + +void SceneTreeEditor::_rename_node(ObjectID p_node,const String& p_name) { + + Object *o = ObjectDB::get_instance(p_node); + ERR_FAIL_COND(!o); + Node *n = o->cast_to<Node>(); + ERR_FAIL_COND(!n); + TreeItem* item=_find(tree->get_root(),n->get_path()); + ERR_FAIL_COND(!item); + + n->set_name( p_name ); + item->set_metadata(0,n->get_path()); + item->set_text(0,p_name); + emit_signal("node_renamed"); + + if (!tree_dirty) { + MessageQueue::get_singleton()->push_call(this,"_update_tree"); + tree_dirty=true; + } + + +} + + +void SceneTreeEditor::_renamed() { + + TreeItem *which=tree->get_edited(); + + ERR_FAIL_COND(!which); + NodePath np = which->get_metadata(0); + Node *n=get_node(np); + ERR_FAIL_COND(!n); + + String new_name=which->get_text(0); + if (new_name.find(".") != -1 || new_name.find("/") != -1) { + + error->set_text(TTR("Invalid node name, the following characters are not allowed:")+"\n \".\", \"/\""); + error->popup_centered_minsize(); + new_name=n->get_name(); + } + + if (new_name==n->get_name()) + return; + + if (!undo_redo) { + n->set_name( new_name ); + which->set_metadata(0,n->get_path()); + emit_signal("node_renamed"); + } else { + undo_redo->create_action(TTR("Rename Node")); + emit_signal("node_prerename",n,new_name); + undo_redo->add_do_method(this,"_rename_node",n->get_instance_ID(),new_name); + undo_redo->add_undo_method(this,"_rename_node",n->get_instance_ID(),n->get_name()); + undo_redo->commit_action(); + } +} + + +Node *SceneTreeEditor::get_selected() { + + return selected; +} + +void SceneTreeEditor::set_marked(const Set<Node*>& p_marked,bool p_selectable,bool p_children_selectable) { + + if (tree_dirty) + _update_tree(); + marked=p_marked; + marked_selectable=p_selectable; + marked_children_selectable=p_children_selectable; + _update_tree(); +} + +void SceneTreeEditor::set_marked(Node *p_marked,bool p_selectable,bool p_children_selectable) { + + Set<Node*> s; + if (p_marked) + s.insert(p_marked); + set_marked(s,p_selectable,p_children_selectable); + + +} + +void SceneTreeEditor::set_filter(const String& p_filter) { + + filter=p_filter; + _update_tree(); +} + +String SceneTreeEditor::get_filter() const { + + return filter; +} + + +void SceneTreeEditor::set_display_foreign_nodes(bool p_display) { + + display_foreign=p_display; + _update_tree(); +} +bool SceneTreeEditor::get_display_foreign_nodes() const { + + return display_foreign; +} + +void SceneTreeEditor::set_editor_selection(EditorSelection *p_selection) { + + editor_selection=p_selection; + tree->set_select_mode(Tree::SELECT_MULTI); + tree->set_cursor_can_exit_tree(false); + editor_selection->connect("selection_changed",this,"_selection_changed"); +} + +void SceneTreeEditor::_update_selection(TreeItem *item) { + + ERR_FAIL_COND(!item); + + NodePath np = item->get_metadata(0); + + if (!has_node(np)) + return; + + Node *n=get_node(np); + + if (!n) + return; + + if (editor_selection->is_selected(n)) + item->select(0); + else + item->deselect(0); + + TreeItem *c=item->get_children(); + + + while(c) { + + _update_selection(c); + c=c->get_next(); + } +} + +void SceneTreeEditor::_selection_changed() { + + if (!editor_selection) + return; + + TreeItem *root=tree->get_root(); + + if (!root) + return; + _update_selection(root); +} + +void SceneTreeEditor::_cell_collapsed(Object *p_obj) { + + if (updating_tree) + return; + if (!can_rename) + return; + + TreeItem *ti=p_obj->cast_to<TreeItem>(); + if (!ti) + return; + + bool collapsed=ti->is_collapsed(); + + NodePath np = ti->get_metadata(0); + + Node *n=get_node(np); + ERR_FAIL_COND(!n); + + n->set_display_folded(collapsed); + +} + +Variant SceneTreeEditor::get_drag_data_fw(const Point2& p_point,Control* p_from) { + if (!can_rename) + return Variant(); //not editable tree + + Vector<Node*> selected; + Vector<Ref<Texture> > icons; + TreeItem *next=tree->get_next_selected(NULL); + while (next) { + + NodePath np = next->get_metadata(0); + + Node *n=get_node(np); + if (n) { + + selected.push_back(n); + icons.push_back(next->get_icon(0)); + } + next=tree->get_next_selected(next); + } + + if (selected.empty()) + return Variant(); + + VBoxContainer *vb = memnew( VBoxContainer ); + Array objs; + int list_max = 10; + float opacity_step = 1.0f / list_max; + float opacity_item = 1.0f; + for(int i=0;i<selected.size();i++) { + + if (i<list_max){ + HBoxContainer *hb = memnew( HBoxContainer ); + TextureRect *tf = memnew(TextureRect); + tf->set_texture(icons[i]); + hb->add_child(tf); + Label *label = memnew( Label( selected[i]->get_name() ) ); + hb->add_child(label); + vb->add_child(hb); + hb->set_modulate(Color(1,1,1,opacity_item)); + opacity_item -= opacity_step; + } + NodePath p = selected[i]->get_path(); + objs.push_back(p); + } + + set_drag_preview(vb); + Dictionary drag_data; + drag_data["type"]="nodes"; + drag_data["nodes"]=objs; + + tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN|Tree::DROP_MODE_ON_ITEM); + emit_signal("nodes_dragged"); + + return drag_data; +} + +bool SceneTreeEditor::_is_script_type(const StringName &p_type) const { + return (script_types->find(p_type)); +} + +bool SceneTreeEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const { + + if (!can_rename) + return false; //not editable tree + if (filter!=String()) + return false; //can't rearrange tree with filter turned on + + + Dictionary d=p_data; + if (!d.has("type")) + return false; + + TreeItem *item = tree->get_item_at_pos(p_point); + if (!item) + return false; + + int section = tree->get_drop_section_at_pos(p_point); + if (section<-1 || (section==-1 && !item->get_parent())) + return false; + + if (String(d["type"])=="files") { + + Vector<String> files = d["files"]; + + if (files.size()==0) + return false; //weird + + if (_is_script_type(EditorFileSystem::get_singleton()->get_file_type(files[0]))) { + tree->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM); + return true; + } + + for(int i=0;i<files.size();i++) { + String file = files[i]; + String ftype = EditorFileSystem::get_singleton()->get_file_type(file); + if (ftype!="PackedScene") + return false; + } + + tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN|Tree::DROP_MODE_ON_ITEM); //so it works.. + + return true; + } + + + if (String(d["type"])=="nodes") { + return true; + } + + return false; +} +void SceneTreeEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) { + + if (!can_drop_data_fw(p_point,p_data,p_from)) + return; + + TreeItem *item = tree->get_item_at_pos(p_point); + if (!item) + return; + int section = tree->get_drop_section_at_pos(p_point); + if (section<-1) + return; + + NodePath np = item->get_metadata(0); + Node *n=get_node(np); + if (!n) + return; + + Dictionary d=p_data; + + if (String(d["type"])=="nodes") { + Array nodes=d["nodes"]; + emit_signal("nodes_rearranged",nodes,np,section); + } + + if (String(d["type"])=="files") { + + Vector<String> files = d["files"]; + + + String ftype = EditorFileSystem::get_singleton()->get_file_type(files[0]); + if (_is_script_type(ftype)) { + emit_signal("script_dropped", files[0],np); + } else { + emit_signal("files_dropped",files,np,section); + } + } + +} + +void SceneTreeEditor::_rmb_select(const Vector2& p_pos) { + + emit_signal("rmb_pressed",tree->get_global_transform().xform(p_pos)); +} + + +void SceneTreeEditor::_warning_changed(Node* p_for_node) { + + //should use a timer + update_timer->start(); + //print_line("WARNING CHANGED "+String(p_for_node->get_name())); + +} + + +void SceneTreeEditor::_editor_settings_changed() { + bool enable_rl = EditorSettings::get_singleton()->get("docks/scene_tree/draw_relationship_lines"); + Color rl_color = EditorSettings::get_singleton()->get("docks/scene_tree/relationship_line_color"); + + if (enable_rl) { + tree->add_constant_override("draw_relationship_lines",1); + tree->add_color_override("relationship_line_color", rl_color); + } + else + tree->add_constant_override("draw_relationship_lines",0); + +} + + +void SceneTreeEditor::_bind_methods() { + + ClassDB::bind_method("_tree_changed",&SceneTreeEditor::_tree_changed); + ClassDB::bind_method("_update_tree",&SceneTreeEditor::_update_tree); + ClassDB::bind_method("_node_removed",&SceneTreeEditor::_node_removed); + ClassDB::bind_method("_selected_changed",&SceneTreeEditor::_selected_changed); + ClassDB::bind_method("_renamed",&SceneTreeEditor::_renamed); + ClassDB::bind_method("_rename_node",&SceneTreeEditor::_rename_node); + ClassDB::bind_method("_test_update_tree",&SceneTreeEditor::_test_update_tree); + ClassDB::bind_method("_cell_multi_selected",&SceneTreeEditor::_cell_multi_selected); + ClassDB::bind_method("_selection_changed",&SceneTreeEditor::_selection_changed); + ClassDB::bind_method("_cell_button_pressed",&SceneTreeEditor::_cell_button_pressed); + ClassDB::bind_method("_cell_collapsed",&SceneTreeEditor::_cell_collapsed); + ClassDB::bind_method("_subscene_option",&SceneTreeEditor::_subscene_option); + ClassDB::bind_method("_rmb_select",&SceneTreeEditor::_rmb_select); + ClassDB::bind_method("_warning_changed",&SceneTreeEditor::_warning_changed); + + ClassDB::bind_method("_node_script_changed",&SceneTreeEditor::_node_script_changed); + ClassDB::bind_method("_node_visibility_changed",&SceneTreeEditor::_node_visibility_changed); + + ClassDB::bind_method("_editor_settings_changed", &SceneTreeEditor::_editor_settings_changed); + + ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &SceneTreeEditor::get_drag_data_fw); + ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SceneTreeEditor::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("drop_data_fw"), &SceneTreeEditor::drop_data_fw); + + ClassDB::bind_method(D_METHOD("update_tree"), &SceneTreeEditor::update_tree); + + ADD_SIGNAL( MethodInfo("node_selected") ); + ADD_SIGNAL( MethodInfo("node_renamed") ); + ADD_SIGNAL( MethodInfo("node_prerename") ); + ADD_SIGNAL( MethodInfo("node_changed") ); + ADD_SIGNAL( MethodInfo("nodes_dragged") ); + ADD_SIGNAL( MethodInfo("nodes_rearranged",PropertyInfo(Variant::ARRAY,"paths"),PropertyInfo(Variant::NODE_PATH,"to_path"),PropertyInfo(Variant::INT,"type") ) ); + ADD_SIGNAL( MethodInfo("files_dropped",PropertyInfo(Variant::POOL_STRING_ARRAY,"files"),PropertyInfo(Variant::NODE_PATH,"to_path"),PropertyInfo(Variant::INT,"type") ) ); + ADD_SIGNAL( MethodInfo("script_dropped",PropertyInfo(Variant::STRING,"file"),PropertyInfo(Variant::NODE_PATH,"to_path"))); + ADD_SIGNAL( MethodInfo("rmb_pressed",PropertyInfo(Variant::VECTOR2,"pos")) ) ; + + ADD_SIGNAL( MethodInfo("open") ); + ADD_SIGNAL( MethodInfo("open_script") ); + + +} + + +SceneTreeEditor::SceneTreeEditor(bool p_label,bool p_can_rename, bool p_can_open_instance) { + + + undo_redo=NULL; + tree_dirty=true; + selected=NULL; + + marked_selectable=false; + marked_children_selectable=false; + can_rename=p_can_rename; + can_open_instance=p_can_open_instance; + display_foreign=false; + editor_selection=NULL; + + if (p_label) { + Label *label = memnew( Label ); + label->set_pos( Point2(10, 0)); + label->set_text(TTR("Scene Tree (Nodes):")); + + add_child(label); + } + + tree = memnew( Tree ); + tree->set_anchor( MARGIN_RIGHT, ANCHOR_END ); + tree->set_anchor( MARGIN_BOTTOM, ANCHOR_END ); + tree->set_begin( Point2(0,p_label?18:0 )); + tree->set_end( Point2(0,0 )); + + add_child( tree ); + + tree->set_drag_forwarding(this); + if (p_can_rename) { + tree->set_allow_rmb_select(true); + tree->connect("item_rmb_selected",this,"_rmb_select"); + tree->connect("empty_tree_rmb_selected",this,"_rmb_select"); + } + + tree->connect("cell_selected", this,"_selected_changed"); + tree->connect("item_edited", this,"_renamed",varray(),CONNECT_DEFERRED); + tree->connect("multi_selected",this,"_cell_multi_selected"); + tree->connect("button_pressed",this,"_cell_button_pressed"); + //tree->connect("item_edited", this,"_renamed",Vector<Variant>(),true); + + error = memnew( AcceptDialog ); + add_child(error); + + warning = memnew( AcceptDialog ); + add_child(warning); + warning->set_title("Node Configuration Warning!"); + + + show_enabled_subscene=false; + + last_hash=0; + pending_test_update=false; + updating_tree=false; + blocked=0; + + instance_menu = memnew( PopupMenu ); + instance_menu->add_check_item(TTR("Editable Children"),SCENE_MENU_EDITABLE_CHILDREN); + instance_menu->add_check_item(TTR("Load As Placeholder"),SCENE_MENU_USE_PLACEHOLDER); + instance_menu->add_separator(); + instance_menu->add_item(TTR("Discard Instancing"),SCENE_MENU_CLEAR_INSTANCING); + instance_menu->add_separator(); + instance_menu->add_item(TTR("Open in Editor"),SCENE_MENU_OPEN); + instance_menu->connect("id_pressed",this,"_subscene_option"); + add_child(instance_menu); + + inheritance_menu = memnew( PopupMenu ); + inheritance_menu->add_item(TTR("Clear Inheritance"),SCENE_MENU_CLEAR_INHERITANCE); + inheritance_menu->add_separator(); + inheritance_menu->add_item(TTR("Open in Editor"),SCENE_MENU_OPEN_INHERITED); + inheritance_menu->connect("id_pressed",this,"_subscene_option"); + + add_child(inheritance_menu); + + clear_inherit_confirm = memnew( ConfirmationDialog ); + clear_inherit_confirm->set_text(TTR("Clear Inheritance? (No Undo!)")); + clear_inherit_confirm->get_ok()->set_text(TTR("Clear!")); + add_child(clear_inherit_confirm); + + update_timer = memnew(Timer); + update_timer->connect("timeout",this,"_update_tree"); + update_timer->set_one_shot(true); + update_timer->set_wait_time(0.5); + add_child(update_timer); + + script_types = memnew(List<StringName>); + ClassDB::get_inheriters_from_class("Script", script_types); + +} + + + +SceneTreeEditor::~SceneTreeEditor() { + + memdelete(script_types); +} + + +/******** DIALOG *********/ + +void SceneTreeDialog::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + connect("confirmed", this,"_select"); + + } + + if (p_what==NOTIFICATION_EXIT_TREE) { + disconnect("confirmed", this,"_select"); + + } + if (p_what==NOTIFICATION_DRAW) { + + RID ci = get_canvas_item(); + get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size())); + } + + if (p_what==NOTIFICATION_VISIBILITY_CHANGED && is_visible_in_tree()) { + + tree->update_tree(); + } + + +} + +void SceneTreeDialog::_cancel() { + + hide(); + + + +} +void SceneTreeDialog::_select() { + + if (tree->get_selected()) { + emit_signal("selected",tree->get_selected()->get_path()); + hide(); + } +} + +void SceneTreeDialog::_bind_methods() { + + ClassDB::bind_method("_select",&SceneTreeDialog::_select); + ClassDB::bind_method("_cancel",&SceneTreeDialog::_cancel); + ADD_SIGNAL( MethodInfo("selected",PropertyInfo(Variant::NODE_PATH,"path"))); + +} + + +SceneTreeDialog::SceneTreeDialog() { + + set_title(TTR("Select a Node")); + + tree = memnew( SceneTreeEditor(false,false) ); + add_child(tree); + //set_child_rect(tree); + + tree->get_scene_tree()->connect("item_activated",this,"_select"); + +} + + +SceneTreeDialog::~SceneTreeDialog() +{ +} diff --git a/tools/editor/scene_tree_editor.h b/editor/scene_tree_editor.h index 5586f02c00..5586f02c00 100644 --- a/tools/editor/scene_tree_editor.h +++ b/editor/scene_tree_editor.h diff --git a/tools/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index dfaa1f645c..dfaa1f645c 100644 --- a/tools/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h new file mode 100644 index 0000000000..ad9616c071 --- /dev/null +++ b/editor/script_create_dialog.h @@ -0,0 +1,79 @@ +/*************************************************************************/ +/* script_create_dialog.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef SCRIPT_CREATE_DIALOG_H +#define SCRIPT_CREATE_DIALOG_H + +#include "scene/gui/dialogs.h" +#include "scene/gui/line_edit.h" +#include "scene/gui/option_button.h" +#include "editor/editor_file_dialog.h" +#include "editor/editor_settings.h" +#include "scene/gui/check_button.h" + +class ScriptCreateDialog : public ConfirmationDialog { + GDCLASS(ScriptCreateDialog,ConfirmationDialog); + + LineEdit *class_name; + Label *error_label; + Label *path_error_label; + LineEdit *parent_name; + OptionButton *language_menu; + LineEdit *file_path; + EditorFileDialog *file_browse; + CheckButton *internal; + VBoxContainer *path_vb; + AcceptDialog *alert; + bool path_valid; + bool create_new; + String initial_bp; + EditorSettings *editor_settings; + + + void _path_changed(const String& p_path=String()); + void _lang_changed(int l=0); + void _built_in_pressed(); + bool _validate(const String& p_strin); + void _class_name_changed(const String& p_name); + void _browse_path(); + void _file_selected(const String& p_file); + virtual void ok_pressed(); + void _create_new(); + void _load_exist(); + void _update_controls(); +protected: + + static void _bind_methods(); +public: + + void config(const String& p_base_name,const String&p_base_path); + + ScriptCreateDialog(); +}; + +#endif // SCRIPT_CREATE_DIALOG_H diff --git a/tools/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp index fa33ffe5c7..fa33ffe5c7 100644 --- a/tools/editor/script_editor_debugger.cpp +++ b/editor/script_editor_debugger.cpp diff --git a/tools/editor/script_editor_debugger.h b/editor/script_editor_debugger.h index a02934bbaf..a02934bbaf 100644 --- a/tools/editor/script_editor_debugger.h +++ b/editor/script_editor_debugger.h diff --git a/tools/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index 7d8d6ffcec..7d8d6ffcec 100644 --- a/tools/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp diff --git a/tools/editor/settings_config_dialog.h b/editor/settings_config_dialog.h index 17a05c27d3..17a05c27d3 100644 --- a/tools/editor/settings_config_dialog.h +++ b/editor/settings_config_dialog.h diff --git a/tools/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 825db5356b..825db5356b 100644 --- a/tools/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp diff --git a/editor/spatial_editor_gizmos.h b/editor/spatial_editor_gizmos.h new file mode 100644 index 0000000000..c44a987144 --- /dev/null +++ b/editor/spatial_editor_gizmos.h @@ -0,0 +1,521 @@ +/*************************************************************************/ +/* spatial_editor_gizmos.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ +#ifndef SPATIAL_EDITOR_GIZMOS_H +#define SPATIAL_EDITOR_GIZMOS_H + + +#include "editor/plugins/spatial_editor_plugin.h" +#include "scene/3d/light.h" +#include "scene/3d/listener.h" +#include "scene/3d/camera.h" +#include "scene/3d/position_3d.h" +#include "scene/3d/test_cube.h" +#include "scene/3d/mesh_instance.h" +#include "scene/3d/body_shape.h" +#include "scene/3d/room_instance.h" +#include "scene/3d/visibility_notifier.h" +#include "scene/3d/portal.h" +#include "scene/3d/ray_cast.h" +#include "scene/3d/navigation_mesh.h" +#include "scene/3d/reflection_probe.h" +#include "scene/3d/gi_probe.h" + +#include "scene/3d/vehicle_body.h" +#include "scene/3d/collision_polygon.h" +#include "scene/3d/physics_joint.h" + + +class Camera; + +class EditorSpatialGizmo : public SpatialEditorGizmo { + + GDCLASS(EditorSpatialGizmo,SpatialGizmo); + + struct Instance{ + + RID instance; + Ref<Mesh> mesh; + RID skeleton; + bool billboard; + bool unscaled; + bool can_intersect; + bool extra_margin; + Instance() { + + billboard=false; + unscaled=false; + can_intersect=false; + extra_margin=false; + } + + void create_instance(Spatial *p_base); + + }; + + Vector<Vector3> collision_segments; + Ref<TriangleMesh> collision_mesh; + + struct Handle { + Vector3 pos; + bool billboard; + }; + + Vector<Vector3> handles; + Vector<Vector3> secondary_handles; + bool billboard_handle; + + bool valid; + Spatial *base; + Vector<Instance> instances; + Spatial *spatial_node; + + void _set_spatial_node(Node *p_node) { set_spatial_node(p_node->cast_to<Spatial>()); } +protected: + void add_lines(const Vector<Vector3> &p_lines,const Ref<Material>& p_material,bool p_billboard=false); + void add_mesh(const Ref<Mesh>& p_mesh,bool p_billboard=false,const RID& p_skeleton=RID()); + void add_collision_segments(const Vector<Vector3> &p_lines); + void add_collision_triangles(const Ref<TriangleMesh>& p_tmesh); + void add_unscaled_billboard(const Ref<Material>& p_material,float p_scale=1); + void add_handles(const Vector<Vector3> &p_handles,bool p_billboard=false,bool p_secondary=false); + + void set_spatial_node(Spatial *p_node); + + static void _bind_methods(); +public: + + virtual Vector3 get_handle_pos(int p_idx) const; + virtual bool intersect_frustum(const Camera *p_camera,const Vector<Plane> &p_frustum); + virtual bool intersect_ray(const Camera *p_camera,const Point2& p_point, Vector3& r_pos, Vector3& r_normal,int *r_gizmo_handle=NULL,bool p_sec_first=false); + + void clear(); + void create(); + void transform(); + virtual void redraw(); + void free(); + + EditorSpatialGizmo(); + ~EditorSpatialGizmo(); +}; + + + +class LightSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(LightSpatialGizmo,EditorSpatialGizmo); + + Light* light; + +public: + + + virtual String get_handle_name(int p_idx) const; + virtual Variant get_handle_value(int p_idx) const; + virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); + virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); + + void redraw(); + LightSpatialGizmo(Light* p_light=NULL); + +}; + +class CameraSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(CameraSpatialGizmo,EditorSpatialGizmo); + + Camera* camera; + +public: + + + virtual String get_handle_name(int p_idx) const; + virtual Variant get_handle_value(int p_idx) const; + virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); + virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); + + void redraw(); + CameraSpatialGizmo(Camera* p_camera=NULL); + +}; + + + +class MeshInstanceSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(MeshInstanceSpatialGizmo,EditorSpatialGizmo); + + MeshInstance* mesh; + +public: + + void redraw(); + MeshInstanceSpatialGizmo(MeshInstance* p_mesh=NULL); + +}; + +class Position3DSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(Position3DSpatialGizmo,EditorSpatialGizmo); + + Position3D* p3d; + +public: + + void redraw(); + Position3DSpatialGizmo(Position3D* p_p3d=NULL); + +}; + +class SkeletonSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(SkeletonSpatialGizmo,EditorSpatialGizmo); + + Skeleton* skel; + +public: + + void redraw(); + SkeletonSpatialGizmo(Skeleton* p_skel=NULL); + +}; + + +class TestCubeSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(TestCubeSpatialGizmo,EditorSpatialGizmo); + + TestCube* tc; + +public: + void redraw(); + TestCubeSpatialGizmo(TestCube* p_tc=NULL); + +}; + + +class RoomSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(RoomSpatialGizmo,EditorSpatialGizmo); + + + struct _EdgeKey { + + Vector3 from; + Vector3 to; + + bool operator<(const _EdgeKey& p_with) const { return from==p_with.from ? to < p_with.to : from < p_with.from; } + }; + + + + Room* room; + +public: + + void redraw(); + RoomSpatialGizmo(Room* p_room=NULL); + +}; + + +class PortalSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(PortalSpatialGizmo,EditorSpatialGizmo); + + Portal* portal; + +public: + + void redraw(); + PortalSpatialGizmo(Portal* p_portal=NULL); + +}; + + +class VisibilityNotifierGizmo : public EditorSpatialGizmo { + + GDCLASS(VisibilityNotifierGizmo ,EditorSpatialGizmo); + + + VisibilityNotifier* notifier; + +public: + + virtual String get_handle_name(int p_idx) const; + virtual Variant get_handle_value(int p_idx) const; + virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); + virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); + + void redraw(); + VisibilityNotifierGizmo(VisibilityNotifier* p_notifier=NULL); + +}; + + +class ReflectionProbeGizmo : public EditorSpatialGizmo { + + GDCLASS(ReflectionProbeGizmo ,EditorSpatialGizmo); + + + ReflectionProbe* probe; + +public: + + virtual String get_handle_name(int p_idx) const; + virtual Variant get_handle_value(int p_idx) const; + virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); + virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); + + void redraw(); + ReflectionProbeGizmo(ReflectionProbe* p_notifier=NULL); + +}; + +class GIProbeGizmo : public EditorSpatialGizmo { + + GDCLASS(GIProbeGizmo ,EditorSpatialGizmo); + + + GIProbe* probe; + +public: + + virtual String get_handle_name(int p_idx) const; + virtual Variant get_handle_value(int p_idx) const; + virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); + virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); + + void redraw(); + GIProbeGizmo(GIProbe* p_notifier=NULL); + +}; + + +class CollisionShapeSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(CollisionShapeSpatialGizmo,EditorSpatialGizmo); + + CollisionShape* cs; + +public: + virtual String get_handle_name(int p_idx) const; + virtual Variant get_handle_value(int p_idx) const; + virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); + virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); + void redraw(); + CollisionShapeSpatialGizmo(CollisionShape* p_cs=NULL); + +}; + + +class CollisionPolygonSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(CollisionPolygonSpatialGizmo,EditorSpatialGizmo); + + CollisionPolygon* polygon; + +public: + + void redraw(); + CollisionPolygonSpatialGizmo(CollisionPolygon* p_polygon=NULL); + +}; + + + +class RayCastSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(RayCastSpatialGizmo,EditorSpatialGizmo); + + RayCast* raycast; + +public: + + void redraw(); + RayCastSpatialGizmo(RayCast* p_raycast=NULL); + +}; + + + +class VehicleWheelSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(VehicleWheelSpatialGizmo,EditorSpatialGizmo); + + VehicleWheel* car_wheel; + +public: + + void redraw(); + VehicleWheelSpatialGizmo(VehicleWheel* p_car_wheel=NULL); + +}; + + +class NavigationMeshSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(NavigationMeshSpatialGizmo,EditorSpatialGizmo); + + + struct _EdgeKey { + + Vector3 from; + Vector3 to; + + bool operator<(const _EdgeKey& p_with) const { return from==p_with.from ? to < p_with.to : from < p_with.from; } + }; + + + + NavigationMeshInstance* navmesh; + +public: + + void redraw(); + NavigationMeshSpatialGizmo(NavigationMeshInstance* p_navmesh=NULL); + +}; + + +class PinJointSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(PinJointSpatialGizmo,EditorSpatialGizmo); + + PinJoint* p3d; + +public: + + void redraw(); + PinJointSpatialGizmo(PinJoint* p_p3d=NULL); + +}; + + +class HingeJointSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(HingeJointSpatialGizmo,EditorSpatialGizmo); + + HingeJoint* p3d; + +public: + + void redraw(); + HingeJointSpatialGizmo(HingeJoint* p_p3d=NULL); + +}; + +class SliderJointSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(SliderJointSpatialGizmo,EditorSpatialGizmo); + + SliderJoint* p3d; + +public: + + void redraw(); + SliderJointSpatialGizmo(SliderJoint* p_p3d=NULL); + +}; + +class ConeTwistJointSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(ConeTwistJointSpatialGizmo,EditorSpatialGizmo); + + ConeTwistJoint* p3d; + +public: + + void redraw(); + ConeTwistJointSpatialGizmo(ConeTwistJoint* p_p3d=NULL); + +}; + + +class Generic6DOFJointSpatialGizmo : public EditorSpatialGizmo { + + GDCLASS(Generic6DOFJointSpatialGizmo,EditorSpatialGizmo); + + Generic6DOFJoint* p3d; + +public: + + void redraw(); + Generic6DOFJointSpatialGizmo(Generic6DOFJoint* p_p3d=NULL); + +}; + + +class SpatialEditorGizmos { +public: + + Ref<FixedSpatialMaterial> create_line_material(const Color& p_base_color); + Ref<FixedSpatialMaterial> create_solid_material(const Color& p_base_color); + Ref<FixedSpatialMaterial> handle2_material; + Ref<FixedSpatialMaterial> handle_material; + Ref<FixedSpatialMaterial> light_material; + Ref<FixedSpatialMaterial> light_material_omni_icon; + Ref<FixedSpatialMaterial> light_material_directional_icon; + Ref<FixedSpatialMaterial> camera_material; + Ref<FixedSpatialMaterial> skeleton_material; + Ref<FixedSpatialMaterial> reflection_probe_material; + Ref<FixedSpatialMaterial> reflection_probe_material_internal; + Ref<FixedSpatialMaterial> gi_probe_material; + Ref<FixedSpatialMaterial> gi_probe_material_internal; + Ref<FixedSpatialMaterial> room_material; + Ref<FixedSpatialMaterial> portal_material; + Ref<FixedSpatialMaterial> raycast_material; + Ref<FixedSpatialMaterial> visibility_notifier_material; + Ref<FixedSpatialMaterial> car_wheel_material; + Ref<FixedSpatialMaterial> joint_material; + + Ref<FixedSpatialMaterial> navmesh_edge_material; + Ref<FixedSpatialMaterial> navmesh_solid_material; + Ref<FixedSpatialMaterial> navmesh_edge_material_disabled; + Ref<FixedSpatialMaterial> navmesh_solid_material_disabled; + + Ref<FixedSpatialMaterial> listener_icon; + + Ref<FixedSpatialMaterial> sample_player_icon; + Ref<FixedSpatialMaterial> stream_player_icon; + Ref<FixedSpatialMaterial> visibility_notifier_icon; + + Ref<FixedSpatialMaterial> shape_material; + Ref<Texture> handle_t; + + Ref<Mesh> pos3d_mesh; + Ref<Mesh> listener_line_mesh; + static SpatialEditorGizmos *singleton; + + Ref<TriangleMesh> test_cube_tm; + + + Ref<SpatialEditorGizmo> get_gizmo(Spatial *p_spatial); + + SpatialEditorGizmos(); +}; +#endif // SPATIAL_EDITOR_GIZMOS_H diff --git a/editor/translations/Makefile b/editor/translations/Makefile new file mode 100644 index 0000000000..4f5d9f165f --- /dev/null +++ b/editor/translations/Makefile @@ -0,0 +1,20 @@ +# Makefile providing various facilities to manage translations + +TEMPLATE = editor.pot +POFILES = $(wildcard *.po) +LANGS = $(POFILES:%.po=%) + +all: update merge + +update: + @cd ../..; python2 editor/translations/extract.py + +merge: + @for po in $(POFILES); do \ + echo -e "\nMerging $$po..."; \ + msgmerge -w 79 -C $$po $$po $(TEMPLATE) > "$$po".new; \ + mv -f "$$po".new $$po; \ + done + +check: + @for po in $(POFILES); do msgfmt -c $$po -o /dev/null; done diff --git a/tools/editor/translations/README.md b/editor/translations/README.md index 351bc9e2d1..351bc9e2d1 100644 --- a/tools/editor/translations/README.md +++ b/editor/translations/README.md diff --git a/tools/editor/translations/ar.po b/editor/translations/ar.po index 539b94ab62..539b94ab62 100644 --- a/tools/editor/translations/ar.po +++ b/editor/translations/ar.po diff --git a/tools/editor/translations/bg.po b/editor/translations/bg.po index fe711e1b30..fe711e1b30 100644 --- a/tools/editor/translations/bg.po +++ b/editor/translations/bg.po diff --git a/tools/editor/translations/bn.po b/editor/translations/bn.po index 0b1993caa0..0b1993caa0 100644 --- a/tools/editor/translations/bn.po +++ b/editor/translations/bn.po diff --git a/tools/editor/translations/ca.po b/editor/translations/ca.po index c45cad964b..c45cad964b 100644 --- a/tools/editor/translations/ca.po +++ b/editor/translations/ca.po diff --git a/tools/editor/translations/cs.po b/editor/translations/cs.po index 3dc52fa536..3dc52fa536 100644 --- a/tools/editor/translations/cs.po +++ b/editor/translations/cs.po diff --git a/tools/editor/translations/da.po b/editor/translations/da.po index 6148d0b82d..6148d0b82d 100644 --- a/tools/editor/translations/da.po +++ b/editor/translations/da.po diff --git a/tools/editor/translations/de.po b/editor/translations/de.po index 0545ea2f21..0545ea2f21 100644 --- a/tools/editor/translations/de.po +++ b/editor/translations/de.po diff --git a/tools/editor/translations/de_CH.po b/editor/translations/de_CH.po index 0420d3fc97..0420d3fc97 100644 --- a/tools/editor/translations/de_CH.po +++ b/editor/translations/de_CH.po diff --git a/tools/editor/translations/tools.pot b/editor/translations/editor.pot index 8e54d88989..8e54d88989 100644 --- a/tools/editor/translations/tools.pot +++ b/editor/translations/editor.pot diff --git a/tools/editor/translations/es.po b/editor/translations/es.po index a1108822fa..a1108822fa 100644 --- a/tools/editor/translations/es.po +++ b/editor/translations/es.po diff --git a/tools/editor/translations/es_AR.po b/editor/translations/es_AR.po index d921254859..d921254859 100644 --- a/tools/editor/translations/es_AR.po +++ b/editor/translations/es_AR.po diff --git a/editor/translations/extract.py b/editor/translations/extract.py new file mode 100755 index 0000000000..616fec17a0 --- /dev/null +++ b/editor/translations/extract.py @@ -0,0 +1,121 @@ +#!/bin/python + +import fnmatch +import os +import shutil +import subprocess +import sys + + +line_nb = False + +for arg in sys.argv[1:]: + if (arg == "--with-line-nb"): + print("Enabling line numbers in the context locations.") + line_nb = True + else: + os.sys.exit("Non supported argument '" + arg + "'. Aborting.") + + +if (not os.path.exists("editor")): + os.sys.exit("ERROR: This script should be started from the root of the git repo.") + + +matches = [] +for root, dirnames, filenames in os.walk('.'): + for filename in fnmatch.filter(filenames, '*.cpp'): + if (filename.find("collada") != -1): + continue + matches.append(os.path.join(root, filename)) + for filename in fnmatch.filter(filenames, '*.h'): + if (filename.find("collada") != -1): + continue + matches.append(os.path.join(root, filename)) +matches.sort() + + +unique_str = [] +unique_loc = {} +main_po = """ +# LANGUAGE translation of the Godot Engine editor +# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community +# This file is distributed under the same license as the Godot source code. +# +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Godot Engine editor\\n" +"Content-Type: text/plain; charset=UTF-8\\n" +"Content-Transfer-Encoding: 8-bit\\n" +""" + +print("Updating the editor.pot template...") + +for fname in matches: + + f = open(fname, "rb") + + l = f.readline() + lc = 1 + while (l): + + patterns = ['RTR(\"', 'TTR(\"'] + idx = 0 + pos = 0 + while (pos >= 0): + pos = l.find(patterns[idx], pos) + if (pos == -1): + if (idx < len(patterns) - 1): + idx += 1 + pos = 0 + continue + pos += 5 + + msg = "" + while (pos < len(l) and (l[pos] != '"' or l[pos - 1] == '\\')): + msg += l[pos] + pos += 1 + + location = os.path.relpath(fname).replace('\\', '/') + if (line_nb): + location += ":" + str(lc) + + if (not msg in unique_str): + main_po += "\n#: " + location + "\n" + main_po += 'msgid "' + msg + '"\n' + main_po += 'msgstr ""\n' + unique_str.append(msg) + unique_loc[msg] = [location] + elif (not location in unique_loc[msg]): + # Add additional location to previous occurence too + msg_pos = main_po.find('\nmsgid "' + msg + '"') + if (msg_pos == -1): + print("Someone apparently thought writing Python was as easy as GDScript. Ping Akien.") + main_po = main_po[:msg_pos] + ' ' + location + main_po[msg_pos:] + unique_loc[msg].append(location) + + l = f.readline() + lc += 1 + + f.close() + + +f = open("editor.pot", "wb") +f.write(main_po) +f.close() + +if (os.name == "posix"): + print("Wrapping template at 79 characters for compatibility with Weblate.") + os.system("msgmerge -w79 editor.pot editor.pot > editor.pot.wrap") + shutil.move("editor.pot.wrap", "editor.pot") + +shutil.move("editor.pot", "editor/translations/editor.pot") + +# TODO: Make that in a portable way, if we care; if not, kudos to Unix users +if (os.name == "posix"): + added = subprocess.check_output("git diff editor/translations/editor.pot | grep \+msgid | wc -l", shell=True) + removed = subprocess.check_output("git diff editor/translations/editor.pot | grep \\\-msgid | wc -l", shell=True) + print("\n# Template changes compared to the staged status:") + print("# Additions: %s msgids.\n# Deletions: %s msgids." % (int(added), int(removed))) diff --git a/tools/editor/translations/fa.po b/editor/translations/fa.po index 41a686ba52..41a686ba52 100644 --- a/tools/editor/translations/fa.po +++ b/editor/translations/fa.po diff --git a/tools/editor/translations/fr.po b/editor/translations/fr.po index 2c4f7144fe..2c4f7144fe 100644 --- a/tools/editor/translations/fr.po +++ b/editor/translations/fr.po diff --git a/tools/editor/translations/hu.po b/editor/translations/hu.po index 335ab25c6a..335ab25c6a 100644 --- a/tools/editor/translations/hu.po +++ b/editor/translations/hu.po diff --git a/tools/editor/translations/id.po b/editor/translations/id.po index 30bd357a21..30bd357a21 100644 --- a/tools/editor/translations/id.po +++ b/editor/translations/id.po diff --git a/tools/editor/translations/it.po b/editor/translations/it.po index 8fefe67677..8fefe67677 100644 --- a/tools/editor/translations/it.po +++ b/editor/translations/it.po diff --git a/tools/editor/translations/ja.po b/editor/translations/ja.po index ea314db101..ea314db101 100644 --- a/tools/editor/translations/ja.po +++ b/editor/translations/ja.po diff --git a/tools/editor/translations/ko.po b/editor/translations/ko.po index a0ecb70bf5..a0ecb70bf5 100644 --- a/tools/editor/translations/ko.po +++ b/editor/translations/ko.po diff --git a/tools/editor/translations/nb.po b/editor/translations/nb.po index cbd2a09951..cbd2a09951 100644 --- a/tools/editor/translations/nb.po +++ b/editor/translations/nb.po diff --git a/tools/editor/translations/pl.po b/editor/translations/pl.po index 50afecad1b..50afecad1b 100644 --- a/tools/editor/translations/pl.po +++ b/editor/translations/pl.po diff --git a/tools/editor/translations/pr.po b/editor/translations/pr.po index 8ea2967a22..8ea2967a22 100644 --- a/tools/editor/translations/pr.po +++ b/editor/translations/pr.po diff --git a/tools/editor/translations/pt_BR.po b/editor/translations/pt_BR.po index 9ab81786b1..9ab81786b1 100644 --- a/tools/editor/translations/pt_BR.po +++ b/editor/translations/pt_BR.po diff --git a/tools/editor/translations/pt_PT.po b/editor/translations/pt_PT.po index da9d971347..da9d971347 100644 --- a/tools/editor/translations/pt_PT.po +++ b/editor/translations/pt_PT.po diff --git a/tools/editor/translations/ru.po b/editor/translations/ru.po index 0595a675b3..0595a675b3 100644 --- a/tools/editor/translations/ru.po +++ b/editor/translations/ru.po diff --git a/tools/editor/translations/sk.po b/editor/translations/sk.po index 6aa2e16664..6aa2e16664 100644 --- a/tools/editor/translations/sk.po +++ b/editor/translations/sk.po diff --git a/tools/editor/translations/sl.po b/editor/translations/sl.po index 4934be97d7..4934be97d7 100644 --- a/tools/editor/translations/sl.po +++ b/editor/translations/sl.po diff --git a/tools/editor/translations/tr.po b/editor/translations/tr.po index 5c0b6ebca8..5c0b6ebca8 100644 --- a/tools/editor/translations/tr.po +++ b/editor/translations/tr.po diff --git a/tools/editor/translations/ur_PK.po b/editor/translations/ur_PK.po index b898301d0c..b898301d0c 100644 --- a/tools/editor/translations/ur_PK.po +++ b/editor/translations/ur_PK.po diff --git a/tools/editor/translations/zh_CN.po b/editor/translations/zh_CN.po index 47c77f6170..47c77f6170 100644 --- a/tools/editor/translations/zh_CN.po +++ b/editor/translations/zh_CN.po diff --git a/tools/editor/translations/zh_HK.po b/editor/translations/zh_HK.po index b0bb11d527..b0bb11d527 100644 --- a/tools/editor/translations/zh_HK.po +++ b/editor/translations/zh_HK.po diff --git a/tools/editor/translations/zh_TW.po b/editor/translations/zh_TW.po index 3e9b61ec0f..3e9b61ec0f 100644 --- a/tools/editor/translations/zh_TW.po +++ b/editor/translations/zh_TW.po diff --git a/main/main.cpp b/main/main.cpp index fb7f2ebceb..32aea6a4a5 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -54,9 +54,9 @@ #include "scene/main/viewport.h" #ifdef TOOLS_ENABLED -#include "tools/editor/doc/doc_data.h" -#include "tools/editor/editor_node.h" -#include "tools/editor/project_manager.h" +#include "editor/doc/doc_data.h" +#include "editor/editor_node.h" +#include "editor/project_manager.h" #endif #include "io/file_access_network.h" diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index db47ee43ce..d1d69c6709 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -41,10 +41,10 @@ ResourceFormatSaverGDScript *resource_saver_gd=NULL; #if 0 #ifdef TOOLS_ENABLED -#include "tools/editor/editor_import_export.h" +#include "editor/editor_import_export.h" #include "gd_tokenizer.h" -#include "tools/editor/editor_node.h" -#include "tools/editor/editor_settings.h" +#include "editor/editor_node.h" +#include "editor/editor_settings.h" class EditorExportGDScript : public EditorExportPlugin { diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 2630360058..a5d2f84c68 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -27,9 +27,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "grid_map_editor_plugin.h" -#include "tools/editor/plugins/spatial_editor_plugin.h" +#include "editor/plugins/spatial_editor_plugin.h" #include "scene/3d/camera.h" -#include "tools/editor/editor_settings.h" +#include "editor/editor_settings.h" #include "os/keyboard.h" #include "geometry.h" diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h index 66ec5dc4bc..07ac34cd4e 100644 --- a/modules/gridmap/grid_map_editor_plugin.h +++ b/modules/gridmap/grid_map_editor_plugin.h @@ -29,10 +29,10 @@ #ifndef GRID_MAP_EDITOR_PLUGIN_H #define GRID_MAP_EDITOR_PLUGIN_H -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" +#include "editor/editor_plugin.h" +#include "editor/editor_node.h" #include "grid_map.h" -#include "tools/editor/pane_drag.h" +#include "editor/pane_drag.h" /** @author Juan Linietsky <reduzio@gmail.com> */ diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index eadc9a8892..3f5ba63b98 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -1,11 +1,11 @@ #include "visual_script_editor.h" -#include "tools/editor/editor_node.h" +#include "editor/editor_node.h" #include "visual_script_nodes.h" #include "visual_script_flow_control.h" #include "visual_script_func_nodes.h" #include "visual_script_expression.h" #include "os/input.h" -#include "tools/editor/editor_resource_preview.h" +#include "editor/editor_resource_preview.h" #include "os/keyboard.h" #ifdef TOOLS_ENABLED diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index 1dc62b3e69..df3aa20d39 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -1,12 +1,12 @@ #ifndef VisualSCRIPT_EDITOR_H #define VisualSCRIPT_EDITOR_H -#include "tools/editor/plugins/script_editor_plugin.h" +#include "editor/plugins/script_editor_plugin.h" #include "visual_script.h" -#include "tools/editor/property_editor.h" +#include "editor/property_editor.h" #include "scene/gui/graph_edit.h" -#include "tools/editor/create_dialog.h" -#include "tools/editor/property_selector.h" +#include "editor/create_dialog.h" +#include "editor/property_selector.h" class VisualScriptEditorSignalEdit; class VisualScriptEditorVariableEdit; diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 1d1ee25622..3fc822860d 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -28,9 +28,9 @@ /*************************************************************************/ #include "version.h" #include "export.h" -#include "tools/editor/editor_settings.h" -#include "tools/editor/editor_export.h" -#include "tools/editor/editor_node.h" +#include "editor/editor_settings.h" +#include "editor/editor_export.h" +#include "editor/editor_node.h" #include "io/zip_io.h" #include "io/marshalls.h" #include "global_config.h" diff --git a/platform/bb10/export/export.cpp b/platform/bb10/export/export.cpp index 2643c96576..cf8e2fcc0a 100644 --- a/platform/bb10/export/export.cpp +++ b/platform/bb10/export/export.cpp @@ -28,9 +28,9 @@ /*************************************************************************/ #include "version.h" #include "export.h" -#include "tools/editor/editor_settings.h" -#include "tools/editor/editor_export.h" -#include "tools/editor/editor_node.h" +#include "editor/editor_settings.h" +#include "editor/editor_export.h" +#include "editor/editor_node.h" #include "io/zip_io.h" #include "io/marshalls.h" #include "global_config.h" diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 2657eaddb5..b9ef63fe2f 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -28,9 +28,9 @@ /*************************************************************************/ #include "version.h" #include "export.h" -#include "tools/editor/editor_settings.h" -#include "tools/editor/editor_export.h" -#include "tools/editor/editor_node.h" +#include "editor/editor_settings.h" +#include "editor/editor_export.h" +#include "editor/editor_node.h" #include "io/zip_io.h" #include "io/marshalls.h" #include "global_config.h" diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index 69973dc95d..4af2aaca63 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -28,9 +28,9 @@ /*************************************************************************/ #include "version.h" #include "export.h" -#include "tools/editor/editor_settings.h" -#include "tools/editor/editor_export.h" -#include "tools/editor/editor_node.h" +#include "editor/editor_settings.h" +#include "editor/editor_export.h" +#include "editor/editor_node.h" #include "io/zip_io.h" #include "io/marshalls.h" #include "io/resource_saver.h" diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index 4966489188..52a22a1942 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -69,8 +69,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "version.h" #include "export.h" #include "object.h" -#include "tools/editor/editor_import_export.h" -#include "tools/editor/editor_node.h" +#include "editor/editor_import_export.h" +#include "editor/editor_node.h" #include "platform/uwp/logo.h" #include "os/file_access.h" #include "io/zip.h" diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index 1c827a93b0..44c0acdb2e 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -28,7 +28,7 @@ /*************************************************************************/ #include "export.h" #include "platform/windows/logo.h" -#include "tools/editor/editor_export.h" +#include "editor/editor_export.h" void register_windows_exporter() { diff --git a/platform/x11/export/export.cpp b/platform/x11/export/export.cpp index 5c7f98c1f3..c40b8f3c1f 100644 --- a/platform/x11/export/export.cpp +++ b/platform/x11/export/export.cpp @@ -28,7 +28,7 @@ /*************************************************************************/ #include "export.h" #include "platform/x11/logo.h" -#include "tools/editor/editor_export.h" +#include "editor/editor_export.h" #include "scene/resources/texture.h" diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 4161725ad5..496b1e03cf 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -40,7 +40,7 @@ #include "scene/gui/panel.h" #include "scene/gui/label.h" #ifdef TOOLS_ENABLED -#include "tools/editor/editor_settings.h" +#include "editor/editor_settings.h" #endif #include <stdio.h> diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 893670efea..7f61cf80ec 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -33,7 +33,7 @@ #include "label.h" #include "translation.h" #ifdef TOOLS_ENABLED -#include "tools/editor/editor_settings.h" +#include "editor/editor_settings.h" #endif static bool _is_text_char(CharType c) { diff --git a/tools/editor/SCsub b/tools/editor/SCsub deleted file mode 100644 index c9b2392eb2..0000000000 --- a/tools/editor/SCsub +++ /dev/null @@ -1,205 +0,0 @@ -#!/usr/bin/env python - -Import('env') -env.editor_sources = [] - -import os - - -def make_certs_header(target, source, env): - - src = source[0].srcnode().abspath - dst = target[0].srcnode().abspath - f = open(src, "rb") - g = open(dst, "wb") - buf = f.read() - decomp_size = len(buf) - import zlib - buf = zlib.compress(buf) - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _CERTS_RAW_H\n") - g.write("#define _CERTS_RAW_H\n") - g.write("static const int _certs_compressed_size=" + str(len(buf)) + ";\n") - g.write("static const int _certs_uncompressed_size=" + str(decomp_size) + ";\n") - g.write("static const unsigned char _certs_compressed[]={\n") - for i in range(len(buf)): - g.write(str(ord(buf[i])) + ",\n") - g.write("};\n") - g.write("#endif") - - -def make_doc_header(target, source, env): - - dst = target[0].srcnode().abspath - g = open(dst, "wb") - buf = "" - docbegin = "" - docend = "" - for s in source: - src = s.srcnode().abspath - f = open(src, "rb") - content = f.read() - buf += content[content.find("<class"): content.rfind("</doc>")] - if len(docbegin) == 0: - docbegin = content[0: content.find("<class")] - if len(docend) == 0: - docend = content[content.rfind("</doc>"): len(buf)] - buf = docbegin + buf + docend - decomp_size = len(buf) - import zlib - buf = zlib.compress(buf) - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _DOC_DATA_RAW_H\n") - g.write("#define _DOC_DATA_RAW_H\n") - g.write("static const int _doc_data_compressed_size=" + str(len(buf)) + ";\n") - g.write("static const int _doc_data_uncompressed_size=" + str(decomp_size) + ";\n") - g.write("static const unsigned char _doc_data_compressed[]={\n") - for i in range(len(buf)): - g.write(str(ord(buf[i])) + ",\n") - g.write("};\n") - g.write("#endif") - - -def make_fonts_header(target, source, env): - - dst = target[0].srcnode().abspath - - g = open(dst, "wb") - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _EDITOR_FONTS_H\n") - g.write("#define _EDITOR_FONTS_H\n") - - # saving uncompressed, since freetype will reference from memory pointer - xl_names = [] - for i in range(len(source)): - print("Appending font: " + source[i].srcnode().abspath) - f = open(source[i].srcnode().abspath, "rb") - buf = f.read() - import os.path - - name = os.path.splitext(os.path.basename(source[i].srcnode().abspath))[0] - - g.write("static const int _font_" + name + "_size=" + str(len(buf)) + ";\n") - g.write("static const unsigned char _font_" + name + "[]={\n") - for i in range(len(buf)): - g.write(str(ord(buf[i])) + ",\n") - - g.write("};\n") - - g.write("#endif") - - -def make_translations_header(target, source, env): - - dst = target[0].srcnode().abspath - - g = open(dst, "wb") - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _EDITOR_TRANSLATIONS_H\n") - g.write("#define _EDITOR_TRANSLATIONS_H\n") - - import zlib - import os.path - - paths = [node.srcnode().abspath for node in source] - sorted_paths = sorted(paths, key=lambda path: os.path.splitext(os.path.basename(path))[0]) - - xl_names = [] - for i in range(len(sorted_paths)): - print("Appending translation: " + sorted_paths[i]) - f = open(sorted_paths[i], "rb") - buf = f.read() - decomp_size = len(buf) - buf = zlib.compress(buf) - name = os.path.splitext(os.path.basename(sorted_paths[i]))[0] - - #g.write("static const int _translation_"+name+"_compressed_size="+str(len(buf))+";\n") - #g.write("static const int _translation_"+name+"_uncompressed_size="+str(decomp_size)+";\n") - g.write("static const unsigned char _translation_" + name + "_compressed[]={\n") - for i in range(len(buf)): - g.write(str(ord(buf[i])) + ",\n") - - g.write("};\n") - - xl_names.append([name, len(buf), str(decomp_size)]) - - g.write("struct EditorTranslationList {\n") - g.write("\tconst char* lang;\n") - g.write("\tint comp_size;\n") - g.write("\tint uncomp_size;\n") - g.write("\tconst unsigned char* data;\n") - g.write("};\n\n") - g.write("static EditorTranslationList _editor_translations[]={\n") - for x in xl_names: - g.write("\t{ \"" + x[0] + "\", " + str(x[1]) + ", " + str(x[2]) + ",_translation_" + x[0] + "_compressed},\n") - g.write("\t{NULL,0,0,NULL}\n") - g.write("};\n") - - g.write("#endif") - - -if (env["tools"] == "yes"): - - # Register exporters - reg_exporters_inc = '#include "register_exporters.h"\n' - reg_exporters = 'void register_exporters() {\n' - for e in env.platform_exporters: - env.editor_sources.append("#platform/" + e + "/export/export.cpp") - reg_exporters += '\tregister_' + e + '_exporter();\n' - reg_exporters_inc += '#include "platform/' + e + '/export/export.h"\n' - reg_exporters += '}\n' - f = open("register_exporters.cpp", "wb") - f.write(reg_exporters_inc) - f.write(reg_exporters) - f.close() - - # API documentation - docs = ["#doc/base/classes.xml"] - moduledir = os.path.join(os.getcwd(), "..", "..", "modules") - for m in os.listdir(moduledir): - curmodle = os.path.join(moduledir, m) - docfile = os.path.join(curmodle, "classes.xml") - if os.path.isdir(curmodle) and os.path.isfile(docfile): - docs.append(docfile) - env.Depends("#tools/editor/doc_data_compressed.h", docs) - env.Command("#tools/editor/doc_data_compressed.h", docs, make_doc_header) - - # Certificates - env.Depends("#tools/editor/certs_compressed.h", "#thirdparty/certs/ca-certificates.crt") - env.Command("#tools/editor/certs_compressed.h", "#thirdparty/certs/ca-certificates.crt", make_certs_header) - - import glob - path = env.Dir('.').abspath - - # Translations - tlist = glob.glob(path + "/translations/*.po") - print("translations: ", tlist) - env.Depends('#tools/editor/translations.h', tlist) - env.Command('#tools/editor/translations.h', tlist, make_translations_header) - - # Fonts - flist = glob.glob(path + "/../../thirdparty/fonts/*.ttf") - flist.append(glob.glob(path + "/../../thirdparty/fonts/*.otf")) - print("fonts: ", flist) - env.Depends('#tools/editor/builtin_fonts.h', flist) - env.Command('#tools/editor/builtin_fonts.h', flist, make_fonts_header) - - - env.add_source_files(env.editor_sources, "*.cpp") - - SConscript('collada/SCsub') - SConscript('doc/SCsub') - SConscript('fileserver/SCsub') - SConscript('icons/SCsub') - SConscript('import/SCsub') - SConscript('io_plugins/SCsub') - SConscript('plugins/SCsub') - - lib = env.Library("editor", env.editor_sources) - env.Prepend(LIBS=[lib]) - - Export('env') diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp deleted file mode 100644 index d675c6a6bb..0000000000 --- a/tools/editor/animation_editor.cpp +++ /dev/null @@ -1,4331 +0,0 @@ -/*************************************************************************/ -/* animation_editor.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 "animation_editor.h" - -#include "editor_settings.h" -#include "os/keyboard.h" -#include "os/os.h" -#include "io/resource_saver.h" -#include "pair.h" -#include "scene/gui/separator.h" -#include "editor_node.h" -#include "tools/editor/plugins/animation_player_editor_plugin.h" -#include "scene/main/viewport.h" -/* Missing to fix: - - *Set - *Find better source for hint for edited value keys - * + button on track to add a key - * when clicked for first time, erase selection of not selected at first - * automatically create discrete/continuous tracks!! - *when create track do undo/redo -*/ - - -class AnimationCurveEdit : public Control { - GDCLASS( AnimationCurveEdit, Control ); -public: - enum Mode { - MODE_DISABLED, - MODE_SINGLE, - MODE_MULTIPLE - }; -private: - - Set<float> multiples; - float transition; - Mode mode; - - void _notification(int p_what) { - - if (p_what==NOTIFICATION_DRAW) { - - - RID ci = get_canvas_item(); - - Size2 s = get_size(); - Rect2 r(Point2(),s); - - //r=r.grow(3); - Ref<StyleBox> sb = get_stylebox("normal","LineEdit"); - sb->draw(ci,r); - r.size-=sb->get_minimum_size(); - r.pos+=sb->get_offset(); - //VisualServer::get_singleton()->canvas_item_add - - Ref<Font> f = get_font("font","Label"); - r=r.grow(-2); - Color color = get_color("font_color","Label"); - - int points = 48; - if (mode==MODE_MULTIPLE) { - - Color mcolor=color; - mcolor.a*=0.3; - - Set<float>::Element *E=multiples.front(); - for(int j=0;j<16;j++) { - - if (!E) - break; - - float prev=1.0; - float exp=E->get(); - bool flip=false;//hint_text=="attenuation"; - - - for(int i=1;i<=points;i++) { - - float ifl = i/float(points); - float iflp = (i-1)/float(points); - - float h = 1.0-Math::ease(ifl,exp); - - if (flip) { - ifl=1.0-ifl; - iflp=1.0-iflp; - } - - VisualServer::get_singleton()->canvas_item_add_line(ci,r.pos+Point2(iflp*r.size.width,prev*r.size.height),r.pos+Point2(ifl*r.size.width,h*r.size.height),mcolor); - prev=h; - } - - E=E->next(); - } - } - - float exp=transition; - if (mode!=MODE_DISABLED) { - - - float prev=1.0; - - bool flip=false;//hint_text=="attenuation"; - - - for(int i=1;i<=points;i++) { - - float ifl = i/float(points); - float iflp = (i-1)/float(points); - - float h = 1.0-Math::ease(ifl,exp); - - if (flip) { - ifl=1.0-ifl; - iflp=1.0-iflp; - } - - VisualServer::get_singleton()->canvas_item_add_line(ci,r.pos+Point2(iflp*r.size.width,prev*r.size.height),r.pos+Point2(ifl*r.size.width,h*r.size.height),color); - prev=h; - } - } - - String txt=String::num(exp,2); - if (mode==MODE_DISABLED) { - txt=TTR("Disabled"); - } else if (mode==MODE_MULTIPLE) { - txt+=" - "+TTR("All Selection"); - } - - f->draw(ci,Point2(10,10+f->get_ascent()),txt,color); - - } - } - - void _gui_input(const InputEvent& p_ev) { - if (p_ev.type==InputEvent::MOUSE_MOTION && p_ev.mouse_motion.button_mask&BUTTON_MASK_LEFT) { - - if (mode==MODE_DISABLED) - return; - - float rel = p_ev.mouse_motion.relative_x; - if (rel==0) - return; - - bool flip=false; - - if (flip) - rel=-rel; - - float val = transition; - if (val==0) - return; - bool sg = val < 0; - val = Math::absf(val); - - val = Math::log(val)/Math::log((float)2.0); - //logspace - val+=rel*0.05; - // - - val = Math::pow((float)2.0,val); - if (sg) - val=-val; - - transition=val; - update(); - //emit_signal("variant_changed"); - emit_signal("transition_changed",transition); - } - } - -public: - - static void _bind_methods() { - - //ClassDB::bind_method("_update_obj",&AnimationKeyEdit::_update_obj); - ClassDB::bind_method("_gui_input",&AnimationCurveEdit::_gui_input); - ADD_SIGNAL(MethodInfo("transition_changed")); - } - - void set_mode(Mode p_mode) { - - mode=p_mode; - update(); - } - - void clear_multiples() { multiples.clear(); update();} - void set_multiple(float p_transition) { - - multiples.insert(p_transition); - } - - void set_transition(float p_transition) { - transition=p_transition; - update(); - } - - float get_transition() const { - return transition; - } - - void force_transition(float p_value) { - if (mode==MODE_DISABLED) - return; - transition=p_value; - emit_signal("transition_changed",p_value); - update(); - } - - AnimationCurveEdit() { - - transition=1.0; - set_default_cursor_shape(CURSOR_HSPLIT); - mode=MODE_DISABLED; - } - -}; - -class AnimationKeyEdit : public Object { - - GDCLASS(AnimationKeyEdit,Object); -public: - bool setting; - bool hidden; - - static void _bind_methods() { - - ClassDB::bind_method("_update_obj",&AnimationKeyEdit::_update_obj); - ClassDB::bind_method("_key_ofs_changed",&AnimationKeyEdit::_key_ofs_changed); - } - - //PopupDialog *ke_dialog; - - void _fix_node_path(Variant &value) { - - - NodePath np=value; - - if (np==NodePath()) - return; - - Node* root = EditorNode::get_singleton()->get_tree()->get_root(); - - Node* np_node = root->get_node(np); - ERR_FAIL_COND(!np_node); - - Node* edited_node = root->get_node(base); - ERR_FAIL_COND(!edited_node); - - - - value = edited_node->get_path_to(np_node); - } - - - void _update_obj(const Ref<Animation> &p_anim) { - if (setting) - return; - if (hidden) - return; - if (!(animation==p_anim)) - return; - notify_change(); - } - - void _key_ofs_changed(const Ref<Animation> &p_anim,float from, float to) { - if (hidden) - return; - if (!(animation==p_anim)) - return; - if (from!=key_ofs) - return; - key_ofs=to; - if (setting) - return; - notify_change(); - } - - bool _set(const StringName& p_name, const Variant& p_value) { - - int key = animation->track_find_key(track,key_ofs,true); - ERR_FAIL_COND_V(key==-1,false); - - String name=p_name; - if (name=="time") { - - float new_time = p_value; - if (new_time==key_ofs) - return true; - - int existing = animation->track_find_key(track,new_time,true); - - setting=true; - undo_redo->create_action(TTR("Move Add Key"),UndoRedo::MERGE_ENDS); - - Variant val = animation->track_get_key_value(track,key); - float trans = animation->track_get_key_transition(track,key); - - undo_redo->add_do_method(animation.ptr(),"track_remove_key",track,key); - undo_redo->add_do_method(animation.ptr(),"track_insert_key",track,new_time,val,trans); - undo_redo->add_do_method(this,"_key_ofs_changed",animation,key_ofs,new_time); - undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",track,new_time); - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",track,key_ofs,val,trans); - undo_redo->add_undo_method(this,"_key_ofs_changed",animation,new_time,key_ofs); - - - if (existing!=-1) { - Variant v = animation->track_get_key_value(track,existing); - float trans = animation->track_get_key_transition(track,existing); - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",track,new_time,v,trans); - } - - undo_redo->commit_action(); - setting=false; - - return true; - } else if (name=="easing") { - - float val = p_value; - float prev_val = animation->track_get_key_transition(track,key); - setting=true; - undo_redo->create_action(TTR("Anim Change Transition"),UndoRedo::MERGE_ENDS); - undo_redo->add_do_method(animation.ptr(),"track_set_key_transition",track,key,val); - undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",track,key,prev_val); - undo_redo->add_do_method(this,"_update_obj",animation); - undo_redo->add_undo_method(this,"_update_obj",animation); - undo_redo->commit_action(); - setting=false; - return true; - } - - - - switch(animation->track_get_type(track)) { - - - case Animation::TYPE_TRANSFORM: { - - Dictionary d_old = animation->track_get_key_value(track,key); - Dictionary d_new = d_old; - d_new[p_name]=p_value; - setting=true; - undo_redo->create_action(TTR("Anim Change Transform")); - undo_redo->add_do_method(animation.ptr(),"track_set_key_value",track,key,d_new); - undo_redo->add_undo_method(animation.ptr(),"track_set_key_value",track,key,d_old); - undo_redo->add_do_method(this,"_update_obj",animation); - undo_redo->add_undo_method(this,"_update_obj",animation); - undo_redo->commit_action(); - setting=false; - return true; - - } break; - case Animation::TYPE_VALUE: { - - if (name=="value") { - - Variant value = p_value; - - if (value.get_type()==Variant::NODE_PATH) { - - _fix_node_path(value); - } - - setting=true; - undo_redo->create_action(TTR("Anim Change Value"),UndoRedo::MERGE_ENDS); - Variant prev = animation->track_get_key_value(track,key); - undo_redo->add_do_method(animation.ptr(),"track_set_key_value",track,key,value); - undo_redo->add_undo_method(animation.ptr(),"track_set_key_value",track,key,prev); - undo_redo->add_do_method(this,"_update_obj",animation); - undo_redo->add_undo_method(this,"_update_obj",animation); - undo_redo->commit_action(); - setting=false; - return true; - } - - - - } break; - case Animation::TYPE_METHOD: { - - Dictionary d_old = animation->track_get_key_value(track,key); - Dictionary d_new = d_old; - - bool change_notify_deserved=false; - bool mergeable=false; - - if (name=="name") { - - d_new["method"]=p_value; - - } - - if (name=="arg_count") { - - Vector<Variant> args = d_old["args"]; - args.resize(p_value); - d_new["args"]=args; - change_notify_deserved=true; - } - - if (name.begins_with("args/")) { - - - Vector<Variant> args = d_old["args"]; - int idx = name.get_slice("/",1).to_int(); - ERR_FAIL_INDEX_V(idx,args.size(),false); - - String what = name.get_slice("/",2); - if (what=="type") { - Variant::Type t = Variant::Type(int(p_value)); - - if (t!=args[idx].get_type()) { - Variant::CallError err; - if (Variant::can_convert(args[idx].get_type(),t)) { - Variant old=args[idx]; - Variant *ptrs[1]={&old}; - args[idx]=Variant::construct(t,(const Variant**)ptrs,1,err); - } else { - - args[idx]=Variant::construct(t,NULL,0,err); - } - change_notify_deserved=true; - d_new["args"]=args; - } - - } - if (what=="value") { - - Variant value=p_value; - if (value.get_type()==Variant::NODE_PATH) { - - _fix_node_path(value); - } - - args[idx]=value; - d_new["args"]=args; - mergeable=true; - } - } - - if (mergeable) - undo_redo->create_action(TTR("Anim Change Call"),UndoRedo::MERGE_ENDS); - else - undo_redo->create_action(TTR("Anim Change Call")); - - Variant prev = animation->track_get_key_value(track,key); - setting=true; - undo_redo->add_do_method(animation.ptr(),"track_set_key_value",track,key,d_new); - undo_redo->add_undo_method(animation.ptr(),"track_set_key_value",track,key,d_old); - undo_redo->add_do_method(this,"_update_obj",animation); - undo_redo->add_undo_method(this,"_update_obj",animation); - undo_redo->commit_action(); - setting=false; - if (change_notify_deserved) - notify_change(); - return true; - } break; - } - - - - return false; - - } - - bool _get(const StringName& p_name,Variant &r_ret) const { - - int key = animation->track_find_key(track,key_ofs,true); - ERR_FAIL_COND_V(key==-1,false); - - String name=p_name; - if (name=="time") { - r_ret = key_ofs; - return true; - } else if (name=="easing") { - r_ret = animation->track_get_key_transition(track,key); - return true; - } - - - - switch(animation->track_get_type(track)) { - - - case Animation::TYPE_TRANSFORM: { - - Dictionary d = animation->track_get_key_value(track,key); - ERR_FAIL_COND_V(!d.has(name),false); - r_ret = d[p_name]; - return true; - - } break; - case Animation::TYPE_VALUE: { - - if (name=="value") { - r_ret = animation->track_get_key_value(track,key); - return true; - } - - - - } break; - case Animation::TYPE_METHOD: { - - Dictionary d = animation->track_get_key_value(track,key); - - if (name=="name") { - - ERR_FAIL_COND_V(!d.has("method"),false); - r_ret=d["method"]; - return true; - } - - ERR_FAIL_COND_V(!d.has("args"),false); - - Vector<Variant> args = d["args"]; - - - if (name=="arg_count") { - - r_ret=args.size(); - return true; - } - - - if (name.begins_with("args/")) { - - int idx = name.get_slice("/",1).to_int(); - ERR_FAIL_INDEX_V(idx,args.size(),false); - - String what = name.get_slice("/",2); - if (what=="type") { - r_ret=args[idx].get_type(); - return true; - } - if (what=="value") { - r_ret=args[idx]; - return true; - } - } - - } break; - } - - return false; - } - void _get_property_list( List<PropertyInfo> *p_list) const { - - if (animation.is_null()) - return; - - ERR_FAIL_INDEX(track,animation->get_track_count()); - int key = animation->track_find_key(track,key_ofs,true); - ERR_FAIL_COND(key==-1); - - p_list->push_back( PropertyInfo( Variant::REAL, "time", PROPERTY_HINT_RANGE,"0,"+rtos(animation->get_length())+",0.01") ); - - switch(animation->track_get_type(track)) { - - - case Animation::TYPE_TRANSFORM: { - - p_list->push_back( PropertyInfo( Variant::VECTOR3, "loc")); - p_list->push_back( PropertyInfo( Variant::QUAT, "rot")); - p_list->push_back( PropertyInfo( Variant::VECTOR3, "scale")); - - } break; - case Animation::TYPE_VALUE: { - - Variant v = animation->track_get_key_value(track,key); - - - - if (hint.type!=Variant::NIL) { - - PropertyInfo pi=hint; - pi.name="value"; - p_list->push_back( pi ); - } else { - - PropertyHint hint= PROPERTY_HINT_NONE; - String hint_string; - - if (v.get_type()==Variant::OBJECT) { - //could actually check the object property if exists..? yes i will! - Ref<Resource> res = v; - if (res.is_valid()) { - - hint=PROPERTY_HINT_RESOURCE_TYPE; - hint_string=res->get_class(); - } - } - - if (v.get_type()!=Variant::NIL) - p_list->push_back( PropertyInfo( v.get_type(), "value", hint,hint_string)); - } - - } break; - case Animation::TYPE_METHOD: { - - p_list->push_back( PropertyInfo( Variant::STRING, "name")); - p_list->push_back( PropertyInfo( Variant::INT, "arg_count",PROPERTY_HINT_RANGE,"0,5,1")); - - Dictionary d = animation->track_get_key_value(track,key); - ERR_FAIL_COND(!d.has("args")); - Vector<Variant> args=d["args"]; - String vtypes; - for(int i=0;i<Variant::VARIANT_MAX;i++) { - - if (i>0) - vtypes+=","; - vtypes+=Variant::get_type_name( Variant::Type(i) ); - } - - for(int i=0;i<args.size();i++) { - - p_list->push_back( PropertyInfo( Variant::INT, "args/"+itos(i)+"/type", PROPERTY_HINT_ENUM,vtypes)); - if (args[i].get_type()!=Variant::NIL) - p_list->push_back( PropertyInfo( args[i].get_type(), "args/"+itos(i)+"/value")); - } - - } break; - } - - /* - if (animation->track_get_type(track)!=Animation::TYPE_METHOD) - p_list->push_back( PropertyInfo( Variant::REAL, "easing", PROPERTY_HINT_EXP_EASING)); - */ - } - - UndoRedo *undo_redo; - Ref<Animation> animation; - int track; - float key_ofs; - - PropertyInfo hint; - NodePath base; - - - void notify_change() { - - _change_notify(); - } - - AnimationKeyEdit() { hidden=true; key_ofs=0; track=-1; setting=false; } - -}; - - -void AnimationKeyEditor::_menu_add_track(int p_type) { - - ERR_FAIL_COND(!animation.is_valid()); - - - switch(p_type) { - - case ADD_TRACK_MENU_ADD_CALL_TRACK: { - if (root) { - call_select->popup_centered_ratio(); - break; - } - } break; - case ADD_TRACK_MENU_ADD_VALUE_TRACK: - case ADD_TRACK_MENU_ADD_TRANSFORM_TRACK: { - - undo_redo->create_action(TTR("Anim Add Track")); - undo_redo->add_do_method(animation.ptr(),"add_track",p_type); - undo_redo->add_do_method(animation.ptr(),"track_set_path",animation->get_track_count(),"."); - undo_redo->add_undo_method(animation.ptr(),"remove_track",animation->get_track_count()); - undo_redo->commit_action(); - - - } break; - } -} - -void AnimationKeyEditor::_anim_duplicate_keys(bool transpose) { - //duplicait! - if (selection.size() && animation.is_valid() && selected_track>=0 && selected_track<animation->get_track_count()) { - - int top_track=0x7FFFFFFF; - float top_time = 1e10; - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - const SelectedKey &sk = E->key(); - - float t = animation->track_get_key_time(sk.track,sk.key); - if (t<top_time) - top_time=t; - if (sk.track<top_track) - top_track=sk.track; - - } - ERR_FAIL_COND( top_track == 0x7FFFFFFF || top_time==1e10 ); - - // - - int start_track = transpose ? selected_track : top_track; - - undo_redo->create_action(TTR("Anim Duplicate Keys")); - - List<Pair<int,float> > new_selection_values; - - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - const SelectedKey &sk = E->key(); - - float t = animation->track_get_key_time(sk.track,sk.key); - - float dst_time = t+(timeline_pos - top_time); - int dst_track = sk.track + (start_track - top_track); - - if (dst_track < 0 || dst_track>= animation->get_track_count()) - continue; - - if (animation->track_get_type(dst_track) != animation->track_get_type(sk.track)) - continue; - - int existing_idx = animation->track_find_key(dst_track,dst_time,true); - - undo_redo->add_do_method(animation.ptr(),"track_insert_key",dst_track,dst_time,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); - undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",dst_track,dst_time); - - Pair<int,float> p; - p.first=dst_track; - p.second=dst_time; - new_selection_values.push_back( p ); - - if (existing_idx!=-1) { - - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",dst_track,dst_time,animation->track_get_key_value(dst_track,existing_idx),animation->track_get_key_transition(dst_track,existing_idx)); - - } - - } - - undo_redo->commit_action(); - - //reselect duplicated - - Map<SelectedKey,KeyInfo> new_selection; - for (List<Pair<int,float> >::Element *E=new_selection_values.front();E;E=E->next()) { - - int track=E->get().first; - float time = E->get().second; - - int existing_idx = animation->track_find_key(track,time,true); - - if (existing_idx==-1) - continue; - SelectedKey sk2; - sk2.track=track; - sk2.key=existing_idx; - - KeyInfo ki; - ki.pos=time; - - new_selection[sk2]=ki; - - } - - - selection=new_selection; - track_editor->update(); - _edit_if_single_selection(); - - } -} - -void AnimationKeyEditor::_menu_track(int p_type) { - - ERR_FAIL_COND(!animation.is_valid()); - - last_menu_track_opt=p_type; - switch(p_type) { - - case TRACK_MENU_SCALE: - case TRACK_MENU_SCALE_PIVOT: { - - scale_dialog->popup_centered(Size2(200,100)); - } break; - case TRACK_MENU_MOVE_UP: { - - int idx=selected_track; - if (idx>0 && idx<animation->get_track_count()) { - undo_redo->create_action(TTR("Move Anim Track Up")); - undo_redo->add_do_method(animation.ptr(),"track_move_down",idx); - undo_redo->add_undo_method(animation.ptr(),"track_move_up",idx-1); - undo_redo->commit_action(); - selected_track=idx-1; - } - - } break; - case TRACK_MENU_MOVE_DOWN: { - - - int idx=selected_track; - if (idx>=0 && idx<animation->get_track_count()-1) { - undo_redo->create_action(TTR("Move Anim Track Down")); - undo_redo->add_do_method(animation.ptr(),"track_move_up",idx); - undo_redo->add_undo_method(animation.ptr(),"track_move_down",idx+1); - undo_redo->commit_action(); - selected_track=idx+1; - } - - } break; - case TRACK_MENU_REMOVE: { - - int idx=selected_track; - if (idx>=0 && idx<animation->get_track_count()) { - undo_redo->create_action(TTR("Remove Anim Track")); - undo_redo->add_do_method(animation.ptr(),"remove_track",idx); - undo_redo->add_undo_method(animation.ptr(),"add_track",animation->track_get_type(idx),idx); - undo_redo->add_undo_method(animation.ptr(),"track_set_path",idx,animation->track_get_path(idx)); - //todo interpolation - for(int i=0;i<animation->track_get_key_count(idx);i++) { - - Variant v = animation->track_get_key_value(idx,i); - float time = animation->track_get_key_time(idx,i); - float trans = animation->track_get_key_transition(idx,i); - - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",idx,time,v); - undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",idx,i,trans); - - } - - undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_type",idx,animation->track_get_interpolation_type(idx)); - if (animation->track_get_type(idx)==Animation::TYPE_VALUE) { - undo_redo->add_undo_method(animation.ptr(),"value_track_set_update_mode",idx,animation->value_track_get_update_mode(idx)); - - } - - undo_redo->commit_action(); - } - - - } break; - case TRACK_MENU_DUPLICATE: - case TRACK_MENU_DUPLICATE_TRANSPOSE: { - - _anim_duplicate_keys(p_type==TRACK_MENU_DUPLICATE_TRANSPOSE); - } break; - case TRACK_MENU_SET_ALL_TRANS_LINEAR: - case TRACK_MENU_SET_ALL_TRANS_CONSTANT: - case TRACK_MENU_SET_ALL_TRANS_OUT: - case TRACK_MENU_SET_ALL_TRANS_IN: - case TRACK_MENU_SET_ALL_TRANS_INOUT: - case TRACK_MENU_SET_ALL_TRANS_OUTIN: { - - if (!selection.size() || !animation.is_valid()) - break; - - float t=0; - switch(p_type) { - case TRACK_MENU_SET_ALL_TRANS_LINEAR: t=1.0; break; - case TRACK_MENU_SET_ALL_TRANS_CONSTANT: t=0.0; break; - case TRACK_MENU_SET_ALL_TRANS_OUT: t=0.5; break; - case TRACK_MENU_SET_ALL_TRANS_IN: t=2.0; break; - case TRACK_MENU_SET_ALL_TRANS_INOUT: t=-0.5; break; - case TRACK_MENU_SET_ALL_TRANS_OUTIN: t=-2.0; break; - } - - undo_redo->create_action(TTR("Set Transitions to:")+" "+rtos(t)); - - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - const SelectedKey &sk = E->key(); - - undo_redo->add_do_method(animation.ptr(),"track_set_key_transition",sk.track,sk.key,t); - undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",sk.track,sk.key,animation->track_get_key_transition(sk.track,sk.key)); - - } - - undo_redo->commit_action(); - - } break; - case TRACK_MENU_NEXT_STEP: { - - if (animation.is_null()) - break; - float step = animation->get_step(); - if (step==0) - step=1; - - float pos=timeline_pos; - - pos=Math::stepify(pos+step,step); - if (pos>animation->get_length()) - pos=animation->get_length(); - timeline_pos=pos; - track_pos->update(); - emit_signal("timeline_changed",pos,true); - - } break; - case TRACK_MENU_PREV_STEP: { - if (animation.is_null()) - break; - float step = animation->get_step(); - if (step==0) - step=1; - - float pos=timeline_pos; - pos=Math::stepify(pos-step,step); - if (pos<0) - pos=0; - timeline_pos=pos; - track_pos->update(); - emit_signal("timeline_changed",pos,true); - - - } break; - - case TRACK_MENU_OPTIMIZE: { - - optimize_dialog->popup_centered(Size2(250,180)); - } break; - case TRACK_MENU_CLEAN_UP: { - - cleanup_dialog->popup_centered_minsize(Size2(300,0)); - } break; - case TRACK_MENU_CLEAN_UP_CONFIRM: { - - if (cleanup_all->is_pressed()) { - List<StringName> names; - AnimationPlayerEditor::singleton->get_player()->get_animation_list(&names); - for (List<StringName>::Element *E=names.front();E;E=E->next()) { - _cleanup_animation(AnimationPlayerEditor::singleton->get_player()->get_animation(E->get())); - } - } else { - _cleanup_animation(animation); - - } - } break; - case CURVE_SET_LINEAR: { - curve_edit->force_transition(1.0); - - } break; - case CURVE_SET_IN: { - - curve_edit->force_transition(4.0); - - } break; - case CURVE_SET_OUT: { - - curve_edit->force_transition(0.25); - } break; - case CURVE_SET_INOUT: { - curve_edit->force_transition(-4); - - } break; - case CURVE_SET_OUTIN: { - - curve_edit->force_transition(-0.25); - } break; - case CURVE_SET_CONSTANT: { - - curve_edit->force_transition(0); - } break; - - } - -} - -void AnimationKeyEditor::_cleanup_animation(Ref<Animation> p_animation) { - - - for(int i=0;i<p_animation->get_track_count();i++) { - - bool prop_exists=false; - Variant::Type valid_type=Variant::NIL; - Object *obj=NULL; - - RES res; - Node *node = root->get_node_and_resource(p_animation->track_get_path(i),res); - - if (res.is_valid()) { - obj=res.ptr(); - } else if (node) { - obj=node; - } - - if (obj && p_animation->track_get_type(i)==Animation::TYPE_VALUE) { - valid_type=obj->get_static_property_type(p_animation->track_get_path(i).get_property(),&prop_exists); - } - - if (!obj && cleanup_tracks->is_pressed()) { - - p_animation->remove_track(i); - i--; - continue; - } - - if (!prop_exists || p_animation->track_get_type(i)!=Animation::TYPE_VALUE || cleanup_keys->is_pressed()==false) - continue; - - for(int j=0;j<p_animation->track_get_key_count(i);j++) { - - Variant v = p_animation->track_get_key_value(i,j); - - if (!Variant::can_convert(v.get_type(),valid_type)) { - p_animation->track_remove_key(i,j); - j--; - } - } - - if (p_animation->track_get_key_count(i)==0 && cleanup_tracks->is_pressed()) { - p_animation->remove_track(i); - i--; - } - } - - undo_redo->clear_history(); - _update_paths(); -} - -void AnimationKeyEditor::_animation_optimize() { - - - - animation->optimize(optimize_linear_error->get_value(),optimize_angular_error->get_value(),optimize_max_angle->get_value()); - track_editor->update(); - undo_redo->clear_history(); - -} - - -float AnimationKeyEditor::_get_zoom_scale() const { - - float zv = zoom->get_value(); - if (zv<1) { - zv = 1.0-zv; - return Math::pow(1.0f+zv,8.0f)*100; - } else { - return 1.0/Math::pow(zv,8.0f)*100; - } -} - -void AnimationKeyEditor::_track_pos_draw() { - - if (!animation.is_valid()) { - return; - } - - - Ref<StyleBox> style = get_stylebox("normal","TextEdit"); - Size2 size= track_editor->get_size() - style->get_minimum_size(); - Size2 ofs = style->get_offset(); - - int settings_limit = size.width - right_data_size_cache; - int name_limit = settings_limit * name_column_ratio; - - float keys_from= h_scroll->get_value(); - float zoom_scale = _get_zoom_scale(); - float keys_to=keys_from+(settings_limit-name_limit) / zoom_scale; - - - - //will move to separate control! (for speedup) - if (timeline_pos >= keys_from && timeline_pos<keys_to) { - //draw position - int pixel = (timeline_pos - h_scroll->get_value()) * zoom_scale; - pixel+=name_limit; - track_pos->draw_line(ofs+Point2(pixel,0),ofs+Point2(pixel,size.height),Color(1,0.3,0.3,0.8)); - - } -} - -void AnimationKeyEditor::_track_editor_draw() { - - - if (animation.is_valid() && animation->get_track_count()) { - if (selected_track < 0) - selected_track=0; - else if (selected_track>=animation->get_track_count()) - selected_track=animation->get_track_count()-1; - } - - track_pos->update(); - Control *te=track_editor; - Ref<StyleBox> style = get_stylebox("normal","TextEdit"); - te->draw_style_box(style,Rect2(Point2(),track_editor->get_size())); - - if (te->has_focus()) { - te->draw_style_box(get_stylebox("bg_focus","Tree"),Rect2(Point2(),track_editor->get_size())); - } - - if (!animation.is_valid()) { - v_scroll->hide(); - h_scroll->hide(); - menu_add_track->set_disabled(true); - menu_track->set_disabled(true); - edit_button->set_disabled(true); - key_editor_tab->hide(); - move_up_button->set_disabled(true); - move_down_button->set_disabled(true); - remove_button->set_disabled(true); - - return; - } - - menu_add_track->set_disabled(false); - menu_track->set_disabled(false); - edit_button->set_disabled(false); - move_up_button->set_disabled(false); - move_down_button->set_disabled(false); - remove_button->set_disabled(false); - if (edit_button->is_pressed()) - key_editor_tab->show(); - - te_drawing=true; - - Size2 size= te->get_size() - style->get_minimum_size(); - Size2 ofs = style->get_offset(); - - Ref<Font> font = te->get_font("font","Tree"); - int sep = get_constant("vseparation","Tree"); - int hsep = get_constant("hseparation","Tree"); - Color color = get_color("font_color","Tree"); - Color sepcolor = get_color("guide_color","Tree"); - Color timecolor = get_color("prop_subsection","Editor"); - timecolor = Color::html("ff4a414f"); - Color hover_color = Color(1,1,1,0.05); - Color select_color = Color(1,1,1,0.1); - Color invalid_path_color = Color(1,0.6,0.4,0.5); - Color track_select_color =Color::html("ffbd8e8e"); - - Ref<Texture> remove_icon = get_icon("Remove","EditorIcons"); - Ref<Texture> move_up_icon = get_icon("MoveUp","EditorIcons"); - Ref<Texture> move_down_icon = get_icon("MoveDown","EditorIcons"); - Ref<Texture> remove_icon_hl = get_icon("RemoveHl","EditorIcons"); - Ref<Texture> move_up_icon_hl = get_icon("MoveUpHl","EditorIcons"); - Ref<Texture> move_down_icon_hl = get_icon("MoveDownHl","EditorIcons"); - Ref<Texture> add_key_icon = get_icon("TrackAddKey","EditorIcons"); - Ref<Texture> add_key_icon_hl = get_icon("TrackAddKeyHl","EditorIcons"); - Ref<Texture> down_icon = get_icon("select_arrow","Tree"); - - Ref<Texture> wrap_icon[2]={ - get_icon("InterpWrapClamp","EditorIcons"), - get_icon("InterpWrapLoop","EditorIcons"), - }; - - Ref<Texture> interp_icon[3]={ - get_icon("InterpRaw","EditorIcons"), - get_icon("InterpLinear","EditorIcons"), - get_icon("InterpCubic","EditorIcons") - }; - Ref<Texture> cont_icon[3]={ - get_icon("TrackContinuous","EditorIcons"), - get_icon("TrackDiscrete","EditorIcons"), - get_icon("TrackTrigger","EditorIcons") - }; - Ref<Texture> type_icon[3]={ - get_icon("KeyValue","EditorIcons"), - get_icon("KeyXform","EditorIcons"), - get_icon("KeyCall","EditorIcons") - }; - - Ref<Texture> invalid_icon = get_icon("KeyInvalid","EditorIcons"); - Ref<Texture> invalid_icon_hover = get_icon("KeyInvalidHover","EditorIcons"); - - Ref<Texture> hsize_icon = get_icon("Hsize","EditorIcons"); - - Ref<Texture> type_hover=get_icon("KeyHover","EditorIcons"); - Ref<Texture> type_selected=get_icon("KeySelected","EditorIcons"); - - int right_separator_ofs = down_icon->get_width() *3 + add_key_icon->get_width() + interp_icon[0]->get_width() + wrap_icon[0]->get_width() + cont_icon[0]->get_width() + hsep*9; - - int h = font->get_height()+sep; - - - int fit = (size.height / h)-1; - int total = animation->get_track_count(); - if (total < fit) { - v_scroll->hide(); - v_scroll->set_max( total ); - v_scroll->set_page( fit ); - } else { - v_scroll->show(); - v_scroll->set_max( total ); - v_scroll->set_page( fit ); - } - - - int settings_limit = size.width - right_separator_ofs; - int name_limit = settings_limit * name_column_ratio; - - te->draw_line(ofs+Point2(name_limit,0),ofs+Point2(name_limit,size.height),color); - te->draw_line(ofs+Point2(settings_limit,0),ofs+Point2(settings_limit,size.height),color); - te->draw_texture(hsize_icon,ofs+Point2(name_limit-hsize_icon->get_width()-hsep,(h-hsize_icon->get_height())/2)); - - te->draw_line(ofs+Point2(0,h),ofs+Point2(size.width,h),color); - // draw time - - float keys_from; - float keys_to; - float zoom_scale; - - - { - - int zoomw = settings_limit-name_limit; - - - float scale = _get_zoom_scale(); - zoom_scale=scale; - - - float l = animation->get_length(); - if (l<=0) - l=0.001; //avoid crashor - - int end_px = (l - h_scroll->get_value()) * scale; - int begin_px = -h_scroll->get_value() * scale; - Color notimecol; - notimecol.r=timecolor.gray(); - notimecol.g=notimecol.r; - notimecol.b=notimecol.r; - notimecol.a=timecolor.a; - - { - - te->draw_rect(Rect2( ofs + Point2(name_limit,0), Point2(zoomw-1,h)), notimecol); - - - if (begin_px < zoomw && end_px >0) { - - if (begin_px<0) - begin_px=0; - if (end_px>zoomw) - end_px=zoomw; - - te->draw_rect(Rect2( ofs + Point2(name_limit+begin_px,0), Point2(end_px-begin_px-1,h)), timecolor); - } - - } - - - - keys_from= h_scroll->get_value(); - keys_to=keys_from+zoomw / scale; - - { - float time_min=0; - float time_max=animation->get_length(); - for(int i=0;i<animation->get_track_count();i++) { - - if (animation->track_get_key_count(i)>0) { - - float beg = animation->track_get_key_time(i,0); - if (beg<time_min) - time_min=beg; - float end = animation->track_get_key_time(i,animation->track_get_key_count(i)-1); - if (end>time_max) - time_max=end; - } - } - - - - - - float extra = (zoomw / scale)*0.5; - - if (time_min<-0.001) - time_min-=extra; - time_max+=extra; - h_scroll->set_min(time_min); - h_scroll->set_max(time_max); - - if (zoomw / scale < (time_max-time_min)) { - h_scroll->show(); - - } else { - - h_scroll->hide(); - } - - - } - - h_scroll->set_page(zoomw / scale); - - Color color_time_sec = color; - Color color_time_dec = color; - color_time_dec.a*=0.5; -#define SC_ADJ 100 - int min=30; - int dec=1; - int step=1; - int decimals=2; - bool step_found=false; - - while(!step_found) { - - static const int _multp[3]={1,2,5}; - for(int i=0;i<3;i++) { - - step = (_multp[i] * dec); - if (step*scale/SC_ADJ> min) { - step_found=true; - break; - } - - } - if (step_found) - break; - dec*=10; - decimals--; - if (decimals<0) - decimals=0; - } - - - for(int i=0;i<zoomw;i++) { - - float pos = h_scroll->get_value() + double(i)/scale; - float prev = h_scroll->get_value() + (double(i)-1.0)/scale; - - - int sc = int(Math::floor(pos*SC_ADJ)); - int prev_sc = int(Math::floor(prev*SC_ADJ)); - bool sub = (sc % SC_ADJ); - - if ((sc/step)!=(prev_sc/step) || (prev_sc<0 && sc>=0)) { - - int scd = sc < 0 ? prev_sc : sc; - te->draw_line( ofs + Point2(name_limit+i,0), ofs+Point2(name_limit+i,h), color); - te->draw_string( font,ofs + Point2(name_limit+i+3,(h-font->get_height())/2+font->get_ascent()).floor(),String::num((scd-(scd%step))/double(SC_ADJ),decimals),sub?color_time_dec:color_time_sec,zoomw-i); - } - - - } - } - - color.a*=0.5; - - for(int i=0;i<fit;i++) { - - //this code sucks, i always forget how it works - - int idx = v_scroll->get_value() + i; - if (idx>=animation->get_track_count()) - break; - int y = h+i*h+sep; - - bool prop_exists=false; - Variant::Type valid_type=Variant::NIL; - Object *obj=NULL; - - RES res; - Node *node = root->get_node_and_resource(animation->track_get_path(idx),res); - - if (res.is_valid()) { - obj=res.ptr(); - } else if (node) { - obj=node; - } - - if (obj && animation->track_get_type(idx)==Animation::TYPE_VALUE) { - valid_type=obj->get_static_property_type(animation->track_get_path(idx).get_property(),&prop_exists); - } - - - if (/*mouse_over.over!=MouseOver::OVER_NONE &&*/ idx==mouse_over.track) { - Color sepc=hover_color; - te->draw_rect(Rect2(ofs+Point2(0,y),Size2(size.width,h-1)),sepc); - } - - if (selected_track==idx) { - Color tc = select_color; - //tc.a*=0.7; - te->draw_rect(Rect2(ofs+Point2(0,y),Size2(size.width-1,h-1)),tc); - } - - te->draw_texture(type_icon[animation->track_get_type(idx)],ofs+Point2(0,y+(h-type_icon[0]->get_height())/2).floor()); - NodePath np = animation->track_get_path(idx); - Node *n = root->get_node(np); - Color ncol = color; - if (n && editor_selection->is_selected(n)) - ncol=track_select_color; - te->draw_string(font,Point2(ofs+Point2(type_icon[0]->get_width()+sep,y+font->get_ascent()+(sep/2))).floor(),np,ncol,name_limit-(type_icon[0]->get_width()+sep)-5); - - if (!obj) - te->draw_line(ofs+Point2(0,y+h/2),ofs+Point2(name_limit,y+h/2),invalid_path_color); - - te->draw_line(ofs+Point2(0,y+h),ofs+Point2(size.width,y+h),sepcolor); - - Point2 icon_ofs = ofs + Point2( size.width, y + (h - remove_icon->get_height() )/2).floor(); - icon_ofs.y+=4; - - -/* icon_ofs.x-=remove_icon->get_width(); - - te->draw_texture((mouse_over.over==MouseOver::OVER_REMOVE && mouse_over.track==idx)?remove_icon_hl:remove_icon,icon_ofs); - icon_ofs.x-=hsep; - icon_ofs.x-=move_down_icon->get_width(); - te->draw_texture((mouse_over.over==MouseOver::OVER_DOWN && mouse_over.track==idx)?move_down_icon_hl:move_down_icon,icon_ofs); - icon_ofs.x-=hsep; - icon_ofs.x-=move_up_icon->get_width(); - te->draw_texture((mouse_over.over==MouseOver::OVER_UP && mouse_over.track==idx)?move_up_icon_hl:move_up_icon,icon_ofs); - icon_ofs.x-=hsep; - te->draw_line(Point2(icon_ofs.x,ofs.y+y),Point2(icon_ofs.x,ofs.y+y+h),sepcolor); - - icon_ofs.x-=hsep; - */ - track_ofs[0]=size.width-icon_ofs.x; - icon_ofs.x-=down_icon->get_width(); - te->draw_texture(down_icon,icon_ofs); - - int wrap_type = animation->track_get_interpolation_loop_wrap(idx)?1:0; - icon_ofs.x-=hsep; - icon_ofs.x-=wrap_icon[wrap_type]->get_width(); - te->draw_texture(wrap_icon[wrap_type],icon_ofs); - - icon_ofs.x-=hsep; - te->draw_line(Point2(icon_ofs.x,ofs.y+y),Point2(icon_ofs.x,ofs.y+y+h),sepcolor); - - track_ofs[1]=size.width-icon_ofs.x; - - icon_ofs.x-=down_icon->get_width(); - te->draw_texture(down_icon,icon_ofs); - - int interp_type = animation->track_get_interpolation_type(idx); - ERR_CONTINUE(interp_type<0 || interp_type>=3); - icon_ofs.x-=hsep; - icon_ofs.x-=interp_icon[interp_type]->get_width(); - te->draw_texture(interp_icon[interp_type],icon_ofs); - - icon_ofs.x-=hsep; - te->draw_line(Point2(icon_ofs.x,ofs.y+y),Point2(icon_ofs.x,ofs.y+y+h),sepcolor); - - track_ofs[2]=size.width-icon_ofs.x; - - if (animation->track_get_type(idx)==Animation::TYPE_VALUE) { - - - int umode = animation->value_track_get_update_mode(idx); - - icon_ofs.x-=hsep; - icon_ofs.x-=down_icon->get_width(); - te->draw_texture(down_icon,icon_ofs); - - icon_ofs.x-=hsep; - icon_ofs.x-=cont_icon[umode]->get_width(); - te->draw_texture(cont_icon[umode],icon_ofs); - } else { - - icon_ofs.x -= hsep*2 + cont_icon[0]->get_width() + down_icon->get_width(); - } - - icon_ofs.x-=hsep; - te->draw_line(Point2(icon_ofs.x,ofs.y+y),Point2(icon_ofs.x,ofs.y+y+h),sepcolor); - - track_ofs[3]=size.width-icon_ofs.x; - - icon_ofs.x-=hsep; - icon_ofs.x-=add_key_icon->get_width(); - te->draw_texture((mouse_over.over==MouseOver::OVER_ADD_KEY && mouse_over.track==idx)?add_key_icon_hl:add_key_icon,icon_ofs); - - track_ofs[4]=size.width-icon_ofs.x; - - //draw the keys; - int tt = animation->track_get_type(idx); - float key_vofs = Math::floor((float)(h - type_icon[tt]->get_height())/2); - float key_hofs = -Math::floor((float)type_icon[tt]->get_height()/2); - - int kc=animation->track_get_key_count(idx); - bool first=true; - - - - for(int i=0;i<kc;i++) { - - - float time = animation->track_get_key_time(idx,i); - if (time<keys_from) - continue; - if (time>keys_to) { - - if (first && i>0 && animation->track_get_key_value(idx,i)==animation->track_get_key_value(idx,i-1)) { - //draw whole line - te->draw_line(ofs+Vector2(name_limit,y+h/2),ofs+Point2(settings_limit,y+h/2),color); - } - - break; - } - - float x = key_hofs + name_limit + (time-keys_from)*zoom_scale; - - Ref<Texture> tex = type_icon[tt]; - - SelectedKey sk; - sk.key=i; - sk.track=idx; - if (selection.has(sk)) { - - if (click.click==ClickOver::CLICK_MOVE_KEYS) - continue; - tex=type_selected; - } - - if (mouse_over.over==MouseOver::OVER_KEY && mouse_over.track==idx && mouse_over.over_key==i) - tex=type_hover; - - Variant value = animation->track_get_key_value(idx,i); - if (first && i>0 && value==animation->track_get_key_value(idx,i-1)) { - - te->draw_line(ofs+Vector2(name_limit,y+h/2),ofs+Point2(x,y+h/2),color); - } - - if (i<kc-1 && value==animation->track_get_key_value(idx,i+1)) { - float x_n = key_hofs + name_limit + (animation->track_get_key_time(idx,i+1)-keys_from)*zoom_scale; - - x_n = MIN( x_n, settings_limit); - te->draw_line(ofs+Point2(x_n,y+h/2),ofs+Point2(x,y+h/2),color); - - } - - if (prop_exists && !Variant::can_convert(value.get_type(),valid_type)) { - te->draw_texture(invalid_icon,ofs+Point2(x,y+key_vofs).floor()); - } - - if (prop_exists && !Variant::can_convert(value.get_type(),valid_type)) { - if (tex==type_hover) - te->draw_texture(invalid_icon_hover,ofs+Point2(x,y+key_vofs).floor()); - else - te->draw_texture(invalid_icon,ofs+Point2(x,y+key_vofs).floor()); - } else { - - te->draw_texture(tex,ofs+Point2(x,y+key_vofs).floor()); - } - - - first=false; - } - - } - - switch(click.click) { - case ClickOver::CLICK_SELECT_KEYS: { - - te->draw_rect(Rect2(click.at,click.to-click.at),Color(0.7,0.7,1.0,0.5)); - - } break; - case ClickOver::CLICK_MOVE_KEYS: { - - float from_t = 1e20; - - for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { - float t = animation->track_get_key_time(E->key().track,E->key().key); - if (t<from_t) - from_t=t; - - } - - float motion = from_t+(click.to.x - click.at.x)/zoom_scale; - if (step->get_value()) - motion = Math::stepify(motion,step->get_value()); - - for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { - - - int idx = E->key().track; - int i = idx-v_scroll->get_value(); - if (i<0 || i>=fit) - continue; - int y = h+i*h+sep; - - float key_vofs = Math::floor((float)(h - type_selected->get_height())/2); - float key_hofs = -Math::floor((float)type_selected->get_height()/2); - - float time = animation->track_get_key_time(idx,E->key().key); - float diff = time-from_t; - - float t = motion + diff; - - float x = (t-keys_from)*zoom_scale; - //x+=click.to.x - click.at.x; - if (x<0 || x>=(settings_limit-name_limit)) - continue; - - x+=name_limit; - - te->draw_texture(type_selected,ofs+Point2(x+key_hofs,y+key_vofs).floor()); - - } - } break; - default: {}; - } - - - te_drawing=false; -} - -void AnimationKeyEditor::_track_name_changed(const String& p_name) { - - ERR_FAIL_COND(!animation.is_valid()); - undo_redo->create_action(TTR("Anim Track Rename")); - undo_redo->add_do_method(animation.ptr(),"track_set_path",track_name_editing,p_name); - undo_redo->add_undo_method(animation.ptr(),"track_set_path",track_name_editing,animation->track_get_path(track_name_editing)); - undo_redo->commit_action(); - track_name->hide(); - -} - -void AnimationKeyEditor::_track_menu_selected(int p_idx) { - - - ERR_FAIL_COND(!animation.is_valid()); - - if (interp_editing!=-1) { - - ERR_FAIL_INDEX(interp_editing,animation->get_track_count()); - undo_redo->create_action(TTR("Anim Track Change Interpolation")); - undo_redo->add_do_method(animation.ptr(),"track_set_interpolation_type",interp_editing,p_idx); - undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_type",interp_editing,animation->track_get_interpolation_type(interp_editing)); - undo_redo->commit_action(); - } else if (cont_editing!=-1) { - - ERR_FAIL_INDEX(cont_editing,animation->get_track_count()); - - undo_redo->create_action(TTR("Anim Track Change Value Mode")); - undo_redo->add_do_method(animation.ptr(),"value_track_set_update_mode",cont_editing,p_idx); - undo_redo->add_undo_method(animation.ptr(),"value_track_set_update_mode",cont_editing,animation->value_track_get_update_mode(cont_editing)); - undo_redo->commit_action(); - } else if (wrap_editing!=-1) { - - ERR_FAIL_INDEX(wrap_editing,animation->get_track_count()); - - undo_redo->create_action(TTR("Anim Track Change Wrap Mode")); - undo_redo->add_do_method(animation.ptr(),"track_set_interpolation_loop_wrap",wrap_editing,p_idx?true:false); - undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_loop_wrap",wrap_editing,animation->track_get_interpolation_loop_wrap(wrap_editing)); - undo_redo->commit_action(); - } else { - switch (p_idx) { - - case RIGHT_MENU_DUPLICATE: - _anim_duplicate_keys(); break; - case RIGHT_MENU_DUPLICATE_TRANSPOSE: - _anim_duplicate_keys(true); break; - case RIGHT_MENU_REMOVE: - _anim_delete_keys(); break; - } - } - -} - -struct _AnimMoveRestore { - - int track; - float time; - Variant key; - float transition; -}; - -void AnimationKeyEditor::_clear_selection_for_anim(const Ref<Animation>& p_anim) { - - if (!(animation==p_anim)) - return; - //selection.clear(); - _clear_selection(); - -} - -void AnimationKeyEditor::_select_at_anim(const Ref<Animation>& p_anim,int p_track,float p_pos){ - - if (!(animation==p_anim)) - return; - - int idx = animation->track_find_key(p_track,p_pos,true); - ERR_FAIL_COND(idx<0); - - SelectedKey sk; - sk.track=p_track; - sk.key=idx; - KeyInfo ki; - ki.pos=p_pos; - - selection.insert(sk,ki); - -} - - -PropertyInfo AnimationKeyEditor::_find_hint_for_track(int p_idx,NodePath& r_base_path) { - - r_base_path=NodePath(); - ERR_FAIL_COND_V(!animation.is_valid(),PropertyInfo()); - ERR_FAIL_INDEX_V(p_idx,animation->get_track_count(),PropertyInfo()); - - if (!root) - return PropertyInfo(); - - NodePath path = animation->track_get_path(p_idx); - - - if (!root->has_node_and_resource(path)) - return PropertyInfo(); - - RES res; - Node *node = root->get_node_and_resource(path,res); - - - if (node) { - r_base_path=node->get_path(); - } - - String property = path.get_property(); - if (property=="") - return PropertyInfo(); - - List<PropertyInfo> pinfo; - if (res.is_valid()) - res->get_property_list(&pinfo); - else - node->get_property_list(&pinfo); - - for(List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) { - - if (E->get().name==property) - return E->get(); - } - - return PropertyInfo(); -} - - -void AnimationKeyEditor::_curve_transition_changed(float p_what) { - - if (selection.size()==0) - return; - if (selection.size()==1) - undo_redo->create_action(TTR("Edit Node Curve"),UndoRedo::MERGE_ENDS); - else - undo_redo->create_action(TTR("Edit Selection Curve"),UndoRedo::MERGE_ENDS); - - for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { - - int track = E->key().track; - int key = E->key().key; - float prev_val = animation->track_get_key_transition(track,key); - undo_redo->add_do_method(animation.ptr(),"track_set_key_transition",track,key,p_what); - undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",track,key,prev_val); - } - - undo_redo->commit_action(); - -} - -void AnimationKeyEditor::_toggle_edit_curves() { - - if (edit_button->is_pressed()) - key_editor_tab->show(); - else - key_editor_tab->hide(); -} - - -bool AnimationKeyEditor::_edit_if_single_selection() { - - if (selection.size()!=1) { - - if (selection.size()==0) { - curve_edit->set_mode(AnimationCurveEdit::MODE_DISABLED); - //print_line("disable"); - } else { - - curve_edit->set_mode(AnimationCurveEdit::MODE_MULTIPLE); - curve_edit->set_transition(1.0); - curve_edit->clear_multiples(); - //add all - for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { - - curve_edit->set_multiple(animation->track_get_key_transition(E->key().track,E->key().key)); - } - //print_line("multiple"); - - } - return false; - } - curve_edit->set_mode(AnimationCurveEdit::MODE_SINGLE); - //print_line("regular"); - - int idx = selection.front()->key().track; - int key = selection.front()->key().key; - { - - key_edit->animation=animation; - key_edit->track=idx; - key_edit->key_ofs=animation->track_get_key_time(idx,key); - key_edit->hint=_find_hint_for_track(idx,key_edit->base); - key_edit->notify_change(); - - curve_edit->set_transition(animation->track_get_key_transition(idx,key)); - - /*key_edit_dialog->set_size( Size2( 200,200) ); - key_edit_dialog->set_pos( track_editor->get_global_pos() + ofs + mpos +Point2(-100,20)); - key_edit_dialog->popup();*/ - - } - - return true; - -} - -void AnimationKeyEditor::_anim_delete_keys() { - if (selection.size()) { - undo_redo->create_action(TTR("Anim Delete Keys")); - - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - undo_redo->add_do_method(animation.ptr(),"track_remove_key",E->key().track,E->key().key); - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",E->key().track,E->get().pos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); - - } - undo_redo->add_do_method(this,"_clear_selection_for_anim",animation); - undo_redo->add_undo_method(this,"_clear_selection_for_anim",animation); - undo_redo->commit_action(); - //selection.clear(); - accept_event(); - _edit_if_single_selection(); - } -} - -void AnimationKeyEditor::_track_editor_gui_input(const InputEvent& p_input) { - - Control *te=track_editor; - Ref<StyleBox> style = get_stylebox("normal","TextEdit"); - - if (!animation.is_valid()) { - return; - } - - Size2 size= te->get_size() - style->get_minimum_size(); - Size2 ofs = style->get_offset(); - - Ref<Font> font = te->get_font("font","Tree"); - int sep = get_constant("vseparation","Tree"); - int hsep = get_constant("hseparation","Tree"); - Ref<Texture> remove_icon = get_icon("Remove","EditorIcons"); - Ref<Texture> move_up_icon = get_icon("MoveUp","EditorIcons"); - Ref<Texture> move_down_icon = get_icon("MoveDown","EditorIcons"); - Ref<Texture> down_icon = get_icon("select_arrow","Tree"); - Ref<Texture> hsize_icon = get_icon("Hsize","EditorIcons"); - Ref<Texture> add_key_icon = get_icon("TrackAddKey","EditorIcons"); - - Ref<Texture> wrap_icon[2]={ - get_icon("InterpWrapClamp","EditorIcons"), - get_icon("InterpWrapLoop","EditorIcons"), - }; - Ref<Texture> interp_icon[3]={ - get_icon("InterpRaw","EditorIcons"), - get_icon("InterpLinear","EditorIcons"), - get_icon("InterpCubic","EditorIcons") - }; - Ref<Texture> cont_icon[3]={ - get_icon("TrackContinuous","EditorIcons"), - get_icon("TrackDiscrete","EditorIcons"), - get_icon("TrackTrigger","EditorIcons") - }; - Ref<Texture> type_icon[3]={ - get_icon("KeyValue","EditorIcons"), - get_icon("KeyXform","EditorIcons"), - get_icon("KeyCall","EditorIcons") - }; - int right_separator_ofs = down_icon->get_width() *3 + add_key_icon->get_width() + interp_icon[0]->get_width() + wrap_icon[0]->get_width() + cont_icon[0]->get_width() + hsep*9; - - int h = font->get_height()+sep; - - int fit = (size.height / h)-1; - int total = animation->get_track_count(); - if (total < fit) { - v_scroll->hide(); - } else { - v_scroll->show(); - v_scroll->set_max( total ); - v_scroll->set_page( fit ); - } - - int settings_limit = size.width - right_separator_ofs; - int name_limit = settings_limit * name_column_ratio; - - - switch(p_input.type) { - - case InputEvent::KEY: { - - if (p_input.key.scancode==KEY_D && p_input.key.pressed && p_input.key.mod.command) { - - if (p_input.key.mod.shift) - _menu_track(TRACK_MENU_DUPLICATE_TRANSPOSE); - else - _menu_track(TRACK_MENU_DUPLICATE); - - accept_event(); - - } else if (p_input.key.scancode==KEY_DELETE && p_input.key.pressed && click.click==ClickOver::CLICK_NONE) { - - _anim_delete_keys(); - } else if (animation.is_valid() && animation->get_track_count()>0) { - - if (p_input.is_pressed() && (p_input.is_action("ui_up") || p_input.is_action("ui_page_up"))) { - - if (p_input.is_action("ui_up")) - selected_track--; - if (v_scroll->is_visible_in_tree() && p_input.is_action("ui_page_up")) - selected_track--; - - if (selected_track<0) - selected_track=0; - - - if (v_scroll->is_visible_in_tree()) { - if (v_scroll->get_value() > selected_track) - v_scroll->set_value(selected_track); - - } - - track_editor->update(); - accept_event(); - - } - - if (p_input.is_pressed() && (p_input.is_action("ui_down") || p_input.is_action("ui_page_down"))) { - - if (p_input.is_action("ui_down")) - selected_track++; - else if (v_scroll->is_visible_in_tree() && p_input.is_action("ui_page_down")) - selected_track+=v_scroll->get_page(); - - if (selected_track >= animation->get_track_count()) - selected_track=animation->get_track_count()-1; - - if (v_scroll->is_visible_in_tree() && v_scroll->get_page()+v_scroll->get_value() < selected_track+1) { - v_scroll->set_value(selected_track-v_scroll->get_page()+1); - } - - track_editor->update(); - accept_event(); - } - } - - - } break; - case InputEvent::MOUSE_BUTTON: { - - const InputEventMouseButton &mb = p_input.mouse_button; - - if (mb.button_index==BUTTON_WHEEL_UP && mb.pressed) { - - if (mb.mod.command) { - zoom->set_value(zoom->get_value() + zoom->get_step()); - } else { - v_scroll->set_value( v_scroll->get_value() - v_scroll->get_page() / 8 ); - } - } - - if (mb.button_index==BUTTON_WHEEL_DOWN && mb.pressed) { - - if (mb.mod.command) { - zoom->set_value(zoom->get_value() - zoom->get_step()); - } else { - v_scroll->set_value( v_scroll->get_value() + v_scroll->get_page() / 8 ); - } - } - - if (mb.button_index==BUTTON_RIGHT && mb.pressed) { - - Point2 mpos = Point2(mb.x,mb.y)-ofs; - - if (selection.size() == 0) { - // Auto-select on right-click if nothing is selected - // Note: This code is pretty much duplicated from the left click code, - // both codes could be moved into a function to avoid the duplicated code. - Point2 mpos = Point2(mb.x,mb.y)-ofs; - - if (mpos.y < h ) { - return; - } - - mpos.y -= h; - - int idx = mpos.y / h; - idx+=v_scroll->get_value(); - if (idx <0 || idx>=animation->get_track_count()) - break; - - if (mpos.x < name_limit) { - } else if (mpos.x < settings_limit) { - float pos = mpos.x - name_limit; - pos/=_get_zoom_scale(); - pos+=h_scroll->get_value(); - float w_time = (type_icon[0]->get_width() / _get_zoom_scale())/2.0; - - int kidx = animation->track_find_key(idx,pos); - int kidx_n = kidx+1; - int key=-1; - - if (kidx>=0 && kidx<animation->track_get_key_count(idx)) { - - float kpos = animation->track_get_key_time(idx,kidx); - if (ABS(pos-kpos)<=w_time) { - - key=kidx; - } - } - - if (key==-1 && kidx_n>=0 && kidx_n<animation->track_get_key_count(idx)) { - - float kpos = animation->track_get_key_time(idx,kidx_n); - if (ABS(pos-kpos)<=w_time) { - - key=kidx_n; - } - } - - if (key==-1) { - - click.click=ClickOver::CLICK_SELECT_KEYS; - click.at=Point2(mb.x,mb.y); - click.to=click.at; - click.shift=mb.mod.shift; - selected_track=idx; - track_editor->update(); - //drag select region - return; - - } - - - - SelectedKey sk; - sk.track=idx; - sk.key=key; - KeyInfo ki; - ki.pos= animation->track_get_key_time(idx,key); - click.shift=mb.mod.shift; - click.selk=sk; - - - if (!mb.mod.shift && !selection.has(sk)) - _clear_selection(); - - selection.insert(sk,ki); - - click.click=ClickOver::CLICK_MOVE_KEYS; - click.at=Point2(mb.x,mb.y); - click.to=click.at; - update(); - selected_track=idx; - track_editor->update(); - - if (_edit_if_single_selection() && mb.mod.command) { - edit_button->set_pressed(true); - key_editor_tab->show(); - } - } - } - - if (selection.size()) { - // User has right clicked and we have a selection, show a popup menu with options - track_menu->clear(); - track_menu->set_size(Point2(1,1)); - track_menu->add_item(TTR("Duplicate Selection"), RIGHT_MENU_DUPLICATE); - track_menu->add_item(TTR("Duplicate Transposed"), RIGHT_MENU_DUPLICATE_TRANSPOSE); - track_menu->add_item(TTR("Remove Selection"), RIGHT_MENU_REMOVE); - - track_menu->set_pos(te->get_global_pos()+mpos); - - interp_editing=-1; - cont_editing=-1; - wrap_editing=-1; - - track_menu->popup(); - } - } - - if (mb.button_index==BUTTON_LEFT && !(mb.button_mask&~BUTTON_MASK_LEFT)) { - - - if (mb.pressed) { - - Point2 mpos = Point2(mb.x,mb.y)-ofs; - - if (mpos.y < h ) { - - - if (mpos.x<name_limit && mpos.x > (name_limit - hsep - hsize_icon->get_width())) { - - - click.click=ClickOver::CLICK_RESIZE_NAMES; - click.at=Point2(mb.x,mb.y); - click.to=click.at; - click.at.y=name_limit; - - } - - if (mpos.x>=name_limit && mpos.x<settings_limit) { - //seek - //int zoomw = settings_limit-name_limit; - float scale = _get_zoom_scale(); - float pos = h_scroll->get_value() + (mpos.x-name_limit) / scale; - if (animation->get_step()) - pos=Math::stepify(pos,animation->get_step()); - - if (pos<0 ) - pos=0; - if (pos>=animation->get_length()) - pos=animation->get_length(); - timeline_pos=pos; - click.click=ClickOver::CLICK_DRAG_TIMELINE; - click.at=Point2(mb.x,mb.y); - click.to=click.at; - emit_signal("timeline_changed",pos,false); - - } - - return; - } - - mpos.y -= h; - - int idx = mpos.y / h; - idx+=v_scroll->get_value(); - if (idx <0) - break; - - if (idx>=animation->get_track_count()) { - - if (mpos.x >= name_limit && mpos.x<settings_limit) { - - click.click=ClickOver::CLICK_SELECT_KEYS; - click.at=Point2(mb.x,mb.y); - click.to=click.at; - //drag select region - } - - break; - } - - if (mpos.x < name_limit) { - //name column - - // area - if (idx!=selected_track) { - - selected_track=idx; - track_editor->update(); - break; - } - - Rect2 area(ofs.x,ofs.y+((int(mpos.y)/h)+1)*h,name_limit, h ); - track_name->set_text(animation->track_get_path(idx)); - track_name->set_pos( te->get_global_pos() + area.pos); - track_name->set_size(area.size); - track_name->show_modal(); - track_name->grab_focus(); - track_name->select_all(); - track_name_editing=idx; - - } else if (mpos.x < settings_limit) { - - float pos = mpos.x - name_limit; - pos/=_get_zoom_scale(); - pos+=h_scroll->get_value(); - float w_time = (type_icon[0]->get_width() / _get_zoom_scale())/2.0; - - int kidx = animation->track_find_key(idx,pos); - int kidx_n = kidx+1; - int key=-1; - - if (kidx>=0 && kidx<animation->track_get_key_count(idx)) { - - float kpos = animation->track_get_key_time(idx,kidx); - if (ABS(pos-kpos)<=w_time) { - - key=kidx; - } - } - - if (key==-1 && kidx_n>=0 && kidx_n<animation->track_get_key_count(idx)) { - - float kpos = animation->track_get_key_time(idx,kidx_n); - if (ABS(pos-kpos)<=w_time) { - - key=kidx_n; - } - } - - if (key==-1) { - - click.click=ClickOver::CLICK_SELECT_KEYS; - click.at=Point2(mb.x,mb.y); - click.to=click.at; - click.shift=mb.mod.shift; - selected_track=idx; - track_editor->update(); - //drag select region - return; - - } - - - - SelectedKey sk; - sk.track=idx; - sk.key=key; - KeyInfo ki; - ki.pos= animation->track_get_key_time(idx,key); - click.shift=mb.mod.shift; - click.selk=sk; - - - if (!mb.mod.shift && !selection.has(sk)) - _clear_selection(); - - selection.insert(sk,ki); - - click.click=ClickOver::CLICK_MOVE_KEYS; - click.at=Point2(mb.x,mb.y); - click.to=click.at; - update(); - selected_track=idx; - track_editor->update(); - - if (_edit_if_single_selection() && mb.mod.command) { - edit_button->set_pressed(true); - key_editor_tab->show(); - } - } else { - //button column - int ofsx = size.width - mpos.x; - if (ofsx < 0) - break; -/* - if (ofsx < remove_icon->get_width()) { - - undo_redo->create_action("Remove Anim Track"); - undo_redo->add_do_method(animation.ptr(),"remove_track",idx); - undo_redo->add_undo_method(animation.ptr(),"add_track",animation->track_get_type(idx),idx); - undo_redo->add_undo_method(animation.ptr(),"track_set_path",idx,animation->track_get_path(idx)); - //todo interpolation - for(int i=0;i<animation->track_get_key_count(idx);i++) { - - Variant v = animation->track_get_key_value(idx,i); - float time = animation->track_get_key_time(idx,i); - float trans = animation->track_get_key_transition(idx,i); - - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",idx,time,v); - undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",idx,i,trans); - - } - - undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_type",idx,animation->track_get_interpolation_type(idx)); - if (animation->track_get_type(idx)==Animation::TYPE_VALUE) { - undo_redo->add_undo_method(animation.ptr(),"value_track_set_continuous",idx,animation->value_track_is_continuous(idx)); - - } - - undo_redo->commit_action(); - - - return; - } - - ofsx-=hsep+remove_icon->get_width(); - - if (ofsx < move_down_icon->get_width()) { - - if (idx < animation->get_track_count() -1) { - undo_redo->create_action("Move Anim Track Down"); - undo_redo->add_do_method(animation.ptr(),"track_move_up",idx); - undo_redo->add_undo_method(animation.ptr(),"track_move_down",idx+1); - undo_redo->commit_action(); - } - return; - } - - ofsx-=hsep+move_down_icon->get_width(); - - if (ofsx < move_up_icon->get_width()) { - - if (idx >0) { - undo_redo->create_action("Move Anim Track Up"); - undo_redo->add_do_method(animation.ptr(),"track_move_down",idx); - undo_redo->add_undo_method(animation.ptr(),"track_move_up",idx-1); - undo_redo->commit_action(); - } - return; - } - - - ofsx-=hsep*3+move_up_icon->get_width(); - */ - - - if (ofsx < track_ofs[1]) { - - track_menu->clear(); - track_menu->set_size(Point2(1,1)); - static const char *interp_name[2]={"Clamp Loop Interp","Wrap Loop Interp"}; - for(int i=0;i<2;i++) { - track_menu->add_icon_item(wrap_icon[i],interp_name[i]); - } - - int popup_y = ofs.y+((int(mpos.y)/h)+2)*h; - int popup_x = size.width-track_ofs[1]; - - track_menu->set_pos(te->get_global_pos()+Point2(popup_x,popup_y)); - - - wrap_editing=idx; - interp_editing=-1; - cont_editing=-1; - - track_menu->popup(); - - return; - } - - - if (ofsx < track_ofs[2]) { - - track_menu->clear(); - track_menu->set_size(Point2(1,1)); - static const char *interp_name[3]={"Nearest","Linear","Cubic"}; - for(int i=0;i<3;i++) { - track_menu->add_icon_item(interp_icon[i],interp_name[i]); - } - - int popup_y = ofs.y+((int(mpos.y)/h)+2)*h; - int popup_x = size.width-track_ofs[2]; - - track_menu->set_pos(te->get_global_pos()+Point2(popup_x,popup_y)); - - - interp_editing=idx; - cont_editing=-1; - wrap_editing=-1; - - track_menu->popup(); - - return; - } - - if (ofsx < track_ofs[3]) { - - track_menu->clear(); - track_menu->set_size(Point2(1,1)); - String cont_name[3]={TTR("Continuous"),TTR("Discrete"),TTR("Trigger")}; - for(int i=0;i<3;i++) { - track_menu->add_icon_item(cont_icon[i],cont_name[i]); - } - - - int popup_y = ofs.y+((int(mpos.y)/h)+2)*h; - int popup_x = size.width-track_ofs[3]; - - track_menu->set_pos(te->get_global_pos()+Point2(popup_x,popup_y)); - - interp_editing=-1; - wrap_editing=-1; - cont_editing=idx; - - track_menu->popup(); - - return; - } - - if (ofsx < track_ofs[4]) { - - Animation::TrackType tt = animation->track_get_type(idx); - - float pos = timeline_pos; - int existing = animation->track_find_key(idx,pos,true); - - - - Variant newval; - - if (tt==Animation::TYPE_TRANSFORM) { - Dictionary d; - d["loc"]=Vector3(); - d["rot"]=Quat(); - d["scale"]=Vector3(); - newval=d; - - } else if (tt==Animation::TYPE_METHOD) { - - Dictionary d; - d["method"]=""; - d["args"]=Vector<Variant>(); - - - newval=d; - } else if (tt==Animation::TYPE_VALUE) { - - NodePath np; - PropertyInfo inf = _find_hint_for_track(idx,np); - if (inf.type!=Variant::NIL) { - - Variant::CallError err; - newval=Variant::construct(inf.type,NULL,0,err); - - } - - if (newval.get_type()==Variant::NIL) { - //popup a new type - cvi_track=idx; - cvi_pos=pos; - - type_menu->set_pos( get_global_pos() + mpos +ofs ); - type_menu->popup(); - return; - } - - } - - undo_redo->create_action(TTR("Anim Add Key")); - - undo_redo->add_do_method(animation.ptr(),"track_insert_key",idx,pos,newval,1); - undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",idx,pos); - - if (existing!=-1) { - Variant v = animation->track_get_key_value(idx,existing); - float trans = animation->track_get_key_transition(idx,existing); - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",idx,pos,v,trans); - } - - undo_redo->commit_action(); - - - return; - } - - } - - } else { - - switch(click.click) { - case ClickOver::CLICK_SELECT_KEYS: { - - - float zoom_scale=_get_zoom_scale(); - float keys_from = h_scroll->get_value(); - float keys_to = keys_from + (settings_limit-name_limit) / zoom_scale; - - float from_time = keys_from + ( click.at.x - (name_limit+ofs.x)) / zoom_scale; - float to_time = keys_from + (click.to.x - (name_limit+ofs.x)) / zoom_scale; - - - if (to_time < from_time) - SWAP(from_time,to_time); - - if (from_time > keys_to || to_time < keys_from) - break; - - if (from_time < keys_from) - from_time = keys_from; - - if (to_time >= keys_to) - to_time = keys_to; - - - int from_track = int(click.at.y-ofs.y-h-sep) / h + v_scroll->get_value(); - int to_track = int(click.to.y-ofs.y-h-sep) / h + v_scroll->get_value(); - int from_mod = int(click.at.y-ofs.y-sep) % h; - int to_mod = int(click.to.y-ofs.y-sep) % h; - - if (to_track < from_track) { - - SWAP(from_track,to_track); - SWAP(from_mod,to_mod); - } - - - - - if ((from_mod > (h/2)) && ((click.at.y-ofs.y)>=(h+sep))) { - from_track++; - } - - if (to_mod < h/2) { - to_track--; - } - - if (from_track>to_track) { - if (!click.shift) - _clear_selection(); - _edit_if_single_selection(); - break; - } - - int tracks_from = v_scroll->get_value(); - int tracks_to = v_scroll->get_value()+fit-1; - if (tracks_to>=animation->get_track_count()) - tracks_to=animation->get_track_count()-1; - - tracks_from=0; - tracks_to=animation->get_track_count()-1; - if (to_track >tracks_to) - to_track = tracks_to; - if (from_track<tracks_from) - from_track=tracks_from; - - if (from_track > tracks_to || to_track < tracks_from) { - if (!click.shift) - _clear_selection(); - _edit_if_single_selection(); - break; - } - - if (!click.shift) - _clear_selection(); - - - int higher_track=0x7FFFFFFF; - for(int i=from_track;i<=to_track;i++) { - - int kc=animation->track_get_key_count(i); - for(int j=0;j<kc;j++) { - - float t = animation->track_get_key_time(i,j); - if (t<from_time) - continue; - if (t>to_time) - break; - - if (i<higher_track) - higher_track=i; - - SelectedKey sk; - sk.track=i; - sk.key=j; - KeyInfo ki; - ki.pos=t; - selection[sk]=ki; - } - } - - if (higher_track!=0x7FFFFFFF) { - selected_track=higher_track; - track_editor->update(); - } - - - _edit_if_single_selection(); - - - } break; - case ClickOver::CLICK_MOVE_KEYS: { - - if (selection.empty()) - break; - if (click.at==click.to) { - - if (!click.shift) { - - KeyInfo ki=selection[click.selk]; - _clear_selection(); - selection[click.selk]=ki; - _edit_if_single_selection(); - } - - break; - } - - float from_t = 1e20; - - for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { - float t = animation->track_get_key_time(E->key().track,E->key().key); - if (t<from_t) - from_t=t; - - } - - float motion = from_t+(click.to.x - click.at.x)/_get_zoom_scale(); - if (step->get_value()) - motion = Math::stepify(motion,step->get_value()); - - - - - undo_redo->create_action(TTR("Anim Move Keys")); - - List<_AnimMoveRestore> to_restore; - - // 1-remove the keys - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - undo_redo->add_do_method(animation.ptr(),"track_remove_key",E->key().track,E->key().key); - } - // 2- remove overlapped keys - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - float newtime = E->get().pos-from_t+motion; - int idx = animation->track_find_key(E->key().track,newtime,true); - if (idx==-1) - continue; - SelectedKey sk; - sk.key=idx; - sk.track=E->key().track; - if (selection.has(sk)) - continue; //already in selection, don't save - - undo_redo->add_do_method(animation.ptr(),"track_remove_key_at_pos",E->key().track,newtime); - _AnimMoveRestore amr; - - amr.key=animation->track_get_key_value(E->key().track,idx); - amr.track=E->key().track; - amr.time=newtime; - amr.transition=animation->track_get_key_transition(E->key().track,idx); - - to_restore.push_back(amr); - - } - - // 3-move the keys (re insert them) - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - float newpos=E->get().pos-from_t+motion; - /* - if (newpos<0) - continue; //no add at the begining - */ - undo_redo->add_do_method(animation.ptr(),"track_insert_key",E->key().track,newpos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); - - } - - // 4-(undo) remove inserted keys - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - float newpos=E->get().pos+-from_t+motion; - /* - if (newpos<0) - continue; //no remove what no inserted - */ - undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",E->key().track,newpos); - - } - - // 5-(undo) reinsert keys - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",E->key().track,E->get().pos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); - - } - - // 6-(undo) reinsert overlapped keys - for(List<_AnimMoveRestore>::Element *E=to_restore.front();E;E=E->next()) { - - _AnimMoveRestore &amr = E->get(); - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",amr.track,amr.time,amr.key,amr.transition); - - } - - // 6-(undo) reinsert overlapped keys - for(List<_AnimMoveRestore>::Element *E=to_restore.front();E;E=E->next()) { - - _AnimMoveRestore &amr = E->get(); - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",amr.track,amr.time,amr.key,amr.transition); - - } - - undo_redo->add_do_method(this,"_clear_selection_for_anim",animation); - undo_redo->add_undo_method(this,"_clear_selection_for_anim",animation); - - // 7-reselect - - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - float oldpos=E->get().pos; - float newpos=oldpos-from_t+motion; - //if (newpos>=0) - undo_redo->add_do_method(this,"_select_at_anim",animation,E->key().track,newpos); - undo_redo->add_undo_method(this,"_select_at_anim",animation,E->key().track,oldpos); - - } - - undo_redo->commit_action(); - _edit_if_single_selection(); - - } break; - default: {} - } - - //button released - click.click=ClickOver::CLICK_NONE; - track_editor->update(); - - - } - } - - } break; - - case InputEvent::MOUSE_MOTION: { - - const InputEventMouseMotion &mb = p_input.mouse_motion; - - mouse_over.over=MouseOver::OVER_NONE; - mouse_over.track=-1; - te->update(); - track_editor->set_tooltip(""); - - if (!track_editor->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) - track_editor->call_deferred("grab_focus"); - - - if (click.click!=ClickOver::CLICK_NONE) { - - switch(click.click) { - case ClickOver::CLICK_RESIZE_NAMES: { - - - float base = click.at.y; - float clickp = click.at.x-ofs.x; - float dif = base - clickp; - - float target = mb.x+dif-ofs.x; - - float ratio = target / settings_limit; - - if (ratio>0.9) - ratio=0.9; - else if (ratio<0.2) - ratio=0.2; - - name_column_ratio=ratio; - - - } break; - case ClickOver::CLICK_DRAG_TIMELINE: { - - Point2 mpos = Point2(mb.x,mb.y)-ofs; - /* - if (mpos.x<name_limit) - mpos.x=name_limit; - if (mpos.x>settings_limit) - mpos.x=settings_limit; - */ - - - //int zoomw = settings_limit-name_limit; - float scale = _get_zoom_scale(); - float pos = h_scroll->get_value() + (mpos.x-name_limit) / scale; - if (animation->get_step()) { - pos=Math::stepify(pos,animation->get_step()); - - } - if (pos<0) - pos=0; - if (pos>=animation->get_length()) - pos=animation->get_length(); - - if (pos < h_scroll->get_value()) { - h_scroll->set_value(pos); - } else if (pos > h_scroll->get_value() + (settings_limit - name_limit) / scale) { - h_scroll->set_value( pos - (settings_limit - name_limit) / scale ); - } - - timeline_pos=pos; - emit_signal("timeline_changed",pos,true); - - - - } break; - case ClickOver::CLICK_SELECT_KEYS: { - - click.to=Point2(mb.x,mb.y); - if (click.to.y<h && click.at.y>h && mb.relative_y<0) { - - float prev = v_scroll->get_value(); - v_scroll->set_value( v_scroll->get_value() -1 ); - if (prev!=v_scroll->get_value()) - click.at.y+=h; - - - } - if (click.to.y>size.height && click.at.y<size.height && mb.relative_y>0) { - - float prev = v_scroll->get_value(); - v_scroll->set_value( v_scroll->get_value() +1 ); - if (prev!=v_scroll->get_value()) - click.at.y-=h; - } - - } break; - case ClickOver::CLICK_MOVE_KEYS: { - - click.to=Point2(mb.x,mb.y); - } break; - default: {} - } - - return; - } else if (mb.button_mask&BUTTON_MASK_MIDDLE) { - - int rel = mb.relative_x; - float relf = rel / _get_zoom_scale(); - h_scroll->set_value( h_scroll->get_value() - relf ); - } - - if (mb.button_mask==0) { - - - Point2 mpos = Point2(mb.x,mb.y)-ofs; - - if (mpos.y < h ) { -#if 0 - //seek - //int zoomw = settings_limit-name_limit; - float scale = _get_zoom_scale(); - float pos = h_scroll->get_val() + (mpos.y-name_limit) / scale; - if (pos<0 ) - pos=0; - if (pos>=animation->get_length()) - pos=animation->get_length(); - timeline->set_val(pos); -#endif - return; - } - - mpos.y -= h; - - int idx = mpos.y / h; - idx+=v_scroll->get_value(); - if (idx <0 || idx>=animation->get_track_count()) - break; - - mouse_over.track=idx; - - if (mpos.x < name_limit) { - //name column - - - mouse_over.over=MouseOver::OVER_NAME; - - } else if (mpos.x < settings_limit) { - - float pos = mpos.x - name_limit; - pos/=_get_zoom_scale(); - pos+=h_scroll->get_value(); - float w_time = (type_icon[0]->get_width() / _get_zoom_scale())/2.0; - - int kidx = animation->track_find_key(idx,pos); - int kidx_n = kidx+1; - - bool found = false; - - if (kidx>=0 && kidx<animation->track_get_key_count(idx)) { - - float kpos = animation->track_get_key_time(idx,kidx); - if (ABS(pos-kpos)<=w_time) { - - mouse_over.over=MouseOver::OVER_KEY; - mouse_over.track=idx; - mouse_over.over_key=kidx; - found=true; - } - } - - if (!found && kidx_n>=0 && kidx_n<animation->track_get_key_count(idx)) { - - float kpos = animation->track_get_key_time(idx,kidx_n); - if (ABS(pos-kpos)<=w_time) { - - mouse_over.over=MouseOver::OVER_KEY; - mouse_over.track=idx; - mouse_over.over_key=kidx_n; - found=true; - } - } - - - if (found) { - - String text; - text="time: "+rtos(animation->track_get_key_time(idx,mouse_over.over_key))+"\n"; - - - switch(animation->track_get_type(idx)) { - - case Animation::TYPE_TRANSFORM: { - - Dictionary d = animation->track_get_key_value(idx,mouse_over.over_key); - if (d.has("loc")) - text+="loc: "+String(d["loc"])+"\n"; - if (d.has("rot")) - text+="rot: "+String(d["rot"])+"\n"; - if (d.has("scale")) - text+="scale: "+String(d["scale"])+"\n"; - } break; - case Animation::TYPE_VALUE: { - - Variant v = animation->track_get_key_value(idx,mouse_over.over_key); - //text+="value: "+String(v)+"\n"; - - bool prop_exists=false; - Variant::Type valid_type=Variant::NIL; - Object *obj=NULL; - - RES res; - Node *node = root->get_node_and_resource(animation->track_get_path(idx),res); - - if (res.is_valid()) { - obj=res.ptr(); - } else if (node) { - obj=node; - } - - if (obj) { - valid_type=obj->get_static_property_type(animation->track_get_path(idx).get_property(),&prop_exists); - } - - text+="type: "+Variant::get_type_name(v.get_type())+"\n"; - if (prop_exists && !Variant::can_convert(v.get_type(),valid_type)) { - text+="value: "+String(v)+" (Invalid, expected type: "+Variant::get_type_name(valid_type)+")\n"; - } else { - text+="value: "+String(v)+"\n"; - } - - } break; - case Animation::TYPE_METHOD: { - - - Dictionary d = animation->track_get_key_value(idx,mouse_over.over_key); - if (d.has("method")) - text+=String(d["method"]); - text+="("; - Vector<Variant> args; - if (d.has("args")) - args=d["args"]; - for(int i=0;i<args.size();i++) { - - if (i>0) - text+=", "; - text+=String(args[i]); - } - text+=")\n"; - - } break; - } - text+="easing: "+rtos(animation->track_get_key_transition(idx,mouse_over.over_key)); - - - - track_editor->set_tooltip(text); - return; - - } - - } else { - //button column - int ofsx = size.width - mpos.x; - if (ofsx < 0) - break; -/* - if (ofsx < remove_icon->get_width()) { - - mouse_over.over=MouseOver::OVER_REMOVE; - - return; - } - - ofsx-=hsep+remove_icon->get_width(); - - if (ofsx < move_down_icon->get_width()) { - - mouse_over.over=MouseOver::OVER_DOWN; - return; - } - - ofsx-=hsep+move_down_icon->get_width(); - - if (ofsx < move_up_icon->get_width()) { - - mouse_over.over=MouseOver::OVER_UP; - return; - } - - ofsx-=hsep*3+move_up_icon->get_width(); - - */ - - if (ofsx < down_icon->get_width() + wrap_icon[0]->get_width() + hsep*3) { - - mouse_over.over=MouseOver::OVER_WRAP; - return; - } - - ofsx-=hsep*3+wrap_icon[0]->get_width() + down_icon->get_width(); - - if (ofsx < down_icon->get_width() + interp_icon[0]->get_width() + hsep*3) { - - mouse_over.over=MouseOver::OVER_INTERP; - return; - } - - - ofsx-=hsep*2+interp_icon[0]->get_width() + down_icon->get_width(); - - if (ofsx < down_icon->get_width() + cont_icon[0]->get_width() +hsep*3) { - - mouse_over.over=MouseOver::OVER_VALUE; - return; - } - - ofsx-=hsep*3+cont_icon[0]->get_width() + down_icon->get_width(); - - if (ofsx < add_key_icon->get_width()) { - - mouse_over.over=MouseOver::OVER_ADD_KEY; - return; - } - - - } - - } - - } break; - - } -} - -void AnimationKeyEditor::_notification(int p_what) { - - - switch(p_what) { - case NOTIFICATION_VISIBILITY_CHANGED: { - - EditorNode::get_singleton()->update_keying(); - emit_signal("keying_changed"); - } break; - - case NOTIFICATION_ENTER_TREE: { - - key_editor->edit(key_edit); - - zoomicon->set_texture( get_icon("Zoom","EditorIcons") ); - - menu_add_track->set_icon(get_icon("AddTrack","EditorIcons")); - menu_add_track->get_popup()->add_icon_item(get_icon("KeyValue","EditorIcons"),"Add Normal Track",ADD_TRACK_MENU_ADD_VALUE_TRACK); - menu_add_track->get_popup()->add_icon_item(get_icon("KeyXform","EditorIcons"),"Add Transform Track",ADD_TRACK_MENU_ADD_TRANSFORM_TRACK); - menu_add_track->get_popup()->add_icon_item(get_icon("KeyCall","EditorIcons"),"Add Call Func Track",ADD_TRACK_MENU_ADD_CALL_TRACK); - - menu_track->set_icon(get_icon("Tools","EditorIcons")); - menu_track->get_popup()->add_item(TTR("Scale Selection"),TRACK_MENU_SCALE); - menu_track->get_popup()->add_item(TTR("Scale From Cursor"),TRACK_MENU_SCALE_PIVOT); - menu_track->get_popup()->add_separator(); - menu_track->get_popup()->add_item(TTR("Duplicate Selection"),TRACK_MENU_DUPLICATE); - menu_track->get_popup()->add_item(TTR("Duplicate Transposed"),TRACK_MENU_DUPLICATE_TRANSPOSE); - menu_track->get_popup()->add_separator(); - menu_track->get_popup()->add_item(TTR("Goto Next Step"),TRACK_MENU_NEXT_STEP,KEY_MASK_CMD|KEY_RIGHT); - menu_track->get_popup()->add_item(TTR("Goto Prev Step"),TRACK_MENU_PREV_STEP,KEY_MASK_CMD|KEY_LEFT); - menu_track->get_popup()->add_separator(); - PopupMenu *tpp = memnew( PopupMenu ); - tpp->add_item(TTR("Linear"),TRACK_MENU_SET_ALL_TRANS_LINEAR); - tpp->add_item(TTR("Constant"),TRACK_MENU_SET_ALL_TRANS_CONSTANT); - tpp->add_item(TTR("In"),TRACK_MENU_SET_ALL_TRANS_IN); - tpp->add_item(TTR("Out"),TRACK_MENU_SET_ALL_TRANS_OUT); - tpp->add_item(TTR("In-Out"),TRACK_MENU_SET_ALL_TRANS_INOUT); - tpp->add_item(TTR("Out-In"),TRACK_MENU_SET_ALL_TRANS_OUTIN); - tpp->set_name(TTR("Transitions")); - tpp->connect("id_pressed",this,"_menu_track"); - optimize_dialog->connect("confirmed",this,"_animation_optimize"); - - menu_track->get_popup()->add_child(tpp); - //menu_track->get_popup()->add_submenu_item("Set Transitions..","Transitions"); - //menu_track->get_popup()->add_separator(); - menu_track->get_popup()->add_item(TTR("Optimize Animation"),TRACK_MENU_OPTIMIZE); - menu_track->get_popup()->add_item(TTR("Clean-Up Animation"),TRACK_MENU_CLEAN_UP); - - curve_linear->set_icon(get_icon("CurveLinear","EditorIcons")); - curve_in->set_icon(get_icon("CurveIn","EditorIcons")); - curve_out->set_icon(get_icon("CurveOut","EditorIcons")); - curve_inout->set_icon(get_icon("CurveInOut","EditorIcons")); - curve_outin->set_icon(get_icon("CurveOutIn","EditorIcons")); - curve_constant->set_icon(get_icon("CurveConstant","EditorIcons")); - - curve_linear->connect("pressed",this,"_menu_track",varray(CURVE_SET_LINEAR)); - curve_in->connect("pressed",this,"_menu_track",varray(CURVE_SET_IN)); - curve_out->connect("pressed",this,"_menu_track",varray(CURVE_SET_OUT)); - curve_inout->connect("pressed",this,"_menu_track",varray(CURVE_SET_INOUT)); - curve_outin->connect("pressed",this,"_menu_track",varray(CURVE_SET_OUTIN)); - curve_constant->connect("pressed",this,"_menu_track",varray(CURVE_SET_CONSTANT)); - - - move_up_button->set_icon(get_icon("MoveUp","EditorIcons")); - move_down_button->set_icon(get_icon("MoveDown","EditorIcons")); - remove_button->set_icon(get_icon("Remove","EditorIcons")); - edit_button->set_icon(get_icon("EditKey","EditorIcons")); - edit_button->connect("pressed",this,"_toggle_edit_curves"); - - loop->set_icon(get_icon("Loop","EditorIcons")); - curve_edit->connect("transition_changed",this,"_curve_transition_changed"); - - //edit_button->add_color_override("font_color",get_color("font_color","Tree")); - //edit_button->add_color_override("font_color_hover",get_color("font_color","Tree")); - - { - - right_data_size_cache=0; - int hsep = get_constant("hseparation","Tree"); - Ref<Texture> remove_icon = get_icon("Remove","EditorIcons"); - Ref<Texture> move_up_icon = get_icon("MoveUp","EditorIcons"); - Ref<Texture> move_down_icon = get_icon("MoveDown","EditorIcons"); - Ref<Texture> down_icon = get_icon("select_arrow","Tree"); - Ref<Texture> add_key_icon = get_icon("TrackAddKey","EditorIcons"); - Ref<Texture> interp_icon[3]={ - get_icon("InterpRaw","EditorIcons"), - get_icon("InterpLinear","EditorIcons"), - get_icon("InterpCubic","EditorIcons") - }; - Ref<Texture> cont_icon[3]={ - get_icon("TrackContinuous","EditorIcons"), - get_icon("TrackDiscrete","EditorIcons"), - get_icon("TrackTrigger","EditorIcons") - }; - - Ref<Texture> wrap_icon[2]={ - get_icon("InterpWrapClamp","EditorIcons"), - get_icon("InterpWrapLoop","EditorIcons"), - }; - - //right_data_size_cache = remove_icon->get_width() + move_up_icon->get_width() + move_down_icon->get_width() + down_icon->get_width() *2 + interp_icon[0]->get_width() + cont_icon[0]->get_width() + add_key_icon->get_width() + hsep*11; - right_data_size_cache = down_icon->get_width() *3 + add_key_icon->get_width() + interp_icon[0]->get_width() + cont_icon[0]->get_width() + wrap_icon[0]->get_width() + hsep*8; - - - } - call_select->connect("selected",this,"_add_call_track"); - //rename_anim->set_icon( get_icon("Rename","EditorIcons") ); -/* - edit_anim->set_icon( get_icon("Edit","EditorIcons") ); - blend_anim->set_icon( get_icon("Blend","EditorIcons") ); - play->set_icon( get_icon("Play","EditorIcons") ); - stop->set_icon( get_icon("Stop","EditorIcons") ); - pause->set_icon( get_icon("Pause","EditorIcons") ); -*/ - //menu->set_icon(get_icon("Animation","EditorIcons")); - //play->set_icon(get_icon("AnimationPlay","EditorIcons")); - //menu->set_icon(get_icon("Animation","EditorIcons")); - _update_menu(); - - } break; - - - } - -} - - - -void AnimationKeyEditor::_scroll_changed(double) { - - if (te_drawing) - return; - - track_editor->update(); -} - - - -void AnimationKeyEditor::_update_paths() { - - if (animation.is_valid()) { - //timeline->set_max(animation->get_length()); - //timeline->set_step(0.01); - track_editor->update(); - length->set_value(animation->get_length()); - step->set_value(animation->get_step()); - } -} - - -void AnimationKeyEditor::_root_removed() { - - root=NULL; -} - -void AnimationKeyEditor::_update_menu() { - - - updating=true; - - if (animation.is_valid()) { - - length->set_value(animation->get_length()); - loop->set_pressed(animation->has_loop()); - step->set_value(animation->get_step()); - } - - track_editor->update(); - updating=false; - -} -void AnimationKeyEditor::_clear_selection() { - - selection.clear(); - key_edit->animation=Ref<Animation>(); - key_edit->track=0; - key_edit->key_ofs=0; - key_edit->hint=PropertyInfo(); - key_edit->base=NodePath(); - key_edit->notify_change(); - -} - - -void AnimationKeyEditor::set_animation(const Ref<Animation>& p_anim) { - - if (animation.is_valid()) - animation->disconnect("changed",this,"_update_paths"); - animation=p_anim; - if (animation.is_valid()) - animation->connect("changed",this,"_update_paths"); - - timeline_pos=0; - _clear_selection(); - _update_paths(); - - _update_menu(); - selected_track=-1; - _edit_if_single_selection(); - - EditorNode::get_singleton()->update_keying(); -} - -void AnimationKeyEditor::set_root(Node *p_root) { - - if (root) - root->disconnect("tree_exited",this,"_root_removed"); - - root=p_root; - - if (root) - root->connect("tree_exited",this,"_root_removed",make_binds(),CONNECT_ONESHOT); - - -} - -Node *AnimationKeyEditor::get_root() const { - - return root; -} - - - - - - -void AnimationKeyEditor::update_keying() { - - bool keying_enabled=is_visible_in_tree() && animation.is_valid(); - - if (keying_enabled==keying) - return; - - keying=keying_enabled; - _update_menu(); - emit_signal("keying_changed"); - -} - -bool AnimationKeyEditor::has_keying() const { - - return keying; -} - -void AnimationKeyEditor::_query_insert(const InsertData& p_id) { - - - if (insert_frame!=Engine::get_singleton()->get_frames_drawn()) { - //clear insert list for the frame if frame changed - if (insert_confirm->is_visible_in_tree()) - return; //do nothing - insert_data.clear(); - insert_query=false; - } - insert_frame=Engine::get_singleton()->get_frames_drawn(); - - for (List<InsertData>::Element *E=insert_data.front();E;E=E->next()) { - //prevent insertion of multiple tracks - if (E->get().path==p_id.path) - return; //already inserted a track for this on this frame - } - - insert_data.push_back(p_id); - - if (p_id.track_idx==-1) { - if (bool(EDITOR_DEF("editors/animation/confirm_insert_track",true))) { - //potential new key, does not exist - if (insert_data.size()==1) - insert_confirm->set_text(vformat(TTR("Create NEW track for %s and insert key?"),p_id.query)); - else - insert_confirm->set_text(vformat(TTR("Create %d NEW tracks and insert keys?"),insert_data.size())); - - insert_confirm->get_ok()->set_text(TTR("Create")); - insert_confirm->popup_centered_minsize(); - insert_query=true; - } else { - call_deferred("_insert_delay"); - insert_queue=true; - } - - } else { - if (!insert_query && !insert_queue) { - call_deferred("_insert_delay"); - insert_queue=true; - } - } - -} - -void AnimationKeyEditor::insert_transform_key(Spatial *p_node,const String& p_sub,const Transform& p_xform) { - - if (!keying) - return; - if (!animation.is_valid()) - return; - - - ERR_FAIL_COND(!root); - //let's build a node path - String path = root->get_path_to(p_node); - if (p_sub!="") - path+=":"+p_sub; - - NodePath np=path; - - int track_idx=-1; - - for(int i=0;i<animation->get_track_count();i++) { - - if (animation->track_get_type(i)!=Animation::TYPE_TRANSFORM) - continue; - if (animation->track_get_path(i)!=np) - continue; - - track_idx=i; - break; - } - - InsertData id; - Dictionary val; - - id.path=np; - id.track_idx=track_idx; - id.value=p_xform; - id.type=Animation::TYPE_TRANSFORM; - id.query="node '"+p_node->get_name()+"'"; - id.advance=false; - - //dialog insert - - _query_insert(id); - -} - - -void AnimationKeyEditor::insert_node_value_key(Node* p_node, const String& p_property,const Variant& p_value,bool p_only_if_exists) { - - ERR_FAIL_COND(!root); - //let's build a node path - - Node *node = p_node; - - String path = root->get_path_to(node); - - for(int i=1;i<history->get_path_size();i++) { - - String prop = history->get_path_property(i); - ERR_FAIL_COND(prop==""); - path+=":"+prop; - } - - - path+=":"+p_property; - - NodePath np = path; - - //locate track - - int track_idx=-1; - - for(int i=0;i<animation->get_track_count();i++) { - - if (animation->track_get_type(i)!=Animation::TYPE_VALUE) - continue; - if (animation->track_get_path(i)!=np) - continue; - - track_idx=i; - break; - } - - if (p_only_if_exists && track_idx==-1) - return; - InsertData id; - id.path=np; - id.track_idx=track_idx; - id.value=p_value; - id.type=Animation::TYPE_VALUE; - id.query="property '"+p_property+"'"; - id.advance=false; - //dialog insert - _query_insert(id); - - - -} - -void AnimationKeyEditor::insert_value_key(const String& p_property,const Variant& p_value,bool p_advance) { - - ERR_FAIL_COND(!root); - //let's build a node path - ERR_FAIL_COND(history->get_path_size()==0); - Object *obj = ObjectDB::get_instance(history->get_path_object(0)); - ERR_FAIL_COND(!obj || !obj->cast_to<Node>()); - - Node *node = obj->cast_to<Node>(); - - String path = root->get_path_to(node); - - for(int i=1;i<history->get_path_size();i++) { - - String prop = history->get_path_property(i); - ERR_FAIL_COND(prop==""); - path+=":"+prop; - } - - - - path+=":"+p_property; - - NodePath np = path; - - //locate track - - int track_idx=-1; - - for(int i=0;i<animation->get_track_count();i++) { - - if (animation->track_get_type(i)!=Animation::TYPE_VALUE) - continue; - if (animation->track_get_path(i)!=np) - continue; - - track_idx=i; - break; - } - - InsertData id; - id.path=np; - id.track_idx=track_idx; - id.value=p_value; - id.type=Animation::TYPE_VALUE; - id.query="property '"+p_property+"'"; - id.advance=p_advance; - //dialog insert - _query_insert(id); - - - -} - -void AnimationKeyEditor::_confirm_insert_list() { - - - undo_redo->create_action(TTR("Anim Create & Insert")); - - int last_track = animation->get_track_count(); - while(insert_data.size()) { - - last_track=_confirm_insert(insert_data.front()->get(),last_track); - insert_data.pop_front(); - } - - undo_redo->commit_action(); -} - -int AnimationKeyEditor::_confirm_insert(InsertData p_id,int p_last_track) { - - if (p_last_track==-1) - p_last_track=animation->get_track_count(); - - bool created=false; - if (p_id.track_idx<0) { - - created=true; - undo_redo->create_action(TTR("Anim Insert Track & Key")); - Animation::UpdateMode update_mode=Animation::UPDATE_DISCRETE; - - if (p_id.type==Animation::TYPE_VALUE) { - //wants a new tack - - { - //shitty hack - NodePath np; - animation->add_track(p_id.type); - animation->track_set_path(animation->get_track_count()-1,p_id.path); - PropertyInfo h = _find_hint_for_track(animation->get_track_count()-1,np); - animation->remove_track(animation->get_track_count()-1); //hack - - if ( h.type==Variant::REAL || - h.type==Variant::VECTOR2 || - h.type==Variant::RECT2 || - h.type==Variant::VECTOR3 || - h.type==Variant::RECT3 || - h.type==Variant::QUAT || - h.type==Variant::COLOR || - h.type==Variant::TRANSFORM ) { - - update_mode=Animation::UPDATE_CONTINUOUS; - } - - if (h.usage&PROPERTY_USAGE_ANIMATE_AS_TRIGGER) { - update_mode=Animation::UPDATE_TRIGGER; - } - } - } - - p_id.track_idx=p_last_track; - - undo_redo->add_do_method(animation.ptr(),"add_track",p_id.type); - undo_redo->add_do_method(animation.ptr(),"track_set_path",p_id.track_idx,p_id.path); - if (p_id.type==Animation::TYPE_VALUE) - undo_redo->add_do_method(animation.ptr(),"value_track_set_update_mode",p_id.track_idx,update_mode); - - } else { - undo_redo->create_action(TTR("Anim Insert Key")); - } - - float time = timeline_pos; - Variant value; - - - switch(p_id.type) { - - case Animation::TYPE_VALUE: { - - value = p_id.value; - - - } break; - case Animation::TYPE_TRANSFORM: { - - - Transform tr = p_id.value; - Dictionary d; - d["loc"]=tr.origin; - d["scale"]=tr.basis.get_scale(); - d["rot"]=Quat(tr.basis);//.orthonormalized(); - value=d; - } break; - default:{} - } - - - - undo_redo->add_do_method(animation.ptr(),"track_insert_key",p_id.track_idx,time,value); - - if (created) { - - //just remove the track - undo_redo->add_undo_method(animation.ptr(),"remove_track",p_last_track); - p_last_track++; - } else { - - undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",p_id.track_idx,time); - int existing = animation->track_find_key(p_id.track_idx,time,true); - if (existing!=-1) { - Variant v = animation->track_get_key_value(p_id.track_idx,existing); - float trans = animation->track_get_key_transition(p_id.track_idx,existing); - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",p_id.track_idx,time,v,trans); - } - } - - undo_redo->add_do_method(this,"update"); - undo_redo->add_undo_method(this,"update"); - undo_redo->add_do_method(track_editor,"update"); - undo_redo->add_undo_method(track_editor,"update"); - undo_redo->add_do_method(track_pos,"update"); - undo_redo->add_undo_method(track_pos,"update"); - - undo_redo->commit_action(); - - return p_last_track; - -} - - - - -Ref<Animation> AnimationKeyEditor::get_current_animation() const { - - return animation; -} - -void AnimationKeyEditor::_animation_len_changed(float p_len) { - - - if (updating) - return; - - if (!animation.is_null()) { - - undo_redo->create_action(TTR("Change Anim Len")); - undo_redo->add_do_method(animation.ptr(),"set_length",p_len); - undo_redo->add_undo_method(animation.ptr(),"set_length",animation->get_length()); - undo_redo->add_do_method(this,"_animation_len_update"); - undo_redo->add_undo_method(this,"_animation_len_update"); - undo_redo->commit_action(); - } -} - -void AnimationKeyEditor::_animation_len_update() { - - if (!animation.is_null()) - emit_signal(alc,animation->get_length()); -} - -void AnimationKeyEditor::_animation_changed() { - if (updating) - return; - _update_menu(); - -} - -void AnimationKeyEditor::_animation_loop_changed() { - - if (updating) - return; - - if (!animation.is_null()) { - - undo_redo->create_action(TTR("Change Anim Loop")); - undo_redo->add_do_method(animation.ptr(),"set_loop",loop->is_pressed()); - undo_redo->add_undo_method(animation.ptr(),"set_loop",!loop->is_pressed()); - undo_redo->commit_action(); - } - -} - - -void AnimationKeyEditor::_create_value_item(int p_type) { - - undo_redo->create_action(TTR("Anim Create Typed Value Key")); - - Variant::CallError ce; - Variant v = Variant::construct(Variant::Type(p_type),NULL,0,ce); - undo_redo->add_do_method(animation.ptr(),"track_insert_key",cvi_track,cvi_pos,v); - undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",cvi_track,cvi_pos); - - int existing = animation->track_find_key(cvi_track,cvi_pos,true); - - if (existing!=-1) { - Variant v = animation->track_get_key_value(cvi_track,existing); - float trans = animation->track_get_key_transition(cvi_track,existing); - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",cvi_track,cvi_pos,v,trans); - } - - undo_redo->commit_action(); - -} - - -void AnimationKeyEditor::set_anim_pos(float p_pos) { - - if (animation.is_null()) - return; - timeline_pos=p_pos; - update(); - track_pos->update(); - track_editor->update(); -} - -void AnimationKeyEditor::_pane_drag(const Point2& p_delta) { - - Size2 ecs = ec->get_custom_minimum_size(); - ecs.y-=p_delta.y; - if (ecs.y<100) - ecs.y=100; - ec->set_custom_minimum_size(ecs); - -} - -void AnimationKeyEditor::_insert_delay() { - - if (insert_query) { - //discard since it's entered into query mode - insert_queue=false; - return; - } - - undo_redo->create_action(TTR("Anim Insert")); - - int last_track = animation->get_track_count(); - bool advance=false; - while(insert_data.size()) { - - if (insert_data.front()->get().advance) - advance=true; - last_track=_confirm_insert(insert_data.front()->get(),last_track); - insert_data.pop_front(); - } - - undo_redo->commit_action(); - - if (advance) { - float step = animation->get_step(); - if (step==0) - step=1; - - float pos=timeline_pos; - - pos=Math::stepify(pos+step,step); - if (pos>animation->get_length()) - pos=animation->get_length(); - timeline_pos=pos; - track_pos->update(); - emit_signal("timeline_changed",pos,true); - } - insert_queue=false; -} - -void AnimationKeyEditor::_step_changed(float p_len) { - - updating=true; - if (!animation.is_null()) { - animation->set_step(p_len); - emit_signal("animation_step_changed",animation->get_step()); - } - updating=false; -} - -void AnimationKeyEditor::_scale() { - - - if (selection.empty()) - return; - - - float from_t = 1e20; - float to_t = -1e20; - float len = -1e20; - float pivot=0; - - for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { - float t = animation->track_get_key_time(E->key().track,E->key().key); - if (t<from_t) - from_t=t; - if (t>to_t) - to_t=t; - - } - - len=to_t-from_t; - if (last_menu_track_opt==TRACK_MENU_SCALE_PIVOT) { - pivot = timeline_pos; - - } else { - - pivot=from_t; - - } - - float s = scale->get_value(); - if (s==0) { - ERR_PRINT("Can't scale to 0"); - } - - - - undo_redo->create_action(TTR("Anim Scale Keys")); - - List<_AnimMoveRestore> to_restore; - - // 1-remove the keys - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - undo_redo->add_do_method(animation.ptr(),"track_remove_key",E->key().track,E->key().key); - } - // 2- remove overlapped keys - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - float newtime = (E->get().pos-from_t)*s+from_t; - int idx = animation->track_find_key(E->key().track,newtime,true); - if (idx==-1) - continue; - SelectedKey sk; - sk.key=idx; - sk.track=E->key().track; - if (selection.has(sk)) - continue; //already in selection, don't save - - undo_redo->add_do_method(animation.ptr(),"track_remove_key_at_pos",E->key().track,newtime); - _AnimMoveRestore amr; - - amr.key=animation->track_get_key_value(E->key().track,idx); - amr.track=E->key().track; - amr.time=newtime; - amr.transition=animation->track_get_key_transition(E->key().track,idx); - - to_restore.push_back(amr); - - } - -#define _NEW_POS(m_ofs) (((s>0)?m_ofs:from_t+(len-(m_ofs-from_t)))-pivot)*ABS(s)+from_t - // 3-move the keys (re insert them) - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - float newpos=_NEW_POS(E->get().pos); - undo_redo->add_do_method(animation.ptr(),"track_insert_key",E->key().track,newpos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); - - } - - // 4-(undo) remove inserted keys - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - float newpos=_NEW_POS(E->get().pos); - undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",E->key().track,newpos); - - } - - // 5-(undo) reinsert keys - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",E->key().track,E->get().pos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); - - } - - // 6-(undo) reinsert overlapped keys - for(List<_AnimMoveRestore>::Element *E=to_restore.front();E;E=E->next()) { - - _AnimMoveRestore &amr = E->get(); - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",amr.track,amr.time,amr.key,amr.transition); - - } - - // 6-(undo) reinsert overlapped keys - for(List<_AnimMoveRestore>::Element *E=to_restore.front();E;E=E->next()) { - - _AnimMoveRestore &amr = E->get(); - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",amr.track,amr.time,amr.key,amr.transition); - - } - - undo_redo->add_do_method(this,"_clear_selection_for_anim",animation); - undo_redo->add_undo_method(this,"_clear_selection_for_anim",animation); - - // 7-reselect - - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - float oldpos=E->get().pos; - float newpos=_NEW_POS(oldpos); - if (newpos>=0) - undo_redo->add_do_method(this,"_select_at_anim",animation,E->key().track,newpos); - undo_redo->add_undo_method(this,"_select_at_anim",animation,E->key().track,oldpos); - - } -#undef _NEW_POS - undo_redo->commit_action(); - -} - - -void AnimationKeyEditor::_add_call_track(const NodePath& p_base) { - - - Node* base = EditorNode::get_singleton()->get_edited_scene(); - if (!base) - return; - Node* from=base->get_node(p_base); - if (!from || !root) - return; - - NodePath path = root->get_path_to(from); - - //print_line("root: "+String(root->get_path())); - //print_line("path: "+String(path)); - - undo_redo->create_action(TTR("Anim Add Call Track")); - undo_redo->add_do_method(animation.ptr(),"add_track",Animation::TYPE_METHOD); - undo_redo->add_do_method(animation.ptr(),"track_set_path",animation->get_track_count(),path); - undo_redo->add_undo_method(animation.ptr(),"remove_track",animation->get_track_count()); - undo_redo->commit_action(); - -} - -void AnimationKeyEditor::cleanup() { - - set_animation(Ref<Animation>()); -} - -void AnimationKeyEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_root_removed"),&AnimationKeyEditor::_root_removed); - ClassDB::bind_method(D_METHOD("_scale"),&AnimationKeyEditor::_scale); - ClassDB::bind_method(D_METHOD("set_root"),&AnimationKeyEditor::set_root); - - - //ClassDB::bind_method(D_METHOD("_confirm_insert"),&AnimationKeyEditor::_confirm_insert); - ClassDB::bind_method(D_METHOD("_confirm_insert_list"),&AnimationKeyEditor::_confirm_insert_list); - - - - ClassDB::bind_method(D_METHOD("_update_paths"),&AnimationKeyEditor::_update_paths); - ClassDB::bind_method(D_METHOD("_track_editor_draw"),&AnimationKeyEditor::_track_editor_draw); - - - - - ClassDB::bind_method(D_METHOD("_animation_changed"),&AnimationKeyEditor::_animation_changed); - ClassDB::bind_method(D_METHOD("_scroll_changed"),&AnimationKeyEditor::_scroll_changed); - ClassDB::bind_method(D_METHOD("_track_editor_gui_input"),&AnimationKeyEditor::_track_editor_gui_input); - ClassDB::bind_method(D_METHOD("_track_name_changed"),&AnimationKeyEditor::_track_name_changed); - ClassDB::bind_method(D_METHOD("_track_menu_selected"),&AnimationKeyEditor::_track_menu_selected); - ClassDB::bind_method(D_METHOD("_menu_add_track"),&AnimationKeyEditor::_menu_add_track); - ClassDB::bind_method(D_METHOD("_menu_track"),&AnimationKeyEditor::_menu_track); - ClassDB::bind_method(D_METHOD("_clear_selection_for_anim"),&AnimationKeyEditor::_clear_selection_for_anim); - ClassDB::bind_method(D_METHOD("_select_at_anim"),&AnimationKeyEditor::_select_at_anim); - ClassDB::bind_method(D_METHOD("_track_pos_draw"),&AnimationKeyEditor::_track_pos_draw); - ClassDB::bind_method(D_METHOD("_insert_delay"),&AnimationKeyEditor::_insert_delay); - ClassDB::bind_method(D_METHOD("_step_changed"),&AnimationKeyEditor::_step_changed); - - - ClassDB::bind_method(D_METHOD("_animation_loop_changed"),&AnimationKeyEditor::_animation_loop_changed); - ClassDB::bind_method(D_METHOD("_animation_len_changed"),&AnimationKeyEditor::_animation_len_changed); - ClassDB::bind_method(D_METHOD("_create_value_item"),&AnimationKeyEditor::_create_value_item); - ClassDB::bind_method(D_METHOD("_pane_drag"),&AnimationKeyEditor::_pane_drag); - - ClassDB::bind_method(D_METHOD("_animation_len_update"),&AnimationKeyEditor::_animation_len_update); - - ClassDB::bind_method(D_METHOD("set_animation"),&AnimationKeyEditor::set_animation); - ClassDB::bind_method(D_METHOD("_animation_optimize"),&AnimationKeyEditor::_animation_optimize); - ClassDB::bind_method(D_METHOD("_curve_transition_changed"),&AnimationKeyEditor::_curve_transition_changed); - ClassDB::bind_method(D_METHOD("_toggle_edit_curves"),&AnimationKeyEditor::_toggle_edit_curves); - ClassDB::bind_method(D_METHOD("_add_call_track"),&AnimationKeyEditor::_add_call_track); - - - ADD_SIGNAL( MethodInfo("resource_selected", PropertyInfo( Variant::OBJECT, "res"),PropertyInfo( Variant::STRING, "prop") ) ); - ADD_SIGNAL( MethodInfo("keying_changed" ) ); - ADD_SIGNAL( MethodInfo("timeline_changed", PropertyInfo(Variant::REAL,"pos"), PropertyInfo(Variant::BOOL,"drag") ) ); - ADD_SIGNAL( MethodInfo("animation_len_changed", PropertyInfo(Variant::REAL,"len") ) ); - ADD_SIGNAL( MethodInfo("animation_step_changed", PropertyInfo(Variant::REAL,"step") ) ); - ADD_SIGNAL( MethodInfo("key_edited", PropertyInfo(Variant::INT,"track"), PropertyInfo(Variant::INT,"key") ) ); - -} - - -AnimationKeyEditor::AnimationKeyEditor() { - - alc="animation_len_changed"; - editor_selection=EditorNode::get_singleton()->get_editor_selection(); - - selected_track=-1; - updating=false; - te_drawing=false; - undo_redo=EditorNode::get_singleton()->get_undo_redo(); - history=EditorNode::get_singleton()->get_editor_history(); - - ec = memnew (Control); - ec->set_custom_minimum_size(Size2(0,150)); - add_child(ec); - ec->set_v_size_flags(SIZE_EXPAND_FILL); - - h_scroll = memnew( HScrollBar ); - h_scroll->connect("value_changed",this,"_scroll_changed"); - add_child(h_scroll); - h_scroll->set_value(0); - - - HBoxContainer *hb = memnew( HBoxContainer ); - add_child(hb); - - - root=NULL; - //menu = memnew( MenuButton ); - //menu->set_flat(true); - //menu->set_pos(Point2()); - //add_child(menu); - - zoomicon = memnew( TextureRect ); - hb->add_child(zoomicon); - zoomicon->set_tooltip(TTR("Animation zoom.")); - - zoom = memnew( HSlider ); - //hb->add_child(zoom); - zoom->set_step(0.01); - zoom->set_min(0.0); - zoom->set_max(2.0); - zoom->set_value(1.0); - zoom->set_h_size_flags(SIZE_EXPAND_FILL); - zoom->set_stretch_ratio(2); - hb->add_child(zoom); - zoom->connect("value_changed",this,"_scroll_changed"); - zoom->set_tooltip(TTR("Animation zoom.")); - - hb->add_child( memnew( VSeparator ) ); - - Label *l = memnew( Label ); - l->set_text(TTR("Length (s):")); - hb->add_child(l); - - length = memnew( SpinBox ); - length->set_min(0.01); - length->set_max(10000); - length->set_step(0.01); - length->set_h_size_flags(SIZE_EXPAND_FILL); - length->set_stretch_ratio(1); - length->set_tooltip(TTR("Animation length (in seconds).")); - - hb->add_child(length); - length->connect("value_changed",this,"_animation_len_changed"); - - l = memnew( Label ); - l->set_text(TTR("Step (s):")); - hb->add_child(l); - - step = memnew( SpinBox ); - step->set_min(0.00); - step->set_max(128); - step->set_step(0.01); - step->set_value(0.0); - step->set_h_size_flags(SIZE_EXPAND_FILL); - step->set_stretch_ratio(1); - step->set_tooltip(TTR("Cursor step snap (in seconds).")); - - hb->add_child(step); - step->connect("value_changed",this,"_step_changed"); - - loop = memnew( ToolButton ); - loop->set_toggle_mode(true); - loop->connect("pressed",this,"_animation_loop_changed"); - hb->add_child(loop); - loop->set_tooltip(TTR("Enable/Disable looping in animation.")); - - hb->add_child( memnew( VSeparator ) ); - - menu_add_track = memnew( MenuButton ); - hb->add_child(menu_add_track); - menu_add_track->get_popup()->connect("id_pressed",this,"_menu_add_track"); - menu_add_track->set_tooltip(TTR("Add new tracks.")); - - move_up_button = memnew( ToolButton ); - hb->add_child(move_up_button); - move_up_button->connect("pressed",this,"_menu_track",make_binds(TRACK_MENU_MOVE_UP)); - move_up_button->set_focus_mode(FOCUS_NONE); - move_up_button->set_disabled(true); - move_up_button->set_tooltip(TTR("Move current track up.")); - - move_down_button = memnew( ToolButton ); - hb->add_child(move_down_button); - move_down_button->connect("pressed",this,"_menu_track",make_binds(TRACK_MENU_MOVE_DOWN)); - move_down_button->set_focus_mode(FOCUS_NONE); - move_down_button->set_disabled(true); - move_down_button->set_tooltip(TTR("Move current track down.")); - - remove_button = memnew( ToolButton ); - hb->add_child(remove_button); - remove_button->connect("pressed",this,"_menu_track",make_binds(TRACK_MENU_REMOVE)); - remove_button->set_focus_mode(FOCUS_NONE); - remove_button->set_disabled(true); - remove_button->set_tooltip(TTR("Remove selected track.")); - - hb->add_child(memnew( VSeparator )); - - menu_track = memnew( MenuButton ); - hb->add_child(menu_track); - menu_track->get_popup()->connect("id_pressed",this,"_menu_track"); - menu_track->set_tooltip(TTR("Track tools")); - - edit_button = memnew( ToolButton ); - edit_button->set_toggle_mode(true); - edit_button->set_focus_mode(FOCUS_NONE); - edit_button->set_disabled(true); - - hb->add_child(edit_button); - edit_button->set_tooltip(TTR("Enable editing of individual keys by clicking them.")); - - optimize_dialog = memnew( ConfirmationDialog ); - add_child(optimize_dialog); - optimize_dialog->set_title(TTR("Anim. Optimizer")); - VBoxContainer *optimize_vb = memnew( VBoxContainer ); - optimize_dialog->add_child(optimize_vb); - - optimize_linear_error = memnew( SpinBox ); - optimize_linear_error->set_max(1.0); - optimize_linear_error->set_min(0.001); - optimize_linear_error->set_step(0.001); - optimize_linear_error->set_value(0.05); - optimize_vb->add_margin_child(TTR("Max. Linear Error:"),optimize_linear_error); - optimize_angular_error = memnew( SpinBox ); - optimize_angular_error->set_max(1.0); - optimize_angular_error->set_min(0.001); - optimize_angular_error->set_step(0.001); - optimize_angular_error->set_value(0.01); - - optimize_vb->add_margin_child(TTR("Max. Angular Error:"),optimize_angular_error); - optimize_max_angle = memnew( SpinBox ); - optimize_vb->add_margin_child(TTR("Max Optimizable Angle:"),optimize_max_angle); - optimize_max_angle->set_max(360.0); - optimize_max_angle->set_min(0.0); - optimize_max_angle->set_step(0.1); - optimize_max_angle->set_value(22); - - optimize_dialog->get_ok()->set_text(TTR("Optimize")); - - - - /*keying = memnew( Button ); - keying->set_toggle_mode(true); - //keying->set_text("Keys"); - keying->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,60); - keying->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,10); - keying->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_BEGIN,55); - keying->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,10); - //add_child(keying); - keying->connect("pressed",this,"_keying_toggled"); - */ - -/* l = memnew( Label ); - l->set_text("Base: "); - l->set_pos(Point2(0,3)); - //dr_panel->add_child(l);*/ - - //menu->get_popup()->connect("id_pressed",this,"_menu_callback"); - - - hb = memnew( HBoxContainer); - hb->set_area_as_parent_rect(); - ec->add_child(hb); - hb->set_v_size_flags(SIZE_EXPAND_FILL); - - track_editor = memnew( Control ); - track_editor->connect("draw",this,"_track_editor_draw"); - hb->add_child(track_editor); - track_editor->connect("gui_input",this,"_track_editor_gui_input"); - track_editor->set_focus_mode(Control::FOCUS_ALL); - track_editor->set_h_size_flags(SIZE_EXPAND_FILL); - - - - track_pos = memnew( Control ); - track_pos->set_area_as_parent_rect(); - track_pos->set_mouse_filter(MOUSE_FILTER_IGNORE); - track_editor->add_child(track_pos); - track_pos->connect("draw",this,"_track_pos_draw"); - - select_anim_warning = memnew( Label ); - track_editor->add_child(select_anim_warning); - select_anim_warning->set_area_as_parent_rect(); - select_anim_warning->set_text(TTR("Select an AnimationPlayer from the Scene Tree to edit animations.")); - select_anim_warning->set_autowrap(true); - select_anim_warning->set_align(Label::ALIGN_CENTER); - select_anim_warning->set_valign(Label::VALIGN_CENTER); - - - - v_scroll = memnew( VScrollBar ); - hb->add_child(v_scroll); - v_scroll->connect("value_changed",this,"_scroll_changed"); - v_scroll->set_value(0); - - key_editor_tab = memnew(TabContainer); - hb->add_child(key_editor_tab); - key_editor_tab->set_custom_minimum_size(Size2(200,0)); - - key_editor = memnew( PropertyEditor ); - key_editor->set_area_as_parent_rect(); - key_editor->hide_top_label(); - key_editor->set_name(TTR("Key")); - key_editor_tab->add_child(key_editor); - - key_edit = memnew( AnimationKeyEdit ); - key_edit->undo_redo=undo_redo; - //key_edit->ke_dialog=key_edit_dialog; - - type_menu = memnew( PopupMenu ); - add_child(type_menu); - for(int i=0;i<Variant::VARIANT_MAX;i++) - type_menu->add_item(Variant::get_type_name(Variant::Type(i)),i); - type_menu->connect("id_pressed",this,"_create_value_item"); - - VBoxContainer *curve_vb = memnew( VBoxContainer ); - curve_vb->set_name(TTR("Transition")); - HBoxContainer *curve_hb = memnew( HBoxContainer ); - curve_vb->add_child(curve_hb); - - curve_linear = memnew( ToolButton ); - curve_linear->set_focus_mode(FOCUS_NONE); - curve_hb->add_child(curve_linear); - curve_in = memnew( ToolButton ); - curve_in->set_focus_mode(FOCUS_NONE); - curve_hb->add_child(curve_in); - curve_out = memnew( ToolButton ); - curve_out->set_focus_mode(FOCUS_NONE); - curve_hb->add_child(curve_out); - curve_inout = memnew( ToolButton ); - curve_inout->set_focus_mode(FOCUS_NONE); - curve_hb->add_child(curve_inout); - curve_outin = memnew( ToolButton ); - curve_outin->set_focus_mode(FOCUS_NONE); - curve_hb->add_child(curve_outin); - curve_constant = memnew( ToolButton ); - curve_constant->set_focus_mode(FOCUS_NONE); - curve_hb->add_child(curve_constant); - - - curve_edit = memnew( AnimationCurveEdit ); - curve_vb->add_child(curve_edit); - curve_edit->set_v_size_flags(SIZE_EXPAND_FILL); - key_editor_tab->add_child(curve_vb); - - track_name = memnew( LineEdit ); - track_name->set_as_toplevel(true); - track_name->hide(); - add_child(track_name); - track_name->connect("text_entered",this,"_track_name_changed"); - track_menu = memnew( PopupMenu ); - add_child(track_menu); - track_menu->connect("id_pressed",this,"_track_menu_selected"); - - key_editor_tab->hide(); - - last_idx =1; - - _update_menu(); - - - - insert_confirm = memnew( ConfirmationDialog ); - add_child(insert_confirm); - insert_confirm->connect("confirmed",this,"_confirm_insert_list"); - - click.click=ClickOver::CLICK_NONE; - - - name_column_ratio=0.3; - timeline_pos=0; - - - keying=false; - insert_frame=0; - insert_query=false; - insert_queue=false; - - editor_selection->connect("selection_changed",track_editor,"update"); - - - scale_dialog = memnew( ConfirmationDialog ); - VBoxContainer *vbc = memnew( VBoxContainer ); - scale_dialog->add_child(vbc); - - scale = memnew( SpinBox ); - scale->set_min(-99999); - scale->set_max(99999); - scale->set_step(0.001); - vbc->add_margin_child(TTR("Scale Ratio:"),scale); - scale_dialog->connect("confirmed",this,"_scale"); - add_child(scale_dialog); - - call_select = memnew( SceneTreeDialog ); - add_child(call_select); - call_select->set_title(TTR("Call Functions in Which Node?")); - - cleanup_dialog = memnew( ConfirmationDialog ); - add_child(cleanup_dialog); - VBoxContainer *cleanup_vb = memnew( VBoxContainer ); - cleanup_dialog->add_child(cleanup_vb); - - cleanup_keys = memnew( CheckButton ); - cleanup_keys->set_text(TTR("Remove invalid keys")); - cleanup_keys->set_pressed(true); - cleanup_vb->add_child(cleanup_keys); - - cleanup_tracks = memnew( CheckButton ); - cleanup_tracks->set_text(TTR("Remove unresolved and empty tracks")); - cleanup_tracks->set_pressed(true); - cleanup_vb->add_child(cleanup_tracks); - - cleanup_all = memnew( CheckButton ); - cleanup_all->set_text(TTR("Clean-up all animations")); - cleanup_vb->add_child(cleanup_all); - - cleanup_dialog->set_title(TTR("Clean-Up Animation(s) (NO UNDO!)")); - cleanup_dialog->get_ok()->set_text(TTR("Clean-Up")); - - cleanup_dialog->connect("confirmed",this,"_menu_track",varray(TRACK_MENU_CLEAN_UP_CONFIRM)); - - add_constant_override("separation",get_constant("separation","VBoxContainer")); - - track_editor->set_clip_contents(true); - -} - -AnimationKeyEditor::~AnimationKeyEditor() { - - - - memdelete( key_edit ); - -} diff --git a/tools/editor/call_dialog.h b/tools/editor/call_dialog.h deleted file mode 100644 index b0ebe68d86..0000000000 --- a/tools/editor/call_dialog.h +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************/ -/* call_dialog.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef CALL_DIALOG_H -#define CALL_DIALOG_H - -#include "scene/gui/popup.h" -#include "scene/gui/button.h" -#include "scene/gui/tree.h" -#include "scene/gui/label.h" -#include "scene/gui/line_edit.h" -#include "tools/editor/property_editor.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -#if 0 - -class CallDialogParams; - -class CallDialog : public Popup { - - GDCLASS( CallDialog, Popup ); - - - Label* method_label; - Tree *tree; - Button *call; - Button *cancel; - - CallDialogParams *call_params; - PropertyEditor *property_editor; - - Label *return_label; - LineEdit *return_value; - Object *object; - StringName selected; - - Vector<MethodInfo> methods; - - - void _item_selected(); - void _update_method_list(); - void _call(); - void _cancel(); - -protected: - static void _bind_methods(); - void _notification(int p_what); -public: - - void set_object(Object *p_object,StringName p_selected=""); - - CallDialog(); - ~CallDialog(); - -}; - -#endif -#endif diff --git a/tools/editor/code_editor.cpp b/tools/editor/code_editor.cpp deleted file mode 100644 index 0a25b43716..0000000000 --- a/tools/editor/code_editor.cpp +++ /dev/null @@ -1,1323 +0,0 @@ -/*************************************************************************/ -/* code_editor.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 "code_editor.h" - -#include "editor_settings.h" -#include "scene/gui/margin_container.h" -#include "scene/gui/separator.h" -#include "scene/resources/dynamic_font.h" -#include "os/keyboard.h" -#include "tools/editor/editor_scale.h" - -void GotoLineDialog::popup_find_line(TextEdit *p_edit) { - - text_editor=p_edit; - - line->set_text(itos(text_editor->cursor_get_line())); - line->select_all(); - popup_centered(Size2(180,80)); - line->grab_focus(); -} - - -int GotoLineDialog::get_line() const { - - return line->get_text().to_int(); -} - - -void GotoLineDialog::ok_pressed() { - - if (get_line()<1 || get_line()>text_editor->get_line_count()) - return; - text_editor->cursor_set_line(get_line()-1); - hide(); -} - -GotoLineDialog::GotoLineDialog() { - - set_title(TTR("Go to Line")); - Label *l = memnew(Label); - l->set_text(TTR("Line Number:")); - l->set_pos(Point2(5,5)); - add_child(l); - - line = memnew( LineEdit ); - line->set_anchor( MARGIN_RIGHT, ANCHOR_END ); - line->set_begin( Point2(15,22) ); - line->set_end( Point2(15,35) ); - add_child(line); - register_text_enter(line); - text_editor=NULL; - - set_hide_on_ok(false); -} - - -void FindReplaceBar::_notification(int p_what) { - - if (p_what == NOTIFICATION_READY) { - - find_prev->set_icon(get_icon("MoveUp", "EditorIcons")); - find_next->set_icon(get_icon("MoveDown", "EditorIcons")); - hide_button->set_normal_texture(get_icon("Close","EditorIcons")); - hide_button->set_hover_texture(get_icon("CloseHover","EditorIcons")); - hide_button->set_pressed_texture(get_icon("Close","EditorIcons")); - - } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { - - set_process_unhandled_input(is_visible_in_tree()); - } -} - -void FindReplaceBar::_unhandled_input(const InputEvent &p_event) { - - if (p_event.type == InputEvent::KEY) { - - const InputEventKey& k = p_event.key; - - if (k.pressed && (text_edit->has_focus() || text_vbc->is_a_parent_of(get_focus_owner()))) { - - bool accepted = true; - - switch (k.scancode) { - - case KEY_ESCAPE: { - - _hide_bar(); - } break; - default: { - - accepted = false; - } break; - } - - if (accepted) { - accept_event(); - } - } - } -} - -bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col) { - - int line, col; - String text=get_search_text(); - - bool found=text_edit->search(text,p_flags,p_from_line,p_from_col,line,col); - - if (found) { - if (!preserve_cursor) { - text_edit->cursor_set_line(line, false); - text_edit->cursor_set_column(col+text.length(), false); - text_edit->center_viewport_to_cursor(); - } - - text_edit->set_search_text(text); - text_edit->set_search_flags(p_flags); - text_edit->set_current_search_result(line,col); - - result_line=line; - result_col=col; - - set_error(""); - } else { - result_line=-1; - result_col=-1; - text_edit->set_search_text(""); - set_error(text.empty()?"":TTR("No Matches")); - } - - return found; -} - -void FindReplaceBar::_replace() { - - if (result_line!=-1 && result_col!=-1) { - text_edit->begin_complex_operation(); - - text_edit->select(result_line,result_col,result_line,result_col+get_search_text().length()); - text_edit->insert_text_at_cursor(get_replace_text()); - - text_edit->end_complex_operation(); - } - - search_current(); -} - -void FindReplaceBar::_replace_all() { - - // line as x so it gets priority in comparison, column as y - Point2i orig_cursor(text_edit->cursor_get_line(),text_edit->cursor_get_column()); - Point2i prev_match=Point2(-1,-1); - - bool selection_enabled = text_edit->is_selection_active(); - Point2i selection_begin,selection_end; - if (selection_enabled) { - selection_begin=Point2i(text_edit->get_selection_from_line(),text_edit->get_selection_from_column()); - selection_end=Point2i(text_edit->get_selection_to_line(),text_edit->get_selection_to_column()); - } - - int vsval = text_edit->get_v_scroll(); - - text_edit->cursor_set_line(0); - text_edit->cursor_set_column(0); - - String replace_text=get_replace_text(); - int search_text_len=get_search_text().length(); - - int rc=0; - - replace_all_mode = true; - - text_edit->begin_complex_operation(); - - while (search_next()) { - - // replace area - Point2i match_from(result_line,result_col); - Point2i match_to(result_line,result_col+search_text_len); - - if (match_from < prev_match) - break; // done - - prev_match=Point2i(result_line,result_col+replace_text.length()); - - text_edit->select(result_line,result_col,result_line,match_to.y); - - if (selection_enabled && is_selection_only()) { - - if (match_from<selection_begin || match_to>selection_end) - continue; - - // replace but adjust selection bounds - text_edit->insert_text_at_cursor(replace_text); - if (match_to.x==selection_end.x) - selection_end.y+=replace_text.length()-search_text_len; - } else { - // just replace - text_edit->insert_text_at_cursor(replace_text); - } - - rc++; - } - - text_edit->end_complex_operation(); - - replace_all_mode = false; - - // restore editor state (selection, cursor, scroll) - text_edit->cursor_set_line(orig_cursor.x); - text_edit->cursor_set_column(orig_cursor.y); - - if (selection_enabled && is_selection_only()) { - // reselect - text_edit->select(selection_begin.x,selection_begin.y,selection_end.x,selection_end.y); - } else { - text_edit->deselect(); - } - - text_edit->set_v_scroll(vsval); - set_error(vformat(TTR("Replaced %d Ocurrence(s)."), rc)); -} - -void FindReplaceBar::_get_search_from(int& r_line, int& r_col) { - - r_line=text_edit->cursor_get_line(); - r_col=text_edit->cursor_get_column(); - - if (text_edit->is_selection_active() && !replace_all_mode) { - - int selection_line=text_edit->get_selection_from_line(); - - if (text_edit->get_selection_text()==get_search_text() && r_line==selection_line) { - - int selection_from_col=text_edit->get_selection_from_column(); - - if (r_col>=selection_from_col && r_col<=text_edit->get_selection_to_column()) { - r_col=selection_line; - r_col=selection_from_col; - } - } - } - - if (r_line==result_line && r_col>=result_col && r_col<=result_col+get_search_text().length()) { - r_col=result_col; - } -} - -bool FindReplaceBar::search_current() { - - uint32_t flags=0; - - if (is_whole_words()) - flags|=TextEdit::SEARCH_WHOLE_WORDS; - if (is_case_sensitive()) - flags|=TextEdit::SEARCH_MATCH_CASE; - - int line, col; - _get_search_from(line, col); - - return _search(flags,line,col); -} - -bool FindReplaceBar::search_prev() { - - uint32_t flags=0; - String text = get_search_text(); - - if (is_whole_words()) - flags|=TextEdit::SEARCH_WHOLE_WORDS; - if (is_case_sensitive()) - flags|=TextEdit::SEARCH_MATCH_CASE; - - flags|=TextEdit::SEARCH_BACKWARDS; - - int line, col; - _get_search_from(line, col); - - col-=text.length(); - if (col<0) { - line-=1; - if (line<0) - line=text_edit->get_line_count()-1; - col=text_edit->get_line(line).length(); - } - - return _search(flags,line,col); -} - -bool FindReplaceBar::search_next() { - - uint32_t flags=0; - String text = get_search_text(); - - if (is_whole_words()) - flags|=TextEdit::SEARCH_WHOLE_WORDS; - if (is_case_sensitive()) - flags|=TextEdit::SEARCH_MATCH_CASE; - - int line, col; - _get_search_from(line, col); - - if (line==result_line && col==result_col) { - col+=text.length(); - if (col>text_edit->get_line(line).length()) { - line+=1; - if (line>=text_edit->get_line_count()) - line=0; - col=0; - } - } - - return _search(flags,line,col); -} - -void FindReplaceBar::_hide_bar() { - - if (replace_text->has_focus() || search_text->has_focus()) - text_edit->grab_focus(); - - text_edit->set_search_text(""); - result_line = -1; - result_col = -1; - replace_hbc->hide(); - replace_options_hbc->hide(); - hide(); -} - -void FindReplaceBar::_show_search() { - - show(); - search_text->grab_focus(); - - if (text_edit->is_selection_active() && !selection_only->is_pressed()) { - search_text->set_text(text_edit->get_selection_text()); - } - - if (!get_search_text().empty()) { - search_text->select_all(); - search_text->set_cursor_pos(search_text->get_text().length()); - search_current(); - } -} - -void FindReplaceBar::popup_search() { - - replace_hbc->hide(); - replace_options_hbc->hide(); - _show_search(); -} - -void FindReplaceBar::popup_replace() { - - - if (!replace_hbc->is_visible_in_tree() || !replace_options_hbc->is_visible_in_tree()) { - replace_text->clear(); - replace_hbc->show(); - replace_options_hbc->show(); - - } - - selection_only->set_pressed( (text_edit->is_selection_active() && text_edit->get_selection_from_line() < text_edit->get_selection_to_line()) ); - - _show_search(); -} - -void FindReplaceBar::_search_options_changed(bool p_pressed) { - - search_current(); -} - -void FindReplaceBar::_editor_text_changed() { - - if (is_visible_in_tree()) { - preserve_cursor=true; - search_current(); - preserve_cursor=false; - } -} - -void FindReplaceBar::_search_text_changed(const String& p_text) { - - search_current(); -} - -void FindReplaceBar::_search_text_entered(const String& p_text) { - - search_next(); -} - -void FindReplaceBar::_replace_text_entered(const String& p_text) { - - if (selection_only->is_pressed() && text_edit->is_selection_active()) { - _replace_all(); - _hide_bar(); - } -} - -String FindReplaceBar::get_search_text() const { - - return search_text->get_text(); -} - -String FindReplaceBar::get_replace_text() const { - - return replace_text->get_text(); -} - -bool FindReplaceBar::is_case_sensitive() const { - - return case_sensitive->is_pressed(); -} - -bool FindReplaceBar::is_whole_words() const { - - return whole_words->is_pressed(); -} - -bool FindReplaceBar::is_selection_only() const { - - return selection_only->is_pressed(); -} - -void FindReplaceBar::set_error(const String &p_label) { - - error_label->set_text(p_label); -} - -void FindReplaceBar::set_text_edit(TextEdit *p_text_edit) { - - text_edit = p_text_edit; - text_edit->connect("text_changed",this,"_editor_text_changed"); -} - -void FindReplaceBar::_bind_methods() { - - ClassDB::bind_method("_unhandled_input",&FindReplaceBar::_unhandled_input); - - ClassDB::bind_method("_editor_text_changed",&FindReplaceBar::_editor_text_changed); - ClassDB::bind_method("_search_text_changed",&FindReplaceBar::_search_text_changed); - ClassDB::bind_method("_search_text_entered",&FindReplaceBar::_search_text_entered); - ClassDB::bind_method("_replace_text_entered",&FindReplaceBar::_replace_text_entered); - ClassDB::bind_method("_search_current",&FindReplaceBar::search_current); - ClassDB::bind_method("_search_next",&FindReplaceBar::search_next); - ClassDB::bind_method("_search_prev",&FindReplaceBar::search_prev); - ClassDB::bind_method("_replace_pressed",&FindReplaceBar::_replace); - ClassDB::bind_method("_replace_all_pressed",&FindReplaceBar::_replace_all); - ClassDB::bind_method("_search_options_changed",&FindReplaceBar::_search_options_changed); - ClassDB::bind_method("_hide_pressed",&FindReplaceBar::_hide_bar); - - ADD_SIGNAL(MethodInfo("search")); -} - -FindReplaceBar::FindReplaceBar() { - - replace_all_mode=false; - preserve_cursor=false; - - text_vbc = memnew(VBoxContainer); - add_child(text_vbc); - - HBoxContainer *search_hbc = memnew(HBoxContainer); - text_vbc->add_child(search_hbc); - - search_text = memnew(LineEdit); - search_hbc->add_child(search_text); - search_text->set_custom_minimum_size(Size2(200, 0)); - search_text->connect("text_changed",this,"_search_text_changed"); - search_text->connect("text_entered",this,"_search_text_entered"); - - find_prev = memnew(ToolButton); - search_hbc->add_child(find_prev); - find_prev->set_focus_mode(FOCUS_NONE); - find_prev->connect("pressed",this,"_search_prev"); - - find_next = memnew(ToolButton); - search_hbc->add_child(find_next); - find_next->set_focus_mode(FOCUS_NONE); - find_next->connect("pressed",this,"_search_next"); - - replace_hbc = memnew(HBoxContainer); - text_vbc->add_child(replace_hbc); - replace_hbc->hide(); - - replace_text = memnew(LineEdit); - replace_hbc->add_child(replace_text); - replace_text->set_custom_minimum_size(Size2(200, 0)); - replace_text->connect("text_entered",this,"_replace_text_entered"); - - - replace = memnew(Button); - replace_hbc->add_child(replace); - replace->set_text(TTR("Replace")); - //replace->set_focus_mode(FOCUS_NONE); - replace->connect("pressed",this,"_replace_pressed"); - - replace_all = memnew(Button); - replace_hbc->add_child(replace_all); - replace_all->set_text(TTR("Replace All")); - //replace_all->set_focus_mode(FOCUS_NONE); - replace_all->connect("pressed",this,"_replace_all_pressed"); - - Control *spacer_split = memnew( Control ); - spacer_split->set_custom_minimum_size(Size2(0, 1)); - text_vbc->add_child(spacer_split); - - VBoxContainer *options_vbc = memnew(VBoxContainer); - add_child(options_vbc); - options_vbc->set_h_size_flags(SIZE_EXPAND_FILL); - - HBoxContainer *search_options = memnew(HBoxContainer); - options_vbc->add_child(search_options); - - case_sensitive = memnew(CheckBox); - search_options->add_child(case_sensitive); - case_sensitive->set_text(TTR("Match Case")); - case_sensitive->set_focus_mode(FOCUS_NONE); - case_sensitive->connect("toggled",this,"_search_options_changed"); - - whole_words = memnew(CheckBox); - search_options->add_child(whole_words); - whole_words->set_text(TTR("Whole Words")); - whole_words->set_focus_mode(FOCUS_NONE); - whole_words->connect("toggled",this,"_search_options_changed"); - - error_label = memnew(Label); - search_options->add_child(error_label); - error_label->add_color_override("font_color", Color(1,1,0,1)); - error_label->add_color_override("font_color_shadow", Color(0,0,0,1)); - error_label->add_constant_override("shadow_as_outline", 1); - - search_options->add_spacer(); - - hide_button = memnew(TextureButton); - search_options->add_child(hide_button); - hide_button->set_focus_mode(FOCUS_NONE); - hide_button->connect("pressed",this,"_hide_pressed"); - - replace_options_hbc = memnew(HBoxContainer); - options_vbc->add_child(replace_options_hbc); - replace_options_hbc->hide(); - - selection_only = memnew(CheckBox); - replace_options_hbc->add_child(selection_only); - selection_only->set_text(TTR("Selection Only")); - selection_only->set_focus_mode(FOCUS_NONE); - selection_only->connect("toggled",this,"_search_options_changed"); -} - - -void FindReplaceDialog::popup_search() { - - set_title(TTR("Search")); - replace_mc->hide(); - replace_label->hide(); - replace_vb->hide(); - skip->hide(); - popup_centered(Point2(300,190)); - get_ok()->set_text(TTR("Find")); - search_text->grab_focus(); - if (text_edit->is_selection_active() && ( text_edit->get_selection_from_line() == text_edit->get_selection_to_line())) { - - search_text->set_text( text_edit->get_selection_text() ); - } - search_text->select_all(); - - error_label->set_text(""); - -} - -void FindReplaceDialog::popup_replace() { - - - set_title(TTR("Replace")); - bool do_selection=(text_edit->is_selection_active() && text_edit->get_selection_from_line() < text_edit->get_selection_to_line()); - - set_replace_selection_only(do_selection); - - if (!do_selection && text_edit->is_selection_active()) { - search_text->set_text(text_edit->get_selection_text()); - } - - replace_mc->show(); - replace_label->show(); - replace_vb->show(); - popup_centered(Point2(300,300)); - if (search_text->get_text()!="" && replace_text->get_text()=="") { - search_text->select(0,0); - replace_text->grab_focus(); - } else { - search_text->grab_focus(); - search_text->select_all(); - } - error_label->set_text(""); - - if (prompt->is_pressed()) { - skip->show(); - get_ok()->set_text(TTR("Next")); - selection_only->set_disabled(true); - - } else { - skip->hide(); - get_ok()->set_text(TTR("Replace")); - selection_only->set_disabled(false); - } - -} - -void FindReplaceDialog::_search_callback() { - - if (is_replace_mode()) - _replace(); - else - _search(); - -} - -void FindReplaceDialog::_replace_skip_callback() { - - _search(); -} - -void FindReplaceDialog::_replace() { - - text_edit->begin_complex_operation(); - if (is_replace_all_mode()) { - - //line as x so it gets priority in comparison, column as y - Point2i orig_cursor(text_edit->cursor_get_line(),text_edit->cursor_get_column()); - Point2i prev_match=Point2(-1,-1); - - - bool selection_enabled = text_edit->is_selection_active(); - Point2i selection_begin,selection_end; - if (selection_enabled) { - selection_begin=Point2i(text_edit->get_selection_from_line(),text_edit->get_selection_from_column()); - selection_end=Point2i(text_edit->get_selection_to_line(),text_edit->get_selection_to_column()); - } - int vsval = text_edit->get_v_scroll(); - //int hsval = text_edit->get_h_scroll(); - - text_edit->cursor_set_line(0); - text_edit->cursor_set_column(0); - - int rc=0; - - while(_search()) { - - if (!text_edit->is_selection_active()) { - //search selects - break; - } - - //replace area - Point2i match_from(text_edit->get_selection_from_line(),text_edit->get_selection_from_column()); - Point2i match_to(text_edit->get_selection_to_line(),text_edit->get_selection_to_column()); - - if (match_from < prev_match) - break; //done - - prev_match=match_to; - - if (selection_enabled && is_replace_selection_only()) { - - if (match_from<selection_begin || match_to>selection_end) - continue; - - //replace but adjust selection bounds - - text_edit->insert_text_at_cursor(get_replace_text()); - if (match_to.x==selection_end.x) - selection_end.y+=get_replace_text().length() - get_search_text().length(); - } else { - //just replace - text_edit->insert_text_at_cursor(get_replace_text()); - } - rc++; - - } - //restore editor state (selection, cursor, scroll) - text_edit->cursor_set_line(orig_cursor.x); - text_edit->cursor_set_column(orig_cursor.y); - - if (selection_enabled && is_replace_selection_only()) { - //reselect - text_edit->select(selection_begin.x,selection_begin.y,selection_end.x,selection_end.y); - } else { - text_edit->deselect(); - } - - text_edit->set_v_scroll(vsval); - //text_edit->set_h_scroll(hsval); - error_label->set_text(vformat(TTR("Replaced %d ocurrence(s)."),rc)); - - - //hide(); - } else { - - if (text_edit->get_selection_text()==get_search_text()) { - - text_edit->insert_text_at_cursor(get_replace_text()); - } - - _search(); - } - text_edit->end_complex_operation(); -} - - - -bool FindReplaceDialog::_search() { - - - String text=get_search_text(); - uint32_t flags=0; - - if (is_whole_words()) - flags|=TextEdit::SEARCH_WHOLE_WORDS; - if (is_case_sensitive()) - flags|=TextEdit::SEARCH_MATCH_CASE; - if (is_backwards()) - flags|=TextEdit::SEARCH_BACKWARDS; - - int line=text_edit->cursor_get_line(),col=text_edit->cursor_get_column(); - - if (is_backwards()) { - col-=1; - if (col<0) { - line-=1; - if (line<0) { - line=text_edit->get_line_count()-1; - } - col=text_edit->get_line(line).length(); - } - } - bool found = text_edit->search(text,flags,line,col,line,col); - - - if (found) { - // print_line("found"); - text_edit->cursor_set_line(line); - if (is_backwards()) - text_edit->cursor_set_column(col); - else - text_edit->cursor_set_column(col+text.length()); - text_edit->select(line,col,line,col+text.length()); - set_error(""); - return true; - } else { - - set_error(TTR("Not found!")); - return false; - } - -} - -void FindReplaceDialog::_prompt_changed() { - - if (prompt->is_pressed()) { - skip->show(); - get_ok()->set_text(TTR("Next")); - selection_only->set_disabled(true); - - } else { - skip->hide(); - get_ok()->set_text(TTR("Replace")); - selection_only->set_disabled(false); - } -} - - -void FindReplaceDialog::_skip_pressed() { - - _replace_skip_callback(); -} - -bool FindReplaceDialog::is_replace_mode() const { - - return replace_text->is_visible_in_tree(); -} - -bool FindReplaceDialog::is_replace_all_mode() const { - - return !prompt->is_pressed(); -} - -bool FindReplaceDialog::is_replace_selection_only() const { - - return selection_only->is_pressed(); -} -void FindReplaceDialog::set_replace_selection_only(bool p_enable){ - - selection_only->set_pressed(p_enable); -} - - -void FindReplaceDialog::ok_pressed() { - - _search_callback(); -} - -void FindReplaceDialog::_search_text_entered(const String& p_text) { - - if (replace_text->is_visible_in_tree()) - return; - emit_signal("search"); - _search(); - -} - -void FindReplaceDialog::_replace_text_entered(const String& p_text) { - - if (!replace_text->is_visible_in_tree()) - return; - - emit_signal("search"); - _replace(); - -} - - -String FindReplaceDialog::get_search_text() const { - - return search_text->get_text(); -} -String FindReplaceDialog::get_replace_text() const { - - return replace_text->get_text(); -} -bool FindReplaceDialog::is_whole_words() const { - - return whole_words->is_pressed(); -} -bool FindReplaceDialog::is_case_sensitive() const { - - return case_sensitive->is_pressed(); - -} -bool FindReplaceDialog::is_backwards() const { - - return backwards->is_pressed(); - -} - -void FindReplaceDialog::set_error(const String& p_error) { - - error_label->set_text(p_error); -} - -void FindReplaceDialog::set_text_edit(TextEdit *p_text_edit) { - - text_edit=p_text_edit; -} - -void FindReplaceDialog::search_next() { - _search(); -} - - -void FindReplaceDialog::_bind_methods() { - - ClassDB::bind_method("_search_text_entered",&FindReplaceDialog::_search_text_entered); - ClassDB::bind_method("_replace_text_entered",&FindReplaceDialog::_replace_text_entered); - ClassDB::bind_method("_prompt_changed",&FindReplaceDialog::_prompt_changed); - ClassDB::bind_method("_skip_pressed",&FindReplaceDialog::_skip_pressed); - ADD_SIGNAL(MethodInfo("search")); - ADD_SIGNAL(MethodInfo("skip")); - -} - -FindReplaceDialog::FindReplaceDialog() { - - set_self_modulate(Color(1,1,1,0.8)); - - VBoxContainer *vb = memnew( VBoxContainer ); - add_child(vb); - - - - search_text = memnew( LineEdit ); - vb->add_margin_child(TTR("Search"),search_text); - search_text->connect("text_entered", this,"_search_text_entered"); - //search_text->set_self_opacity(0.7); - - - - replace_label = memnew( Label); - replace_label->set_text(TTR("Replace By")); - vb->add_child(replace_label); - replace_mc= memnew( MarginContainer); - vb->add_child(replace_mc); - - replace_text = memnew( LineEdit ); - replace_text->set_anchor( MARGIN_RIGHT, ANCHOR_END ); - replace_text->set_begin( Point2(15,132) ); - replace_text->set_end( Point2(15,135) ); - //replace_text->set_self_opacity(0.7); - replace_mc->add_child(replace_text); - - - replace_text->connect("text_entered", this,"_replace_text_entered"); - - - - MarginContainer *opt_mg = memnew( MarginContainer ); - vb->add_child(opt_mg); - VBoxContainer *svb = memnew( VBoxContainer); - opt_mg->add_child(svb); - - svb ->add_child(memnew(Label)); - - whole_words = memnew( CheckButton ); - whole_words->set_text(TTR("Whole Words")); - svb->add_child(whole_words); - - case_sensitive = memnew( CheckButton ); - case_sensitive->set_text(TTR("Case Sensitive")); - svb->add_child(case_sensitive); - - backwards = memnew( CheckButton ); - backwards->set_text(TTR("Backwards")); - svb->add_child(backwards); - - opt_mg = memnew( MarginContainer ); - vb->add_child(opt_mg); - VBoxContainer *rvb = memnew( VBoxContainer); - opt_mg->add_child(rvb); - replace_vb=rvb; - //rvb ->add_child(memnew(HSeparator)); - rvb ->add_child(memnew(Label)); - - prompt = memnew( CheckButton ); - prompt->set_text(TTR("Prompt On Replace")); - rvb->add_child(prompt); - prompt->connect("pressed", this,"_prompt_changed"); - - selection_only = memnew( CheckButton ); - selection_only->set_text(TTR("Selection Only")); - rvb->add_child(selection_only); - - - int margin = get_constant("margin","Dialogs"); - int button_margin = get_constant("button_margin","Dialogs"); - - skip = memnew( Button ); - skip->set_anchor( MARGIN_LEFT, ANCHOR_END ); - skip->set_anchor( MARGIN_TOP, ANCHOR_END ); - skip->set_anchor( MARGIN_RIGHT, ANCHOR_END ); - skip->set_anchor( MARGIN_BOTTOM, ANCHOR_END ); - skip->set_begin( Point2( 70, button_margin ) ); - skip->set_end( Point2( 10, margin ) ); - skip->set_text(TTR("Skip")); - add_child(skip); - skip->connect("pressed", this,"_skip_pressed"); - - - error_label = memnew( Label ); - error_label->set_align(Label::ALIGN_CENTER); - error_label->add_color_override("font_color",Color(1,0.4,0.3)); - error_label->add_color_override("font_color_shadow",Color(0,0,0,0.2)); - error_label->add_constant_override("shadow_as_outline",1); - - vb->add_child(error_label); - - - set_hide_on_ok(false); - -} - - -/*** CODE EDITOR ****/ - -void CodeTextEditor::_text_editor_gui_input(const InputEvent& p_event) { - - if (p_event.type==InputEvent::MOUSE_BUTTON) { - - const InputEventMouseButton& mb=p_event.mouse_button; - - if (mb.pressed && mb.mod.command) { - - if (mb.button_index==BUTTON_WHEEL_UP) { - _zoom_in(); - } else if (mb.button_index==BUTTON_WHEEL_DOWN) { - _zoom_out(); - } - } - } else if (p_event.type==InputEvent::KEY) { - - if (p_event.key.pressed) { - if (ED_IS_SHORTCUT("script_editor/zoom_in", p_event)) { - _zoom_in(); - } - if (ED_IS_SHORTCUT("script_editor/zoom_out", p_event)) { - _zoom_out(); - } - if (ED_IS_SHORTCUT("script_editor/reset_zoom", p_event)) { - _reset_zoom(); - } - } - } -} - -void CodeTextEditor::_zoom_in() { - font_resize_val+=1; - - if (font_resize_timer->get_time_left()==0) - font_resize_timer->start(); -} - -void CodeTextEditor::_zoom_out() { - font_resize_val-=1; - - if (font_resize_timer->get_time_left()==0) - font_resize_timer->start(); -} - -void CodeTextEditor::_reset_zoom() { - Ref<DynamicFont> font = text_editor->get_font("font"); // reset source font size to default - - if (font.is_valid()) { - EditorSettings::get_singleton()->set("interface/source_font_size",14); - font->set_size(14); - } -} - -void CodeTextEditor::_line_col_changed() { - - line_nb->set_text(itos(text_editor->cursor_get_line() + 1)); - col_nb->set_text(itos(text_editor->cursor_get_column() + 1)); -} - -void CodeTextEditor::_text_changed() { - - code_complete_timer->start(); - idle->start(); -} - -void CodeTextEditor::_code_complete_timer_timeout() { - if (!is_visible_in_tree()) - return; - if (enable_complete_timer) - text_editor->query_code_comple(); -} - -void CodeTextEditor::_complete_request() { - - List<String> entries; - String ctext = text_editor->get_text_for_completion(); - _code_complete_script(ctext,&entries); - if (code_complete_func) { - code_complete_func(code_complete_ud,ctext,&entries); - } - // print_line("COMPLETE: "+p_request); - if (entries.size()==0) - return; - Vector<String> strs; - strs.resize(entries.size()); - int i=0; - for(List<String>::Element *E=entries.front();E;E=E->next()) { - - strs[i++]=E->get(); - } - - text_editor->code_complete(strs); -} - -void CodeTextEditor::_font_resize_timeout() { - - Ref<DynamicFont> font = text_editor->get_font("font"); - - if (font.is_valid()) { - int size=font->get_size()+font_resize_val; - - if (size>=8 && size<=96) { - EditorSettings::get_singleton()->set("interface/source_font_size",size); - font->set_size(size); - } - - font_resize_val=0; - } -} - -void CodeTextEditor::update_editor_settings() { - - text_editor->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/completion/auto_brace_complete")); - text_editor->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file")); - text_editor->set_tab_size(EditorSettings::get_singleton()->get("text_editor/indent/tab_size")); - text_editor->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/indent/draw_tabs")); - text_editor->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_numbers")); - text_editor->set_line_numbers_zero_padded(EditorSettings::get_singleton()->get("text_editor/line_numbers/line_numbers_zero_padded")); - text_editor->set_show_line_length_guideline(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_length_guideline")); - text_editor->set_line_length_guideline_column(EditorSettings::get_singleton()->get("text_editor/line_numbers/line_length_guideline_column")); - text_editor->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/highlighting/syntax_highlighting")); - text_editor->set_highlight_all_occurrences(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_all_occurrences")); - text_editor->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink")); - text_editor->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed")); - text_editor->set_draw_breakpoint_gutter(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_breakpoint_gutter")); - text_editor->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret")); -} - -void CodeTextEditor::set_error(const String& p_error) { - - if (p_error!="") { - error->set_text(p_error); - error->show(); - } else { - error->hide(); - } - -} - -void CodeTextEditor::_update_font() { - - // FONTS - String editor_font = EDITOR_DEF("text_editor/theme/font", ""); - bool font_overridden = false; - if (editor_font!="") { - Ref<Font> fnt = ResourceLoader::load(editor_font); - if (fnt.is_valid()) { - text_editor->add_font_override("font",fnt); - font_overridden = true; - } - } - if(!font_overridden) { - - text_editor->add_font_override("font",get_font("source","EditorFonts")); - } -} - -void CodeTextEditor::_on_settings_change() { - - _update_font(); - - // AUTO BRACE COMPLETION - text_editor->set_auto_brace_completion( - EDITOR_DEF("text_editor/completion/auto_brace_complete", true) - ); - - code_complete_timer->set_wait_time( - EDITOR_DEF("text_editor/completion/code_complete_delay",.3f) - ); - - enable_complete_timer = EDITOR_DEF("text_editor/completion/enable_code_completion_delay",true); - - // call hint settings - text_editor->set_callhint_settings( - EDITOR_DEF("text_editor/completion/put_callhint_tooltip_below_current_line", true), - EDITOR_DEF("text_editor/completion/callhint_tooltip_offset", Vector2()) - ); -} - -void CodeTextEditor::_text_changed_idle_timeout() { - - - _validate_script(); - emit_signal("validate_script"); -} - -void CodeTextEditor::_notification(int p_what) { - - - if (p_what==EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - _load_theme_settings(); - emit_signal("load_theme_settings"); - } - if (p_what==NOTIFICATION_THEME_CHANGED) { - _update_font(); - } -} - -void CodeTextEditor::_bind_methods() { - - ClassDB::bind_method("_text_editor_gui_input",&CodeTextEditor::_text_editor_gui_input); - ClassDB::bind_method("_line_col_changed",&CodeTextEditor::_line_col_changed); - ClassDB::bind_method("_text_changed",&CodeTextEditor::_text_changed); - ClassDB::bind_method("_on_settings_change",&CodeTextEditor::_on_settings_change); - ClassDB::bind_method("_text_changed_idle_timeout",&CodeTextEditor::_text_changed_idle_timeout); - ClassDB::bind_method("_code_complete_timer_timeout",&CodeTextEditor::_code_complete_timer_timeout); - ClassDB::bind_method("_complete_request",&CodeTextEditor::_complete_request); - ClassDB::bind_method("_font_resize_timeout",&CodeTextEditor::_font_resize_timeout); - - ADD_SIGNAL(MethodInfo("validate_script")); - ADD_SIGNAL(MethodInfo("load_theme_settings")); - -} - -void CodeTextEditor::set_code_complete_func(CodeTextEditorCodeCompleteFunc p_code_complete_func,void * p_ud) { - code_complete_func=p_code_complete_func; - code_complete_ud=p_ud; -} - - -CodeTextEditor::CodeTextEditor() { - - code_complete_func=NULL; - ED_SHORTCUT("script_editor/zoom_in", TTR("Zoom In"), KEY_MASK_CMD|KEY_EQUAL); - ED_SHORTCUT("script_editor/zoom_out", TTR("Zoom Out"), KEY_MASK_CMD|KEY_MINUS); - ED_SHORTCUT("script_editor/reset_zoom", TTR("Reset Zoom"), KEY_MASK_CMD|KEY_0); - - find_replace_bar = memnew( FindReplaceBar ); - add_child(find_replace_bar); - find_replace_bar->set_h_size_flags(SIZE_EXPAND_FILL); - find_replace_bar->hide(); - - text_editor = memnew( TextEdit ); - add_child(text_editor); - text_editor->set_v_size_flags(SIZE_EXPAND_FILL); - - find_replace_bar->set_text_edit(text_editor); - - text_editor->set_show_line_numbers(true); - text_editor->set_brace_matching(true); - text_editor->set_auto_indent(true); - - MarginContainer *status_mc = memnew( MarginContainer ); - add_child(status_mc); - status_mc->set("custom_constants/margin_left", 2); - status_mc->set("custom_constants/margin_top", 5); - status_mc->set("custom_constants/margin_right", 2); - status_mc->set("custom_constants/margin_bottom", 1); - - HBoxContainer *status_bar = memnew( HBoxContainer ); - status_mc->add_child(status_bar); - status_bar->set_h_size_flags(SIZE_EXPAND_FILL); - status_bar->add_child( memnew( Label ) ); //to keep the height if the other labels are not visible - - idle = memnew( Timer ); - add_child(idle); - idle->set_one_shot(true); - idle->set_wait_time(EDITOR_DEF("text_editor/completion/idle_parse_delay",2)); - - code_complete_timer = memnew(Timer); - add_child(code_complete_timer); - code_complete_timer->set_one_shot(true); - enable_complete_timer = EDITOR_DEF("text_editor/completion/enable_code_completion_delay",true); - - code_complete_timer->set_wait_time(EDITOR_DEF("text_editor/completion/code_complete_delay",.3f)); - - error = memnew( Label ); - status_bar->add_child(error); - error->hide(); - error->set_valign(Label::VALIGN_CENTER); - error->add_color_override("font_color",Color(1,0.7,0.6,0.9)); - - status_bar->add_spacer(); - - Label *line_txt = memnew( Label ); - status_bar->add_child(line_txt); - line_txt->set_align(Label::ALIGN_RIGHT); - line_txt->set_valign(Label::VALIGN_CENTER); - line_txt->set_v_size_flags(SIZE_FILL); - line_txt->set_text(TTR("Line:")); - - line_nb = memnew( Label ); - status_bar->add_child(line_nb); - line_nb->set_valign(Label::VALIGN_CENTER); - line_nb->set_v_size_flags(SIZE_FILL); - line_nb->set_autowrap(true); // workaround to prevent resizing the label on each change - line_nb->set_custom_minimum_size(Size2(40,1)*EDSCALE); - - Label *col_txt = memnew( Label ); - status_bar->add_child(col_txt); - col_txt->set_align(Label::ALIGN_RIGHT); - col_txt->set_valign(Label::VALIGN_CENTER); - col_txt->set_v_size_flags(SIZE_FILL); - col_txt->set_text(TTR("Col:")); - - col_nb = memnew( Label ); - status_bar->add_child(col_nb); - col_nb->set_valign(Label::VALIGN_CENTER); - col_nb->set_v_size_flags(SIZE_FILL); - col_nb->set_autowrap(true); // workaround to prevent resizing the label on each change - col_nb->set_custom_minimum_size(Size2(40,1)*EDSCALE); - - text_editor->connect("gui_input", this,"_text_editor_gui_input"); - text_editor->connect("cursor_changed", this,"_line_col_changed"); - text_editor->connect("text_changed", this,"_text_changed"); - text_editor->connect("request_completion", this,"_complete_request"); - Vector<String> cs; - cs.push_back("."); - cs.push_back(","); - cs.push_back("("); - cs.push_back("$"); - text_editor->set_completion(true,cs); - idle->connect("timeout", this,"_text_changed_idle_timeout"); - - code_complete_timer->connect("timeout", this,"_code_complete_timer_timeout"); - - font_resize_val=0; - font_resize_timer = memnew(Timer); - add_child(font_resize_timer); - font_resize_timer->set_one_shot(true); - font_resize_timer->set_wait_time(0.07); - font_resize_timer->connect("timeout", this, "_font_resize_timeout"); - - EditorSettings::get_singleton()->connect("settings_changed",this,"_on_settings_change"); -} diff --git a/tools/editor/code_editor.h b/tools/editor/code_editor.h deleted file mode 100644 index a000f02010..0000000000 --- a/tools/editor/code_editor.h +++ /dev/null @@ -1,261 +0,0 @@ -/*************************************************************************/ -/* code_editor.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef CODE_EDITOR_H -#define CODE_EDITOR_H - -#include "tools/editor/editor_plugin.h" -#include "scene/gui/text_edit.h" -#include "scene/gui/dialogs.h" -#include "scene/main/timer.h" -#include "scene/gui/tool_button.h" -#include "scene/gui/check_button.h" -#include "scene/gui/check_box.h" -#include "scene/gui/line_edit.h" - - - -class GotoLineDialog : public ConfirmationDialog { - - GDCLASS(GotoLineDialog,ConfirmationDialog); - - Label *line_label; - LineEdit *line; - - TextEdit *text_editor; - - virtual void ok_pressed(); -public: - - void popup_find_line(TextEdit *p_edit); - int get_line() const; - - - void set_text_editor(TextEdit *p_text_editor); - GotoLineDialog(); -}; - -class FindReplaceBar : public HBoxContainer { - - GDCLASS(FindReplaceBar,HBoxContainer); - - LineEdit *search_text; - ToolButton *find_prev; - ToolButton *find_next; - CheckBox *case_sensitive; - CheckBox *whole_words; - Label *error_label; - TextureButton *hide_button; - - LineEdit *replace_text; - Button *replace; - Button *replace_all; - CheckBox *selection_only; - - VBoxContainer *text_vbc; - HBoxContainer *replace_hbc; - HBoxContainer *replace_options_hbc; - - TextEdit *text_edit; - - int result_line; - int result_col; - - bool replace_all_mode; - bool preserve_cursor; - - void _get_search_from(int& r_line, int& r_col); - - void _show_search(); - void _hide_bar(); - - void _editor_text_changed(); - void _search_options_changed(bool p_pressed); - void _search_text_changed(const String& p_text); - void _search_text_entered(const String& p_text); - void _replace_text_entered(const String& p_text); - -protected: - void _notification(int p_what); - void _unhandled_input(const InputEvent &p_event); - - bool _search(uint32_t p_flags, int p_from_line, int p_from_col); - - void _replace(); - void _replace_all(); - - static void _bind_methods(); - -public: - String get_search_text() const; - String get_replace_text() const; - - bool is_case_sensitive() const; - bool is_whole_words() const; - bool is_selection_only() const; - void set_error(const String& p_label); - - void set_text_edit(TextEdit *p_text_edit); - - void popup_search(); - void popup_replace(); - - bool search_current(); - bool search_prev(); - bool search_next(); - - FindReplaceBar(); -}; - -class FindReplaceDialog : public ConfirmationDialog { - - GDCLASS(FindReplaceDialog,ConfirmationDialog); - - LineEdit *search_text; - LineEdit *replace_text; - CheckButton *whole_words; - CheckButton *case_sensitive; - CheckButton *backwards; - CheckButton *prompt; - CheckButton *selection_only; - Button *skip; - Label *error_label; - MarginContainer *replace_mc; - Label *replace_label; - VBoxContainer *replace_vb; - - void _search_text_entered(const String& p_text); - void _replace_text_entered(const String& p_text); - void _prompt_changed(); - void _skip_pressed(); - - - TextEdit *text_edit; -protected: - - void _search_callback(); - void _replace_skip_callback(); - - bool _search(); - void _replace(); - - virtual void ok_pressed(); - static void _bind_methods(); -public: - - String get_search_text() const; - String get_replace_text() const; - bool is_whole_words() const; - bool is_case_sensitive() const; - bool is_backwards() const; - bool is_replace_mode() const; - bool is_replace_all_mode() const; - bool is_replace_selection_only() const; - void set_replace_selection_only(bool p_enable); - - void set_error(const String& p_error); - - void popup_search(); - void popup_replace(); - - void set_text_edit(TextEdit *p_text_edit); - - void search_next(); - FindReplaceDialog(); -}; - - -typedef void (*CodeTextEditorCodeCompleteFunc)(void* p_ud,const String& p_code, List<String>* r_options); - -class CodeTextEditor : public VBoxContainer { - - GDCLASS(CodeTextEditor,VBoxContainer); - - TextEdit *text_editor; - FindReplaceBar *find_replace_bar; - - Label *line_nb; - Label *col_nb; - Label *info; - Timer *idle; - Timer *code_complete_timer; - bool enable_complete_timer; - - Timer *font_resize_timer; - int font_resize_val; - - Label *error; - - void _on_settings_change(); - - void _update_font(); - void _complete_request(); - void _font_resize_timeout(); - - void _text_editor_gui_input(const InputEvent& p_event); - void _zoom_in(); - void _zoom_out(); - void _reset_zoom(); - - - CodeTextEditorCodeCompleteFunc code_complete_func; - void *code_complete_ud; - -protected: - - - virtual void _load_theme_settings() {} - virtual void _validate_script() {} - virtual void _code_complete_script(const String& p_code, List<String>* r_options) {} - - void _text_changed_idle_timeout(); - void _code_complete_timer_timeout(); - void _text_changed(); - void _line_col_changed(); - void _notification(int); - static void _bind_methods(); - -public: - - void update_editor_settings(); - void set_error(const String& p_error); - void update_line_and_column() { _line_col_changed(); } - TextEdit *get_text_edit() { return text_editor; } - FindReplaceBar *get_find_replace_bar() { return find_replace_bar; } - virtual void apply_code() {} - - - void set_code_complete_func(CodeTextEditorCodeCompleteFunc p_code_complete_func, void * p_ud); - - - CodeTextEditor(); -}; - - - -#endif // CODE_EDITOR_H diff --git a/tools/editor/connections_dialog.h b/tools/editor/connections_dialog.h deleted file mode 100644 index 64b292bc34..0000000000 --- a/tools/editor/connections_dialog.h +++ /dev/null @@ -1,134 +0,0 @@ -/*************************************************************************/ -/* connections_dialog.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef CONNECTIONS_DIALOG_H -#define CONNECTIONS_DIALOG_H - -#include "scene/gui/popup.h" -#include "scene/gui/button.h" -#include "scene/gui/check_button.h" -#include "scene/gui/tree.h" -#include "scene/gui/dialogs.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/line_edit.h" -#include "tools/editor/scene_tree_editor.h" -#include "tools/editor/property_editor.h" -#include "undo_redo.h" - -/** -@author Juan Linietsky <reduzio@gmail.com> -*/ - -class ConnectDialogBinds; - -class ConnectDialog : public ConfirmationDialog { - - GDCLASS( ConnectDialog, ConfirmationDialog ); - - - ConfirmationDialog *error; - LineEdit *dst_path; - LineEdit *dst_method; - SceneTreeEditor *tree; - //MenuButton *dst_method_list; - OptionButton *type_list; - CheckButton *deferred; - CheckButton *oneshot; - CheckButton *make_callback; - PropertyEditor *bind_editor; - Node *node; - ConnectDialogBinds *cdbinds; - void ok_pressed(); - void _cancel_pressed(); - void _tree_node_selected(); - void _dst_method_list_selected(int p_idx); - void _add_bind(); - void _remove_bind(); - -protected: - - void _notification(int p_what); - static void _bind_methods(); -public: - - - bool get_make_callback() { return make_callback->is_visible() && make_callback->is_pressed(); } - NodePath get_dst_path() const; - StringName get_dst_method() const; - bool get_deferred() const; - bool get_oneshot() const; - Vector<Variant> get_binds() const; - void set_dst_method(const StringName& p_method); - void set_dst_node(Node* p_node); - - //Button *get_ok() { return ok; } - //Button *get_cancel() { return cancel; } - void edit(Node *p_node); - - ConnectDialog(); - ~ConnectDialog(); - -}; - -class ConnectionsDock : public VBoxContainer { - - GDCLASS( ConnectionsDock , VBoxContainer ); - - Button *connect_button; - EditorNode *editor; - Node *node; - Tree *tree; - ConfirmationDialog *remove_confirm; - ConnectDialog *connect_dialog; - - void update_tree(); - - void _close(); - void _connect(); - void _something_selected(); - void _something_activated(); - UndoRedo *undo_redo; - -protected: - - void _connect_pressed(); - void _notification(int p_what); - static void _bind_methods(); -public: - - void set_undoredo(UndoRedo *p_undo_redo) { undo_redo=p_undo_redo; } - - void set_node(Node* p_node); - String get_selected_type(); - - ConnectionsDock(EditorNode *p_editor=NULL); - ~ConnectionsDock(); - -}; - -#endif diff --git a/tools/editor/editor_audio_buses.h b/tools/editor/editor_audio_buses.h deleted file mode 100644 index e44f8cd579..0000000000 --- a/tools/editor/editor_audio_buses.h +++ /dev/null @@ -1,186 +0,0 @@ -#ifndef EDITORAUDIOBUSES_H -#define EDITORAUDIOBUSES_H - - -#include "scene/gui/box_container.h" -#include "scene/gui/button.h" -#include "scene/gui/tool_button.h" -#include "scene/gui/scroll_container.h" -#include "scene/gui/panel_container.h" -#include "scene/gui/slider.h" -#include "scene/gui/texture_progress.h" -#include "scene/gui/texture_rect.h" -#include "scene/gui/line_edit.h" -#include "scene/gui/tree.h" -#include "scene/gui/option_button.h" -#include "scene/gui/panel.h" -#include "tools/editor/editor_file_dialog.h" -#include "editor_plugin.h" - -class EditorAudioBuses; - -class EditorAudioBus : public PanelContainer { - - GDCLASS( EditorAudioBus, PanelContainer ) - - bool prev_active; - float peak_l; - float peak_r; - - Ref<Texture> disabled_vu; - LineEdit *track_name; - VSlider *slider; - TextureProgress *vu_l; - TextureProgress *vu_r; - TextureRect *scale; - OptionButton *send; - - PopupMenu *effect_options; - PopupMenu *delete_popup; - PopupMenu *delete_effect_popup; - - Button *solo; - Button *mute; - Button *bypass; - - Tree *effects; - - bool updating_bus; - - void _gui_input(const InputEvent& p_event); - void _delete_pressed(int p_option); - - void _name_changed(const String& p_new_name); - void _name_focus_exit() { _name_changed(track_name->get_text()); } - void _volume_db_changed(float p_db); - void _solo_toggled(); - void _mute_toggled(); - void _bypass_toggled(); - void _send_selected(int p_which); - void _effect_edited(); - void _effect_add(int p_which); - void _effect_selected(); - void _delete_effect_pressed(int p_option); - void _effect_rmb(const Vector2& p_pos); - - - virtual Variant get_drag_data(const Point2& p_point); - virtual bool can_drop_data(const Point2& p_point,const Variant& p_data) const; - virtual void drop_data(const Point2& p_point,const Variant& p_data); - - - Variant get_drag_data_fw(const Point2& p_point,Control* p_from); - bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; - void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); - -friend class EditorAudioBuses; - - EditorAudioBuses *buses; - -protected: - - static void _bind_methods(); - void _notification(int p_what); -public: - - void update_bus(); - void update_send(); - - EditorAudioBus(EditorAudioBuses *p_buses=NULL); -}; - - -class EditorAudioBusDrop : public Panel { - - GDCLASS(EditorAudioBusDrop,Panel); - - virtual bool can_drop_data(const Point2& p_point,const Variant& p_data) const; - virtual void drop_data(const Point2& p_point,const Variant& p_data); -protected: - - static void _bind_methods(); -public: - - EditorAudioBusDrop(); -}; - -class EditorAudioBuses : public VBoxContainer { - - GDCLASS(EditorAudioBuses,VBoxContainer) - - HBoxContainer *top_hb; - - Button *add; - ScrollContainer *bus_scroll; - HBoxContainer *bus_hb; - - EditorAudioBusDrop *drop_end; - - Button *file; - Button *load; - Button *save_as; - Button *_default; - Button *_new; - - Timer *save_timer; - String edited_path; - - void _add_bus(); - void _update_buses(); - void _update_bus(int p_index); - void _update_sends(); - - void _delete_bus(Object* p_which); - void _duplicate_bus(int p_which); - - - void _request_drop_end(); - void _drop_at_index(int p_bus,int p_index); - - void _server_save(); - - void _select_layout(); - void _load_layout(); - void _save_as_layout(); - void _load_default_layout(); - void _new_layout(); - - EditorFileDialog *file_dialog; - bool new_layout; - - void _file_dialog_callback(const String& p_string); - -protected: - - static void _bind_methods(); - void _notification(int p_what); -public: - - void open_layout(const String& p_path); - - static EditorAudioBuses* register_editor(); - - EditorAudioBuses(); -}; - - - -class AudioBusesEditorPlugin : public EditorPlugin { - - GDCLASS( AudioBusesEditorPlugin, EditorPlugin ); - - EditorAudioBuses *audio_bus_editor; -public: - - virtual String get_name() const { return "SampleLibrary"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - AudioBusesEditorPlugin(EditorAudioBuses *p_node); - ~AudioBusesEditorPlugin(); - -}; - -#endif // EDITORAUDIOBUSES_H diff --git a/tools/editor/editor_data.h b/tools/editor/editor_data.h deleted file mode 100644 index fce606f722..0000000000 --- a/tools/editor/editor_data.h +++ /dev/null @@ -1,269 +0,0 @@ -/*************************************************************************/ -/* editor_data.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITOR_DATA_H -#define EDITOR_DATA_H - -#include "tools/editor/editor_plugin.h" -#include "scene/resources/texture.h" -#include "list.h" -#include "undo_redo.h" -#include "pair.h" - -class EditorHistory { - - enum { - - HISTORY_MAX=64 - }; - - struct Obj { - - REF ref; - ObjectID object; - String property; - }; - - struct History { - - Vector<Obj> path; - int level; - }; -friend class EditorData; - - Vector<History> history; - int current; - - //Vector<EditorPlugin*> editor_plugins; - - struct PropertyData { - - String name; - Variant value; - }; - - - void _cleanup_history(); - - void _add_object(ObjectID p_object,const String& p_property,int p_level_change); - -public: - - bool is_at_begining() const; - bool is_at_end() const; - - void add_object(ObjectID p_object); - void add_object(ObjectID p_object,const String& p_subprop); - void add_object(ObjectID p_object,int p_relevel); - - int get_history_len(); - int get_history_pos(); - ObjectID get_history_obj(int p_obj) const; - - bool next(); - bool previous(); - ObjectID get_current(); - - int get_path_size() const; - ObjectID get_path_object(int p_index) const; - String get_path_property(int p_index) const; - - void clear(); - - EditorHistory(); -}; - -class EditorSelection; - -class EditorData { - -public: - struct CustomType { - - String name; - Ref<Script> script; - Ref<Texture> icon; - }; -private: - - Vector<EditorPlugin*> editor_plugins; - - struct PropertyData { - - String name; - Variant value; - }; - Map<String,Vector<CustomType> > custom_types; - - List<PropertyData> clipboard; - UndoRedo undo_redo; - - - void _cleanup_history(); - - struct EditedScene { - Node* root; - Dictionary editor_states; - List<Node*> selection; - Vector<EditorHistory::History> history_stored; - int history_current; - Dictionary custom_state; - uint64_t version; - NodePath live_edit_root; - - - }; - - Vector<EditedScene> edited_scene; - int current_edited_scene; - - bool _find_updated_instances(Node* p_root,Node *p_node,Set<String> &checked_paths); - -public: - - EditorPlugin* get_editor(Object *p_object); - EditorPlugin* get_subeditor(Object *p_object); - Vector<EditorPlugin*> get_subeditors(Object *p_object); - EditorPlugin* get_editor(String p_name); - - void copy_object_params(Object *p_object); - void paste_object_params(Object *p_object); - - Dictionary get_editor_states() const; - Dictionary get_scene_editor_states(int p_idx) const; - void set_editor_states(const Dictionary& p_states); - void get_editor_breakpoints(List<String> *p_breakpoints); - void clear_editor_states(); - void save_editor_external_data(); - void apply_changes_in_editors(); - - void add_editor_plugin(EditorPlugin *p_plugin); - void remove_editor_plugin(EditorPlugin *p_plugin); - - int get_editor_plugin_count() const; - EditorPlugin *get_editor_plugin(int p_idx); - - UndoRedo &get_undo_redo(); - - void save_editor_global_states(); - void restore_editor_global_states(); - - void add_custom_type(const String& p_type, const String& p_inherits,const Ref<Script>& p_script,const Ref<Texture>& p_icon ); - void remove_custom_type(const String& p_type); - const Map<String,Vector<CustomType> >& get_custom_types() const { return custom_types; } - - - int add_edited_scene(int p_at_pos); - void move_edited_scene_index(int p_idx,int p_to_idx); - void remove_scene(int p_idx); - void set_edited_scene(int p_idx); - void set_edited_scene_root(Node* p_root); - int get_edited_scene() const; - Node* get_edited_scene_root(int p_idx = -1); - int get_edited_scene_count() const; - String get_scene_title(int p_idx) const; - String get_scene_path(int p_idx) const; - String get_scene_type(int p_idx) const; - Ref<Script> get_scene_root_script(int p_idx) const; - void set_edited_scene_version(uint64_t version, int p_scene_idx = -1); - uint64_t get_edited_scene_version() const; - uint64_t get_scene_version(int p_idx) const; - void clear_edited_scenes(); - void set_edited_scene_live_edit_root(const NodePath& p_root); - NodePath get_edited_scene_live_edit_root(); - bool check_and_update_scene(int p_idx); - void move_edited_scene_to_index(int p_idx); - - - void set_plugin_window_layout(Ref<ConfigFile> p_layout); - void get_plugin_window_layout(Ref<ConfigFile> p_layout); - - void save_edited_scene_state(EditorSelection *p_selection,EditorHistory *p_history,const Dictionary& p_custom); - Dictionary restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history); - void notify_edited_scene_changed(); - - - EditorData(); -}; - - - -class EditorSelection : public Object { - - GDCLASS(EditorSelection,Object); -public: - - Map<Node*,Object*> selection; - - bool changed; - bool nl_changed; - - void _node_removed(Node *p_node); - - List<Object*> editor_plugins; - List<Node*> selected_node_list; - - void _update_nl(); - Array _get_selected_nodes(); - Array _get_transformable_selected_nodes(); - -protected: - - static void _bind_methods(); -public: - - void add_node(Node *p_node); - void remove_node(Node *p_node); - bool is_selected(Node *) const; - - template<class T> - T* get_node_editor_data(Node *p_node) { - if (!selection.has(p_node)) - return NULL; - Object *obj = selection[p_node]; - if (!obj) - return NULL; - return obj->cast_to<T>(); - } - - void add_editor_plugin(Object *p_object); - - void update(); - void clear(); - - - List<Node*>& get_selected_node_list(); - Map<Node*,Object*>& get_selection() { return selection; } - - - EditorSelection(); - ~EditorSelection(); -}; - - -#endif // EDITOR_DATA_H diff --git a/tools/editor/editor_dir_dialog.cpp b/tools/editor/editor_dir_dialog.cpp deleted file mode 100644 index c353e43070..0000000000 --- a/tools/editor/editor_dir_dialog.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/*************************************************************************/ -/* editor_dir_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 "editor_dir_dialog.h" - -#include "os/os.h" -#include "os/keyboard.h" -#include "tools/editor/editor_settings.h" -#include "tools/editor/editor_file_system.h" - - -void EditorDirDialog::_update_dir(TreeItem* p_item) { - - updating=true; - p_item->clear_children(); - DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - String cdir = p_item->get_metadata(0); - - da->change_dir(cdir); - da->list_dir_begin(); - String p=da->get_next(); - - List<String> dirs; - bool ishidden; - bool show_hidden = EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"); - - while(p!="") { - - ishidden = da->current_is_hidden(); - - if (show_hidden || !ishidden) { - if (da->current_is_dir() && !p.begins_with(".")) { - dirs.push_back(p); - } - } - p=da->get_next(); - } - - dirs.sort(); - - for(List<String>::Element *E=dirs.front();E;E=E->next()) { - TreeItem *ti = tree->create_item(p_item); - ti->set_text(0,E->get()); - ti->set_icon(0,get_icon("Folder","EditorIcons")); - ti->set_collapsed(true); - - } - - memdelete(da); - updating=false; - -} - - -void EditorDirDialog::reload() { - - if (!is_visible_in_tree()) { - must_reload=true; - return; - } - - tree->clear(); - TreeItem *root = tree->create_item(); - root->set_metadata(0,"res://"); - root->set_icon(0,get_icon("Folder","EditorIcons")); - root->set_text(0,"/"); - _update_dir(root); - _item_collapsed(root); - must_reload=false; - -} - - -void EditorDirDialog::_notification(int p_what) { - - if (p_what==NOTIFICATION_ENTER_TREE) { - reload(); - - if (!tree->is_connected("item_collapsed",this,"_item_collapsed")) { - tree->connect("item_collapsed",this,"_item_collapsed",varray(),CONNECT_DEFERRED); - } - - if (!EditorFileSystem::get_singleton()->is_connected("filesystem_changed",this,"reload")) { - EditorFileSystem::get_singleton()->connect("filesystem_changed",this,"reload"); - } - - } - - if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { - if (must_reload && is_visible_in_tree()) { - reload(); - } - } -} - -void EditorDirDialog::_item_collapsed(Object* _p_item){ - - TreeItem *p_item=_p_item->cast_to<TreeItem>(); - - if (updating || p_item->is_collapsed()) - return; - - TreeItem *ci = p_item->get_children(); - while(ci) { - - String p =ci->get_metadata(0); - if (p=="") { - String pp = p_item->get_metadata(0); - ci->set_metadata(0,pp.plus_file(ci->get_text(0))); - _update_dir(ci); - } - ci=ci->get_next(); - } - -} - -void EditorDirDialog::set_current_path(const String& p_path) { - - reload(); - String p = p_path; - if (p.begins_with("res://")) - p = p.replace_first("res://",""); - - Vector<String> dirs = p.split("/",false); - - TreeItem *r=tree->get_root(); - for(int i=0;i<dirs.size();i++) { - - String d = dirs[i]; - TreeItem *p = r->get_children(); - while(p) { - - if (p->get_text(0)==d) - break; - p=p->get_next(); - } - - ERR_FAIL_COND(!p); - String pp = p->get_metadata(0); - if (pp=="") { - p->set_metadata(0,String(r->get_metadata(0)).plus_file(d)); - _update_dir(p); - } - updating=true; - p->set_collapsed(false); - updating=false; - _item_collapsed(p); - r=p; - } - - r->select(0); - -} - -void EditorDirDialog::ok_pressed() { - - TreeItem *ti=tree->get_selected(); - if (!ti) - return; - - String dir = ti->get_metadata(0); - emit_signal("dir_selected",dir); - hide(); -} - - -void EditorDirDialog::_make_dir() { - - TreeItem *ti=tree->get_selected(); - if (!ti) { - mkdirerr->set_text("Please select a base directory first"); - mkdirerr->popup_centered_minsize(); - return; - } - - makedialog->popup_centered_minsize(Size2(250,80)); - makedirname->grab_focus(); -} - -void EditorDirDialog::_make_dir_confirm() { - - TreeItem *ti=tree->get_selected(); - if (!ti) - return; - - String dir = ti->get_metadata(0); - - DirAccess *d = DirAccess::open(dir); - ERR_FAIL_COND(!d); - Error err = d->make_dir(makedirname->get_text()); - - if (err!=OK) { - mkdirerr->popup_centered_minsize(Size2(250,80)); - } else { - set_current_path(dir.plus_file(makedirname->get_text())); - } - makedirname->set_text(""); // reset label -} - - -void EditorDirDialog::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_item_collapsed"),&EditorDirDialog::_item_collapsed); - ClassDB::bind_method(D_METHOD("_make_dir"),&EditorDirDialog::_make_dir); - ClassDB::bind_method(D_METHOD("_make_dir_confirm"),&EditorDirDialog::_make_dir_confirm); - ClassDB::bind_method(D_METHOD("reload"),&EditorDirDialog::reload); - - ADD_SIGNAL(MethodInfo("dir_selected",PropertyInfo(Variant::STRING,"dir"))); -} - - - -EditorDirDialog::EditorDirDialog() { - - updating=false; - - set_title(TTR("Choose a Directory")); - set_hide_on_ok(false); - - tree = memnew( Tree ); - add_child(tree); - - tree->connect("item_activated",this,"_ok"); - - makedir = add_button(TTR("Create Folder"),OS::get_singleton()->get_swap_ok_cancel()?true:false,"makedir"); - makedir->connect("pressed",this,"_make_dir"); - - makedialog = memnew( ConfirmationDialog ); - makedialog->set_title(TTR("Create Folder")); - add_child(makedialog); - - VBoxContainer *makevb= memnew( VBoxContainer ); - makedialog->add_child(makevb); - //makedialog->set_child_rect(makevb); - - makedirname = memnew( LineEdit ); - makevb->add_margin_child(TTR("Name:"),makedirname); - makedialog->register_text_enter(makedirname); - makedialog->connect("confirmed",this,"_make_dir_confirm"); - - mkdirerr = memnew( AcceptDialog ); - mkdirerr->set_text(TTR("Could not create folder.")); - add_child(mkdirerr); - - get_ok()->set_text(TTR("Choose")); - - must_reload=false; - - - -} diff --git a/tools/editor/editor_export.cpp b/tools/editor/editor_export.cpp deleted file mode 100644 index a67b583868..0000000000 --- a/tools/editor/editor_export.cpp +++ /dev/null @@ -1,3231 +0,0 @@ -/*************************************************************************/ -/* editor_import_export.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 "editor_export.h" -#include "version.h" -#include "script_language.h" -#include "global_config.h" -#include "os/file_access.h" -#include "os/dir_access.h" -#include "tools/editor/editor_file_system.h" -#include "io/resource_loader.h" -#include "editor_node.h" -#include "editor_settings.h" -#include "io/config_file.h" -#include "io/resource_saver.h" -#include "io/md5.h" -#include "tools/editor/plugins/script_editor_plugin.h" -#include "io/zip_io.h" - -static int _get_pad(int p_alignment, int p_n) { - - int rest = p_n % p_alignment; - int pad = 0; - if (rest > 0) { - pad = p_alignment - rest; - }; - - return pad; -}; - -#define PCK_PADDING 16 - -bool EditorExportPreset::_set(const StringName& p_name, const Variant& p_value) { - - if (values.has(p_name)) { - values[p_name]=p_value; - EditorExport::singleton->save_presets(); - return true; - } - - return false; -} - -bool EditorExportPreset::_get(const StringName& p_name,Variant &r_ret) const{ - - if (values.has(p_name)) { - r_ret=values[p_name]; - return true; - } - - return false; -} -void EditorExportPreset::_get_property_list( List<PropertyInfo> *p_list) const{ - - for (const List<PropertyInfo>::Element *E=properties.front();E;E=E->next()) { - - p_list->push_back(E->get()); - } -} - -Ref<EditorExportPlatform> EditorExportPreset::get_platform() const { - - return platform; -} - -Vector<String> EditorExportPreset::get_files_to_export() const { - - Vector<String> files; - for(Set<String>::Element *E=selected_files.front();E;E=E->next()) { - files.push_back(E->get()); - } - return files; -} - -void EditorExportPreset::set_name(const String& p_name) { - name=p_name; - EditorExport::singleton->save_presets(); - -} - -String EditorExportPreset::get_name() const { - return name; - -} - -void EditorExportPreset::set_runnable(bool p_enable) { - - runnable=p_enable; - EditorExport::singleton->save_presets(); -} - -bool EditorExportPreset::is_runnable() const { - - return runnable; -} - -void EditorExportPreset::set_export_filter(ExportFilter p_filter) { - - export_filter=p_filter; - EditorExport::singleton->save_presets(); - -} - -EditorExportPreset::ExportFilter EditorExportPreset::get_export_filter() const { - return export_filter; -} - -void EditorExportPreset::set_include_filter(const String& p_include) { - - include_filter=p_include; - EditorExport::singleton->save_presets(); - -} - -String EditorExportPreset::get_include_filter() const { - - return include_filter; -} - -void EditorExportPreset::set_exclude_filter(const String& p_exclude) { - - exclude_filter=p_exclude; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_exclude_filter() const { - - return exclude_filter; -} - -void EditorExportPreset::add_export_file(const String& p_path) { - - selected_files.insert(p_path); - EditorExport::singleton->save_presets(); -} - -void EditorExportPreset::remove_export_file(const String& p_path) { - selected_files.erase(p_path); - EditorExport::singleton->save_presets(); -} - -bool EditorExportPreset::has_export_file(const String& p_path) { - - return selected_files.has(p_path); -} - -void EditorExportPreset::add_patch(const String& p_path,int p_at_pos) { - - if (p_at_pos<0) - patches.push_back(p_path); - else - patches.insert(p_at_pos,p_path); - EditorExport::singleton->save_presets(); -} - -void EditorExportPreset::remove_patch(int p_idx) { - patches.remove(p_idx); - EditorExport::singleton->save_presets(); -} - -void EditorExportPreset::set_patch(int p_index,const String& p_path) { - ERR_FAIL_INDEX(p_index,patches.size()); - patches[p_index]=p_path; - EditorExport::singleton->save_presets(); -} -String EditorExportPreset::get_patch(int p_index) { - - ERR_FAIL_INDEX_V(p_index,patches.size(),String()); - return patches[p_index]; -} - -Vector<String> EditorExportPreset::get_patches() const { - return patches; -} - -EditorExportPreset::EditorExportPreset() { - - export_filter=EXPORT_ALL_RESOURCES; - runnable=false; -} - - -/////////////////////////////////// - -void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags) { - - String host = EditorSettings::get_singleton()->get("network/debug_host"); - - if (p_flags&DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST) - host="localhost"; - - if (p_flags&DEBUG_FLAG_DUMB_CLIENT) { - int port = EditorSettings::get_singleton()->get("filesystem/file_server/port"); - String passwd = EditorSettings::get_singleton()->get("filesystem/file_server/password"); - r_flags.push_back("-rfs"); - r_flags.push_back(host+":"+itos(port)); - if (passwd!="") { - r_flags.push_back("-rfs_pass"); - r_flags.push_back(passwd); - } - } - - if (p_flags&DEBUG_FLAG_REMOTE_DEBUG) { - - r_flags.push_back("-rdebug"); - - r_flags.push_back(host+":"+String::num(GLOBAL_DEF("network/debug/remote_port", 6007))); - - List<String> breakpoints; - ScriptEditor::get_singleton()->get_breakpoints(&breakpoints); - - - if (breakpoints.size()) { - - r_flags.push_back("-bp"); - String bpoints; - for(const List<String>::Element *E=breakpoints.front();E;E=E->next()) { - - bpoints+=E->get().replace(" ","%20"); - if (E->next()) - bpoints+=","; - } - - r_flags.push_back(bpoints); - } - - } - - if (p_flags&DEBUG_FLAG_VIEW_COLLISONS) { - - r_flags.push_back("-debugcol"); - } - - if (p_flags&DEBUG_FLAG_VIEW_NAVIGATION) { - - r_flags.push_back("-debugnav"); - } -} - -Error EditorExportPlatform::_save_pack_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total) { - - PackData *pd = (PackData*)p_userdata; - - SavedData sd; - sd.path_utf8=p_path.utf8(); - sd.ofs = pd->f->get_pos(); - sd.size = p_data.size(); - - pd->f->store_buffer(p_data.ptr(),p_data.size()); - int pad = _get_pad(PCK_PADDING,sd.size); - for(int i=0;i<pad;i++) { - pd->f->store_8(0); - } - - { - MD5_CTX ctx; - MD5Init(&ctx); - MD5Update(&ctx,(unsigned char*)p_data.ptr(),p_data.size()); - MD5Final(&ctx); - sd.md5.resize(16); - for(int i=0;i<16;i++) { - sd.md5[i]=ctx.digest[i]; - } - } - - pd->file_ofs.push_back(sd); - - pd->ep->step(TTR("Storing File:")+" "+p_path,2+p_file*100/p_total,false); - - return OK; -} - -Error EditorExportPlatform::_save_zip_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total) { - - - String path=p_path.replace_first("res://",""); - - ZipData *zd = (ZipData*)p_userdata; - - zipFile zip=(zipFile)zd->zip; - - zipOpenNewFileInZip(zip, - path.utf8().get_data(), - NULL, - NULL, - 0, - NULL, - 0, - NULL, - Z_DEFLATED, - Z_DEFAULT_COMPRESSION); - - zipWriteInFileInZip(zip,p_data.ptr(),p_data.size()); - zipCloseFileInZip(zip); - - zd->ep->step(TTR("Storing File:")+" "+p_path,2+p_file*100/p_total,false); - - return OK; -} - -String EditorExportPlatform::find_export_template(String template_file_name, String *err) const { - - String user_file = EditorSettings::get_singleton()->get_settings_path() - +"/templates/"+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"."+_MKSTR(VERSION_STATUS)+"/"+template_file_name; - String system_file=OS::get_singleton()->get_installed_templates_path(); - bool has_system_path=(system_file!=""); - system_file+=template_file_name; - - // Prefer user file - if (FileAccess::exists(user_file)) { - return user_file; - } - - // Now check system file - if (has_system_path) { - if (FileAccess::exists(system_file)) { - return system_file; - } - } - - // Not found - if (err) { - *err+="No export template found at \""+user_file+"\""; - if (has_system_path) - *err+="\n or \""+system_file+"\"."; - else - *err+="."; - } - return ""; -} - -Ref<EditorExportPreset> EditorExportPlatform::create_preset() { - - Ref<EditorExportPreset> preset; - preset.instance(); - preset->platform=Ref<EditorExportPlatform>(this); - - List<ExportOption> options; - get_export_options(&options); - - for (List<ExportOption>::Element *E=options.front();E;E=E->next()) { - - preset->properties.push_back(E->get().option); - preset->values[E->get().option.name]=E->get().default_value; - } - - return preset; - -} - -void EditorExportPlatform::_export_find_resources(EditorFileSystemDirectory *p_dir,Set<String>& p_paths) { - - for(int i=0;i<p_dir->get_subdir_count();i++) { - _export_find_resources(p_dir->get_subdir(i),p_paths); - } - - for(int i=0;i<p_dir->get_file_count();i++) { - p_paths.insert(p_dir->get_file_path(i)); - } -} - - -void EditorExportPlatform::_export_find_dependencies(const String& p_path,Set<String>& p_paths) { - - if (p_paths.has(p_path)) - return; - - p_paths.insert(p_path); - - EditorFileSystemDirectory *dir; - int file_idx; - dir = EditorFileSystem::get_singleton()->find_file(p_path,&file_idx); - if (!dir) - return; - - Vector<String> deps = dir->get_file_deps(file_idx); - - for(int i=0;i<deps.size();i++) { - - _export_find_dependencies(deps[i],p_paths); - } -} - - -Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset>& p_preset,EditorExportSaveFunction p_func, void* p_udata) { - - Ref<EditorExportPlatform> platform = p_preset->get_platform(); - List<String> feature_list; - platform->get_preset_features(p_preset,&feature_list); - //figure out features - Set<String> features; - for (List<String>::Element *E=feature_list.front();E;E=E->next()) { - features.insert(E->get()); - } - - //figure out paths of files that will be exported - Set<String> paths; - - if (p_preset->get_export_filter()==EditorExportPreset::EXPORT_ALL_RESOURCES) { - //find stuff - _export_find_resources(EditorFileSystem::get_singleton()->get_filesystem(),paths); - } else { - bool scenes_only = p_preset->get_export_filter()==EditorExportPreset::EXPORT_SELECTED_SCENES; - - Vector<String> files = p_preset->get_files_to_export(); - for(int i=0;i<files.size();i++) { - if (scenes_only && ResourceLoader::get_resource_type(files[i])!="PackedScene") - continue; - - _export_find_dependencies(files[i],paths); - } - } - - //store everything in the export medium - int idx = 0; - int total=paths.size(); - - for(Set<String>::Element *E=paths.front();E;E=E->next()) { - - String path = E->get(); - - if (FileAccess::exists(path+".import")) { - //file is imported, replace by what it imports - Ref<ConfigFile> config; - config.instance(); - Error err = config->load(path+".import"); - if (err!=OK) { - ERR_PRINTS("Could not parse: '"+path+"', not exported."); - continue; - } - - List<String> remaps; - config->get_section_keys("remap",&remaps); - - for(List<String>::Element *F=remaps.front();F;F=F->next()) { - - String remap=F->get(); - if (remap=="path") { - String remapped_path=config->get_value("remap",remap); - Vector<uint8_t> array = FileAccess::get_file_as_array(remapped_path); - p_func(p_udata,remapped_path,array,idx,total); - } else if (remap.begins_with("path.")) { - String feature = remap.get_slice(".",1); - if (features.has(feature)) { - String remapped_path=config->get_value("remap",remap); - Vector<uint8_t> array = FileAccess::get_file_as_array(remapped_path); - p_func(p_udata,remapped_path,array,idx,total); - } - } - } - - //also save the .import file - Vector<uint8_t> array = FileAccess::get_file_as_array(path+".import"); - p_func(p_udata,path+".import",array,idx,total); - - } else { - //just store it as it comes - Vector<uint8_t> array = FileAccess::get_file_as_array(path); - p_func(p_udata,path,array,idx,total); - } - - idx++; - } - - //save config! - - String config_file="godot.cfb"; - String engine_cfb =EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmp"+config_file; - GlobalConfig::get_singleton()->save_custom(engine_cfb); - Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb); - - p_func(p_udata,"res://"+config_file,data,idx,total); - - return OK; -} - -Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset>& p_preset,const String& p_path) { - - EditorProgress ep("savepack",TTR("Packing"),102); - - String tmppath = EditorSettings::get_singleton()->get_settings_path()+"/tmp/packtmp"; - FileAccess *ftmp = FileAccess::open(tmppath,FileAccess::WRITE); - ERR_FAIL_COND_V(!ftmp,ERR_CANT_CREATE) - - PackData pd; - pd.ep=&ep; - pd.f=ftmp; - - Error err = export_project_files(p_preset,_save_pack_file,&pd); - - memdelete(ftmp); //close tmp file - - if (err) - return err; - - pd.file_ofs.sort(); //do sort, so we can do binary search later - - - FileAccess *f = FileAccess::open(p_path,FileAccess::WRITE); - ERR_FAIL_COND_V(!f,ERR_CANT_CREATE) - f->store_32(0x43504447); //GDPK - f->store_32(1); //pack version - f->store_32(VERSION_MAJOR); - f->store_32(VERSION_MINOR); - f->store_32(0); //hmph - for(int i=0;i<16;i++) { - //reserved - f->store_32(0); - } - - f->store_32(pd.file_ofs.size()); //amount of files - - size_t header_size = f->get_pos(); - - //precalculate header size - - for(int i=0;i<pd.file_ofs.size();i++) { - header_size += 4; // size of path string (32 bits is enough) - uint32_t string_len = pd.file_ofs[i].path_utf8.length(); - header_size += string_len + _get_pad(4,string_len); ///size of path string - header_size += 8; // offset to file _with_ header size included - header_size += 8; // size of file - header_size +=16; // md5 - - } - - size_t header_padding = _get_pad(PCK_PADDING,header_size); - - - for(int i=0;i<pd.file_ofs.size();i++) { - - uint32_t string_len = pd.file_ofs[i].path_utf8.length(); - uint32_t pad = _get_pad(4,string_len);; - f->store_32(string_len+pad); - f->store_buffer((const uint8_t*)pd.file_ofs[i].path_utf8.get_data(),string_len); - for(uint32_t j=0;j<pad;j++) { - f->store_8(0); - } - - f->store_64(pd.file_ofs[i].ofs + header_padding + header_size); - f->store_64(pd.file_ofs[i].size); // pay attention here, this is where file is - f->store_buffer(pd.file_ofs[i].md5.ptr(),16); //also save md5 for file - } - - for(uint32_t j=0;j<header_padding;j++) { - f->store_8(0); - } - - //save the rest of the data - - ftmp = FileAccess::open(tmppath,FileAccess::READ); - if (!ftmp) { - memdelete(f); - ERR_FAIL_COND_V(!ftmp,ERR_CANT_CREATE) - } - - const int bufsize=16384; - uint8_t buf[bufsize]; - - while(true) { - - int got = ftmp->get_buffer(buf,bufsize); - if (got<=0) - break; - f->store_buffer(buf,got); - } - - memdelete(ftmp); - - f->store_32(0x43504447); //GDPK - memdelete(f); - - return OK; -} - -Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset>& p_preset,const String& p_path) { - - EditorProgress ep("savezip",TTR("Packing"),102); - - //FileAccess *tmp = FileAccess::open(tmppath,FileAccess::WRITE); - - FileAccess *src_f; - zlib_filefunc_def io = zipio_create_io_from_file(&src_f); - zipFile zip=zipOpen2(p_path.utf8().get_data(),APPEND_STATUS_CREATE,NULL,&io); - - ZipData zd; - zd.ep=&ep; - zd.zip=zip; - - - Error err = export_project_files(p_preset,_save_zip_file,&zd); - - zipClose(zip,NULL); - - return OK; -} - -EditorExportPlatform::EditorExportPlatform() { - - -} - - -//// - -EditorExport *EditorExport::singleton=NULL; - - -void EditorExport::_save() { - - - Ref<ConfigFile> config; - config.instance(); - for(int i=0;i<export_presets.size();i++) { - - Ref<EditorExportPreset> preset = export_presets[i]; - String section="preset."+itos(i); - - config->set_value(section,"name",preset->get_name()); - config->set_value(section,"platform",preset->get_platform()->get_name()); - config->set_value(section,"runnable",preset->is_runnable()); - bool save_files=false; - switch(preset->get_export_filter()) { - case EditorExportPreset::EXPORT_ALL_RESOURCES: { - config->set_value(section,"export_filter","all_resources"); - } break; - case EditorExportPreset::EXPORT_SELECTED_SCENES: { - config->set_value(section,"export_filter","scenes"); - save_files=true; - } break; - case EditorExportPreset::EXPORT_SELECTED_RESOURCES: { - config->set_value(section,"export_filter","resources"); - save_files=true; - } break; - - - } - - if (save_files) { - Vector<String> export_files = preset->get_files_to_export(); - config->set_value(section,"export_files",export_files); - } - config->set_value(section,"include_filter",preset->get_include_filter()); - config->set_value(section,"exclude_filter",preset->get_exclude_filter()); - config->set_value(section,"patch_list",preset->get_patches()); - - String option_section="preset."+itos(i)+".options"; - - for (const List<PropertyInfo>::Element *E=preset->get_properties().front();E;E=E->next()) { - config->set_value(option_section,E->get().name,preset->get(E->get().name)); - } - } - - config->save("res://export_presets.cfg"); - - print_line("saved ok"); - -} - - -void EditorExport::save_presets() { - - print_line("save presets"); - if (block_save) - return; - save_timer->start(); -} - -void EditorExport::_bind_methods() { - - ClassDB::bind_method("_save",&EditorExport::_save); -} - -void EditorExport::add_export_platform(const Ref<EditorExportPlatform>& p_platform) { - - export_platforms.push_back(p_platform); -} - -int EditorExport::get_export_platform_count() { - - return export_platforms.size(); -} - -Ref<EditorExportPlatform> EditorExport::get_export_platform(int p_idx) { - - ERR_FAIL_INDEX_V(p_idx,export_platforms.size(),Ref<EditorExportPlatform>()); - - return export_platforms[p_idx]; -} - - -void EditorExport::add_export_preset(const Ref<EditorExportPreset>& p_preset,int p_at_pos) { - - if (p_at_pos<0) - export_presets.push_back(p_preset); - else - export_presets.insert(p_at_pos,p_preset); - - -} - -int EditorExport::get_export_preset_count() const { - - return export_presets.size(); -} - -Ref<EditorExportPreset> EditorExport::get_export_preset(int p_idx) { - - ERR_FAIL_INDEX_V( p_idx, export_presets.size(),Ref<EditorExportPreset>() ); - return export_presets[p_idx]; -} - -void EditorExport::remove_export_preset(int p_idx) { - - export_presets.remove(p_idx); -} - -void EditorExport::_notification(int p_what) { - - if (p_what==NOTIFICATION_ENTER_TREE) { - load_config(); - } -} - -void EditorExport::load_config() { - - Ref<ConfigFile> config; - config.instance(); - Error err = config->load("res://export_presets.cfg"); - if (err!=OK) - return; - - block_save=true; - - int index=0; - while(true) { - - String section = "preset."+itos(index); - if (!config->has_section(section)) - break; - - String platform=config->get_value(section,"platform"); - - Ref<EditorExportPreset> preset; - - for(int i=0;i<export_platforms.size();i++) { - if (export_platforms[i]->get_name()==platform) { - preset = export_platforms[i]->create_preset(); - break; - } - } - - if (!preset.is_valid()) { - index++; - ERR_CONTINUE(!preset.is_valid()); - } - - preset->set_name( config->get_value(section,"name") ); - preset->set_runnable( config->get_value(section,"runnable") ); - - String export_filter = config->get_value(section,"export_filter"); - - bool get_files=false; - - if (export_filter=="all_resources") { - preset->set_export_filter(EditorExportPreset::EXPORT_ALL_RESOURCES); - } else if (export_filter=="scenes") { - preset->set_export_filter(EditorExportPreset::EXPORT_SELECTED_SCENES); - get_files=true; - } else if (export_filter=="resources") { - preset->set_export_filter(EditorExportPreset::EXPORT_SELECTED_RESOURCES); - get_files=true; - } - - if (get_files) { - - Vector<String> files = config->get_value(section,"export_files"); - - for(int i=0;i<files.size();i++) { - preset->add_export_file(files[i]); - } - } - - preset->set_include_filter( config->get_value(section,"include_filter") ); - preset->set_exclude_filter( config->get_value(section,"exclude_filter") ); - - - Vector<String> patch_list = config->get_value(section,"patch_list"); - - for(int i=0;i<patch_list.size();i++) { - preset->add_patch(patch_list[i]); - } - - String option_section="preset."+itos(index)+".options"; - - List<String> options; - - config->get_section_keys(option_section,&options); - - for (List<String>::Element *E=options.front();E;E=E->next()) { - - Variant value = config->get_value(option_section,E->get()); - - preset->set(E->get(),value); - } - - add_export_preset(preset); - index++; - } - - block_save=false; - -} - - - -EditorExport::EditorExport() { - - save_timer = memnew( Timer ); - add_child(save_timer); - save_timer->set_wait_time(0.8); - save_timer->set_one_shot(true); - save_timer->connect("timeout",this,"_save"); - block_save=false; - - singleton=this; -} - -EditorExport::~EditorExport() { - - -} - - -////////// - -void EditorExportPlatformPC::get_preset_features(const Ref<EditorExportPreset>& p_preset,List<String>* r_features) { - - if (p_preset->get("texture_format/s3tc")) { - r_features->push_back("s3tc"); - } - if (p_preset->get("texture_format/etc")) { - r_features->push_back("etc"); - } - if (p_preset->get("texture_format/etc2")) { - r_features->push_back("etc2"); - } -} - -void EditorExportPlatformPC::get_export_options(List<ExportOption> *r_options) { - - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL,"texture_format/s3tc"),true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL,"texture_format/etc"),false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL,"texture_format/etc2"),false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL,"binary_format/64_bits"),true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING,"custom_template/release",PROPERTY_HINT_GLOBAL_FILE),"")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING,"custom_template/debug",PROPERTY_HINT_GLOBAL_FILE),"")); -} - -String EditorExportPlatformPC::get_name() const { - - return name; -} -Ref<Texture> EditorExportPlatformPC::get_logo() const { - - return logo; -} - -bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset>& p_preset,String &r_error, bool &r_missing_templates) const { - - r_missing_templates=false; - - if (find_export_template(release_file_32)==String()) { - r_missing_templates=true; - } else if (find_export_template(debug_file_32)==String()) { - r_missing_templates=true; - } else if (find_export_template(release_file_64)==String()) { - r_missing_templates=true; - } else if (find_export_template(debug_file_64)==String()) { - r_missing_templates=true; - } - return !r_missing_templates; -} - -String EditorExportPlatformPC::get_binary_extension() const { - return extension; -} - -Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset>& p_preset, bool p_debug, const String& p_path, int p_flags) { - - return OK; -} - -void EditorExportPlatformPC::set_extension(const String& p_extension) { - extension=p_extension; -} - -void EditorExportPlatformPC::set_name(const String& p_name) { - name=p_name; -} - -void EditorExportPlatformPC::set_logo(const Ref<Texture>& p_logo) { - logo=p_logo; -} - -void EditorExportPlatformPC::set_release_64(const String& p_file) { - - release_file_64=p_file; -} - -void EditorExportPlatformPC::set_release_32(const String& p_file){ - - release_file_32=p_file; -} -void EditorExportPlatformPC::set_debug_64(const String& p_file){ - - debug_file_64=p_file; -} -void EditorExportPlatformPC::set_debug_32(const String& p_file){ - - debug_file_32=p_file; - -} - -EditorExportPlatformPC::EditorExportPlatformPC() { - -} - -//////// - -#if 0 -#include "version.h" -#include "script_language.h" -#include "global_config.h" -#include "os/file_access.h" -#include "os/dir_access.h" -#include "tools/editor/editor_file_system.h" -#include "io/resource_loader.h" -#include "editor_node.h" -#include "editor_settings.h" -#include "io/config_file.h" -#include "io/resource_saver.h" -#include "io/md5.h" -#include "io_plugins/editor_texture_import_plugin.h" -#include "tools/editor/plugins/script_editor_plugin.h" -#include "io/zip_io.h" - - -String EditorImportPlugin::validate_source_path(const String& p_path) { - - String gp = GlobalConfig::get_singleton()->globalize_path(p_path); - String rp = GlobalConfig::get_singleton()->get_resource_path(); - if (!rp.ends_with("/")) - rp+="/"; - - return rp.path_to_file(gp); -} - -String EditorImportPlugin::expand_source_path(const String& p_path) { - - if (p_path.is_rel_path()) { - return GlobalConfig::get_singleton()->get_resource_path().plus_file(p_path).simplify_path(); - } else { - return p_path; - } -} - - -String EditorImportPlugin::_validate_source_path(const String& p_path) { - - return validate_source_path(p_path); -} - -String EditorImportPlugin::_expand_source_path(const String& p_path) { - - return expand_source_path(p_path); -} - -void EditorImportPlugin::_bind_methods() { - - - ClassDB::bind_method(D_METHOD("validate_source_path","path"),&EditorImportPlugin::_validate_source_path); - ClassDB::bind_method(D_METHOD("expand_source_path","path"),&EditorImportPlugin::_expand_source_path); - - ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::STRING,"get_name")); - ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::STRING,"get_visible_name")); - ClassDB::add_virtual_method(get_class_static(),MethodInfo("import_dialog",PropertyInfo(Variant::STRING,"from"))); - ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::INT,"import",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"from",PROPERTY_HINT_RESOURCE_TYPE,"ResourceImportMetadata"))); - ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::POOL_BYTE_ARRAY,"custom_export",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"platform",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatform"))); - ClassDB::add_virtual_method(get_class_static(),MethodInfo("import_from_drop",PropertyInfo(Variant::POOL_STRING_ARRAY,"files"),PropertyInfo(Variant::STRING,"dest_path"))); - ClassDB::add_virtual_method(get_class_static(),MethodInfo("reimport_multiple_files",PropertyInfo(Variant::POOL_STRING_ARRAY,"files"))); - ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::BOOL,"can_reimport_multiple_files")); - - //BIND_VMETHOD( mi ); -} - -String EditorImportPlugin::get_name() const { - - if (get_script_instance() && get_script_instance()->has_method("get_name")) { - return get_script_instance()->call("get_name"); - } - - ERR_FAIL_V(""); -} - -String EditorImportPlugin::get_visible_name() const { - - if (get_script_instance() && get_script_instance()->has_method("get_visible_name")) { - return get_script_instance()->call("get_visible_name"); - } - - ERR_FAIL_V(""); -} - - -void EditorImportPlugin::import_dialog(const String& p_from) { - - if (get_script_instance() && get_script_instance()->has_method("import_dialog")) { - get_script_instance()->call("import_dialog",p_from); - return; - } - - ERR_FAIL(); - -} - -Error EditorImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from) { - - if (get_script_instance() && get_script_instance()->has_method("import")) { - return Error(get_script_instance()->call("import",p_path,p_from).operator int()); - } - - ERR_FAIL_V(ERR_UNAVAILABLE); -} - -Vector<uint8_t> EditorImportPlugin::custom_export(const String& p_path, const Ref<EditorExportPlatform> &p_platform) { - - if (get_script_instance() && get_script_instance()->has_method("custom_export")) { - get_script_instance()->call("custom_export",p_path,p_platform); - } - - return Vector<uint8_t>(); -} - -bool EditorImportPlugin::can_reimport_multiple_files() const { - - if (get_script_instance() && get_script_instance()->has_method("can_reimport_multiple_files")) { - return get_script_instance()->call("can_reimport_multiple_files"); - } - - return false; -} -void EditorImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { - - if (get_script_instance() && get_script_instance()->has_method("reimport_multiple_files")) { - get_script_instance()->call("reimport_multiple_files",p_list); - } - -} - -void EditorImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { - - if (get_script_instance() && get_script_instance()->has_method("import_from_drop")) { - get_script_instance()->call("import_from_drop",p_drop,p_dest_path); - } - -} - -EditorImportPlugin::EditorImportPlugin() { - - -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// - - -void EditorExportPlugin::_bind_methods() { - - MethodInfo mi = MethodInfo("custom_export:Variant",PropertyInfo(Variant::STRING,"name"),PropertyInfo(Variant::OBJECT,"platform",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatform")); - mi.return_val.type=Variant::POOL_BYTE_ARRAY; - - BIND_VMETHOD( mi ); -} - - -Vector<uint8_t> EditorExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) { - - if (get_script_instance()) { - - Variant d = get_script_instance()->call("custom_export",p_path,p_platform); - if (d.get_type()==Variant::NIL) - return Vector<uint8_t>(); - if (d.get_type()==Variant::POOL_BYTE_ARRAY) - return d; - - ERR_FAIL_COND_V(d.get_type()!=Variant::DICTIONARY,Vector<uint8_t>()); - Dictionary dict=d; - ERR_FAIL_COND_V(!dict.has("name"),Vector<uint8_t>()); - ERR_FAIL_COND_V(!dict.has("data"),Vector<uint8_t>()); - p_path=dict["name"]; - return dict["data"]; - } - - return Vector<uint8_t>(); - -} - - -EditorExportPlugin::EditorExportPlugin() { - - -} - -///////////////////////////////////////////////////////////////////////////////////////////////////// - - - -static void _add_to_list(EditorFileSystemDirectory *p_efsd,Set<StringName>& r_list) { - - for(int i=0;i<p_efsd->get_subdir_count();i++) { - - _add_to_list(p_efsd->get_subdir(i),r_list); - } - - for(int i=0;i<p_efsd->get_file_count();i++) { - r_list.insert(p_efsd->get_file_path(i)); - } -} - - -struct __EESortDepCmp { - - _FORCE_INLINE_ bool operator()(const StringName& p_l,const StringName& p_r) const { - return p_l.operator String() < p_r.operator String(); - } -}; - - - - -static void _edit_files_with_filter(DirAccess *da,const List<String>& p_filters,Set<StringName>& r_list,bool exclude) { - - - List<String> files; - List<String> dirs; - - da->list_dir_begin(); - - String f = da->get_next(); - while(f!="") { - - print_line("HOHO: "+f); - if (da->current_is_dir()) - dirs.push_back(f); - else - files.push_back(f); - - f=da->get_next(); - } - - String r = da->get_current_dir().replace("\\","/"); - if (!r.ends_with("/")) - r+="/"; - - print_line("AT: "+r); - - for(List<String>::Element *E=files.front();E;E=E->next()) { - String fullpath=r+E->get(); - for(const List<String>::Element *F=p_filters.front();F;F=F->next()) { - - if (fullpath.matchn(F->get())) { - String act = TTR("Added:")+" "; - - if (!exclude) { - r_list.insert(fullpath); - } else { - act = TTR("Removed:")+" "; - r_list.erase(fullpath); - } - - - print_line(act+fullpath); - } - } - } - - da->list_dir_end(); - - for(List<String>::Element *E=dirs.front();E;E=E->next()) { - if (E->get().begins_with(".")) - continue; - da->change_dir(E->get()); - _edit_files_with_filter(da,p_filters,r_list,exclude); - da->change_dir(".."); - } - -} - -static void _edit_filter_list(Set<StringName>& r_list,const String& p_filter,bool exclude) { - - if (p_filter=="") - return; - Vector<String> split = p_filter.split(","); - List<String> filters; - for(int i=0;i<split.size();i++) { - String f = split[i].strip_edges(); - if (f.empty()) - continue; - filters.push_back(f); - } - - DirAccess *da = DirAccess::open("res://"); - ERR_FAIL_NULL(da); - _edit_files_with_filter(da,filters,r_list,exclude); - memdelete(da); -} - -static void _add_filter_to_list(Set<StringName>& r_list,const String& p_filter) { - _edit_filter_list(r_list,p_filter,false); -} - -static void _remove_filter_from_list(Set<StringName>& r_list,const String& p_filter) { - _edit_filter_list(r_list,p_filter,true); -} - -bool EditorExportPlatform::_set(const StringName& p_name, const Variant& p_value) { - - String n = p_name; - - if (n=="debug/debugging_enabled") { - set_debugging_enabled(p_value); - } else { - return false; - } - - return true; - -} - -bool EditorExportPlatform::_get(const StringName& p_name,Variant &r_ret) const { - - String n = p_name; - - if (n=="debug/debugging_enabled") { - r_ret=is_debugging_enabled(); - } else { - return false; - } - - return true; - -} - -void EditorExportPlatform::_get_property_list( List<PropertyInfo> *p_list) const { - - p_list->push_front( PropertyInfo( Variant::BOOL, "debug/debugging_enabled")); -} - -Vector<uint8_t> EditorExportPlatform::get_exported_file_default(String& p_fname) const { - - FileAccess *f = FileAccess::open(p_fname,FileAccess::READ); - ERR_FAIL_COND_V(!f,Vector<uint8_t>()); - Vector<uint8_t> ret; - ret.resize(f->get_len()); - int rbs = f->get_buffer(ret.ptr(),ret.size()); - memdelete(f); - return ret; -} - -Vector<uint8_t> EditorExportPlatform::get_exported_file(String& p_fname) const { - - Ref<EditorExportPlatform> ep=EditorImportExport::get_singleton()->get_export_platform(get_name()); - - for(int i=0;i<EditorImportExport::get_singleton()->get_export_plugin_count();i++) { - - Vector<uint8_t> data = EditorImportExport::get_singleton()->get_export_plugin(i)->custom_export(p_fname,ep); - if (data.size()) - return data; - - } - - - return get_exported_file_default(p_fname); - - -} - -Vector<StringName> EditorExportPlatform::get_dependencies(bool p_bundles) const { - - - Set<StringName> exported; - - if (FileAccess::exists("res://godot.cfg")) - exported.insert("res://godot.cfg"); - - if (EditorImportExport::get_singleton()->get_export_filter()!=EditorImportExport::EXPORT_SELECTED) { - - String filter; - if (EditorImportExport::get_singleton()->get_export_filter()==EditorImportExport::EXPORT_ALL) { - _add_filter_to_list(exported,"*"); - } else { - _add_to_list(EditorFileSystem::get_singleton()->get_filesystem(),exported); - String cf = EditorImportExport::get_singleton()->get_export_custom_filter(); - if (cf!="") - cf+=","; - cf+="*.flags"; - _add_filter_to_list(exported,cf); - - cf = EditorImportExport::get_singleton()->get_export_custom_filter_exclude(); - _remove_filter_from_list(exported,cf); - } - - - } else { - - - Map<String,Map<String,String> > remapped_paths; - - Set<String> scene_extensions; - Set<String> resource_extensions; - - { - - List<String> l; - /* - SceneLoader::get_recognized_extensions(&l); - for(List<String>::Element *E=l.front();E;E=E->next()) { - scene_extensions.insert(E->get()); - } - */ - ResourceLoader::get_recognized_extensions_for_type("",&l); - for(List<String>::Element *E=l.front();E;E=E->next()) { - - resource_extensions.insert(E->get()); - } - } - - - List<StringName> toexport; - - EditorImportExport::get_singleton()->get_export_file_list(&toexport); - - print_line("TO EXPORT: "+itos(toexport.size())); - - - for (List<StringName>::Element *E=toexport.front();E;E=E->next()) { - - print_line("DEP: "+String(E->get())); - exported.insert(E->get()); - if (p_bundles && EditorImportExport::get_singleton()->get_export_file_action(E->get())==EditorImportExport::ACTION_BUNDLE) { - print_line("NO BECAUSE OF BUNDLE!"); - continue; //no dependencies needed to be copied - } - - List<String> testsubs; - testsubs.push_back(E->get()); - - while(testsubs.size()) { - //recursive subdep search! - List<String> deplist; - ResourceLoader::get_dependencies(testsubs.front()->get(),&deplist); - testsubs.pop_front(); - - List<String> subdeps; - - for (List<String>::Element *F=deplist.front();F;F=F->next()) { - - StringName dep = F->get(); - - if (exported.has(dep) || EditorImportExport::get_singleton()->get_export_file_action(dep)!=EditorImportExport::ACTION_NONE) - continue; //dependency added or to be added - print_line(" SUBDEP: "+String(dep)); - - exported.insert(dep); - testsubs.push_back(dep); - } - } - } - String cf = EditorImportExport::get_singleton()->get_export_custom_filter(); - if (cf!="") - cf+=","; - cf+="*.flags"; - _add_filter_to_list(exported,cf); - - cf = EditorImportExport::get_singleton()->get_export_custom_filter_exclude(); - _remove_filter_from_list(exported,cf); - - - } - - Vector<StringName> ret; - ret.resize(exported.size()); - - - int idx=0; - for(Set<StringName>::Element *E=exported.front();E;E=E->next()) { - - ret[idx++]=E->get(); - - } - - SortArray<StringName,__EESortDepCmp> sort; //some platforms work better if this is sorted - sort.sort(ret.ptr(),ret.size()); - - return ret; - -} - -String EditorExportPlatform::find_export_template(String template_file_name, String *err) const { - String user_file = EditorSettings::get_singleton()->get_settings_path() - +"/templates/"+template_file_name; - String system_file=OS::get_singleton()->get_installed_templates_path(); - bool has_system_path=(system_file!=""); - system_file+=template_file_name; - - // Prefer user file - if (FileAccess::exists(user_file)) { - return user_file; - } - - // Now check system file - if (has_system_path) { - if (FileAccess::exists(system_file)) { - return system_file; - } - } - - // Not found - if (err) { - *err+="No export template found at \""+user_file+"\""; - if (has_system_path) - *err+="\n or \""+system_file+"\"."; - else - *err+="."; - } - return ""; -} - -bool EditorExportPlatform::exists_export_template(String template_file_name, String *err) const { - return find_export_template(template_file_name,err)!=""; -} - -/////////////////////////////////////// - - - -bool EditorExportPlatform::is_debugging_enabled() const { - - return debugging_enabled; -} - -void EditorExportPlatform::set_debugging_enabled(bool p_enabled) { - - debugging_enabled = p_enabled; -} - -bool EditorExportPlatformPC::_set(const StringName& p_name, const Variant& p_value) { - - String n = p_name; - - if (n=="custom_binary/release") { - - custom_release_binary=p_value; - } else if (n=="custom_binary/debug") { - - custom_debug_binary=p_value; - } else if (n=="resources/pack_mode") { - - export_mode=ExportMode(int(p_value)); - } else if (n=="resources/bundle_dependencies_(for_optical_disc)") { - - bundle=p_value; - } else if (n=="binary/64_bits") { - - use64=p_value; - } else - return false; - - return true; - -} - -bool EditorExportPlatformPC::_get(const StringName& p_name,Variant &r_ret) const { - - String n = p_name; - - if (n=="custom_binary/release") { - - r_ret=custom_release_binary; - } else if (n=="custom_binary/debug") { - - r_ret=custom_debug_binary; - } else if (n=="resources/pack_mode") { - - r_ret=export_mode; - } else if (n=="resources/bundle_dependencies_(for_optical_disc)") { - - r_ret=bundle; - } else if (n=="binary/64_bits") { - - r_ret=use64; - } else - return false; - - return true; - -} - -void EditorExportPlatformPC::_get_property_list( List<PropertyInfo> *p_list) const { - - p_list->push_back( PropertyInfo( Variant::STRING, "custom_binary/debug", PROPERTY_HINT_GLOBAL_FILE,binary_extension)); - p_list->push_back( PropertyInfo( Variant::STRING, "custom_binary/release", PROPERTY_HINT_GLOBAL_FILE,binary_extension)); - p_list->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Pack into executable,Pack into binary file (.pck),Pack into archive file (.zip)")); - p_list->push_back( PropertyInfo( Variant::BOOL, "resources/bundle_dependencies_(for_optical_disc)")); - p_list->push_back( PropertyInfo( Variant::BOOL, "binary/64_bits")); -} - - - -static void _exp_add_dep(Map<StringName,List<StringName> > &deps,const StringName& p_path) { - - - if (deps.has(p_path)) - return; //already done - - deps.insert(p_path,List<StringName>()); - - List<StringName> &deplist=deps[p_path]; - Set<StringName> depset; - - List<String> dl; - ResourceLoader::get_dependencies(p_path,&dl); - - //added in order so child dependencies are always added bfore parent dependencies - for (List<String>::Element *E=dl.front();E;E=E->next()) { - - - if (!deps.has(E->get())) - _exp_add_dep(deps,E->get()); - - for(List<StringName>::Element *F=deps[E->get()].front();F;F=F->next()) { - - - if (!depset.has(F->get())) { - depset.insert(F->get()); - deplist.push_back(F->get()); - } - } - - if (!depset.has(E->get())) { - depset.insert(E->get()); - deplist.push_back(E->get()); - } - - } -} - - - -Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func, void* p_udata,bool p_make_bundles) { - -/* ALL FILES AND DEPENDENCIES */ - - Vector<StringName> files=get_dependencies(p_make_bundles); - - Map<StringName,List<StringName> > deps; - - if (false) { - for(int i=0;i<files.size();i++) { - - _exp_add_dep(deps,files[i]); - - } - } - - - -/* GROUP ATLAS */ - - - List<StringName> groups; - - EditorImportExport::get_singleton()->image_export_get_groups(&groups); - - Map<StringName,StringName> remap_files; - Set<StringName> saved; - - int counter=0; - - for(List<StringName>::Element *E=groups.front();E;E=E->next()) { - - if (!EditorImportExport::get_singleton()->image_export_group_get_make_atlas(E->get())) - continue; //uninterested, only process for atlas! - - List<StringName> atlas_images; - EditorImportExport::get_singleton()->image_export_get_images_in_group(E->get(),&atlas_images); - atlas_images.sort_custom<StringName::AlphCompare>(); - - for (List<StringName>::Element *F=atlas_images.front();F;) { - - List<StringName>::Element *N=F->next(); - - if (!FileAccess::exists(F->get())) { - atlas_images.erase(F); - } - - F=N; - - } - - if (atlas_images.size()<=1) - continue; - - int group_format=0; - float group_lossy_quality=EditorImportExport::get_singleton()->image_export_group_get_lossy_quality(E->get()); - int group_shrink=EditorImportExport::get_singleton()->image_export_group_get_shrink(E->get()); - group_shrink*=EditorImportExport::get_singleton()->get_export_image_shrink(); - - switch(EditorImportExport::get_singleton()->image_export_group_get_image_action(E->get())) { - case EditorImportExport::IMAGE_ACTION_KEEP: - case EditorImportExport::IMAGE_ACTION_NONE: { - - switch(EditorImportExport::get_singleton()->get_export_image_action()) { - case EditorImportExport::IMAGE_ACTION_NONE: { - - group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS; //? - - } break; //use default - case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: { - group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY; - } break; //use default - case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: { - group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM; - } break; //use default - } - - group_lossy_quality=EditorImportExport::get_singleton()->get_export_image_quality(); - - } break; //use default - case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: { - group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY; - } break; //use default - case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: { - group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM; - } break; //use default - } - - String image_listD_METHOD5; - - { - MD5_CTX ctx; - MD5Init(&ctx); - for (List<StringName>::Element *F=atlas_images.front();F;F=F->next()) { - - String p = F->get(); - MD5Update(&ctx,(unsigned char*)p.utf8().get_data(),p.utf8().length()); - - } - - MD5Final(&ctx); - image_listD_METHOD5=String::md5(ctx.digest); - } - //ok see if cached - String md5; - bool atlas_valid=true; - String atlas_name; - - { - MD5_CTX ctx; - MD5Init(&ctx); - String path = GlobalConfig::get_singleton()->get_resource_path()+"::"+String(E->get())+"::"+get_name(); - MD5Update(&ctx,(unsigned char*)path.utf8().get_data(),path.utf8().length()); - MD5Final(&ctx); - md5 = String::md5(ctx.digest); - } - - FileAccess *f=NULL; - - if (!FileAccess::exists(EditorSettings::get_singleton()->get_settings_path()+"/tmp/atlas-"+md5)) { - print_line("NO MD5 INVALID"); - atlas_valid=false; - } - - if (atlas_valid) - f=FileAccess::open(EditorSettings::get_singleton()->get_settings_path()+"/tmp/atlas-"+md5,FileAccess::READ); - - if (atlas_valid) { - //compare options - /*Dictionary options; - options.parse_json(f->get_line()); - if (!options.has("lossy_quality") || float(options["lossy_quality"])!=group_lossy_quality) - atlas_valid=false; - else if (!options.has("shrink") || int(options["shrink"])!=group_shrink) - atlas_valid=false; - else if (!options.has("image_format") || int(options["image_format"])!=group_format) - atlas_valid=false; - - if (!atlas_valid) - print_line("JSON INVALID"); -*/ - } - - - if (atlas_valid) { - //check md5 of list of image /names/ - if (f->get_line().strip_edges()!=image_listD_METHOD5) { - atlas_valid=false; - print_line("IMAGE MD5 INVALID!"); - } - - } - - Vector<Rect2> rects; - bool resave_deps=false; - - if (atlas_valid) { - - //check if images were not modified - for (List<StringName>::Element *F=atlas_images.front();F;F=F->next()) { - - Vector<String> slices = f->get_line().strip_edges().split("::"); - - if (slices.size()!=10) { - atlas_valid=false; - print_line("CANT SLICE IN 10"); - break; - } - uint64_t mod_time = slices[0].to_int64(); - uint64_t file_mod_time = FileAccess::get_modified_time(F->get()); - if (mod_time!=file_mod_time) { - - String imageD_METHOD5 = slices[1]; - String fileD_METHOD5 = FileAccess::getD_METHOD5(F->get()); - - if (imageD_METHOD5!=fileD_METHOD5) { - atlas_valid=false; - print_line("IMAGE INVALID "+slices[0]); - break; - } else { - resave_deps=true; - } - } - - if (atlas_valid) { - //push back region and margin - rects.push_back(Rect2(slices[2].to_float(),slices[3].to_float(),slices[4].to_float(),slices[5].to_float())); - rects.push_back(Rect2(slices[6].to_float(),slices[7].to_float(),slices[8].to_float(),slices[9].to_float())); - } - } - - } - - if (f) { - memdelete(f); - f=NULL; - } - - print_line("ATLAS VALID? "+itos(atlas_valid)+" RESAVE DEPS? "+itos(resave_deps)); - if (!atlas_valid) { - rects.clear(); - //oh well, atlas is not valid. need to make new one.... - - String dst_file = EditorSettings::get_singleton()->get_settings_path()+"/tmp/atlas-"+md5+".tex"; - Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); - //imd->set_editor(); - - - for (List<StringName>::Element *F=atlas_images.front();F;F=F->next()) { - - imd->add_source(EditorImportPlugin::validate_source_path(F->get()),FileAccess::getD_METHOD5(F->get())); - - } - - - imd->set_option("format",group_format); - - - int flags=0; - - if (GlobalConfig::get_singleton()->get("image_loader/filter")) - flags|=EditorTextureImportPlugin::IMAGE_FLAG_FILTER; - if (!GlobalConfig::get_singleton()->get("image_loader/gen_mipmaps")) - flags|=EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS; - if (!GlobalConfig::get_singleton()->get("image_loader/repeat")) - flags|=EditorTextureImportPlugin::IMAGE_FLAG_REPEAT; - - flags|=EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA; - - imd->set_option("flags",flags); - imd->set_option("quality",group_lossy_quality); - imd->set_option("atlas",true); - imd->set_option("crop",true); - imd->set_option("shrink",group_shrink); - - - - Ref<EditorTextureImportPlugin> plugin = EditorImportExport::get_singleton()->get_import_plugin_by_name("texture"); - Error err = plugin->import2(dst_file,imd,get_image_compression(),true); - if (err) { - - EditorNode::add_io_error(TTR("Error saving atlas:")+" "+dst_file.get_file()); - return ERR_CANT_CREATE; - } - - ERR_FAIL_COND_V(imd->get_option("rects")==Variant(),ERR_BUG); - - Array r_rects=imd->get_option("rects"); - rects.resize(r_rects.size()); - for(int i=0;i<r_rects.size();i++) { - //get back region and margins - rects[i]=r_rects[i]; - } - - - resave_deps=true; - } - - - //atlas is valid (or it was just saved i guess), create the atex files and save them - - if (resave_deps) { - f=FileAccess::open(EditorSettings::get_singleton()->get_settings_path()+"/tmp/atlas-"+md5,FileAccess::WRITE); - Dictionary options; - options["lossy_quality"]=group_lossy_quality; - options["shrink"]=EditorImportExport::get_singleton()->image_export_group_get_shrink(E->get()); - options["image_format"]=group_format; - //f->store_line(options.to_json()); - f->store_line(image_listD_METHOD5); - } - - //go through all ATEX files - - { - Ref<ImageTexture> atlas = memnew( ImageTexture ); //fake atlas! - String atlas_path="res://atlas-"+md5+".tex"; - atlas->set_path(atlas_path); - int idx=0; - for (List<StringName>::Element *F=atlas_images.front();F;F=F->next()) { - - String p = F->get(); - Ref<AtlasTexture> atex = memnew(AtlasTexture); - atex->set_atlas(atlas); - Rect2 region=rects[idx++]; - Rect2 margin=rects[idx++]; - atex->set_region(region); - atex->set_margin(margin); - - String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmpatlas.atex"; - Error err = ResourceSaver::save(path,atex); - if (err!=OK) { - EditorNode::add_io_error(TTR("Could not save atlas subtexture:")+" "+path); - return ERR_CANT_CREATE; - } - Vector<uint8_t> data = FileAccess::get_file_as_array(path); - String dst_path = F->get().operator String().get_basename()+".atex"; - err = p_func(p_udata,dst_path,data,counter++,files.size()); - saved.insert(dst_path); - if (err) - return err; - - if (f) { - //recreating deps.. - String depline; - //depline=String(F->get())+"::"+itos(FileAccess::get_modified_time(F->get()))+"::"+FileAccess::getD_METHOD5(F->get()); name unneccesary by top md5 - depline=itos(FileAccess::get_modified_time(F->get()))+"::"+FileAccess::getD_METHOD5(F->get()); - depline+="::"+itos(region.pos.x)+"::"+itos(region.pos.y)+"::"+itos(region.size.x)+"::"+itos(region.size.y); - depline+="::"+itos(margin.pos.x)+"::"+itos(margin.pos.y)+"::"+itos(margin.size.x)+"::"+itos(margin.size.y); - f->store_line(depline); - } - - remap_files[F->get()]=dst_path; - } - - Vector<uint8_t> atlas_data = FileAccess::get_file_as_array(EditorSettings::get_singleton()->get_settings_path()+"/tmp/atlas-"+md5+".tex"); - Error err = p_func(p_udata,atlas_path,atlas_data,counter,files.size()); - saved.insert(atlas_path); - if (err) - return err; - - } - - - if (f) { - memdelete(f); - } - - } - - - StringName engine_cfg="res://godot.cfg"; - StringName boot_splash; - { - String splash=GlobalConfig::get_singleton()->get("application/boot_splash"); //avoid splash from being converted - splash=splash.strip_edges(); - if (splash!=String()) { - if (!splash.begins_with("res://")) - splash="res://"+splash; - splash=splash.simplify_path(); - boot_splash=splash; - } - } - StringName custom_cursor; - { - String splash=GlobalConfig::get_singleton()->get("display/custom_mouse_cursor"); //avoid splash from being converted - splash=splash.strip_edges(); - if (splash!=String()) { - if (!splash.begins_with("res://")) - splash="res://"+splash; - splash=splash.simplify_path(); - custom_cursor=splash; - } - } - - - - - for(int i=0;i<files.size();i++) { - - if (remap_files.has(files[i]) || files[i]==engine_cfg) //gonna be remapped (happened before!) - continue; //from atlas? - String src=files[i]; - Vector<uint8_t> buf; - - if (src==boot_splash || src==custom_cursor) - buf = get_exported_file_default(src); //bootsplash must be kept if used - else - buf = get_exported_file(src); - - ERR_CONTINUE( saved.has(src) ); - - Error err = p_func(p_udata,src,buf,counter++,files.size()); - if (err) - return err; - - saved.insert(src); - if (src!=String(files[i])) - remap_files[files[i]]=src; - - } - - - { - - //make binary godot.cfg config - Map<String,Variant> custom; - - - if (remap_files.size()) { - Vector<String> remapsprop; - for(Map<StringName,StringName>::Element *E=remap_files.front();E;E=E->next()) { - print_line("REMAP: "+String(E->key())+" -> "+E->get()); - remapsprop.push_back(E->key()); - remapsprop.push_back(E->get()); - } - - custom["remap/all"]=remapsprop; - } - - //add presaved dependencies - for(Map<StringName,List<StringName> >::Element *E=deps.front();E;E=E->next()) { - - if (E->get().size()==0) - continue; //no deps - String key; - Vector<StringName> deps; - //if bundle continue (when bundles supported obviously) - - if (remap_files.has(E->key())) { - key=remap_files[E->key()]; - } else { - key=E->key(); - } - - deps.resize(E->get().size()); - int i=0; - - for(List<StringName>::Element *F=E->get().front();F;F=F->next()) { - deps[i++]=F->get(); - print_line(" -"+String(F->get())); - } - - NodePath prop(deps,true,String()); //seems best to use this for performance - - custom["deps/"+key.md5_text()]=prop; - - } - - String remap_file="godot.cfb"; - String engine_cfb =EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmp"+remap_file; - GlobalConfig::get_singleton()->save_custom(engine_cfb,custom); - Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb); - - Error err = p_func(p_udata,"res://"+remap_file,data,counter,files.size()); - if (err) - return err; - - } - - return OK; -} - -static int _get_pad(int p_alignment, int p_n) { - - int rest = p_n % p_alignment; - int pad = 0; - if (rest > 0) { - pad = p_alignment - rest; - }; - - return pad; -}; - -void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags) { - - String host = EditorSettings::get_singleton()->get("network/debug_host"); - - if (p_flags&EXPORT_REMOTE_DEBUG_LOCALHOST) - host="localhost"; - - if (p_flags&EXPORT_DUMB_CLIENT) { - int port = EditorSettings::get_singleton()->get("filesystem/file_server/port"); - String passwd = EditorSettings::get_singleton()->get("filesystem/file_server/password"); - r_flags.push_back("-rfs"); - r_flags.push_back(host+":"+itos(port)); - if (passwd!="") { - r_flags.push_back("-rfs_pass"); - r_flags.push_back(passwd); - } - } - - if (p_flags&EXPORT_REMOTE_DEBUG) { - - r_flags.push_back("-rdebug"); - - r_flags.push_back(host+":"+String::num(GLOBAL_DEF("network/debug/remote_port", 6007))); - - List<String> breakpoints; - ScriptEditor::get_singleton()->get_breakpoints(&breakpoints); - - - if (breakpoints.size()) { - - r_flags.push_back("-bp"); - String bpoints; - for(const List<String>::Element *E=breakpoints.front();E;E=E->next()) { - - bpoints+=E->get().replace(" ","%20"); - if (E->next()) - bpoints+=","; - } - - r_flags.push_back(bpoints); - } - - } - - if (p_flags&EXPORT_VIEW_COLLISONS) { - - r_flags.push_back("-debugcol"); - } - - if (p_flags&EXPORT_VIEW_NAVIGATION) { - - r_flags.push_back("-debugnav"); - } - - -} - -Error EditorExportPlatform::save_pack_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total) { - - - PackData *pd = (PackData*)p_userdata; - - CharString cs=p_path.utf8(); - pd->f->store_32(cs.length()); - pd->f->store_buffer((uint8_t*)cs.get_data(),cs.length()); - TempData td; - td.pos=pd->f->get_pos(); - td.ofs=pd->ftmp->get_pos(); - td.size=p_data.size(); - pd->file_ofs.push_back(td); - pd->f->store_64(0); //ofs - pd->f->store_64(0); //size - { - MD5_CTX ctx; - MD5Init(&ctx); - MD5Update(&ctx,(unsigned char*)p_data.ptr(),p_data.size()); - MD5Final(&ctx); - pd->f->store_buffer(ctx.digest,16); - } - pd->ep->step(TTR("Storing File:")+" "+p_path,2+p_file*100/p_total,false); - pd->count++; - pd->ftmp->store_buffer(p_data.ptr(),p_data.size()); - if (pd->alignment > 1) { - - int pad = _get_pad(pd->alignment, pd->ftmp->get_pos()); - for (int i=0; i<pad; i++) { - - pd->ftmp->store_8(0); - }; - }; - return OK; - -} - -Error EditorExportPlatform::save_zip_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total) { - - - String path=p_path.replace_first("res://",""); - - ZipData *zd = (ZipData*)p_userdata; - - zipFile zip=(zipFile)zd->zip; - - zipOpenNewFileInZip(zip, - path.utf8().get_data(), - NULL, - NULL, - 0, - NULL, - 0, - NULL, - Z_DEFLATED, - Z_DEFAULT_COMPRESSION); - - zipWriteInFileInZip(zip,p_data.ptr(),p_data.size()); - zipCloseFileInZip(zip); - - zd->ep->step(TTR("Storing File:")+" "+p_path,2+p_file*100/p_total,false); - zd->count++; - return OK; - -} - -Error EditorExportPlatform::save_zip(const String& p_path, bool p_make_bundles) { - - EditorProgress ep("savezip",TTR("Packing"),102); - - //FileAccess *tmp = FileAccess::open(tmppath,FileAccess::WRITE); - - FileAccess *src_f; - zlib_filefunc_def io = zipio_create_io_from_file(&src_f); - zipFile zip=zipOpen2(p_path.utf8().get_data(),APPEND_STATUS_CREATE,NULL,&io); - - ZipData zd; - zd.count=0; - zd.ep=&ep; - zd.zip=zip; - - - Error err = export_project_files(save_zip_file,&zd,p_make_bundles); - - zipClose(zip,NULL); - - return err; -} - -Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles, int p_alignment) { - - EditorProgress ep("savepack",TTR("Packing"),102); - - String tmppath = EditorSettings::get_singleton()->get_settings_path()+"/tmp/packtmp"; - FileAccess *tmp = FileAccess::open(tmppath,FileAccess::WRITE); - uint64_t ofs_begin = dst->get_pos(); - - dst->store_32(0x43504447); //GDPK - dst->store_32(0); //pack version - dst->store_32(VERSION_MAJOR); - dst->store_32(VERSION_MINOR); - dst->store_32(0); //hmph - for(int i=0;i<16;i++) { - //reserved - dst->store_32(0); - } - - size_t fcountpos = dst->get_pos(); - dst->store_32(0); - - PackData pd; - pd.ep=&ep; - pd.f=dst; - pd.ftmp=tmp; - pd.count=0; - pd.alignment = p_alignment; - Error err = export_project_files(save_pack_file,&pd,p_make_bundles); - memdelete(tmp); - if (err) - return err; - - if (p_alignment > 1) { - int pad = _get_pad(p_alignment, dst->get_pos()); - for (int i=0; i<pad; i++) { - - dst->store_8(0); - }; - }; - - size_t ofsplus = dst->get_pos(); - //append file - - tmp = FileAccess::open(tmppath,FileAccess::READ); - - ERR_FAIL_COND_V(!tmp,ERR_CANT_OPEN;) - const int bufsize=16384; - uint8_t buf[bufsize]; - - while(true) { - - int got = tmp->get_buffer(buf,bufsize); - if (got<=0) - break; - dst->store_buffer(buf,got); - } - - memdelete(tmp); - - dst->store_64(dst->get_pos()-ofs_begin); - dst->store_32(0x43504447); //GDPK - - //fix offsets - - dst->seek(fcountpos); - dst->store_32(pd.count); - for(int i=0;i<pd.file_ofs.size();i++) { - - dst->seek(pd.file_ofs[i].pos); - dst->store_64(pd.file_ofs[i].ofs+ofsplus); - dst->store_64(pd.file_ofs[i].size); - } - - return OK; -} - -EditorExportPlatform::EditorExportPlatform() { - - debugging_enabled = true; -} - -Error EditorExportPlatformPC::export_project(const String& p_path, bool p_debug, int p_flags) { - - - - EditorProgress ep("export",vformat(TTR("Exporting for %s"),get_name()),102); - - const int BUFSIZE = 32768; - - - - ep.step(TTR("Setting Up.."),0); - - String exe_path=""; - - if (p_debug) - exe_path=custom_debug_binary; - else - exe_path=custom_release_binary; - - if (exe_path=="") { - String fname; - if (use64) { - if (p_debug) - fname=debug_binary64; - else - fname=release_binary64; - } else { - if (p_debug) - fname=debug_binary32; - else - fname=release_binary32; - } - String err=""; - exe_path=find_export_template(fname,&err); - if (exe_path=="") { - EditorNode::add_io_error(err); - return ERR_FILE_CANT_READ; - } - } - - FileAccess *src_exe=FileAccess::open(exe_path,FileAccess::READ); - if (!src_exe) { - - EditorNode::add_io_error("Couldn't read source executable at:\n "+exe_path); - return ERR_FILE_CANT_READ; - } - - FileAccess *dst=FileAccess::open(p_path,FileAccess::WRITE); - if (!dst) { - - EditorNode::add_io_error("Can't copy executable file to:\n "+p_path); - return ERR_FILE_CANT_WRITE; - } - - uint8_t buff[32768]; - - while(true) { - - int c = src_exe->get_buffer(buff,BUFSIZE); - if (c>0) { - - dst->store_buffer(buff,c); - } else { - break; - } - } - - String dstfile = p_path.replace_first("res://","").replace("\\","/"); - if (export_mode!=EXPORT_EXE) { - - String dstfile_extension=export_mode==EXPORT_ZIP?".zip":".pck"; - if (dstfile.find("/")!=-1) - dstfile=dstfile.get_base_dir()+"/data"+dstfile_extension; - else - dstfile="data"+dstfile_extension; - if (export_mode==EXPORT_PACK) { - - memdelete(dst); - - dst=FileAccess::open(dstfile,FileAccess::WRITE); - if (!dst) { - - EditorNode::add_io_error("Can't write data pack to:\n "+p_path); - return ERR_FILE_CANT_WRITE; - } - } - } - - - - memdelete(src_exe); - - Error err = export_mode==EXPORT_ZIP?save_zip(dstfile,bundle):save_pack(dst,bundle); - memdelete(dst); - return err; -} - -void EditorExportPlatformPC::set_binary_extension(const String& p_extension) { - - binary_extension=p_extension; -} - -bool EditorExportPlatformPC::can_export(String *r_error) const { - - String err; - bool valid=true; - - if (use64 && (!exists_export_template(debug_binary64) || !exists_export_template(release_binary64))) { - valid=false; - err="No 64 bits export templates found.\nDownload and install export templates.\n"; - } - - if (!use64 && (!exists_export_template(debug_binary32) || !exists_export_template(release_binary32))) { - valid=false; - err="No 32 bits export templates found.\nDownload and install export templates.\n"; - } - - if(custom_debug_binary=="" && custom_release_binary=="") { - if (r_error) *r_error=err; - return valid; - } - - bool dvalid = true; - bool rvalid = true; - - if(!FileAccess::exists(custom_debug_binary)) { - dvalid = false; - err = "Custom debug binary not found.\n"; - } - - if(!FileAccess::exists(custom_release_binary)) { - rvalid = false; - err = "Custom release binary not found.\n"; - } - - if (dvalid || rvalid) - valid = true; - else - valid = false; - - if (r_error) - *r_error=err; - return valid; -} - - -EditorExportPlatformPC::EditorExportPlatformPC() { - - export_mode=EXPORT_PACK; - use64=true; -} - - - - - - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////// - - -EditorImportExport* EditorImportExport::singleton=NULL; - -void EditorImportExport::add_import_plugin(const Ref<EditorImportPlugin>& p_plugin) { - - // Need to make sure the name is unique if we are going to lookup by it - ERR_FAIL_COND(by_idx.has(p_plugin->get_name())); - - by_idx[ p_plugin->get_name() ]=plugins.size(); - plugins.push_back(p_plugin); -} - -void EditorImportExport::remove_import_plugin(const Ref<EditorImportPlugin>& p_plugin) { - - String plugin_name = p_plugin->get_name(); - - // Keep the indices the same - // Find the index of the target plugin - ERR_FAIL_COND(!by_idx.has(plugin_name)); - int idx = by_idx[plugin_name]; - int last_idx = plugins.size() - 1; - - // Swap the last plugin and the target one - SWAP(plugins[idx], plugins[last_idx]); - - // Update the index of the old last one - by_idx[plugins[idx]->get_name()] = idx; - - // Remove the target plugin's by_idx entry - by_idx.erase(plugin_name); - - // Erase the plugin - plugins.remove(last_idx); -} - -int EditorImportExport::get_import_plugin_count() const{ - - return plugins.size(); -} -Ref<EditorImportPlugin> EditorImportExport::get_import_plugin(int p_idx) const{ - - ERR_FAIL_INDEX_V(p_idx,plugins.size(),Ref<EditorImportPlugin>()); - return plugins[p_idx]; - -} - - - -Ref<EditorImportPlugin> EditorImportExport::get_import_plugin_by_name(const String& p_string) const{ - - ERR_FAIL_COND_V( !by_idx.has(p_string), Ref<EditorImportPlugin>()); - return plugins[ by_idx[p_string] ]; -} - -void EditorImportExport::add_export_plugin(const Ref<EditorExportPlugin>& p_plugin) { - - ERR_FAIL_COND( p_plugin.is_null() ); - - export_plugins.push_back(p_plugin); -} - -void EditorImportExport::remove_export_plugin(const Ref<EditorExportPlugin>& p_plugin) { - - ERR_FAIL_COND( p_plugin.is_null() ); - export_plugins.erase(p_plugin); -} - -int EditorImportExport::get_export_plugin_count() const{ - - return export_plugins.size(); -} -Ref<EditorExportPlugin> EditorImportExport::get_export_plugin(int p_idx) const{ - - ERR_FAIL_INDEX_V(p_idx,export_plugins.size(),Ref<EditorExportPlugin>()); - return export_plugins[p_idx]; -} - -void EditorImportExport::set_export_file_action(const StringName& p_file, FileAction p_action) { - - if (p_action==ACTION_NONE) { - - files.erase(p_file); - } else { - - files[p_file]=p_action; - } - -} - -EditorImportExport::FileAction EditorImportExport::get_export_file_action(const StringName& p_file) const{ - - - if (files.has(p_file)) - return files[p_file]; - - - return ACTION_NONE; -} - -void EditorImportExport::get_export_file_list(List<StringName> *p_files){ - - - for (Map<StringName,FileAction>::Element *E=files.front();E;E=E->next()) { - - p_files->push_back(E->key()); - } - -} - -void EditorImportExport::add_export_platform(const Ref<EditorExportPlatform>& p_export) { - - exporters[p_export->get_name()]=p_export; -} - - -void EditorImportExport::get_export_platforms(List<StringName> *r_platforms) { - - for (Map<StringName,Ref<EditorExportPlatform> >::Element *E=exporters.front();E;E=E->next()) { - - r_platforms->push_back(E->key()); - } -} - -Ref<EditorExportPlatform> EditorImportExport::get_export_platform(const StringName& p_platform) { - - if (exporters.has(p_platform)) { - return exporters[p_platform]; - } else { - return Ref<EditorExportPlatform>(); - } -} - - -bool EditorImportExport::poll_export_platforms() { - - bool changed=false; - for (Map<StringName,Ref<EditorExportPlatform> >::Element *E=exporters.front();E;E=E->next()) { - - if (E->get()->poll_devices()) - changed=true; - } - - return changed; - -} - -void EditorImportExport::set_export_filter(ExportFilter p_enable) { - - export_filter=p_enable; -} - -EditorImportExport::ExportFilter EditorImportExport::get_export_filter() const{ - - return export_filter; -} - -void EditorImportExport::set_export_custom_filter(const String& p_custom_filter){ - export_custom_filter=p_custom_filter; -} -void EditorImportExport::set_export_custom_filter_exclude(const String& p_custom_filter){ - export_custom_filter_exclude=p_custom_filter; -} -String EditorImportExport::get_export_custom_filter() const{ - return export_custom_filter; -} -String EditorImportExport::get_export_custom_filter_exclude() const{ - return export_custom_filter_exclude; -} - -void EditorImportExport::set_export_image_action(ImageAction p_action) { - - image_action=p_action; -} - -EditorImportExport::ImageAction EditorImportExport::get_export_image_action() const{ - - return image_action; -} - -void EditorImportExport::set_export_image_shrink(float p_shrink) { - - image_shrink=p_shrink; -} - -float EditorImportExport::get_export_image_shrink() const{ - - return image_shrink; -} - - -void EditorImportExport::set_export_image_quality(float p_quality){ - - image_action_compress_quality=p_quality; -} - -float EditorImportExport::get_export_image_quality() const{ - - return image_action_compress_quality; -} - -void EditorImportExport::image_export_group_create(const StringName& p_name) { - - ERR_FAIL_COND(image_groups.has(p_name)); - ImageGroup ig; - ig.action=IMAGE_ACTION_NONE; //default - ig.make_atlas=false; - ig.shrink=1; - ig.lossy_quality=0.7; - image_groups[p_name]=ig; - - -} - - -bool EditorImportExport::image_export_has_group(const StringName& p_name) const { - - return image_groups.has(p_name); -} -void EditorImportExport::image_export_get_groups(List<StringName> *r_name) const { - - for (Map<StringName,ImageGroup>::Element *E=image_groups.front();E;E=E->next()) { - - r_name->push_back(E->key()); - } -} - -void EditorImportExport::image_export_group_remove(const StringName& p_name){ - - ERR_FAIL_COND(!image_groups.has(p_name)); - image_groups.erase(p_name); -} -void EditorImportExport::image_export_group_set_image_action(const StringName& p_export_group,ImageAction p_action){ - - ERR_FAIL_COND(!image_groups.has(p_export_group)); - image_groups[p_export_group].action=p_action; - -} -EditorImportExport::ImageAction EditorImportExport::image_export_group_get_image_action(const StringName& p_export_group) const{ - - ERR_FAIL_COND_V(!image_groups.has(p_export_group),IMAGE_ACTION_NONE); - return image_groups[p_export_group].action; - -} -void EditorImportExport::image_export_group_set_make_atlas(const StringName& p_export_group,bool p_make){ - - ERR_FAIL_COND(!image_groups.has(p_export_group)); - image_groups[p_export_group].make_atlas=p_make; - -} -bool EditorImportExport::image_export_group_get_make_atlas(const StringName& p_export_group) const{ - - ERR_FAIL_COND_V(!image_groups.has(p_export_group),false); - return image_groups[p_export_group].make_atlas; - -} -void EditorImportExport::image_export_group_set_shrink(const StringName& p_export_group,float p_amount){ - ERR_FAIL_COND(!image_groups.has(p_export_group)); - image_groups[p_export_group].shrink=p_amount; - -} -float EditorImportExport::image_export_group_get_shrink(const StringName& p_export_group) const{ - - ERR_FAIL_COND_V(!image_groups.has(p_export_group),1); - return image_groups[p_export_group].shrink; - -} - -void EditorImportExport::image_export_group_set_lossy_quality(const StringName& p_export_group,float p_amount){ - ERR_FAIL_COND(!image_groups.has(p_export_group)); - image_groups[p_export_group].lossy_quality=p_amount; - -} -float EditorImportExport::image_export_group_get_lossy_quality(const StringName& p_export_group) const{ - - ERR_FAIL_COND_V(!image_groups.has(p_export_group),1); - return image_groups[p_export_group].lossy_quality; - -} - -StringName EditorImportExport::image_get_export_group(const StringName& p_image) const { - - if (image_group_files.has(p_image)) - return image_group_files[p_image]; - else - return StringName(); - -} - -void EditorImportExport::image_add_to_export_group(const StringName& p_image,const StringName& p_export_group) { - - - bool emptygroup = String(p_export_group)==String(); - ERR_FAIL_COND(!emptygroup && !image_groups.has(p_export_group)); - - if (emptygroup) - image_group_files.erase(p_image); - else - image_group_files[p_image]=p_export_group; -} - -void EditorImportExport::image_export_get_images_in_group(const StringName& p_group,List<StringName> *r_images) const { - - for (Map<StringName,StringName>::Element *E=image_group_files.front();E;E=E->next()) { - - if (p_group==E->get()) - r_images->push_back(E->key()); - } -} - -void EditorImportExport::set_convert_text_scenes(bool p_convert) { - - convert_text_scenes=p_convert; -} - -bool EditorImportExport::get_convert_text_scenes() const{ - - return convert_text_scenes; -} - - -void EditorImportExport::load_config() { - - Ref<ConfigFile> cf = memnew( ConfigFile ); - - Error err = cf->load("res://export.cfg"); - if (err!=OK) - return; //no export config to be loaded! - - - export_custom_filter=cf->get_value("export_filter","filter"); - export_custom_filter_exclude=cf->get_value("export_filter","filter_exclude"); - String t=cf->get_value("export_filter","type"); - if (t=="selected") - export_filter=EXPORT_SELECTED; - else if (t=="resources") - export_filter=EXPORT_RESOURCES; - else if (t=="all") - export_filter=EXPORT_ALL; - - if (cf->has_section("convert_images")) { - - String ci = "convert_images"; - String action = cf->get_value(ci,"action"); - if (action=="none") - image_action=IMAGE_ACTION_NONE; - else if (action=="compress_ram") - image_action=IMAGE_ACTION_COMPRESS_RAM; - else if (action=="compress_disk") - image_action=IMAGE_ACTION_COMPRESS_DISK; - - image_action_compress_quality = cf->get_value(ci,"compress_quality"); - if (cf->has_section_key(ci,"shrink")) - image_shrink = cf->get_value(ci,"shrink"); - else - image_shrink=1; - String formats=cf->get_value(ci,"formats"); - Vector<String> f = formats.split(","); - image_formats.clear(); - for(int i=0;i<f.size();i++) { - image_formats.insert(f[i].strip_edges()); - } - } - - if (cf->has_section("convert_scenes")) { - - convert_text_scenes = cf->get_value("convert_scenes","convert_text_scenes"); - } - - - if (cf->has_section("export_filter_files")) { - - - String eff = "export_filter_files"; - List<String> k; - cf->get_section_keys(eff,&k); - for(List<String>::Element *E=k.front();E;E=E->next()) { - - String val = cf->get_value(eff,E->get()); - if (val=="copy") { - files[E->get()]=ACTION_COPY; - } else if (val=="bundle") { - files[E->get()]=ACTION_BUNDLE; - } - } - } - - List<String> sect; - - cf->get_sections(§); - - for(List<String>::Element *E=sect.front();E;E=E->next()) { - - String s = E->get(); - if (!s.begins_with("platform:")) - continue; - String p = s.substr(s.find(":")+1,s.length()); - - if (!exporters.has(p)) - continue; - - Ref<EditorExportPlatform> ep = exporters[p]; - if (!ep.is_valid()) { - continue; - } - List<String> keys; - cf->get_section_keys(s,&keys); - for(List<String>::Element *F=keys.front();F;F=F->next()) { - ep->set(F->get(),cf->get_value(s,F->get())); - } - } - - //save image groups - - if (cf->has_section("image_groups")) { - - sect.clear(); - cf->get_section_keys("image_groups",§); - for(List<String>::Element *E=sect.front();E;E=E->next()) { - - Dictionary d = cf->get_value("image_groups",E->get()); - ImageGroup g; - g.action=IMAGE_ACTION_NONE; - g.make_atlas=false; - g.lossy_quality=0.7; - g.shrink=1; - - if (d.has("action")) { - String action=d["action"]; - if (action=="compress_ram") - g.action=IMAGE_ACTION_COMPRESS_RAM; - else if (action=="compress_disk") - g.action=IMAGE_ACTION_COMPRESS_DISK; - else if (action=="keep") - g.action=IMAGE_ACTION_KEEP; - } - - if (d.has("atlas")) - g.make_atlas=d["atlas"]; - if (d.has("lossy_quality")) - g.lossy_quality=d["lossy_quality"]; - if (d.has("shrink")) { - - g.shrink=d["shrink"]; - g.shrink=CLAMP(g.shrink,1,8); - } - - image_groups[E->get()]=g; - - } - - if (cf->has_section_key("image_group_files","files")) { - - Vector<String> sa=cf->get_value("image_group_files","files"); - if (sa.size()%2==0) { - for(int i=0;i<sa.size();i+=2) { - image_group_files[sa[i]]=sa[i+1]; - } - } - } - - } - - - if (cf->has_section("script")) { - - if (cf->has_section_key("script","action")) { - - String action = cf->get_value("script","action"); - if (action=="compile") - script_action=SCRIPT_ACTION_COMPILE; - else if (action=="encrypt") - script_action=SCRIPT_ACTION_ENCRYPT; - else - script_action=SCRIPT_ACTION_NONE; - - } - - if (cf->has_section_key("script","encrypt_key")) { - - script_key = cf->get_value("script","encrypt_key"); - } - } - - if (cf->has_section("convert_samples")) { - - if (cf->has_section_key("convert_samples","action")) { - String action = cf->get_value("convert_samples","action"); - if (action=="none") { - sample_action=SAMPLE_ACTION_NONE; - } else if (action=="compress_ram") { - sample_action=SAMPLE_ACTION_COMPRESS_RAM; - } - } - - if (cf->has_section_key("convert_samples","max_hz")) - sample_action_max_hz=cf->get_value("convert_samples","max_hz"); - - if (cf->has_section_key("convert_samples","trim")) - sample_action_trim=cf->get_value("convert_samples","trim"); - } - - - -} - - - - - -void EditorImportExport::save_config() { - - Ref<ConfigFile> cf = memnew( ConfigFile ); - - switch(export_filter) { - case EXPORT_SELECTED: cf->set_value("export_filter","type","selected"); break; - case EXPORT_RESOURCES: cf->set_value("export_filter","type","resources"); break; - case EXPORT_ALL: cf->set_value("export_filter","type","all"); break; - } - - cf->set_value("export_filter","filter",export_custom_filter); - cf->set_value("export_filter", "filter_exclude",export_custom_filter_exclude); - - String file_action_section = "export_filter_files"; - - for (Map<StringName,FileAction>::Element *E=files.front();E;E=E->next()) { - - String f=E->key(); - String a; - switch (E->get()) { - case ACTION_NONE: {} - case ACTION_COPY: a="copy"; break; - case ACTION_BUNDLE: a="bundle"; break; - } - - cf->set_value(file_action_section,f,a); - } - - - for (Map<StringName,Ref<EditorExportPlatform> >::Element *E=exporters.front();E;E=E->next()) { - - String pname = "platform:"+String(E->key()); - - Ref<EditorExportPlatform> ep = E->get(); - - List<PropertyInfo> pl; - ep->get_property_list(&pl); - - for (List<PropertyInfo>::Element *F=pl.front();F;F=F->next()) { - - cf->set_value(pname,F->get().name,ep->get(F->get().name)); - } - - } - - switch(image_action) { - case IMAGE_ACTION_NONE: cf->set_value("convert_images","action","none"); break; - case IMAGE_ACTION_COMPRESS_RAM: cf->set_value("convert_images","action","compress_ram"); break; - case IMAGE_ACTION_COMPRESS_DISK: cf->set_value("convert_images","action","compress_disk"); break; - } - - cf->set_value("convert_images","shrink",image_shrink); - cf->set_value("convert_images","compress_quality",image_action_compress_quality); - - String formats; - for(Set<String>::Element *E=image_formats.front();E;E=E->next()) { - - if (E!=image_formats.front()) - formats+=","; - formats+=E->get(); - } - - cf->set_value("convert_images","formats",formats); - - //save image groups - - for(Map<StringName,ImageGroup>::Element *E=image_groups.front();E;E=E->next()) { - - Dictionary d; - switch(E->get().action) { - case IMAGE_ACTION_NONE: d["action"]="default"; break; - case IMAGE_ACTION_COMPRESS_RAM: d["action"]="compress_ram"; break; - case IMAGE_ACTION_COMPRESS_DISK: d["action"]="compress_disk"; break; - case IMAGE_ACTION_KEEP: d["action"]="keep"; break; - } - - - d["atlas"]=E->get().make_atlas; - d["shrink"]=E->get().shrink; - d["lossy_quality"]=E->get().lossy_quality; - cf->set_value("image_groups",E->key(),d); - - } - - if (image_groups.size() && image_group_files.size()){ - - Vector<String> igfkeys; - igfkeys.resize(image_group_files.size()); - int idx=0; - for (Map<StringName,StringName>::Element *E=image_group_files.front();E;E=E->next()) { - igfkeys[idx++]=E->key(); - } - igfkeys.sort(); - - Vector<String> igfsave; - igfsave.resize(image_group_files.size()*2); - idx=0; - for (int i=0;i<igfkeys.size();++i) { - - igfsave[idx++]=igfkeys[i]; - igfsave[idx++]=image_group_files[igfkeys[i]]; - } - cf->set_value("image_group_files","files",igfsave); - } - - switch(script_action) { - case SCRIPT_ACTION_NONE: cf->set_value("script","action","none"); break; - case SCRIPT_ACTION_COMPILE: cf->set_value("script","action","compile"); break; - case SCRIPT_ACTION_ENCRYPT: cf->set_value("script","action","encrypt"); break; - } - - cf->set_value("convert_scenes","convert_text_scenes",convert_text_scenes); - - cf->set_value("script","encrypt_key",script_key); - - switch(sample_action) { - case SAMPLE_ACTION_NONE: cf->set_value("convert_samples","action","none"); break; - case SAMPLE_ACTION_COMPRESS_RAM: cf->set_value("convert_samples","action","compress_ram"); break; - } - - cf->set_value("convert_samples","max_hz",sample_action_max_hz); - cf->set_value("convert_samples","trim",sample_action_trim); - - cf->save("res://export.cfg"); - -} - - -void EditorImportExport::script_set_action(ScriptAction p_action) { - - script_action=p_action; -} - -EditorImportExport::ScriptAction EditorImportExport::script_get_action() const{ - - return script_action; -} - -void EditorImportExport::script_set_encryption_key(const String& p_key){ - - script_key=p_key; -} -String EditorImportExport::script_get_encryption_key() const{ - - return script_key; -} - - -void EditorImportExport::sample_set_action(SampleAction p_action) { - - sample_action=p_action; -} - -EditorImportExport::SampleAction EditorImportExport::sample_get_action() const{ - - return sample_action; -} - -void EditorImportExport::sample_set_max_hz(int p_hz){ - - sample_action_max_hz=p_hz; -} -int EditorImportExport::sample_get_max_hz() const{ - - return sample_action_max_hz; -} - -void EditorImportExport::sample_set_trim(bool p_trim){ - - sample_action_trim=p_trim; -} -bool EditorImportExport::sample_get_trim() const{ - - return sample_action_trim; -} - -PoolVector<String> EditorImportExport::_get_export_file_list() { - - PoolVector<String> fl; - for (Map<StringName,FileAction>::Element *E=files.front();E;E=E->next()) { - - fl.push_back(E->key()); - } - - return fl; -} - -PoolVector<String> EditorImportExport::_get_export_platforms() { - - PoolVector<String> ep; - for (Map<StringName,Ref<EditorExportPlatform> >::Element *E=exporters.front();E;E=E->next()) { - - ep.push_back(E->key()); - } - - return ep; - -} - -void EditorImportExport::_bind_methods() { - - ClassDB::bind_method(D_METHOD("add_import_plugin","plugin:EditorImportPlugin"),&EditorImportExport::add_import_plugin); - ClassDB::bind_method(D_METHOD("remove_import_plugin","plugin:EditorImportPlugin"),&EditorImportExport::remove_import_plugin); - ClassDB::bind_method(D_METHOD("get_import_plugin_count"),&EditorImportExport::get_import_plugin_count); - ClassDB::bind_method(D_METHOD("get_import_plugin:EditorImportPlugin","idx"),&EditorImportExport::get_import_plugin); - ClassDB::bind_method(D_METHOD("get_import_plugin_by_name:EditorImportPlugin","name"),&EditorImportExport::get_import_plugin_by_name); - - ClassDB::bind_method(D_METHOD("add_export_plugin","plugin:EditorExportPlugin"),&EditorImportExport::add_export_plugin); - ClassDB::bind_method(D_METHOD("remove_export_plugin","plugin:EditorExportPlugin"),&EditorImportExport::remove_export_plugin); - ClassDB::bind_method(D_METHOD("get_export_plugin_count"),&EditorImportExport::get_export_plugin_count); - ClassDB::bind_method(D_METHOD("get_export_plugin:EditorExportPlugin","idx"),&EditorImportExport::get_export_plugin); - - ClassDB::bind_method(D_METHOD("set_export_file_action","file","action"),&EditorImportExport::set_export_file_action); - ClassDB::bind_method(D_METHOD("get_export_file_action","file"),&EditorImportExport::get_export_file_action); - ClassDB::bind_method(D_METHOD("get_export_file_list"),&EditorImportExport::_get_export_file_list); - - ClassDB::bind_method(D_METHOD("add_export_platform","platform:EditorExportplatform"),&EditorImportExport::add_export_platform); - //ClassDB::bind_method(D_METHOD("remove_export_platform","platform:EditorExportplatform"),&EditorImportExport::add_export_platform); - ClassDB::bind_method(D_METHOD("get_export_platform:EditorExportPlatform","name"),&EditorImportExport::get_export_platform); - ClassDB::bind_method(D_METHOD("get_export_platforms"),&EditorImportExport::_get_export_platforms); - - ClassDB::bind_method(D_METHOD("set_export_filter","filter"),&EditorImportExport::set_export_filter); - ClassDB::bind_method(D_METHOD("get_export_filter"),&EditorImportExport::get_export_filter); - - ClassDB::bind_method(D_METHOD("set_export_custom_filter","filter"),&EditorImportExport::set_export_custom_filter); - ClassDB::bind_method(D_METHOD("get_export_custom_filter"),&EditorImportExport::get_export_custom_filter); - - ClassDB::bind_method(D_METHOD("set_export_custom_filter_exclude","filter_exclude"),&EditorImportExport::set_export_custom_filter_exclude); - ClassDB::bind_method(D_METHOD("get_export_custom_filter_exclude"),&EditorImportExport::get_export_custom_filter_exclude); - - - ClassDB::bind_method(D_METHOD("image_export_group_create"),&EditorImportExport::image_export_group_create); - ClassDB::bind_method(D_METHOD("image_export_group_remove"),&EditorImportExport::image_export_group_remove); - ClassDB::bind_method(D_METHOD("image_export_group_set_image_action"),&EditorImportExport::image_export_group_set_image_action); - ClassDB::bind_method(D_METHOD("image_export_group_set_make_atlas"),&EditorImportExport::image_export_group_set_make_atlas); - ClassDB::bind_method(D_METHOD("image_export_group_set_shrink"),&EditorImportExport::image_export_group_set_shrink); - ClassDB::bind_method(D_METHOD("image_export_group_get_image_action"),&EditorImportExport::image_export_group_get_image_action); - ClassDB::bind_method(D_METHOD("image_export_group_get_make_atlas"),&EditorImportExport::image_export_group_get_make_atlas); - ClassDB::bind_method(D_METHOD("image_export_group_get_shrink"),&EditorImportExport::image_export_group_get_shrink); - ClassDB::bind_method(D_METHOD("image_add_to_export_group"),&EditorImportExport::image_add_to_export_group); - ClassDB::bind_method(D_METHOD("script_set_action"),&EditorImportExport::script_set_action); - ClassDB::bind_method(D_METHOD("script_set_encryption_key"),&EditorImportExport::script_set_encryption_key); - ClassDB::bind_method(D_METHOD("script_get_action"),&EditorImportExport::script_get_action); - ClassDB::bind_method(D_METHOD("script_get_encryption_key"),&EditorImportExport::script_get_encryption_key); - - - - BIND_CONSTANT( ACTION_NONE ); - BIND_CONSTANT( ACTION_COPY ); - BIND_CONSTANT( ACTION_BUNDLE ); - - BIND_CONSTANT( EXPORT_SELECTED ); - BIND_CONSTANT( EXPORT_RESOURCES ); - BIND_CONSTANT( EXPORT_ALL ); - - BIND_CONSTANT( IMAGE_ACTION_NONE ); - BIND_CONSTANT( IMAGE_ACTION_COMPRESS_DISK ); - BIND_CONSTANT( IMAGE_ACTION_COMPRESS_RAM ); - BIND_CONSTANT( IMAGE_ACTION_KEEP ); - - BIND_CONSTANT( SCRIPT_ACTION_NONE ); - BIND_CONSTANT( SCRIPT_ACTION_COMPILE ); - BIND_CONSTANT( SCRIPT_ACTION_ENCRYPT ); -}; - - - -EditorImportExport::EditorImportExport() { - - export_filter=EXPORT_RESOURCES; - singleton=this; - image_action=IMAGE_ACTION_NONE; - image_action_compress_quality=0.7; - image_formats.insert("png"); - image_shrink=1; - - - script_action=SCRIPT_ACTION_COMPILE; - - sample_action=SAMPLE_ACTION_NONE; - sample_action_max_hz=44100; - sample_action_trim=false; - - convert_text_scenes=true; - -} - - - -EditorImportExport::~EditorImportExport() { - - - -} -#endif diff --git a/tools/editor/editor_help.cpp b/tools/editor/editor_help.cpp deleted file mode 100644 index 5b629b2590..0000000000 --- a/tools/editor/editor_help.cpp +++ /dev/null @@ -1,1929 +0,0 @@ -/*************************************************************************/ -/* editor_help.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 "editor_help.h" - -#include "editor_node.h" -#include "editor_settings.h" -#include "os/keyboard.h" -#include "doc_data_compressed.h" -#include "tools/editor/plugins/script_editor_plugin.h" - -void EditorHelpSearch::popup() { - popup_centered_ratio(0.6); - if (search_box->get_text()!="") { - search_box->select_all(); - _update_search(); - } - search_box->grab_focus(); -} - -void EditorHelpSearch::popup(const String& p_term) { - - popup_centered_ratio(0.6); - if (p_term!="") { - search_box->set_text(p_term); - search_box->select_all(); - _update_search(); - } else - search_box->clear(); - search_box->grab_focus(); -} - - -void EditorHelpSearch::_text_changed(const String& p_newtext) { - - _update_search(); -} - -void EditorHelpSearch::_sbox_input(const InputEvent& p_ie) { - - if (p_ie.type==InputEvent::KEY && ( - p_ie.key.scancode == KEY_UP || - p_ie.key.scancode == KEY_DOWN || - p_ie.key.scancode == KEY_PAGEUP || - p_ie.key.scancode == KEY_PAGEDOWN ) ) { - - search_options->call("_gui_input",p_ie); - search_box->accept_event(); - } - -} - -void EditorHelpSearch::_update_search() { - - search_options->clear(); - search_options->set_hide_root(true); - - /* - TreeItem *root = search_options->create_item(); - _parse_fs(EditorFileSystem::get_singleton()->get_filesystem()); -*/ - - List<StringName> type_list; - ClassDB::get_class_list(&type_list); - - DocData *doc=EditorHelp::get_doc_data(); - String term = search_box->get_text(); - if (term.length()<2) - return; - - TreeItem *root = search_options->create_item(); - - - - Ref<Texture> def_icon = get_icon("Node","EditorIcons"); - //classes first - for (Map<String,DocData::ClassDoc>::Element *E=doc->class_list.front();E;E=E->next()) { - - if (E->key().findn(term)!=-1) { - - TreeItem *item = search_options->create_item(root); - item->set_metadata(0,"class_name:"+E->key()); - item->set_text(0,E->key()+" (Class)"); - if (has_icon(E->key(),"EditorIcons")) - item->set_icon(0,get_icon(E->key(),"EditorIcons")); - else - item->set_icon(0,def_icon); - - - } - - } - - //class methods, etc second - for (Map<String,DocData::ClassDoc>::Element *E=doc->class_list.front();E;E=E->next()) { - - - DocData::ClassDoc & c = E->get(); - - Ref<Texture> cicon; - if (has_icon(E->key(),"EditorIcons")) - cicon=get_icon(E->key(),"EditorIcons"); - else - cicon=def_icon; - - - for(int i=0;i<c.methods.size();i++) { - if( (term.begins_with(".") && c.methods[i].name.begins_with(term.right(1))) - || (term.ends_with("(") && c.methods[i].name.ends_with(term.left(term.length()-1).strip_edges())) - || (term.begins_with(".") && term.ends_with("(") && c.methods[i].name==term.substr(1,term.length()-2).strip_edges()) - || c.methods[i].name.findn(term)!=-1) { - - TreeItem *item = search_options->create_item(root); - item->set_metadata(0,"class_method:"+E->key()+":"+c.methods[i].name); - item->set_text(0,E->key()+"."+c.methods[i].name+" (Method)"); - item->set_icon(0,cicon); - } - } - - for(int i=0;i<c.signals.size();i++) { - - if (c.signals[i].name.findn(term)!=-1) { - - TreeItem *item = search_options->create_item(root); - item->set_metadata(0,"class_signal:"+E->key()+":"+c.signals[i].name); - item->set_text(0,E->key()+"."+c.signals[i].name+" (Signal)"); - item->set_icon(0,cicon); - } - } - - for(int i=0;i<c.constants.size();i++) { - - if (c.constants[i].name.findn(term)!=-1) { - - TreeItem *item = search_options->create_item(root); - item->set_metadata(0,"class_constant:"+E->key()+":"+c.constants[i].name); - item->set_text(0,E->key()+"."+c.constants[i].name+" (Constant)"); - item->set_icon(0,cicon); - } - } - - for(int i=0;i<c.properties.size();i++) { - - if (c.properties[i].name.findn(term)!=-1) { - - TreeItem *item = search_options->create_item(root); - item->set_metadata(0,"class_property:"+E->key()+":"+c.properties[i].name); - item->set_text(0,E->key()+"."+c.properties[i].name+" (Property)"); - item->set_icon(0,cicon); - } - } - - for(int i=0;i<c.theme_properties.size();i++) { - - if (c.theme_properties[i].name.findn(term)!=-1) { - - TreeItem *item = search_options->create_item(root); - item->set_metadata(0,"class_theme_item:"+E->key()+":"+c.theme_properties[i].name); - item->set_text(0,E->key()+"."+c.theme_properties[i].name+" (Theme Item)"); - item->set_icon(0,cicon); - } - } - - - } - - //same but descriptions - - for (Map<String,DocData::ClassDoc>::Element *E=doc->class_list.front();E;E=E->next()) { - - - DocData::ClassDoc & c = E->get(); - - Ref<Texture> cicon; - if (has_icon(E->key(),"EditorIcons")) - cicon=get_icon(E->key(),"EditorIcons"); - else - cicon=def_icon; - - if (c.description.findn(term)!=-1) { - - - TreeItem *item = search_options->create_item(root); - item->set_metadata(0,"class_desc:"+E->key()); - item->set_text(0,E->key()+" (Class Description)"); - item->set_icon(0,cicon); - - } - - for(int i=0;i<c.methods.size();i++) { - - if (c.methods[i].description.findn(term)!=-1) { - - TreeItem *item = search_options->create_item(root); - item->set_metadata(0,"class_method_desc:"+E->key()+":"+c.methods[i].name); - item->set_text(0,E->key()+"."+c.methods[i].name+" (Method Description)"); - item->set_icon(0,cicon); - } - } - - for(int i=0;i<c.signals.size();i++) { - - if (c.signals[i].description.findn(term)!=-1) { - - TreeItem *item = search_options->create_item(root); - item->set_metadata(0,"class_signal:"+E->key()+":"+c.signals[i].name); - item->set_text(0,E->key()+"."+c.signals[i].name+" (Signal Description)"); - item->set_icon(0,cicon); - } - } - - for(int i=0;i<c.constants.size();i++) { - - if (c.constants[i].description.findn(term)!=-1) { - - TreeItem *item = search_options->create_item(root); - item->set_metadata(0,"class_constant:"+E->key()+":"+c.constants[i].name); - item->set_text(0,E->key()+"."+c.constants[i].name+" (Constant Description)"); - item->set_icon(0,cicon); - } - } - - for(int i=0;i<c.properties.size();i++) { - - if (c.properties[i].description.findn(term)!=-1) { - - TreeItem *item = search_options->create_item(root); - item->set_metadata(0,"class_property_desc:"+E->key()+":"+c.properties[i].name); - item->set_text(0,E->key()+"."+c.properties[i].name+" (Property Description)"); - item->set_icon(0,cicon); - } - } - - } - - get_ok()->set_disabled(root->get_children()==NULL); - -} - -void EditorHelpSearch::_confirmed() { - - TreeItem *ti = search_options->get_selected(); - if (!ti) - return; - - String mdata=ti->get_metadata(0); - emit_signal("go_to_help",mdata); - editor->call("_editor_select",EditorNode::EDITOR_SCRIPT); // in case EditorHelpSearch beeen invoked on top of other editor window - // go to that - hide(); -} - -void EditorHelpSearch::_notification(int p_what) { - - if (p_what==NOTIFICATION_ENTER_TREE) { - - connect("confirmed",this,"_confirmed"); - _update_search(); - } - - if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { - - if (is_visible_in_tree()) { - - search_box->call_deferred("grab_focus"); // still not visible - search_box->select_all(); - } - } - -} - - -void EditorHelpSearch::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_text_changed"),&EditorHelpSearch::_text_changed); - ClassDB::bind_method(D_METHOD("_confirmed"),&EditorHelpSearch::_confirmed); - ClassDB::bind_method(D_METHOD("_sbox_input"),&EditorHelpSearch::_sbox_input); - ClassDB::bind_method(D_METHOD("_update_search"),&EditorHelpSearch::_update_search); - - ADD_SIGNAL(MethodInfo("go_to_help")); - -} - - -EditorHelpSearch::EditorHelpSearch() { - - editor=EditorNode::get_singleton(); - VBoxContainer *vbc = memnew( VBoxContainer ); - add_child(vbc); - - HBoxContainer *sb_hb = memnew( HBoxContainer); - search_box = memnew( LineEdit ); - sb_hb->add_child(search_box); - search_box->set_h_size_flags(SIZE_EXPAND_FILL); - Button *sb = memnew( Button(TTR("Search"))); - sb->connect("pressed",this,"_update_search"); - sb_hb->add_child(sb); - vbc->add_margin_child(TTR("Search:"),sb_hb); - search_box->connect("text_changed",this,"_text_changed"); - search_box->connect("gui_input",this,"_sbox_input"); - search_options = memnew( Tree ); - vbc->add_margin_child(TTR("Matches:"),search_options,true); - get_ok()->set_text(TTR("Open")); - get_ok()->set_disabled(true); - register_text_enter(search_box); - set_hide_on_ok(false); - search_options->connect("item_activated",this,"_confirmed"); - set_title(TTR("Search Help")); - - //search_options->set_hide_root(true); - -} - -///////////////////////////////// - -//////////////////////////////////// -/// ///////////////////////////////// - - - -void EditorHelpIndex::add_type(const String& p_type,HashMap<String,TreeItem*>& p_types,TreeItem *p_root) { - - if (p_types.has(p_type)) - return; - /* - if (!ClassDB::is_type(p_type,base) || p_type==base) - return; - */ - - String inherits=EditorHelp::get_doc_data()->class_list[p_type].inherits; - - TreeItem *parent=p_root; - - - if (inherits.length()) { - - if (!p_types.has(inherits)) { - - add_type(inherits,p_types,p_root); - } - - if (p_types.has(inherits) ) - parent=p_types[inherits]; - } - - TreeItem *item = class_list->create_item(parent); - item->set_metadata(0,p_type); - item->set_tooltip(0,EditorHelp::get_doc_data()->class_list[p_type].brief_description); - item->set_text(0,p_type); - - - if (has_icon(p_type,"EditorIcons")) { - - item->set_icon(0, get_icon(p_type,"EditorIcons")); - } - - p_types[p_type]=item; -} - - -void EditorHelpIndex::_tree_item_selected() { - - - TreeItem *s=class_list->get_selected(); - if (!s) - return; - - emit_signal("open_class",s->get_text(0)); - - hide(); - - //_goto_desc(s->get_text(0)); - -} - -void EditorHelpIndex::select_class(const String& p_class) { - - if (!tree_item_map.has(p_class)) - return; - tree_item_map[p_class]->select(0); - class_list->ensure_cursor_is_visible(); -} - -void EditorHelpIndex::popup() { - - popup_centered_ratio(0.6); - - search_box->set_text(""); - _update_class_list(); -} - -void EditorHelpIndex::_notification(int p_what) { - - if (p_what==NOTIFICATION_ENTER_TREE) { - - _update_class_list(); - - connect("confirmed",this,"_tree_item_selected"); - - } else if (p_what==NOTIFICATION_POST_POPUP) { - - search_box->call_deferred("grab_focus"); - } -} - -void EditorHelpIndex::_text_changed(const String& p_text) { - - _update_class_list(); -} - -void EditorHelpIndex::_update_class_list() { - - class_list->clear(); - tree_item_map.clear(); - TreeItem *root = class_list->create_item(); - class_list->set_hide_root(true); - - String filter = search_box->get_text().strip_edges(); - String to_select = ""; - - for(Map<String,DocData::ClassDoc>::Element *E=EditorHelp::get_doc_data()->class_list.front();E;E=E->next()) { - - if (filter == "") { - add_type(E->key(),tree_item_map,root); - } else { - - bool found = false; - String type = E->key(); - - while(type != "") { - if (filter.is_subsequence_ofi(type)) { - - if (to_select.empty()) { - to_select = type; - } - - found=true; - break; - } - - type = EditorHelp::get_doc_data()->class_list[type].inherits; - } - - if (found) { - add_type(E->key(),tree_item_map,root); - } - } - } - - if (tree_item_map.has(filter)) { - select_class(filter); - } else if (to_select != "") { - select_class(to_select); - } -} - - -void EditorHelpIndex::_sbox_input(const InputEvent& p_ie) { - - if (p_ie.type==InputEvent::KEY && ( - p_ie.key.scancode == KEY_UP || - p_ie.key.scancode == KEY_DOWN || - p_ie.key.scancode == KEY_PAGEUP || - p_ie.key.scancode == KEY_PAGEDOWN ) ) { - - class_list->call("_gui_input",p_ie); - search_box->accept_event(); - } -} - -void EditorHelpIndex::_bind_methods() { - - ClassDB::bind_method("_tree_item_selected",&EditorHelpIndex::_tree_item_selected); - ClassDB::bind_method("_text_changed",&EditorHelpIndex::_text_changed); - ClassDB::bind_method("_sbox_input",&EditorHelpIndex::_sbox_input); - ClassDB::bind_method("select_class",&EditorHelpIndex::select_class); - ADD_SIGNAL( MethodInfo("open_class")); -} - - - -EditorHelpIndex::EditorHelpIndex() { - - VBoxContainer *vbc = memnew( VBoxContainer ); - add_child(vbc); - - search_box = memnew( LineEdit ); - vbc->add_margin_child(TTR("Search:"), search_box); - search_box->set_h_size_flags(SIZE_EXPAND_FILL); - - register_text_enter(search_box); - - search_box->connect("text_changed", this, "_text_changed"); - search_box->connect("gui_input", this, "_sbox_input"); - - class_list = memnew( Tree ); - vbc->add_margin_child(TTR("Class List:")+" ", class_list, true); - class_list->set_v_size_flags(SIZE_EXPAND_FILL); - - class_list->connect("item_activated",this,"_tree_item_selected"); - - get_ok()->set_text(TTR("Open")); - set_title(TTR("Search Classes")); -} - - - -///////////////////////////////// - -//////////////////////////////////// -/// ///////////////////////////////// -DocData *EditorHelp::doc=NULL; - -void EditorHelp::_unhandled_key_input(const InputEvent& p_ev) { - - if (!is_visible_in_tree()) - return; - if ( p_ev.key.mod.control && p_ev.key.scancode==KEY_F) { - - search->grab_focus(); - search->select_all(); - } -} - -void EditorHelp::_search(const String&) { - - if (search->get_text()=="") - return; - - - String stext=search->get_text(); - bool keep = prev_search==stext; - - bool ret = class_desc->search(stext, keep); - if (!ret) { - class_desc->search(stext, false); - } - - prev_search=stext; - - -} - -#if 0 -void EditorHelp::_button_pressed(int p_idx) { - - if (p_idx==PAGE_CLASS_LIST) { - - //edited_class->set_pressed(false); - //class_list_button->set_pressed(true); - //tabs->set_current_tab(PAGE_CLASS_LIST); - - } else if (p_idx==PAGE_CLASS_DESC) { - - //edited_class->set_pressed(true); - //class_list_button->set_pressed(false); - //tabs->set_current_tab(PAGE_CLASS_DESC); - - } else if (p_idx==PAGE_CLASS_PREV) { - - if (history_pos<2) - return; - history_pos--; - ERR_FAIL_INDEX(history_pos-1,history.size()); - _goto_desc(history[history_pos-1].c,false,history[history_pos-1].scroll); - _update_history_buttons(); - - - } else if (p_idx==PAGE_CLASS_NEXT) { - - if (history_pos>=history.size()) - return; - - history_pos++; - ERR_FAIL_INDEX(history_pos-1,history.size()); - _goto_desc(history[history_pos-1].c,false,history[history_pos-1].scroll); - _update_history_buttons(); - - } else if (p_idx==PAGE_SEARCH) { - - _search(""); - } -} - - -#endif - -void EditorHelp::_class_list_select(const String& p_select) { - - _goto_desc(p_select); -} - -void EditorHelp::_class_desc_select(const String& p_select) { - - - - //print_line("LINK: "+p_select); - if (p_select.begins_with("#")) { - //_goto_desc(p_select.substr(1,p_select.length())); - emit_signal("go_to_help","class_name:"+p_select.substr(1,p_select.length())); - return; - } else if (p_select.begins_with("@")) { - - String m = p_select.substr(1,p_select.length()); - - if (m.find(".")!=-1) { - //must go somewhere else - - emit_signal("go_to_help","class_method:"+m.get_slice(".",0)+":"+m.get_slice(".",0)); - } else { - - if (!method_line.has(m)) - return; - class_desc->scroll_to_line(method_line[m]); - } - - } - - -} - -void EditorHelp::_class_desc_input(const InputEvent& p_input) { - if (p_input.type==InputEvent::MOUSE_BUTTON && p_input.mouse_button.pressed && p_input.mouse_button.button_index==1) { - class_desc->set_selection_enabled(false); - class_desc->set_selection_enabled(true); - } - set_focused(); -} - -void EditorHelp::_add_type(const String& p_type) { - - String t = p_type; - if (t=="") - t="void"; - bool can_ref = (t!="int" && t!="real" && t!="bool" && t!="void"); - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color")); - if (can_ref) - class_desc->push_meta("#"+t); //class - class_desc->add_text(t); - if (can_ref) - class_desc->pop(); - class_desc->pop(); - -} - -void EditorHelp::_scroll_changed(double p_scroll) { - - if (scroll_locked) - return; - - if (!class_desc->get_v_scroll()->is_visible()) - p_scroll=0; - - //history[p].scroll=p_scroll; -} - -Error EditorHelp::_goto_desc(const String& p_class,int p_vscr) { - - //ERR_FAIL_COND(!doc->class_list.has(p_class)); - if (!doc->class_list.has(p_class)) - return ERR_DOES_NOT_EXIST; - - - //if (tree_item_map.has(p_class)) { - select_locked = true; - //} - - class_desc->show(); - //tabs->set_current_tab(PAGE_CLASS_DESC); - description_line=0; - - if (p_class==edited_class) - return OK; //already there - - scroll_locked=true; - - class_desc->clear(); - method_line.clear(); - edited_class=p_class; - //edited_class->show(); - - - DocData::ClassDoc cd=doc->class_list[p_class]; //make a copy, so we can sort without worrying - - Color h_color; - - Ref<Font> doc_font = get_font("doc","EditorFonts"); - Ref<Font> doc_title_font = get_font("doc_title","EditorFonts"); - Ref<Font> doc_code_font = get_font("doc_source","EditorFonts"); - - - h_color=Color(1,1,1,1); - - class_desc->push_font(doc_title_font); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->add_text(TTR("Class:")+" "); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color")); - _add_text(p_class); - class_desc->pop(); - class_desc->pop(); - class_desc->pop(); - class_desc->add_newline(); - - if (cd.inherits!="") { - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Inherits:")+" "); - class_desc->pop(); - class_desc->pop(); - - String inherits = cd.inherits; - - class_desc->push_font(doc_font); - - while (inherits != "") { - _add_type(inherits); - - inherits = doc->class_list[inherits].inherits; - - if (inherits != "") { - class_desc->add_text(" , "); - } - } - - class_desc->pop(); - class_desc->add_newline(); - } - - if (ClassDB::class_exists(cd.name)) { - - bool found = false; - bool prev = false; - - for (Map<String,DocData::ClassDoc>::Element *E=doc->class_list.front();E;E=E->next()) { - - if (E->get().inherits == cd.name) { - - if (!found) { - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Inherited by:")+" "); - class_desc->pop(); - class_desc->pop(); - - found = true; - class_desc->push_font(doc_font); - } - - if (prev) { - - class_desc->add_text(" , "); - prev = false; - } - - _add_type(E->get().name); - prev = true; - } - } - - if (found) - class_desc->pop(); - - class_desc->add_newline(); - } - - class_desc->add_newline(); - - if (cd.brief_description!="") { - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Brief Description:")); - class_desc->pop(); - class_desc->pop(); - - //class_desc->add_newline(); - class_desc->add_newline(); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - class_desc->push_font( doc_font ); - class_desc->push_indent(1); - _add_text(cd.brief_description); - class_desc->pop(); - class_desc->pop(); - class_desc->pop(); - class_desc->add_newline(); - class_desc->add_newline(); - } - - Set<String> skip_methods; - bool property_descr=false; - - if (cd.properties.size()) { - - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Members:")); - class_desc->pop(); - class_desc->pop(); - //class_desc->add_newline(); - - class_desc->push_indent(1); - class_desc->push_table(2); - class_desc->set_table_column_expand(1,1); - - for(int i=0;i<cd.properties.size();i++) { - property_line[cd.properties[i].name]=class_desc->get_line_count()-2; //gets overriden if description - - class_desc->push_cell(); - class_desc->push_align(RichTextLabel::ALIGN_RIGHT); - class_desc->push_font(doc_code_font); - _add_type(cd.properties[i].type); - class_desc->add_text(" "); - class_desc->pop(); - class_desc->pop(); - class_desc->pop(); - - bool describe=false; - - if (cd.properties[i].setter!="") { - skip_methods.insert(cd.properties[i].setter); - describe=true; - - } - if (cd.properties[i].getter!="") { - skip_methods.insert(cd.properties[i].getter); - describe=true; - } - - if (cd.properties[i].description!="") { - describe=true; - - } - class_desc->push_cell(); - if (describe) { - class_desc->push_meta("@"+cd.properties[i].name); - } - - class_desc->push_font(doc_code_font); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - _add_text(cd.properties[i].name); - - if (describe) { - class_desc->pop(); - } - - - if (cd.properties[i].brief_description!="") { - class_desc->push_font(doc_font); - class_desc->add_text(" "); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color")); - _add_text(cd.properties[i].description); - class_desc->pop(); - class_desc->pop(); - - } - - if (describe) { - property_descr=true; - } - - - class_desc->pop(); - class_desc->pop(); - class_desc->pop(); - - } - - - class_desc->pop(); //table - class_desc->pop(); - class_desc->add_newline(); - class_desc->add_newline(); - } - - - bool method_descr=false; - bool sort_methods = EditorSettings::get_singleton()->get("text_editor/help/sort_functions_alphabetically"); - - Vector<DocData::MethodDoc> methods; - - for(int i=0;i<cd.methods.size();i++) { - if (skip_methods.has(cd.methods[i].name)) - continue; - methods.push_back(cd.methods[i]); - } - - if (methods.size()) { - - if (sort_methods) - methods.sort(); - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Public Methods:")); - class_desc->pop(); - class_desc->pop(); - - //class_desc->add_newline(); - //class_desc->add_newline(); - - class_desc->push_indent(1); - class_desc->push_table(2); - class_desc->set_table_column_expand(1,1); - - for(int i=0;i<methods.size();i++) { - - class_desc->push_cell(); - - - method_line[methods[i].name]=class_desc->get_line_count()-2; //gets overriden if description - class_desc->push_align(RichTextLabel::ALIGN_RIGHT); - class_desc->push_font(doc_code_font); - _add_type(methods[i].return_type); - //class_desc->add_text(" "); - class_desc->pop(); //align - class_desc->pop(); //font - class_desc->pop(); //cell - class_desc->push_cell(); - class_desc->push_font(doc_code_font); - - if (methods[i].description!="") { - method_descr=true; - class_desc->push_meta("@"+methods[i].name); - } - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - _add_text(methods[i].name); - class_desc->pop(); - if (methods[i].description!="") - class_desc->pop(); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); - class_desc->add_text(methods[i].arguments.size()?"( ":"("); - class_desc->pop(); - for(int j=0;j<methods[i].arguments.size();j++) { - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - if (j>0) - class_desc->add_text(", "); - _add_type(methods[i].arguments[j].type); - class_desc->add_text(" "); - _add_text(methods[i].arguments[j].name); - if (methods[i].arguments[j].default_value!="") { - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); - class_desc->add_text("="); - class_desc->pop(); - _add_text(methods[i].arguments[j].default_value); - } - - class_desc->pop(); - } - - if (methods[i].qualifiers.find("vararg")!=-1) { - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - class_desc->add_text(","); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); - class_desc->add_text(" ... "); - class_desc->pop(); - class_desc->pop(); - } - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); - class_desc->add_text(methods[i].arguments.size()?" )":")"); - class_desc->pop(); - if (methods[i].qualifiers!="") { - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->add_text(" "); - _add_text(methods[i].qualifiers); - class_desc->pop(); - - } - class_desc->pop();//monofont - //class_desc->add_newline(); - class_desc->pop(); //cell - - } - class_desc->pop(); //table - class_desc->pop(); - class_desc->add_newline(); - class_desc->add_newline(); - - } - - - if (cd.theme_properties.size()) { - - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("GUI Theme Items:")); - class_desc->pop(); - class_desc->pop(); - class_desc->add_newline(); - - class_desc->push_indent(1); - - //class_desc->add_newline(); - - for(int i=0;i<cd.theme_properties.size();i++) { - - theme_property_line[cd.theme_properties[i].name]=class_desc->get_line_count()-2; //gets overriden if description - class_desc->push_font(doc_code_font); - _add_type(cd.theme_properties[i].type); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - class_desc->add_text(" "); - _add_text(cd.theme_properties[i].name); - class_desc->pop(); - class_desc->pop(); - - if (cd.theme_properties[i].description!="") { - class_desc->push_font(doc_font); - class_desc->add_text(" "); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color")); - _add_text(cd.theme_properties[i].description); - class_desc->pop(); - class_desc->pop(); - - } - - class_desc->add_newline(); - } - - class_desc->pop(); - class_desc->add_newline(); - } - - if (cd.signals.size()) { - - if (sort_methods) { - cd.signals.sort(); - } - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Signals:")); - class_desc->pop(); - class_desc->pop(); - - class_desc->add_newline(); - //class_desc->add_newline(); - - class_desc->push_indent(1); - - for(int i=0;i<cd.signals.size();i++) { - - signal_line[cd.signals[i].name]=class_desc->get_line_count()-2; //gets overriden if description - class_desc->push_font(doc_code_font); // monofont - //_add_type("void"); - //class_desc->add_text(" "); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - _add_text(cd.signals[i].name); - class_desc->pop(); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); - class_desc->add_text(cd.signals[i].arguments.size()?"( ":"("); - class_desc->pop(); - for(int j=0;j<cd.signals[i].arguments.size();j++) { - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - if (j>0) - class_desc->add_text(", "); - _add_type(cd.signals[i].arguments[j].type); - class_desc->add_text(" "); - _add_text(cd.signals[i].arguments[j].name); - if (cd.signals[i].arguments[j].default_value!="") { - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); - class_desc->add_text("="); - class_desc->pop(); - _add_text(cd.signals[i].arguments[j].default_value); - } - - class_desc->pop(); - } - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); - class_desc->add_text(cd.signals[i].arguments.size()?" )":")"); - class_desc->pop(); - class_desc->pop(); // end monofont - if (cd.signals[i].description!="") { - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color")); - class_desc->add_text(" "); - _add_text(cd.signals[i].description); - class_desc->pop(); - - } - class_desc->add_newline(); - - } - - class_desc->pop(); - class_desc->add_newline(); - - } - - if (cd.constants.size()) { - - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Constants:")); - class_desc->pop(); - class_desc->pop(); - class_desc->push_indent(1); - - class_desc->add_newline(); - //class_desc->add_newline(); - - for(int i=0;i<cd.constants.size();i++) { - - constant_line[cd.constants[i].name]=class_desc->get_line_count()-2; - class_desc->push_font(doc_code_font); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color")); - _add_text(cd.constants[i].name); - class_desc->pop(); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); - class_desc->add_text(" = "); - class_desc->pop(); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - _add_text(cd.constants[i].value); - class_desc->pop(); - class_desc->pop(); - if (cd.constants[i].description!="") { - class_desc->push_font(doc_font); - class_desc->add_text(" "); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color")); - _add_text(cd.constants[i].description); - class_desc->pop(); - class_desc->pop(); - } - - class_desc->add_newline(); - } - - class_desc->pop(); - class_desc->add_newline(); - - - } - - if (cd.description!="") { - - description_line=class_desc->get_line_count()-2; - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Description:")); - class_desc->pop(); - class_desc->pop(); - - class_desc->add_newline(); - class_desc->add_newline(); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - class_desc->push_font( doc_font ); - class_desc->push_indent(1); - _add_text(cd.description); - class_desc->pop(); - class_desc->pop(); - class_desc->pop(); - class_desc->add_newline(); - class_desc->add_newline(); - } - - if (property_descr) { - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Property Description:")); - class_desc->pop(); - class_desc->pop(); - - class_desc->add_newline(); - class_desc->add_newline(); - - - for(int i=0;i<cd.properties.size();i++) { - - method_line[cd.properties[i].name]=class_desc->get_line_count()-2; - - class_desc->push_font(doc_code_font); - _add_type(cd.properties[i].type); - - class_desc->add_text(" "); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - _add_text(cd.properties[i].name); - class_desc->pop(); //color - - class_desc->add_text(" "); - - class_desc->pop(); //font - - if (cd.properties[i].setter!="") { - - class_desc->push_font( doc_font ); - - class_desc->push_indent(2); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->add_text("Setter: "); - class_desc->pop(); - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - class_desc->add_text(cd.properties[i].setter+"(value)"); - class_desc->pop(); //color - - class_desc->pop(); //indent - - class_desc->pop(); //font - - } - - if (cd.properties[i].getter!="") { - - class_desc->push_font( doc_font ); - - class_desc->push_indent(2); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->add_text("Getter: "); - class_desc->pop(); - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - class_desc->add_text(cd.properties[i].getter+"()"); - class_desc->pop(); //color - - class_desc->pop(); //indent - - class_desc->pop(); //font - - } - - class_desc->add_newline(); - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - class_desc->push_font( doc_font ); - class_desc->push_indent(1); - _add_text(cd.properties[i].description); - class_desc->pop(); - class_desc->pop(); - class_desc->pop(); - class_desc->add_newline(); - class_desc->add_newline(); - class_desc->add_newline(); - - } - - } - - if (method_descr) { - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->push_font(doc_title_font); - class_desc->add_text(TTR("Method Description:")); - class_desc->pop(); - class_desc->pop(); - - class_desc->add_newline(); - class_desc->add_newline(); - - - for(int i=0;i<methods.size();i++) { - - method_line[methods[i].name]=class_desc->get_line_count()-2; - - class_desc->push_font(doc_code_font); - _add_type(methods[i].return_type); - - class_desc->add_text(" "); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - _add_text(methods[i].name); - class_desc->pop(); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); - class_desc->add_text(methods[i].arguments.size()?"( ":"("); - class_desc->pop(); - for(int j=0;j<methods[i].arguments.size();j++) { - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - if (j>0) - class_desc->add_text(", "); - _add_type(methods[i].arguments[j].type); - class_desc->add_text(" "); - _add_text(methods[i].arguments[j].name); - if (methods[i].arguments[j].default_value!="") { - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); - class_desc->add_text("="); - class_desc->pop(); - _add_text(methods[i].arguments[j].default_value); - } - - class_desc->pop(); - } - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color")); - class_desc->add_text(methods[i].arguments.size()?" )":")"); - class_desc->pop(); - if (methods[i].qualifiers!="") { - - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - class_desc->add_text(" "); - _add_text(methods[i].qualifiers); - class_desc->pop(); - - } - - class_desc->pop(); - - class_desc->add_newline(); - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - class_desc->push_font( doc_font ); - class_desc->push_indent(1); - _add_text(methods[i].description); - class_desc->pop(); - class_desc->pop(); - class_desc->pop(); - class_desc->add_newline(); - class_desc->add_newline(); - class_desc->add_newline(); - - } - - - - - - } - - - - scroll_locked=false; - - return OK; -} - -void EditorHelp::_request_help(const String& p_string) { - Error err = _goto_desc(p_string); - if (err==OK) { - editor->call("_editor_select",EditorNode::EDITOR_SCRIPT); - } - //100 palabras -} - - -void EditorHelp::_help_callback(const String& p_topic) { - - String what = p_topic.get_slice(":",0); - String clss = p_topic.get_slice(":",1); - String name; - if (p_topic.get_slice_count(":")==3) - name=p_topic.get_slice(":",2); - - _request_help(clss); //first go to class - - int line=0; - - if (what=="class_desc") { - line=description_line; - } else if (what=="class_signal") { - if (signal_line.has(name)) - line=signal_line[name]; - } else if (what=="class_method" || what=="class_method_desc") { - if (method_line.has(name)) - line=method_line[name]; - } else if (what=="class_property") { - - if (property_line.has(name)) - line=property_line[name]; - } else if (what=="class_theme_item") { - - if (theme_property_line.has(name)) - line=theme_property_line[name]; - } else if (what=="class_constant") { - - if (constant_line.has(name)) - line=constant_line[name]; - } - - class_desc->call_deferred("scroll_to_line", line); - -} - - - -static void _add_text_to_rt(const String& p_bbcode,RichTextLabel *p_rt) { - - DocData *doc = EditorHelp::get_doc_data(); - String base_path; - - /*p_rt->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color")); - p_rt->push_font( get_font("normal","Fonts") ); - p_rt->push_indent(1);*/ - int pos = 0; - - Ref<Font> doc_font = p_rt->get_font("doc","EditorFonts"); - Ref<Font> doc_code_font = p_rt->get_font("doc_source","EditorFonts"); - - String bbcode=p_bbcode.replace("\t"," ").replace("\r"," ").strip_edges(); - - //change newlines for double newlines - for(int i=0;i<bbcode.length();i++) { - - //find valid newlines (double) - if (bbcode[i]=='\n') { - bool dnl=false; - int j=i+1; - for(;j<p_bbcode.length();j++) { - if (bbcode[j]==' ') - continue; - if (bbcode[j]=='\n') { - dnl=true; - break; - } - break; - } - - if (dnl) { - bbcode[i]=0xFFFF; - //keep - i=j; - } else { - bbcode=bbcode.insert(i,"\n"); - i++; - //bbcode[i]=' '; - //i=j-1; - } - } - } - - //remove double spaces or spaces after newlines - for(int i=0;i<bbcode.length();i++) { - - if (bbcode[i]==' ' || bbcode[i]=='\n' || bbcode[i]==0xFFFF) { - - for(int j=i+1;j<p_bbcode.length();j++) { - if (bbcode[j]==' ') { - bbcode.remove(j); - j--; - continue; - } else { - break; - } - } - } - } - - //change newlines to double newlines - - CharType dnls[2]={0xFFFF,0}; - bbcode=bbcode.replace(dnls,"\n"); - - - List<String> tag_stack; - - while(pos < bbcode.length()) { - - - int brk_pos = bbcode.find("[",pos); - - if (brk_pos<0) - brk_pos=bbcode.length(); - - if (brk_pos > pos) { - p_rt->add_text(bbcode.substr(pos,brk_pos-pos)); - - } - - if (brk_pos==bbcode.length()) - break; //nothing else o add - - int brk_end = bbcode.find("]",brk_pos+1); - - if (brk_end==-1) { - //no close, add the rest - p_rt->add_text(bbcode.substr(brk_pos,bbcode.length()-brk_pos)); - - break; - } - - - String tag = bbcode.substr(brk_pos+1,brk_end-brk_pos-1); - - - if (tag.begins_with("/")) { - bool tag_ok = tag_stack.size() && tag_stack.front()->get()==tag.substr(1,tag.length()); - if (tag_stack.size()) { - - - - } - if (!tag_ok) { - - p_rt->add_text("["); - pos++; - continue; - } - - tag_stack.pop_front(); - pos=brk_end+1; - if (tag!="/img") - p_rt->pop(); - - } else if (tag.begins_with("method ")) { - - String m = tag.substr(7,tag.length()); - p_rt->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - p_rt->push_meta("@"+m); - p_rt->add_text(m+"()"); - p_rt->pop(); - p_rt->pop(); - pos=brk_end+1; - - } else if (doc->class_list.has(tag)) { - - - p_rt->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color")); - p_rt->push_meta("#"+tag); - p_rt->add_text(tag); - p_rt->pop(); - p_rt->pop(); - pos=brk_end+1; - - } else if (tag=="b") { - - //use bold font - p_rt->push_font(doc_code_font); - pos=brk_end+1; - tag_stack.push_front(tag); - } else if (tag=="i") { - - //use italics font - Color text_color = EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"); - //no italics so emphasize with color - text_color.r*=1.1; - text_color.g*=1.1; - text_color.b*=1.1; - p_rt->push_color(text_color); - //p_rt->push_font(get_font("italic","Fonts")); - pos=brk_end+1; - tag_stack.push_front(tag); - } else if (tag=="code" || tag=="codeblock") { - - //use monospace font - p_rt->push_font(doc_code_font); - pos=brk_end+1; - tag_stack.push_front(tag); - } else if (tag=="center") { - - //use monospace font - p_rt->push_align(RichTextLabel::ALIGN_CENTER); - pos=brk_end+1; - tag_stack.push_front(tag); - } else if (tag=="br") { - - //use monospace font - p_rt->add_newline(); - pos=brk_end+1; - } else if (tag=="u") { - - //use underline - p_rt->push_underline(); - pos=brk_end+1; - tag_stack.push_front(tag); - } else if (tag=="s") { - - //use strikethrough (not supported underline instead) - p_rt->push_underline(); - pos=brk_end+1; - tag_stack.push_front(tag); - - } else if (tag=="url") { - - //use strikethrough (not supported underline instead) - int end=bbcode.find("[",brk_end); - if (end==-1) - end=bbcode.length(); - String url = bbcode.substr(brk_end+1,end-brk_end-1); - p_rt->push_meta(url); - - pos=brk_end+1; - tag_stack.push_front(tag); - } else if (tag.begins_with("url=")) { - - String url = tag.substr(4,tag.length()); - p_rt->push_meta(url); - pos=brk_end+1; - tag_stack.push_front("url"); - } else if (tag=="img") { - - //use strikethrough (not supported underline instead) - int end=bbcode.find("[",brk_end); - if (end==-1) - end=bbcode.length(); - String image = bbcode.substr(brk_end+1,end-brk_end-1); - - Ref<Texture> texture = ResourceLoader::load(base_path+"/"+image,"Texture"); - if (texture.is_valid()) - p_rt->add_image(texture); - - pos=end; - tag_stack.push_front(tag); - } else if (tag.begins_with("color=")) { - - String col = tag.substr(6,tag.length()); - Color color; - - if (col.begins_with("#")) - color=Color::html(col); - else if (col=="aqua") - color=Color::html("#00FFFF"); - else if (col=="black") - color=Color::html("#000000"); - else if (col=="blue") - color=Color::html("#0000FF"); - else if (col=="fuchsia") - color=Color::html("#FF00FF"); - else if (col=="gray" || col=="grey") - color=Color::html("#808080"); - else if (col=="green") - color=Color::html("#008000"); - else if (col=="lime") - color=Color::html("#00FF00"); - else if (col=="maroon") - color=Color::html("#800000"); - else if (col=="navy") - color=Color::html("#000080"); - else if (col=="olive") - color=Color::html("#808000"); - else if (col=="purple") - color=Color::html("#800080"); - else if (col=="red") - color=Color::html("#FF0000"); - else if (col=="silver") - color=Color::html("#C0C0C0"); - else if (col=="teal") - color=Color::html("#008008"); - else if (col=="white") - color=Color::html("#FFFFFF"); - else if (col=="yellow") - color=Color::html("#FFFF00"); - else - color=Color(0,0,0,1); //base_color; - - - - p_rt->push_color(color); - pos=brk_end+1; - tag_stack.push_front("color"); - - } else if (tag.begins_with("font=")) { - - String fnt = tag.substr(5,tag.length()); - - - Ref<Font> font = ResourceLoader::load(base_path+"/"+fnt,"Font"); - if (font.is_valid()) - p_rt->push_font(font); - else { - p_rt->push_font(doc_font); - } - - pos=brk_end+1; - tag_stack.push_front("font"); - - - } else { - - p_rt->add_text("["); //ignore - pos=brk_pos+1; - - } - } - - /*p_rt->pop(); - p_rt->pop(); - p_rt->pop();*/ - -} - - -void EditorHelp::_add_text(const String& p_bbcode) { - - - _add_text_to_rt(p_bbcode,class_desc); - -} - - - - -void EditorHelp::_update_doc() { - - - -} - - -void EditorHelp::generate_doc() { - - doc = memnew( DocData ); - doc->generate(true); - DocData compdoc; - compdoc.load_compressed(_doc_data_compressed,_doc_data_compressed_size,_doc_data_uncompressed_size); - doc->merge_from(compdoc); //ensure all is up to date - - -} - -void EditorHelp::_notification(int p_what) { - - - switch(p_what) { - - case NOTIFICATION_READY: { - - - //forward->set_icon(get_icon("Forward","EditorIcons")); - //back->set_icon(get_icon("Back","EditorIcons")); - _update_doc(); - - } break; - } -} - -void EditorHelp::go_to_help(const String& p_help) { - - _help_callback(p_help); -} - -void EditorHelp::go_to_class(const String& p_class,int p_scroll) { - - _goto_desc(p_class,p_scroll); -} - -void EditorHelp::popup_search() { - - - search_dialog->popup_centered(Size2(250,80)); - search->grab_focus(); -} - -void EditorHelp::_search_cbk() { - - _search(search->get_text()); -} - -String EditorHelp::get_class() { - - return edited_class; -} - -void EditorHelp::search_again() { - _search(prev_search); -} - -int EditorHelp::get_scroll() const { - - return class_desc->get_v_scroll()->get_value(); -} -void EditorHelp::set_scroll(int p_scroll) { - - - class_desc->get_v_scroll()->set_value(p_scroll); - -} - -void EditorHelp::_bind_methods() { - - ClassDB::bind_method("_class_list_select",&EditorHelp::_class_list_select); - ClassDB::bind_method("_class_desc_select",&EditorHelp::_class_desc_select); - ClassDB::bind_method("_class_desc_input",&EditorHelp::_class_desc_input); - //ClassDB::bind_method("_button_pressed",&EditorHelp::_button_pressed); - ClassDB::bind_method("_scroll_changed",&EditorHelp::_scroll_changed); - ClassDB::bind_method("_request_help",&EditorHelp::_request_help); - ClassDB::bind_method("_unhandled_key_input",&EditorHelp::_unhandled_key_input); - ClassDB::bind_method("_search",&EditorHelp::_search); - ClassDB::bind_method("_search_cbk",&EditorHelp::_search_cbk); - ClassDB::bind_method("_help_callback",&EditorHelp::_help_callback); - - ADD_SIGNAL(MethodInfo("go_to_help")); - -} - -EditorHelp::EditorHelp() { - - editor=EditorNode::get_singleton(); - - VBoxContainer *vbc = this; - - EDITOR_DEF("text_editor/help/sort_functions_alphabetically",true); - - //class_list->connect("meta_clicked",this,"_class_list_select"); - //class_list->set_selection_enabled(true); - - { - Panel *pc = memnew( Panel ); - Ref<StyleBoxFlat> style( memnew( StyleBoxFlat ) ); - style->set_bg_color( EditorSettings::get_singleton()->get("text_editor/highlighting/background_color") ); - pc->set_v_size_flags(SIZE_EXPAND_FILL); - pc->add_style_override("panel", style); //get_stylebox("normal","TextEdit")); - vbc->add_child(pc); - class_desc = memnew( RichTextLabel ); - pc->add_child(class_desc); - class_desc->set_area_as_parent_rect(8); - class_desc->connect("meta_clicked",this,"_class_desc_select"); - class_desc->connect("gui_input",this,"_class_desc_input"); - } - - class_desc->get_v_scroll()->connect("value_changed",this,"_scroll_changed"); - class_desc->set_selection_enabled(true); - - scroll_locked=false; - select_locked=false; - set_process_unhandled_key_input(true); - class_desc->hide(); - - search_dialog = memnew( ConfirmationDialog ); - add_child(search_dialog); - VBoxContainer *search_vb = memnew( VBoxContainer ); - search_dialog->add_child(search_vb); - - search = memnew( LineEdit ); - search_dialog->register_text_enter(search); - search_vb->add_margin_child(TTR("Search Text"),search); - search_dialog->get_ok()->set_text(TTR("Find")); - search_dialog->connect("confirmed",this,"_search_cbk"); - search_dialog->set_hide_on_ok(false); - search_dialog->set_self_modulate(Color(1,1,1,0.8)); - - - /*class_search = memnew( EditorHelpSearch(editor) ); - editor->get_gui_base()->add_child(class_search); - class_search->connect("go_to_help",this,"_help_callback");*/ - - //prev_search_page=-1; -} - -EditorHelp::~EditorHelp() { - -} - -///////////// - - - -void EditorHelpBit::_go_to_help(String p_what) { - - EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT); - ScriptEditor::get_singleton()->goto_help(p_what); - emit_signal("request_hide"); -} - -void EditorHelpBit::_meta_clicked(String p_select) { - - //print_line("LINK: "+p_select); - if (p_select.begins_with("#")) { - //_goto_desc(p_select.substr(1,p_select.length())); - _go_to_help("class_name:"+p_select.substr(1,p_select.length())); - return; - } else if (p_select.begins_with("@")) { - - String m = p_select.substr(1,p_select.length()); - - if (m.find(".")!=-1) { - //must go somewhere else - - _go_to_help("class_method:"+m.get_slice(".",0)+":"+m.get_slice(".",0)); - } else { - /* - if (!method_line.has(m)) - return; - class_desc->scroll_to_line(method_line[m]); - */ - } - - } - - -} - -void EditorHelpBit::_bind_methods() { - - ClassDB::bind_method("_meta_clicked",&EditorHelpBit::_meta_clicked); - ADD_SIGNAL(MethodInfo("request_hide")); -} - -void EditorHelpBit::_notification(int p_what){ - - if (p_what==NOTIFICATION_ENTER_TREE) { - add_style_override("panel",get_stylebox("normal","TextEdit")); - } -} - - -void EditorHelpBit::set_text(const String& p_text) { - - rich_text->clear(); - _add_text_to_rt(p_text,rich_text); -} - -EditorHelpBit::EditorHelpBit() { - - rich_text = memnew( RichTextLabel ); - add_child(rich_text); - rich_text->set_area_as_parent_rect(8*EDSCALE); - rich_text->connect("meta_clicked",this,"_meta_clicked"); - set_custom_minimum_size(Size2(0,70*EDSCALE)); - -} diff --git a/tools/editor/editor_help.h b/tools/editor/editor_help.h deleted file mode 100644 index 3c4ba1f43e..0000000000 --- a/tools/editor/editor_help.h +++ /dev/null @@ -1,222 +0,0 @@ -/*************************************************************************/ -/* editor_help.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITOR_HELP_H -#define EDITOR_HELP_H - -#include "tools/editor/editor_plugin.h" -#include "scene/gui/tab_container.h" -#include "scene/gui/text_edit.h" -#include "scene/gui/split_container.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/rich_text_label.h" -#include "scene/gui/panel_container.h" -#include "scene/gui/tree.h" - -#include "scene/main/timer.h" -#include "tools/editor/code_editor.h" -#include "tools/editor/doc/doc_data.h" - - -class EditorNode; - -class EditorHelpSearch : public ConfirmationDialog { - - GDCLASS(EditorHelpSearch,ConfirmationDialog ) - - EditorNode *editor; - LineEdit *search_box; - Tree *search_options; - String base_type; - - void _update_search(); - - void _sbox_input(const InputEvent& p_ie); - - void _confirmed(); - void _text_changed(const String& p_newtext); - - -protected: - - void _notification(int p_what); - static void _bind_methods(); -public: - - void popup(); - void popup(const String& p_term); - - EditorHelpSearch(); -}; - -class EditorHelpIndex : public ConfirmationDialog { - GDCLASS( EditorHelpIndex, ConfirmationDialog ); - - LineEdit *search_box; - Tree *class_list; - HashMap<String,TreeItem*> tree_item_map; - - void _tree_item_selected(); - void _text_changed(const String& p_text); - void _sbox_input(const InputEvent& p_ie); - - void _update_class_list(); - - void add_type(const String& p_type,HashMap<String,TreeItem*>& p_types,TreeItem *p_root); -protected: - - void _notification(int p_what); - static void _bind_methods(); - -public: - - void select_class(const String& p_class); - - void popup(); - - EditorHelpIndex(); -}; - - -class EditorHelp : public VBoxContainer { - GDCLASS( EditorHelp, VBoxContainer ); - - - enum Page { - - PAGE_CLASS_LIST, - PAGE_CLASS_DESC, - PAGE_CLASS_PREV, - PAGE_CLASS_NEXT, - PAGE_SEARCH, - CLASS_SEARCH, - - }; - - - bool select_locked; - - String prev_search; - - String edited_class; - - EditorNode *editor; - Map<String,int> method_line; - Map<String,int> signal_line; - Map<String,int> property_line; - Map<String,int> theme_property_line; - Map<String,int> constant_line; - int description_line; - - - RichTextLabel *class_desc; - HSplitContainer *h_split; - static DocData *doc; - - - ConfirmationDialog *search_dialog; - LineEdit *search; - - - String base_path; - - - void _help_callback(const String& p_topic); - - void _add_text(const String& p_text); - bool scroll_locked; - - //void _button_pressed(int p_idx); - void _add_type(const String& p_type); - - void _scroll_changed(double p_scroll); - void _class_list_select(const String& p_select); - void _class_desc_select(const String& p_select); - void _class_desc_input(const InputEvent& p_input); - - Error _goto_desc(const String& p_class, int p_vscr=-1); - //void _update_history_buttons(); - void _update_doc(); - - void _request_help(const String& p_string); - void _search(const String& p_str); - void _search_cbk(); - - void _unhandled_key_input(const InputEvent& p_ev); - - - -protected: - - - void _notification(int p_what); - static void _bind_methods(); -public: - - static void generate_doc(); - static DocData *get_doc_data() { return doc; } - - void go_to_help(const String& p_help); - void go_to_class(const String& p_class,int p_scroll=0); - - void popup_search(); - void search_again(); - - String get_class(); - - void set_focused() { class_desc->grab_focus(); } - - int get_scroll() const; - void set_scroll(int p_scroll); - - EditorHelp(); - ~EditorHelp(); -}; - - - -class EditorHelpBit : public Panel { - - GDCLASS( EditorHelpBit, Panel); - - RichTextLabel *rich_text; - void _go_to_help(String p_what); - void _meta_clicked(String p_what); - - -protected: - - static void _bind_methods(); - void _notification(int p_what); -public: - - void set_text(const String& p_text); - EditorHelpBit(); -}; - -#endif // EDITOR_HELP_H diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h deleted file mode 100644 index 41c1012ff0..0000000000 --- a/tools/editor/editor_node.h +++ /dev/null @@ -1,833 +0,0 @@ -/*************************************************************************/ -/* editor_node.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITOR_NODE_H -#define EDITOR_NODE_H - -#include "scene/gui/control.h" -#include "scene/gui/panel.h" -#include "scene/gui/tool_button.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/tree.h" -#include "scene/gui/dialogs.h" -#include "scene/gui/separator.h" -#include "scene/gui/tab_container.h" -#include "scene/gui/panel_container.h" -#include "scene/gui/file_dialog.h" -#include "scene/gui/split_container.h" -#include "scene/gui/center_container.h" -#include "scene/gui/texture_progress.h" -#include "tools/editor/filesystem_dock.h" -#include "tools/editor/scene_tree_editor.h" -#include "tools/editor/property_editor.h" -#include "tools/editor/create_dialog.h" -#include "tools/editor/call_dialog.h" -#include "tools/editor/reparent_dialog.h" -#include "tools/editor/connections_dialog.h" -#include "tools/editor/node_dock.h" -#include "tools/editor/import_dock.h" -#include "tools/editor/settings_config_dialog.h" -#include "tools/editor/groups_editor.h" -#include "tools/editor/editor_data.h" -#include "tools/editor/editor_path.h" -#include "tools/editor/editor_run.h" - -#include "tools/editor/pane_drag.h" - -#include "tools/editor/script_create_dialog.h" -#include "tools/editor/run_settings_dialog.h" -#include "tools/editor/project_settings.h" -#include "tools/editor/project_export.h" -#include "tools/editor/editor_log.h" -#include "tools/editor/scene_tree_dock.h" -#include "tools/editor/resources_dock.h" -#include "tools/editor/editor_run_script.h" - -#include "tools/editor/editor_run_native.h" -#include "scene/gui/tabs.h" -#include "tools/editor/quick_open.h" -#include "tools/editor/project_export.h" -#include "tools/editor/editor_sub_scene.h" -#include "editor_export.h" -#include "editor_reimport_dialog.h" -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_name_dialog.h" - -#include "fileserver/editor_file_server.h" -#include "editor_resource_preview.h" -#include "scene/gui/viewport_container.h" - - -#include "progress_dialog.h" - -#include "editor_scale.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - - - - - -typedef void (*EditorNodeInitCallback)(); -typedef void (*EditorPluginInitializeCallback)(); -typedef void (*EditorBuildCallback)(); - -class EditorPluginList; - -class EditorNode : public Node { - - GDCLASS( EditorNode, Node ); - -public: - enum DockSlot { - DOCK_SLOT_LEFT_UL, - DOCK_SLOT_LEFT_BL, - DOCK_SLOT_LEFT_UR, - DOCK_SLOT_LEFT_BR, - DOCK_SLOT_RIGHT_UL, - DOCK_SLOT_RIGHT_BL, - DOCK_SLOT_RIGHT_UR, - DOCK_SLOT_RIGHT_BR, - DOCK_SLOT_MAX - }; -private: - enum { - HISTORY_SIZE=64 - }; - - enum MenuOptions { - FILE_NEW_SCENE, - FILE_NEW_INHERITED_SCENE, - FILE_OPEN_SCENE, - FILE_SAVE_SCENE, - FILE_SAVE_AS_SCENE, - FILE_SAVE_ALL_SCENES, - FILE_SAVE_BEFORE_RUN, - FILE_SAVE_AND_RUN, - FILE_IMPORT_SUBSCENE, - FILE_EXPORT_PROJECT, - FILE_EXPORT_MESH_LIBRARY, - FILE_EXPORT_TILESET, - FILE_SAVE_OPTIMIZED, - FILE_OPEN_RECENT, - FILE_OPEN_OLD_SCENE, - FILE_QUICK_OPEN_SCENE, - FILE_QUICK_OPEN_SCRIPT, - FILE_RUN_SCRIPT, - FILE_OPEN_PREV, - FILE_CLOSE, - FILE_QUIT, - FILE_EXTERNAL_OPEN_SCENE, - EDIT_UNDO, - EDIT_REDO, - EDIT_REVERT, - TOOLS_ORPHAN_RESOURCES, - RESOURCE_NEW, - RESOURCE_LOAD, - RESOURCE_SAVE, - RESOURCE_SAVE_AS, - RESOURCE_UNREF, - RESOURCE_COPY, - RESOURCE_PASTE, - OBJECT_COPY_PARAMS, - OBJECT_PASTE_PARAMS, - OBJECT_UNIQUE_RESOURCES, - OBJECT_REQUEST_HELP, - RUN_PLAY, - - RUN_STOP, - RUN_PLAY_SCENE, - RUN_PLAY_NATIVE, - RUN_PLAY_CUSTOM_SCENE, - RUN_SCENE_SETTINGS, - RUN_SETTINGS, - RUN_PROJECT_MANAGER, - RUN_FILE_SERVER, - //RUN_DEPLOY_DUMB_CLIENTS, - RUN_LIVE_DEBUG, - RUN_DEBUG_COLLISONS, - RUN_DEBUG_NAVIGATION, - RUN_DEPLOY_REMOTE_DEBUG, - RUN_RELOAD_SCRIPTS, - SETTINGS_UPDATE_ALWAYS, - SETTINGS_UPDATE_CHANGES, - SETTINGS_UPDATE_SPINNER_HIDE, - SETTINGS_EXPORT_PREFERENCES, - SETTINGS_PREFERENCES, - SETTINGS_OPTIMIZED_PRESETS, - SETTINGS_LAYOUT_SAVE, - SETTINGS_LAYOUT_DELETE, - SETTINGS_LAYOUT_DEFAULT, - SETTINGS_LOAD_EXPORT_TEMPLATES, - SETTINGS_PICK_MAIN_SCENE, - SETTINGS_TOGGLE_FULLSCREN, - SETTINGS_HELP, - SETTINGS_ABOUT, - SOURCES_REIMPORT, - DEPENDENCY_LOAD_CHANGED_IMAGES, - DEPENDENCY_UPDATE_IMPORTED, - SCENE_TAB_CLOSE, - - IMPORT_PLUGIN_BASE=100, - - OBJECT_METHOD_BASE=500, - - TOOL_MENU_BASE=1000 - }; - - - - //Node *edited_scene; //scene being edited - Viewport *scene_root; //root of the scene being edited - - //Ref<ResourceImportMetadata> scene_import_metadata; - - PanelContainer* scene_root_parent; - Control *gui_base; - VBoxContainer *main_vbox; - - //split - - HSplitContainer *left_l_hsplit; - VSplitContainer *left_l_vsplit; - HSplitContainer *left_r_hsplit; - VSplitContainer *left_r_vsplit; - HSplitContainer *main_hsplit; - HSplitContainer *right_hsplit; - VSplitContainer *right_l_vsplit; - VSplitContainer *right_r_vsplit; - - VSplitContainer *center_split; - - //main tabs - - Tabs *scene_tabs; - int tab_closing; - - bool exiting; - - int old_split_ofs; - VSplitContainer *top_split; - HBoxContainer *bottom_hb; - Control *vp_base; - PaneDrag *pd; - //PaneDrag *pd_anim; - Panel *menu_panel; - - - //HSplitContainer *editor_hsplit; - //VSplitContainer *editor_vsplit; - CenterContainer *play_cc; - HBoxContainer *menu_hb; - Control *viewport; - MenuButton *file_menu; - MenuButton *import_menu; - MenuButton *tool_menu; - ToolButton *export_button; - ToolButton *prev_scene; - MenuButton *object_menu; - MenuButton *settings_menu; - ToolButton *play_button; - MenuButton *native_play_button; - ToolButton *pause_button; - ToolButton *stop_button; - ToolButton *run_settings_button; - ToolButton *play_scene_button; - ToolButton *play_custom_scene_button; - MenuButton *debug_button; - ToolButton *search_button; - TextureProgress *audio_vu; - //MenuButton *fileserver_menu; - - RichTextLabel *load_errors; - AcceptDialog *load_error_dialog; - - //Control *scene_root_base; - Ref<Theme> theme; - - PopupMenu *recent_scenes; - Button *property_back; - Button *property_forward; - SceneTreeDock *scene_tree_dock; - //ResourcesDock *resources_dock; - PropertyEditor *property_editor; - NodeDock *node_dock; - ImportDock *import_dock; - VBoxContainer *prop_editor_vb; - FileSystemDock *filesystem_dock; - EditorRunNative *run_native; - - HBoxContainer *search_bar; - LineEdit *search_box; - - CreateDialog *create_dialog; - - //CallDialog *call_dialog; - ConfirmationDialog *confirmation; - ConfirmationDialog *import_confirmation; - ConfirmationDialog *open_recent_confirmation; - ConfirmationDialog *pick_main_scene; - AcceptDialog *accept; - AcceptDialog *about; - AcceptDialog *warning; - - int overridden_default_layout; - Ref<ConfigFile> default_layout; - PopupMenu *editor_layouts; - EditorNameDialog *layout_dialog; - - //OptimizedPresetsDialog *optimized_presets; - EditorSettingsDialog *settings_config_dialog; - RunSettingsDialog *run_settings_dialog; - ProjectSettings *project_settings; - EditorFileDialog *file; - FileDialog *file_templates; - FileDialog *file_export; - FileDialog *file_export_lib; - FileDialog *file_script; - CheckButton *file_export_lib_merge; - LineEdit *file_export_password; - String current_path; - MenuButton *update_menu; - ToolButton *sources_button; - //TabContainer *prop_pallete; - //TabContainer *top_pallete; - String defer_load_scene; - String defer_export; - String defer_export_platform; - bool defer_export_debug; - Node *_last_instanced_scene; - EditorPath *editor_path; - ToolButton *resource_new_button; - ToolButton *resource_load_button; - MenuButton *resource_save_button; - MenuButton *editor_history_menu; - - EditorLog *log; - CenterContainer *tabs_center; - EditorQuickOpen *quick_open; - EditorQuickOpen *quick_run; - - HBoxContainer *main_editor_button_vb; - Vector<ToolButton*> main_editor_buttons; - Vector<EditorPlugin*> editor_table; - -// EditorReImportDialog *reimport_dialog; - - ProgressDialog *progress_dialog; - BackgroundProgress *progress_hb; - - DependencyErrorDialog *dependency_error; - DependencyEditor *dependency_fixer; - OrphanResourcesDialog *orphan_resources; - ConfirmationDialog *open_imported; - Button *new_inherited_button; - String open_import_request; - - - TabContainer *dock_slot[DOCK_SLOT_MAX]; - Rect2 dock_select_rect[DOCK_SLOT_MAX]; - int dock_select_rect_over; - PopupPanel *dock_select_popoup; - Control *dock_select; - ToolButton *dock_tab_move_left; - ToolButton *dock_tab_move_right; - int dock_popup_selected; - Timer *dock_drag_timer; - bool docks_visible; - ToolButton *distraction_free; - - String _tmp_import_path; - - EditorExport *editor_export; - - Object *current; - - bool _playing_edited; - String run_custom_filename; - bool reference_resource_mem; - bool save_external_resources_mem; - uint64_t saved_version; - uint64_t last_checked_version; - bool unsaved_cache; - String open_navigate; - bool changing_scene; - bool waiting_for_first_scan; - - bool waiting_for_sources_changed; - - uint32_t circle_step_msec; - uint64_t circle_step_frame; - int circle_step; - - Vector<EditorPlugin*> editor_plugins; - EditorPlugin *editor_plugin_screen; - EditorPluginList *editor_plugins_over; - - EditorHistory editor_history; - EditorData editor_data; - EditorRun editor_run; - EditorSelection *editor_selection; -// ProjectExport *project_export; - ProjectExportDialog *project_export; - EditorResourcePreview *resource_preview; - - EditorFileServer *file_server; - - - struct BottomPanelItem { - String name; - Control *control; - ToolButton *button; - }; - - Vector<BottomPanelItem> bottom_panel_items; - - PanelContainer *bottom_panel; - HBoxContainer *bottom_panel_hb; - VBoxContainer *bottom_panel_vb; - - void _bottom_panel_switch(bool p_enable, int p_idx); - - String external_file; - List<String> previous_scenes; - bool opening_prev; - - void _dialog_action(String p_file); - - - void _edit_current(); - void _dialog_display_file_error(String p_file,Error p_error); - - int current_option; - //void _animation_visibility_toggle(); - void _resource_created(); - void _resource_selected(const RES& p_res,const String& p_property=""); - void _menu_option(int p_option); - void _menu_confirm_current(); - void _menu_option_confirm(int p_option,bool p_confirmed); - void _update_debug_options(); - - void _property_editor_forward(); - void _property_editor_back(); - - void _select_history(int p_idx); - void _prepare_history(); - - - void _fs_changed(); - void _sources_changed(bool p_exist); - void _imported(Node *p_node); - - void _node_renamed(); - void _editor_select(int p_which); - void _set_scene_metadata(const String &p_file, int p_idx=-1); - void _get_scene_metadata(const String& p_file); - void _update_title(); - void _update_scene_tabs(); - void _close_messages(); - void _show_messages(); - void _vp_resized(); - - void _rebuild_import_menu(); - - void _save_scene(String p_file, int idx = -1); - - - void _instance_request(const Vector<String>& p_files); - - void _property_keyed(const String& p_keyed, const Variant& p_value, bool p_advance); - void _transform_keyed(Object *sp,const String& p_sub,const Transform& p_key); - - void _hide_top_editors(); - void _display_top_editors(bool p_display); - void _set_top_editors(Vector<EditorPlugin*> p_editor_plugins_over); - void _set_editing_top_editors(Object * p_current_object); - - void _quick_opened(); - void _quick_run(); - - void _run(bool p_current=false, const String &p_custom=""); - - void _save_optimized(); - void _import_action(const String& p_action); - void _import(const String &p_file); - void _add_to_recent_scenes(const String& p_scene); - void _update_recent_scenes(); - void _open_recent_scene(int p_idx); - void _dropped_files(const Vector<String>& p_files,int p_screen); - //void _open_recent_scene_confirm(); - String _recent_scene; - - bool convert_old; - - void _unhandled_input(const InputEvent& p_event); - - static void _load_error_notify(void* p_ud,const String& p_text); - - bool has_main_screen() const { return true; } - - bool _find_editing_changed_scene(Node *p_from); - - String import_reload_fn; - - Set<FileDialog*> file_dialogs; - Set<EditorFileDialog*> editor_file_dialogs; - - Map<String,Ref<Texture> > icon_type_cache; - - bool _initializing_addons; - Map<String,EditorPlugin*> plugin_addons; - - - static Ref<Texture> _file_dialog_get_icon(const String& p_path); - static void _file_dialog_register(FileDialog *p_dialog); - static void _file_dialog_unregister(FileDialog *p_dialog); - static void _editor_file_dialog_register(EditorFileDialog *p_dialog); - static void _editor_file_dialog_unregister(EditorFileDialog *p_dialog); - - - void _cleanup_scene(); - void _remove_edited_scene(); - void _remove_scene(int index); - bool _find_and_save_resource(RES p_res,Map<RES,bool>& processed,int32_t flags); - bool _find_and_save_edited_subresources(Object *obj,Map<RES,bool>& processed,int32_t flags); - void _save_edited_subresources(Node* scene,Map<RES,bool>& processed,int32_t flags); - - void _find_node_types(Node* p_node, int&count_2d, int&count_3d); - void _save_scene_with_preview(String p_file); - - - Map<String,Set<String> > dependency_errors; - - static void _dependency_error_report(void *ud,const String& p_path,const String& p_dep,const String& p_type) { - EditorNode*en=(EditorNode*)ud; - if (!en->dependency_errors.has(p_path)) - en->dependency_errors[p_path]=Set<String>(); - en->dependency_errors[p_path].insert(p_dep+"::"+p_type); - - } - - struct ExportDefer { - String platform; - String path; - bool debug; - String password; - - } export_defer; - - static EditorNode *singleton; - - static Vector<EditorNodeInitCallback> _init_callbacks; - - bool _find_scene_in_use(Node* p_node,const String& p_path) const; - - void _dock_select_input(const InputEvent& p_input); - void _dock_move_left(); - void _dock_move_right(); - void _dock_select_draw(); - void _dock_pre_popup(int p_which); - void _dock_split_dragged(int ofs); - void _dock_popup_exit(); - void _scene_tab_changed(int p_tab); - void _scene_tab_closed(int p_tab); - void _scene_tab_script_edited(int p_tab); - - Dictionary _get_main_scene_state(); - void _set_main_scene_state(Dictionary p_state,Node* p_for_scene); - - int _get_current_main_editor(); - - void _save_docks(); - void _load_docks(); - void _save_docks_to_config(Ref<ConfigFile> p_layout, const String& p_section); - void _load_docks_from_config(Ref<ConfigFile> p_layout, const String& p_section); - void _update_dock_slots_visibility(); - void _update_top_menu_visibility(); - - void _update_layouts_menu(); - void _layout_menu_option(int p_idx); - - void _toggle_search_bar(bool p_pressed); - void _clear_search_box(); - void _clear_undo_history(); - - void _update_addon_config(); - - static void _file_access_close_error_notify(const String& p_str); - - void _toggle_distraction_free_mode(); - - enum { - MAX_INIT_CALLBACKS=128, - MAX_BUILD_CALLBACKS=128 - }; - - void _inherit_imported(const String &p_action); - void _open_imported(); - - - static int plugin_init_callback_count; - static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS]; - - void _call_build(); - static int build_callback_count; - static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS]; - - bool _initializing_tool_menu; - - struct ToolMenuItem { - String name; - String submenu; - Variant ud; - ObjectID handler; - String callback; - }; - - Vector<ToolMenuItem> tool_menu_items; - - void _tool_menu_insert_item(const ToolMenuItem& p_item); - void _rebuild_tool_menu() const; - -protected: - void _notification(int p_what); - static void _bind_methods(); -public: - - static void add_plugin_init_callback(EditorPluginInitializeCallback p_callback); - - enum EditorTable { - EDITOR_2D = 0, - EDITOR_3D, - EDITOR_SCRIPT - }; - - void set_visible_editor(EditorTable p_table) { _editor_select(p_table); } - static EditorNode* get_singleton() { return singleton; } - - - EditorPlugin *get_editor_plugin_screen() { return editor_plugin_screen; } - EditorPluginList *get_editor_plugins_over() { return editor_plugins_over; } - PropertyEditor *get_property_editor() { return property_editor; } - VBoxContainer *get_property_editor_vb() { return prop_editor_vb; } - - static void add_editor_plugin(EditorPlugin *p_editor); - static void remove_editor_plugin(EditorPlugin *p_editor); - - void new_inherited_scene() { _menu_option_confirm(FILE_NEW_INHERITED_SCENE,false); } - - - void set_docks_visible(bool p_show); - bool get_docks_visible() const; - - void set_distraction_free_mode(bool p_enter); - bool get_distraction_free_mode() const; - - void add_control_to_dock(DockSlot p_slot,Control* p_control); - void remove_control_from_dock(Control* p_control); - - void set_addon_plugin_enabled(const String& p_addon,bool p_enabled); - bool is_addon_plugin_enabled(const String &p_addon) const; - - void edit_node(Node *p_node); - void edit_resource(const Ref<Resource>& p_resource); - void open_resource(const String& p_type=""); - - void save_resource_in_path(const Ref<Resource>& p_resource,const String& p_path); - void save_resource(const Ref<Resource>& p_resource); - void save_resource_as(const Ref<Resource>& p_resource, const String &p_at_path=String()); - - void merge_from_scene() { _menu_option_confirm(FILE_IMPORT_SUBSCENE,false); } - - static bool has_unsaved_changes() { return singleton->unsaved_cache; } - - static HBoxContainer *get_menu_hb() { return singleton->menu_hb; } - - void push_item(Object *p_object,const String& p_property=""); - - void open_request(const String& p_path); - - bool is_changing_scene() const; - - - static EditorLog *get_log() { return singleton->log; } - Control* get_viewport(); - - //void animation_editor_make_visible(bool p_visible); - //void hide_animation_player_editors(); - //void animation_panel_make_visible(bool p_visible); - - void set_edited_scene(Node *p_scene); - - Node *get_edited_scene() { return editor_data.get_edited_scene_root(); } - - Viewport *get_scene_root() { return scene_root; } //root of the scene being edited - - void fix_dependencies(const String& p_for_file); - void clear_scene() { _cleanup_scene(); } - Error load_scene(const String& p_scene, bool p_ignore_broken_deps=false, bool p_set_inherited=false, bool p_clear_errors=true,bool p_force_open_imported=false); - Error load_resource(const String& p_scene); - - bool is_scene_open(const String& p_path); - - void set_current_version(uint64_t p_version); - void set_current_scene(int p_idx); - - static EditorData& get_editor_data() { return singleton->editor_data; } - EditorHistory * get_editor_history() { return &editor_history; } - - static VSplitContainer *get_top_split() { return singleton->top_split; } - - void request_instance_scene(const String &p_path); - void request_instance_scenes(const Vector<String>& p_files); - FileSystemDock *get_filesystem_dock(); - ImportDock *get_import_dock(); - SceneTreeDock *get_scene_tree_dock(); - static UndoRedo* get_undo_redo() { return &singleton->editor_data.get_undo_redo(); } - - EditorSelection *get_editor_selection() { return editor_selection; } - - void set_convert_old_scene(bool p_old) { convert_old=p_old; } - - void notify_child_process_exited(); - - OS::ProcessID get_child_process_id() const { return editor_run.get_pid(); } - void stop_child_process(); - - Ref<Theme> get_editor_theme() const { return theme; } - - - void show_warning(const String& p_text,const String& p_title="Warning!"); - - - Error export_platform(const String& p_platform, const String& p_path, bool p_debug,const String& p_password,bool p_quit_after=false); - - static void register_editor_types(); - static void unregister_editor_types(); - - Control *get_gui_base() { return gui_base; } - Control *get_theme_base() { return gui_base->get_parent_control(); } - - static void add_io_error(const String& p_error); - - static void progress_add_task(const String& p_task,const String& p_label, int p_steps); - static void progress_task_step(const String& p_task,const String& p_state, int p_step=-1,bool p_force_refresh=true); - static void progress_end_task(const String& p_task); - - static void progress_add_task_bg(const String& p_task,const String& p_label, int p_steps); - static void progress_task_step_bg(const String& p_task,int p_step=-1); - static void progress_end_task_bg(const String& p_task); - - void save_scene(String p_file) { _save_scene(p_file); } - - bool is_scene_in_use(const String& p_path); - - void scan_import_changes(); - - void save_layout(); - - void update_keying(); - - void reload_scene(const String& p_path); - - bool is_exiting() const { return exiting; } - - ToolButton *get_pause_button() { return pause_button; } - - - ToolButton* add_bottom_panel_item(String p_text,Control *p_item); - bool are_bottom_panels_hidden() const; - void make_bottom_panel_item_visible(Control *p_item); - void raise_bottom_panel_item(Control *p_item); - void hide_bottom_panel(); - void remove_bottom_panel_item(Control *p_item); - - Variant drag_resource(const Ref<Resource>& p_res,Control* p_from); - Variant drag_files(const Vector<String>& p_files,Control* p_from); - Variant drag_files_and_dirs(const Vector<String>& p_files,Control* p_from); - - void add_tool_menu_item(const String& p_name, Object *p_handler, const String& p_callback, const Variant& p_ud = Variant()); - void add_tool_submenu_item(const String& p_name, PopupMenu *p_submenu); - void remove_tool_menu_item(const String& p_name); - - EditorNode(); - ~EditorNode(); - void get_singleton(const char* arg1, bool arg2); - - static void add_init_callback(EditorNodeInitCallback p_callback) { _init_callbacks.push_back(p_callback); } - static void add_build_callback(EditorBuildCallback p_callback); - - - -}; - -struct EditorProgress { - - String task; - void step(const String& p_state, int p_step=-1,bool p_force_refresh=true) { EditorNode::progress_task_step(task,p_state,p_step,p_force_refresh); } - EditorProgress(const String& p_task,const String& p_label,int p_amount) { EditorNode::progress_add_task(p_task,p_label,p_amount); task=p_task; } - ~EditorProgress() { EditorNode::progress_end_task(task); } -}; - -class EditorPluginList : public Object { -private: - Vector<EditorPlugin*> plugins_list; - -public: - - void set_plugins_list(Vector<EditorPlugin*> p_plugins_list) { - plugins_list = p_plugins_list; - } - - Vector<EditorPlugin*>& get_plugins_list() { - return plugins_list; - } - - void make_visible(bool p_visible); - void edit(Object *p_object); - bool forward_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event); - bool forward_spatial_gui_input(Camera* p_camera, const InputEvent& p_event); - void forward_draw_over_canvas(const Transform2D& p_canvas_xform,Control* p_canvas); - void clear(); - bool empty(); - - EditorPluginList(); - ~EditorPluginList(); - -} ; - -struct EditorProgressBG { - - String task; - void step(int p_step=-1) { EditorNode::progress_task_step_bg(task,p_step); } - EditorProgressBG(const String& p_task,const String& p_label,int p_amount) { EditorNode::progress_add_task_bg(p_task,p_label,p_amount); task=p_task; } - ~EditorProgressBG() { EditorNode::progress_end_task_bg(task); } -}; - -#endif diff --git a/tools/editor/editor_plugin.cpp b/tools/editor/editor_plugin.cpp deleted file mode 100644 index 2a0efa5be9..0000000000 --- a/tools/editor/editor_plugin.cpp +++ /dev/null @@ -1,432 +0,0 @@ -/*************************************************************************/ -/* editor_plugin.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 "editor_plugin.h" - -#include "scene/gui/popup_menu.h" -#include "scene/3d/camera.h" -#include "plugins/canvas_item_editor_plugin.h" -#include "plugins/spatial_editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "tools/editor/editor_settings.h" -#include "editor_resource_preview.h" - -void EditorPlugin::add_custom_type(const String& p_type, const String& p_base,const Ref<Script>& p_script, const Ref<Texture>& p_icon) { - - EditorNode::get_editor_data().add_custom_type(p_type,p_base,p_script,p_icon); -} - -void EditorPlugin::remove_custom_type(const String& p_type){ - - EditorNode::get_editor_data().remove_custom_type(p_type); -} - - -ToolButton * EditorPlugin::add_control_to_bottom_panel(Control *p_control, const String &p_title) { - - return EditorNode::get_singleton()->add_bottom_panel_item(p_title,p_control); -} - -void EditorPlugin::add_control_to_dock(DockSlot p_slot,Control *p_control) { - - ERR_FAIL_NULL(p_control); - EditorNode::get_singleton()->add_control_to_dock(EditorNode::DockSlot(p_slot),p_control); - -} - -void EditorPlugin::remove_control_from_docks(Control *p_control) { - - ERR_FAIL_NULL(p_control); - EditorNode::get_singleton()->remove_control_from_dock(p_control); - -} - -void EditorPlugin::remove_control_from_bottom_panel(Control *p_control) { - - ERR_FAIL_NULL(p_control); - EditorNode::get_singleton()->remove_bottom_panel_item(p_control); - -} - -Control * EditorPlugin::get_editor_viewport() { - - return EditorNode::get_singleton()->get_viewport(); -} - -void EditorPlugin::edit_resource(const Ref<Resource>& p_resource){ - - EditorNode::get_singleton()->edit_resource(p_resource); -} - -void EditorPlugin::add_control_to_container(CustomControlContainer p_location,Control *p_control) { - - switch(p_location) { - - case CONTAINER_TOOLBAR: { - - EditorNode::get_menu_hb()->add_child(p_control); - } break; - - case CONTAINER_SPATIAL_EDITOR_MENU: { - - SpatialEditor::get_singleton()->add_control_to_menu_panel(p_control); - - } break; - case CONTAINER_SPATIAL_EDITOR_SIDE: { - - SpatialEditor::get_singleton()->get_palette_split()->add_child(p_control); - SpatialEditor::get_singleton()->get_palette_split()->move_child(p_control,0); - - } break; - case CONTAINER_SPATIAL_EDITOR_BOTTOM: { - - SpatialEditor::get_singleton()->get_shader_split()->add_child(p_control); - - } break; - case CONTAINER_CANVAS_EDITOR_MENU: { - - CanvasItemEditor::get_singleton()->add_control_to_menu_panel(p_control); - - } break; - case CONTAINER_CANVAS_EDITOR_SIDE: { - - CanvasItemEditor::get_singleton()->get_palette_split()->add_child(p_control); - CanvasItemEditor::get_singleton()->get_palette_split()->move_child(p_control,0); - - } break; - case CONTAINER_CANVAS_EDITOR_BOTTOM: { - - CanvasItemEditor::get_singleton()->get_bottom_split()->add_child(p_control); - - } break; - case CONTAINER_PROPERTY_EDITOR_BOTTOM: { - - EditorNode::get_singleton()->get_property_editor_vb()->add_child(p_control); - - } break; - - - } -} - -void EditorPlugin::add_tool_menu_item(const String& p_name, Object *p_handler, const String& p_callback, const Variant& p_ud) { - - //EditorNode::get_singleton()->add_tool_menu_item(p_name, p_handler, p_callback, p_ud); -} - -void EditorPlugin::add_tool_submenu_item(const String& p_name, Object *p_submenu) { - - ERR_FAIL_NULL(p_submenu); - PopupMenu *submenu = p_submenu->cast_to<PopupMenu>(); - ERR_FAIL_NULL(submenu); - //EditorNode::get_singleton()->add_tool_submenu_item(p_name, submenu); -} - -void EditorPlugin::remove_tool_menu_item(const String& p_name) { - - //EditorNode::get_singleton()->remove_tool_menu_item(p_name); -} - -Ref<SpatialEditorGizmo> EditorPlugin::create_spatial_gizmo(Spatial* p_spatial) { - //?? - if (get_script_instance() && get_script_instance()->has_method("create_spatial_gizmo")) { - return get_script_instance()->call("create_spatial_gizmo",p_spatial); - } - - return Ref<SpatialEditorGizmo>(); -} - -bool EditorPlugin::forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { - - if (get_script_instance() && get_script_instance()->has_method("forward_canvas_gui_input")) { - return get_script_instance()->call("forward_canvas_gui_input",p_canvas_xform,p_event); - } - return false; -} - -void EditorPlugin::forward_draw_over_canvas(const Transform2D& p_canvas_xform,Control *p_canvas) { - - if (get_script_instance() && get_script_instance()->has_method("forward_draw_over_canvas")) { - get_script_instance()->call("forward_draw_over_canvas",p_canvas_xform,p_canvas); - } -} - -void EditorPlugin::update_canvas() { - CanvasItemEditor::get_singleton()->get_viewport_control()->update(); -} - -bool EditorPlugin::forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event) { - - if (get_script_instance() && get_script_instance()->has_method("forward_spatial_gui_input")) { - return get_script_instance()->call("forward_spatial_gui_input",p_camera,p_event); - } - - return false; -} -String EditorPlugin::get_name() const { - - if (get_script_instance() && get_script_instance()->has_method("get_name")) { - return get_script_instance()->call("get_name"); - } - - return String(); - -} -bool EditorPlugin::has_main_screen() const { - - if (get_script_instance() && get_script_instance()->has_method("has_main_screen")) { - return get_script_instance()->call("has_main_screen"); - } - - return false; - -} -void EditorPlugin::make_visible(bool p_visible) { - - if (get_script_instance() && get_script_instance()->has_method("make_visible")) { - get_script_instance()->call("make_visible",p_visible); - } -} - - -void EditorPlugin::edit(Object *p_object) { - - if (get_script_instance() && get_script_instance()->has_method("edit")) { - get_script_instance()->call("edit",p_object); - } - -} - -bool EditorPlugin::handles(Object *p_object) const { - - if (get_script_instance() && get_script_instance()->has_method("handles")) { - return get_script_instance()->call("handles",p_object); - } - - return false; -} -Dictionary EditorPlugin::get_state() const { - - if (get_script_instance() && get_script_instance()->has_method("get_state")) { - return get_script_instance()->call("get_state"); - } - - return Dictionary(); -} - -void EditorPlugin::set_state(const Dictionary& p_state) { - - if (get_script_instance() && get_script_instance()->has_method("set_state")) { - get_script_instance()->call("set_state",p_state); - } -} - -void EditorPlugin::clear() { - - if (get_script_instance() && get_script_instance()->has_method("clear")) { - get_script_instance()->call("clear"); - } - -} - -// if editor references external resources/scenes, save them -void EditorPlugin::save_external_data() { - - if (get_script_instance() && get_script_instance()->has_method("save_external_data")) { - get_script_instance()->call("save_external_data"); - } -} - -// if changes are pending in editor, apply them -void EditorPlugin::apply_changes() { - - if (get_script_instance() && get_script_instance()->has_method("apply_changes")) { - get_script_instance()->call("apply_changes"); - } -} - -void EditorPlugin::get_breakpoints(List<String> *p_breakpoints) { - - if (get_script_instance() && get_script_instance()->has_method("get_breakpoints")) { - PoolStringArray arr = get_script_instance()->call("get_breakpoints"); - for(int i=0;i<arr.size();i++) - p_breakpoints->push_back(arr[i]); - } - -} -bool EditorPlugin::get_remove_list(List<Node*> *p_list) { - - return false; -} - -void EditorPlugin::restore_global_state() {} -void EditorPlugin::save_global_state() {} - -void EditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) { - - if (get_script_instance() && get_script_instance()->has_method("set_window_layout")) { - get_script_instance()->call("set_window_layout", p_layout); - } -} - -void EditorPlugin::get_window_layout(Ref<ConfigFile> p_layout){ - - if (get_script_instance() && get_script_instance()->has_method("get_window_layout")) { - get_script_instance()->call("get_window_layout", p_layout); - } -} - -void EditorPlugin::queue_save_layout() const { - - EditorNode::get_singleton()->save_layout(); -} - -EditorSelection* EditorPlugin::get_selection() { - return EditorNode::get_singleton()->get_editor_selection(); -} - - -EditorSettings *EditorPlugin::get_editor_settings() { - return EditorSettings::get_singleton(); -} - -EditorResourcePreview *EditorPlugin::get_resource_previewer() { - return EditorResourcePreview::get_singleton(); -} - -Control *EditorPlugin::get_base_control() { - - return EditorNode::get_singleton()->get_gui_base(); -} - -void EditorPlugin::make_bottom_panel_item_visible(Control * p_item) { - - EditorNode::get_singleton()->make_bottom_panel_item_visible(p_item); -} - -void EditorPlugin::hide_bottom_panel() { - - EditorNode::get_singleton()->hide_bottom_panel(); -} - -void EditorPlugin::inspect_object(Object *p_obj,const String& p_for_property) { - - EditorNode::get_singleton()->push_item(p_obj,p_for_property); -} - -EditorFileSystem *EditorPlugin::get_resource_file_system() { - return EditorFileSystem::get_singleton(); -} - -void EditorPlugin::_bind_methods() { - - ClassDB::bind_method(D_METHOD("add_control_to_container","container","control:Control"),&EditorPlugin::add_control_to_container); - ClassDB::bind_method(D_METHOD("add_control_to_bottom_panel:ToolButton","control:Control","title"),&EditorPlugin::add_control_to_bottom_panel); - ClassDB::bind_method(D_METHOD("add_control_to_dock","slot","control:Control"),&EditorPlugin::add_control_to_dock); - ClassDB::bind_method(D_METHOD("remove_control_from_docks","control:Control"),&EditorPlugin::remove_control_from_docks); - ClassDB::bind_method(D_METHOD("remove_control_from_bottom_panel","control:Control"),&EditorPlugin::remove_control_from_bottom_panel); - //ClassDB::bind_method(D_METHOD("add_tool_menu_item", "name", "handler", "callback", "ud"),&EditorPlugin::add_tool_menu_item,DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("add_tool_submenu_item", "name", "submenu:PopupMenu"),&EditorPlugin::add_tool_submenu_item); - //ClassDB::bind_method(D_METHOD("remove_tool_menu_item", "name"),&EditorPlugin::remove_tool_menu_item); - ClassDB::bind_method(D_METHOD("add_custom_type","type","base","script:Script","icon:Texture"),&EditorPlugin::add_custom_type); - ClassDB::bind_method(D_METHOD("remove_custom_type","type"),&EditorPlugin::remove_custom_type); - ClassDB::bind_method(D_METHOD("get_editor_viewport:Control"), &EditorPlugin::get_editor_viewport); - - ClassDB::bind_method(D_METHOD("get_resource_previewer:EditorResourcePreview"),&EditorPlugin::get_resource_previewer); - ClassDB::bind_method(D_METHOD("get_resource_filesystem:EditorFileSystem"),&EditorPlugin::get_resource_file_system); - - ClassDB::bind_method(D_METHOD("inspect_object","object","for_property"),&EditorPlugin::inspect_object,DEFVAL(String())); - ClassDB::bind_method(D_METHOD("update_canvas"),&EditorPlugin::update_canvas); - - ClassDB::bind_method(D_METHOD("make_bottom_panel_item_visible","item:Control"), &EditorPlugin::make_bottom_panel_item_visible); - ClassDB::bind_method(D_METHOD("hide_bottom_panel"), &EditorPlugin::hide_bottom_panel); - - ClassDB::bind_method(D_METHOD("get_base_control:Control"),&EditorPlugin::get_base_control); - ClassDB::bind_method(D_METHOD("get_undo_redo:UndoRedo"),&EditorPlugin::_get_undo_redo); - ClassDB::bind_method(D_METHOD("get_selection:EditorSelection"),&EditorPlugin::get_selection); - ClassDB::bind_method(D_METHOD("get_editor_settings:EditorSettings"),&EditorPlugin::get_editor_settings); - ClassDB::bind_method(D_METHOD("queue_save_layout"),&EditorPlugin::queue_save_layout); - ClassDB::bind_method(D_METHOD("edit_resource"),&EditorPlugin::edit_resource); - - ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::BOOL,"forward_canvas_gui_input",PropertyInfo(Variant::TRANSFORM2D,"canvas_xform"),PropertyInfo(Variant::INPUT_EVENT,"event"))); - ClassDB::add_virtual_method(get_class_static(),MethodInfo("forward_draw_over_canvas",PropertyInfo(Variant::TRANSFORM2D,"canvas_xform"),PropertyInfo(Variant::OBJECT,"canvas:Control"))); - ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::BOOL,"forward_spatial_gui_input",PropertyInfo(Variant::OBJECT,"camera",PROPERTY_HINT_RESOURCE_TYPE,"Camera"),PropertyInfo(Variant::INPUT_EVENT,"event"))); - MethodInfo gizmo = MethodInfo(Variant::OBJECT,"create_spatial_gizmo",PropertyInfo(Variant::OBJECT,"for_spatial:Spatial")); - gizmo.return_val.hint=PROPERTY_HINT_RESOURCE_TYPE; - gizmo.return_val.hint_string="EditorSpatialGizmo"; - ClassDB::add_virtual_method(get_class_static(),gizmo); - ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::STRING,"get_name")); - ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::BOOL,"has_main_screen")); - ClassDB::add_virtual_method(get_class_static(),MethodInfo("make_visible",PropertyInfo(Variant::BOOL,"visible"))); - ClassDB::add_virtual_method(get_class_static(),MethodInfo("edit",PropertyInfo(Variant::OBJECT,"object"))); - ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::BOOL,"handles",PropertyInfo(Variant::OBJECT,"object"))); - ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::DICTIONARY,"get_state")); - ClassDB::add_virtual_method(get_class_static(),MethodInfo("set_state",PropertyInfo(Variant::DICTIONARY,"state"))); - ClassDB::add_virtual_method(get_class_static(),MethodInfo("clear")); - ClassDB::add_virtual_method(get_class_static(),MethodInfo("save_external_data")); - ClassDB::add_virtual_method(get_class_static(),MethodInfo("apply_changes")); - ClassDB::add_virtual_method(get_class_static(),MethodInfo(Variant::POOL_STRING_ARRAY,"get_breakpoints")); - ClassDB::add_virtual_method(get_class_static(),MethodInfo("set_window_layout",PropertyInfo(Variant::OBJECT,"layout",PROPERTY_HINT_RESOURCE_TYPE,"ConfigFile"))); - ClassDB::add_virtual_method(get_class_static(),MethodInfo("get_window_layout",PropertyInfo(Variant::OBJECT,"layout",PROPERTY_HINT_RESOURCE_TYPE,"ConfigFile"))); - - BIND_CONSTANT( CONTAINER_TOOLBAR ); - BIND_CONSTANT( CONTAINER_SPATIAL_EDITOR_MENU ); - BIND_CONSTANT( CONTAINER_SPATIAL_EDITOR_SIDE ); - BIND_CONSTANT( CONTAINER_SPATIAL_EDITOR_BOTTOM ); - BIND_CONSTANT( CONTAINER_CANVAS_EDITOR_MENU ); - BIND_CONSTANT( CONTAINER_CANVAS_EDITOR_SIDE ); - BIND_CONSTANT( CONTAINER_PROPERTY_EDITOR_BOTTOM ); - - - BIND_CONSTANT( DOCK_SLOT_LEFT_UL ); - BIND_CONSTANT( DOCK_SLOT_LEFT_BL ); - BIND_CONSTANT( DOCK_SLOT_LEFT_UR ); - BIND_CONSTANT( DOCK_SLOT_LEFT_BR ); - BIND_CONSTANT( DOCK_SLOT_RIGHT_UL ); - BIND_CONSTANT( DOCK_SLOT_RIGHT_BL ); - BIND_CONSTANT( DOCK_SLOT_RIGHT_UR ); - BIND_CONSTANT( DOCK_SLOT_RIGHT_BR ); - BIND_CONSTANT( DOCK_SLOT_MAX ); - -} - -EditorPlugin::EditorPlugin() -{ - undo_redo=NULL; -} - - -EditorPlugin::~EditorPlugin() -{ -} - - - -EditorPluginCreateFunc EditorPlugins::creation_funcs[MAX_CREATE_FUNCS]; - -int EditorPlugins::creation_func_count=0; diff --git a/tools/editor/editor_sub_scene.h b/tools/editor/editor_sub_scene.h deleted file mode 100644 index cc9faffc77..0000000000 --- a/tools/editor/editor_sub_scene.h +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************/ -/* editor_sub_scene.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITOR_SUB_SCENE_H -#define EDITOR_SUB_SCENE_H - -#include "scene/gui/dialogs.h" -#include "scene/gui/tree.h" -#include "tools/editor/editor_file_dialog.h" - -class EditorSubScene : public ConfirmationDialog { - - GDCLASS(EditorSubScene,ConfirmationDialog); - - - LineEdit *path; - Tree *tree; - Node *scene; - - EditorFileDialog *file_dialog; - - void _fill_tree(Node* p_node,TreeItem *p_parent); - void _reown(Node* p_node,List<Node*> *p_to_reown); - - void ok_pressed(); - - -protected: - - - void _notification(int p_what); - static void _bind_methods(); - void _path_browse(); - void _path_selected(const String& p_path); - void _path_changed(const String& p_path); - -public: - - void move(Node* p_new_parent, Node* p_new_owner); - void clear(); - EditorSubScene(); -}; - -#endif // EDITOR_SUB_SCENE_H diff --git a/tools/editor/icons/SCsub b/tools/editor/icons/SCsub deleted file mode 100644 index 4af481d1f6..0000000000 --- a/tools/editor/icons/SCsub +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python - -Import('env') - - -def make_editor_icons_action(target, source, env): - - import os - import cStringIO - - dst = target[0].srcnode().abspath - pixmaps = source - - s = cStringIO.StringIO() - - s.write("#include \"editor_icons.h\"\n\n") - s.write("#include \"editor_scale.h\"\n\n") - s.write("#include \"scene/resources/theme.h\"\n\n") - - hidpi_list = [] - - for x in pixmaps: - - x = str(x) - var_str = os.path.basename(x)[:-4] + "_png" - # print(var_str) - - s.write("static const unsigned char " + var_str + "[]={\n") - - pngf = open(x, "rb") - - b = pngf.read(1) - while(len(b) == 1): - s.write(hex(ord(b))) - b = pngf.read(1) - if (len(b) == 1): - s.write(",") - - s.write("\n};\n\n") - - pngf.close() - var_str = os.path.basename(x)[:-4] + "_hidpi_png" - try: - - pngf = open(os.path.dirname(x) + "/2x/" + os.path.basename(x), "rb") - - s.write("static const unsigned char " + var_str + "[]={\n") - - b = pngf.read(1) - while(len(b) == 1): - s.write(hex(ord(b))) - b = pngf.read(1) - if (len(b) == 1): - s.write(",") - - s.write("\n};\n\n\n") - hidpi_list.append(x) - - except: - s.write("static const unsigned char* " + var_str + "=NULL;\n\n\n") - - s.write("static Ref<ImageTexture> make_icon(const uint8_t* p_png,const uint8_t* p_hidpi_png) {\n") - s.write("\tRef<ImageTexture> texture( memnew( ImageTexture ) );\n") - s.write("\tbool use_hidpi_image=(editor_get_scale()>1.0&&p_hidpi_png);\n") - s.write("\tImage img(use_hidpi_image?p_hidpi_png:p_png);\n") - s.write("\tif (editor_get_scale()>1.0 && !p_hidpi_png) { img.convert(Image::FORMAT_RGBA8); img.expand_x2_hq2x(); use_hidpi_image=true;}\n") - s.write("\timg.resize(img.get_width()*EDSCALE/(use_hidpi_image?2:1),img.get_height()*EDSCALE/(use_hidpi_image?2:1));\n") - s.write("\ttexture->create_from_image( img,ImageTexture::FLAG_FILTER );\n") - s.write("\treturn texture;\n") - s.write("}\n\n") - - s.write("void editor_register_icons(Ref<Theme> p_theme) {\n\n") - - for x in pixmaps: - - x = os.path.basename(str(x)) - type = x[5:-4].title().replace("_", "") - var_str = x[:-4] + "_png" - var_str_hidpi = x[:-4] + "_hidpi_png" - s.write("\tp_theme->set_icon(\"" + type + "\",\"EditorIcons\",make_icon(" + var_str + "," + var_str_hidpi + "));\n") - - s.write("\n\n}\n\n") - - f = open(dst, "wb") - f.write(s.getvalue()) - f.close() - s.close() - -make_editor_icons_builder = Builder(action=make_editor_icons_action, - suffix='.cpp', - src_suffix='.png') -env['BUILDERS']['MakeEditorIconsBuilder'] = make_editor_icons_builder -env.Alias('editor_icons', [env.MakeEditorIconsBuilder('#tools/editor/editor_icons.cpp', Glob("*.png"))]) - -env.editor_sources.append("#tools/editor/editor_icons.cpp") -Export('env') diff --git a/tools/editor/import/editor_import_collada.cpp b/tools/editor/import/editor_import_collada.cpp deleted file mode 100644 index a901de1faf..0000000000 --- a/tools/editor/import/editor_import_collada.cpp +++ /dev/null @@ -1,2508 +0,0 @@ -/*************************************************************************/ -/* editor_import_collada.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 "editor_import_collada.h" - - -#include "scene/3d/spatial.h" -#include "scene/3d/skeleton.h" -#include "scene/3d/path.h" -#include "scene/3d/camera.h" -#include "scene/3d/light.h" -#include "scene/animation/animation_player.h" -#include "scene/3d/mesh_instance.h" -#include "scene/resources/animation.h" -#include "scene/resources/packed_scene.h" -#include "os/os.h" -#include "tools/editor/collada/collada.h" -#include "tools/editor/editor_node.h" -#include <iostream> - - -struct ColladaImport { - - Collada collada; - Spatial *scene; - - Vector<Ref<Animation> > animations; - - struct NodeMap { - //String path; - Spatial *node; - int bone; - List<int> anim_tracks; - - NodeMap() { node=NULL; bone=-1; } - }; - - bool found_ambient; - Color ambient; - bool found_directional; - bool force_make_tangents; - bool apply_mesh_xform_to_vertices; - bool use_mesh_builtin_materials; - float bake_fps; - - - - Map<String,NodeMap> node_map; //map from collada node to engine node - Map<String,String> node_name_map; //map from collada node to engine node - Map<String, Ref<Mesh> > mesh_cache; - Map<String, Ref<Curve3D> > curve_cache; - Map<String, Ref<Material> > material_cache; - Map<Collada::Node*,Skeleton*> skeleton_map; - - Map< Skeleton*, Map< String, int> > skeleton_bone_map; - - Set<String> valid_animated_nodes; - Vector<int> valid_animated_properties; - Map<String,bool> bones_with_animation; - - Error _populate_skeleton(Skeleton *p_skeleton,Collada::Node *p_node, int &r_bone, int p_parent); - Error _create_scene_skeletons(Collada::Node *p_node); - Error _create_scene(Collada::Node *p_node, Spatial *p_parent); - Error _create_resources(Collada::Node *p_node); - Error _create_material(const String& p_material); - Error _create_mesh_surfaces(bool p_optimize, Ref<Mesh>& p_mesh, const Map<String,Collada::NodeGeometry::Material>& p_material_map, const Collada::MeshData &meshdata, const Transform& p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_data, const Collada::MorphControllerData *p_morph_data, Vector<Ref<Mesh> > p_morph_meshes=Vector<Ref<Mesh> >(), bool p_for_morph=false, bool p_use_mesh_material=false); - Error load(const String& p_path, int p_flags, bool p_force_make_tangents=false); - void _fix_param_animation_tracks(); - void create_animation(int p_clip,bool p_make_tracks_in_all_bones, bool p_import_value_tracks); - void create_animations(bool p_make_tracks_in_all_bones, bool p_import_value_tracks); - - Set<String> tracks_in_clips; - Vector<String> missing_textures; - - void _pre_process_lights(Collada::Node *p_node); - - ColladaImport() { - - found_ambient=false; - found_directional=false; - force_make_tangents=false; - apply_mesh_xform_to_vertices=true; - bake_fps=15; - - } -}; - - -Error ColladaImport::_populate_skeleton(Skeleton *p_skeleton,Collada::Node *p_node, int &r_bone, int p_parent) { - - - if (p_node->type!=Collada::Node::TYPE_JOINT) - return OK; - - Collada::NodeJoint *joint = static_cast<Collada::NodeJoint*>(p_node); - - print_line("populating joint "+joint->name); - p_skeleton->add_bone(p_node->name); - if (p_parent>=0) - p_skeleton->set_bone_parent(r_bone,p_parent); - - NodeMap nm; - nm.node=p_skeleton; - nm.bone = r_bone; - node_map[p_node->id]=nm; - node_name_map[p_node->name]=p_node->id; - - skeleton_bone_map[p_skeleton][joint->sid]=r_bone; - - if (collada.state.bone_rest_map.has(joint->sid)) { - - p_skeleton->set_bone_rest(r_bone,collada.fix_transform(collada.state.bone_rest_map[joint->sid])); - //should map this bone to something for animation? - } else { - print_line("no rest: "+joint->sid); - WARN_PRINT("Joint has no rest.."); - } - - - int id = r_bone++; - for(int i=0;i<p_node->children.size();i++) { - - Error err = _populate_skeleton(p_skeleton,p_node->children[i],r_bone,id); - if (err) - return err; - } - - return OK; -} - - -void ColladaImport::_pre_process_lights(Collada::Node *p_node) { - - - if (p_node->type==Collada::Node::TYPE_LIGHT) { - - - Collada::NodeLight *light=static_cast<Collada::NodeLight*>(p_node); - if (collada.state.light_data_map.has(light->light)) { - - Collada::LightData &ld = collada.state.light_data_map[light->light]; - if (ld.mode==Collada::LightData::MODE_AMBIENT) { - found_ambient=true; - ambient=ld.color; - } - if (ld.mode==Collada::LightData::MODE_DIRECTIONAL) { - found_directional=true; - } - } - - } - - - for(int i=0;i<p_node->children.size();i++) - _pre_process_lights(p_node->children[i]); -} - -Error ColladaImport::_create_scene_skeletons(Collada::Node *p_node) { - - - if (p_node->type==Collada::Node::TYPE_SKELETON) { - - Skeleton *sk = memnew( Skeleton ); - int bone = 0; - - for(int i=0;i<p_node->children.size();i++) { - - _populate_skeleton(sk,p_node->children[i],bone,-1); - } - sk->localize_rests(); //after creating skeleton, rests must be localized...! - skeleton_map[p_node]=sk; - } - - - for(int i=0;i<p_node->children.size();i++) { - - Error err = _create_scene_skeletons(p_node->children[i]); - if (err) - return err; - } - return OK; - -} - - -Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) { - - Spatial * node=NULL; - - switch(p_node->type) { - - case Collada::Node::TYPE_NODE: { - - node = memnew( Spatial ); - } break; - case Collada::Node::TYPE_JOINT: { - - return OK; // do nothing - } break; - case Collada::Node::TYPE_LIGHT: { - - //node = memnew( Light) - Collada::NodeLight *light = static_cast<Collada::NodeLight*>(p_node); - if (collada.state.light_data_map.has(light->light)) { - - Collada::LightData &ld = collada.state.light_data_map[light->light]; - - if (ld.mode==Collada::LightData::MODE_AMBIENT) { - - if (found_directional) - return OK; //do nothing not needed - - if (!bool(GLOBAL_DEF("collada/use_ambient",false))) - return OK; - //well, it's an ambient light.. - Light *l = memnew( DirectionalLight ); - //l->set_color(Light::COLOR_AMBIENT,ld.color); - //l->set_color(Light::COLOR_DIFFUSE,Color(0,0,0)); - //l->set_color(Light::COLOR_SPECULAR,Color(0,0,0)); - node = l; - - } else if (ld.mode==Collada::LightData::MODE_DIRECTIONAL) { - - //well, it's an ambient light.. - Light *l = memnew( DirectionalLight ); - /* - if (found_ambient) //use it here - l->set_color(Light::COLOR_AMBIENT,ambient); - - l->set_color(Light::COLOR_DIFFUSE,ld.color); - l->set_color(Light::COLOR_SPECULAR,Color(1,1,1)); - */ - node = l; - } else { - - Light *l; - - if (ld.mode==Collada::LightData::MODE_OMNI) - l=memnew( OmniLight ); - else { - l=memnew( SpotLight ); - //l->set_parameter(Light::PARAM_SPOT_ANGLE,ld.spot_angle); - //l->set_parameter(Light::PARAM_SPOT_ATTENUATION,ld.spot_exp); - } - - // - //l->set_color(Light::COLOR_DIFFUSE,ld.color); - //l->set_color(Light::COLOR_SPECULAR,Color(1,1,1)); - //l->approximate_opengl_attenuation(ld.constant_att,ld.linear_att,ld.quad_att); - node=l; - } - - } else { - - node = memnew( Spatial ); - } - } break; - case Collada::Node::TYPE_CAMERA: { - - Collada::NodeCamera *cam = static_cast<Collada::NodeCamera*>(p_node); - Camera *camera = memnew( Camera ); - - if (collada.state.camera_data_map.has(cam->camera)) { - - const Collada::CameraData &cd = collada.state.camera_data_map[cam->camera]; - - switch(cd.mode) { - - case Collada::CameraData::MODE_ORTHOGONAL: { - - if (cd.orthogonal.y_mag) { - - camera->set_keep_aspect_mode(Camera::KEEP_HEIGHT); - camera->set_orthogonal(cd.orthogonal.y_mag*2.0 ,cd.z_near,cd.z_far); - - } else if (!cd.orthogonal.y_mag && cd.orthogonal.x_mag) { - - - camera->set_keep_aspect_mode(Camera::KEEP_WIDTH); - camera->set_orthogonal(cd.orthogonal.x_mag*2.0,cd.z_near,cd.z_far); - } - - } break; - case Collada::CameraData::MODE_PERSPECTIVE: { - - if (cd.perspective.y_fov) { - - camera->set_perspective(cd.perspective.y_fov,cd.z_near,cd.z_far); - - } else if (!cd.perspective.y_fov && cd.perspective.x_fov) { - - camera->set_perspective(cd.perspective.x_fov / cd.aspect,cd.z_near,cd.z_far); - } - - } break; - } - - } - - node=camera; - - } break; - case Collada::Node::TYPE_GEOMETRY: { - - Collada::NodeGeometry *ng = static_cast<Collada::NodeGeometry*>(p_node); - - if (collada.state.curve_data_map.has(ng->source)) { - - node = memnew( Path ); - } else { - //mesh since nothing else - node = memnew( MeshInstance ); - node->cast_to<MeshInstance>()->set_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT,true); - } - } break; - case Collada::Node::TYPE_SKELETON: { - - ERR_FAIL_COND_V(!skeleton_map.has(p_node),ERR_CANT_CREATE); - Skeleton *sk = skeleton_map[p_node]; - node=sk; - } break; - - } - - if (p_node->name!="") - node->set_name(p_node->name); - NodeMap nm; - nm.node=node; - node_map[p_node->id]=nm; - node_name_map[p_node->name]=p_node->id; - Transform xf = p_node->default_transform; - - xf = collada.fix_transform( xf ) * p_node->post_transform; - node->set_transform(xf); - p_parent->add_child(node); - node->set_owner(scene); - - if (p_node->empty_draw_type!="") { - node->set_meta("empty_draw_type", Variant(p_node->empty_draw_type)); - } - - for(int i=0;i<p_node->children.size();i++) { - - Error err = _create_scene(p_node->children[i],node); - if (err) - return err; - } - return OK; -} - - -Error ColladaImport::_create_material(const String& p_target) { - - ERR_FAIL_COND_V(material_cache.has(p_target),ERR_ALREADY_EXISTS); - ERR_FAIL_COND_V(!collada.state.material_map.has(p_target),ERR_INVALID_PARAMETER); - Collada::Material &src_mat=collada.state.material_map[p_target]; - ERR_FAIL_COND_V(!collada.state.effect_map.has(src_mat.instance_effect),ERR_INVALID_PARAMETER); - Collada::Effect &effect=collada.state.effect_map[src_mat.instance_effect]; - - Ref<FixedSpatialMaterial> material= memnew( FixedSpatialMaterial ); - - if (src_mat.name!="") - material->set_name(src_mat.name); - else if (effect.name!="") - material->set_name(effect.name); - - // DIFFUSE - - if (effect.diffuse.texture!="") { - - String texfile = effect.get_texture_path(effect.diffuse.texture,collada); - if (texfile!="") { - - Ref<Texture> texture = ResourceLoader::load(texfile,"Texture"); - if (texture.is_valid()) { - - material->set_texture(FixedSpatialMaterial::TEXTURE_ALBEDO,texture); - material->set_albedo(Color(1,1,1,1)); - //material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1,1)); - } else { - missing_textures.push_back(texfile.get_file()); - } - } - } else { - //material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,effect.diffuse.color); - } - - // SPECULAR - - if (effect.specular.texture!="") { - - String texfile = effect.get_texture_path(effect.specular.texture,collada); - if (texfile!="") { - - Ref<Texture> texture = ResourceLoader::load(texfile,"Texture"); - if (texture.is_valid()) { - material->set_texture(FixedSpatialMaterial::TEXTURE_SPECULAR,texture); - material->set_specular(Color(1,1,1,1)); - - //material->set_texture(FixedSpatialMaterial::PARAM_SPECULAR,texture); - //material->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR,Color(1,1,1,1)); - } else { - missing_textures.push_back(texfile.get_file()); - } - - } - } else { - material->set_metalness(effect.specular.color.get_v()); - } - - - // EMISSION - - if (effect.emission.texture!="") { - - String texfile = effect.get_texture_path(effect.emission.texture,collada); - if (texfile!="") { - - Ref<Texture> texture = ResourceLoader::load(texfile,"Texture"); - if (texture.is_valid()) { - - material->set_feature(FixedSpatialMaterial::FEATURE_EMISSION,true); - material->set_texture(FixedSpatialMaterial::TEXTURE_EMISSION,texture); - material->set_emission(Color(1,1,1,1)); - - //material->set_parameter(FixedSpatialMaterial::PARAM_EMISSION,Color(1,1,1,1)); - }else { - missing_textures.push_back(texfile.get_file()); - } - - } - } else { - if (effect.emission.color!=Color()) { - material->set_feature(FixedSpatialMaterial::FEATURE_EMISSION,true); - material->set_emission(effect.emission.color); - } - } - - // NORMAL - - if (effect.bump.texture!="") { - - String texfile = effect.get_texture_path(effect.bump.texture,collada); - if (texfile!="") { - - Ref<Texture> texture = ResourceLoader::load(texfile,"Texture"); - if (texture.is_valid()) { - material->set_feature(FixedSpatialMaterial::FEATURE_NORMAL_MAPPING,true); - material->set_texture(FixedSpatialMaterial::TEXTURE_NORMAL,texture); - //material->set_emission(Color(1,1,1,1)); - - //material->set_texture(FixedSpatialMaterial::PARAM_NORMAL,texture); - }else { - //missing_textures.push_back(texfile.get_file()); - } - - } - } - - - float roughness = Math::sqrt(1.0-((Math::log(effect.shininess)/Math::log(2.0))/8.0)); //not very right.. - material->set_roughness(roughness); - - if (effect.double_sided) { - material->set_cull_mode(FixedSpatialMaterial::CULL_DISABLED); - } - material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED,effect.unshaded); - - - - material_cache[p_target]=material; - return OK; -} - - -static void _generate_normals(const PoolVector<int>& p_indices,const PoolVector<Vector3>& p_vertices,PoolVector<Vector3>&r_normals) { - - - r_normals.resize(p_vertices.size()); - PoolVector<Vector3>::Write narrayw = r_normals.write(); - - int iacount=p_indices.size()/3; - PoolVector<int>::Read index_arrayr = p_indices.read(); - PoolVector<Vector3>::Read vertex_arrayr = p_vertices.read(); - - for(int idx=0;idx<iacount;idx++) { - - Vector3 v[3]={ - vertex_arrayr[index_arrayr[idx*3+0]], - vertex_arrayr[index_arrayr[idx*3+1]], - vertex_arrayr[index_arrayr[idx*3+2]] - }; - - Vector3 normal = Plane(v[0],v[1],v[2]).normal; - - narrayw[index_arrayr[idx*3+0]]+=normal; - narrayw[index_arrayr[idx*3+1]]+=normal; - narrayw[index_arrayr[idx*3+2]]+=normal; - } - - int vlen=p_vertices.size(); - - for(int idx=0;idx<vlen;idx++) { - narrayw[idx].normalize(); - } - -} - - -static void _generate_tangents_and_binormals(const PoolVector<int>& p_indices,const PoolVector<Vector3>& p_vertices,const PoolVector<Vector3>& p_uvs,const PoolVector<Vector3>& p_normals,PoolVector<real_t>&r_tangents) { - - int vlen=p_vertices.size(); - - Vector<Vector3> tangents; - tangents.resize(vlen); - Vector<Vector3> binormals; - binormals.resize(vlen); - - - int iacount=p_indices.size()/3; - - PoolVector<int>::Read index_arrayr = p_indices.read(); - PoolVector<Vector3>::Read vertex_arrayr = p_vertices.read(); - PoolVector<Vector3>::Read narrayr = p_normals.read(); - PoolVector<Vector3>::Read uvarrayr = p_uvs.read(); - - - for(int idx=0;idx<iacount;idx++) { - - - Vector3 v1 = vertex_arrayr[ index_arrayr[idx*3+0] ]; - Vector3 v2 = vertex_arrayr[ index_arrayr[idx*3+1] ]; - Vector3 v3 = vertex_arrayr[ index_arrayr[idx*3+2] ]; - - Vector3 w1 = uvarrayr[ index_arrayr[idx*3+0] ]; - Vector3 w2 = uvarrayr[ index_arrayr[idx*3+1] ]; - Vector3 w3 = uvarrayr[ index_arrayr[idx*3+2] ]; - - real_t x1 = v2.x - v1.x; - real_t x2 = v3.x - v1.x; - real_t y1 = v2.y - v1.y; - real_t y2 = v3.y - v1.y; - real_t z1 = v2.z - v1.z; - real_t z2 = v3.z - v1.z; - - real_t s1 = w2.x - w1.x; - real_t s2 = w3.x - w1.x; - real_t t1 = w2.y - w1.y; - real_t t2 = w3.y - w1.y; - - real_t r = (s1 * t2 - s2 * t1); - - Vector3 tangent; - Vector3 binormal; - - if (r==0) { - - binormal=Vector3(); - tangent=Vector3(); - } else { - tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, - (t2 * z1 - t1 * z2) * r).normalized(); - binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, - (s1 * z2 - s2 * z1) * r).normalized(); - } - - tangents[ index_arrayr[idx*3+0] ]+=tangent; - binormals[ index_arrayr[idx*3+0] ]+=binormal; - tangents[ index_arrayr[idx*3+1] ]+=tangent; - binormals[ index_arrayr[idx*3+1] ]+=binormal; - tangents[ index_arrayr[idx*3+2] ]+=tangent; - binormals[ index_arrayr[idx*3+2] ]+=binormal; - - //print_line(itos(idx)+" tangent: "+tangent); - //print_line(itos(idx)+" binormal: "+binormal); - } - - r_tangents.resize(vlen*4); - PoolVector<real_t>::Write tarrayw = r_tangents.write(); - - for(int idx=0;idx<vlen;idx++) { - Vector3 tangent = tangents[idx]; - Vector3 bingen = narrayr[idx].cross(tangent); - float dir; - if (bingen.dot(binormals[idx]) < 0 ) - dir=-1.0; - else - dir=+1.0; - - tarrayw[idx*4+0]=tangent.x; - tarrayw[idx*4+1]=tangent.y; - tarrayw[idx*4+2]=tangent.z; - tarrayw[idx*4+3]=dir; - } -} - -Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,const Map<String,Collada::NodeGeometry::Material>& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector<int> &bone_remap, const Collada::SkinControllerData *skin_controller, const Collada::MorphControllerData *p_morph_data,Vector<Ref<Mesh> > p_morph_meshes,bool p_for_morph,bool p_use_mesh_material) { - - - bool local_xform_mirror=p_local_xform.basis.determinant() < 0; - - if (p_morph_data) { - - //add morphie target - ERR_FAIL_COND_V( !p_morph_data->targets.has("MORPH_TARGET"), ERR_INVALID_DATA ); - String mt = p_morph_data->targets["MORPH_TARGET"]; - ERR_FAIL_COND_V( !p_morph_data->sources.has(mt), ERR_INVALID_DATA); - int morph_targets = p_morph_data->sources[mt].sarray.size(); - for(int i=0;i<morph_targets;i++) { - - String target = p_morph_data->sources[mt].sarray[i]; - ERR_FAIL_COND_V( !collada.state.mesh_data_map.has(target), ERR_INVALID_DATA ); - String name = collada.state.mesh_data_map[target].name; - - p_mesh->add_blend_shape(name); - } - if (p_morph_data->mode=="RELATIVE") - p_mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_RELATIVE); - else if (p_morph_data->mode=="NORMALIZED") - p_mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED); - } - - - int surface=0; - for(int p_i = 0; p_i < meshdata.primitives.size(); p_i ++ ) { - - - - const Collada::MeshData::Primitives& p = meshdata.primitives[p_i]; - - /* VERTEX SOURCE */ - ERR_FAIL_COND_V(!p.sources.has("VERTEX"),ERR_INVALID_DATA); - - String vertex_src_id = p.sources["VERTEX"].source; - int vertex_ofs=p.sources["VERTEX"].offset; - - ERR_FAIL_COND_V(!meshdata.vertices.has(vertex_src_id),ERR_INVALID_DATA); - - ERR_FAIL_COND_V(!meshdata.vertices[vertex_src_id].sources.has("POSITION"),ERR_INVALID_DATA); - String position_src_id = meshdata.vertices[vertex_src_id].sources["POSITION"]; - - ERR_FAIL_COND_V(!meshdata.sources.has(position_src_id),ERR_INVALID_DATA); - - const Collada::MeshData::Source *vertex_src=&meshdata.sources[position_src_id]; - - /* NORMAL SOURCE */ - - const Collada::MeshData::Source *normal_src=NULL; - int normal_ofs=0; - - if (p.sources.has("NORMAL")) { - - String normal_source_id = p.sources["NORMAL"].source; - normal_ofs = p.sources["NORMAL"].offset; - ERR_FAIL_COND_V( !meshdata.sources.has(normal_source_id),ERR_INVALID_DATA); - normal_src=&meshdata.sources[normal_source_id]; - } - - const Collada::MeshData::Source *binormal_src=NULL; - int binormal_ofs=0; - - if (p.sources.has("TEXBINORMAL")) { - - String binormal_source_id = p.sources["TEXBINORMAL"].source; - binormal_ofs = p.sources["TEXBINORMAL"].offset; - ERR_FAIL_COND_V( !meshdata.sources.has(binormal_source_id),ERR_INVALID_DATA); - binormal_src=&meshdata.sources[binormal_source_id]; - } - - const Collada::MeshData::Source *tangent_src=NULL; - int tangent_ofs=0; - - if (p.sources.has("TEXTANGENT")) { - - String tangent_source_id = p.sources["TEXTANGENT"].source; - tangent_ofs = p.sources["TEXTANGENT"].offset; - ERR_FAIL_COND_V( !meshdata.sources.has(tangent_source_id),ERR_INVALID_DATA); - tangent_src=&meshdata.sources[tangent_source_id]; - } - - - const Collada::MeshData::Source *uv_src=NULL; - int uv_ofs=0; - - if (p.sources.has("TEXCOORD0")) { - - String uv_source_id = p.sources["TEXCOORD0"].source; - uv_ofs = p.sources["TEXCOORD0"].offset; - ERR_FAIL_COND_V( !meshdata.sources.has(uv_source_id),ERR_INVALID_DATA); - uv_src=&meshdata.sources[uv_source_id]; - } - - const Collada::MeshData::Source *uv2_src=NULL; - int uv2_ofs=0; - - if (p.sources.has("TEXCOORD1")) { - - String uv2_source_id = p.sources["TEXCOORD1"].source; - uv2_ofs = p.sources["TEXCOORD1"].offset; - ERR_FAIL_COND_V( !meshdata.sources.has(uv2_source_id),ERR_INVALID_DATA); - uv2_src=&meshdata.sources[uv2_source_id]; - } - - - const Collada::MeshData::Source *color_src=NULL; - int color_ofs=0; - - if (p.sources.has("COLOR")) { - - String color_source_id = p.sources["COLOR"].source; - color_ofs = p.sources["COLOR"].offset; - ERR_FAIL_COND_V( !meshdata.sources.has(color_source_id), ERR_INVALID_DATA ); - color_src=&meshdata.sources[color_source_id]; - } - - //find largest source.. - - /************************/ - /* ADD WEIGHTS IF EXIST */ - /************************/ - - Map<int,Vector<Collada::Vertex::Weight> > pre_weights; - - bool has_weights=false; - - if (skin_controller) { - - const Collada::SkinControllerData::Source *weight_src=NULL; - int weight_ofs=0; - - if (skin_controller->weights.sources.has("WEIGHT")) { - - String weight_id = skin_controller->weights.sources["WEIGHT"].source; - weight_ofs = skin_controller->weights.sources["WEIGHT"].offset; - if (skin_controller->sources.has(weight_id)) { - - weight_src = &skin_controller->sources[weight_id]; - - } - } - - int joint_ofs=0; - - if (skin_controller->weights.sources.has("JOINT")) { - - joint_ofs = skin_controller->weights.sources["JOINT"].offset; - } - - //should be OK, given this was pre-checked. - - int index_ofs=0; - int wstride = skin_controller->weights.sources.size(); - for(int w_i=0;w_i<skin_controller->weights.sets.size();w_i++) { - - int amount = skin_controller->weights.sets[w_i]; - - Vector<Collada::Vertex::Weight> weights; - - for (int a_i=0;a_i<amount;a_i++) { - - Collada::Vertex::Weight w; - - int read_from = index_ofs+a_i*wstride; - ERR_FAIL_INDEX_V(read_from+wstride-1,skin_controller->weights.indices.size(),ERR_INVALID_DATA); - int weight_index = skin_controller->weights.indices[read_from+weight_ofs]; - ERR_FAIL_INDEX_V(weight_index,weight_src->array.size(),ERR_INVALID_DATA); - - w.weight = weight_src->array[weight_index]; - - int bone_index = skin_controller->weights.indices[read_from+joint_ofs]; - if (bone_index==-1) - continue; //ignore this weight (refers to bind shape) - ERR_FAIL_INDEX_V(bone_index,bone_remap.size(),ERR_INVALID_DATA); - - w.bone_idx=bone_remap[bone_index]; - - - weights.push_back(w); - } - - /* FIX WEIGHTS */ - - - - weights.sort(); - - if (weights.size()>4) { - //cap to 4 and make weights add up 1 - weights.resize(4); - - } - - //make sure weights allways add up to 1 - float total=0; - for(int i=0;i<weights.size();i++) - total+=weights[i].weight; - if (total) - for(int i=0;i<weights.size();i++) - weights[i].weight/=total; - - if (weights.size()==0 || total==0) { //if nothing, add a weight to bone 0 - //no weights assigned - Collada::Vertex::Weight w; - w.bone_idx=0; - w.weight=1.0; - weights.clear(); - weights.push_back(w); - - } - - pre_weights[w_i]=weights; - - /* - for(Set<int>::Element *E=vertex_map[w_i].front();E;E=E->next()) { - - int dst = E->get(); - ERR_EXPLAIN("invalid vertex index in array"); - ERR_FAIL_INDEX_V(dst,vertex_array.size(),ERR_INVALID_DATA); - vertex_array[dst].weights=weights; - - }*/ - - - - - index_ofs+=wstride*amount; - - } - - //vertices need to be localized - has_weights=true; - - } - - Set<Collada::Vertex> vertex_set; //vertex set will be the vertices - List<int> indices_list; //indices will be the indices - //Map<int,Set<int> > vertex_map; //map vertices (for setting skinning/morph) - - /**************************/ - /* CREATE PRIMITIVE ARRAY */ - /**************************/ - - // The way collada uses indices is more optimal, and friendlier with 3D modelling sofware, - // because it can index everything, not only vertices (similar to how the WII works). - // This is, however, more incompatible with standard video cards, so arrays must be converted. - // Must convert to GL/DX format. - - int _prim_ofs=0; - int vertidx=0; - for(int p_i=0;p_i<p.count;p_i++) { - - - int amount; - if (p.polygons.size()) { - - ERR_FAIL_INDEX_V(p_i,p.polygons.size(),ERR_INVALID_DATA); - amount=p.polygons[p_i]; - } else { - amount=3; //triangles; - } - - //COLLADA_PRINT("amount: "+itos(amount)); - - int prev2[2]={0,0}; - - for(int j=0;j<amount;j++) { - - int src=_prim_ofs; - //_prim_ofs+=p.sources.size() - - ERR_FAIL_INDEX_V(src,p.indices.size(),ERR_INVALID_DATA); - - Collada::Vertex vertex; - if (!p_optimize) - vertex.uid=vertidx++; - - - - int vertex_index=p.indices[src+vertex_ofs]; //used for index field (later used by controllers) - int vertex_pos = (vertex_src->stride?vertex_src->stride:3) * vertex_index; - ERR_FAIL_INDEX_V(vertex_pos,vertex_src->array.size(),ERR_INVALID_DATA); - vertex.vertex=Vector3(vertex_src->array[vertex_pos+0],vertex_src->array[vertex_pos+1],vertex_src->array[vertex_pos+2]); - - if (pre_weights.has(vertex_index)) { - vertex.weights=pre_weights[vertex_index]; - } - - if (normal_src) { - - - - int normal_pos = (normal_src->stride?normal_src->stride:3) * p.indices[src+normal_ofs]; - ERR_FAIL_INDEX_V(normal_pos,normal_src->array.size(),ERR_INVALID_DATA); - vertex.normal=Vector3(normal_src->array[normal_pos+0],normal_src->array[normal_pos+1],normal_src->array[normal_pos+2]); - vertex.normal=vertex.normal.snapped(0.001); - - - if (tangent_src && binormal_src) { - - int binormal_pos = (binormal_src->stride?binormal_src->stride:3) * p.indices[src+binormal_ofs]; - ERR_FAIL_INDEX_V(binormal_pos,binormal_src->array.size(),ERR_INVALID_DATA); - Vector3 binormal =Vector3(binormal_src->array[binormal_pos+0],binormal_src->array[binormal_pos+1],binormal_src->array[binormal_pos+2]); - - int tangent_pos = (tangent_src->stride?tangent_src->stride:3) * p.indices[src+tangent_ofs]; - ERR_FAIL_INDEX_V(tangent_pos,tangent_src->array.size(),ERR_INVALID_DATA); - Vector3 tangent =Vector3(tangent_src->array[tangent_pos+0],tangent_src->array[tangent_pos+1],tangent_src->array[tangent_pos+2]); - - vertex.tangent.normal=tangent; - vertex.tangent.d= vertex.normal.cross(tangent).dot(binormal) > 0 ? 1 : -1; - } - - } - - - if (uv_src) { - - int uv_pos = (uv_src->stride?uv_src->stride:2) * p.indices[src+uv_ofs]; - ERR_FAIL_INDEX_V(uv_pos,uv_src->array.size(),ERR_INVALID_DATA); - vertex.uv=Vector3(uv_src->array[uv_pos+0],1.0-uv_src->array[uv_pos+1],0); - } - - if (uv2_src) { - - int uv2_pos = (uv2_src->stride?uv2_src->stride:2) * p.indices[src+uv2_ofs]; - ERR_FAIL_INDEX_V(uv2_pos,uv2_src->array.size(),ERR_INVALID_DATA); - vertex.uv2=Vector3(uv2_src->array[uv2_pos+0],1.0-uv2_src->array[uv2_pos+1],0); - } - - if (color_src) { - - int color_pos = (color_src->stride?color_src->stride:3) * p.indices[src+color_ofs]; // colors are RGB in collada.. - ERR_FAIL_INDEX_V(color_pos,color_src->array.size(),ERR_INVALID_DATA); - vertex.color=Color(color_src->array[color_pos+0],color_src->array[color_pos+1],color_src->array[color_pos+2],(color_src->stride>3)?color_src->array[color_pos+3]:1.0); - - } - -#ifndef NO_UP_AXIS_SWAP - if (collada.state.up_axis==Vector3::AXIS_Z) { - - SWAP( vertex.vertex.z, vertex.vertex.y ); - vertex.vertex.z = -vertex.vertex.z; - SWAP( vertex.normal.z, vertex.normal.y ); - vertex.normal.z = -vertex.normal.z; - SWAP( vertex.tangent.normal.z, vertex.tangent.normal.y ); - vertex.tangent.normal.z = -vertex.tangent.normal.z; - - } - -#endif - - vertex.fix_unit_scale(collada); - int index=0; - //COLLADA_PRINT("vertex: "+vertex.vertex); - - if (vertex_set.has(vertex)) { - - index=vertex_set.find(vertex)->get().idx; - } else { - - index=vertex_set.size(); - vertex.idx=index; - vertex_set.insert(vertex); - } - - /* if (!vertex_map.has(vertex_index)) - vertex_map[vertex_index]=Set<int>(); - vertex_map[vertex_index].insert(index); //should be outside..*/ - //build triangles if needed - if (j==0) - prev2[0]=index; - - if (j>=2) { - //insert indices in reverse order (collada uses CCW as frontface) - if (local_xform_mirror) { - - indices_list.push_back(prev2[0]); - indices_list.push_back(prev2[1]); - indices_list.push_back(index); - - } else { - indices_list.push_back(prev2[0]); - indices_list.push_back(index); - indices_list.push_back(prev2[1]); - } - } - - prev2[1]=index; - _prim_ofs+=p.vertex_size; - } - - } - - - - Vector<Collada::Vertex> vertex_array; //there we go, vertex array - - vertex_array.resize(vertex_set.size()); - for(Set<Collada::Vertex>::Element *F=vertex_set.front();F;F=F->next()) { - - vertex_array[F->get().idx]=F->get(); - } - - - if (has_weights) { - - //if skeleton, localize - Transform local_xform = p_local_xform; - for(int i=0;i<vertex_array.size();i++) { - - vertex_array[i].vertex=local_xform.xform(vertex_array[i].vertex); - vertex_array[i].normal=local_xform.basis.xform(vertex_array[i].normal).normalized(); - vertex_array[i].tangent.normal=local_xform.basis.xform(vertex_array[i].tangent.normal).normalized(); - if (local_xform_mirror) { - //i shouldn't do this? wtf? - //vertex_array[i].normal*=-1.0; - //vertex_array[i].tangent.normal*=-1.0; - } - } - } - - - PoolVector<int> index_array; - index_array.resize(indices_list.size()); - PoolVector<int>::Write index_arrayw = index_array.write(); - - int iidx=0; - for(List<int>::Element *F=indices_list.front();F;F=F->next()) { - - index_arrayw[iidx++]=F->get(); - } - - index_arrayw=PoolVector<int>::Write(); - - - /*****************/ - /* MAKE SURFACES */ - /*****************/ - - - { - - Ref<FixedSpatialMaterial> material; - - //find material - Mesh::PrimitiveType primitive=Mesh::PRIMITIVE_TRIANGLES; - - { - - if (p_material_map.has(p.material)) { - String target=p_material_map[p.material].target; - - if (!material_cache.has(target)) { - Error err = _create_material(target); - if (!err) - material=material_cache[target]; - } else - material=material_cache[target]; - - } else if (p.material!=""){ - print_line("Warning, unreferenced material in geometry instance: "+p.material); - } - } - - - - PoolVector<Vector3> final_vertex_array; - PoolVector<Vector3> final_normal_array; - PoolVector<float> final_tangent_array; - PoolVector<Color> final_color_array; - PoolVector<Vector3> final_uv_array; - PoolVector<Vector3> final_uv2_array; - PoolVector<int> final_bone_array; - PoolVector<float> final_weight_array; - - uint32_t final_format=0; - - //create format - final_format=Mesh::ARRAY_FORMAT_VERTEX|Mesh::ARRAY_FORMAT_INDEX; - - if (normal_src) { - final_format|=Mesh::ARRAY_FORMAT_NORMAL; - if (uv_src && binormal_src && tangent_src) { - final_format|=Mesh::ARRAY_FORMAT_TANGENT; - } - - } - - - - if (color_src) - final_format|=Mesh::ARRAY_FORMAT_COLOR; - if (uv_src) - final_format|=Mesh::ARRAY_FORMAT_TEX_UV; - if (uv2_src) - final_format|=Mesh::ARRAY_FORMAT_TEX_UV2; - - if (has_weights) { - final_format|=Mesh::ARRAY_FORMAT_WEIGHTS; - final_format|=Mesh::ARRAY_FORMAT_BONES; - } - - - //set arrays - - int vlen = vertex_array.size(); - { //vertices - - PoolVector<Vector3> varray; - varray.resize(vertex_array.size()); - - PoolVector<Vector3>::Write varrayw = varray.write(); - - for(int k=0;k<vlen;k++) - varrayw[k]=vertex_array[k].vertex; - - varrayw = PoolVector<Vector3>::Write(); - final_vertex_array=varray; - - } - - - if (uv_src) { //compute uv first, may be needed for computing tangent/bionrmal - PoolVector<Vector3> uvarray; - uvarray.resize(vertex_array.size()); - PoolVector<Vector3>::Write uvarrayw = uvarray.write(); - - for(int k=0;k<vlen;k++) { - uvarrayw[k]=vertex_array[k].uv; - } - - uvarrayw = PoolVector<Vector3>::Write(); - final_uv_array=uvarray; - - } - - if (uv2_src) { //compute uv first, may be needed for computing tangent/bionrmal - PoolVector<Vector3> uv2array; - uv2array.resize(vertex_array.size()); - PoolVector<Vector3>::Write uv2arrayw = uv2array.write(); - - for(int k=0;k<vlen;k++) { - uv2arrayw[k]=vertex_array[k].uv2; - } - - uv2arrayw = PoolVector<Vector3>::Write(); - final_uv2_array=uv2array; - - } - - if (normal_src) { - PoolVector<Vector3> narray; - narray.resize(vertex_array.size()); - PoolVector<Vector3>::Write narrayw = narray.write(); - - for(int k=0;k<vlen;k++) { - narrayw[k]=vertex_array[k].normal; - } - - narrayw = PoolVector<Vector3>::Write(); - final_normal_array=narray; - - /* - PoolVector<Vector3> altnaray; - _generate_normals(index_array,final_vertex_array,altnaray); - - for(int i=0;i<altnaray.size();i++) - print_line(rtos(altnaray[i].dot(final_normal_array[i]))); - */ - - } else if (primitive==Mesh::PRIMITIVE_TRIANGLES) { - //generate normals (even if unused later) - - _generate_normals(index_array,final_vertex_array,final_normal_array); - if (OS::get_singleton()->is_stdout_verbose()) - print_line("Collada: Triangle mesh lacks normals, so normals were generated."); - final_format|=Mesh::ARRAY_FORMAT_NORMAL; - - } - - if (final_normal_array.size() && uv_src && binormal_src && tangent_src && !force_make_tangents) { - - PoolVector<real_t> tarray; - tarray.resize(vertex_array.size()*4); - PoolVector<real_t>::Write tarrayw = tarray.write(); - - - for(int k=0;k<vlen;k++) { - tarrayw[k*4+0]=vertex_array[k].tangent.normal.x; - tarrayw[k*4+1]=vertex_array[k].tangent.normal.y; - tarrayw[k*4+2]=vertex_array[k].tangent.normal.z; - tarrayw[k*4+3]=vertex_array[k].tangent.d; - - } - - tarrayw = PoolVector<real_t>::Write(); - - final_tangent_array=tarray; - } else if (final_normal_array.size() && primitive==Mesh::PRIMITIVE_TRIANGLES && final_uv_array.size() && (force_make_tangents || (material.is_valid()))){ - //if this uses triangles, there are uvs and the material is using a normalmap, generate tangents and binormals, because they WILL be needed - //generate binormals/tangents - _generate_tangents_and_binormals(index_array,final_vertex_array,final_uv_array,final_normal_array,final_tangent_array); - final_format|=Mesh::ARRAY_FORMAT_TANGENT; - if (OS::get_singleton()->is_stdout_verbose()) - print_line("Collada: Triangle mesh lacks tangents (And normalmap was used), so tangents were generated."); - - } - - - if (color_src) { - PoolVector<Color> colorarray; - colorarray.resize(vertex_array.size()); - PoolVector<Color>::Write colorarrayw = colorarray.write(); - - for(int k=0;k<vlen;k++) { - colorarrayw[k]=vertex_array[k].color; - } - - colorarrayw = PoolVector<Color>::Write(); - - final_color_array=colorarray; - } - - if (has_weights) { - PoolVector<float> weightarray; - PoolVector<int> bonearray; - - weightarray.resize(vertex_array.size()*4); - PoolVector<float>::Write weightarrayw = weightarray.write(); - bonearray.resize(vertex_array.size()*4); - PoolVector<int>::Write bonearrayw = bonearray.write(); - - for(int k=0;k<vlen;k++) { - float sum=0; - - for(int l=0;l<VS::ARRAY_WEIGHTS_SIZE;l++) { - if (l<vertex_array[k].weights.size()) { - weightarrayw[k*VS::ARRAY_WEIGHTS_SIZE+l]=vertex_array[k].weights[l].weight; - sum+=weightarrayw[k*VS::ARRAY_WEIGHTS_SIZE+l]; - bonearrayw[k*VS::ARRAY_WEIGHTS_SIZE+l]=int(vertex_array[k].weights[l].bone_idx); - //COLLADA_PRINT(itos(k)+": "+rtos(bonearrayw[k*VS::ARRAY_WEIGHTS_SIZE+l])+":"+rtos(weightarray[k*VS::ARRAY_WEIGHTS_SIZE+l])); - } else { - - weightarrayw[k*VS::ARRAY_WEIGHTS_SIZE+l]=0; - bonearrayw[k*VS::ARRAY_WEIGHTS_SIZE+l]=0; - - } - - - } - /* - if (sum<0.8) - COLLADA_PRINT("ERROR SUMMING INDEX "+itos(k)+" had weights: "+itos(vertex_array[k].weights.size())); - */ - - } - - weightarrayw = PoolVector<float>::Write(); - bonearrayw = PoolVector<int>::Write(); - - final_weight_array = weightarray; - final_bone_array = bonearray; - } - - - - //////////////////////////// - // FINALLY CREATE SUFRACE // - //////////////////////////// - - Array d; - d.resize(VS::ARRAY_MAX); - - d[Mesh::ARRAY_INDEX]=index_array; - d[Mesh::ARRAY_VERTEX]=final_vertex_array; - - if (final_normal_array.size()) - d[Mesh::ARRAY_NORMAL]=final_normal_array; - if (final_tangent_array.size()) - d[Mesh::ARRAY_TANGENT]=final_tangent_array; - if (final_uv_array.size()) - d[Mesh::ARRAY_TEX_UV]=final_uv_array; - if (final_uv2_array.size()) - d[Mesh::ARRAY_TEX_UV2]=final_uv2_array; - if (final_color_array.size()) - d[Mesh::ARRAY_COLOR]=final_color_array; - if (final_weight_array.size()) - d[Mesh::ARRAY_WEIGHTS]=final_weight_array; - if (final_bone_array.size()) - d[Mesh::ARRAY_BONES]=final_bone_array; - - - Array mr; - - //////////////////////////// - // THEN THE MORPH TARGETS // - //////////////////////////// -#if 0 - if (p_morph_data) { - - //add morphie target - ERR_FAIL_COND_V( !p_morph_data->targets.has("MORPH_TARGET"), ERR_INVALID_DATA ); - String mt = p_morph_data->targets["MORPH_TARGET"]; - ERR_FAIL_COND_V( !p_morph_data->sources.has(mt), ERR_INVALID_DATA); - int morph_targets = p_morph_data->sources[mt].sarray.size(); - mr.resize(morph_targets); - - for(int j=0;j<morph_targets;j++) { - - Array mrt; - mrt.resize(VS::ARRAY_MAX); - - String target = p_morph_data->sources[mt].sarray[j]; - ERR_FAIL_COND_V( !collada.state.mesh_data_map.has(target), ERR_INVALID_DATA ); - String name = collada.state.mesh_data_map[target].name; - Collada::MeshData &md = collada.state.mesh_data_map[target]; - - // collada in itself supports morphing everything. However, the spec is unclear and no examples or exporters that - // morph anything but "POSITIONS" seem to exit. Because of this, normals and binormals/tangents have to be regenerated here, - // which may result in inaccurate (but most of the time good enough) results. - - PoolVector<Vector3> vertices; - vertices.resize(vlen); - - ERR_FAIL_COND_V( md.vertices.size() != 1, ERR_INVALID_DATA); - String vertex_src_id=md.vertices.front()->key(); - ERR_FAIL_COND_V(!md.vertices[vertex_src_id].sources.has("POSITION"),ERR_INVALID_DATA); - String position_src_id = md.vertices[vertex_src_id].sources["POSITION"]; - - ERR_FAIL_COND_V(!md.sources.has(position_src_id),ERR_INVALID_DATA); - - const Collada::MeshData::Source *m=&md.sources[position_src_id]; - - ERR_FAIL_COND_V( m->array.size() != vertex_src->array.size(), ERR_INVALID_DATA); - int stride=m->stride; - if (stride==0) - stride=3; - - - //read vertices from morph target - PoolVector<Vector3>::Write vertw = vertices.write(); - - for(int m_i=0;m_i<m->array.size()/stride;m_i++) { - - int pos = m_i*stride; - Vector3 vtx( m->array[pos+0], m->array[pos+1], m->array[pos+2] ); - -#ifndef NO_UP_AXIS_SWAP - if (collada.state.up_axis==Vector3::AXIS_Z) { - - SWAP( vtx.z, vtx.y ); - vtx.z = -vtx.z; - - } -#endif - - Collada::Vertex vertex; - vertex.vertex=vtx; - vertex.fix_unit_scale(collada); - vtx=vertex.vertex; - - vtx = p_local_xform.xform(vtx); - - - if (vertex_map.has(m_i)) { //vertex may no longer be here, don't bother converting - - - for (Set<int> ::Element *E=vertex_map[m_i].front() ; E; E=E->next() ) { - - vertw[E->get()]=vtx; - } - } - } - - - //vertices are in place, now generate everything else - vertw = PoolVector<Vector3>::Write(); - PoolVector<Vector3> normals; - PoolVector<float> tangents; - print_line("vertex source id: "+vertex_src_id); - if(md.vertices[vertex_src_id].sources.has("NORMAL")){ - //has normals - normals.resize(vlen); - //std::cout << "has normals" << std::endl; - String normal_src_id = md.vertices[vertex_src_id].sources["NORMAL"]; - //std::cout << "normals source: "<< normal_src_id.utf8().get_data() <<std::endl; - ERR_FAIL_COND_V(!md.sources.has(normal_src_id),ERR_INVALID_DATA); - - const Collada::MeshData::Source *m=&md.sources[normal_src_id]; - - ERR_FAIL_COND_V( m->array.size() != vertex_src->array.size(), ERR_INVALID_DATA); - int stride=m->stride; - if (stride==0) - stride=3; - - - //read normals from morph target - PoolVector<Vector3>::Write vertw = normals.write(); - - for(int m_i=0;m_i<m->array.size()/stride;m_i++) { - - int pos = m_i*stride; - Vector3 vtx( m->array[pos+0], m->array[pos+1], m->array[pos+2] ); - - #ifndef NO_UP_AXIS_SWAP - if (collada.state.up_axis==Vector3::AXIS_Z) { - - SWAP( vtx.z, vtx.y ); - vtx.z = -vtx.z; - - } - #endif - - Collada::Vertex vertex; - vertex.vertex=vtx; - vertex.fix_unit_scale(collada); - vtx=vertex.vertex; - - vtx = p_local_xform.xform(vtx); - - - if (vertex_map.has(m_i)) { //vertex may no longer be here, don't bother converting - - - for (Set<int> ::Element *E=vertex_map[m_i].front() ; E; E=E->next() ) { - - vertw[E->get()]=vtx; - } - } - } - - print_line("using built-in normals"); - }else{ - print_line("generating normals"); - _generate_normals(index_array,vertices,normals);//no normals - } - if (final_tangent_array.size() && final_uv_array.size()) { - - _generate_tangents_and_binormals(index_array,vertices,final_uv_array,normals,tangents); - - } - - mrt[Mesh::ARRAY_VERTEX]=vertices; - - mrt[Mesh::ARRAY_NORMAL]=normals; - if (tangents.size()) - mrt[Mesh::ARRAY_TANGENT]=tangents; - if (final_uv_array.size()) - mrt[Mesh::ARRAY_TEX_UV]=final_uv_array; - if (final_uv2_array.size()) - mrt[Mesh::ARRAY_TEX_UV2]=final_uv2_array; - if (final_color_array.size()) - mrt[Mesh::ARRAY_COLOR]=final_color_array; - - mr[j]=mrt; - - } - - } - -#endif - for(int mi=0;mi<p_morph_meshes.size();mi++) { - - //print_line("want surface "+itos(mi)+" has "+itos(p_morph_meshes[mi]->get_surface_count())); - Array a = p_morph_meshes[mi]->surface_get_arrays(surface); - //add valid weight and bone arrays if they exist, TODO check if they are unique to shape (generally not) - - if (final_weight_array.size()) - a[Mesh::ARRAY_WEIGHTS]=final_weight_array; - if (final_bone_array.size()) - a[Mesh::ARRAY_BONES]=final_bone_array; - - a[Mesh::ARRAY_INDEX]=Variant(); - //a.resize(Mesh::ARRAY_MAX); //no need for index - mr.push_back(a); - } - - - p_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES,d,mr,p_for_morph?0:Mesh::ARRAY_COMPRESS_DEFAULT); - - if (material.is_valid()) { - if (p_use_mesh_material) { - p_mesh->surface_set_material(surface, material); - } - p_mesh->surface_set_name(surface, material->get_name()); - } - } - - /*****************/ - /* FIND MATERIAL */ - /*****************/ - - surface++; - } - - - return OK; - -} - - -Error ColladaImport::_create_resources(Collada::Node *p_node) { - - - if (p_node->type==Collada::Node::TYPE_GEOMETRY && node_map.has(p_node->id)) { - - - Spatial * node=node_map[p_node->id].node; - Collada::NodeGeometry *ng = static_cast<Collada::NodeGeometry*>(p_node); - - - if (node->cast_to<Path>()) { - - Path *path = node->cast_to<Path>(); - - String curve = ng->source; - - if (curve_cache.has(ng->source)) { - - path->set_curve(curve_cache[ng->source]); - } else { - - Ref<Curve3D> c = memnew( Curve3D ); - - const Collada::CurveData &cd = collada.state.curve_data_map[ng->source]; - - ERR_FAIL_COND_V( !cd.control_vertices.has("POSITION") , ERR_INVALID_DATA); - ERR_FAIL_COND_V( !cd.control_vertices.has("IN_TANGENT") , ERR_INVALID_DATA); - ERR_FAIL_COND_V( !cd.control_vertices.has("OUT_TANGENT") , ERR_INVALID_DATA); - ERR_FAIL_COND_V( !cd.control_vertices.has("INTERPOLATION") , ERR_INVALID_DATA); - - - ERR_FAIL_COND_V( !cd.sources.has(cd.control_vertices["POSITION"] ) , ERR_INVALID_DATA); - const Collada::CurveData::Source &vertices = cd.sources[ cd.control_vertices["POSITION"] ]; - ERR_FAIL_COND_V( vertices.stride!=3, ERR_INVALID_DATA ); - - ERR_FAIL_COND_V( !cd.sources.has(cd.control_vertices["IN_TANGENT"] ) , ERR_INVALID_DATA); - const Collada::CurveData::Source &in_tangents = cd.sources[ cd.control_vertices["IN_TANGENT"] ]; - ERR_FAIL_COND_V( in_tangents.stride!=3 , ERR_INVALID_DATA); - - ERR_FAIL_COND_V( !cd.sources.has(cd.control_vertices["OUT_TANGENT"] ), ERR_INVALID_DATA ); - const Collada::CurveData::Source &out_tangents = cd.sources[ cd.control_vertices["OUT_TANGENT"] ]; - ERR_FAIL_COND_V( out_tangents.stride!=3, ERR_INVALID_DATA ); - - ERR_FAIL_COND_V( !cd.sources.has(cd.control_vertices["INTERPOLATION"] ), ERR_INVALID_DATA ); - const Collada::CurveData::Source &interps = cd.sources[ cd.control_vertices["INTERPOLATION"] ]; - ERR_FAIL_COND_V( interps.stride!=1, ERR_INVALID_DATA ); - - const Collada::CurveData::Source *tilts=NULL; - if (cd.control_vertices.has("TILT") && cd.sources.has(cd.control_vertices["TILT"])) - tilts=&cd.sources[ cd.control_vertices["TILT"] ]; - - - if (tilts) { - print_line("FOUND TILTS!!!"); - } - int pc = vertices.array.size()/3; - for(int i=0;i<pc;i++) { - - Vector3 pos( vertices.array[i*3+0], vertices.array[i*3+1], vertices.array[i*3+2] ); - Vector3 in( in_tangents.array[i*3+0], in_tangents.array[i*3+1], in_tangents.array[i*3+2] ); - Vector3 out( out_tangents.array[i*3+0], out_tangents.array[i*3+1], out_tangents.array[i*3+2] ); - -#ifndef NO_UP_AXIS_SWAP - if (collada.state.up_axis==Vector3::AXIS_Z) { - - SWAP(pos.y,pos.z); - pos.z=-pos.z; - SWAP(in.y,in.z); - in.z=-in.z; - SWAP(out.y,out.z); - out.z=-out.z; - } -#endif - pos*=collada.state.unit_scale; - in*=collada.state.unit_scale; - out*=collada.state.unit_scale; - - c->add_point(pos,in-pos,out-pos); - if (tilts) - c->set_point_tilt(i,tilts->array[i]); - - } - - curve_cache[ng->source]=c; - path->set_curve(c); - - } - - - } - - - if (node->cast_to<MeshInstance>()) { - - - Collada::NodeGeometry *ng = static_cast<Collada::NodeGeometry*>(p_node); - - MeshInstance *mi = node->cast_to<MeshInstance>(); - - - ERR_FAIL_COND_V(!mi,ERR_BUG); - - - Collada::SkinControllerData *skin=NULL; - Collada::MorphControllerData *morph=NULL; - String meshid; - Transform apply_xform; - Vector<int> bone_remap; - Vector<Ref<Mesh> > morphs; - - print_line("mesh: "+String(mi->get_name())); - - if (ng->controller) { - - print_line("has controller"); - - String ngsource = ng->source; - - if (collada.state.skin_controller_data_map.has(ngsource)) { - - - ERR_FAIL_COND_V(!collada.state.skin_controller_data_map.has(ngsource),ERR_INVALID_DATA); - skin=&collada.state.skin_controller_data_map[ngsource]; - - Vector<String> skeletons = ng->skeletons; - - ERR_FAIL_COND_V( skeletons.empty(), ERR_INVALID_DATA ); - - String skname = skeletons[0]; - if (!node_map.has(skname)) { - print_line("no node for skeleton "+skname); - } - ERR_FAIL_COND_V( !node_map.has(skname), ERR_INVALID_DATA ); - NodeMap nmsk = node_map[skname]; - Skeleton *sk = nmsk.node->cast_to<Skeleton>(); - ERR_FAIL_COND_V( !sk, ERR_INVALID_DATA ); - ERR_FAIL_COND_V( !skeleton_bone_map.has(sk), ERR_INVALID_DATA ); - Map<String, int> &bone_remap_map=skeleton_bone_map[sk]; - - - meshid=skin->base; - - if (collada.state.morph_controller_data_map.has(meshid)) { - //it's a morph!! - morph = &collada.state.morph_controller_data_map[meshid]; - ngsource=meshid; - meshid=morph->mesh; - } else { - ngsource=""; - } - - if (apply_mesh_xform_to_vertices) { - apply_xform=collada.fix_transform(p_node->default_transform); - node->set_transform(Transform()); - } else { - apply_xform=Transform(); - } - - Collada::SkinControllerData::Source *joint_src=NULL; - - ERR_FAIL_COND_V(!skin->weights.sources.has("JOINT"),ERR_INVALID_DATA); - - String joint_id = skin->weights.sources["JOINT"].source; - ERR_FAIL_COND_V(!skin->sources.has(joint_id),ERR_INVALID_DATA); - - joint_src = &skin->sources[joint_id]; - - bone_remap.resize(joint_src->sarray.size()); - - for(int i=0;i<bone_remap.size();i++) { - - String str = joint_src->sarray[i]; - if (!bone_remap_map.has(str)) { - print_line("bone not found for remap: "+str); - print_line("in skeleton: "+skname); - } - ERR_FAIL_COND_V( !bone_remap_map.has(str), ERR_INVALID_DATA ); - bone_remap[i]=bone_remap_map[str]; - } - } - - if (collada.state.morph_controller_data_map.has(ngsource)) { - print_line("is morph "+ngsource); - //it's a morph!! - morph = &collada.state.morph_controller_data_map[ngsource]; - meshid=morph->mesh; - printf("KKmorph: %p\n",morph); - print_line("morph mshid: "+meshid); - - Vector<String> targets; - - morph->targets.has("MORPH_TARGET"); - String target = morph->targets["MORPH_TARGET"]; - bool valid=false; - if (morph->sources.has(target)) { - valid=true; - Vector<String> names = morph->sources[target].sarray; - for(int i=0;i<names.size();i++) { - - String meshid=names[i]; - if (collada.state.mesh_data_map.has(meshid)) { - Ref<Mesh> mesh=Ref<Mesh>(memnew( Mesh )); - const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid]; - Error err = _create_mesh_surfaces(false,mesh,ng->material_map,meshdata,apply_xform,bone_remap,skin,NULL,Vector<Ref<Mesh> >(),true); - ERR_FAIL_COND_V(err,err); - - morphs.push_back(mesh); - } else { - valid=false; - } - } - } - - if (!valid) - morphs.clear(); - - ngsource=""; - } - - if (ngsource!=""){ - ERR_EXPLAIN("Controller Instance Source '"+ngsource+"' is neither skin or morph!"); - ERR_FAIL_V( ERR_INVALID_DATA ); - } - - - - } else { - meshid=ng->source; - } - - Ref<Mesh> mesh; - if (mesh_cache.has(meshid)) { - mesh=mesh_cache[meshid]; - } else { - if (collada.state.mesh_data_map.has(meshid)) { - //bleh, must ignore invalid - - ERR_FAIL_COND_V(!collada.state.mesh_data_map.has(meshid),ERR_INVALID_DATA); - mesh=Ref<Mesh>(memnew( Mesh )); - const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid]; - mesh->set_name( meshdata.name ); - Error err = _create_mesh_surfaces(morphs.size()==0,mesh,ng->material_map,meshdata,apply_xform,bone_remap,skin,morph,morphs,false,use_mesh_builtin_materials); - ERR_FAIL_COND_V(err,err); - - mesh_cache[meshid]=mesh; - } else { - - print_line("Warning, will not import geometry: "+meshid); - } - } - - if (!mesh.is_null()) { - - mi->set_mesh(mesh); - if (!use_mesh_builtin_materials) { - const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid]; - - for(int i=0;i<meshdata.primitives.size();i++) { - - String matname=meshdata.primitives[i].material; - - if (ng->material_map.has(matname)) { - String target=ng->material_map[matname].target; - - Ref<Material> material; - if (!material_cache.has(target)) { - Error err = _create_material(target); - if (!err) - material=material_cache[target]; - } else - material=material_cache[target]; - - mi->set_surface_material(i,material); - } else if (matname!=""){ - print_line("Warning, unreferenced material in geometry instance: "+matname); - } - - } - } - } - } - } - - for(int i=0;i<p_node->children.size();i++) { - - Error err = _create_resources(p_node->children[i]); - if (err) - return err; - } - return OK; -} - - -Error ColladaImport::load(const String& p_path,int p_flags,bool p_force_make_tangents) { - - Error err = collada.load(p_path,p_flags); - ERR_FAIL_COND_V(err,err); - - force_make_tangents=p_force_make_tangents; - ERR_FAIL_COND_V( !collada.state.visual_scene_map.has( collada.state.root_visual_scene ), ERR_INVALID_DATA ); - Collada::VisualScene &vs = collada.state.visual_scene_map[ collada.state.root_visual_scene ]; - - scene = memnew( Spatial ); // root - - //determine what's going on with the lights - for(int i=0;i<vs.root_nodes.size();i++) { - - _pre_process_lights(vs.root_nodes[i]); - - } - //import scene - - for(int i=0;i<vs.root_nodes.size();i++) { - - Error err = _create_scene_skeletons(vs.root_nodes[i]); - if (err!=OK) { - memdelete(scene); - ERR_FAIL_COND_V(err,err); - } - } - - for(int i=0;i<vs.root_nodes.size();i++) { - - Error err = _create_scene(vs.root_nodes[i],scene); - if (err!=OK) { - memdelete(scene); - ERR_FAIL_COND_V(err,err); - } - - Error err2 = _create_resources(vs.root_nodes[i]); - if (err2!=OK) { - memdelete(scene); - ERR_FAIL_COND_V(err2,err2); - } - } - - //optatively, set unit scale in the root - scene->set_transform(collada.get_root_transform()); - - - return OK; - -} - -void ColladaImport::_fix_param_animation_tracks() { - - for (Map<String,Collada::Node*>::Element *E=collada.state.scene_map.front();E;E=E->next()) { - - Collada::Node *n = E->get(); - switch(n->type) { - - case Collada::Node::TYPE_NODE: { - // ? do nothing - } break; - case Collada::Node::TYPE_JOINT: { - - } break; - case Collada::Node::TYPE_SKELETON: { - - } break; - case Collada::Node::TYPE_LIGHT: { - - } break; - case Collada::Node::TYPE_CAMERA: { - - } break; - case Collada::Node::TYPE_GEOMETRY: { - - Collada::NodeGeometry *ng = static_cast<Collada::NodeGeometry*>(n); - // test source(s) - String source = ng->source; - - while (source!="") { - - if (collada.state.skin_controller_data_map.has(source)) { - - const Collada::SkinControllerData& skin = collada.state.skin_controller_data_map[source]; - - //nothing to animate here i think - - source=skin.base; - } else if (collada.state.morph_controller_data_map.has(source)) { - - - const Collada::MorphControllerData& morph = collada.state.morph_controller_data_map[source]; - - if (morph.targets.has("MORPH_WEIGHT") && morph.targets.has("MORPH_TARGET")) { - - - String weights = morph.targets["MORPH_WEIGHT"]; - String targets = morph.targets["MORPH_TARGET"]; - //fails here - - if (morph.sources.has(targets) && morph.sources.has(weights)) { - const Collada::MorphControllerData::Source &weight_src=morph.sources[weights]; - const Collada::MorphControllerData::Source &target_src=morph.sources[targets]; - - - ERR_FAIL_COND(weight_src.array.size() != target_src.sarray.size()); - - for(int i=0;i<weight_src.array.size();i++) { - - String track_name = weights+"("+itos(i)+")"; - String mesh_name = target_src.sarray[i]; - if (collada.state.mesh_name_map.has(mesh_name) && collada.state.referenced_tracks.has(track_name)) { - - - const Vector<int>&rt = collada.state.referenced_tracks[track_name]; - - for(int rti=0;rti<rt.size();rti++) { - Collada::AnimationTrack *at = &collada.state.animation_tracks[rt[rti]]; - - at->target=E->key(); - at->param="morph/"+collada.state.mesh_name_map[mesh_name]; - at->property=true; - //at->param - } - } - } - } - } - source=morph.mesh; - } else { - - source=""; // for now nothing else supported - } - } - - } break; - - } - } - -} - -void ColladaImport::create_animations(bool p_make_tracks_in_all_bones, bool p_import_value_tracks) { - - - _fix_param_animation_tracks(); - for(int i=0;i<collada.state.animation_clips.size();i++) { - - for(int j=0;j<collada.state.animation_clips[i].tracks.size();j++) - tracks_in_clips.insert(collada.state.animation_clips[i].tracks[j]); - } - - - - for(int i=0;i<collada.state.animation_tracks.size();i++) { - - Collada::AnimationTrack &at = collada.state.animation_tracks[i]; - //print_line("CHANNEL: "+at.target+" PARAM: "+at.param); - - String node; - - if (!node_map.has(at.target)) { - - if (node_name_map.has(at.target)) { - - node=node_name_map[at.target]; - } else { - print_line("Coudlnt find node: "+at.target); - continue; - } - } else { - node=at.target; - } - - - if (at.property) { - - valid_animated_properties.push_back(i); - - } else { - - node_map[node].anim_tracks.push_back(i); - valid_animated_nodes.insert(node); - } - - } - - create_animation(-1,p_make_tracks_in_all_bones, p_import_value_tracks); - //print_line("clipcount: "+itos(collada.state.animation_clips.size())); - for(int i=0;i<collada.state.animation_clips.size();i++) - create_animation(i, p_make_tracks_in_all_bones, p_import_value_tracks); - -} - -void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones, bool p_import_value_tracks) { - - Ref<Animation> animation = Ref<Animation>( memnew( Animation )); - - - if (p_clip==-1) { - - //print_line("default"); - animation->set_name("default"); - } else { - //print_line("clip name: "+collada.state.animation_clips[p_clip].name); - animation->set_name(collada.state.animation_clips[p_clip].name); - } - - for(Map<String,NodeMap>::Element *E=node_map.front();E;E=E->next()) { - - if (E->get().bone<0) - continue; - bones_with_animation[E->key()]=false; - } - //store and validate tracks - - if (p_clip==-1) { - //main anim - } - - Set<int> track_filter; - - - if (p_clip==-1) { - - for(int i=0;i<collada.state.animation_clips.size();i++) { - - int tc = collada.state.animation_clips[i].tracks.size(); - for(int j=0;j<tc;j++) { - - String n = collada.state.animation_clips[i].tracks[j]; - if (collada.state.by_id_tracks.has(n)) { - - const Vector<int>&ti = collada.state.by_id_tracks[n]; - for(int k=0;k<ti.size();k++) { - track_filter.insert(ti[k]); - } - } - } - } - } else { - - int tc = collada.state.animation_clips[p_clip].tracks.size(); - for(int j=0;j<tc;j++) { - - String n = collada.state.animation_clips[p_clip].tracks[j]; - if (collada.state.by_id_tracks.has(n)) { - - const Vector<int>&ti = collada.state.by_id_tracks[n]; - for(int k=0;k<ti.size();k++) { - track_filter.insert(ti[k]); - } - } - } - - } - - //animation->set_loop(true); - //create animation tracks - - Vector<float> base_snapshots; - - float f=0; - float snapshot_interval = 1.0/bake_fps; //should be customizable somewhere... - - float anim_length=collada.state.animation_length; - if (p_clip>=0 && collada.state.animation_clips[p_clip].end) - anim_length=collada.state.animation_clips[p_clip].end; - - while(f<anim_length) { - - base_snapshots.push_back(f); - - f+=snapshot_interval; - - if (f>=anim_length) { - base_snapshots.push_back(anim_length); - - } - } - - //print_line("anim len: "+rtos(anim_length)); - animation->set_length(anim_length); - - bool tracks_found=false; - - - - for(Set<String>::Element* E=valid_animated_nodes.front();E;E=E->next()) { - - // take snapshots - - - if (!collada.state.scene_map.has(E->get())) { - - continue; - } - - NodeMap &nm = node_map[E->get()]; - String path = scene->get_path_to(nm.node); - - if (nm.bone>=0) { - Skeleton *sk = static_cast<Skeleton*>(nm.node); - String name = sk->get_bone_name(nm.bone); - path=path+":"+name; - } - - bool found_anim=false; - - - Collada::Node *cn = collada.state.scene_map[E->get()]; - if (cn->ignore_anim) { - - continue; - } - - - - animation->add_track(Animation::TYPE_TRANSFORM); - int track = animation->get_track_count() -1; - animation->track_set_path( track , path ); - animation->track_set_imported( track , true ); //helps merging later - - Vector<float> snapshots = base_snapshots; - - if (nm.anim_tracks.size()==1) { - //use snapshot keys from anim track instead, because this was most likely exported baked - Collada::AnimationTrack &at = collada.state.animation_tracks[nm.anim_tracks.front()->get()]; - snapshots.clear(); - for(int i=0;i<at.keys.size();i++) - snapshots.push_back(at.keys[i].time); - - - } - - - for(int i=0;i<snapshots.size();i++) { - - - for(List<int>::Element *ET=nm.anim_tracks.front();ET;ET=ET->next()) { - //apply tracks - - - if (p_clip==-1) { - - if (track_filter.has(ET->get())) { - - continue; - } - } else { - - if (!track_filter.has(ET->get())) - continue; - - } - - found_anim=true; - - Collada::AnimationTrack &at = collada.state.animation_tracks[ET->get()]; - - int xform_idx=-1; - for(int j=0;j<cn->xform_list.size();j++) { - - - if (cn->xform_list[j].id==at.param) { - - xform_idx=j; - break; - } - } - - if (xform_idx==-1) { - print_line("couldnt find matching node "+at.target+" xform for track "+at.param); - continue; - } - - ERR_CONTINUE(xform_idx==-1); - - Vector<float> data = at.get_value_at_time(snapshots[i]); - ERR_CONTINUE(data.empty()); - - - Collada::Node::XForm &xf = cn->xform_list[xform_idx]; - - if (at.component=="ANGLE") { - ERR_CONTINUE(data.size()!=1); - ERR_CONTINUE(xf.op!=Collada::Node::XForm::OP_ROTATE); - ERR_CONTINUE(xf.data.size()<4); - xf.data[3]=data[0]; - } else if (at.component=="X" || at.component=="Y" || at.component=="Z") { - int cn=at.component[0]-'X'; - ERR_CONTINUE(cn>=xf.data.size()); - ERR_CONTINUE(data.size()>1); - xf.data[cn]=data[0]; - } else if (data.size()==xf.data.size()) { - - xf.data=data; - } else { - - - if ( data.size()!=xf.data.size() ) { - print_line("component "+at.component+" datasize "+itos(data.size())+" xfdatasize "+itos(xf.data.size())); - } - - ERR_CONTINUE( data.size()!=xf.data.size() ); - } - } - - Transform xform = cn->compute_transform(collada); - xform = collada.fix_transform(xform) * cn->post_transform; - - - if (nm.bone>=0) { - //make bone transform relative to rest (in case of skeleton) - Skeleton *sk = nm.node->cast_to<Skeleton>(); - if (sk) { - - xform = sk->get_bone_rest(nm.bone).affine_inverse() * xform; - } else { - - ERR_PRINT("INVALID SKELETON!!!!"); - } - } - - Quat q = xform.basis; - q.normalize(); - Vector3 s = xform.basis.get_scale(); - Vector3 l = xform.origin; - - animation->transform_track_insert_key(track,snapshots[i],l,q,s); - - } - - - - if (nm.bone>=0) { - if (found_anim) - bones_with_animation[E->get()]=true; - } - - if (found_anim) - tracks_found=true; - else { - animation->remove_track( track ); - } - - } - - if (p_make_tracks_in_all_bones) { - - //some bones may lack animation, but since we don't store pose as a property, we must add keyframes! - for(Map<String,bool>::Element *E=bones_with_animation.front();E;E=E->next()) { - - if (E->get()) - continue; - - //print_line("BONE LACKS ANIM: "+E->key()); - - NodeMap &nm = node_map[E->key()]; - String path = scene->get_path_to(nm.node); - ERR_CONTINUE( nm.bone <0 ); - Skeleton *sk = static_cast<Skeleton*>(nm.node); - String name = sk->get_bone_name(nm.bone); - path=path+":"+name; - - Collada::Node *cn = collada.state.scene_map[E->key()]; - if (cn->ignore_anim) { - print_line("warning, ignoring animation on node: "+path); - continue; - } - - animation->add_track(Animation::TYPE_TRANSFORM); - int track = animation->get_track_count() -1; - animation->track_set_path( track , path ); - animation->track_set_imported( track , true ); //helps merging later - - - Transform xform = cn->compute_transform(collada); - xform = collada.fix_transform(xform) * cn->post_transform; - - xform = sk->get_bone_rest(nm.bone).affine_inverse() * xform; - - Quat q = xform.basis; - q.normalize(); - Vector3 s = xform.basis.get_scale(); - Vector3 l = xform.origin; - - animation->transform_track_insert_key(track,0,l,q,s); - - tracks_found=true; - } - } - - - - if (p_import_value_tracks) { - for (int i = 0; i < valid_animated_properties.size(); i++) { - - - int ti = valid_animated_properties[i]; - - if (p_clip == -1) { - - if (track_filter.has(ti)) - continue; - } - else { - - if (!track_filter.has(ti)) - continue; - - } - - - Collada::AnimationTrack &at = collada.state.animation_tracks[ti]; - - // take snapshots - if (!collada.state.scene_map.has(at.target)) - continue; - - NodeMap &nm = node_map[at.target]; - String path = scene->get_path_to(nm.node); - - animation->add_track(Animation::TYPE_VALUE); - int track = animation->get_track_count() - 1; - - path = path + ":" + at.param; - animation->track_set_path(track, path); - animation->track_set_imported(track, true); //helps merging later - - - for (int i = 0; i < at.keys.size(); i++) { - - float time = at.keys[i].time; - Variant value; - Vector<float> data = at.keys[i].data; - if (data.size() == 1) { - //push a float - value = data[0]; - - } - else if (data.size() == 16) { - //matrix - print_line("value keys for matrices not supported"); - } - else { - - print_line("don't know what to do with this amount of value keys: " + itos(data.size())); - } - - animation->track_insert_key(track, time, value); - } - - - tracks_found = true; - - } - } - - - - if (tracks_found) { - - animations.push_back(animation); - } - - - -} - - -/*********************************************************************************/ -/*************************************** SCENE ***********************************/ -/*********************************************************************************/ - - -#define DEBUG_ANIMATION - - -uint32_t EditorSceneImporterCollada::get_import_flags() const { - - return IMPORT_SCENE|IMPORT_ANIMATION; - -} -void EditorSceneImporterCollada::get_extensions(List<String> *r_extensions) const { - - - r_extensions->push_back("dae"); -} -Node* EditorSceneImporterCollada::import_scene(const String& p_path, uint32_t p_flags,int p_bake_fps, List<String> *r_missing_deps, Error* r_err) { - - ColladaImport state; - uint32_t flags=Collada::IMPORT_FLAG_SCENE; - if (p_flags&IMPORT_ANIMATION) - flags|=Collada::IMPORT_FLAG_ANIMATION; - - state.use_mesh_builtin_materials=!(p_flags&IMPORT_MATERIALS_IN_INSTANCES); - state.bake_fps=p_bake_fps; - - Error err = state.load(p_path,flags,p_flags&EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS); - - ERR_FAIL_COND_V(err!=OK,NULL); - - if (state.missing_textures.size()) { - - /* - for(int i=0;i<state.missing_textures.size();i++) { - EditorNode::add_io_error("Texture Not Found: "+state.missing_textures[i]); - } - */ - - - if (r_missing_deps) { - - for(int i=0;i<state.missing_textures.size();i++) { - //EditorNode::add_io_error("Texture Not Found: "+state.missing_textures[i]); - r_missing_deps->push_back(state.missing_textures[i]); - } - - } - } - - if (p_flags&IMPORT_ANIMATION) { - - state.create_animations(p_flags&IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS,p_flags&EditorSceneImporter::IMPORT_ANIMATION_KEEP_VALUE_TRACKS); - AnimationPlayer *ap = memnew( AnimationPlayer ); - for(int i=0;i<state.animations.size();i++) { - String name; - if (state.animations[i]->get_name()=="") - name="default"; - else - name=state.animations[i]->get_name(); - - if (p_flags&IMPORT_ANIMATION_DETECT_LOOP) { - - if (name.begins_with("loop") || name.ends_with("loop") || name.begins_with("cycle") || name.ends_with("cycle")) { - state.animations[i]->set_loop(true); - } - } - - ap->add_animation(name,state.animations[i]); - } - state.scene->add_child(ap); - ap->set_owner(state.scene); - - } - - return state.scene; - -} - -Ref<Animation> EditorSceneImporterCollada::import_animation(const String& p_path,uint32_t p_flags) { - - - ColladaImport state; - - - state.use_mesh_builtin_materials=false; - - Error err = state.load(p_path,Collada::IMPORT_FLAG_ANIMATION,p_flags&EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS); - ERR_FAIL_COND_V(err!=OK,RES()); - - - state.create_animations(p_flags&EditorSceneImporter::IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS,p_flags&EditorSceneImporter::IMPORT_ANIMATION_KEEP_VALUE_TRACKS); - if (state.scene) - memdelete(state.scene); - - if (state.animations.size()==0) - return Ref<Animation>(); - Ref<Animation> anim=state.animations[0]; - anim=state.animations[0]; - print_line("Anim Load OK"); - String base = p_path.get_basename().to_lower(); - if (p_flags&IMPORT_ANIMATION_DETECT_LOOP) { - - if (base.begins_with("loop") || base.ends_with("loop") || base.begins_with("cycle") || base.ends_with("cycle")) { - anim->set_loop(true); - } - } - - - return anim; -} - - -EditorSceneImporterCollada::EditorSceneImporterCollada() { - - -} - diff --git a/tools/editor/import/editor_import_collada.h b/tools/editor/import/editor_import_collada.h deleted file mode 100644 index cd3614bb40..0000000000 --- a/tools/editor/import/editor_import_collada.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************/ -/* editor_import_collada.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITOR_IMPORT_COLLADA_H -#define EDITOR_IMPORT_COLLADA_H - -#include "tools/editor/import/resource_importer_scene.h" - - - -class EditorSceneImporterCollada : public EditorSceneImporter { - - GDCLASS(EditorSceneImporterCollada,EditorSceneImporter ); -public: - - virtual uint32_t get_import_flags() const; - virtual void get_extensions(List<String> *r_extensions) const; - virtual Node* import_scene(const String& p_path,uint32_t p_flags,int p_bake_fps,List<String> *r_missing_deps=NULL,Error* r_err=NULL); - virtual Ref<Animation> import_animation(const String& p_path,uint32_t p_flags); - - EditorSceneImporterCollada(); -}; - - -#endif - diff --git a/tools/editor/import/resource_importer_scene.cpp b/tools/editor/import/resource_importer_scene.cpp deleted file mode 100644 index 406058c59e..0000000000 --- a/tools/editor/import/resource_importer_scene.cpp +++ /dev/null @@ -1,1328 +0,0 @@ -#include "resource_importer_scene.h" - -#include "scene/resources/packed_scene.h" -#include "io/resource_saver.h" -#include "tools/editor/editor_node.h" - -#include "scene/3d/mesh_instance.h" -#include "scene/3d/navigation.h" -#include "scene/3d/room_instance.h" -#include "scene/3d/body_shape.h" -#include "scene/3d/physics_body.h" -#include "scene/3d/portal.h" -#include "scene/3d/vehicle_body.h" -#include "scene/resources/sphere_shape.h" -#include "scene/resources/box_shape.h" -#include "scene/resources/ray_shape.h" -#include "scene/resources/plane_shape.h" - - -void EditorScenePostImport::_bind_methods() { - - BIND_VMETHOD( MethodInfo("post_import",PropertyInfo(Variant::OBJECT,"scene")) ); - -} - -Node *EditorScenePostImport::post_import(Node* p_scene) { - - if (get_script_instance()) - return get_script_instance()->call("post_import",p_scene); - - return p_scene; -} - -EditorScenePostImport::EditorScenePostImport() { - - -} - - -String ResourceImporterScene::get_importer_name() const { - - return "scene"; -} - -String ResourceImporterScene::get_visible_name() const{ - - return "Scene"; -} - -void ResourceImporterScene::get_recognized_extensions(List<String> *p_extensions) const{ - - for (Set< Ref<EditorSceneImporter> >::Element *E=importers.front();E;E=E->next()) { - E->get()->get_extensions(p_extensions); - } -} - -String ResourceImporterScene::get_save_extension() const { - return "scn"; -} - -String ResourceImporterScene::get_resource_type() const{ - - return "PackedScene"; -} - -bool ResourceImporterScene::get_option_visibility(const String& p_option,const Map<StringName,Variant>& p_options) const { - - if (p_option.begins_with("animation/")) { - if (p_option!="animation/import" && !bool(p_options["animation/import"])) - return false; - - if (p_option.begins_with("animation/optimizer/") && p_option!="animation/optimizer/enabled" && !bool(p_options["animation/optimizer/enabled"])) - return false; - - if (p_option.begins_with("animation/clip_")) { - int max_clip = p_options["animation/clips/amount"]; - int clip = p_option.get_slice("/",1).get_slice("_",1).to_int()-1; - if (clip>=max_clip) - return false; - } - } - - return true; - -} - -int ResourceImporterScene::get_preset_count() const { - return 0; -} -String ResourceImporterScene::get_preset_name(int p_idx) const { - - return ""; -} - - -static bool _teststr(const String& p_what,const String& p_str) { - - if (p_what.findn("$"+p_str)!=-1) //blender and other stuff - return true; - if (p_what.to_lower().ends_with("-"+p_str)) //collada only supports "_" and "-" besides letters - return true; - if (p_what.to_lower().ends_with("_"+p_str)) //collada only supports "_" and "-" besides letters - return true; - return false; -} - -static String _fixstr(const String& p_what,const String& p_str) { - - if (p_what.findn("$"+p_str)!=-1) //blender and other stuff - return p_what.replace("$"+p_str,""); - if (p_what.to_lower().ends_with("-"+p_str)) //collada only supports "_" and "-" besides letters - return p_what.substr(0,p_what.length()-(p_str.length()+1)); - if (p_what.to_lower().ends_with("_"+p_str)) //collada only supports "_" and "-" besides letters - return p_what.substr(0,p_what.length()-(p_str.length()+1)); - return p_what; -} - - -Node* ResourceImporterScene::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map) { - - // children first.. - for(int i=0;i<p_node->get_child_count();i++) { - - - Node *r = _fix_node(p_node->get_child(i),p_root,collision_map); - if (!r) { - print_line("was erased.."); - i--; //was erased - } - } - - String name = p_node->get_name(); - - bool isroot = p_node==p_root; - - - if (!isroot && _teststr(name,"noimp")) { - - memdelete(p_node); - return NULL; - } - - - if (p_node->cast_to<MeshInstance>()) { - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - bool bb=false; - - if ((_teststr(name,"bb"))) { - bb=true; - } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"bb"))) { - bb=true; - - } - - if (bb) { - mi->set_flag(GeometryInstance::FLAG_BILLBOARD,true); - if (mi->get_mesh().is_valid()) { - - Ref<Mesh> m = mi->get_mesh(); - for(int i=0;i<m->get_surface_count();i++) { - - Ref<FixedSpatialMaterial> fm = m->surface_get_material(i); - if (fm.is_valid()) { - //fm->set_flag(Material::FLAG_UNSHADED,true); - //fm->set_flag(Material::FLAG_DOUBLE_SIDED,true); - //fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); - //fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); - } - } - } - } - } - - - if (p_node->cast_to<MeshInstance>()) { - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - Ref<Mesh> m = mi->get_mesh(); - - if (m.is_valid()) { - - for(int i=0;i<m->get_surface_count();i++) { - - Ref<FixedSpatialMaterial> mat = m->surface_get_material(i); - if (!mat.is_valid()) - continue; - - if (_teststr(mat->get_name(),"alpha")) { - - mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT,true); - mat->set_name(_fixstr(mat->get_name(),"alpha")); - } - if (_teststr(mat->get_name(),"vcol")) { - - mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR,true); - mat->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR,true); - mat->set_name(_fixstr(mat->get_name(),"vcol")); - } - - } - } - } - - if (p_node->cast_to<AnimationPlayer>()) { - //remove animations referencing non-importable nodes - AnimationPlayer *ap = p_node->cast_to<AnimationPlayer>(); - - List<StringName> anims; - ap->get_animation_list(&anims); - for(List<StringName>::Element *E=anims.front();E;E=E->next()) { - - Ref<Animation> anim=ap->get_animation(E->get()); - ERR_CONTINUE(anim.is_null()); - for(int i=0;i<anim->get_track_count();i++) { - NodePath path = anim->track_get_path(i); - - for(int j=0;j<path.get_name_count();j++) { - String node = path.get_name(j); - if (_teststr(node,"noimp")) { - anim->remove_track(i); - i--; - break; - } - } - } - - } - } - - - if (p_node->cast_to<MeshInstance>()) { - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - String str; - - if ((_teststr(name,"imp"))) { - str=name; - } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"imp"))) { - str=mi->get_mesh()->get_name(); - - } - - - if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) { - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>(); - String d=str.substr(str.find("imp")+3,str.length()); - if (d!="") { - if ((d[0]<'0' || d[0]>'9')) - d=d.substr(1,d.length()); - if (d.length() && d[0]>='0' && d[0]<='9') { - float dist = d.to_double(); - mi->set_flag(GeometryInstance::FLAG_BILLBOARD,true); - mi->set_flag(GeometryInstance::FLAG_BILLBOARD_FIX_Y,true); - //mi->set_draw_range_begin(dist); - //mi->set_draw_range_end(100000); - - //mip->set_draw_range_begin(0); - //mip->set_draw_range_end(dist); - - if (mi->get_mesh().is_valid()) { - - Ref<Mesh> m = mi->get_mesh(); - for(int i=0;i<m->get_surface_count();i++) { - - Ref<FixedSpatialMaterial> fm = m->surface_get_material(i); - if (fm.is_valid()) { - //fm->set_flag(Material::FLAG_UNSHADED,true); - //fm->set_flag(Material::FLAG_DOUBLE_SIDED,true); - //fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); - //fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); - } - } - } - } - } - } - } -#if 0 - if (p_flags&SCENE_FLAG_CREATE_LODS && p_node->cast_to<MeshInstance>()) { - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - String str; - - if ((_teststr(name,"lod"))) { - str=name; - } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"lod"))) { - str=mi->get_mesh()->get_name(); - - } - - - if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) { - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>(); - String d=str.substr(str.find("lod")+3,str.length()); - if (d!="") { - if ((d[0]<'0' || d[0]>'9')) - d=d.substr(1,d.length()); - if (d.length() && d[0]>='0' && d[0]<='9') { - float dist = d.to_double(); - /// mi->set_draw_range_begin(dist); - // mi->set_draw_range_end(100000); - - // mip->set_draw_range_begin(0); - // mip->set_draw_range_end(dist); - - /*if (mi->get_mesh().is_valid()) { - - Ref<Mesh> m = mi->get_mesh(); - for(int i=0;i<m->get_surface_count();i++) { - - Ref<FixedSpatialMaterial> fm = m->surface_get_material(i); - if (fm.is_valid()) { - fm->set_flag(Material::FLAG_UNSHADED,true); - fm->set_flag(Material::FLAG_DOUBLE_SIDED,true); - fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true); - fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); - } - } - }*/ - } - } - } - } - - - if (p_flags&SCENE_FLAG_DETECT_LIGHTMAP_LAYER && _teststr(name,"lm") && p_node->cast_to<MeshInstance>()) { - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - String str=name; - int layer = str.substr(str.find("lm")+3,str.length()).to_int(); - //mi->set_baked_light_texture_id(layer); - } -#endif - if (_teststr(name,"colonly")) { - - if (isroot) - return p_node; - - if (p_node->cast_to<MeshInstance>()) { - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - Node * col = mi->create_trimesh_collision_node(); - ERR_FAIL_COND_V(!col,NULL); - - col->set_name(_fixstr(name,"colonly")); - col->cast_to<Spatial>()->set_transform(mi->get_transform()); - p_node->replace_by(col); - memdelete(p_node); - p_node=col; - - StaticBody *sb = col->cast_to<StaticBody>(); - CollisionShape *colshape = memnew( CollisionShape); - colshape->set_shape(sb->get_shape(0)); - colshape->set_name("shape"); - sb->add_child(colshape); - colshape->set_owner(p_node->get_owner()); - } else if (p_node->has_meta("empty_draw_type")) { - String empty_draw_type = String(p_node->get_meta("empty_draw_type")); - print_line(empty_draw_type); - StaticBody *sb = memnew( StaticBody); - sb->set_name(_fixstr(name,"colonly")); - sb->cast_to<Spatial>()->set_transform(p_node->cast_to<Spatial>()->get_transform()); - p_node->replace_by(sb); - memdelete(p_node); - CollisionShape *colshape = memnew( CollisionShape); - if (empty_draw_type == "CUBE") { - BoxShape *boxShape = memnew( BoxShape); - boxShape->set_extents(Vector3(1, 1, 1)); - colshape->set_shape(boxShape); - colshape->set_name("BoxShape"); - } else if (empty_draw_type == "SINGLE_ARROW") { - RayShape *rayShape = memnew( RayShape); - rayShape->set_length(1); - colshape->set_shape(rayShape); - colshape->set_name("RayShape"); - sb->cast_to<Spatial>()->rotate_x(Math_PI / 2); - } else if (empty_draw_type == "IMAGE") { - PlaneShape *planeShape = memnew( PlaneShape); - colshape->set_shape(planeShape); - colshape->set_name("PlaneShape"); - } else { - SphereShape *sphereShape = memnew( SphereShape); - sphereShape->set_radius(1); - colshape->set_shape(sphereShape); - colshape->set_name("SphereShape"); - } - sb->add_child(colshape); - colshape->set_owner(sb->get_owner()); - } - - } else if (_teststr(name,"rigid") && p_node->cast_to<MeshInstance>()) { - - if (isroot) - return p_node; - - // get mesh instance and bounding box - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - Rect3 aabb = mi->get_aabb(); - - // create a new rigid body collision node - RigidBody * rigid_body = memnew( RigidBody ); - Node * col = rigid_body; - ERR_FAIL_COND_V(!col,NULL); - - // remove node name postfix - col->set_name(_fixstr(name,"rigid")); - // get mesh instance xform matrix to the rigid body collision node - col->cast_to<Spatial>()->set_transform(mi->get_transform()); - // save original node by duplicating it into a new instance and correcting the name - Node * mesh = p_node->duplicate(); - mesh->set_name(_fixstr(name,"rigid")); - // reset the xform matrix of the duplicated node so it can inherit parent node xform - mesh->cast_to<Spatial>()->set_transform(Transform(Basis())); - // reparent the new mesh node to the rigid body collision node - p_node->add_child(mesh); - mesh->set_owner(p_node->get_owner()); - // replace the original node with the rigid body collision node - p_node->replace_by(col); - memdelete(p_node); - p_node=col; - - // create an alias for the rigid body collision node - RigidBody *rb = col->cast_to<RigidBody>(); - // create a new Box collision shape and set the right extents - Ref<BoxShape> shape = memnew( BoxShape ); - shape->set_extents(aabb.get_size() * 0.5); - CollisionShape *colshape = memnew( CollisionShape); - colshape->set_name("shape"); - colshape->set_shape(shape); - // reparent the new collision shape to the rigid body collision node - rb->add_child(colshape); - colshape->set_owner(p_node->get_owner()); - - } else if (_teststr(name,"col") && p_node->cast_to<MeshInstance>()) { - - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - mi->set_name(_fixstr(name,"col")); - Node *col= mi->create_trimesh_collision_node(); - ERR_FAIL_COND_V(!col,NULL); - - col->set_name("col"); - p_node->add_child(col); - - StaticBody *sb=col->cast_to<StaticBody>(); - CollisionShape *colshape = memnew( CollisionShape); - colshape->set_shape(sb->get_shape(0)); - colshape->set_name("shape"); - col->add_child(colshape); - colshape->set_owner(p_node->get_owner()); - sb->set_owner(p_node->get_owner()); - - } else if (_teststr(name,"navmesh") && p_node->cast_to<MeshInstance>()) { - - if (isroot) - return p_node; - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - Ref<Mesh> mesh=mi->get_mesh(); - ERR_FAIL_COND_V(mesh.is_null(),NULL); - NavigationMeshInstance *nmi = memnew( NavigationMeshInstance ); - - - nmi->set_name(_fixstr(name,"navmesh")); - Ref<NavigationMesh> nmesh = memnew( NavigationMesh); - nmesh->create_from_mesh(mesh); - nmi->set_navigation_mesh(nmesh); - nmi->cast_to<Spatial>()->set_transform(mi->get_transform()); - p_node->replace_by(nmi); - memdelete(p_node); - p_node=nmi; - } else if (_teststr(name,"vehicle")) { - - if (isroot) - return p_node; - - Node *owner = p_node->get_owner(); - Spatial *s = p_node->cast_to<Spatial>(); - VehicleBody *bv = memnew( VehicleBody ); - String n = _fixstr(p_node->get_name(),"vehicle"); - bv->set_name(n); - p_node->replace_by(bv); - p_node->set_name(n); - bv->add_child(p_node); - bv->set_owner(owner); - p_node->set_owner(owner); - bv->set_transform(s->get_transform()); - s->set_transform(Transform()); - - p_node=bv; - - - } else if (_teststr(name,"wheel")) { - - if (isroot) - return p_node; - - Node *owner = p_node->get_owner(); - Spatial *s = p_node->cast_to<Spatial>(); - VehicleWheel *bv = memnew( VehicleWheel ); - String n = _fixstr(p_node->get_name(),"wheel"); - bv->set_name(n); - p_node->replace_by(bv); - p_node->set_name(n); - bv->add_child(p_node); - bv->set_owner(owner); - p_node->set_owner(owner); - bv->set_transform(s->get_transform()); - s->set_transform(Transform()); - - p_node=bv; - - } else if (_teststr(name,"room") && p_node->cast_to<MeshInstance>()) { - - - if (isroot) - return p_node; - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - PoolVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID); - - - BSP_Tree bsptree(faces); - - Ref<RoomBounds> area = memnew( RoomBounds ); - //area->set_bounds(faces); - //area->set_geometry_hint(faces); - - - Room * room = memnew( Room ); - room->set_name(_fixstr(name,"room")); - room->set_transform(mi->get_transform()); - room->set_room(area); - - p_node->replace_by(room); - memdelete(p_node); - p_node=room; - - } else if (_teststr(name,"room")) { - - if (isroot) - return p_node; - - Spatial *dummy = p_node->cast_to<Spatial>(); - ERR_FAIL_COND_V(!dummy,NULL); - - Room * room = memnew( Room ); - room->set_name(_fixstr(name,"room")); - room->set_transform(dummy->get_transform()); - - p_node->replace_by(room); - memdelete(p_node); - p_node=room; - - //room->compute_room_from_subtree(); - - } else if (_teststr(name,"portal") && p_node->cast_to<MeshInstance>()) { - - if (isroot) - return p_node; - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - PoolVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID); - - ERR_FAIL_COND_V(faces.size()==0,NULL); - //step 1 compute the plane - Set<Vector3> points; - Plane plane; - - Vector3 center; - - for(int i=0;i<faces.size();i++) { - - Face3 f = faces.get(i); - Plane p = f.get_plane(); - plane.normal+=p.normal; - plane.d+=p.d; - - for(int i=0;i<3;i++) { - - Vector3 v = f.vertex[i].snapped(0.01); - if (!points.has(v)) { - points.insert(v); - center+=v; - } - } - } - - plane.normal.normalize(); - plane.d/=faces.size(); - center/=points.size(); - - //step 2, create points - - Transform t; - t.basis.from_z(plane.normal); - t.basis.transpose(); - t.origin=center; - - Vector<Point2> portal_points; - - for(Set<Vector3>::Element *E=points.front();E;E=E->next()) { - - Vector3 local = t.xform_inv(E->get()); - portal_points.push_back(Point2(local.x,local.y)); - } - // step 3 bubbly sort points - - int swaps=0; - - do { - swaps=0; - - for(int i=0;i<portal_points.size()-1;i++) { - - float a = portal_points[i].angle(); - float b = portal_points[i+1].angle(); - - if (a>b) { - SWAP( portal_points[i], portal_points[i+1] ); - swaps++; - } - - } - - } while(swaps); - - - Portal *portal = memnew( Portal ); - - portal->set_shape(portal_points); - portal->set_transform( mi->get_transform() * t); - - p_node->replace_by(portal); - memdelete(p_node); - p_node=portal; - - } else if (p_node->cast_to<MeshInstance>()) { - - //last attempt, maybe collision insde the mesh data - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - Ref<Mesh> mesh = mi->get_mesh(); - if (!mesh.is_null()) { - - if (_teststr(mesh->get_name(),"col")) { - - mesh->set_name( _fixstr(mesh->get_name(),"col") ); - Ref<Shape> shape; - - if (collision_map.has(mesh)) { - shape = collision_map[mesh]; - - } else { - - shape = mesh->create_trimesh_shape(); - if (!shape.is_null()) - collision_map[mesh]=shape; - - - } - - if (!shape.is_null()) { -#if 0 - StaticBody* static_body = memnew( StaticBody ); - ERR_FAIL_COND_V(!static_body,NULL); - static_body->set_name( String(mesh->get_name()) + "_col" ); - shape->set_name(static_body->get_name()); - static_body->add_shape(shape); - - mi->add_child(static_body); - if (mi->get_owner()) - static_body->set_owner( mi->get_owner() ); -#endif - } - - } - - for(int i=0;i<mesh->get_surface_count();i++) { - - Ref<FixedSpatialMaterial> fm = mesh->surface_get_material(i); - if (fm.is_valid()) { - String name = fm->get_name(); - /* if (_teststr(name,"alpha")) { - fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); - name=_fixstr(name,"alpha"); - } - - if (_teststr(name,"vcol")) { - fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY,true); - name=_fixstr(name,"vcol"); - }*/ - fm->set_name(name); - } - } - - } - - } - - - return p_node; -} - - -void ResourceImporterScene::_create_clips(Node *scene, const Array& p_clips,bool p_bake_all) { - - if (!scene->has_node(String("AnimationPlayer"))) - return; - - Node* n = scene->get_node(String("AnimationPlayer")); - ERR_FAIL_COND(!n); - AnimationPlayer *anim = n->cast_to<AnimationPlayer>(); - ERR_FAIL_COND(!anim); - - if (!anim->has_animation("default")) - return; - - - Ref<Animation> default_anim = anim->get_animation("default"); - - for(int i=0;i<p_clips.size();i+=4) { - - String name = p_clips[i]; - float from=p_clips[i+1]; - float to=p_clips[i+2]; - bool loop=p_clips[i+3]; - if (from>=to) - continue; - - Ref<Animation> new_anim = memnew( Animation ); - - for(int j=0;j<default_anim->get_track_count();j++) { - - - List<float> keys; - int kc = default_anim->track_get_key_count(j); - int dtrack=-1; - for(int k=0;k<kc;k++) { - - float kt = default_anim->track_get_key_time(j,k); - if (kt>=from && kt<to) { - - //found a key within range, so create track - if (dtrack==-1) { - new_anim->add_track(default_anim->track_get_type(j)); - dtrack = new_anim->get_track_count()-1; - new_anim->track_set_path(dtrack,default_anim->track_get_path(j)); - - if (kt>(from+0.01) && k>0) { - - if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { - Quat q; - Vector3 p; - Vector3 s; - default_anim->transform_track_interpolate(j,from,&p,&q,&s); - new_anim->transform_track_insert_key(dtrack,0,p,q,s); - } - } - - } - - if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { - Quat q; - Vector3 p; - Vector3 s; - default_anim->transform_track_get_key(j,k,&p,&q,&s); - new_anim->transform_track_insert_key(dtrack,kt-from,p,q,s); - } - - } - - if (dtrack!=-1 && kt>=to) { - - if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { - Quat q; - Vector3 p; - Vector3 s; - default_anim->transform_track_interpolate(j,to,&p,&q,&s); - new_anim->transform_track_insert_key(dtrack,to-from,p,q,s); - } - } - - } - - if (dtrack==-1 && p_bake_all) { - new_anim->add_track(default_anim->track_get_type(j)); - dtrack = new_anim->get_track_count()-1; - new_anim->track_set_path(dtrack,default_anim->track_get_path(j)); - if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { - - - Quat q; - Vector3 p; - Vector3 s; - default_anim->transform_track_interpolate(j,from,&p,&q,&s); - new_anim->transform_track_insert_key(dtrack,0,p,q,s); - default_anim->transform_track_interpolate(j,to,&p,&q,&s); - new_anim->transform_track_insert_key(dtrack,to-from,p,q,s); - } - - } - } - - - new_anim->set_loop(loop); - new_anim->set_length(to-from); - anim->add_animation(name,new_anim); - } - - anim->remove_animation("default"); //remove default (no longer needed) -} - -void ResourceImporterScene::_filter_anim_tracks(Ref<Animation> anim,Set<String> &keep) { - - Ref<Animation> a = anim; - ERR_FAIL_COND(!a.is_valid()); - - print_line("From Anim "+anim->get_name()+":"); - - for(int j=0;j<a->get_track_count();j++) { - - String path = a->track_get_path(j); - - if (!keep.has(path)) { - - print_line("Remove: "+path); - a->remove_track(j); - j--; - } - - } -} - - -void ResourceImporterScene::_filter_tracks(Node *scene, const String& p_text) { - - if (!scene->has_node(String("AnimationPlayer"))) - return; - Node* n = scene->get_node(String("AnimationPlayer")); - ERR_FAIL_COND(!n); - AnimationPlayer *anim = n->cast_to<AnimationPlayer>(); - ERR_FAIL_COND(!anim); - - Vector<String> strings = p_text.split("\n"); - for(int i=0;i<strings.size();i++) { - - strings[i]=strings[i].strip_edges(); - } - - List<StringName> anim_names; - anim->get_animation_list(&anim_names); - for(List<StringName>::Element *E=anim_names.front();E;E=E->next()) { - - String name = E->get(); - bool valid_for_this=false; - bool valid=false; - - Set<String> keep; - Set<String> keep_local; - - - for(int i=0;i<strings.size();i++) { - - - if (strings[i].begins_with("@")) { - - valid_for_this=false; - for(Set<String>::Element *F=keep_local.front();F;F=F->next()) { - keep.insert(F->get()); - } - keep_local.clear(); - - Vector<String> filters=strings[i].substr(1,strings[i].length()).split(","); - for(int j=0;j<filters.size();j++) { - - String fname = filters[j].strip_edges(); - if (fname=="") - continue; - int fc = fname[0]; - bool plus; - if (fc=='+') - plus=true; - else if (fc=='-') - plus=false; - else - continue; - - String filter=fname.substr(1,fname.length()).strip_edges(); - - if (!name.matchn(filter)) - continue; - valid_for_this=plus; - } - - if (valid_for_this) - valid=true; - - } else if (valid_for_this) { - - Ref<Animation> a = anim->get_animation(name); - if (!a.is_valid()) - continue; - - for(int j=0;j<a->get_track_count();j++) { - - String path = a->track_get_path(j); - - String tname = strings[i]; - if (tname=="") - continue; - int fc = tname[0]; - bool plus; - if (fc=='+') - plus=true; - else if (fc=='-') - plus=false; - else - continue; - - String filter=tname.substr(1,tname.length()).strip_edges(); - - if (!path.matchn(filter)) - continue; - - if (plus) - keep_local.insert(path); - else if (!keep.has(path)) { - keep_local.erase(path); - } - } - - } - - } - - if (valid) { - for(Set<String>::Element *F=keep_local.front();F;F=F->next()) { - keep.insert(F->get()); - } - _filter_anim_tracks(anim->get_animation(name),keep); - } else { - - } - - } - - - -} - -void ResourceImporterScene::_optimize_animations(Node *scene, float p_max_lin_error,float p_max_ang_error,float p_max_angle) { - - if (!scene->has_node(String("AnimationPlayer"))) - return; - Node* n = scene->get_node(String("AnimationPlayer")); - ERR_FAIL_COND(!n); - AnimationPlayer *anim = n->cast_to<AnimationPlayer>(); - ERR_FAIL_COND(!anim); - - - List<StringName> anim_names; - anim->get_animation_list(&anim_names); - for(List<StringName>::Element *E=anim_names.front();E;E=E->next()) { - - Ref<Animation> a = anim->get_animation(E->get()); - a->optimize(p_max_lin_error,p_max_ang_error,Math::deg2rad(p_max_angle)); - } -} - - -static String _make_extname(const String& p_str) { - - String ext_name=p_str.replace(".","_"); - ext_name=ext_name.replace(":","_"); - ext_name=ext_name.replace("\"","_"); - ext_name=ext_name.replace("<","_"); - ext_name=ext_name.replace(">","_"); - ext_name=ext_name.replace("/","_"); - ext_name=ext_name.replace("|","_"); - ext_name=ext_name.replace("\\","_"); - ext_name=ext_name.replace("?","_"); - ext_name=ext_name.replace("*","_"); - - return ext_name; -} - -void ResourceImporterScene::_make_external_resources(Node* p_node,const String& p_base_path, bool p_make_materials, bool p_make_meshes, Map<Ref<Material>,Ref<Material> >& p_materials, Map<Ref<Mesh>,Ref<Mesh> >& p_meshes) { - - List<PropertyInfo> pi; - - p_node->get_property_list(&pi); - - for (List<PropertyInfo>::Element *E=pi.front();E;E=E->next()) { - - if (E->get().type==Variant::OBJECT) { - - Ref<Material> mat = p_node->get(E->get().name); - if (p_make_materials && mat.is_valid() && mat->get_name()!="") { - - - if (!p_materials.has(mat)) { - - String ext_name = p_base_path+"."+_make_extname(mat->get_name())+".mtl"; - if (FileAccess::exists(ext_name)) { - //if exists, use it - Ref<Material> existing = ResourceLoader::load(ext_name); - p_materials[mat]=existing; - } else { - - ResourceSaver::save(ext_name,mat,ResourceSaver::FLAG_CHANGE_PATH); - p_materials[mat]=mat; - } - } - - if (p_materials[mat]!=mat) { - - p_node->set(E->get().name,p_materials[mat]); - } - } else { - - Ref<Mesh> mesh = p_node->get(E->get().name); - - if (mesh.is_valid()) { - - bool mesh_just_added=false; - - if (p_make_meshes) { - - if (!p_meshes.has(mesh)) { - - String ext_name = p_base_path+"."+_make_extname(mesh->get_name())+".msh"; - if (FileAccess::exists(ext_name)) { - //if exists, use it - Ref<Mesh> existing = ResourceLoader::load(ext_name); - p_meshes[mesh]=existing; - } else { - - ResourceSaver::save(ext_name,mesh,ResourceSaver::FLAG_CHANGE_PATH); - p_meshes[mesh]=mesh; - mesh_just_added=true; - } - - - } - } - - - if (p_make_materials){ - - if (mesh_just_added || !p_meshes.has(mesh)) { - - - for(int i=0;i<mesh->get_surface_count();i++) { - mat=mesh->surface_get_material(i); - if (!mat.is_valid() || mat->get_name()=="") - continue; - - if (!p_materials.has(mat)) { - - String ext_name = p_base_path+"."+_make_extname(mat->get_name())+".mtl"; - if (FileAccess::exists(ext_name)) { - //if exists, use it - Ref<Material> existing = ResourceLoader::load(ext_name); - p_materials[mat]=existing; - } else { - - ResourceSaver::save(ext_name,mat,ResourceSaver::FLAG_CHANGE_PATH); - p_materials[mat]=mat; - } - } - - if (p_materials[mat]!=mat) { - - mesh->surface_set_material(i,p_materials[mat]); - } - - } - - if(!p_make_meshes) { - p_meshes[mesh]=Ref<Mesh>(); //save it anyway, so it won't be checked again - } - } - } - } - } - } - } - - for(int i=0;i<p_node->get_child_count();i++) { - - _make_external_resources(p_node->get_child(i),p_base_path,p_make_materials,p_make_meshes,p_materials,p_meshes); - } -} - - -void ResourceImporterScene::get_import_options(List<ImportOption> *r_options,int p_preset) const { - - - r_options->push_back(ImportOption(PropertyInfo(Variant::STRING,"nodes/root_type",PROPERTY_HINT_TYPE_STRING,"Node"),"Spatial")); - r_options->push_back(ImportOption(PropertyInfo(Variant::STRING,"nodes/root_name"),"Scene Root")); - - List<String> script_extentions; - ResourceLoader::get_recognized_extensions_for_type("Script",&script_extentions); - - String script_ext_hint; - - for(List<String>::Element *E=script_extentions.front();E;E=E->next()) { - if (script_ext_hint!="") - script_ext_hint+=","; - script_ext_hint+="*."+E->get(); - } - - r_options->push_back(ImportOption(PropertyInfo(Variant::STRING,"nodes/custom_script",PROPERTY_HINT_FILE,script_ext_hint),"")); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"materials/location",PROPERTY_HINT_ENUM,"Node,Mesh"),0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"materials/storage",PROPERTY_HINT_ENUM,"Bult-In,Files"),0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"geometry/compress"),true)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"geometry/ensure_tangents"),true)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"geometry/storage",PROPERTY_HINT_ENUM,"Built-In,Files"),0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"animation/import",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED),true)); - r_options->push_back(ImportOption(PropertyInfo(Variant::REAL,"animation/fps",PROPERTY_HINT_RANGE,"1,120,1"),15)); - r_options->push_back(ImportOption(PropertyInfo(Variant::STRING,"animation/filter_script",PROPERTY_HINT_MULTILINE_TEXT),"")); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"animation/optimizer/enabled",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED),true)); - r_options->push_back(ImportOption(PropertyInfo(Variant::REAL,"animation/optimizer/max_linear_error"),0.05)); - r_options->push_back(ImportOption(PropertyInfo(Variant::REAL,"animation/optimizer/max_angular_error"),0.01)); - r_options->push_back(ImportOption(PropertyInfo(Variant::REAL,"animation/optimizer/max_angle"),22)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"animation/optimizer/remove_unused_tracks"),true)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"animation/clips/amount",PROPERTY_HINT_RANGE,"0,256,1",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED),0)); - for(int i=0;i<256;i++) { - r_options->push_back(ImportOption(PropertyInfo(Variant::STRING,"animation/clip_"+itos(i+1)+"/name"),"")); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"animation/clip_"+itos(i+1)+"/start_frame"),0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"animation/clip_"+itos(i+1)+"/end_frame"),0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"animation/clip_"+itos(i+1)+"/loops"),false)); - } -} - -Error ResourceImporterScene::import(const String& p_source_file, const String& p_save_path, const Map<StringName,Variant>& p_options, List<String>* r_platform_variants, List<String> *r_gen_files) { - - String src_path=p_source_file; - - Ref<EditorSceneImporter> importer; - String ext=src_path.get_extension().to_lower(); - - - EditorProgress progress("import",TTR("Import Scene"),104); - progress.step(TTR("Importing Scene.."),0); - - for(Set< Ref<EditorSceneImporter> >::Element *E=importers.front();E;E=E->next()) { - - List<String> extensions; - E->get()->get_extensions(&extensions); - - for(List<String>::Element *F=extensions.front();F;F=F->next()) { - - if (F->get().to_lower()==ext) { - - importer = E->get(); - break; - } - } - - if (importer.is_valid()) - break; - } - - ERR_FAIL_COND_V(!importer.is_valid(),ERR_FILE_UNRECOGNIZED); - - float fps=p_options["animation/fps"]; - - - - int import_flags=EditorSceneImporter::IMPORT_ANIMATION_DETECT_LOOP; - if (!bool(p_options["animation/optimizer/remove_unused_tracks"])) - import_flags|=EditorSceneImporter::IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS; - - if (bool(p_options["animation/import"])) - import_flags|=EditorSceneImporter::IMPORT_ANIMATION; - - if (bool(p_options["geometry/ensure_tangents"])) - import_flags|=EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS; - - if (int(p_options["materials/location"])==0) - import_flags|=EditorSceneImporter::IMPORT_MATERIALS_IN_INSTANCES; - - - Error err=OK; - List<String> missing_deps; // for now, not much will be done with this - Node *scene = importer->import_scene(src_path,import_flags,fps,&missing_deps,&err); - if (!scene || err!=OK) { - return err; - } - - String root_type = p_options["nodes/root_type"]; - - if (scene->get_class()!=root_type) { - Object *base = ClassDB::instance(root_type); - Node *base_node = NULL; - if (base) - base_node=base->cast_to<Node>(); - - if (base_node) { - - scene->replace_by(base_node); - memdelete(scene); - scene=base_node; - } - } - - scene->set_name(p_options["nodes/root_name"]); - - - err=OK; - - String animation_filter = String(p_options["animation/filter_script"]).strip_edges(); - - bool use_optimizer = p_options["animation/optimizer/enabled"]; - float anim_optimizer_linerr=p_options["animation/optimizer/max_linear_error"]; - float anim_optimizer_angerr=p_options["animation/optimizer/max_angular_error"]; - float anim_optimizer_maxang=p_options["animation/optimizer/max_angle"]; - - Map<Ref<Mesh>,Ref<Shape> > collision_map; - - scene=_fix_node(scene,scene,collision_map); - - if (use_optimizer) { - _optimize_animations(scene,anim_optimizer_linerr,anim_optimizer_angerr,anim_optimizer_maxang); - } - - Array animation_clips; - { - - - int clip_count = p_options["animation/clips/amount"]; - - for(int i=0;i<clip_count;i++) { - String name = p_options["animation/clip_"+itos(i+1)+"/name"]; - int from_frame = p_options["animation/clip_"+itos(i+1)+"/start_frame"]; - int end_frame = p_options["animation/clip_"+itos(i+1)+"/end_frame"]; - bool loop = p_options["animation/clip_"+itos(i+1)+"/loops"]; - - animation_clips.push_back(name); - animation_clips.push_back(from_frame/fps); - animation_clips.push_back(end_frame/fps); - animation_clips.push_back(loop); - } - - } - if (animation_clips.size()) { - _create_clips(scene,animation_clips,!bool(p_options["animation/optimizer/remove_unused_tracks"])); - } - - if (animation_filter!="") { - _filter_tracks(scene,animation_filter); - } - - - bool external_materials = p_options["materials/storage"]; - bool external_meshes = p_options["geometry/storage"]; - - if (external_materials || external_meshes) { - Map<Ref<Material>, Ref<Material> > mat_map; - Map<Ref<Mesh>, Ref<Mesh> > mesh_map; - _make_external_resources(scene,p_source_file.get_basename(),external_materials,external_meshes,mat_map,mesh_map); - } - - progress.step(TTR("Running Custom Script.."),2); - - String post_import_script_path = p_options["nodes/custom_script"]; - Ref<EditorScenePostImport> post_import_script; - - if (post_import_script_path!="") { - post_import_script_path = post_import_script_path; // FIXME: is there a good reason for this? - Ref<Script> scr = ResourceLoader::load(post_import_script_path); - if (!scr.is_valid()) { - EditorNode::add_io_error(TTR("Couldn't load post-import script:")+" "+post_import_script_path); - } else { - - post_import_script = Ref<EditorScenePostImport>( memnew( EditorScenePostImport ) ); - post_import_script->set_script(scr.get_ref_ptr()); - if (!post_import_script->get_script_instance()) { - EditorNode::add_io_error(TTR("Invalid/broken script for post-import (check console):")+" "+post_import_script_path); - post_import_script.unref(); - return ERR_CANT_CREATE; - } - } - } - - - if (post_import_script.is_valid()) { - scene = post_import_script->post_import(scene); - if (!scene) { - EditorNode::add_io_error(TTR("Error running post-import script:")+" "+post_import_script_path); - return err; - } - - - } - - progress.step(TTR("Saving.."),104); - - Ref<PackedScene> packer = memnew( PackedScene ); - packer->pack(scene); - print_line("SAVING TO: "+p_save_path+".scn"); - err = ResourceSaver::save(p_save_path+".scn",packer); //do not take over, let the changed files reload themselves - - memdelete(scene); - - EditorNode::get_singleton()->reload_scene(p_source_file); - - return OK; -} - -ResourceImporterScene *ResourceImporterScene::singleton=NULL; - -ResourceImporterScene::ResourceImporterScene() -{ - singleton=this; -} diff --git a/tools/editor/import/resource_importer_texture.cpp b/tools/editor/import/resource_importer_texture.cpp deleted file mode 100644 index 21e434fa11..0000000000 --- a/tools/editor/import/resource_importer_texture.cpp +++ /dev/null @@ -1,393 +0,0 @@ -#include "resource_importer_texture.h" -#include "io/image_loader.h" -#include "scene/resources/texture.h" -#include "tools/editor/editor_file_system.h" -#include "io/config_file.h" - - -void ResourceImporterTexture::_texture_reimport_srgb(const Ref<StreamTexture>& p_tex) { - - singleton->mutex->lock(); - StringName path = p_tex->get_path(); - - if (!singleton->make_flags.has(path)) { - singleton->make_flags[path]=0; - } - - singleton->make_flags[path]|=MAKE_SRGB_FLAG; - - print_line("requesting srgb for "+String(path)); - - singleton->mutex->unlock(); - -} - - - -void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture>& p_tex) { - - - singleton->mutex->lock(); - StringName path = p_tex->get_path(); - - if (!singleton->make_flags.has(path)) { - singleton->make_flags[path]=0; - } - - singleton->make_flags[path]|=MAKE_3D_FLAG; - - print_line("requesting 3d for "+String(path)); - - singleton->mutex->unlock(); - - -} - -void ResourceImporterTexture::update_imports() { - - if (EditorFileSystem::get_singleton()->is_scanning() || EditorFileSystem::get_singleton()->is_importing()) { - return; // do nothing for noe - } - mutex->lock(); - - if (make_flags.empty()) { - mutex->unlock(); - return; - } - - Vector<String> to_reimport; - for (Map<StringName,int>::Element *E=make_flags.front();E;E=E->next()) { - - print_line("checking for reimport "+String(E->key())); - - - Ref<ConfigFile> cf; - cf.instance(); - String src_path = String(E->key())+".import"; - - Error err = cf->load(src_path); - ERR_CONTINUE(err!=OK); - - bool changed=false; - if (E->get()&MAKE_SRGB_FLAG && int(cf->get_value("params","flags/srgb"))==2) { - cf->set_value("params","flags/srgb",1); - changed=true; - } - - if (E->get()&MAKE_3D_FLAG && bool(cf->get_value("params","detect_3d"))) { - cf->set_value("params","detect_3d",false); - cf->set_value("params","compress/mode",2); - cf->set_value("params","flags/repeat",true); - cf->set_value("params","flags/filter",true); - cf->set_value("params","flags/mipmaps",true); - changed=true; - } - - if (changed) { - cf->save(src_path); - to_reimport.push_back(E->key()); - } - - } - - make_flags.clear(); - - mutex->unlock(); - - if (to_reimport.size()) { - EditorFileSystem::get_singleton()->reimport_files(to_reimport); - } - -} - - - -String ResourceImporterTexture::get_importer_name() const { - - return "texture"; -} - -String ResourceImporterTexture::get_visible_name() const{ - - return "Texture"; -} -void ResourceImporterTexture::get_recognized_extensions(List<String> *p_extensions) const{ - - ImageLoader::get_recognized_extensions(p_extensions); -} -String ResourceImporterTexture::get_save_extension() const { - return "stex"; -} - -String ResourceImporterTexture::get_resource_type() const{ - - return "StreamTexture"; -} - -bool ResourceImporterTexture::get_option_visibility(const String& p_option,const Map<StringName,Variant>& p_options) const { - - if (p_option=="compress/lossy_quality" && int(p_options["compress/mode"])!=COMPRESS_LOSSY) - return false; - - return true; -} - -int ResourceImporterTexture::get_preset_count() const { - return 4; -} -String ResourceImporterTexture::get_preset_name(int p_idx) const { - - static const char* preset_names[]={ - "2D, Detect 3D", - "2D", - "2D Pixel", - "3D" - }; - - return preset_names[p_idx]; -} - - -void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,int p_preset) const { - - - r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"compress/mode",PROPERTY_HINT_ENUM,"Lossless,Lossy,Video RAM,Uncompressed",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED),p_preset==PRESET_3D?2:0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::REAL,"compress/lossy_quality",PROPERTY_HINT_RANGE,"0,1,0.01"),0.7)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"flags/repeat",PROPERTY_HINT_ENUM,"Disabled,Enabled,Mirrored"),p_preset==PRESET_3D?1:0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"flags/filter"),p_preset==PRESET_2D_PIXEL?false:true)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"flags/mipmaps"),p_preset==PRESET_3D?true:false)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"flags/anisotropic"),false)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"flags/srgb",PROPERTY_HINT_ENUM,"Disable,Enable,Detect"),2)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"process/fix_alpha_border"),p_preset!=PRESET_3D?true:false)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"process/premult_alpha"),true)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"stream"),false)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"size_limit",PROPERTY_HINT_RANGE,"0,4096,1"),0)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"detect_3d"),p_preset==PRESET_DETECT)); - -} - - -void ResourceImporterTexture::_save_stex(const Image& p_image, const String& p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable, bool p_detect_3d, bool p_detect_srgb) { - - - FileAccess *f = FileAccess::open(p_to_path,FileAccess::WRITE); - f->store_8('G'); - f->store_8('D'); - f->store_8('S'); - f->store_8('T'); //godot streamable texture - - f->store_32(p_image.get_width()); - f->store_32(p_image.get_height()); - f->store_32(p_texture_flags); - - uint32_t format=0; - - if (p_streamable) - format|=StreamTexture::FORMAT_BIT_STREAM; - if (p_mipmaps || p_compress_mode==COMPRESS_VIDEO_RAM) //VRAM always uses mipmaps - format|=StreamTexture::FORMAT_BIT_HAS_MIPMAPS; //mipmaps bit - if (p_detect_3d) - format|=StreamTexture::FORMAT_BIT_DETECT_3D; - if (p_detect_srgb) - format|=StreamTexture::FORMAT_BIT_DETECT_SRGB; - - - switch (p_compress_mode) { - case COMPRESS_LOSSLESS: { - - Image image = p_image; - if (p_mipmaps) { - image.generate_mipmaps(); - } else { - image.clear_mipmaps(); - } - - int mmc = image.get_mipmap_count() + 1; - - format|=StreamTexture::FORMAT_BIT_LOSSLESS; - f->store_32(format); - f->store_32(mmc); - - for(int i=0;i<mmc;i++) { - - if (i>0) { - image.shrink_x2(); - } - - PoolVector<uint8_t> data = Image::lossless_packer(image); - int data_len = data.size(); - f->store_32(data_len); - - PoolVector<uint8_t>::Read r= data.read(); - f->store_buffer(r.ptr(),data_len); - - } - - - } break; - case COMPRESS_LOSSY: { - Image image = p_image; - if (p_mipmaps) { - image.generate_mipmaps(); - } else { - image.clear_mipmaps(); - } - - int mmc = image.get_mipmap_count() + 1; - - format|=StreamTexture::FORMAT_BIT_LOSSY; - f->store_32(format); - f->store_32(mmc); - - for(int i=0;i<mmc;i++) { - - if (i>0) { - image.shrink_x2(); - } - - PoolVector<uint8_t> data = Image::lossy_packer(image,p_lossy_quality); - int data_len = data.size(); - f->store_32(data_len); - - PoolVector<uint8_t>::Read r = data.read(); - f->store_buffer(r.ptr(),data_len); - - } - } break; - case COMPRESS_VIDEO_RAM: { - - Image image = p_image; - image.generate_mipmaps(); - image.compress(p_vram_compression); - - format |= image.get_format(); - - f->store_32(format); - - PoolVector<uint8_t> data=image.get_data(); - int dl = data.size(); - PoolVector<uint8_t>::Read r = data.read(); - f->store_buffer(r.ptr(),dl); - - } break; - case COMPRESS_UNCOMPRESSED: { - - Image image = p_image; - if (p_mipmaps) { - image.generate_mipmaps(); - } else { - image.clear_mipmaps(); - } - - format |= image.get_format(); - f->store_32(format); - - PoolVector<uint8_t> data=image.get_data(); - int dl = data.size(); - PoolVector<uint8_t>::Read r = data.read(); - - f->store_buffer(r.ptr(),dl); - - } break; - } - - memdelete(f); -} - -Error ResourceImporterTexture::import(const String& p_source_file, const String& p_save_path, const Map<StringName,Variant>& p_options, List<String>* r_platform_variants, List<String> *r_gen_files) { - - int compress_mode = p_options["compress/mode"]; - float lossy= p_options["compress/lossy_quality"]; - int repeat= p_options["flags/repeat"]; - bool filter= p_options["flags/filter"]; - bool mipmaps= p_options["flags/mipmaps"]; - bool anisotropic= p_options["flags/anisotropic"]; - int srgb= p_options["flags/srgb"]; - bool fix_alpha_border= p_options["process/fix_alpha_border"]; - bool premult_alpha= p_options["process/premult_alpha"]; - bool stream = p_options["stream"]; - int size_limit = p_options["size_limit"]; - - - Image image; - Error err = ImageLoader::load_image(p_source_file,&image); - if (err!=OK) - return err; - - - int tex_flags=0; - if (repeat>0) - tex_flags|=Texture::FLAG_REPEAT; - if (repeat==2) - tex_flags|=Texture::FLAG_MIRRORED_REPEAT; - if (filter) - tex_flags|=Texture::FLAG_FILTER; - if (mipmaps || compress_mode==COMPRESS_VIDEO_RAM) - tex_flags|=Texture::FLAG_MIPMAPS; - if (anisotropic) - tex_flags|=Texture::FLAG_ANISOTROPIC_FILTER; - if (srgb==1) - tex_flags|=Texture::FLAG_CONVERT_TO_LINEAR; - - if (size_limit >0 && (image.get_width()>size_limit || image.get_height()>size_limit )) { - //limit size - if (image.get_width() >= image.get_height()) { - int new_width = size_limit; - int new_height = image.get_height() * new_width / image.get_width(); - - image.resize(new_width,new_height,Image::INTERPOLATE_CUBIC); - } else { - - int new_height = size_limit; - int new_width = image.get_width() * new_height / image.get_height(); - - image.resize(new_width,new_height,Image::INTERPOLATE_CUBIC); - } - } - - if (fix_alpha_border) { - image.fix_alpha_edges(); - } - - if (premult_alpha) { - image.premultiply_alpha(); - } - - bool detect_3d = p_options["detect_3d"]; - bool detect_srgb = srgb==2; - - if (compress_mode==COMPRESS_VIDEO_RAM) { - //must import in all formats - //Android, GLES 2.x - _save_stex(image,p_save_path+".etc.stex",compress_mode,lossy,Image::COMPRESS_ETC,mipmaps,tex_flags,stream,detect_3d,detect_srgb); - r_platform_variants->push_back("etc"); - //_save_stex(image,p_save_path+".etc2.stex",compress_mode,lossy,Image::COMPRESS_ETC2,mipmaps,tex_flags,stream); - //r_platform_variants->push_back("etc2"); - _save_stex(image,p_save_path+".s3tc.stex",compress_mode,lossy,Image::COMPRESS_S3TC,mipmaps,tex_flags,stream,detect_3d,detect_srgb); - r_platform_variants->push_back("s3tc"); - - } else { - //import normally - _save_stex(image,p_save_path+".stex",compress_mode,lossy,Image::COMPRESS_16BIT /*this is ignored */,mipmaps,tex_flags,stream,detect_3d,detect_srgb); - } - - return OK; -} - -ResourceImporterTexture *ResourceImporterTexture::singleton=NULL; - -ResourceImporterTexture::ResourceImporterTexture() -{ - - singleton=this; - StreamTexture::request_3d_callback=_texture_reimport_3d; - StreamTexture::request_srgb_callback=_texture_reimport_srgb; - mutex = Mutex::create(); -} - -ResourceImporterTexture::~ResourceImporterTexture() -{ - - memdelete(mutex); -} - diff --git a/tools/editor/io_plugins/editor_bitmask_import_plugin.cpp b/tools/editor/io_plugins/editor_bitmask_import_plugin.cpp deleted file mode 100644 index 587353fef8..0000000000 --- a/tools/editor/io_plugins/editor_bitmask_import_plugin.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/*************************************************************************/ -/* editor_bitmask_import_plugin.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 "editor_bitmask_import_plugin.h" -#if 0 -#include "io/image_loader.h" -#include "tools/editor/editor_file_dialog.h" -#include "tools/editor/editor_dir_dialog.h" -#include "tools/editor/editor_node.h" -#include "tools/editor/property_editor.h" -#include "io/resource_saver.h" -#include "os/file_access.h" -#include "io/marshalls.h" -#include "tools/editor/editor_settings.h" - -class _EditorBitMaskImportOptions : public Object { - - GDCLASS(_EditorBitMaskImportOptions, Object); -public: - - bool _set(const StringName& p_name, const Variant& p_value) { - - return false; - } - - bool _get(const StringName& p_name, Variant &r_ret) const{ - - return false; - } - - void _get_property_list(List<PropertyInfo> *p_list) const{ - - } - - static void _bind_methods() { - - ADD_SIGNAL(MethodInfo("changed")); - } - - - _EditorBitMaskImportOptions() { - - } - -}; - -class EditorBitMaskImportDialog : public ConfirmationDialog { - - GDCLASS(EditorBitMaskImportDialog, ConfirmationDialog); - - EditorBitMaskImportPlugin *plugin; - - LineEdit *import_path; - LineEdit *save_path; - EditorFileDialog *file_select; - EditorDirDialog *save_select; - ConfirmationDialog *error_dialog; - PropertyEditor *option_editor; - -public: - - void _choose_files(const Vector<String>& p_path) { - - String files; - for (int i = 0; i<p_path.size(); i++) { - - if (i>0) - files += ","; - files += p_path[i]; - } - - import_path->set_text(files); - - } - void _choose_save_dir(const String& p_path) { - - save_path->set_text(p_path); - } - - void _browse() { - - file_select->popup_centered_ratio(); - } - - void _browse_target() { - - save_select->popup_centered_ratio(); - - } - - - void popup_import(const String& p_path) { - - popup_centered(Size2(400, 100)*EDSCALE); - if (p_path != "") { - - Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); - ERR_FAIL_COND(!rimd.is_valid()); - - save_path->set_text(p_path.get_base_dir()); - - String src = ""; - for (int i = 0; i<rimd->get_source_count(); i++) { - if (i>0) - src += ","; - src += EditorImportPlugin::expand_source_path(rimd->get_source_path(i)); - } - import_path->set_text(src); - } - } - - - void _import() { - - Vector<String> bitmasks = import_path->get_text().split(","); - - if (bitmasks.size() == 0) { - error_dialog->set_text(TTR("No bit masks to import!")); - error_dialog->popup_centered(Size2(200, 100)*EDSCALE); - } - - if (save_path->get_text().strip_edges() == "") { - error_dialog->set_text(TTR("Target path is empty.")); - error_dialog->popup_centered_minsize(); - return; - } - - if (!save_path->get_text().begins_with("res://")) { - error_dialog->set_text(TTR("Target path must be a complete resource path.")); - error_dialog->popup_centered_minsize(); - return; - } - - if (!DirAccess::exists(save_path->get_text())) { - error_dialog->set_text(TTR("Target path must exist.")); - error_dialog->popup_centered_minsize(); - return; - } - - for (int i = 0; i<bitmasks.size(); i++) { - - Ref<ResourceImportMetadata> imd = memnew(ResourceImportMetadata); - - imd->add_source(EditorImportPlugin::validate_source_path(bitmasks[i])); - - String dst = save_path->get_text(); - if (dst == "") { - error_dialog->set_text(TTR("Save path is empty!")); - error_dialog->popup_centered(Size2(200, 100)*EDSCALE); - } - - dst = dst.plus_file(bitmasks[i].get_file().get_basename() + ".pbm"); - - plugin->import(dst, imd); - } - - hide(); - - } - - - void _notification(int p_what) { - - } - - static void _bind_methods() { - - - ClassDB::bind_method("_choose_files", &EditorBitMaskImportDialog::_choose_files); - ClassDB::bind_method("_choose_save_dir", &EditorBitMaskImportDialog::_choose_save_dir); - ClassDB::bind_method("_import", &EditorBitMaskImportDialog::_import); - ClassDB::bind_method("_browse", &EditorBitMaskImportDialog::_browse); - ClassDB::bind_method("_browse_target", &EditorBitMaskImportDialog::_browse_target); - //ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); - } - - EditorBitMaskImportDialog(EditorBitMaskImportPlugin *p_plugin) { - - plugin = p_plugin; - - - set_title(TTR("Import BitMasks")); - - VBoxContainer *vbc = memnew(VBoxContainer); - add_child(vbc); - //set_child_rect(vbc); - - - HBoxContainer *hbc = memnew(HBoxContainer); - vbc->add_margin_child(TTR("Source Texture(s):"), hbc); - - import_path = memnew(LineEdit); - import_path->set_h_size_flags(SIZE_EXPAND_FILL); - hbc->add_child(import_path); - - Button * import_choose = memnew(Button); - import_choose->set_text(" .. "); - hbc->add_child(import_choose); - - import_choose->connect("pressed", this, "_browse"); - - hbc = memnew(HBoxContainer); - vbc->add_margin_child(TTR("Target Path:"), hbc); - - save_path = memnew(LineEdit); - save_path->set_h_size_flags(SIZE_EXPAND_FILL); - hbc->add_child(save_path); - - Button * save_choose = memnew(Button); - save_choose->set_text(" .. "); - hbc->add_child(save_choose); - - save_choose->connect("pressed", this, "_browse_target"); - - file_select = memnew(EditorFileDialog); - file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - add_child(file_select); - file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); - file_select->connect("files_selected", this, "_choose_files"); - - List<String> extensions; - ImageLoader::get_recognized_extensions(&extensions); - file_select->clear_filters(); - for (int i = 0; i<extensions.size(); i++) { - - file_select->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper()); - } - - save_select = memnew(EditorDirDialog); - add_child(save_select); - - //save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); - save_select->connect("dir_selected", this, "_choose_save_dir"); - - get_ok()->connect("pressed", this, "_import"); - get_ok()->set_text(TTR("Import")); - - - error_dialog = memnew(ConfirmationDialog); - add_child(error_dialog); - error_dialog->get_ok()->set_text(TTR("Accept")); - //error_dialog->get_cancel()->hide(); - - set_hide_on_ok(false); - } - - ~EditorBitMaskImportDialog() { - } - -}; - - -String EditorBitMaskImportPlugin::get_name() const { - - return "bitmask"; -} -String EditorBitMaskImportPlugin::get_visible_name() const{ - - return TTR("Bit Mask"); -} -void EditorBitMaskImportPlugin::import_dialog(const String& p_from){ - - dialog->popup_import(p_from); -} -Error EditorBitMaskImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from){ - - ERR_FAIL_COND_V(p_from->get_source_count() != 1, ERR_INVALID_PARAMETER); - - Ref<ResourceImportMetadata> from = p_from; - - String src_path = EditorImportPlugin::expand_source_path(from->get_source_path(0)); - Ref<ImageTexture> it = ResourceLoader::load(src_path); - ERR_FAIL_COND_V(it.is_null(), ERR_CANT_OPEN); - - Ref<BitMap> target = memnew(BitMap); - target->create_from_image_alpha(it.ptr()->get_data()); - - from->set_source_md5(0, FileAccess::get_md5(src_path)); - from->set_editor(get_name()); - target->set_import_metadata(from); - - - Error err = ResourceSaver::save(p_path, target); - - return err; - -} - - -EditorBitMaskImportPlugin* EditorBitMaskImportPlugin::singleton = NULL; - - -void EditorBitMaskImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { - - Vector<String> files; - - List<String> valid_extensions; - ImageLoader::get_recognized_extensions(&valid_extensions); - for(int i=0;i<p_drop.size();i++) { - - String extension=p_drop[i].get_extension().to_lower(); - - for (List<String>::Element *E=valid_extensions.front();E;E=E->next()) { - - if (E->get()==extension) { - files.push_back(p_drop[i]); - break; - } - } - } - - if (files.size()) { - import_dialog(); - dialog->_choose_files(files); - dialog->_choose_save_dir(p_dest_path); - } -} - -void EditorBitMaskImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { - - if (p_list.size() == 0) - return; - - Vector<String> sources; - for (int i = 0; i<p_list.size(); i++) { - int idx; - EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->find_file(p_list[i], &idx); - if (efsd) { - for (int j = 0; j<efsd->get_source_count(idx); j++) { - String file = expand_source_path(efsd->get_source_file(idx, j)); - if (sources.find(file) == -1) { - sources.push_back(file); - } - - } - } - } - - if (sources.size()) { - - dialog->popup_import(p_list[0]); - dialog->_choose_files(sources); - dialog->_choose_save_dir(p_list[0].get_base_dir()); - } -} - -bool EditorBitMaskImportPlugin::can_reimport_multiple_files() const { - - return true; -} - -EditorBitMaskImportPlugin::EditorBitMaskImportPlugin(EditorNode* p_editor) { - - singleton = this; - dialog = memnew(EditorBitMaskImportDialog(this)); - p_editor->get_gui_base()->add_child(dialog); -} - -EditorBitMaskExportPlugin::EditorBitMaskExportPlugin() { - -} -#endif diff --git a/tools/editor/io_plugins/editor_bitmask_import_plugin.h b/tools/editor/io_plugins/editor_bitmask_import_plugin.h deleted file mode 100644 index 89ff58ec93..0000000000 --- a/tools/editor/io_plugins/editor_bitmask_import_plugin.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************/ -/* editor_bitmask_import_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITOR_BITMASK_IMPORT_PLUGIN_H -#define EDITOR_BITMASK_IMPORT_PLUGIN_H -#if 0 -#include "tools/editor/editor_import_export.h" -#include "scene/resources/font.h" - -class EditorNode; -class EditorBitMaskImportDialog; - -class EditorBitMaskImportPlugin : public EditorImportPlugin { - - GDCLASS(EditorBitMaskImportPlugin, EditorImportPlugin); - - EditorBitMaskImportDialog *dialog; -public: - - static EditorBitMaskImportPlugin *singleton; - - virtual String get_name() const; - virtual String get_visible_name() const; - virtual void import_dialog(const String& p_from = ""); - virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); - void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); - virtual void reimport_multiple_files(const Vector<String>& p_list); - virtual bool can_reimport_multiple_files() const; - - - EditorBitMaskImportPlugin(EditorNode* p_editor); -}; - -class EditorBitMaskExportPlugin : public EditorExportPlugin { - - GDCLASS(EditorBitMaskExportPlugin, EditorExportPlugin); - - -public: - - EditorBitMaskExportPlugin(); -}; - -#endif -#endif // EDITOR_SAMPLE_IMPORT_PLUGIN_H diff --git a/tools/editor/io_plugins/editor_export_scene.cpp b/tools/editor/io_plugins/editor_export_scene.cpp deleted file mode 100644 index 265526aace..0000000000 --- a/tools/editor/io_plugins/editor_export_scene.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/*************************************************************************/ -/* editor_export_scene.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 "editor_export_scene.h" -#if 0 -#include "io/resource_loader.h" -#include "io/resource_saver.h" -#include "os/dir_access.h" -#include "os/file_access.h" -#include "tools/editor/editor_settings.h" -#include "scene/resources/packed_scene.h" -#include "global_config.h" - -Vector<uint8_t> EditorSceneExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) { - - if (!EditorImportExport::get_singleton()->get_convert_text_scenes()) { - return Vector<uint8_t>(); - } - - - String extension = p_path.get_extension(); - - //step 1 check if scene - - if (extension=="xml" || extension=="xres") { - - String type = ResourceLoader::get_resource_type(p_path); - - if (type!="PackedScene") - return Vector<uint8_t>(); - - } else if (extension!="tscn" && extension!="xscn") { - return Vector<uint8_t>(); - } - - //step 2 check if cached - - uint64_t sd=0; - String smd5; - String gp = GlobalConfig::get_singleton()->globalize_path(p_path); - String md5=gp.md5_text(); - String tmp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/"); - - bool valid=false; - { - //if existing, make sure it's valid - FileAccessRef f = FileAccess::open(tmp_path+"scnexp-"+md5+".txt",FileAccess::READ); - if (f) { - - uint64_t d = f->get_line().strip_edges().to_int64(); - sd = FileAccess::get_modified_time(p_path); - - if (d==sd) { - valid=true; - } else { - String cmd5 = f->get_line().strip_edges(); - smd5 = FileAccess::get_md5(p_path); - if (cmd5==smd5) { - valid=true; - } - } - - - } - } - - if (!valid) { - //cache failed, convert - DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - - String copy = p_path+".convert."+extension; - - // a copy will allow loading the internal resources without conflicting with opened scenes - da->copy(p_path,copy); - - //@todo for tscn use something more efficient - - Ref<PackedScene> copyres = ResourceLoader::load(copy,"PackedScene"); - - da->remove(copy); - - memdelete(da); - - ERR_FAIL_COND_V(!copyres.is_valid(),Vector<uint8_t>()); - - Error err = ResourceSaver::save(tmp_path+"scnexp-"+md5+".scn",copyres); - - copyres=Ref<PackedScene>(); - - ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>()); - - FileAccessRef f = FileAccess::open(tmp_path+"scnexp-"+md5+".txt",FileAccess::WRITE); - - if (sd==0) - sd = FileAccess::get_modified_time(p_path); - if (smd5==String()) - smd5 = FileAccess::get_md5(p_path); - - f->store_line(String::num(sd)); - f->store_line(smd5); - f->store_line(gp); //source path for reference - } - - - Vector<uint8_t> ret = FileAccess::get_file_as_array(tmp_path+"scnexp-"+md5+".scn"); - - p_path+=".converted.scn"; - - return ret; - -} - - -EditorSceneExportPlugin::EditorSceneExportPlugin() -{ -} -#endif diff --git a/tools/editor/io_plugins/editor_export_scene.h b/tools/editor/io_plugins/editor_export_scene.h deleted file mode 100644 index c067e835a3..0000000000 --- a/tools/editor/io_plugins/editor_export_scene.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************/ -/* editor_export_scene.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITOR_EXPORT_SCENE_H -#define EDITOR_EXPORT_SCENE_H - -#include "tools/editor/editor_export.h" - -#if 0 -class EditorSceneExportPlugin : public EditorExportPlugin { - GDCLASS( EditorSceneExportPlugin, EditorExportPlugin ); -public: - - virtual Vector<uint8_t> custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform); - - EditorSceneExportPlugin(); -}; -#endif -#endif // EDITOR_EXPORT_SCENE_H diff --git a/tools/editor/io_plugins/editor_font_import_plugin.cpp b/tools/editor/io_plugins/editor_font_import_plugin.cpp deleted file mode 100644 index 417aad0db8..0000000000 --- a/tools/editor/io_plugins/editor_font_import_plugin.cpp +++ /dev/null @@ -1,1704 +0,0 @@ -/*************************************************************************/ -/* editor_font_import_plugin.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 "editor_font_import_plugin.h" -#if 0 -#include "scene/gui/dialogs.h" -#include "tools/editor/editor_file_dialog.h" -#include "tools/editor/editor_node.h" -#include "os/file_access.h" -#include "editor_atlas.h" -#include "io/image_loader.h" -#include "io/resource_saver.h" - -#ifdef FREETYPE_ENABLED -#include <ft2build.h> -#include FT_FREETYPE_H -#endif - - -class _EditorFontImportOptions : public Object { - - GDCLASS(_EditorFontImportOptions,Object); -public: - - enum FontMode { - - FONT_BITMAP, - FONT_DISTANCE_FIELD - }; - - enum ColorType { - COLOR_WHITE, - COLOR_CUSTOM, - COLOR_GRADIENT_RANGE, - COLOR_GRADIENT_IMAGE - }; - - - int char_extra_spacing; - int top_extra_spacing; - int bottom_extra_spacing; - int space_extra_spacing; - - enum CharacterSet { - - CHARSET_ASCII, - CHARSET_LATIN, - CHARSET_UNICODE, - CHARSET_CUSTOM, - CHARSET_CUSTOM_LATIN - }; - - - FontMode font_mode; - - CharacterSet character_set; - String custom_file; - - bool shadow; - Vector2 shadow_offset; - int shadow_radius; - Color shadow_color; - float shadow_transition; - - bool shadow2; - Vector2 shadow2_offset; - int shadow2_radius; - Color shadow2_color; - float shadow2_transition; - - ColorType color_type; - Color color; - Color gradient_begin; - Color gradient_end; - bool color_use_monochrome; - String gradient_image; - - bool enable_filter; - bool round_advance; - bool premultiply_alpha; - - - - bool _set(const StringName& p_name, const Variant& p_value) { - - String n = p_name; - if (n=="mode/mode") { - font_mode=FontMode(int(p_value)); - _change_notify(); - } else if (n=="extra_space/char") - char_extra_spacing=p_value; - else if (n=="extra_space/space") - space_extra_spacing=p_value; - else if (n=="extra_space/top") - top_extra_spacing=p_value; - else if (n=="extra_space/bottom") - bottom_extra_spacing=p_value; - - else if (n=="character_set/mode") { - character_set=CharacterSet(int(p_value)); - _change_notify(); - } else if (n=="character_set/custom") - custom_file=p_value; - - else if (n=="shadow/enabled") { - shadow=p_value; - _change_notify(); - }else if (n=="shadow/radius") - shadow_radius=p_value; - else if (n=="shadow/offset") - shadow_offset=p_value; - else if (n=="shadow/color") - shadow_color=p_value; - else if (n=="shadow/transition") - shadow_transition=p_value; - - else if (n=="shadow2/enabled") { - shadow2=p_value; - _change_notify(); - }else if (n=="shadow2/radius") - shadow2_radius=p_value; - else if (n=="shadow2/offset") - shadow2_offset=p_value; - else if (n=="shadow2/color") - shadow2_color=p_value; - else if (n=="shadow2/transition") - shadow2_transition=p_value; - - else if (n=="color/mode") { - color_type=ColorType(int(p_value)); - _change_notify(); - }else if (n=="color/color") - color=p_value; - else if (n=="color/begin") - gradient_begin=p_value; - else if (n=="color/end") - gradient_end=p_value; - else if (n=="color/image") - gradient_image=p_value; - else if (n=="color/monochrome") - color_use_monochrome=p_value; - else if (n=="advanced/round_advance") - round_advance=p_value; - else if (n=="advanced/enable_filter") - enable_filter=p_value; - else if (n=="advanced/premultiply_alpha") - premultiply_alpha=p_value; - else - return false; - - emit_signal("changed"); - - - return true; - - } - - bool _get(const StringName& p_name,Variant &r_ret) const{ - - String n = p_name; - if (n=="mode/mode") - r_ret=font_mode; - else if (n=="extra_space/char") - r_ret=char_extra_spacing; - else if (n=="extra_space/space") - r_ret=space_extra_spacing; - else if (n=="extra_space/top") - r_ret=top_extra_spacing; - else if (n=="extra_space/bottom") - r_ret=bottom_extra_spacing; - - else if (n=="character_set/mode") - r_ret=character_set; - else if (n=="character_set/custom") - r_ret=custom_file; - - else if (n=="shadow/enabled") - r_ret=shadow; - else if (n=="shadow/radius") - r_ret=shadow_radius; - else if (n=="shadow/offset") - r_ret=shadow_offset; - else if (n=="shadow/color") - r_ret=shadow_color; - else if (n=="shadow/transition") - r_ret=shadow_transition; - - else if (n=="shadow2/enabled") - r_ret=shadow2; - else if (n=="shadow2/radius") - r_ret=shadow2_radius; - else if (n=="shadow2/offset") - r_ret=shadow2_offset; - else if (n=="shadow2/color") - r_ret=shadow2_color; - else if (n=="shadow2/transition") - r_ret=shadow2_transition; - - - else if (n=="color/mode") - r_ret=color_type; - else if (n=="color/color") - r_ret=color; - else if (n=="color/begin") - r_ret=gradient_begin; - else if (n=="color/end") - r_ret=gradient_end; - else if (n=="color/image") - r_ret=gradient_image; - else if (n=="color/monochrome") - r_ret=color_use_monochrome; - else if (n=="advanced/round_advance") - r_ret=round_advance; - else if (n=="advanced/enable_filter") - r_ret=enable_filter; - else if (n=="advanced/premultiply_alpha") - r_ret=premultiply_alpha; - else - return false; - - return true; - - } - - void _get_property_list( List<PropertyInfo> *p_list) const{ - - - p_list->push_back(PropertyInfo(Variant::INT,"mode/mode",PROPERTY_HINT_ENUM,"Bitmap,Distance Field")); - - p_list->push_back(PropertyInfo(Variant::INT,"extra_space/char",PROPERTY_HINT_RANGE,"-64,64,1")); - p_list->push_back(PropertyInfo(Variant::INT,"extra_space/space",PROPERTY_HINT_RANGE,"-64,64,1")); - p_list->push_back(PropertyInfo(Variant::INT,"extra_space/top",PROPERTY_HINT_RANGE,"-64,64,1")); - p_list->push_back(PropertyInfo(Variant::INT,"extra_space/bottom",PROPERTY_HINT_RANGE,"-64,64,1")); - p_list->push_back(PropertyInfo(Variant::INT,"character_set/mode",PROPERTY_HINT_ENUM,"Ascii,Latin,Unicode,Custom,Custom&Latin")); - - if (character_set>=CHARSET_CUSTOM) - p_list->push_back(PropertyInfo(Variant::STRING,"character_set/custom",PROPERTY_HINT_GLOBAL_FILE)); - - int usage = PROPERTY_USAGE_DEFAULT; - - if (font_mode==FONT_DISTANCE_FIELD) { - usage = PROPERTY_USAGE_NOEDITOR; - } - - { - - p_list->push_back(PropertyInfo(Variant::BOOL,"shadow/enabled",PROPERTY_HINT_NONE,"",usage)); - if (shadow) { - p_list->push_back(PropertyInfo(Variant::INT,"shadow/radius",PROPERTY_HINT_RANGE,"-64,64,1",usage)); - p_list->push_back(PropertyInfo(Variant::VECTOR2,"shadow/offset",PROPERTY_HINT_NONE,"",usage)); - p_list->push_back(PropertyInfo(Variant::COLOR,"shadow/color",PROPERTY_HINT_NONE,"",usage)); - p_list->push_back(PropertyInfo(Variant::REAL,"shadow/transition",PROPERTY_HINT_EXP_EASING,"",usage)); - } - - p_list->push_back(PropertyInfo(Variant::BOOL,"shadow2/enabled",PROPERTY_HINT_NONE,"",usage)); - if (shadow2) { - p_list->push_back(PropertyInfo(Variant::INT,"shadow2/radius",PROPERTY_HINT_RANGE,"-64,64,1",usage)); - p_list->push_back(PropertyInfo(Variant::VECTOR2,"shadow2/offset",PROPERTY_HINT_NONE,"",usage)); - p_list->push_back(PropertyInfo(Variant::COLOR,"shadow2/color",PROPERTY_HINT_NONE,"",usage)); - p_list->push_back(PropertyInfo(Variant::REAL,"shadow2/transition",PROPERTY_HINT_EXP_EASING,"",usage)); - } - - p_list->push_back(PropertyInfo(Variant::INT,"color/mode",PROPERTY_HINT_ENUM,"White,Color,Gradient,Gradient Image",usage)); - if (color_type==COLOR_CUSTOM) { - p_list->push_back(PropertyInfo(Variant::COLOR,"color/color",PROPERTY_HINT_NONE,"",usage)); - - } - if (color_type==COLOR_GRADIENT_RANGE) { - p_list->push_back(PropertyInfo(Variant::COLOR,"color/begin",PROPERTY_HINT_NONE,"",usage)); - p_list->push_back(PropertyInfo(Variant::COLOR,"color/end",PROPERTY_HINT_NONE,"",usage)); - } - if (color_type==COLOR_GRADIENT_IMAGE) { - p_list->push_back(PropertyInfo(Variant::STRING,"color/image",PROPERTY_HINT_GLOBAL_FILE,"",usage)); - } - p_list->push_back(PropertyInfo(Variant::BOOL,"color/monochrome",PROPERTY_HINT_NONE,"",usage)); - } - - p_list->push_back(PropertyInfo(Variant::BOOL,"advanced/round_advance")); - p_list->push_back(PropertyInfo(Variant::BOOL,"advanced/enable_filter")); - p_list->push_back(PropertyInfo(Variant::BOOL,"advanced/premultiply_alpha")); - - } - - - static void _bind_methods() { - - - ADD_SIGNAL( MethodInfo("changed")); - } - - - void reset() { - - char_extra_spacing=0; - top_extra_spacing=0; - bottom_extra_spacing=0; - space_extra_spacing=0; - - character_set=CHARSET_LATIN; - - shadow=false; - shadow_radius=2; - shadow_color=Color(0,0,0,0.3); - shadow_transition=1.0; - - shadow2=false; - shadow2_radius=2; - shadow2_color=Color(0,0,0,0.3); - shadow2_transition=1.0; - - color_type=COLOR_WHITE; - color=Color(1,1,1,1); - gradient_begin=Color(1,1,1,1); - gradient_end=Color(0.5,0.5,0.5,1); - color_use_monochrome=false; - - font_mode=FONT_BITMAP; - round_advance=true; - enable_filter=true; - premultiply_alpha=false; - - } - - _EditorFontImportOptions() { - - font_mode=FONT_BITMAP; - - char_extra_spacing=0; - top_extra_spacing=0; - bottom_extra_spacing=0; - space_extra_spacing=0; - - character_set=CHARSET_LATIN; - - shadow=false; - shadow_radius=2; - shadow_color=Color(0,0,0,0.3); - shadow_transition=1.0; - - shadow2=false; - shadow2_radius=2; - shadow2_color=Color(0,0,0,0.3); - shadow2_transition=1.0; - - color_type=COLOR_WHITE; - color=Color(1,1,1,1); - gradient_begin=Color(1,1,1,1); - gradient_end=Color(0.5,0.5,0.5,1); - color_use_monochrome=false; - - round_advance=true; - enable_filter=true; - premultiply_alpha=false; - } - - -}; - - -class EditorFontImportDialog : public ConfirmationDialog { - - GDCLASS(EditorFontImportDialog, ConfirmationDialog); - - - EditorLineEditFileChooser *source; - EditorLineEditFileChooser *dest; - SpinBox *font_size; - LineEdit *test_string; - ColorPickerButton *test_color; - Label *test_label; - PropertyEditor *prop_edit; - Timer *timer; - ConfirmationDialog *error_dialog; - - - Ref<ResourceImportMetadata> get_rimd() { - - Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); - List<PropertyInfo> pl; - options->_get_property_list(&pl); - for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { - - Variant v; - String opt=E->get().name; - options->_get(opt,v); - if (opt=="color/image" || opt=="character_set/custom") { - v = EditorImportPlugin::validate_source_path(v); - } - imd->set_option(opt,v); - } - - String src_path = EditorImportPlugin::validate_source_path(source->get_line_edit()->get_text()); - //print_line("pre src path "+source->get_line_edit()->get_text()); - //print_line("src path "+src_path); - imd->add_source(src_path); - imd->set_option("font/size",font_size->get_value()); - - return imd; - - } - - void _src_changed(String) { - _prop_changed(); - } - - void _update_text2(String) { - _update_text(); - } - void _update_text3(Color) { - _update_text(); - } - - void _update_text() { - - test_label->set_text(""); - test_label->set_text(test_string->get_text()); - test_label->add_color_override("font_color",test_color->get_pick_color()); - } - - void _update() { - - Ref<ResourceImportMetadata> imd = get_rimd(); - Ref<BitmapFont> font = plugin->generate_font(imd); - test_label->add_font_override("font",font); - _update_text(); - } - - void _font_size_changed(double) { - - _prop_changed(); - } - - void _prop_changed() { - - timer->start(); - } - - void _import_inc(String p_font) { - - Ref<BitmapFont> font = ResourceLoader::load(p_font); - if (!font.is_valid()) - return; - Ref<ImageTexture> tex = font->get_texture(0); - if (tex.is_null()) - return; - FileAccessRef f=FileAccess::open(p_font.get_basename()+".inc",FileAccess::WRITE); - Vector<CharType> ck = font->get_char_keys(); - - f->store_line("static const int _builtin_font_height="+itos(font->get_height())+";"); - f->store_line("static const int _builtin_font_ascent="+itos(font->get_ascent())+";"); - f->store_line("static const int _builtin_font_charcount="+itos(ck.size())+";"); - f->store_line("static const int _builtin_font_charrects["+itos(ck.size())+"][8]={"); - f->store_line("/* charidx , ofs_x, ofs_y, size_x, size_y, valign, halign, advance */"); - - for(int i=0;i<ck.size();i++) { - CharType k=ck[i]; - BitmapFont::Character c=font->get_character(k); - f->store_line("{"+itos(k)+","+rtos(c.rect.pos.x)+","+rtos(c.rect.pos.y)+","+rtos(c.rect.size.x)+","+rtos(c.rect.size.y)+","+rtos(c.v_align)+","+rtos(c.h_align)+","+rtos(c.advance)+"},"); - } - f->store_line("};"); - - Vector<BitmapFont::KerningPairKey> kp=font->get_kerning_pair_keys(); - f->store_line("static const int _builtin_font_kerning_pair_count="+itos(kp.size())+";"); - f->store_line("static const int _builtin_font_kerning_pairs["+itos(kp.size())+"][3]={"); - for(int i=0;i<kp.size();i++) { - - int d = font->get_kerning_pair(kp[i].A,kp[i].B); - f->store_line("{"+itos(kp[i].A)+","+itos(kp[i].B)+","+itos(d)+"},"); - } - - f->store_line("};"); - Image img = tex->get_data(); - - f->store_line("static const int _builtin_font_img_width="+itos(img.get_width())+";"); - f->store_line("static const int _builtin_font_img_height="+itos(img.get_height())+";"); - - String fname = p_font.get_basename()+".sv.png"; - ResourceSaver::save(fname,tex); - Vector<uint8_t> data=FileAccess::get_file_as_array(fname); - - - f->store_line("static const int _builtin_font_img_data_size="+itos(data.size())+";"); - f->store_line("static const unsigned char _builtin_font_img_data["+itos(data.size())+"]={"); - - - - for(int i=0;i<data.size();i++) { - - f->store_line(itos(data[i])+","); - - } - f->store_line("};"); - - } - - void _import() { - - if (source->get_line_edit()->get_text()=="") { - error_dialog->set_text(TTR("No source font file!")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - } - - if (dest->get_line_edit()->get_text()=="") { - error_dialog->set_text(TTR("No target font resource!")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - } - - if (dest->get_line_edit()->get_text().get_file()==".fnt") { - dest->get_line_edit()->set_text(dest->get_line_edit()->get_text().get_base_dir() + "/" + source->get_line_edit()->get_text().get_file().get_basename() + ".fnt" ); - } - - if (dest->get_line_edit()->get_text().get_extension() == dest->get_line_edit()->get_text()) { - dest->get_line_edit()->set_text(dest->get_line_edit()->get_text() + ".fnt"); - } - - if (dest->get_line_edit()->get_text().get_extension().to_lower() != "fnt") { - error_dialog->set_text(TTR("Invalid file extension.\nPlease use .fnt.")); - error_dialog->popup_centered(Size2(200,100)); - return; - } - - Ref<ResourceImportMetadata> rimd = get_rimd(); - - if (rimd.is_null()) { - error_dialog->set_text(TTR("Can't load/process source font.")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - } - - Error err = plugin->import(dest->get_line_edit()->get_text(),rimd); - - if (err!=OK) { - error_dialog->set_text(TTR("Couldn't save font.")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - } - - _import_inc(dest->get_line_edit()->get_text()); - - hide(); - } - - EditorFontImportPlugin *plugin; - _EditorFontImportOptions *options; - - static void _bind_methods() { - - ClassDB::bind_method("_update",&EditorFontImportDialog::_update); - ClassDB::bind_method("_update_text",&EditorFontImportDialog::_update_text); - ClassDB::bind_method("_update_text2",&EditorFontImportDialog::_update_text2); - ClassDB::bind_method("_update_text3",&EditorFontImportDialog::_update_text3); - ClassDB::bind_method("_prop_changed",&EditorFontImportDialog::_prop_changed); - ClassDB::bind_method("_src_changed",&EditorFontImportDialog::_src_changed); - ClassDB::bind_method("_font_size_changed",&EditorFontImportDialog::_font_size_changed); - ClassDB::bind_method("_import",&EditorFontImportDialog::_import); - - } - -public: - - void _notification(int p_what) { - - if (p_what==NOTIFICATION_ENTER_TREE) { - prop_edit->edit(options); - _update_text(); - } - } - - void popup_import(const String& p_path) { - - popup_centered(Size2(600,500)*EDSCALE); - - if (p_path!="") { - - Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); - ERR_FAIL_COND(!rimd.is_valid()); - - dest->get_line_edit()->set_text(p_path); - List<String> opts; - rimd->get_options(&opts); - options->reset(); - for(List<String>::Element *E=opts.front();E;E=E->next()) { - - options->_set(E->get(),rimd->get_option(E->get())); - } - - String src = ""; - for(int i=0;i<rimd->get_source_count();i++) { - if (i>0) - src+=","; - src+=EditorImportPlugin::expand_source_path(rimd->get_source_path(i)); - } - source->get_line_edit()->set_text(src); - - font_size->set_value(rimd->get_option("font/size")); - } - } - - - void set_source_and_dest(const String& p_font,const String& p_dest) { - source->get_line_edit()->set_text(p_font); - dest->get_line_edit()->set_text(p_dest); - _prop_changed(); - } - - EditorFontImportDialog(EditorFontImportPlugin *p_plugin) { - plugin=p_plugin; - VBoxContainer *vbc = memnew( VBoxContainer ); - add_child(vbc); - //set_child_rect(vbc); - HBoxContainer *hbc = memnew( HBoxContainer); - vbc->add_child(hbc); - VBoxContainer *vbl = memnew( VBoxContainer ); - hbc->add_child(vbl); - hbc->set_v_size_flags(SIZE_EXPAND_FILL); - vbl->set_h_size_flags(SIZE_EXPAND_FILL); - VBoxContainer *vbr = memnew( VBoxContainer ); - hbc->add_child(vbr); - vbr->set_h_size_flags(SIZE_EXPAND_FILL); - - source = memnew( EditorLineEditFileChooser ); - source->get_file_dialog()->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - source->get_file_dialog()->set_mode(EditorFileDialog::MODE_OPEN_FILE); - source->get_file_dialog()->add_filter("*.ttf;TrueType"); - source->get_file_dialog()->add_filter("*.otf;OpenType"); - source->get_file_dialog()->add_filter("*.fnt;BMFont"); - source->get_line_edit()->connect("text_entered",this,"_src_changed"); - - vbl->add_margin_child(TTR("Source Font:"),source); - font_size = memnew( SpinBox ); - vbl->add_margin_child(TTR("Source Font Size:"),font_size); - font_size->set_min(3); - font_size->set_max(256); - font_size->set_value(16); - font_size->connect("value_changed",this,"_font_size_changed"); - dest = memnew( EditorLineEditFileChooser ); - // - List<String> fl; - Ref<BitmapFont> font= memnew(BitmapFont); - dest->get_file_dialog()->add_filter("*.fnt ; Font" ); - /* - ResourceSaver::get_recognized_extensions(font,&fl); - for(List<String>::Element *E=fl.front();E;E=E->next()) { - dest->get_file_dialog()->add_filter("*."+E->get()); - } - */ - - vbl->add_margin_child(TTR("Dest Resource:"),dest); - HBoxContainer *testhb = memnew( HBoxContainer ); - test_string = memnew( LineEdit ); - test_string->set_text(TTR("The quick brown fox jumps over the lazy dog.")); - test_string->set_h_size_flags(SIZE_EXPAND_FILL); - test_string->set_stretch_ratio(5); - - testhb->add_child(test_string); - test_color = memnew( ColorPickerButton ); - test_color->set_pick_color(get_color("font_color","Label")); - test_color->set_h_size_flags(SIZE_EXPAND_FILL); - test_color->set_stretch_ratio(1); - test_color->connect("color_changed",this,"_update_text3"); - testhb->add_child(test_color); - - vbl->add_spacer(); - vbl->add_margin_child(TTR("Test:")+" ",testhb); - /* - HBoxContainer *upd_hb = memnew( HBoxContainer ); - //vbl->add_child(upd_hb); - upd_hb->add_spacer(); - Button *update = memnew( Button); - upd_hb->add_child(update); - update->set_text("Update"); - update->connect("pressed",this,"_update"); -*/ - options = memnew( _EditorFontImportOptions ); - prop_edit = memnew( PropertyEditor() ); - vbr->add_margin_child(TTR("Options:"),prop_edit,true); - options->connect("changed",this,"_prop_changed"); - - prop_edit->hide_top_label(); - - Panel *panel = memnew( Panel ); - vbc->add_child(panel); - test_label = memnew( Label ); - test_label->set_autowrap(true); - panel->add_child(test_label); - test_label->set_area_as_parent_rect(); - panel->set_v_size_flags(SIZE_EXPAND_FILL); - test_string->connect("text_changed",this,"_update_text2"); - set_title(TTR("Font Import")); - timer = memnew( Timer ); - add_child(timer); - timer->connect("timeout",this,"_update"); - timer->set_wait_time(0.4); - timer->set_one_shot(true); - - get_ok()->connect("pressed", this,"_import"); - get_ok()->set_text(TTR("Import")); - - error_dialog = memnew ( ConfirmationDialog ); - add_child(error_dialog); - error_dialog->get_ok()->set_text(TTR("Accept")); - set_hide_on_ok(false); - - - } - - ~EditorFontImportDialog() { - memdelete(options); - } -}; - - -/////////////////////////////////////// - - - -struct _EditorFontData { - - Vector<uint8_t> bitmap; - int width,height; - int ofs_x; //ofset to center, from ABOVE - int ofs_y; //ofset to begining, from LEFT - int valign; //vertical alignment - int halign; - float advance; - int character; - int glyph; - - int texture; - Image blit; - Point2i blit_ofs; - //bool printable; - -}; - - -struct _EditorFontDataSort { - - bool operator()(const _EditorFontData *p_A,const _EditorFontData *p_B) const { - return p_A->height > p_B->height; - }; -}; - -struct _EditorKerningKey { - - CharType A,B; - bool operator<(const _EditorKerningKey& p_k) const { return (A==p_k.A)?(B<p_k.B):(A<p_k.A); } - -}; - - -static unsigned char get_SDF_radial( - unsigned char *fontmap, - int w, int h, - int x, int y, - int max_radius ) -{ - //hideous brute force method - float d2 = max_radius*max_radius+1.0; - unsigned char v = fontmap[x+y*w]; - for( int radius = 1; (radius <= max_radius) && (radius*radius < d2); ++radius ) - { - int line, lo, hi; - //north - line = y - radius; - if( (line >= 0) && (line < h) ) - { - lo = x - radius; - hi = x + radius; - if( lo < 0 ) { lo = 0; } - if( hi >= w ) { hi = w-1; } - int idx = line * w + lo; - for( int i = lo; i <= hi; ++i ) - { - //check this pixel - if( fontmap[idx] != v ) - { - float nx = i - x; - float ny = line - y; - float nd2 = nx*nx+ny*ny; - if( nd2 < d2 ) - { - d2 = nd2; - } - } - //move on - ++idx; - } - } - //south - line = y + radius; - if( (line >= 0) && (line < h) ) - { - lo = x - radius; - hi = x + radius; - if( lo < 0 ) { lo = 0; } - if( hi >= w ) { hi = w-1; } - int idx = line * w + lo; - for( int i = lo; i <= hi; ++i ) - { - //check this pixel - if( fontmap[idx] != v ) - { - float nx = i - x; - float ny = line - y; - float nd2 = nx*nx+ny*ny; - if( nd2 < d2 ) - { - d2 = nd2; - } - } - //move on - ++idx; - } - } - //west - line = x - radius; - if( (line >= 0) && (line < w) ) - { - lo = y - radius + 1; - hi = y + radius - 1; - if( lo < 0 ) { lo = 0; } - if( hi >= h ) { hi = h-1; } - int idx = lo * w + line; - for( int i = lo; i <= hi; ++i ) - { - //check this pixel - if( fontmap[idx] != v ) - { - float nx = line - x; - float ny = i - y; - float nd2 = nx*nx+ny*ny; - if( nd2 < d2 ) - { - d2 = nd2; - } - } - //move on - idx += w; - } - } - //east - line = x + radius; - if( (line >= 0) && (line < w) ) - { - lo = y - radius + 1; - hi = y + radius - 1; - if( lo < 0 ) { lo = 0; } - if( hi >= h ) { hi = h-1; } - int idx = lo * w + line; - for( int i = lo; i <= hi; ++i ) - { - //check this pixel - if( fontmap[idx] != v ) - { - float nx = line - x; - float ny = i - y; - float nd2 = nx*nx+ny*ny; - if( nd2 < d2 ) - { - d2 = nd2; - } - } - //move on - idx += w; - } - } - } - d2 = sqrtf( d2 ); - if( v==0 ) - { - d2 = -d2; - } - d2 *= 127.5 / max_radius; - d2 += 127.5; - if( d2 < 0.0 ) d2 = 0.0; - if( d2 > 255.0 ) d2 = 255.0; - return (unsigned char)(d2 + 0.5); -} - - -Ref<BitmapFont> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata>& p_from, const String &p_existing) { - - - - Ref<ResourceImportMetadata> from = p_from; - ERR_FAIL_COND_V(from->get_source_count()!=1,Ref<BitmapFont>()); - - String src_path = EditorImportPlugin::expand_source_path(from->get_source_path(0)); - - if (src_path.get_extension().to_lower()=="fnt") { - - if (ResourceLoader::load(src_path).is_valid()) { - EditorNode::get_singleton()->show_warning(TTR("Path:")+" "+src_path+"\n"+TTR("This file is already a Godot font file, please supply a BMFont type file instead.")); - return Ref<BitmapFont>(); - } - - Ref<BitmapFont> font; - font.instance(); - Error err = font->create_from_fnt(src_path); - if (err) { - EditorNode::get_singleton()->show_warning(TTR("Path:")+" "+src_path+"\n"+TTR("Failed opening as BMFont file.")); - return Ref<BitmapFont>(); - } - - return font; - } - - int size = from->get_option("font/size"); - -#ifdef FREETYPE_ENABLED - FT_Library library; /* handle to library */ - FT_Face face; /* handle to face object */ - - Vector<_EditorFontData*> font_data_list; - - int error = FT_Init_FreeType( &library ); - - ERR_EXPLAIN(TTR("Error initializing FreeType.")); - ERR_FAIL_COND_V( error !=0, Ref<BitmapFont>() ); - - print_line("loadfrom: "+src_path); - error = FT_New_Face( library, src_path.utf8().get_data(),0,&face ); - - if ( error == FT_Err_Unknown_File_Format ) { - ERR_EXPLAIN(TTR("Unknown font format.")); - FT_Done_FreeType( library ); - } else if ( error ) { - - ERR_EXPLAIN(TTR("Error loading font.")); - FT_Done_FreeType( library ); - - } - - ERR_FAIL_COND_V(error,Ref<BitmapFont>()); - - - int height=0; - int ascent=0; - int font_spacing=0; - - error = FT_Set_Char_Size(face,0,64*size,512,512); - - if ( error ) { - FT_Done_FreeType( library ); - ERR_EXPLAIN(TTR("Invalid font size.")); - ERR_FAIL_COND_V( error,Ref<BitmapFont>() ); - - } - - int font_mode = from->get_option("mode/mode"); - - int scaler=(font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD)?16:1; - - error = FT_Set_Pixel_Sizes(face,0,size*scaler); - - FT_GlyphSlot slot = face->glyph; - - //error = FT_Set_Charmap(face,ft_encoding_unicode ); /* encoding.. */ - - - /* PRINT CHARACTERS TO INDIVIDUAL BITMAPS */ - - - //int space_size=5; //size for space, if none found.. 5! - //int min_valign=500; //some ridiculous number - - FT_ULong charcode; - FT_UInt gindex; - - int max_up=-1324345; ///gibberish - int max_down=124232; - - Map<_EditorKerningKey,int> kerning_map; - - charcode = FT_Get_First_Char( face, &gindex ); - - Set<CharType> import_chars; - - int import_mode = from->get_option("character_set/mode"); - bool round_advance = from->get_option("advanced/round_advance"); - - if (import_mode>=_EditorFontImportOptions::CHARSET_CUSTOM) { - - //load from custom text - String path = from->get_option("character_set/custom"); - - FileAccess *fa = FileAccess::open(EditorImportPlugin::expand_source_path(path),FileAccess::READ); - - if ( !fa ) { - - FT_Done_FreeType( library ); - ERR_EXPLAIN(TTR("Invalid font custom source.")); - ERR_FAIL_COND_V( !fa,Ref<BitmapFont>() ); - - } - - - while(!fa->eof_reached()) { - - String line = fa->get_line(); - for(int i=0;i<line.length();i++) { - import_chars.insert(line[i]); - } - } - - if (import_mode==_EditorFontImportOptions::CHARSET_CUSTOM_LATIN) { - - for(int i=32;i<128;i++) - import_chars.insert(i); - } - - memdelete(fa); - } - - int xsize=0; - while ( gindex != 0 ) - { - - bool skip=false; - error = FT_Load_Char( face, charcode, font_mode==_EditorFontImportOptions::FONT_BITMAP?FT_LOAD_RENDER:FT_LOAD_MONOCHROME ); - if (error) skip=true; - else error = FT_Render_Glyph( face->glyph, font_mode==_EditorFontImportOptions::FONT_BITMAP?ft_render_mode_normal:ft_render_mode_mono ); - if (error) { - skip=true; - } else if (!skip) { - - switch(import_mode) { - - case _EditorFontImportOptions::CHARSET_ASCII: skip = charcode>127; break; - case _EditorFontImportOptions::CHARSET_LATIN: skip = charcode>255 ;break; - case _EditorFontImportOptions::CHARSET_UNICODE: break; //none - case _EditorFontImportOptions::CHARSET_CUSTOM: - case _EditorFontImportOptions::CHARSET_CUSTOM_LATIN: skip = !import_chars.has(charcode); break; - - } - } - - if (charcode<=32) //?? - skip=true; - - if (skip) { - charcode=FT_Get_Next_Char(face,charcode,&gindex); - continue; - } - - _EditorFontData * fdata = memnew( _EditorFontData ); - - - int w = slot->bitmap.width; - int h = slot->bitmap.rows; - int p = slot->bitmap.pitch; - - //print_line("W: "+itos(w)+" P: "+itos(slot->bitmap.pitch)); - - if (font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD) { - - //oversize the holding buffer so I can smooth it! - int sw = w + scaler * 4; - int sh = h + scaler * 4; - //do the SDF - int sdfw = sw / scaler; - int sdfh = sh / scaler; - - fdata->width=sdfw; - fdata->height=sdfh; - } else { - fdata->width=w; - fdata->height=h; - } - - fdata->character=charcode; - fdata->glyph=FT_Get_Char_Index(face,charcode); - if (charcode=='x') - xsize=w/scaler; - - - - fdata->valign=slot->bitmap_top; - fdata->halign=slot->bitmap_left; - - if (round_advance) - fdata->advance=(slot->advance.x+(1<<5))>>6; - else - fdata->advance=slot->advance.x/float(1<<6); - - if (font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD) { - - fdata->halign = fdata->halign / scaler - 1.5; - fdata->valign = fdata->valign / scaler + 1.5; - fdata->advance/=scaler; - - } - - fdata->advance+=font_spacing; - - - if (charcode<127) { - int top = fdata->valign; - int hmax = h/scaler; - - if (top>max_up) { - - max_up=top; - } - - - if ( (top - hmax)<max_down ) { - - max_down=top - hmax; - } - } - - if (font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD) { - - - //oversize the holding buffer so I can smooth it! - int sw = w + scaler * 4; - int sh = h + scaler * 4; - - unsigned char *smooth_buf = new unsigned char[sw*sh]; - - for( int i = 0; i < sw*sh; ++i ) { - smooth_buf[i] = 0; - } - - // copy the glyph into the buffer to be smoothed - unsigned char *buf = slot->bitmap.buffer; - for( int j = 0; j < h; ++j ) { - for( int i = 0; i < w; ++i ) { - smooth_buf[scaler*2+i+(j+scaler*2)*sw] = 255 * ((buf[j*p+(i>>3)] >> (7 - (i & 7))) & 1); - } - } - - // do the SDF - int sdfw = fdata->width; - int sdfh = fdata->height; - - fdata->bitmap.resize( sdfw*sdfh ); - - for( int j = 0; j < sdfh; ++j ) { - for( int i = 0; i < sdfw; ++i ) { - int pd_idx = j*sdfw+i; - - //fdata->bitmap[j*slot->bitmap.width+i]=slot->bitmap.buffer[j*slot->bitmap.width+i]; - - fdata->bitmap[pd_idx] = - //get_SDF - get_SDF_radial - ( smooth_buf, sw, sh, - i*scaler + (scaler >>1), j*scaler + (scaler >>1), - 2*scaler ); - - } - } - - delete [] smooth_buf; - - } else { - fdata->bitmap.resize( slot->bitmap.width*slot->bitmap.rows ); - for (int i=0;i<slot->bitmap.width;i++) { - for (int j=0;j<slot->bitmap.rows;j++) { - - fdata->bitmap[j*slot->bitmap.width+i]=slot->bitmap.buffer[j*slot->bitmap.width+i]; - } - } - } - - font_data_list.push_back(fdata); - charcode=FT_Get_Next_Char(face,charcode,&gindex); -// printf("reading char %i\n",charcode); - } - - /* SPACE */ - - _EditorFontData *spd = memnew( _EditorFontData ); - spd->advance=0; - spd->character=' '; - spd->halign=0; - spd->valign=0; - spd->width=0; - spd->height=0; - spd->ofs_x=0; - spd->ofs_y=0; - - if (!FT_Load_Char( face, ' ', FT_LOAD_RENDER ) && !FT_Render_Glyph( face->glyph, font_mode==_EditorFontImportOptions::FONT_BITMAP?ft_render_mode_normal:ft_render_mode_mono )) { - - spd->advance = slot->advance.x>>6; //round to nearest or store as float - spd->advance/=scaler; - spd->advance+=font_spacing; - } else { - - spd->advance=xsize; - spd->advance+=font_spacing; - } - - font_data_list.push_back(spd); - - Set<CharType> exported; - for (int i=0; i<font_data_list.size(); i++) { - exported.insert(font_data_list[i]->character); - }; - int missing = 0; - for(Set<CharType>::Element *E=import_chars.front();E;E=E->next()) { - CharType c = E->get(); - if (!exported.has(c)) { - CharType str[2] = {c, 0}; - printf("** Warning: character %i (%ls) not exported\n", (int)c, str); - ++missing; - }; - }; - print_line("total_chars: "+itos(font_data_list.size())); - - /* KERNING */ - - - for(int i=0;i<font_data_list.size();i++) { - - if (font_data_list[i]->character>512) - continue; - for(int j=0;j<font_data_list.size();j++) { - - if (font_data_list[j]->character>512) - continue; - - FT_Vector delta; - FT_Get_Kerning( face, font_data_list[i]->glyph,font_data_list[j]->glyph, FT_KERNING_DEFAULT, &delta ); - - if (delta.x!=0) { - - _EditorKerningKey kpk; - kpk.A = font_data_list[i]->character; - kpk.B = font_data_list[j]->character; - int kern = ((-delta.x)+(1<<5))>>6; - - if (kern==0) - continue; - kerning_map[kpk]=kern/scaler; - } - } - } - - height=max_up-max_down; - ascent=max_up; - - /* FIND OUT WHAT THE FONT HEIGHT FOR THIS IS */ - - /* ADJUST THE VALIGN FOR EACH CHARACTER */ - - for (int i=0;i<(int)font_data_list.size();i++) { - - font_data_list[i]->valign=max_up-font_data_list[i]->valign; - } - - - - /* ADD THE SPACEBAR CHARACTER */ -/* - _EditorFontData * fdata = new _EditorFontData; - - fdata->character=32; - fdata->bitmap=0; - fdata->width=xsize; - fdata->height=1; - fdata->valign=0; - - font_data_list.push_back(fdata); -*/ - /* SORT BY HEIGHT, SO THEY FIT BETTER ON THE TEXTURE */ - - font_data_list.sort_custom<_EditorFontDataSort>(); - Color *color=memnew_arr(Color,height); - - int gradient_type=from->get_option("color/mode"); - switch(gradient_type) { - case _EditorFontImportOptions::COLOR_WHITE: { - - for(int i=0;i<height;i++){ - color[i]=Color(1,1,1,1); - } - - } break; - case _EditorFontImportOptions::COLOR_CUSTOM: { - - Color cc = from->get_option("color/color"); - for(int i=0;i<height;i++){ - color[i]=cc; - } - - } break; - case _EditorFontImportOptions::COLOR_GRADIENT_RANGE: { - - Color src=from->get_option("color/begin"); - Color to=from->get_option("color/end"); - for(int i=0;i<height;i++){ - color[i]=src.linear_interpolate(to,i/float(height)); - } - - } break; - case _EditorFontImportOptions::COLOR_GRADIENT_IMAGE: { - - String fp = EditorImportPlugin::expand_source_path(from->get_option("color/image")); - Image img; - Error err = ImageLoader::load_image(fp,&img); - if (err==OK) { - - for(int i=0;i<height;i++){ - //color[i]=img.get_pixel(0,i*img.get_height()/height); - } - } else { - - for(int i=0;i<height;i++){ - color[i]=Color(1,1,1,1); - } - } - - } break; - } - - - for(int i=0;i<font_data_list.size();i++) { - - if (font_data_list[i]->bitmap.size()==0) - continue; - - int margin[4]={0,0,0,0}; - - if (from->get_option("shadow/enabled").operator bool()) { - int r=from->get_option("shadow/radius"); - Point2i ofs=Point2(from->get_option("shadow/offset")); - margin[ MARGIN_LEFT ] = MAX( r - ofs.x, 0); - margin[ MARGIN_RIGHT ] = MAX( r + ofs.x, 0); - margin[ MARGIN_TOP ] = MAX( r - ofs.y, 0); - margin[ MARGIN_BOTTOM ] = MAX( r + ofs.y, 0); - - } - - if (from->get_option("shadow2/enabled").operator bool()) { - int r=from->get_option("shadow2/radius"); - Point2i ofs=Point2(from->get_option("shadow2/offset")); - margin[ MARGIN_LEFT ] = MAX( r - ofs.x, margin[ MARGIN_LEFT ]); - margin[ MARGIN_RIGHT ] = MAX( r + ofs.x, margin[ MARGIN_RIGHT ]); - margin[ MARGIN_TOP ] = MAX( r - ofs.y, margin[ MARGIN_TOP ]); - margin[ MARGIN_BOTTOM ] = MAX( r + ofs.y, margin[ MARGIN_BOTTOM ]); - - } - - Size2i s; - s.width=font_data_list[i]->width+margin[MARGIN_LEFT]+margin[MARGIN_RIGHT]; - s.height=font_data_list[i]->height+margin[MARGIN_TOP]+margin[MARGIN_BOTTOM]; - Point2i o; - o.x=margin[MARGIN_LEFT]; - o.y=margin[MARGIN_TOP]; - - int ow=font_data_list[i]->width; - int oh=font_data_list[i]->height; - - PoolVector<uint8_t> pixels; - pixels.resize(s.x*s.y*4); - - PoolVector<uint8_t>::Write w = pixels.write(); - //print_line("val: "+itos(font_data_list[i]->valign)); - for(int y=0;y<s.height;y++) { - - int yc=CLAMP(y-o.y+font_data_list[i]->valign,0,height-1); - Color c=color[yc]; - c.a=0; - - for(int x=0;x<s.width;x++) { - - int ofs=y*s.x+x; - w[ofs*4+0]=c.r*255.0; - w[ofs*4+1]=c.g*255.0; - w[ofs*4+2]=c.b*255.0; - w[ofs*4+3]=c.a*255.0; - } - } - - - for(int si=0;si<2;si++) { - -#define S_VAR(m_v) (String(si==0?"shadow/":"shadow2/")+m_v) - if (from->get_option(S_VAR("enabled")).operator bool()) { - int r = from->get_option(S_VAR("radius")); - - Color sc = from->get_option(S_VAR("color")); - Point2i so=Point2(from->get_option(S_VAR("offset"))); - - float tr = from->get_option(S_VAR("transition")); - print_line("shadow enabled: "+itos(si)); - - Vector<uint8_t> s2buf; - s2buf.resize(s.x*s.y); - uint8_t *wa=s2buf.ptr(); - - for(int j=0;j<s.x*s.y;j++){ - - wa[j]=0; - } - - // blit shadowa - for(int x=0;x<ow;x++) { - for(int y=0;y<oh;y++) { - int ofs = (o.y+y+so.y)*s.x+x+o.x+so.x; - wa[ofs]=font_data_list[i]->bitmap[y*ow+x]; - } - } - //blur shadow2 with separatable convolution - - if (r>0) { - - Vector<uint8_t> pixels2; - pixels2.resize(s2buf.size()); - uint8_t *w2=pixels2.ptr(); - //vert - for(int x=0;x<s.width;x++) { - for(int y=0;y<s.height;y++) { - - int ofs = y*s.width+x; - int sum=wa[ofs]; - - for(int k=1;k<=r;k++) { - - int ofs_d=MIN(y+k,s.height-1)*s.width+x; - int ofs_u=MAX(y-k,0)*s.width+x; - sum+=wa[ofs_d]; - sum+=wa[ofs_u]; - } - - w2[ofs]=sum/(r*2+1); - - } - } - //horiz - for(int x=0;x<s.width;x++) { - for(int y=0;y<s.height;y++) { - - int ofs = y*s.width+x; - int sum=w2[ofs]; - - for(int k=1;k<=r;k++) { - - int ofs_r=MIN(x+k,s.width-1)+s.width*y; - int ofs_l=MAX(x-k,0)+s.width*y; - sum+=w2[ofs_r]; - sum+=w2[ofs_l]; - } - - wa[ofs]=Math::pow(float(sum/(r*2+1))/255.0f,tr)*255.0f; - - } - } - - } - - //blend back - - for(int j=0;j<s.x*s.y;j++){ - Color wd(w[j*4+0]/255.0,w[j*4+1]/255.0,w[j*4+2]/255.0,w[j*4+3]/255.0); - Color ws(sc.r,sc.g,sc.b,sc.a*(wa[j]/255.0)); - Color b = wd.blend(ws); - - w[j*4+0]=b.r*255.0; - w[j*4+1]=b.g*255.0; - w[j*4+2]=b.b*255.0; - w[j*4+3]=b.a*255.0; - - } - } - } - - for(int y=0;y<oh;y++) { - int yc=CLAMP(y+font_data_list[i]->valign,0,height-1); - Color sc=color[yc]; - for(int x=0;x<ow;x++) { - int ofs = (o.y+y)*s.x+x+o.x; - float c = font_data_list[i]->bitmap[y*ow+x]/255.0; - Color src_col=sc; - src_col.a*=c; - Color dst_col(w[ofs*4+0]/255.0,w[ofs*4+1]/255.0,w[ofs*4+2]/255.0,w[ofs*4+3]/255.0); - dst_col = dst_col.blend(src_col); - w[ofs*4+0]=dst_col.r*255.0; - w[ofs*4+1]=dst_col.g*255.0; - w[ofs*4+2]=dst_col.b*255.0; - w[ofs*4+3]=dst_col.a*255.0; - } - } - - - w=PoolVector<uint8_t>::Write(); - - Image img(s.width,s.height,0,Image::FORMAT_RGBA8,pixels); - - font_data_list[i]->blit=img; - font_data_list[i]->blit_ofs=o; - - } - - //make atlas - int spacing=2; - Vector<Size2i> sizes; - sizes.resize(font_data_list.size()); - for(int i=0;i<font_data_list.size();i++) { - - sizes[i]=Size2(font_data_list[i]->blit.get_width()+spacing*2,font_data_list[i]->blit.get_height()+spacing*2); - - } - Vector<Point2i> res; - Size2i res_size; - EditorAtlas::fit(sizes,res,res_size); - res_size.x=nearest_power_of_2(res_size.x); - res_size.y=nearest_power_of_2(res_size.y); - print_line("Atlas size: "+res_size); - - Image atlas(res_size.x,res_size.y,0,Image::FORMAT_RGBA8); - - for(int i=0;i<font_data_list.size();i++) { - - if (font_data_list[i]->bitmap.size()==0) - continue; - atlas.blit_rect(font_data_list[i]->blit,Rect2(0,0,font_data_list[i]->blit.get_width(),font_data_list[i]->blit.get_height()),res[i]+Size2(spacing,spacing)); - font_data_list[i]->ofs_x=res[i].x+spacing; - font_data_list[i]->ofs_y=res[i].y+spacing; - - - } - - if (from->has_option("advanced/premultiply_alpha") && bool(from->get_option("advanced/premultiply_alpha"))) { - - PoolVector<uint8_t> data = atlas.get_data(); - int dl = data.size(); - { - PoolVector<uint8_t>::Write w = data.write(); - - for(int i=0;i<dl;i+=4) { - - w[i+0]= uint8_t(int(w[i+0])*int(w[i+3])/255); - w[i+1]= uint8_t(int(w[i+1])*int(w[i+3])/255); - w[i+2]= uint8_t(int(w[i+2])*int(w[i+3])/255); - } - } - - atlas=Image(res_size.x,res_size.y,0,Image::FORMAT_RGBA8,data); - } - - if (from->has_option("color/monochrome") && bool(from->get_option("color/monochrome"))) { - - atlas.convert(Image::FORMAT_LA8); - } - - - if (0) { - //debug the texture - Ref<ImageTexture> atlast = memnew( ImageTexture ); - atlast->create_from_image(atlas); - //atlast->create_from_image(font_data_list[5]->blit); - TextureRect *tf = memnew( TextureRect ); - tf->set_texture(atlast); - dialog->add_child(tf); - } - - - /* CREATE FONT */ - - int char_space = from->get_option("extra_space/char"); - int space_space = from->get_option("extra_space/space"); - int top_space = from->get_option("extra_space/top"); - int bottom_space = from->get_option("extra_space/bottom"); - bool enable_filter = from->get_option("advanced/enable_filter"); - if (from->has_option("advanced/disable_filter")){ // this is a compatibility check for a deprecated option - enable_filter = !from->get_option("advanced/disable_filter"); - } - - Ref<BitmapFont> font; - - if (p_existing!=String() && ResourceCache::has(p_existing)) { - - font = Ref<BitmapFont>( ResourceCache::get(p_existing)->cast_to<BitmapFont>()); - } - - if (font.is_null()) { - font = Ref<BitmapFont>( memnew( BitmapFont ) ); - } - - font->clear(); - font->set_height(height+bottom_space+top_space); - font->set_ascent(ascent+top_space); - font->set_distance_field_hint(font_mode==_EditorFontImportOptions::FONT_DISTANCE_FIELD); - - //register texures - { - Ref<ImageTexture> t = memnew(ImageTexture); - int flags; - if (!enable_filter) - flags=0; - else - flags=Texture::FLAG_FILTER; - t->create_from_image(atlas,flags); - t->set_storage( ImageTexture::STORAGE_COMPRESS_LOSSLESS ); - font->add_texture(t); - - } - //register characters - - - for(int i=0;i<font_data_list.size();i++) { - _EditorFontData *fd=font_data_list[i]; - int tex_idx=0; - - font->add_char(fd->character,tex_idx,Rect2( fd->ofs_x, fd->ofs_y, fd->blit.get_width(), fd->blit.get_height()),Point2(fd->halign-fd->blit_ofs.x,fd->valign-fd->blit_ofs.y+top_space), fd->advance+char_space+(fd->character==' '?space_space:0)); - memdelete(fd); - } - - for(Map<_EditorKerningKey,int>::Element *E=kerning_map.front();E;E=E->next()) { - - font->add_kerning_pair(E->key().A,E->key().B,E->get()); - } - - FT_Done_FreeType( library ); - - return font; -#else - - return Ref<BitmapFont>(); -#endif -} - - -String EditorFontImportPlugin::get_name() const { - - return "font"; -} -String EditorFontImportPlugin::get_visible_name() const{ - - return TTR("Font"); -} -void EditorFontImportPlugin::import_dialog(const String& p_from){ - - dialog->popup_import(p_from); -} -Error EditorFontImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from){ - - - Ref<BitmapFont> font = EditorFontImportPlugin::generate_font(p_from,p_path); - if (!font.is_valid()) - return ERR_CANT_CREATE; - - Ref<ResourceImportMetadata> from=p_from; - from->set_source_md5(0,FileAccess::get_md5(EditorImportPlugin::expand_source_path(from->get_source_path(0)))); - from->set_editor(get_name()); - font->set_import_metadata(from); - - return ResourceSaver::save(p_path,font); - -} - -void EditorFontImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { - - for(int i=0;i<p_drop.size();i++) { - String ext = p_drop[i].get_extension().to_lower(); - String file = p_drop[i].get_file(); - if (ext=="ttf" || ext=="otf" || ext=="fnt") { - - import_dialog(); - dialog->set_source_and_dest(p_drop[i],p_dest_path.plus_file(file.get_basename()+".fnt")); - break; - } - } -} - - -EditorFontImportPlugin::EditorFontImportPlugin(EditorNode* p_editor) { - - dialog = memnew( EditorFontImportDialog(this) ); - p_editor->get_gui_base()->add_child(dialog); -} -#endif diff --git a/tools/editor/io_plugins/editor_font_import_plugin.h b/tools/editor/io_plugins/editor_font_import_plugin.h deleted file mode 100644 index bed1463aeb..0000000000 --- a/tools/editor/io_plugins/editor_font_import_plugin.h +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************/ -/* editor_font_import_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITOR_FONT_IMPORT_PLUGIN_H -#define EDITOR_FONT_IMPORT_PLUGIN_H - -#include "tools/editor/editor_export.h" -#include "scene/resources/font.h" -#if 0 -class EditorNode; -class EditorFontImportDialog; - -class EditorFontImportPlugin : public EditorImportPlugin { - - GDCLASS(EditorFontImportPlugin,EditorImportPlugin); - - EditorFontImportDialog *dialog; -public: - - Ref<BitmapFont> generate_font(const Ref<ResourceImportMetadata>& p_from,const String& p_existing=String()); //used by editor - - virtual String get_name() const; - virtual String get_visible_name() const; - virtual void import_dialog(const String& p_from=""); - virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); - virtual void import_from_drop(const Vector<String>& p_drop,const String& p_dest_path); - - - EditorFontImportPlugin(EditorNode* p_editor); -}; - -#endif // EDITOR_FONT_IMPORT_PLUGIN_H -#endif diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp deleted file mode 100644 index fc3f8fd8c9..0000000000 --- a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp +++ /dev/null @@ -1,593 +0,0 @@ -/*************************************************************************/ -/* editor_mesh_import_plugin.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 "editor_mesh_import_plugin.h" - -#if 0 - -#include "tools/editor/editor_file_dialog.h" -#include "tools/editor/editor_dir_dialog.h" -#include "tools/editor/editor_node.h" -#include "tools/editor/property_editor.h" -//#include "scene/resources/sample.h" -#include "io/resource_saver.h" -#include "os/file_access.h" -#include "io/marshalls.h" -#include "scene/resources/surface_tool.h" - -class _EditorMeshImportOptions : public Object { - - GDCLASS(_EditorMeshImportOptions,Object); -public: - - - bool generate_tangents; - bool generate_normals; - bool flip_faces; - bool smooth_shading; - bool weld_vertices; - bool import_material; - bool import_textures; - float weld_tolerance; - - - bool _set(const StringName& p_name, const Variant& p_value) { - - String n = p_name; - if (n=="generate/tangents") - generate_tangents=p_value; - else if (n=="generate/normals") - generate_normals=p_value; - else if (n=="import/materials") - import_material=p_value; - else if (n=="import/textures") - import_textures=p_value; - else if (n=="force/flip_faces") - flip_faces=p_value; - else if (n=="force/smooth_shading") - smooth_shading=p_value; - else if (n=="force/weld_vertices") - weld_vertices=p_value; - else if (n=="force/weld_tolerance") - weld_tolerance=p_value; - else - return false; - - return true; - - } - - bool _get(const StringName& p_name,Variant &r_ret) const{ - - String n = p_name; - if (n=="generate/tangents") - r_ret=generate_tangents; - else if (n=="generate/normals") - r_ret=generate_normals; - else if (n=="import/materials") - r_ret=import_material; - else if (n=="import/textures") - r_ret=import_textures; - else if (n=="force/flip_faces") - r_ret=flip_faces; - else if (n=="force/smooth_shading") - r_ret=smooth_shading; - else if (n=="force/weld_vertices") - r_ret=weld_vertices; - else if (n=="force/weld_tolerance") - r_ret=weld_tolerance; - else - return false; - - return true; - - } - void _get_property_list( List<PropertyInfo> *p_list) const{ - - p_list->push_back(PropertyInfo(Variant::BOOL,"generate/tangents")); - p_list->push_back(PropertyInfo(Variant::BOOL,"generate/normals")); - //not for nowp - //p_list->push_back(PropertyInfo(Variant::BOOL,"import/materials")); - //p_list->push_back(PropertyInfo(Variant::BOOL,"import/textures")); - p_list->push_back(PropertyInfo(Variant::BOOL,"force/flip_faces")); - p_list->push_back(PropertyInfo(Variant::BOOL,"force/smooth_shading")); - p_list->push_back(PropertyInfo(Variant::BOOL,"force/weld_vertices")); - p_list->push_back(PropertyInfo(Variant::REAL,"force/weld_tolerance",PROPERTY_HINT_RANGE,"0.00001,16,0.00001")); - //p_list->push_back(PropertyInfo(Variant::BOOL,"compress/enable")); - //p_list->push_back(PropertyInfo(Variant::INT,"compress/bitrate",PROPERTY_HINT_ENUM,"64,96,128,192")); - - - } - - - static void _bind_methods() { - - - ADD_SIGNAL( MethodInfo("changed")); - } - - - _EditorMeshImportOptions() { - - generate_tangents=true; - generate_normals=false; - flip_faces=false; - smooth_shading=false; - weld_vertices=true; - weld_tolerance=0.0001; - import_material=false; - import_textures=false; - - } - - -}; - -class EditorMeshImportDialog : public ConfirmationDialog { - - GDCLASS(EditorMeshImportDialog,ConfirmationDialog); - - EditorMeshImportPlugin *plugin; - - LineEdit *import_path; - LineEdit *save_path; - EditorFileDialog *file_select; - EditorDirDialog *save_select; - AcceptDialog *error_dialog; - PropertyEditor *option_editor; - - _EditorMeshImportOptions *options; - - -public: - - void _choose_files(const Vector<String>& p_path) { - - String files; - for(int i=0;i<p_path.size();i++) { - - if (i>0) - files+=","; - files+=p_path[i]; - } - /* - if (p_path.size()) { - String srctex=p_path[0]; - String ipath = EditorImportDB::get_singleton()->find_source_path(srctex); - - if (ipath!="") - save_path->set_text(ipath.get_base_dir()); - }*/ - import_path->set_text(files); - - } - void _choose_save_dir(const String& p_path) { - - save_path->set_text(p_path); - } - - void _browse() { - - file_select->popup_centered_ratio(); - } - - void _browse_target() { - - save_select->popup_centered_ratio(); - } - - void popup_import(const String& p_path) { - - popup_centered(Size2(400,400)*EDSCALE); - - if (p_path!="") { - - Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); - ERR_FAIL_COND(!rimd.is_valid()); - - save_path->set_text(p_path.get_base_dir()); - List<String> opts; - rimd->get_options(&opts); - for(List<String>::Element *E=opts.front();E;E=E->next()) { - - options->_set(E->get(),rimd->get_option(E->get())); - } - - String src = ""; - for(int i=0;i<rimd->get_source_count();i++) { - if (i>0) - src+=","; - src+=EditorImportPlugin::expand_source_path(rimd->get_source_path(i)); - } - import_path->set_text(src); - } - } - - void _import() { - - Vector<String> meshes = import_path->get_text().split(","); - if (meshes.size()==0) { - error_dialog->set_text(TTR("No meshes to import!")); - error_dialog->popup_centered_minsize(); - return; - } - - String dst = save_path->get_text(); - if (dst=="") { - error_dialog->set_text(TTR("Save path is empty!")); - error_dialog->popup_centered_minsize(); - return; - } - - for(int i=0;i<meshes.size();i++) { - - Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); - - List<PropertyInfo> pl; - options->_get_property_list(&pl); - for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { - - Variant v; - String opt=E->get().name; - options->_get(opt,v); - imd->set_option(opt,v); - - } - - imd->add_source(EditorImportPlugin::validate_source_path(meshes[i])); - - String file_path = dst.plus_file(meshes[i].get_file().get_basename()+".msh"); - - plugin->import(file_path,imd); - } - - hide(); - } - - void _notification(int p_what) { - - - if (p_what==NOTIFICATION_ENTER_TREE) { - - option_editor->edit(options); - } - } - - static void _bind_methods() { - - ClassDB::bind_method("_choose_files",&EditorMeshImportDialog::_choose_files); - ClassDB::bind_method("_choose_save_dir",&EditorMeshImportDialog::_choose_save_dir); - ClassDB::bind_method("_import",&EditorMeshImportDialog::_import); - ClassDB::bind_method("_browse",&EditorMeshImportDialog::_browse); - ClassDB::bind_method("_browse_target",&EditorMeshImportDialog::_browse_target); - } - - EditorMeshImportDialog(EditorMeshImportPlugin *p_plugin) { - - plugin=p_plugin; - - set_title(TTR("Single Mesh Import")); - set_hide_on_ok(false); - - VBoxContainer *vbc = memnew( VBoxContainer ); - add_child(vbc); - //set_child_rect(vbc); - - HBoxContainer *hbc = memnew( HBoxContainer ); - vbc->add_margin_child(TTR("Source Mesh(es):"),hbc); - - import_path = memnew( LineEdit ); - import_path->set_h_size_flags(SIZE_EXPAND_FILL); - hbc->add_child(import_path); - - Button * import_choose = memnew( Button ); - import_choose->set_text(" .. "); - hbc->add_child(import_choose); - - import_choose->connect("pressed", this,"_browse"); - - hbc = memnew( HBoxContainer ); - vbc->add_margin_child(TTR("Target Path:"),hbc); - - save_path = memnew( LineEdit ); - save_path->set_h_size_flags(SIZE_EXPAND_FILL); - hbc->add_child(save_path); - - Button * save_choose = memnew( Button ); - save_choose->set_text(" .. "); - hbc->add_child(save_choose); - - save_choose->connect("pressed", this,"_browse_target"); - - file_select = memnew( EditorFileDialog ); - file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); - file_select->add_filter("*.obj ; Wavefront OBJ"); - add_child(file_select); - file_select->connect("files_selected", this,"_choose_files"); - - save_select = memnew( EditorDirDialog ); - add_child(save_select); - save_select->connect("dir_selected", this,"_choose_save_dir"); - - get_ok()->connect("pressed", this,"_import"); - get_ok()->set_text(TTR("Import")); - - error_dialog = memnew( AcceptDialog ); - add_child(error_dialog); - - options = memnew( _EditorMeshImportOptions ); - - option_editor = memnew( PropertyEditor ); - option_editor->hide_top_label(); - vbc->add_margin_child(TTR("Options:"),option_editor,true); - } - - ~EditorMeshImportDialog() { - memdelete(options); - } - -}; - - -String EditorMeshImportPlugin::get_name() const { - - return "mesh"; -} -String EditorMeshImportPlugin::get_visible_name() const{ - - return TTR("Mesh"); -} -void EditorMeshImportPlugin::import_dialog(const String& p_from){ - - dialog->popup_import(p_from); -} -Error EditorMeshImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from){ - - - ERR_FAIL_COND_V(p_from->get_source_count()!=1,ERR_INVALID_PARAMETER); - - Ref<ResourceImportMetadata> from=p_from; - - String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0)); - FileAccessRef f = FileAccess::open(src_path,FileAccess::READ); - ERR_FAIL_COND_V(!f,ERR_CANT_OPEN); - - Ref<Mesh> mesh; - Map<String,Ref<Material> > name_map; - - if (FileAccess::exists(p_path)) { - mesh=ResourceLoader::load(p_path,"Mesh"); - if (mesh.is_valid()) { - for(int i=0;i<mesh->get_surface_count();i++) { - - if (!mesh->surface_get_material(i).is_valid()) - continue; - String name; - if (mesh->surface_get_name(i)!="") - name=mesh->surface_get_name(i); - else - name=vformat(TTR("Surface %d"),i+1); - - name_map[name]=mesh->surface_get_material(i); - } - - while(mesh->get_surface_count()) { - mesh->surface_remove(0); - } - } - } - - if (!mesh.is_valid()) - mesh = Ref<Mesh>( memnew( Mesh ) ); - - - bool generate_normals=from->get_option("generate/normals"); - bool generate_tangents=from->get_option("generate/tangents"); - bool flip_faces=from->get_option("force/flip_faces"); - bool force_smooth=from->get_option("force/smooth_shading"); - bool weld_vertices=from->get_option("force/weld_vertices"); - float weld_tolerance=from->get_option("force/weld_tolerance"); - Vector<Vector3> vertices; - Vector<Vector3> normals; - Vector<Vector2> uvs; - String name; - - Ref<SurfaceTool> surf_tool = memnew( SurfaceTool) ; - surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES); - if (force_smooth) - surf_tool->add_smooth_group(true); - int has_index_data=false; - - while(true) { - - - String l = f->get_line().strip_edges(); - - if (l.begins_with("v ")) { - //vertex - Vector<String> v = l.split(" ",false); - ERR_FAIL_COND_V(v.size()<4,ERR_INVALID_DATA); - Vector3 vtx; - vtx.x=v[1].to_float(); - vtx.y=v[2].to_float(); - vtx.z=v[3].to_float(); - vertices.push_back(vtx); - } else if (l.begins_with("vt ")) { - //uv - Vector<String> v = l.split(" ",false); - ERR_FAIL_COND_V(v.size()<3,ERR_INVALID_DATA); - Vector2 uv; - uv.x=v[1].to_float(); - uv.y=1.0-v[2].to_float(); - uvs.push_back(uv); - - } else if (l.begins_with("vn ")) { - //normal - Vector<String> v = l.split(" ",false); - ERR_FAIL_COND_V(v.size()<4,ERR_INVALID_DATA); - Vector3 nrm; - nrm.x=v[1].to_float(); - nrm.y=v[2].to_float(); - nrm.z=v[3].to_float(); - normals.push_back(nrm); - } if (l.begins_with("f ")) { - //vertex - - has_index_data=true; - Vector<String> v = l.split(" ",false); - ERR_FAIL_COND_V(v.size()<4,ERR_INVALID_DATA); - - //not very fast, could be sped up - - - Vector<String> face[3]; - face[0] = v[1].split("/"); - face[1] = v[2].split("/"); - ERR_FAIL_COND_V(face[0].size()==0,ERR_PARSE_ERROR); - ERR_FAIL_COND_V(face[0].size()!=face[1].size(),ERR_PARSE_ERROR); - for(int i=2;i<v.size()-1;i++) { - - face[2] = v[i+1].split("/"); - ERR_FAIL_COND_V(face[0].size()!=face[2].size(),ERR_PARSE_ERROR); - for(int j=0;j<3;j++) { - - int idx=j; - - if (!flip_faces && idx<2) { - idx=1^idx; - } - - - if (face[idx].size()==3) { - int norm = face[idx][2].to_int()-1; - ERR_FAIL_INDEX_V(norm,normals.size(),ERR_PARSE_ERROR); - surf_tool->add_normal(normals[norm]); - } - - if (face[idx].size()>=2 && face[idx][1]!=String()) { - - int uv = face[idx][1].to_int()-1; - ERR_FAIL_INDEX_V(uv,uvs.size(),ERR_PARSE_ERROR); - surf_tool->add_uv(uvs[uv]); - } - - int vtx = face[idx][0].to_int()-1; - ERR_FAIL_INDEX_V(vtx,vertices.size(),ERR_PARSE_ERROR); - - Vector3 vertex = vertices[vtx]; - if (weld_vertices) - vertex=vertex.snapped(weld_tolerance); - surf_tool->add_vertex(vertex); - } - - face[1]=face[2]; - } - } else if (l.begins_with("s ") && !force_smooth) { //smoothing - String what = l.substr(2,l.length()).strip_edges(); - if (what=="off") - surf_tool->add_smooth_group(false); - else - surf_tool->add_smooth_group(true); - - } else if (l.begins_with("o ") || f->eof_reached()) { //new surface or done - - if (has_index_data) { - //new object/surface - if (generate_normals || force_smooth) - surf_tool->generate_normals(); - if (uvs.size() && (normals.size() || generate_normals) && generate_tangents) - surf_tool->generate_tangents(); - - surf_tool->index(); - mesh = surf_tool->commit(mesh); - if (name=="") - name=vformat(TTR("Surface %d"),mesh->get_surface_count()-1); - mesh->surface_set_name(mesh->get_surface_count()-1,name); - name=""; - surf_tool->clear(); - surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES); - if (force_smooth) - surf_tool->add_smooth_group(true); - - has_index_data=false; - - if (f->eof_reached()) - break; - } - - if (l.begins_with("o ")) //name - name=l.substr(2,l.length()).strip_edges(); - } - } - - - from->set_source_md5(0,FileAccess::get_md5(src_path)); - from->set_editor(get_name()); - mesh->set_import_metadata(from); - - //re-apply materials if exist - for(int i=0;i<mesh->get_surface_count();i++) { - - String n = mesh->surface_get_name(i); - if (name_map.has(n)) - mesh->surface_set_material(i,name_map[n]); - } - - Error err = ResourceSaver::save(p_path,mesh); - - return err; -} - - -void EditorMeshImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { - - - Vector<String> files; - for(int i=0;i<p_drop.size();i++) { - String ext = p_drop[i].get_extension().to_lower(); - String file = p_drop[i].get_file(); - if (ext=="obj") { - - files.push_back(p_drop[i]); - } - } - - if (files.size()) { - import_dialog(); - dialog->_choose_files(files); - dialog->_choose_save_dir(p_dest_path); - } -} - -EditorMeshImportPlugin::EditorMeshImportPlugin(EditorNode* p_editor) { - - dialog = memnew( EditorMeshImportDialog(this)); - p_editor->get_gui_base()->add_child(dialog); -} -#endif diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.h b/tools/editor/io_plugins/editor_mesh_import_plugin.h deleted file mode 100644 index ba8ec58191..0000000000 --- a/tools/editor/io_plugins/editor_mesh_import_plugin.h +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************/ -/* editor_mesh_import_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITOR_MESH_IMPORT_PLUGIN_H -#define EDITOR_MESH_IMPORT_PLUGIN_H - -#if 0 -#include "tools/editor/editor_import_export.h" -#include "scene/resources/font.h" - -class EditorNode; -class EditorMeshImportDialog; - -class EditorMeshImportPlugin : public EditorImportPlugin { - - GDCLASS(EditorMeshImportPlugin,EditorImportPlugin); - - EditorMeshImportDialog *dialog; - - -public: - - virtual String get_name() const; - virtual String get_visible_name() const; - virtual void import_dialog(const String& p_from=""); - virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); - void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); - - - EditorMeshImportPlugin(EditorNode* p_editor); -}; - -#endif -#endif // EDITOR_MESH_IMPORT_PLUGIN_H diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.cpp b/tools/editor/io_plugins/editor_sample_import_plugin.cpp deleted file mode 100644 index 631291ec1b..0000000000 --- a/tools/editor/io_plugins/editor_sample_import_plugin.cpp +++ /dev/null @@ -1,929 +0,0 @@ -/*************************************************************************/ -/* editor_sample_import_plugin.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 "editor_sample_import_plugin.h" - -#include "tools/editor/editor_file_dialog.h" -#include "tools/editor/editor_dir_dialog.h" -#include "tools/editor/editor_node.h" -#include "tools/editor/property_editor.h" -#include "io/resource_saver.h" -#include "os/file_access.h" -#include "io/marshalls.h" -#include "tools/editor/editor_settings.h" - -#if 0 - -class _EditorSampleImportOptions : public Object { - - GDCLASS(_EditorSampleImportOptions,Object); -public: - - enum CompressMode { - COMPRESS_MODE_DISABLED, - COMPRESS_MODE_RAM, - COMPRESS_MODE_DISK - }; - - enum CompressBitrate { - COMPRESS_64, - COMPRESS_96, - COMPRESS_128, - COMPRESS_192 - }; - - bool force_8_bit; - bool force_mono; - bool force_rate; - float force_rate_hz; - - bool edit_trim; - bool edit_normalize; - bool edit_loop; - - CompressMode compress_mode; - CompressBitrate compress_bitrate; - - - bool _set(const StringName& p_name, const Variant& p_value) { - - String n = p_name; - if (n=="force/8_bit") - force_8_bit=p_value; - else if (n=="force/mono") - force_mono=p_value; - else if (n=="force/max_rate") - force_rate=p_value; - else if (n=="force/max_rate_hz") - force_rate_hz=p_value; - else if (n=="edit/trim") - edit_trim=p_value; - else if (n=="edit/normalize") - edit_normalize=p_value; - else if (n=="edit/loop") - edit_loop=p_value; - else if (n=="compress/mode") - compress_mode=CompressMode(int(p_value)); - else if (n=="compress/bitrate") - compress_bitrate=CompressBitrate(int(p_value)); - else - return false; - - return true; - - } - - bool _get(const StringName& p_name,Variant &r_ret) const{ - - String n = p_name; - if (n=="force/8_bit") - r_ret=force_8_bit; - else if (n=="force/mono") - r_ret=force_mono; - else if (n=="force/max_rate") - r_ret=force_rate; - else if (n=="force/max_rate_hz") - r_ret=force_rate_hz; - else if (n=="edit/trim") - r_ret=edit_trim; - else if (n=="edit/normalize") - r_ret=edit_normalize; - else if (n=="edit/loop") - r_ret=edit_loop; - else if (n=="compress/mode") - r_ret=compress_mode; - else if (n=="compress/bitrate") - r_ret=compress_bitrate; - else - return false; - - return true; - - } - void _get_property_list( List<PropertyInfo> *p_list) const{ - - p_list->push_back(PropertyInfo(Variant::BOOL,"force/8_bit")); - p_list->push_back(PropertyInfo(Variant::BOOL,"force/mono")); - p_list->push_back(PropertyInfo(Variant::BOOL,"force/max_rate")); - p_list->push_back(PropertyInfo(Variant::REAL,"force/max_rate_hz",PROPERTY_HINT_EXP_RANGE,"11025,192000,1")); - p_list->push_back(PropertyInfo(Variant::BOOL,"edit/trim")); - p_list->push_back(PropertyInfo(Variant::BOOL,"edit/normalize")); - p_list->push_back(PropertyInfo(Variant::BOOL,"edit/loop")); - p_list->push_back(PropertyInfo(Variant::INT,"compress/mode",PROPERTY_HINT_ENUM,"Disabled,RAM (Ima-ADPCM)")); - //p_list->push_back(PropertyInfo(Variant::INT,"compress/bitrate",PROPERTY_HINT_ENUM,"64,96,128,192")); - - - } - - - static void _bind_methods() { - - - ADD_SIGNAL( MethodInfo("changed")); - } - - - _EditorSampleImportOptions() { - - force_8_bit=false; - force_mono=false; - force_rate=true; - force_rate_hz=44100; - - edit_trim=true; - edit_normalize=true; - edit_loop=false; - - compress_mode=COMPRESS_MODE_RAM; - compress_bitrate=COMPRESS_128; - } - - -}; - -class EditorSampleImportDialog : public ConfirmationDialog { - - GDCLASS(EditorSampleImportDialog,ConfirmationDialog); - - EditorSampleImportPlugin *plugin; - - LineEdit *import_path; - LineEdit *save_path; - EditorFileDialog *file_select; - EditorDirDialog *save_select; - ConfirmationDialog *error_dialog; - PropertyEditor *option_editor; - - _EditorSampleImportOptions *options; - - -public: - - void _choose_files(const Vector<String>& p_path) { - - String files; - for(int i=0;i<p_path.size();i++) { - - if (i>0) - files+=","; - files+=p_path[i]; - } - /* - if (p_path.size()) { - String srctex=p_path[0]; - String ipath = EditorImportDB::get_singleton()->find_source_path(srctex); - - if (ipath!="") - save_path->set_text(ipath.get_base_dir()); - }*/ - import_path->set_text(files); - - } - void _choose_save_dir(const String& p_path) { - - save_path->set_text(p_path); - } - - void _browse() { - - file_select->popup_centered_ratio(); - } - - void _browse_target() { - - save_select->popup_centered_ratio(); - - } - - - void popup_import(const String& p_path) { - - popup_centered(Size2(400,400)*EDSCALE); - if (p_path!="") { - - Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); - ERR_FAIL_COND(!rimd.is_valid()); - - save_path->set_text(p_path.get_base_dir()); - List<String> opts; - rimd->get_options(&opts); - for(List<String>::Element *E=opts.front();E;E=E->next()) { - - options->_set(E->get(),rimd->get_option(E->get())); - } - - String src = ""; - for(int i=0;i<rimd->get_source_count();i++) { - if (i>0) - src+=","; - src+=EditorImportPlugin::expand_source_path(rimd->get_source_path(i)); - } - import_path->set_text(src); - } - } - - - void _import() { - - Vector<String> samples = import_path->get_text().split(","); - - if (samples.size()==0) { - error_dialog->set_text(TTR("No samples to import!")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - } - - if (save_path->get_text().strip_edges()=="") { - error_dialog->set_text(TTR("Target path is empty.")); - error_dialog->popup_centered_minsize(); - return; - } - - if (!save_path->get_text().begins_with("res://")) { - error_dialog->set_text(TTR("Target path must be a complete resource path.")); - error_dialog->popup_centered_minsize(); - return; - } - - if (!DirAccess::exists(save_path->get_text())) { - error_dialog->set_text(TTR("Target path must exist.")); - error_dialog->popup_centered_minsize(); - return; - } - - for(int i=0;i<samples.size();i++) { - - Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); - - List<PropertyInfo> pl; - options->_get_property_list(&pl); - for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { - - Variant v; - String opt=E->get().name; - options->_get(opt,v); - imd->set_option(opt,v); - - } - - imd->add_source(EditorImportPlugin::validate_source_path(samples[i])); - - String dst = save_path->get_text(); - if (dst=="") { - error_dialog->set_text(TTR("Save path is empty!")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - } - - dst = dst.plus_file(samples[i].get_file().get_basename()+".smp"); - - plugin->import(dst,imd); - } - - hide(); - - } - - - void _notification(int p_what) { - - - if (p_what==NOTIFICATION_ENTER_TREE) { - - option_editor->edit(options); - } - } - - static void _bind_methods() { - - - ClassDB::bind_method("_choose_files",&EditorSampleImportDialog::_choose_files); - ClassDB::bind_method("_choose_save_dir",&EditorSampleImportDialog::_choose_save_dir); - ClassDB::bind_method("_import",&EditorSampleImportDialog::_import); - ClassDB::bind_method("_browse",&EditorSampleImportDialog::_browse); - ClassDB::bind_method("_browse_target",&EditorSampleImportDialog::_browse_target); - //ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); - } - - EditorSampleImportDialog(EditorSampleImportPlugin *p_plugin) { - - plugin=p_plugin; - - - set_title(TTR("Import Audio Samples")); - - VBoxContainer *vbc = memnew( VBoxContainer ); - add_child(vbc); - //set_child_rect(vbc); - - - HBoxContainer *hbc = memnew( HBoxContainer ); - vbc->add_margin_child(TTR("Source Sample(s):"),hbc); - - import_path = memnew( LineEdit ); - import_path->set_h_size_flags(SIZE_EXPAND_FILL); - hbc->add_child(import_path); - - Button * import_choose = memnew( Button ); - import_choose->set_text(" .. "); - hbc->add_child(import_choose); - - import_choose->connect("pressed", this,"_browse"); - - hbc = memnew( HBoxContainer ); - vbc->add_margin_child(TTR("Target Path:"),hbc); - - save_path = memnew( LineEdit ); - save_path->set_h_size_flags(SIZE_EXPAND_FILL); - hbc->add_child(save_path); - - Button * save_choose = memnew( Button ); - save_choose->set_text(" .. "); - hbc->add_child(save_choose); - - save_choose->connect("pressed", this,"_browse_target"); - - file_select = memnew(EditorFileDialog); - file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - add_child(file_select); - file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); - file_select->connect("files_selected", this,"_choose_files"); - file_select->add_filter("*.wav ; MS Waveform"); - save_select = memnew( EditorDirDialog ); - add_child(save_select); - - //save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); - save_select->connect("dir_selected", this,"_choose_save_dir"); - - get_ok()->connect("pressed", this,"_import"); - get_ok()->set_text(TTR("Import")); - - - error_dialog = memnew ( ConfirmationDialog ); - add_child(error_dialog); - error_dialog->get_ok()->set_text(TTR("Accept")); - //error_dialog->get_cancel()->hide(); - - set_hide_on_ok(false); - options = memnew( _EditorSampleImportOptions ); - - option_editor = memnew( PropertyEditor ); - option_editor->hide_top_label(); - vbc->add_margin_child(TTR("Options:"),option_editor,true); - } - - ~EditorSampleImportDialog() { - memdelete(options); - } - -}; - - -String EditorSampleImportPlugin::get_name() const { - - return "sample"; -} -String EditorSampleImportPlugin::get_visible_name() const{ - - return TTR("Audio Sample"); -} -void EditorSampleImportPlugin::import_dialog(const String& p_from){ - - dialog->popup_import(p_from); -} -Error EditorSampleImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from){ - - ERR_FAIL_COND_V(p_from->get_source_count()!=1,ERR_INVALID_PARAMETER); - - Ref<ResourceImportMetadata> from=p_from; - - String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0)); - Ref<Sample> smp = ResourceLoader::load(src_path); - ERR_FAIL_COND_V(smp.is_null(),ERR_CANT_OPEN); - - - float rate = smp->get_mix_rate(); - bool is16 = smp->get_format()==Sample::FORMAT_PCM16; - int chans = smp->is_stereo()?2:1; - int len = smp->get_length(); - Sample::LoopFormat loop= smp->get_loop_format(); - int loop_beg = smp->get_loop_begin(); - int loop_end = smp->get_loop_end(); - - print_line("Input Sample: "); - print_line("\tlen: "+itos(len)); - print_line("\tchans: "+itos(chans)); - print_line("\t16bits: "+itos(is16)); - print_line("\trate: "+itos(rate)); - print_line("\tloop: "+itos(loop)); - print_line("\tloop begin: "+itos(loop_beg)); - print_line("\tloop end: "+itos(loop_end)); - Vector<float> data; - data.resize(len*chans); - - { - PoolVector<uint8_t> src_data = smp->get_data(); - PoolVector<uint8_t>::Read sr = src_data.read(); - - - for(int i=0;i<len*chans;i++) { - - float s=0; - if (is16) { - - int16_t i16 = decode_uint16(&sr[i*2]); - s=i16/32767.0; - } else { - - int8_t i8 = sr[i]; - s=i8/127.0; - } - data[i]=s; - } - } - - //apply frequency limit - - bool limit_rate = from->get_option("force/max_rate"); - int limit_rate_hz = from->get_option("force/max_rate_hz"); - if (limit_rate && rate > limit_rate_hz) { - //resampleeee!!! - int new_data_len = len * limit_rate_hz / rate; - Vector<float> new_data; - new_data.resize( new_data_len * chans ); - for(int c=0;c<chans;c++) { - - for(int i=0;i<new_data_len;i++) { - - //simple cubic interpolation should be enough. - float pos = float(i) * len / new_data_len; - float mu = pos-Math::floor(pos); - int ipos = int(Math::floor(pos)); - - float y0=data[MAX(0,ipos-1)*chans+c]; - float y1=data[ipos*chans+c]; - float y2=data[MIN(len-1,ipos+1)*chans+c]; - float y3=data[MIN(len-1,ipos+2)*chans+c]; - - float mu2 = mu*mu; - float a0 = y3 - y2 - y0 + y1; - float a1 = y0 - y1 - a0; - float a2 = y2 - y0; - float a3 = y1; - - float res=(a0*mu*mu2+a1*mu2+a2*mu+a3); - - new_data[i*chans+c]=res; - } - } - - if (loop) { - - loop_beg=loop_beg*new_data_len/len; - loop_end=loop_end*new_data_len/len; - } - data=new_data; - rate=limit_rate_hz; - len=new_data_len; - } - - - bool normalize = from->get_option("edit/normalize"); - - if (normalize) { - - float max=0; - for(int i=0;i<data.size();i++) { - - float amp = Math::abs(data[i]); - if (amp>max) - max=amp; - } - - if (max>0) { - - float mult=1.0/max; - for(int i=0;i<data.size();i++) { - - data[i]*=mult; - } - - } - } - - bool trim = from->get_option("edit/trim"); - - if (trim && !loop) { - - int first=0; - int last=(len*chans)-1; - bool found=false; - float limit = Math::db2linear((float)-30); - for(int i=0;i<data.size();i++) { - float amp = Math::abs(data[i]); - - if (!found && amp > limit) { - first=i; - found=true; - } - - if (found && amp > limit) { - last=i; - } - } - - first/=chans; - last/=chans; - - if (first<last) { - - Vector<float> new_data; - new_data.resize((last-first+1)*chans); - for(int i=first*chans;i<=last*chans;i++) { - new_data[i-first*chans]=data[i]; - } - - data=new_data; - len=data.size()/chans; - } - - } - - bool make_loop = from->get_option("edit/loop"); - - if (make_loop && !loop) { - - loop=Sample::LOOP_FORWARD; - loop_beg=0; - loop_end=len; - } - - int compression = from->get_option("compress/mode"); - bool force_mono = from->get_option("force/mono"); - - - if (force_mono && chans==2) { - - Vector<float> new_data; - new_data.resize(data.size()/2); - for(int i=0;i<len;i++) { - new_data[i]=(data[i*2+0]+data[i*2+1])/2.0; - } - - data=new_data; - chans=1; - } - - bool force_8_bit = from->get_option("force/8_bit"); - if (force_8_bit) { - - is16=false; - } - - - PoolVector<uint8_t> dst_data; - Sample::Format dst_format; - - if ( compression == _EditorSampleImportOptions::COMPRESS_MODE_RAM) { - - dst_format=Sample::FORMAT_IMA_ADPCM; - if (chans==1) { - _compress_ima_adpcm(data,dst_data); - } else { - - print_line("INTERLEAAVE!"); - - - - //byte interleave - Vector<float> left; - Vector<float> right; - - int tlen = data.size()/2; - left.resize(tlen); - right.resize(tlen); - - for(int i=0;i<tlen;i++) { - left[i]=data[i*2+0]; - right[i]=data[i*2+1]; - } - - PoolVector<uint8_t> bleft; - PoolVector<uint8_t> bright; - - _compress_ima_adpcm(left,bleft); - _compress_ima_adpcm(right,bright); - - int dl = bleft.size(); - dst_data.resize( dl *2 ); - - PoolVector<uint8_t>::Write w=dst_data.write(); - PoolVector<uint8_t>::Read rl=bleft.read(); - PoolVector<uint8_t>::Read rr=bright.read(); - - for(int i=0;i<dl;i++) { - w[i*2+0]=rl[i]; - w[i*2+1]=rr[i]; - } - } - - //print_line("compressing ima-adpcm, resulting buffersize is "+itos(dst_data.size())+" from "+itos(data.size())); - - } else { - - dst_format=is16?Sample::FORMAT_PCM16:Sample::FORMAT_PCM8; - dst_data.resize( data.size() * (is16?2:1)); - { - PoolVector<uint8_t>::Write w = dst_data.write(); - - int ds=data.size(); - for(int i=0;i<ds;i++) { - - if (is16) { - int16_t v = CLAMP(data[i]*32767,-32768,32767); - encode_uint16(v,&w[i*2]); - } else { - int8_t v = CLAMP(data[i]*127,-128,127); - w[i]=v; - } - } - } - } - - - Ref<Sample> target; - - if (ResourceCache::has(p_path)) { - - target = Ref<Sample>( ResourceCache::get(p_path)->cast_to<Sample>() ); - } else { - - target = smp; - } - - target->create(dst_format,chans==2?true:false,len); - target->set_data(dst_data); - target->set_mix_rate(rate); - target->set_loop_format(loop); - target->set_loop_begin(loop_beg); - target->set_loop_end(loop_end); - - from->set_source_md5(0,FileAccess::get_md5(src_path)); - from->set_editor(get_name()); - target->set_import_metadata(from); - - - Error err = ResourceSaver::save(p_path,smp); - - return err; - -} - -void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,PoolVector<uint8_t>& dst_data) { - - - /*p_sample_data->data = (void*)malloc(len); - xm_s8 *dataptr=(xm_s8*)p_sample_data->data;*/ - - static const int16_t _ima_adpcm_step_table[89] = { - 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, - 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, - 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, - 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, - 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, - 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, - 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, - 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 - }; - - static const int8_t _ima_adpcm_index_table[16] = { - -1, -1, -1, -1, 2, 4, 6, 8, - -1, -1, -1, -1, 2, 4, 6, 8 - }; - - - int datalen = p_data.size(); - int datamax=datalen; - if (datalen&1) - datalen++; - - dst_data.resize(datalen/2+4); - PoolVector<uint8_t>::Write w = dst_data.write(); - - - int i,step_idx=0,prev=0; - uint8_t *out = w.ptr(); - //int16_t xm_prev=0; - const float *in=p_data.ptr(); - - - /* initial value is zero */ - *(out++) =0; - *(out++) =0; - /* Table index initial value */ - *(out++) =0; - /* unused */ - *(out++) =0; - - for (i=0;i<datalen;i++) { - int step,diff,vpdiff,mask; - uint8_t nibble; - int16_t xm_sample; - - if (i>=datamax) - xm_sample=0; - else { - - - xm_sample=CLAMP(in[i]*32767.0,-32768,32767); - /* - if (xm_sample==32767 || xm_sample==-32768) - printf("clippy!\n",xm_sample); - */ - } - - //xm_sample=xm_sample+xm_prev; - //xm_prev=xm_sample; - - diff = (int)xm_sample - prev ; - - nibble=0 ; - step = _ima_adpcm_step_table[ step_idx ]; - vpdiff = step >> 3 ; - if (diff < 0) { - nibble=8; - diff=-diff ; - } - mask = 4 ; - while (mask) { - - if (diff >= step) { - - nibble |= mask; - diff -= step; - vpdiff += step; - } - - step >>= 1 ; - mask >>= 1 ; - }; - - if (nibble&8) - prev-=vpdiff ; - else - prev+=vpdiff ; - - if (prev > 32767) { - //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip up %i\n",i,xm_sample,prev,diff,vpdiff,prev); - prev=32767; - } else if (prev < -32768) { - //printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip down %i\n",i,xm_sample,prev,diff,vpdiff,prev); - prev = -32768 ; - } - - step_idx += _ima_adpcm_index_table[nibble]; - if (step_idx< 0) - step_idx= 0 ; - else if (step_idx> 88) - step_idx= 88 ; - - - if (i&1) { - *out|=nibble<<4; - out++; - } else { - *out=nibble; - } - /*dataptr[i]=prev>>8;*/ - } - -} - - -EditorSampleImportPlugin* EditorSampleImportPlugin::singleton=NULL; - - -void EditorSampleImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { - - - Vector<String> files; - for(int i=0;i<p_drop.size();i++) { - String ext = p_drop[i].get_extension().to_lower(); - - if (ext=="wav") { - - files.push_back(p_drop[i]); - } - } - - if (files.size()) { - import_dialog(); - dialog->_choose_files(files); - dialog->_choose_save_dir(p_dest_path); - } -} - -void EditorSampleImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { - - if (p_list.size()==0) - return; - - Vector<String> sources; - for(int i=0;i<p_list.size();i++) { - int idx; - EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->find_file(p_list[i],&idx); - if (efsd) { - for(int j=0;j<efsd->get_source_count(idx);j++) { - String file = expand_source_path(efsd->get_source_file(idx,j)); - if (sources.find(file)==-1) { - sources.push_back(file); - } - - } - } - } - - if (sources.size()) { - - dialog->popup_import(p_list[0]); - dialog->_choose_files(sources); - dialog->_choose_save_dir(p_list[0].get_base_dir()); - } -} - -bool EditorSampleImportPlugin::can_reimport_multiple_files() const { - - return true; -} - -EditorSampleImportPlugin::EditorSampleImportPlugin(EditorNode* p_editor) { - - singleton=this; - dialog = memnew( EditorSampleImportDialog(this)); - p_editor->get_gui_base()->add_child(dialog); -} - -Vector<uint8_t> EditorSampleExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) { - - - - if (EditorImportExport::get_singleton()->sample_get_action()==EditorImportExport::SAMPLE_ACTION_NONE || p_path.get_extension().to_lower()!="wav") { - - return Vector<uint8_t>(); - } - - Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); - - imd->add_source(EditorImportPlugin::validate_source_path(p_path)); - - imd->set_option("force/8_bit",false); - imd->set_option("force/mono",false); - imd->set_option("force/max_rate",true); - imd->set_option("force/max_rate_hz",EditorImportExport::get_singleton()->sample_get_max_hz()); - imd->set_option("edit/trim",EditorImportExport::get_singleton()->sample_get_trim()); - imd->set_option("edit/normalize",false); - imd->set_option("edit/loop",false); - imd->set_option("compress/mode",1); - - String savepath = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/smpconv.smp"); - Error err = EditorSampleImportPlugin::singleton->import(savepath,imd); - - - ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>()); - - p_path=p_path.get_basename()+".converted.smp"; - return FileAccess::get_file_as_array(savepath); - -} - - - -EditorSampleExportPlugin::EditorSampleExportPlugin() { - -} - -#endif diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.h b/tools/editor/io_plugins/editor_sample_import_plugin.h deleted file mode 100644 index 8e02d0e11d..0000000000 --- a/tools/editor/io_plugins/editor_sample_import_plugin.h +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************/ -/* editor_sample_import_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITOR_SAMPLE_IMPORT_PLUGIN_H -#define EDITOR_SAMPLE_IMPORT_PLUGIN_H - -#if 0 -#include "tools/editor/editor_import_export.h" -#include "scene/resources/font.h" - -class EditorNode; -class EditorSampleImportDialog; - -class EditorSampleImportPlugin : public EditorImportPlugin { - - GDCLASS(EditorSampleImportPlugin,EditorImportPlugin); - - EditorSampleImportDialog *dialog; - void _compress_ima_adpcm(const Vector<float>& p_data,PoolVector<uint8_t>& dst_data); -public: - - static EditorSampleImportPlugin *singleton; - - virtual String get_name() const; - virtual String get_visible_name() const; - virtual void import_dialog(const String& p_from=""); - virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); - void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); - virtual void reimport_multiple_files(const Vector<String>& p_list); - virtual bool can_reimport_multiple_files() const; - - - EditorSampleImportPlugin(EditorNode* p_editor); -}; - -class EditorSampleExportPlugin : public EditorExportPlugin { - - GDCLASS( EditorSampleExportPlugin, EditorExportPlugin); - - -public: - - virtual Vector<uint8_t> custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform); - - EditorSampleExportPlugin(); -}; - -#endif // EDITOR_SAMPLE_IMPORT_PLUGIN_H -#endif diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp deleted file mode 100644 index 957072c20a..0000000000 --- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp +++ /dev/null @@ -1,2992 +0,0 @@ -/*************************************************************************/ -/* editor_scene_import_plugin.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 "editor_scene_import_plugin.h" -#if 0 -#include "global_config.h" -#include "tools/editor/editor_node.h" -#include "scene/resources/packed_scene.h" -#include "scene/resources/box_shape.h" -#include "os/file_access.h" -#include "scene/3d/path.h" -#include "scene/animation/animation_player.h" -#include "io/resource_saver.h" -#include "scene/3d/mesh_instance.h" -#include "scene/3d/navigation.h" -#include "scene/3d/room_instance.h" -#include "scene/3d/body_shape.h" -#include "scene/3d/physics_body.h" -#include "scene/3d/portal.h" -#include "scene/3d/vehicle_body.h" -#include "scene/resources/sphere_shape.h" -#include <scene/resources/box_shape.h> -#include <scene/resources/ray_shape.h> -#include <scene/resources/plane_shape.h> -#include "tools/editor/create_dialog.h" -#include "os/os.h" - - - - -EditorSceneImporter::EditorSceneImporter() { - - -} - -void EditorScenePostImport::_bind_methods() { - - BIND_VMETHOD( MethodInfo("post_import",PropertyInfo(Variant::OBJECT,"scene")) ); - -} - -Node *EditorScenePostImport::post_import(Node* p_scene) { - - if (get_script_instance()) - return get_script_instance()->call("post_import",p_scene); - - return p_scene; -} - -EditorScenePostImport::EditorScenePostImport() { - - -} - - -///////////////////////////// - - -class EditorImportAnimationOptions : public VBoxContainer { - - GDCLASS( EditorImportAnimationOptions, VBoxContainer ); - - - - TreeItem *fps; - TreeItem* optimize_linear_error; - TreeItem* optimize_angular_error; - TreeItem* optimize_max_angle; - - TreeItem *clips_base; - - TextEdit *filters; - Vector<TreeItem*> clips; - - Tree *flags; - Tree *clips_tree; - Tree *optimization_tree; - Vector<TreeItem*> items; - - - bool updating; - bool validating; - - - - void _changed(); - void _item_edited(); - void _button_action(Object *p_obj,int p_col,int p_id); - -protected: - static void _bind_methods(); - void _notification(int p_what); - -public: - - void set_flags(uint32_t p_flags); - uint32_t get_flags() const; - - void set_fps(int p_fps); - int get_fps() const; - - void set_optimize_linear_error(float p_error); - float get_optimize_linear_error() const; - - void set_optimize_angular_error(float p_error); - float get_optimize_angular_error() const; - - void set_optimize_max_angle(float p_error); - float get_optimize_max_angle() const; - - void setup_clips(const Array& p_clips); - Array get_clips() const; - - void set_filter(const String& p_filter); - String get_filter() const; - - EditorImportAnimationOptions(); - - -}; - -//////////////////////////// - -class EditorSceneImportDialog : public ConfirmationDialog { - - GDCLASS(EditorSceneImportDialog,ConfirmationDialog); - - - struct FlagInfo { - int value; - const char *category; - const char *text; - bool defval; - }; - - static const FlagInfo scene_flag_names[]; - - EditorImportTextureOptions *texture_options; - EditorImportAnimationOptions *animation_options; - - EditorSceneImportPlugin *plugin; - - EditorNode *editor; - - LineEdit *import_path; - LineEdit *save_path; - LineEdit *script_path; - Tree *import_options; - EditorFileDialog *file_select; - EditorFileDialog *script_select; - EditorDirDialog *save_select; - OptionButton *texture_action; - CreateDialog *root_type_choose; - LineEdit *root_node_name; - - ConfirmationDialog *confirm_open; - - ConfirmationDialog *confirm_import; - RichTextLabel *missing_files; - - Vector<TreeItem*> scene_flags; - - Map<Ref<Mesh>,Ref<Shape> > collision_map; - ConfirmationDialog *error_dialog; - - Button *root_type; - CheckBox *root_default; - - - void _root_default_pressed(); - void _root_type_pressed(); - void _set_root_type(); - - void _choose_file(const String& p_path); - void _choose_save_file(const String& p_path); - void _choose_script(const String& p_path); - void _browse(); - void _browse_target(); - void _browse_script(); - void _import(bool p_and_open=false); - void _import_confirm(); - - Ref<ResourceImportMetadata> wip_rimd; - Node *wip_import; - String wip_save_file; - bool wip_blocked; - bool wip_open; - - void _dialog_hid(); - void _open_and_import(); - - -protected: - - void _notification(int p_what); - static void _bind_methods(); -public: - - void setup_popup(const String& p_from,const String& p_to_path) { - _choose_file(p_from); - _choose_save_file(p_to_path); - } - - Error import(const String& p_from, const String& p_to, const String& p_preset); - void popup_import(const String& p_from); - EditorSceneImportDialog(EditorNode *p_editor,EditorSceneImportPlugin *p_plugin); -}; - -/////////////////////////////////// - - -static const char *anim_flag_names[]={ - "Detect Loop (-loop,-cycle)", - "Keep Value Tracks", - "Optimize", - "Force All Tracks in All Clips", - NULL -}; - -static const char *anim_flag_descript[]={ - "Set loop flag for animation names that\ncontain 'cycle' or 'loop' in the name.", - "When merging an existing aimation,\nkeep the user-created value-tracks.", - "Remove redundant keyframes in\n transform tacks.", - "Some exporters will rely on default pose for some bones.\nThis forces those bones to have at least one animation key.", - NULL -}; - - - -void EditorImportAnimationOptions::set_flags(uint32_t p_flags){ - - updating=true; - for(int i=0;i<items.size();i++) { - - items[i]->set_checked(0,p_flags&(1<<i)); - } - updating=false; - -} -uint32_t EditorImportAnimationOptions::get_flags() const{ - - uint32_t f=0; - for(int i=0;i<items.size();i++) { - - if (items[i]->is_checked(0)) - f|=(1<<i); - } - - return f; -} - - -void EditorImportAnimationOptions::_changed() { - - if (updating) - return; - emit_signal("changed"); -} - - -void EditorImportAnimationOptions::_button_action(Object *p_obj,int p_col,int p_id) { - - memdelete(p_obj); - -} - - -void EditorImportAnimationOptions::_item_edited() { - - if (validating) - return; - - if (clips.size()==0) - return; - validating=true; - print_line("edited"); - TreeItem *item = clips_tree->get_edited(); - if (item==clips[clips.size()-1]) { - //add new - print_line("islast"); - if (item->get_text(0).find("<")!=-1 || item->get_text(0).find(">")!=-1) { - validating=false; - return; //fuckit - } - - item->set_editable(1,true); - item->set_editable(2,true); - item->add_button(0,EditorNode::get_singleton()->get_gui_base()->get_icon("Del","EditorIcons")); - item->set_cell_mode(1,TreeItem::CELL_MODE_RANGE); - item->set_range_config(1,0,3600,0.01); - item->set_range(1,0); - item->set_editable(1,true); - item->set_cell_mode(2,TreeItem::CELL_MODE_RANGE); - item->set_range_config(2,0,3600,0.01); - item->set_range(2,0); - item->set_cell_mode(3,TreeItem::CELL_MODE_CHECK); - item->set_editable(3,true); - - TreeItem *newclip = clips_tree->create_item(clips_base); - newclip->set_text(0,"<new clip>"); - newclip->set_editable(0,true); - newclip->set_editable(1,false); - newclip->set_editable(2,false); - clips.push_back(newclip); - - - - } - - - //make name unique JUST IN CASE - String name = item->get_text(0); - name=name.replace("/","_").replace(":","_").strip_edges(); - if (name=="") - name=TTR("New Clip"); - - if (clips.size()>2) { - int index=1; - while(true) { - bool valid = true; - String try_name=name; - if (index>1) - try_name+=" "+itos(index); - - for(int i=0;i<clips.size()-1;i++) { - - if (clips[i]==item) - continue; - if (clips[i]->get_text(0)==try_name) { - index++; - valid=false; - break; - } - } - - if (valid) { - name=try_name; - break; - } - - } - } - - if (item->get_text(0)!=name) - item->set_text(0,name); - - validating=false; - -} - -void EditorImportAnimationOptions::_bind_methods() { - - ClassDB::bind_method("_changed",&EditorImportAnimationOptions::_changed); - ClassDB::bind_method("_item_edited",&EditorImportAnimationOptions::_item_edited); - ClassDB::bind_method("_button_action",&EditorImportAnimationOptions::_button_action); - //ClassDB::bind_method("_changedp",&EditorImportAnimationOptions::_changedp); - - ADD_SIGNAL(MethodInfo("changed")); -} - - -void EditorImportAnimationOptions::_notification(int p_what) { - - if (p_what==NOTIFICATION_ENTER_TREE) { - - flags->connect("item_edited",this,"_changed"); - clips_tree->connect("item_edited",this,"_item_edited"); - clips_tree->connect("button_pressed",this,"_button_action",varray(),CONNECT_DEFERRED); - //format->connect("item_selected",this,"_changedp"); - } -} - - -Array EditorImportAnimationOptions::get_clips() const { - - Array arr; - for(int i=0;i<clips.size()-1;i++) { - - arr.push_back(clips[i]->get_text(0)); - arr.push_back(clips[i]->get_range(1)); - arr.push_back(clips[i]->get_range(2)); - arr.push_back(clips[i]->is_checked(3)); - } - - return arr; -} - - -void EditorImportAnimationOptions::setup_clips(const Array& p_clips) { - - ERR_FAIL_COND(p_clips.size()%4!=0); - for(int i=0;i<clips.size();i++) { - - memdelete(clips[i]); - } - - - clips.clear(); - - for(int i=0;i<p_clips.size();i+=4) { - - TreeItem *clip = clips_tree->create_item(clips_base); - clip->set_text(0,p_clips[i]); - clip->add_button(0,EditorNode::get_singleton()->get_gui_base()->get_icon("Del","EditorIcons")); - clip->set_editable(0,true); - clip->set_cell_mode(1,TreeItem::CELL_MODE_RANGE); - clip->set_range_config(1,0,3600,0.01); - clip->set_range(1,p_clips[i+1]); - clip->set_editable(1,true); - clip->set_cell_mode(2,TreeItem::CELL_MODE_RANGE); - clip->set_range_config(2,0,3600,0.01); - clip->set_range(2,p_clips[i+2]); - clip->set_editable(2,true); - clip->set_cell_mode(3,TreeItem::CELL_MODE_CHECK); - clip->set_editable(3,true); - clip->set_checked(3,p_clips[i+3]); - clips.push_back(clip); - - } - - TreeItem *newclip = clips_tree->create_item(clips_base); - newclip->set_text(0,"<new clip>"); - newclip->set_editable(0,true); - newclip->set_editable(1,false); - newclip->set_editable(2,false); - newclip->set_editable(3,false); - clips.push_back(newclip); - -} - - -EditorImportAnimationOptions::EditorImportAnimationOptions() { - - - updating=false; - validating=false; - - TabContainer *tab= memnew(TabContainer); - add_margin_child(TTR("Animation Options"),tab,true); - - flags = memnew( Tree ); - flags->set_hide_root(true); - tab->add_child(flags); - flags->set_name(TTR("Flags")); - TreeItem *root = flags->create_item(); - - const char ** fname=anim_flag_names; - const char ** fdescr=anim_flag_descript; - - while( *fname ) { - - TreeItem*ti = flags->create_item(root); - ti->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); - ti->set_text(0,*fname); - ti->set_editable(0,true); - ti->set_tooltip(0,*fdescr); - items.push_back(ti); - fname++; - fdescr++; - } - - - TreeItem *fps_base = flags->create_item(root); - fps_base->set_text(0,TTR("Bake FPS:")); - fps_base->set_editable(0,false); - fps = flags->create_item(fps_base); - fps->set_cell_mode(0,TreeItem::CELL_MODE_RANGE); - fps->set_editable(0,true); - fps->set_range_config(0,1,120,1); - fps->set_range(0,15); - - optimization_tree = memnew( Tree ); - optimization_tree->set_columns(2); - tab->add_child(optimization_tree); - optimization_tree->set_name(TTR("Optimizer")); - optimization_tree->set_column_expand(0,true); - optimization_tree->set_column_expand(1,false); - optimization_tree->set_column_min_width(1,80); - optimization_tree->set_hide_root(true); - - - TreeItem *optimize_root = optimization_tree->create_item(); - - optimize_linear_error = optimization_tree->create_item(optimize_root); - optimize_linear_error->set_text(0,TTR("Max Linear Error")); - optimize_linear_error->set_cell_mode(1,TreeItem::CELL_MODE_RANGE); - optimize_linear_error->set_editable(1,true); - optimize_linear_error->set_range_config(1,0,1,0.001); - optimize_linear_error->set_range(1,0.05); - - optimize_angular_error = optimization_tree->create_item(optimize_root); - optimize_angular_error->set_text(0,TTR("Max Angular Error")); - optimize_angular_error->set_cell_mode(1,TreeItem::CELL_MODE_RANGE); - optimize_angular_error->set_editable(1,true); - optimize_angular_error->set_range_config(1,0,1,0.001); - optimize_angular_error->set_range(1,0.01); - - optimize_max_angle = optimization_tree->create_item(optimize_root); - optimize_max_angle->set_text(0,TTR("Max Angle")); - optimize_max_angle->set_cell_mode(1,TreeItem::CELL_MODE_RANGE); - optimize_max_angle->set_editable(1,true); - optimize_max_angle->set_range_config(1,0,360,0.001); - optimize_max_angle->set_range(1,int(180*0.125)); - - clips_tree = memnew( Tree ); - clips_tree->set_hide_root(true); - tab->add_child(clips_tree); - clips_tree->set_name(TTR("Clips")); - - clips_tree->set_columns(4); - clips_tree->set_column_expand(0,1); - clips_tree->set_column_expand(1,0); - clips_tree->set_column_expand(2,0); - clips_tree->set_column_expand(3,0); - clips_tree->set_column_min_width(1,60); - clips_tree->set_column_min_width(2,60); - clips_tree->set_column_min_width(3,40); - clips_tree->set_column_titles_visible(true); - clips_tree->set_column_title(0,TTR("Name")); - clips_tree->set_column_title(1,TTR("Start(s)")); - clips_tree->set_column_title(2,TTR("End(s)")); - clips_tree->set_column_title(3,TTR("Loop")); - clips_base =clips_tree->create_item(0); - - - setup_clips(Array()); - - - filters = memnew( TextEdit ); - tab->add_child(filters); - filters->set_name(TTR("Filters")); -} - - - -void EditorImportAnimationOptions::set_fps(int p_fps) { - - fps->set_range(0,p_fps); -} - -int EditorImportAnimationOptions::get_fps() const { - - return fps->get_range(0); -} - - -void EditorImportAnimationOptions::set_optimize_linear_error(float p_optimize_linear_error) { - - optimize_linear_error->set_range(1,p_optimize_linear_error); -} - -float EditorImportAnimationOptions::get_optimize_linear_error() const { - - return optimize_linear_error->get_range(1); -} - -void EditorImportAnimationOptions::set_optimize_angular_error(float p_optimize_angular_error) { - - optimize_angular_error->set_range(1,p_optimize_angular_error); -} - -float EditorImportAnimationOptions::get_optimize_angular_error() const { - - return optimize_angular_error->get_range(1); -} - -void EditorImportAnimationOptions::set_optimize_max_angle(float p_optimize_max_angle) { - - optimize_max_angle->set_range(1,p_optimize_max_angle); -} - -float EditorImportAnimationOptions::get_optimize_max_angle() const { - - return optimize_max_angle->get_range(1); -} - - -void EditorImportAnimationOptions::set_filter(const String& p_filter) { - - filters->set_text(p_filter); -} - -String EditorImportAnimationOptions::get_filter() const { - - return filters->get_text(); -} - - - - - -//////////////////////////////////////////////////////// - - - -void EditorSceneImportDialog::_choose_file(const String& p_path) { -#if 0 - StringName sn = EditorImportDB::get_singleton()->find_source_path(p_path); - if (sn!=StringName()) { - - EditorImportDB::ImportScene isc; - if (EditorImportDB::get_singleton()->get_scene(sn,isc)==OK) { - - save_path->set_text(String(sn).get_base_dir()); - texture_options->set_flags( isc.image_flags ); - texture_options->set_quality( isc.image_quality ); - texture_options->set_format( isc.image_format ); - animation_options->set_flags( isc.anim_flags ); - script_path->set_text( isc.import_script ); - uint32_t f = isc.flags; - for(int i=0;i<scene_flags.size();i++) { - - scene_flags[i]->set_checked(0,f&(1<<i)); - } - } - } else { -#endif - save_path->set_text(""); - root_node_name->set_text(""); - //save_path->set_text(p_path.get_file().basename()+".scn"); -#if 0 - } -#endif - - if (p_path!=String()) { - - String from_path = EditorFileSystem::get_singleton()->find_resource_from_source(EditorImportPlugin::validate_source_path(p_path)); - print_line("from path.."+from_path); - if (from_path!=String()) { - popup_import(from_path); - - } - } - - - import_path->set_text(p_path); - if (root_node_name->get_text().size()==0){ - root_node_name->set_text(import_path->get_text().get_file().get_basename()); - } - -} -void EditorSceneImportDialog::_choose_save_file(const String& p_path) { - - save_path->set_text(p_path); -} - -void EditorSceneImportDialog::_choose_script(const String& p_path) { - - String p = GlobalConfig::get_singleton()->localize_path(p_path); - if (!p.is_resource_file()) - p=GlobalConfig::get_singleton()->get_resource_path().path_to(p_path.get_base_dir())+p_path.get_file(); - script_path->set_text(p); - -} - - -void EditorSceneImportDialog::_open_and_import() { - - bool unsaved=EditorNode::has_unsaved_changes(); - - if (unsaved) { - - confirm_open->popup_centered_minsize(Size2(300,80)*EDSCALE); - } else { - _import(true); - } -} - -void EditorSceneImportDialog::_import(bool p_and_open) { - - wip_open=p_and_open; -//' ImportMonitorBlock imb; - - - if (import_path->get_text().strip_edges()=="") { - error_dialog->set_text(TTR("Source path is empty.")); - error_dialog->popup_centered_minsize(); - return; - } - - if (save_path->get_text().strip_edges()=="") { - error_dialog->set_text(TTR("Target path is empty.")); - error_dialog->popup_centered_minsize(); - return; - } - - if (!save_path->get_text().begins_with("res://")) { - error_dialog->set_text(TTR("Target path must be a complete resource path.")); - error_dialog->popup_centered_minsize(); - return; - } - - if (!DirAccess::exists(save_path->get_text())) { - error_dialog->set_text(TTR("Target path must exist.")); - error_dialog->popup_centered_minsize(); - return; - } - - String dst_path; - - if (texture_action->get_selected()==0) - dst_path=save_path->get_text();//.get_base_dir(); - else - dst_path=GlobalConfig::get_singleton()->get("import/shared_textures"); - - uint32_t flags=0; - - for(int i=0;i<scene_flags.size();i++) { - - if (scene_flags[i]->is_checked(0)) { - int md = scene_flags[i]->get_metadata(0); - flags|=md; - } - } - - - - - - if (script_path->get_text()!="") { - Ref<Script> scr = ResourceLoader::load(script_path->get_text()); - if (!scr.is_valid()) { - error_dialog->set_text(TTR("Couldn't load post-import script.")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - } - - Ref<EditorScenePostImport> pi = Ref<EditorScenePostImport>( memnew( EditorScenePostImport ) ); - pi->set_script(scr.get_ref_ptr()); - if (!pi->get_script_instance()) { - - error_dialog->set_text(TTR("Invalid/broken script for post-import.")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - } - - } - - - // Scenes should always be imported as binary format since vertex data is large and would take - // up a lot of space and time to load if imported as text format (GH-5778) - String save_file = save_path->get_text().plus_file(import_path->get_text().get_file().get_basename()+".scn"); - print_line("Saving to: "+save_file); - - - - - - Node *scene=NULL; - - - Ref<ResourceImportMetadata> rim = memnew( ResourceImportMetadata ); - - rim->add_source(EditorImportPlugin::validate_source_path(import_path->get_text())); - rim->set_option("flags",flags); - print_line("GET FLAGS: "+itos(texture_options->get_flags())); - rim->set_option("texture_flags",texture_options->get_flags()); - rim->set_option("texture_format",texture_options->get_format()); - rim->set_option("texture_quality",texture_options->get_quality()); - rim->set_option("animation_flags",animation_options->get_flags()); - rim->set_option("animation_bake_fps",animation_options->get_fps()); - rim->set_option("animation_optimizer_linear_error",animation_options->get_optimize_linear_error()); - rim->set_option("animation_optimizer_angular_error",animation_options->get_optimize_angular_error()); - rim->set_option("animation_optimizer_max_angle",animation_options->get_optimize_max_angle()); - rim->set_option("animation_filters",animation_options->get_filter()); - rim->set_option("animation_clips",animation_options->get_clips()); - rim->set_option("post_import_script",script_path->get_text()); - rim->set_option("reimport",true); - if (!root_default->is_pressed()) { - rim->set_option("root_type",root_type->get_text()); - } - if (root_node_name->get_text().size()==0) { - root_node_name->set_text(import_path->get_text().get_file().get_basename()); - } - rim->set_option("root_name",root_node_name->get_text()); - - List<String> missing; - Error err = plugin->import1(rim,&scene,&missing); - - if (err || !scene) { - - error_dialog->set_text(TTR("Error importing scene.")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - } - - if (missing.size()) { - - missing_files->clear(); - for(List<String>::Element *E=missing.front();E;E=E->next()) { - - missing_files->add_text(E->get()); - missing_files->add_newline(); - } - wip_import=scene; - wip_rimd=rim; - wip_save_file=save_file; - confirm_import->popup_centered_ratio(); - return; - - } else { - - err = plugin->import2(scene,save_file,rim); - - if (err) { - - error_dialog->set_text(TTR("Error importing scene.")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - } - if (wip_open) - EditorNode::get_singleton()->load_scene(save_file,false,false,false); - - } - - hide(); - - /* - editor->clear_scene(); - - Error err = EditorImport::import_scene(import_path->get_text(),save_file,dst_path,flags,texture_options->get_format(),compression,texture_options->get_flags(),texture_options->get_quality(),animation_options->get_flags(), &scene,pi); - - if (err) { - - error_dialog->set_text("Error importing scene."); - error_dialog->popup_centered(Size2(200,100)); - return; - } - - editor->save_import_export(); - if (scene) - editor->set_edited_scene(scene); - - hide(); - */ -}; - - -void EditorSceneImportDialog::_import_confirm() { - - wip_blocked=true; - print_line("import confirm!"); - Error err = plugin->import2(wip_import,wip_save_file,wip_rimd); - wip_blocked=false; - wip_import=NULL; - wip_rimd=Ref<ResourceImportMetadata>(); - confirm_import->hide(); - if (err) { - - wip_save_file=""; - error_dialog->set_text(TTR("Error importing scene.")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - } - - if (wip_open) - EditorNode::get_singleton()->load_scene(wip_save_file,false,false,false); - wip_open=false; - wip_save_file=""; - - hide(); - -} - - -void EditorSceneImportDialog::_browse() { - - file_select->popup_centered_ratio(); -} - -void EditorSceneImportDialog::_browse_target() { - - save_select->popup_centered_ratio(); - if (save_path->get_text()!="") - save_select->set_current_path(save_path->get_text()); - -} - -void EditorSceneImportDialog::_browse_script() { - - script_select->popup_centered_ratio(); - -} - -void EditorSceneImportDialog::popup_import(const String &p_from) { - - popup_centered(Size2(750,550)*EDSCALE); - if (p_from!="") { - Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from); - if (rimd.is_null()) - return; - - int flags = rimd->get_option("flags"); - - for(int i=0;i<scene_flags.size();i++) { - - int md = scene_flags[i]->get_metadata(0); - scene_flags[i]->set_checked(0,flags&md); - } - - texture_options->set_flags(rimd->get_option("texture_flags")); - texture_options->set_format(EditorTextureImportPlugin::ImageFormat(int(rimd->get_option("texture_format")))); - texture_options->set_quality(rimd->get_option("texture_quality")); - animation_options->set_flags(rimd->get_option("animation_flags")); - if (rimd->has_option("animation_clips")) - animation_options->setup_clips(rimd->get_option("animation_clips")); - if (rimd->has_option("animation_filters")) - animation_options->set_filter(rimd->get_option("animation_filters")); - if (rimd->has_option("animation_bake_fps")) - animation_options->set_fps(rimd->get_option("animation_bake_fps")); - if (rimd->has_option("animation_optimizer_linear_error")) - animation_options->set_optimize_linear_error(rimd->get_option("animation_optimizer_linear_error")); - if (rimd->has_option("animation_optimizer_angular_error")) - animation_options->set_optimize_angular_error(rimd->get_option("animation_optimizer_angular_error")); - if (rimd->has_option("animation_optimizer_max_angle")) - animation_options->set_optimize_max_angle(rimd->get_option("animation_optimizer_max_angle")); - - if (rimd->has_option("root_type")) { - root_default->set_pressed(false); - String type = rimd->get_option("root_type"); - root_type->set_text(type); - root_type->set_disabled(false); - - if (has_icon(type,"EditorIcons")) { - root_type->set_icon(get_icon(type,"EditorIcons")); - } else { - root_type->set_icon(get_icon("Object","EditorIcons")); - } - - } else { - root_default->set_pressed(true); - root_type->set_disabled(true); - } - if (rimd->has_option("root_name")) { - root_node_name->set_text(rimd->get_option("root_name")); - } else { - root_node_name->set_text(root_type->get_text()); // backward compatibility for 2.1 or before - } - script_path->set_text(rimd->get_option("post_import_script")); - - save_path->set_text(p_from.get_base_dir()); - import_path->set_text(EditorImportPlugin::expand_source_path(rimd->get_source_path(0))); - - } -} - - -void EditorSceneImportDialog::_notification(int p_what) { - - - if (p_what==NOTIFICATION_ENTER_TREE) { - - - List<String> extensions; - file_select->clear_filters(); - root_type->set_icon(get_icon("Spatial","EditorIcons")); - root_type->set_text("Spatial"); - root_type->set_disabled(true); - - for(int i=0;i<plugin->get_importers().size();i++) { - plugin->get_importers()[i]->get_extensions(&extensions); - } - - - for(int i=0;i<extensions.size();i++) { - - file_select->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); - } - - extensions.clear(); - - //EditorImport::get_import_extensions(&extensions) - /* ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions); - save_select->clear_filters(); - for(int i=0;i<extensions.size();i++) { - - save_select->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); - }*/ - - - } -} - -Error EditorSceneImportDialog::import(const String& p_from, const String& p_to, const String& p_preset) { - - import_path->set_text(p_from); - save_path->set_text(p_to); - script_path->set_text(p_preset); - - _import(); - - - - return OK; -} - -void EditorSceneImportDialog::_dialog_hid() { - - if (wip_blocked) - return; - print_line("DIALOGHID!"); - if (wip_import) { - memdelete(wip_import); - wip_import=NULL; - wip_save_file=""; - wip_rimd=Ref<ResourceImportMetadata>(); - } -} -void EditorSceneImportDialog::_root_default_pressed() { - - root_type->set_disabled(root_default->is_pressed()); -} - -void EditorSceneImportDialog::_root_type_pressed() { - - - root_type_choose->popup(false); -} - - -void EditorSceneImportDialog::_set_root_type() { - - String type = root_type_choose->get_selected_type(); - if (type==String()) - return; - root_type->set_text(type); - if (has_icon(type,"EditorIcons")) { - root_type->set_icon(get_icon(type,"EditorIcons")); - } else { - root_type->set_icon(get_icon("Object","EditorIcons")); - } -} - -void EditorSceneImportDialog::_bind_methods() { - - - ClassDB::bind_method("_choose_file",&EditorSceneImportDialog::_choose_file); - ClassDB::bind_method("_choose_save_file",&EditorSceneImportDialog::_choose_save_file); - ClassDB::bind_method("_choose_script",&EditorSceneImportDialog::_choose_script); - ClassDB::bind_method("_import",&EditorSceneImportDialog::_import,DEFVAL(false)); - ClassDB::bind_method("_browse",&EditorSceneImportDialog::_browse); - ClassDB::bind_method("_browse_target",&EditorSceneImportDialog::_browse_target); - ClassDB::bind_method("_browse_script",&EditorSceneImportDialog::_browse_script); - ClassDB::bind_method("_dialog_hid",&EditorSceneImportDialog::_dialog_hid); - ClassDB::bind_method("_import_confirm",&EditorSceneImportDialog::_import_confirm); - ClassDB::bind_method("_open_and_import",&EditorSceneImportDialog::_open_and_import); - ClassDB::bind_method("_root_default_pressed",&EditorSceneImportDialog::_root_default_pressed); - ClassDB::bind_method("_root_type_pressed",&EditorSceneImportDialog::_root_type_pressed); - ClassDB::bind_method("_set_root_type",&EditorSceneImportDialog::_set_root_type); - - - ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); -} - - - -const EditorSceneImportDialog::FlagInfo EditorSceneImportDialog::scene_flag_names[]={ - - {EditorSceneImportPlugin::SCENE_FLAG_REMOVE_NOIMP,("Actions"),"Remove Nodes (-noimp)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_IMPORT_ANIMATIONS,("Actions"),"Import Animations",true}, - {EditorSceneImportPlugin::SCENE_FLAG_COMPRESS_GEOMETRY,("Actions"),"Compress Geometry",false}, - {EditorSceneImportPlugin::SCENE_FLAG_GENERATE_TANGENT_ARRAYS,("Actions"),"Force Generation of Tangent Arrays",false}, - {EditorSceneImportPlugin::SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES,("Actions"),"SRGB->Linear Of Diffuse Textures",false}, - {EditorSceneImportPlugin::SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY,("Actions"),"Convert Normal Maps to XY",true}, - {EditorSceneImportPlugin::SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS,("Actions"),"Set Material Lightmap to UV2 if Tex2Array Exists",true}, - {EditorSceneImportPlugin::SCENE_FLAG_MERGE_KEEP_MATERIALS,("Merge"),"Keep Materials after first import (delete them for re-import).",true}, - {EditorSceneImportPlugin::SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS,("Merge"),"Keep user-added Animation tracks.",true}, - {EditorSceneImportPlugin::SCENE_FLAG_DETECT_ALPHA,("Materials"),"Set Alpha in Materials (-alpha)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_DETECT_VCOLOR,("Materials"),"Set Vert. Color in Materials (-vcol)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_COLLISIONS,("Create"),"Create Collisions and/or Rigid Bodies (-col,-colonly,-rigid)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_PORTALS,("Create"),"Create Portals (-portal)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_ROOMS,("Create"),"Create Rooms (-room)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_SIMPLIFY_ROOMS,("Create"),"Simplify Rooms",false}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_BILLBOARDS,("Create"),"Create Billboards (-bb)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_IMPOSTORS,("Create"),"Create Impostors (-imp:dist)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_LODS,("Create"),"Create LODs (-lod:dist)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_CARS,("Create"),"Create Vehicles (-vehicle)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_WHEELS,("Create"),"Create Vehicle Wheels (-wheel)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_NAVMESH,("Create"),"Create Navigation Meshes (-navmesh)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_DETECT_LIGHTMAP_LAYER,("Create"),"Detect LightMap Layer (-lm:<int>).",true}, - {-1,NULL,NULL,false} -}; - - -EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSceneImportPlugin *p_plugin) { - - - editor=p_editor; - plugin=p_plugin; - - set_title(TTR("Import 3D Scene")); - HBoxContainer *import_hb = memnew( HBoxContainer ); - add_child(import_hb); - //set_child_rect(import_hb); - - VBoxContainer *vbc = memnew( VBoxContainer ); - import_hb->add_child(vbc); - vbc->set_h_size_flags(SIZE_EXPAND_FILL); - - HBoxContainer *hbc = memnew( HBoxContainer ); - vbc->add_margin_child(TTR("Source Scene:"),hbc); - - import_path = memnew( LineEdit ); - import_path->set_h_size_flags(SIZE_EXPAND_FILL); - hbc->add_child(import_path); - - Button * import_choose = memnew( Button ); - import_choose->set_text(" .. "); - hbc->add_child(import_choose); - - import_choose->connect("pressed", this,"_browse"); - - hbc = memnew( HBoxContainer ); - vbc->add_margin_child(TTR("Target Path:"),hbc); - - save_path = memnew( LineEdit ); - save_path->set_h_size_flags(SIZE_EXPAND_FILL); - hbc->add_child(save_path); - - Button * save_choose = memnew( Button ); - save_choose->set_text(" .. "); - hbc->add_child(save_choose); - - save_choose->connect("pressed", this,"_browse_target"); - - texture_action = memnew( OptionButton ); - texture_action->add_item(TTR("Same as Target Scene")); - texture_action->add_item(TTR("Shared")); - texture_action->select(0); - vbc->add_margin_child(TTR("Target Texture Folder:"),texture_action); - - import_options = memnew( Tree ); - vbc->set_v_size_flags(SIZE_EXPAND_FILL); - vbc->add_margin_child(TTR("Options:"),import_options,true); - - file_select = memnew(EditorFileDialog); - file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - add_child(file_select); - - - file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); - - file_select->connect("file_selected", this,"_choose_file"); - - save_select = memnew(EditorDirDialog); - add_child(save_select); - - //save_select->set_mode(EditorFileDialog::MODE_SAVE_FILE); - save_select->connect("dir_selected", this,"_choose_save_file"); - - get_ok()->connect("pressed", this,"_import"); - get_ok()->set_text(TTR("Import")); - - TreeItem *root = import_options->create_item(NULL); - import_options->set_hide_root(true); - - const FlagInfo* fn=scene_flag_names; - - Map<String,TreeItem*> categories; - - while(fn->text) { - - String cat = fn->category; - TreeItem *parent; - if (!categories.has(cat)) { - parent = import_options->create_item(root); - parent->set_text(0,cat); - categories[cat]=parent; - } else { - parent=categories[cat]; - } - - TreeItem *opt = import_options->create_item(parent); - opt->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); - opt->set_checked(0,fn->defval); - opt->set_editable(0,true); - opt->set_text(0,fn->text); - opt->set_metadata(0,fn->value); - - scene_flags.push_back(opt); - fn++; - } - - hbc = memnew( HBoxContainer ); - vbc->add_margin_child(TTR("Post-Process Script:"),hbc); - - script_path = memnew( LineEdit ); - script_path->set_h_size_flags(SIZE_EXPAND_FILL); - hbc->add_child(script_path); - - Button * script_choose = memnew( Button ); - script_choose->set_text(" .. "); - hbc->add_child(script_choose); - - script_choose->connect("pressed", this,"_browse_script"); - - script_select = memnew(EditorFileDialog); - add_child(script_select); - for(int i=0;i<ScriptServer::get_language_count();i++) { - - ScriptLanguage *sl=ScriptServer::get_language(i); - String ext = sl->get_extension(); - if (ext=="") - continue; - script_select->add_filter("*."+ext+" ; "+sl->get_name()); - } - - - script_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); - - script_select->connect("file_selected", this,"_choose_script"); - - error_dialog = memnew ( ConfirmationDialog ); - add_child(error_dialog); - error_dialog->get_ok()->set_text(TTR("Accept")); - //error_dialog->get_cancel()->hide(); - - - HBoxContainer *custom_root_hb = memnew( HBoxContainer ); - vbc->add_margin_child(TTR("Custom Root Node Type:"),custom_root_hb); - root_type = memnew(Button); - root_type->set_h_size_flags(SIZE_EXPAND_FILL); - root_type->set_text_align(Button::ALIGN_LEFT); - root_type->connect("pressed",this,"_root_type_pressed"); - custom_root_hb->add_child(root_type); - - root_default = memnew(CheckBox); - root_default->set_text(TTR("Auto")); - root_default->set_pressed(true); - root_default->connect("pressed",this,"_root_default_pressed"); - custom_root_hb->add_child(root_default); - - root_node_name = memnew( LineEdit ); - root_node_name->set_h_size_flags(SIZE_EXPAND_FILL); - vbc->add_margin_child(TTR("Root Node Name:"),root_node_name); - /* - this_import = memnew( OptionButton ); - this_import->add_item("Overwrite Existing Scene"); - this_import->add_item("Overwrite Existing, Keep Materials"); - this_import->add_item("Keep Existing, Merge with New"); - this_import->add_item("Keep Existing, Ignore New"); - vbc->add_margin_child("This Time:",this_import); - - next_import = memnew( OptionButton ); - next_import->add_item("Overwrite Existing Scene"); - next_import->add_item("Overwrite Existing, Keep Materials"); - next_import->add_item("Keep Existing, Merge with New"); - next_import->add_item("Keep Existing, Ignore New"); - vbc->add_margin_child("Next Time:",next_import); -*/ - set_hide_on_ok(false); - - GLOBAL_DEF("import/shared_textures","res://"); - GlobalConfig::get_singleton()->set_custom_property_info("import/shared_textures",PropertyInfo(Variant::STRING,"import/shared_textures",PROPERTY_HINT_DIR)); - - import_hb->add_constant_override("separation",30); - - - VBoxContainer *ovb = memnew( VBoxContainer); - ovb->set_h_size_flags(SIZE_EXPAND_FILL); - import_hb->add_child(ovb); - - texture_options = memnew( EditorImportTextureOptions ); - ovb->add_child(texture_options); - texture_options->set_v_size_flags(SIZE_EXPAND_FILL); - //animation_options->set_flags(EditorImport:: - texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM); - texture_options->set_flags( EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA | EditorTextureImportPlugin::IMAGE_FLAG_REPEAT | EditorTextureImportPlugin::IMAGE_FLAG_FILTER ); - - - animation_options = memnew( EditorImportAnimationOptions ); - ovb->add_child(animation_options); - animation_options->set_v_size_flags(SIZE_EXPAND_FILL); - animation_options->set_flags(EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP|EditorSceneAnimationImportPlugin::ANIMATION_KEEP_VALUE_TRACKS|EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE|EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS); - - - confirm_import = memnew( ConfirmationDialog ); - add_child(confirm_import); - VBoxContainer *cvb = memnew( VBoxContainer ); - confirm_import->add_child(cvb); - //confirm_import->set_child_rect(cvb); - - PanelContainer *pc = memnew( PanelContainer ); - pc->add_style_override("panel",get_stylebox("normal","TextEdit")); - //ec->add_child(pc); - missing_files = memnew( RichTextLabel ); - cvb->add_margin_child(TTR("The Following Files are Missing:"),pc,true); - pc->add_child(missing_files); - confirm_import->get_ok()->set_text(TTR("Import Anyway")); - confirm_import->get_cancel()->set_text(TTR("Cancel")); - confirm_import->connect("popup_hide",this,"_dialog_hid"); - confirm_import->connect("confirmed",this,"_import_confirm"); - confirm_import->set_hide_on_ok(false); - - add_button(TTR("Import & Open"),!OS::get_singleton()->get_swap_ok_cancel())->connect("pressed",this,"_open_and_import"); - - confirm_open = memnew( ConfirmationDialog ); - add_child(confirm_open); - confirm_open->set_text(TTR("Edited scene has not been saved, open imported scene anyway?")); - confirm_open->connect("confirmed",this,"_import",varray(true)); - - - wip_import=NULL; - wip_blocked=false; - wip_open=false; - //texture_options->set_format(EditorImport::IMAGE_FORMAT_C); - - root_type_choose = memnew( CreateDialog ); - add_child(root_type_choose); - root_type_choose->set_base_type("Node"); - root_type_choose->connect("create",this,"_set_root_type"); -} - - - -//////////////////////////////// - - - -String EditorSceneImportPlugin::get_name() const { - - return "scene_3d"; -} - -String EditorSceneImportPlugin::get_visible_name() const{ - - return TTR("Scene"); -} - -void EditorSceneImportPlugin::import_dialog(const String& p_from){ - - dialog->popup_import(p_from); -} - - -////////////////////////// - - -static bool _teststr(const String& p_what,const String& p_str) { - - if (p_what.findn("$"+p_str)!=-1) //blender and other stuff - return true; - if (p_what.to_lower().ends_with("-"+p_str)) //collada only supports "_" and "-" besides letters - return true; - if (p_what.to_lower().ends_with("_"+p_str)) //collada only supports "_" and "-" besides letters - return true; - return false; -} - -static String _fixstr(const String& p_what,const String& p_str) { - - if (p_what.findn("$"+p_str)!=-1) //blender and other stuff - return p_what.replace("$"+p_str,""); - if (p_what.to_lower().ends_with("-"+p_str)) //collada only supports "_" and "-" besides letters - return p_what.substr(0,p_what.length()-(p_str.length()+1)); - if (p_what.to_lower().ends_with("_"+p_str)) //collada only supports "_" and "-" besides letters - return p_what.substr(0,p_what.length()-(p_str.length()+1)); - return p_what; -} - - - -void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<ImageTexture>, TextureRole> &image_map,int p_flags) { - - - switch(p_var.get_type()) { - - case Variant::OBJECT: { - - Ref<Resource> res = p_var; - if (res.is_valid()) { - - if (res->is_class("Texture") && !image_map.has(res)) { - - image_map.insert(res,TEXTURE_ROLE_DEFAULT); - - - } else { - - - List<PropertyInfo> pl; - res->get_property_list(&pl); - for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { - - if (E->get().type==Variant::OBJECT || E->get().type==Variant::ARRAY || E->get().type==Variant::DICTIONARY) { - if (E->get().type==Variant::OBJECT && res->cast_to<FixedSpatialMaterial>() && (E->get().name=="textures/diffuse" || E->get().name=="textures/detail" || E->get().name=="textures/emission")) { - - Ref<ImageTexture> tex =res->get(E->get().name); - if (tex.is_valid()) { - - image_map.insert(tex,TEXTURE_ROLE_DIFFUSE); - } - - } else if (E->get().type==Variant::OBJECT && res->cast_to<FixedSpatialMaterial>() && (E->get().name=="textures/normal")) { - - Ref<ImageTexture> tex =res->get(E->get().name); - if (tex.is_valid()) { - - image_map.insert(tex,TEXTURE_ROLE_NORMALMAP); - /* - if (p_flags&SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY) - res->cast_to<FixedSpatialMaterial>()->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_XY_NORMALMAP,true); - */ - } - - - } else { - _find_resources(res->get(E->get().name),image_map,p_flags); - } - } - } - - } - } - - } break; - case Variant::DICTIONARY: { - - Dictionary d= p_var; - - List<Variant> keys; - d.get_key_list(&keys); - - for(List<Variant>::Element *E=keys.front();E;E=E->next()) { - - - _find_resources(E->get(),image_map,p_flags); - _find_resources(d[E->get()],image_map,p_flags); - - } - - - } break; - case Variant::ARRAY: { - - Array a = p_var; - for(int i=0;i<a.size();i++) { - - _find_resources(a[i],image_map,p_flags); - } - - } break; - default: {} - - } - -} - - -Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,TextureRole >& image_map) { - - // children first.. - for(int i=0;i<p_node->get_child_count();i++) { - - - Node *r = _fix_node(p_node->get_child(i),p_root,collision_map,p_flags,image_map); - if (!r) { - print_line("was erased.."); - i--; //was erased - } - } - - String name = p_node->get_name(); - - bool isroot = p_node==p_root; - - - if (!isroot && p_flags&SCENE_FLAG_REMOVE_NOIMP && _teststr(name,"noimp")) { - - memdelete(p_node); - return NULL; - } - - { - - List<PropertyInfo> pl; - p_node->get_property_list(&pl); - for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { - - if (E->get().type==Variant::OBJECT || E->get().type==Variant::ARRAY || E->get().type==Variant::DICTIONARY) { - _find_resources(p_node->get(E->get().name),image_map,p_flags); - } - } - - } - - - - - if (p_flags&SCENE_FLAG_CREATE_BILLBOARDS && p_node->cast_to<MeshInstance>()) { - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - bool bb=false; - - if ((_teststr(name,"bb"))) { - bb=true; - } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"bb"))) { - bb=true; - - } - - if (bb) { - mi->set_flag(GeometryInstance::FLAG_BILLBOARD,true); - if (mi->get_mesh().is_valid()) { - - Ref<Mesh> m = mi->get_mesh(); - for(int i=0;i<m->get_surface_count();i++) { - - Ref<FixedSpatialMaterial> fm = m->surface_get_material(i); - if (fm.is_valid()) { - //fm->set_flag(Material::FLAG_UNSHADED,true); - //fm->set_flag(Material::FLAG_DOUBLE_SIDED,true); - //fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); - //fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); - } - } - } - } - } - - - if (p_flags&(SCENE_FLAG_DETECT_ALPHA|SCENE_FLAG_DETECT_VCOLOR|SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS) && p_node->cast_to<MeshInstance>()) { - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - Ref<Mesh> m = mi->get_mesh(); - - if (m.is_valid()) { - - for(int i=0;i<m->get_surface_count();i++) { - - Ref<FixedSpatialMaterial> mat = m->surface_get_material(i); - if (!mat.is_valid()) - continue; - - if (p_flags&SCENE_FLAG_DETECT_ALPHA && _teststr(mat->get_name(),"alpha")) { - - //mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); - //mat->set_name(_fixstr(mat->get_name(),"alpha")); - } - if (p_flags&SCENE_FLAG_DETECT_VCOLOR && _teststr(mat->get_name(),"vcol")) { - - //mat->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY,true); - //mat->set_name(_fixstr(mat->get_name(),"vcol")); - } - - if (p_flags&SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS && m->surface_get_format(i)&Mesh::ARRAY_FORMAT_TEX_UV2) { - //mat->set_flag(Material::FLAG_LIGHTMAP_ON_UV2,true); - } - - } - } - } - - if (p_flags&SCENE_FLAG_REMOVE_NOIMP && p_node->cast_to<AnimationPlayer>()) { - //remove animations referencing non-importable nodes - AnimationPlayer *ap = p_node->cast_to<AnimationPlayer>(); - - List<StringName> anims; - ap->get_animation_list(&anims); - for(List<StringName>::Element *E=anims.front();E;E=E->next()) { - - Ref<Animation> anim=ap->get_animation(E->get()); - ERR_CONTINUE(anim.is_null()); - for(int i=0;i<anim->get_track_count();i++) { - NodePath path = anim->track_get_path(i); - - for(int j=0;j<path.get_name_count();j++) { - String node = path.get_name(j); - if (_teststr(node,"noimp")) { - anim->remove_track(i); - i--; - break; - } - } - } - - } - } - - - if (p_flags&SCENE_FLAG_CREATE_IMPOSTORS && p_node->cast_to<MeshInstance>()) { - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - String str; - - if ((_teststr(name,"imp"))) { - str=name; - } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"imp"))) { - str=mi->get_mesh()->get_name(); - - } - - - if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) { - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>(); - String d=str.substr(str.find("imp")+3,str.length()); - if (d!="") { - if ((d[0]<'0' || d[0]>'9')) - d=d.substr(1,d.length()); - if (d.length() && d[0]>='0' && d[0]<='9') { - float dist = d.to_double(); - mi->set_flag(GeometryInstance::FLAG_BILLBOARD,true); - mi->set_flag(GeometryInstance::FLAG_BILLBOARD_FIX_Y,true); - //mi->set_draw_range_begin(dist); - //mi->set_draw_range_end(100000); - - //mip->set_draw_range_begin(0); - //mip->set_draw_range_end(dist); - - if (mi->get_mesh().is_valid()) { - - Ref<Mesh> m = mi->get_mesh(); - for(int i=0;i<m->get_surface_count();i++) { - - Ref<FixedSpatialMaterial> fm = m->surface_get_material(i); - if (fm.is_valid()) { - //fm->set_flag(Material::FLAG_UNSHADED,true); - //fm->set_flag(Material::FLAG_DOUBLE_SIDED,true); - //fm->set_depth_draw_mode(Material::DEPTH_DRAW_NEVER); - //fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); - } - } - } - } - } - } - } - - if (p_flags&SCENE_FLAG_CREATE_LODS && p_node->cast_to<MeshInstance>()) { - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - String str; - - if ((_teststr(name,"lod"))) { - str=name; - } else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"lod"))) { - str=mi->get_mesh()->get_name(); - - } - - - if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) { - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>(); - String d=str.substr(str.find("lod")+3,str.length()); - if (d!="") { - if ((d[0]<'0' || d[0]>'9')) - d=d.substr(1,d.length()); - if (d.length() && d[0]>='0' && d[0]<='9') { - float dist = d.to_double(); - /// mi->set_draw_range_begin(dist); - // mi->set_draw_range_end(100000); - - // mip->set_draw_range_begin(0); - // mip->set_draw_range_end(dist); - - /*if (mi->get_mesh().is_valid()) { - - Ref<Mesh> m = mi->get_mesh(); - for(int i=0;i<m->get_surface_count();i++) { - - Ref<FixedSpatialMaterial> fm = m->surface_get_material(i); - if (fm.is_valid()) { - fm->set_flag(Material::FLAG_UNSHADED,true); - fm->set_flag(Material::FLAG_DOUBLE_SIDED,true); - fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true); - fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); - } - } - }*/ - } - } - } - } - - - if (p_flags&SCENE_FLAG_DETECT_LIGHTMAP_LAYER && _teststr(name,"lm") && p_node->cast_to<MeshInstance>()) { - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - String str=name; - int layer = str.substr(str.find("lm")+3,str.length()).to_int(); - //mi->set_baked_light_texture_id(layer); - } - - if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(name,"colonly")) { - - if (isroot) - return p_node; - - if (p_node->cast_to<MeshInstance>()) { - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - Node * col = mi->create_trimesh_collision_node(); - ERR_FAIL_COND_V(!col,NULL); - - col->set_name(_fixstr(name,"colonly")); - col->cast_to<Spatial>()->set_transform(mi->get_transform()); - p_node->replace_by(col); - memdelete(p_node); - p_node=col; - - StaticBody *sb = col->cast_to<StaticBody>(); - CollisionShape *colshape = memnew( CollisionShape); - colshape->set_shape(sb->get_shape(0)); - colshape->set_name("shape"); - sb->add_child(colshape); - colshape->set_owner(p_node->get_owner()); - } else if (p_node->has_meta("empty_draw_type")) { - String empty_draw_type = String(p_node->get_meta("empty_draw_type")); - print_line(empty_draw_type); - StaticBody *sb = memnew( StaticBody); - sb->set_name(_fixstr(name,"colonly")); - sb->cast_to<Spatial>()->set_transform(p_node->cast_to<Spatial>()->get_transform()); - p_node->replace_by(sb); - memdelete(p_node); - CollisionShape *colshape = memnew( CollisionShape); - if (empty_draw_type == "CUBE") { - BoxShape *boxShape = memnew( BoxShape); - boxShape->set_extents(Vector3(1, 1, 1)); - colshape->set_shape(boxShape); - colshape->set_name("BoxShape"); - } else if (empty_draw_type == "SINGLE_ARROW") { - RayShape *rayShape = memnew( RayShape); - rayShape->set_length(1); - colshape->set_shape(rayShape); - colshape->set_name("RayShape"); - sb->cast_to<Spatial>()->rotate_x(Math_PI / 2); - } else if (empty_draw_type == "IMAGE") { - PlaneShape *planeShape = memnew( PlaneShape); - colshape->set_shape(planeShape); - colshape->set_name("PlaneShape"); - } else { - SphereShape *sphereShape = memnew( SphereShape); - sphereShape->set_radius(1); - colshape->set_shape(sphereShape); - colshape->set_name("SphereShape"); - } - sb->add_child(colshape); - colshape->set_owner(sb->get_owner()); - } - - } else if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(name,"rigid") && p_node->cast_to<MeshInstance>()) { - - if (isroot) - return p_node; - - // get mesh instance and bounding box - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - Rect3 aabb = mi->get_aabb(); - - // create a new rigid body collision node - RigidBody * rigid_body = memnew( RigidBody ); - Node * col = rigid_body; - ERR_FAIL_COND_V(!col,NULL); - - // remove node name postfix - col->set_name(_fixstr(name,"rigid")); - // get mesh instance xform matrix to the rigid body collision node - col->cast_to<Spatial>()->set_transform(mi->get_transform()); - // save original node by duplicating it into a new instance and correcting the name - Node * mesh = p_node->duplicate(); - mesh->set_name(_fixstr(name,"rigid")); - // reset the xform matrix of the duplicated node so it can inherit parent node xform - mesh->cast_to<Spatial>()->set_transform(Transform(Basis())); - // reparent the new mesh node to the rigid body collision node - p_node->add_child(mesh); - mesh->set_owner(p_node->get_owner()); - // replace the original node with the rigid body collision node - p_node->replace_by(col); - memdelete(p_node); - p_node=col; - - // create an alias for the rigid body collision node - RigidBody *rb = col->cast_to<RigidBody>(); - // create a new Box collision shape and set the right extents - Ref<BoxShape> shape = memnew( BoxShape ); - shape->set_extents(aabb.get_size() * 0.5); - CollisionShape *colshape = memnew( CollisionShape); - colshape->set_name("shape"); - colshape->set_shape(shape); - // reparent the new collision shape to the rigid body collision node - rb->add_child(colshape); - colshape->set_owner(p_node->get_owner()); - - } else if (p_flags&SCENE_FLAG_CREATE_COLLISIONS &&_teststr(name,"col") && p_node->cast_to<MeshInstance>()) { - - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - mi->set_name(_fixstr(name,"col")); - Node *col= mi->create_trimesh_collision_node(); - ERR_FAIL_COND_V(!col,NULL); - - col->set_name("col"); - p_node->add_child(col); - - StaticBody *sb=col->cast_to<StaticBody>(); - CollisionShape *colshape = memnew( CollisionShape); - colshape->set_shape(sb->get_shape(0)); - colshape->set_name("shape"); - col->add_child(colshape); - colshape->set_owner(p_node->get_owner()); - sb->set_owner(p_node->get_owner()); - - } else if (p_flags&SCENE_FLAG_CREATE_NAVMESH &&_teststr(name,"navmesh") && p_node->cast_to<MeshInstance>()) { - - if (isroot) - return p_node; - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - Ref<Mesh> mesh=mi->get_mesh(); - ERR_FAIL_COND_V(mesh.is_null(),NULL); - NavigationMeshInstance *nmi = memnew( NavigationMeshInstance ); - - - nmi->set_name(_fixstr(name,"navmesh")); - Ref<NavigationMesh> nmesh = memnew( NavigationMesh); - nmesh->create_from_mesh(mesh); - nmi->set_navigation_mesh(nmesh); - nmi->cast_to<Spatial>()->set_transform(mi->get_transform()); - p_node->replace_by(nmi); - memdelete(p_node); - p_node=nmi; - } else if (p_flags&SCENE_FLAG_CREATE_CARS &&_teststr(name,"vehicle")) { - - if (isroot) - return p_node; - - Node *owner = p_node->get_owner(); - Spatial *s = p_node->cast_to<Spatial>(); - VehicleBody *bv = memnew( VehicleBody ); - String n = _fixstr(p_node->get_name(),"vehicle"); - bv->set_name(n); - p_node->replace_by(bv); - p_node->set_name(n); - bv->add_child(p_node); - bv->set_owner(owner); - p_node->set_owner(owner); - bv->set_transform(s->get_transform()); - s->set_transform(Transform()); - - p_node=bv; - - - } else if (p_flags&SCENE_FLAG_CREATE_CARS &&_teststr(name,"wheel")) { - - if (isroot) - return p_node; - - Node *owner = p_node->get_owner(); - Spatial *s = p_node->cast_to<Spatial>(); - VehicleWheel *bv = memnew( VehicleWheel ); - String n = _fixstr(p_node->get_name(),"wheel"); - bv->set_name(n); - p_node->replace_by(bv); - p_node->set_name(n); - bv->add_child(p_node); - bv->set_owner(owner); - p_node->set_owner(owner); - bv->set_transform(s->get_transform()); - s->set_transform(Transform()); - - p_node=bv; - - } else if (p_flags&SCENE_FLAG_CREATE_ROOMS && _teststr(name,"room") && p_node->cast_to<MeshInstance>()) { - - - if (isroot) - return p_node; - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - PoolVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID); - - - BSP_Tree bsptree(faces); - - Ref<RoomBounds> area = memnew( RoomBounds ); - //area->set_bounds(faces); - //area->set_geometry_hint(faces); - - - Room * room = memnew( Room ); - room->set_name(_fixstr(name,"room")); - room->set_transform(mi->get_transform()); - room->set_room(area); - - p_node->replace_by(room); - memdelete(p_node); - p_node=room; - - } else if (p_flags&SCENE_FLAG_CREATE_ROOMS &&_teststr(name,"room")) { - - if (isroot) - return p_node; - - Spatial *dummy = p_node->cast_to<Spatial>(); - ERR_FAIL_COND_V(!dummy,NULL); - - Room * room = memnew( Room ); - room->set_name(_fixstr(name,"room")); - room->set_transform(dummy->get_transform()); - - p_node->replace_by(room); - memdelete(p_node); - p_node=room; - - //room->compute_room_from_subtree(); - - } else if (p_flags&SCENE_FLAG_CREATE_PORTALS &&_teststr(name,"portal") && p_node->cast_to<MeshInstance>()) { - - if (isroot) - return p_node; - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - PoolVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID); - - ERR_FAIL_COND_V(faces.size()==0,NULL); - //step 1 compute the plane - Set<Vector3> points; - Plane plane; - - Vector3 center; - - for(int i=0;i<faces.size();i++) { - - Face3 f = faces.get(i); - Plane p = f.get_plane(); - plane.normal+=p.normal; - plane.d+=p.d; - - for(int i=0;i<3;i++) { - - Vector3 v = f.vertex[i].snapped(0.01); - if (!points.has(v)) { - points.insert(v); - center+=v; - } - } - } - - plane.normal.normalize(); - plane.d/=faces.size(); - center/=points.size(); - - //step 2, create points - - Transform t; - t.basis.from_z(plane.normal); - t.basis.transpose(); - t.origin=center; - - Vector<Point2> portal_points; - - for(Set<Vector3>::Element *E=points.front();E;E=E->next()) { - - Vector3 local = t.xform_inv(E->get()); - portal_points.push_back(Point2(local.x,local.y)); - } - // step 3 bubbly sort points - - int swaps=0; - - do { - swaps=0; - - for(int i=0;i<portal_points.size()-1;i++) { - - float a = portal_points[i].angle(); - float b = portal_points[i+1].angle(); - - if (a>b) { - SWAP( portal_points[i], portal_points[i+1] ); - swaps++; - } - - } - - } while(swaps); - - - Portal *portal = memnew( Portal ); - - portal->set_shape(portal_points); - portal->set_transform( mi->get_transform() * t); - - p_node->replace_by(portal); - memdelete(p_node); - p_node=portal; - - } else if (p_node->cast_to<MeshInstance>()) { - - //last attempt, maybe collision insde the mesh data - - MeshInstance *mi = p_node->cast_to<MeshInstance>(); - - Ref<Mesh> mesh = mi->get_mesh(); - if (!mesh.is_null()) { - - if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(mesh->get_name(),"col")) { - - mesh->set_name( _fixstr(mesh->get_name(),"col") ); - Ref<Shape> shape; - - if (collision_map.has(mesh)) { - shape = collision_map[mesh]; - - } else { - - shape = mesh->create_trimesh_shape(); - if (!shape.is_null()) - collision_map[mesh]=shape; - - - } - - if (!shape.is_null()) { -#if 0 - StaticBody* static_body = memnew( StaticBody ); - ERR_FAIL_COND_V(!static_body,NULL); - static_body->set_name( String(mesh->get_name()) + "_col" ); - shape->set_name(static_body->get_name()); - static_body->add_shape(shape); - - mi->add_child(static_body); - if (mi->get_owner()) - static_body->set_owner( mi->get_owner() ); -#endif - } - - } - - for(int i=0;i<mesh->get_surface_count();i++) { - - Ref<FixedSpatialMaterial> fm = mesh->surface_get_material(i); - if (fm.is_valid()) { - String name = fm->get_name(); - /* if (_teststr(name,"alpha")) { - fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA,true); - name=_fixstr(name,"alpha"); - } - - if (_teststr(name,"vcol")) { - fm->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY,true); - name=_fixstr(name,"vcol"); - }*/ - fm->set_name(name); - } - } - - } - - } - - - return p_node; -} - - - - -#if 0 - -Error EditorImport::import_scene(const String& p_path,const String& p_dest_path,const String& p_resource_path,uint32_t p_flags,ImageFormat p_image_format,ImageCompression p_image_compression,uint32_t p_image_flags,float p_quality,uint32_t animation_flags,Node **r_scene,Ref<EditorPostImport> p_post_import) { - - -} -#endif - -void EditorSceneImportPlugin::_tag_import_paths(Node *p_scene,Node *p_node) { - - if (p_scene!=p_node && p_node->get_owner()!=p_scene) - return; - - NodePath path = p_scene->get_path_to(p_node); - p_node->set_import_path( path ); - - Spatial *snode=p_node->cast_to<Spatial>(); - - if (snode) { - - snode->set_import_transform(snode->get_transform()); - } - - for(int i=0;i<p_node->get_child_count();i++) { - _tag_import_paths(p_scene,p_node->get_child(i)); - } - -} - -Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from,Node**r_node,List<String> *r_missing) { - - Ref<ResourceImportMetadata> from=p_from; - - ERR_FAIL_COND_V(from->get_source_count()!=1,ERR_INVALID_PARAMETER); - - String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0)); - - Ref<EditorSceneImporter> importer; - String ext=src_path.get_extension().to_lower(); - - - EditorProgress progress("import",TTR("Import Scene"),104); - progress.step(TTR("Importing Scene.."),0); - - for(int i=0;i<importers.size();i++) { - - List<String> extensions; - importers[i]->get_extensions(&extensions); - - for(List<String>::Element *E=extensions.front();E;E=E->next()) { - - if (E->get().to_lower()==ext) { - - importer = importers[i]; - break; - } - } - - if (importer.is_valid()) - break; - } - - ERR_FAIL_COND_V(!importer.is_valid(),ERR_FILE_UNRECOGNIZED); - - int animation_flags=p_from->get_option("animation_flags"); - int scene_flags = from->get_option("flags"); - int fps = 24; - if (from->has_option("animation_bake_fps")) - fps=from->get_option("animation_bake_fps"); - - - Array clips; - if (from->has_option("animation_clips")) - clips=from->get_option("animation_clips"); - - uint32_t import_flags=0; - if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP) - import_flags|=EditorSceneImporter::IMPORT_ANIMATION_DETECT_LOOP; - if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_KEEP_VALUE_TRACKS) - import_flags |= EditorSceneImporter::IMPORT_ANIMATION_KEEP_VALUE_TRACKS; - if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE) - import_flags|=EditorSceneImporter::IMPORT_ANIMATION_OPTIMIZE; - if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS) - import_flags|=EditorSceneImporter::IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS; - if (scene_flags&SCENE_FLAG_IMPORT_ANIMATIONS) - import_flags|=EditorSceneImporter::IMPORT_ANIMATION; - /* - if (scene_flags&SCENE_FLAG_FAIL_ON_MISSING_IMAGES) - import_flags|=EditorSceneImporter::IMPORT_FAIL_ON_MISSING_DEPENDENCIES; - */ - if (scene_flags&SCENE_FLAG_GENERATE_TANGENT_ARRAYS) - import_flags|=EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS; - - - - - - Error err=OK; - Node *scene = importer->import_scene(src_path,import_flags,fps,r_missing,&err); - if (!scene || err!=OK) { - return err; - } - - if (from->has_option("root_type")) { - String type = from->get_option("root_type"); - Object *base = ClassDB::instance(type); - Node *base_node = NULL; - if (base) - base_node=base->cast_to<Node>(); - - if (base_node) { - - scene->replace_by(base_node); - memdelete(scene); - scene=base_node; - } - } - - scene->set_name(from->get_option("root_name")); - _tag_import_paths(scene,scene); - - *r_node=scene; - return OK; -} - - -void EditorSceneImportPlugin::_create_clips(Node *scene, const Array& p_clips,bool p_bake_all) { - - if (!scene->has_node(String("AnimationPlayer"))) - return; - - Node* n = scene->get_node(String("AnimationPlayer")); - ERR_FAIL_COND(!n); - AnimationPlayer *anim = n->cast_to<AnimationPlayer>(); - ERR_FAIL_COND(!anim); - - if (!anim->has_animation("default")) - return; - - - Ref<Animation> default_anim = anim->get_animation("default"); - - for(int i=0;i<p_clips.size();i+=4) { - - String name = p_clips[i]; - float from=p_clips[i+1]; - float to=p_clips[i+2]; - bool loop=p_clips[i+3]; - if (from>=to) - continue; - - Ref<Animation> new_anim = memnew( Animation ); - - for(int j=0;j<default_anim->get_track_count();j++) { - - - List<float> keys; - int kc = default_anim->track_get_key_count(j); - int dtrack=-1; - for(int k=0;k<kc;k++) { - - float kt = default_anim->track_get_key_time(j,k); - if (kt>=from && kt<to) { - - //found a key within range, so create track - if (dtrack==-1) { - new_anim->add_track(default_anim->track_get_type(j)); - dtrack = new_anim->get_track_count()-1; - new_anim->track_set_path(dtrack,default_anim->track_get_path(j)); - - if (kt>(from+0.01) && k>0) { - - if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { - Quat q; - Vector3 p; - Vector3 s; - default_anim->transform_track_interpolate(j,from,&p,&q,&s); - new_anim->transform_track_insert_key(dtrack,0,p,q,s); - } - } - - } - - if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { - Quat q; - Vector3 p; - Vector3 s; - default_anim->transform_track_get_key(j,k,&p,&q,&s); - new_anim->transform_track_insert_key(dtrack,kt-from,p,q,s); - } - - } - - if (dtrack!=-1 && kt>=to) { - - if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { - Quat q; - Vector3 p; - Vector3 s; - default_anim->transform_track_interpolate(j,to,&p,&q,&s); - new_anim->transform_track_insert_key(dtrack,to-from,p,q,s); - } - } - - } - - if (dtrack==-1 && p_bake_all) { - new_anim->add_track(default_anim->track_get_type(j)); - dtrack = new_anim->get_track_count()-1; - new_anim->track_set_path(dtrack,default_anim->track_get_path(j)); - if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) { - - - Quat q; - Vector3 p; - Vector3 s; - default_anim->transform_track_interpolate(j,from,&p,&q,&s); - new_anim->transform_track_insert_key(dtrack,0,p,q,s); - default_anim->transform_track_interpolate(j,to,&p,&q,&s); - new_anim->transform_track_insert_key(dtrack,to-from,p,q,s); - } - - } - } - - - new_anim->set_loop(loop); - new_anim->set_length(to-from); - anim->add_animation(name,new_anim); - } - - anim->remove_animation("default"); //remove default (no longer needed) -} - -void EditorSceneImportPlugin::_filter_anim_tracks(Ref<Animation> anim,Set<String> &keep) { - - Ref<Animation> a = anim; - ERR_FAIL_COND(!a.is_valid()); - - print_line("From Anim "+anim->get_name()+":"); - - for(int j=0;j<a->get_track_count();j++) { - - String path = a->track_get_path(j); - - if (!keep.has(path)) { - - print_line("Remove: "+path); - a->remove_track(j); - j--; - } - - } -} - - -void EditorSceneImportPlugin::_filter_tracks(Node *scene, const String& p_text) { - - if (!scene->has_node(String("AnimationPlayer"))) - return; - Node* n = scene->get_node(String("AnimationPlayer")); - ERR_FAIL_COND(!n); - AnimationPlayer *anim = n->cast_to<AnimationPlayer>(); - ERR_FAIL_COND(!anim); - - Vector<String> strings = p_text.split("\n"); - for(int i=0;i<strings.size();i++) { - - strings[i]=strings[i].strip_edges(); - } - - List<StringName> anim_names; - anim->get_animation_list(&anim_names); - for(List<StringName>::Element *E=anim_names.front();E;E=E->next()) { - - String name = E->get(); - bool valid_for_this=false; - bool valid=false; - - Set<String> keep; - Set<String> keep_local; - - - for(int i=0;i<strings.size();i++) { - - - if (strings[i].begins_with("@")) { - - valid_for_this=false; - for(Set<String>::Element *F=keep_local.front();F;F=F->next()) { - keep.insert(F->get()); - } - keep_local.clear(); - - Vector<String> filters=strings[i].substr(1,strings[i].length()).split(","); - for(int j=0;j<filters.size();j++) { - - String fname = filters[j].strip_edges(); - if (fname=="") - continue; - int fc = fname[0]; - bool plus; - if (fc=='+') - plus=true; - else if (fc=='-') - plus=false; - else - continue; - - String filter=fname.substr(1,fname.length()).strip_edges(); - - if (!name.matchn(filter)) - continue; - valid_for_this=plus; - } - - if (valid_for_this) - valid=true; - - } else if (valid_for_this) { - - Ref<Animation> a = anim->get_animation(name); - if (!a.is_valid()) - continue; - - for(int j=0;j<a->get_track_count();j++) { - - String path = a->track_get_path(j); - - String tname = strings[i]; - if (tname=="") - continue; - int fc = tname[0]; - bool plus; - if (fc=='+') - plus=true; - else if (fc=='-') - plus=false; - else - continue; - - String filter=tname.substr(1,tname.length()).strip_edges(); - - if (!path.matchn(filter)) - continue; - - if (plus) - keep_local.insert(path); - else if (!keep.has(path)) { - keep_local.erase(path); - } - } - - } - - } - - if (valid) { - for(Set<String>::Element *F=keep_local.front();F;F=F->next()) { - keep.insert(F->get()); - } - print_line("FILTERING ANIM: "+String(E->get())); - _filter_anim_tracks(anim->get_animation(name),keep); - } else { - print_line("NOT FILTERING ANIM: "+String(E->get())); - - } - - } - - - -} - -void EditorSceneImportPlugin::_optimize_animations(Node *scene, float p_max_lin_error,float p_max_ang_error,float p_max_angle) { - - if (!scene->has_node(String("AnimationPlayer"))) - return; - Node* n = scene->get_node(String("AnimationPlayer")); - ERR_FAIL_COND(!n); - AnimationPlayer *anim = n->cast_to<AnimationPlayer>(); - ERR_FAIL_COND(!anim); - - - List<StringName> anim_names; - anim->get_animation_list(&anim_names); - for(List<StringName>::Element *E=anim_names.front();E;E=E->next()) { - - Ref<Animation> a = anim->get_animation(E->get()); - a->optimize(p_max_lin_error,p_max_ang_error,Math::deg2rad(p_max_angle)); - } -} - - -void EditorSceneImportPlugin::_find_resources_to_merge(Node *scene, Node *node, bool p_merge_material, Map<String, Ref<Material> > &materials, bool p_merge_anims, Map<String,Ref<Animation> >& merged_anims,Set<Ref<Mesh> > &tested_meshes) { - - if (node!=scene && node->get_owner()!=scene) - return; - - String path = scene->get_path_to(node); - - if (p_merge_anims && node->cast_to<AnimationPlayer>()) { - - AnimationPlayer *ap = node->cast_to<AnimationPlayer>(); - List<StringName> anims; - ap->get_animation_list(&anims); - for (List<StringName>::Element *E=anims.front();E;E=E->next()) { - Ref<Animation> anim = ap->get_animation(E->get()); - Ref<Animation> clone; - - bool has_user_tracks=false; - - for(int i=0;i<anim->get_track_count();i++) { - - if (!anim->track_is_imported(i)) { - has_user_tracks=true; - break; - } - } - - if (has_user_tracks) { - - clone = anim->duplicate(); - for(int i=0;i<clone->get_track_count();i++) { - if (clone->track_is_imported(i)) { - clone->remove_track(i); - i--; - } - } - - merged_anims[path+"::"+String(E->get())]=clone; - } - } - } - - - - if (p_merge_material && node->cast_to<MeshInstance>()) { - MeshInstance *mi=node->cast_to<MeshInstance>(); - Ref<Mesh> mesh = mi->get_mesh(); - if (mesh.is_valid() && mesh->get_name()!=String() && !tested_meshes.has(mesh)) { - - for(int i=0;i<mesh->get_surface_count();i++) { - Ref<Material> material = mesh->surface_get_material(i); - - if (material.is_valid()) { - - String sname = mesh->surface_get_name(i); - if (sname=="") - sname="surf_"+itos(i); - - sname=mesh->get_name()+":surf:"+sname; - materials[sname]=material; - } - } - - tested_meshes.insert(mesh); - } - - if (mesh.is_valid()) { - - for(int i=0;i<mesh->get_surface_count();i++) { - Ref<Material> material = mi->get_surface_material(i); - if (material.is_valid()) { - String sname = mesh->surface_get_name(i); - if (sname=="") - sname="surf_"+itos(i); - - sname=path+":inst_surf:"+sname; - materials[sname]=material; - } - } - - } - - Ref<Material> override = mi->get_material_override(); - - if (override.is_valid()) { - - materials[path+":override"]=override; - } - } - - - - for(int i=0;i<node->get_child_count();i++) { - _find_resources_to_merge(scene,node->get_child(i),p_merge_material,materials,p_merge_anims,merged_anims,tested_meshes); - } - -} - - -void EditorSceneImportPlugin::_merge_found_resources(Node *scene, Node *node, bool p_merge_material, const Map<String, Ref<Material> > &materials, bool p_merge_anims, const Map<String,Ref<Animation> >& merged_anims, Set<Ref<Mesh> > &tested_meshes) { - - if (node!=scene && node->get_owner()!=scene) - return; - - String path = scene->get_path_to(node); - - print_line("at path: "+path); - - if (node->cast_to<AnimationPlayer>()) { - - AnimationPlayer *ap = node->cast_to<AnimationPlayer>(); - List<StringName> anims; - ap->get_animation_list(&anims); - for (List<StringName>::Element *E=anims.front();E;E=E->next()) { - Ref<Animation> anim = ap->get_animation(E->get()); - - String anim_path = path+"::"+String(E->get()); - - if (merged_anims.has(anim_path)) { - - Ref<Animation> user_tracks = merged_anims[anim_path]; - for(int i=0;i<user_tracks->get_track_count();i++) { - - int idx = anim->get_track_count(); - anim->add_track(user_tracks->track_get_type(i)); - anim->track_set_path(idx,user_tracks->track_get_path(i)); - anim->track_set_interpolation_type(idx,user_tracks->track_get_interpolation_type(i)); - for(int j=0;j<user_tracks->track_get_key_count(i);j++) { - - float ofs = user_tracks->track_get_key_time(i,j); - float trans = user_tracks->track_get_key_transition(i,j); - Variant value = user_tracks->track_get_key_value(i,j); - - anim->track_insert_key(idx,ofs,value,trans); - } - } - } - } - } - - - - if (node->cast_to<MeshInstance>()) { - MeshInstance *mi=node->cast_to<MeshInstance>(); - Ref<Mesh> mesh = mi->get_mesh(); - if (mesh.is_valid() && mesh->get_name()!=String() && !tested_meshes.has(mesh)) { - - for(int i=0;i<mesh->get_surface_count();i++) { - - String sname = mesh->surface_get_name(i); - if (sname=="") - sname="surf_"+itos(i); - - sname=mesh->get_name()+":surf:"+sname; - - - if (materials.has(sname)) { - - mesh->surface_set_material(i,materials[sname]); - } - } - - tested_meshes.insert(mesh); - } - - if (mesh.is_valid()) { - - for(int i=0;i<mesh->get_surface_count();i++) { - - String sname = mesh->surface_get_name(i); - if (sname=="") - sname="surf_"+itos(i); - - sname=path+":inst_surf:"+sname; - - - if (materials.has(sname)) { - - mi->set_surface_material(i,materials[sname]); - } - } - - } - - - String opath = path+":override"; - if (materials.has(opath)) { - mi->set_material_override(materials[opath]); - } - - } - - - - for(int i=0;i<node->get_child_count();i++) { - _merge_found_resources(scene,node->get_child(i),p_merge_material,materials,p_merge_anims,merged_anims,tested_meshes); - } - -} - -Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, const Ref<ResourceImportMetadata>& p_from) { - - Error err=OK; - Ref<ResourceImportMetadata> from=p_from; - String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0)); - int animation_flags=p_from->get_option("animation_flags"); - Array animation_clips = p_from->get_option("animation_clips"); - String animation_filter = p_from->get_option("animation_filters"); - int scene_flags = from->get_option("flags"); - float anim_optimizer_linerr=0.05; - float anim_optimizer_angerr=0.01; - float anim_optimizer_maxang=22; - - if (from->has_option("animation_optimizer_linear_error")) - anim_optimizer_linerr=from->get_option("animation_optimizer_linear_error"); - if (from->has_option("animation_optimizer_angular_error")) - anim_optimizer_angerr=from->get_option("animation_optimizer_angular_error"); - if (from->has_option("animation_optimizer_max_angle")) - anim_optimizer_maxang=from->get_option("animation_optimizer_max_angle"); - - EditorProgress progress("import",TTR("Import Scene"),104); - progress.step(TTR("Importing Scene.."),2); - - - from->set_source_md5(0,FileAccess::get_md5(src_path)); - from->set_editor(get_name()); - - from->set_option("reimport",false); - String target_res_path=p_dest_path.get_base_dir(); - - Map<Ref<Mesh>,Ref<Shape> > collision_map; - - Map< Ref<ImageTexture>,TextureRole > imagemap; - - scene=_fix_node(scene,scene,collision_map,scene_flags,imagemap); - if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE) - _optimize_animations(scene,anim_optimizer_linerr,anim_optimizer_angerr,anim_optimizer_maxang); - if (animation_clips.size()) - _create_clips(scene,animation_clips,animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS); - - _filter_tracks(scene,animation_filter); - - - if (scene_flags&(SCENE_FLAG_MERGE_KEEP_MATERIALS|SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS) && FileAccess::exists(p_dest_path)) { - //must merge! - - print_line("MUST MERGE"); - Ref<PackedScene> pscene = ResourceLoader::load(p_dest_path,"PackedScene",true); - if (pscene.is_valid()) { - - Node *instance = pscene->instance(); - if (instance) { - Map<String,Ref<Animation> > merged_anims; - Map<String,Ref<Material> > merged_materials; - Set<Ref<Mesh> > tested_meshes; - - _find_resources_to_merge(instance,instance,scene_flags&SCENE_FLAG_MERGE_KEEP_MATERIALS,merged_materials,scene_flags&SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS,merged_anims,tested_meshes); - - tested_meshes.clear(); - _merge_found_resources(scene,scene,scene_flags&SCENE_FLAG_MERGE_KEEP_MATERIALS,merged_materials,scene_flags&SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS,merged_anims,tested_meshes); - - memdelete(instance); - } - - } - - } - - /// BEFORE ANYTHING, RUN SCRIPT - - progress.step(TTR("Running Custom Script.."),2); - - String post_import_script_path = from->get_option("post_import_script"); - Ref<EditorScenePostImport> post_import_script; - - if (post_import_script_path!="") { - post_import_script_path = post_import_script_path; - Ref<Script> scr = ResourceLoader::load(post_import_script_path); - if (!scr.is_valid()) { - EditorNode::add_io_error(TTR("Couldn't load post-import script:")+" "+post_import_script_path); - } else { - - post_import_script = Ref<EditorScenePostImport>( memnew( EditorScenePostImport ) ); - post_import_script->set_script(scr.get_ref_ptr()); - if (!post_import_script->get_script_instance()) { - EditorNode::add_io_error(TTR("Invalid/broken script for post-import (check console):")+" "+post_import_script_path); - post_import_script.unref(); - return ERR_CANT_CREATE; - } - } - } - - - if (post_import_script.is_valid()) { - scene = post_import_script->post_import(scene); - if (!scene) { - EditorNode::add_io_error(TTR("Error running post-import script:")+" "+post_import_script_path); - return err; - } - - - } - - - /// IMPORT IMAGES - - - int idx=0; - - int image_format = from->get_option("texture_format"); - int image_flags = from->get_option("texture_flags"); - float image_quality = from->get_option("texture_quality"); - - for (Map< Ref<ImageTexture>,TextureRole >::Element *E=imagemap.front();E;E=E->next()) { - - //texture could be converted to something more useful for 3D, that could load individual mipmaps and stuff - //but not yet.. - - Ref<ImageTexture> texture = E->key(); - - ERR_CONTINUE(!texture.is_valid()); - - String path = texture->get_path(); - String fname= path.get_file(); - String target_path = GlobalConfig::get_singleton()->localize_path(target_res_path.plus_file(fname)); - progress.step(TTR("Import Image:")+" "+fname,3+(idx)*100/imagemap.size()); - - idx++; - - if (path==target_path) { - - EditorNode::add_io_error(TTR("Can't import a file over itself:")+" "+target_path); - continue; - } - - if (!target_path.begins_with("res://")) { - EditorNode::add_io_error(vformat(TTR("Couldn't localize path: %s (already local)"),target_path)); - continue; - } - - - { - - - target_path=target_path.get_basename()+".tex"; - - Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); - - uint32_t flags = image_flags; - if (E->get()==TEXTURE_ROLE_DIFFUSE && scene_flags&SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES) - flags|=EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_TO_LINEAR; - - if (E->get()==TEXTURE_ROLE_NORMALMAP && scene_flags&SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY) - flags|=EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_NORMAL_TO_XY; - - imd->set_option("flags",flags); - imd->set_option("format",image_format); - imd->set_option("quality",image_quality); - imd->set_option("atlas",false); - imd->add_source(EditorImportPlugin::validate_source_path(path)); - - - if (FileAccess::exists(target_path)) { - - Ref<ResourceImportMetadata> rimdex = ResourceLoader::load_import_metadata(target_path); - if (rimdex.is_valid()) { - //make sure the options are the same, otherwise re-import - List<String> opts; - imd->get_options(&opts); - bool differ=false; - for (List<String>::Element *E=opts.front();E;E=E->next()) { - if (!(rimdex->get_option(E->get())==imd->get_option(E->get()))) { - differ=true; - break; - } - } - - if (!differ) { - texture->set_path(target_path); - continue; //already imported - } - } - } - - EditorTextureImportPlugin::get_singleton()->import(target_path,imd); - - } - } - - - - progress.step(TTR("Saving.."),104); - - Ref<PackedScene> packer = memnew( PackedScene ); - packer->pack(scene); - //packer->set_path(p_dest_path); do not take over, let the changed files reload themselves - packer->set_import_metadata(from); - - print_line("SAVING TO: "+p_dest_path); - err = ResourceSaver::save(p_dest_path,packer); //do not take over, let the changed files reload themselves - - //EditorFileSystem::get_singleton()->update_resource(packer); - - memdelete(scene); - - /* - scene->set_filename(p_dest_path); - if (r_scene) { - *r_scene=scene; - } else { - memdelete(scene); - } - - String sp; - if (p_post_import.is_valid() && !p_post_import->get_script().is_null()) { - Ref<Script> scr = p_post_import->get_script(); - if (scr.is_valid()) - sp=scr->get_path(); - } - - String op=_getrelpath(p_path,p_dest_path); - - */ - - EditorNode::get_singleton()->reload_scene(p_dest_path); - - return err; - -} - - -Error EditorSceneImportPlugin::import(const String& p_dest_path, const Ref<ResourceImportMetadata>& p_from){ - - - Node *n=NULL; - Error err = import1(p_from,&n); - if (err!=OK) { - if (n) { - memdelete(n); - } - return err; - } - return import2(n,p_dest_path,p_from); -} - -void EditorSceneImportPlugin::add_importer(const Ref<EditorSceneImporter>& p_importer) { - - importers.push_back(p_importer); -} - -void EditorSceneImportPlugin::import_from_drop(const Vector<String>& p_drop,const String& p_dest_path) { - - List<String> extensions; - for(int i=0;i<importers.size();i++) { - importers[i]->get_extensions(&extensions); - } - //bool warn_compatible=false; - for(int i=0;i<p_drop.size();i++) { - - String extension = p_drop[i].get_extension().to_lower(); - - for(List<String>::Element *E=extensions.front();E;E=E->next()) { - - if (E->get()==extension) { - - dialog->popup_import(String()); - dialog->setup_popup(p_drop[i],p_dest_path); - return; - } - } - } - -} - - -EditorSceneImportPlugin::EditorSceneImportPlugin(EditorNode* p_editor) { - - dialog = memnew( EditorSceneImportDialog(p_editor,this) ); - p_editor->get_gui_base()->add_child(dialog); -} - - -/////////////////////////////// - - -String EditorSceneAnimationImportPlugin::get_name() const { - - return "anim_3d"; -} -String EditorSceneAnimationImportPlugin::get_visible_name() const{ - - - return TTR("3D Scene Animation"); -} -void EditorSceneAnimationImportPlugin::import_dialog(const String& p_from){ - - -} -Error EditorSceneAnimationImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from){ - - return OK; -} - -EditorSceneAnimationImportPlugin::EditorSceneAnimationImportPlugin(EditorNode* p_editor) { - - -} -#endif diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.h b/tools/editor/io_plugins/editor_scene_import_plugin.h deleted file mode 100644 index bbafc126bb..0000000000 --- a/tools/editor/io_plugins/editor_scene_import_plugin.h +++ /dev/null @@ -1,200 +0,0 @@ -/*************************************************************************/ -/* editor_scene_import_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITOR_SCENE_IMPORT_PLUGIN_H -#define EDITOR_SCENE_IMPORT_PLUGIN_H -#if 0 -#include "scene/gui/dialogs.h" -#include "scene/gui/tree.h" -#include "scene/gui/label.h" -#include "scene/gui/option_button.h" -#include "scene/gui/line_edit.h" -#include "scene/gui/file_dialog.h" -#include "scene/gui/progress_bar.h" -#include "scene/gui/slider.h" -#include "scene/gui/spin_box.h" -#include "scene/resources/mesh.h" -#include "tools/editor/editor_file_system.h" -#include "tools/editor/editor_dir_dialog.h" -#include "tools/editor/editor_import_export.h" -#include "tools/editor/io_plugins/editor_texture_import_plugin.h" -#include "scene/resources/animation.h" - - -class EditorNode; -class EditorSceneImportDialog; - -class EditorSceneImporter : public Reference { - - GDCLASS(EditorSceneImporter,Reference ); -public: - - enum ImportFlags { - IMPORT_SCENE=1, - IMPORT_ANIMATION=2, - IMPORT_ANIMATION_DETECT_LOOP=4, - IMPORT_ANIMATION_OPTIMIZE=8, - IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS=16, - IMPORT_ANIMATION_KEEP_VALUE_TRACKS=32, - IMPORT_GENERATE_TANGENT_ARRAYS=256, - IMPORT_FAIL_ON_MISSING_DEPENDENCIES=512 - - }; - - virtual uint32_t get_import_flags() const=0; - virtual void get_extensions(List<String> *r_extensions) const=0; - virtual Node* import_scene(const String& p_path,uint32_t p_flags,int p_bake_fps,List<String> *r_missing_deps,Error* r_err=NULL)=0; - virtual Ref<Animation> import_animation(const String& p_path,uint32_t p_flags)=0; - - - - EditorSceneImporter(); -}; - -///////////////////////////////////////// - - -//Plugin for post processing scenes or images - -class EditorScenePostImport : public Reference { - - GDCLASS(EditorScenePostImport,Reference ); -protected: - - static void _bind_methods(); -public: - - virtual Node* post_import(Node* p_scene); - EditorScenePostImport(); -}; - - -class EditorSceneImportPlugin : public EditorImportPlugin { - - GDCLASS(EditorSceneImportPlugin,EditorImportPlugin); - - EditorSceneImportDialog *dialog; - - Vector<Ref<EditorSceneImporter> > importers; - - enum TextureRole { - TEXTURE_ROLE_DEFAULT, - TEXTURE_ROLE_DIFFUSE, - TEXTURE_ROLE_NORMALMAP - }; - - void _find_resources(const Variant& p_var,Map<Ref<ImageTexture>,TextureRole >& image_map,int p_flags); - Node* _fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,TextureRole >& image_map); - void _create_clips(Node *scene, const Array& p_clips, bool p_bake_all); - void _filter_anim_tracks(Ref<Animation> anim,Set<String> &keep); - void _filter_tracks(Node *scene, const String& p_text); - void _optimize_animations(Node *scene, float p_max_lin_error,float p_max_ang_error,float p_max_angle); - - void _tag_import_paths(Node *p_scene,Node *p_node); - - void _find_resources_to_merge(Node *scene, Node *node, bool p_merge_material, Map<String,Ref<Material> >&materials, bool p_merge_anims, Map<String,Ref<Animation> >& merged_anims, Set<Ref<Mesh> > &tested_meshes); - void _merge_found_resources(Node *scene, Node *node, bool p_merge_material, const Map<String, Ref<Material> > &materials, bool p_merge_anims, const Map<String,Ref<Animation> >& merged_anims, Set<Ref<Mesh> > &tested_meshes); - - -public: - - enum SceneFlags { - - SCENE_FLAG_CREATE_COLLISIONS=1<<0, - SCENE_FLAG_CREATE_PORTALS=1<<1, - SCENE_FLAG_CREATE_ROOMS=1<<2, - SCENE_FLAG_SIMPLIFY_ROOMS=1<<3, - SCENE_FLAG_CREATE_BILLBOARDS=1<<4, - SCENE_FLAG_CREATE_IMPOSTORS=1<<5, - SCENE_FLAG_CREATE_LODS=1<<6, - SCENE_FLAG_CREATE_CARS=1<<8, - SCENE_FLAG_CREATE_WHEELS=1<<9, - SCENE_FLAG_DETECT_ALPHA=1<<15, - SCENE_FLAG_DETECT_VCOLOR=1<<16, - SCENE_FLAG_CREATE_NAVMESH=1<<17, - SCENE_FLAG_DETECT_LIGHTMAP_LAYER=1<<18, - - SCENE_FLAG_MERGE_KEEP_MATERIALS=1<<20, - SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS=1<<21, - - SCENE_FLAG_REMOVE_NOIMP=1<<24, - SCENE_FLAG_IMPORT_ANIMATIONS=1<<25, - SCENE_FLAG_COMPRESS_GEOMETRY=1<<26, - SCENE_FLAG_GENERATE_TANGENT_ARRAYS=1<<27, - SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES=1<<28, - SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS=1<<29, - SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY=1<<30, - }; - - - - virtual String get_name() const; - virtual String get_visible_name() const; - virtual void import_dialog(const String& p_from=""); - virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); - - Error import1(const Ref<ResourceImportMetadata>& p_from,Node**r_node,List<String> *r_missing=NULL); - Error import2(Node* p_scene,const String& p_path, const Ref<ResourceImportMetadata>& p_from); - - void add_importer(const Ref<EditorSceneImporter>& p_importer); - const Vector<Ref<EditorSceneImporter> >& get_importers() { return importers; } - - virtual void import_from_drop(const Vector<String>& p_drop,const String& p_dest_path); - - EditorSceneImportPlugin(EditorNode* p_editor=NULL); - - -}; - - -class EditorSceneAnimationImportPlugin : public EditorImportPlugin { - - GDCLASS(EditorSceneAnimationImportPlugin,EditorImportPlugin); -public: - - - enum AnimationFlags { - - ANIMATION_DETECT_LOOP=1, - ANIMATION_KEEP_VALUE_TRACKS=2, - ANIMATION_OPTIMIZE=4, - ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS=8 - }; - - virtual String get_name() const; - virtual String get_visible_name() const; - virtual void import_dialog(const String& p_from=""); - virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); - - EditorSceneAnimationImportPlugin(EditorNode* p_editor=NULL); - - -}; - -#endif -#endif // EDITOR_SCENE_IMPORT_PLUGIN_H diff --git a/tools/editor/io_plugins/editor_scene_importer_fbxconv.cpp b/tools/editor/io_plugins/editor_scene_importer_fbxconv.cpp deleted file mode 100644 index af12d85650..0000000000 --- a/tools/editor/io_plugins/editor_scene_importer_fbxconv.cpp +++ /dev/null @@ -1,1136 +0,0 @@ -/*************************************************************************/ -/* editor_scene_importer_fbxconv.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 "editor_scene_importer_fbxconv.h" - -#include "os/file_access.h" -#include "os/os.h" -#include "tools/editor/editor_settings.h" -#include "scene/3d/mesh_instance.h" -#include "scene/animation/animation_player.h" - -#if 0 -String EditorSceneImporterFBXConv::_id(const String& p_id) const { - - return p_id.replace(":","_").replace("/","_"); -} - -uint32_t EditorSceneImporterFBXConv::get_import_flags() const { - - return IMPORT_SCENE|IMPORT_ANIMATION; -} -void EditorSceneImporterFBXConv::get_extensions(List<String> *r_extensions) const{ - - r_extensions->push_back("fbx"); - r_extensions->push_back("g3dj"); -} - - -Color EditorSceneImporterFBXConv::_get_color(const Array& a) { - - if (a.size()<3) - return Color(); - Color c; - c.r=a[0]; - c.g=a[1]; - c.b=a[2]; - if (a.size()>=4) - c.a=a[3]; - return c; - -} - -Transform EditorSceneImporterFBXConv::_get_transform_mixed(const Dictionary& d,const Dictionary& dbase) { - - - - - Array translation; - - if (d.has("translation")) - translation=d["translation"]; - else if (dbase.has("translation")) - translation=dbase["translation"]; - - Array rotation; - - if (d.has("rotation")) - rotation=d["rotation"]; - else if (dbase.has("rotation")) - rotation=dbase["rotation"]; - - Array scale; - - if (d.has("scale")) - scale=d["scale"]; - else if (dbase.has("scale")) - scale=dbase["scale"]; - - Transform t; - - - if (translation.size()) { - Array tr = translation; - if (tr.size()>=3) { - t.origin.x=tr[0]; - t.origin.y=tr[1]; - t.origin.z=tr[2]; - } - } - - if (rotation.size()) { - - Array r = rotation; - if (r.size()>=4) { - - Quat q; - q.x = r[0]; - q.y = r[1]; - q.z = r[2]; - q.w = r[3]; - t.basis=Matrix3(q); - } - } - - - if (scale.size()) { - - Array sc = scale; - if (sc.size()>=3) { - Vector3 s; - s.x=sc[0]; - s.y=sc[1]; - s.z=sc[2]; - t.basis.scale(s); - } - } - - return t; - - -} - -Transform EditorSceneImporterFBXConv::_get_transform(const Dictionary& d) { - - - Transform t; - - if (d.has("translation")) { - Array tr = d["translation"]; - if (tr.size()>=3) { - t.origin.x=tr[0]; - t.origin.y=tr[1]; - t.origin.z=tr[2]; - } - } - - if (d.has("rotation")) { - - Array r = d["rotation"]; - if (r.size()>=4) { - - Quat q; - q.x = r[0]; - q.y = r[1]; - q.z = r[2]; - q.w = r[3]; - t.basis=Matrix3(q); - } - } - - - if (d.has("scale")) { - - Array sc = d["scale"]; - if (sc.size()>=3) { - Vector3 s; - s.x=sc[0]; - s.y=sc[1]; - s.z=sc[2]; - t.basis.scale(s); - } - } - - return t; -} - - -void EditorSceneImporterFBXConv::_detect_bones_in_nodes(State& state,const Array& p_nodes) { - - - for(int i=0;i<p_nodes.size();i++) { - - Dictionary d = p_nodes[i]; - if (d.has("isBone") && bool(d["isBone"])) { - - String bone_name=_id(d["id"]); - print_line("IS BONE: "+bone_name); - if (!state.bones.has(bone_name)) { - state.bones.insert(bone_name,BoneInfo()); - } - - if (!state.bones[bone_name].has_rest) { - state.bones[bone_name].rest=_get_transform(d).affine_inverse(); - } - - state.bones[bone_name].node=d; - - //state.bones[name].rest=_get_transform(b); - } - - if (d.has("parts")) { - - Array parts=d["parts"]; - for(int j=0;j<parts.size();j++) { - - Dictionary p=parts[j]; - if (p.has("bones")) { - Array bones=p["bones"]; - //omfg - for(int k=0;k<bones.size();k++) { - - Dictionary b = bones[k]; - if (b.has("node")) { - - String name = _id(b["node"]); - if (!state.bones.has(name)) { - state.bones.insert(name,BoneInfo()); - } - - state.bones[name].rest=_get_transform(b); - state.bones[name].has_rest=true; - } - } - } - - } - } - - if (d.has("children")) { - - _detect_bones_in_nodes(state,d["children"]); - } - } - -} - -void EditorSceneImporterFBXConv::_parse_skeletons(const String& p_name,State& state, const Array &p_nodes, Skeleton *p_skeleton,int p_parent) { - - - - for(int i=0;i<p_nodes.size();i++) { - - - Dictionary d = p_nodes[i]; - int bone_idx=-1; - String id; - Skeleton* skeleton=p_skeleton; - if (d.has("id")) { - - id=_id(d["id"]); - if (state.bones.has(id)) { - //BONER - if (!skeleton) { - skeleton=memnew( Skeleton ); - state.skeletons[id]=skeleton; - } - bone_idx = skeleton->get_bone_count(); - skeleton->add_bone(id); - skeleton->set_bone_parent(bone_idx,p_parent); - skeleton->set_bone_rest(bone_idx,state.bones[id].rest); - state.bones[id].skeleton=skeleton; - } - } - - if (d.has("children")) { - - _parse_skeletons(id,state,d["children"],skeleton,bone_idx); - } - } - -} - -void EditorSceneImporterFBXConv::_detect_bones(State& state) { - //This format should mark when a node is a bone, - //which is the only thing that Collada does right. - //think about others implementing a parser. - //Just _one_ string and you avoid loads of lines of code to other people. - - for(int i=0;i<state.animations.size();i++) { - - Dictionary an = state.animations[i]; - if (an.has("bones")) { - - Array bo=an["bones"]; - for(int j=0;j<bo.size();j++) { - - Dictionary b=bo[j]; - if (b.has("boneId")) { - - String id = b["boneId"]; - if (!state.bones.has(id)) { - state.bones.insert(id,BoneInfo()); - } - state.bones[id].has_anim_chan=true; //used in anim - - - } - } - } - } - - _detect_bones_in_nodes(state,state.nodes); - _parse_skeletons("",state,state.nodes,NULL,-1); - - print_line("found bones: "+itos(state.bones.size())); - print_line("found skeletons: "+itos(state.skeletons.size())); -} - -Error EditorSceneImporterFBXConv::_parse_bones(State& state,const Array &p_bones,Skeleton* p_skeleton) { - - - - return OK; -} - - -void EditorSceneImporterFBXConv::_add_surface(State& state,Ref<Mesh>& m,const Dictionary &part) { - - if (part.has("meshpartid")) { - - String id = part["meshpartid"]; - ERR_FAIL_COND(!state.surface_cache.has(id)); - - - Ref<Material> mat; - if (part.has("materialid")) { - String matid=part["materialid"]; - if (state.material_cache.has(matid)) { - mat=state.material_cache[matid]; - } - } - int idx = m->get_surface_count(); - - Array array = state.surface_cache[id].array; - PoolVector<float> indices = array[Mesh::ARRAY_BONES]; - if (indices.size() && part.has("bones")) { - - - Map<int,int> index_map; - - Array bones=part["bones"]; - - for(int i=0;i<bones.size();i++) { - - Dictionary bone=bones[i]; - String name=_id(bone["node"]); - - if (state.bones.has(name)) { - int idx=state.bones[name].skeleton->find_bone(name); - if (idx==-1) - idx=0; - index_map[i]=idx; - } - } - - - - int ilen=indices.size(); - { - PoolVector<float>::Write iw=indices.write(); - for(int j=0;j<ilen;j++) { - int b = iw[j]; - ERR_CONTINUE(!index_map.has(b)); - b=index_map[b]; - iw[j]=b; - } - } - - array[Mesh::ARRAY_BONES]=indices; - - - } - - m->add_surface(state.surface_cache[id].primitive,array); - m->surface_set_material(idx,mat); - m->surface_set_name(idx,id); - } - -} - -Error EditorSceneImporterFBXConv::_parse_nodes(State& state,const Array &p_nodes,Node* p_base) { - - for(int i=0;i<p_nodes.size();i++) { - - Dictionary n = p_nodes[i]; - Spatial *node=NULL; - bool skip=false; - - String id; - if (n.has("id")) { - id=_id(n["id"]); - } - - print_line("ID: "+id); - - if (state.skeletons.has(id)) { - - Skeleton *skeleton = state.skeletons[id]; - node=skeleton; - skeleton->localize_rests(); - print_line("IS SKELETON! "); - } else if (state.bones.has(id)) { - if (p_base) - node=p_base->cast_to<Spatial>(); - if (!state.bones[id].has_anim_chan) { - print_line("no has anim "+id); - } - skip=true; - } else if (n.has("parts")) { - //is a mesh - MeshInstance *mesh = memnew( MeshInstance ); - node=mesh; - - Array parts=n["parts"]; - String long_identifier; - for(int j=0;j<parts.size();j++) { - - Dictionary part=parts[j]; - if (part.has("meshpartid")) { - String partid=part["meshpartid"]; - long_identifier+=partid; - } - } - - Ref<Mesh> m; - - if (state.mesh_cache.has(long_identifier)) { - m=state.mesh_cache[long_identifier]; - } else { - m = Ref<Mesh>( memnew( Mesh ) ); - - //and parts are surfaces - for(int j=0;j<parts.size();j++) { - - Dictionary part=parts[j]; - if (part.has("meshpartid")) { - _add_surface(state,m,part); - } - } - - - state.mesh_cache[long_identifier]=m; - } - - mesh->set_mesh(m); - } - - if (!skip) { - - if (!node) { - node = memnew( Spatial ); - } - - node->set_name(id); - node->set_transform(_get_transform(n)); - p_base->add_child(node); - node->set_owner(state.scene); - } - - - if (n.has("children")) { - Error err = _parse_nodes(state,n["children"],node); - if (err) - return err; - } - } - - return OK; -} - - -void EditorSceneImporterFBXConv::_parse_materials(State& state) { - - for(int i=0;i<state.materials.size();i++) { - - Dictionary material = state.materials[i]; - - ERR_CONTINUE(!material.has("id")); - String id = _id(material["id"]); - - Ref<FixedSpatialMaterial> mat = memnew( FixedSpatialMaterial ); - - if (material.has("diffuse")) { - mat->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,_get_color(material["diffuse"])); - } - - if (material.has("specular")) { - mat->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR,_get_color(material["specular"])); - } - - if (material.has("emissive")) { - mat->set_parameter(FixedSpatialMaterial::PARAM_EMISSION,_get_color(material["emissive"])); - } - - if (material.has("shininess")) { - float exp = material["shininess"]; - mat->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR_EXP,exp); - } - - if (material.has("opacity")) { - Color c = mat->get_parameter(FixedSpatialMaterial::PARAM_DIFFUSE); - c.a=material["opacity"]; - mat->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,c); - } - - - if (material.has("textures")) { - - Array textures = material["textures"]; - for(int j=0;j<textures.size();j++) { - - Dictionary texture=textures[j]; - Ref<Texture> tex; - if (texture.has("filename")) { - - - String filename=texture["filename"]; - String path=state.base_path+"/"+filename.replace("\\","/"); - if (state.texture_cache.has(path)) { - tex=state.texture_cache[path]; - } else { - tex = ResourceLoader::load(path,"ImageTexture"); - if (tex.is_null()) { - if (state.missing_deps) - state.missing_deps->push_back(path); - } - state.texture_cache[path]=tex; //add anyway - } - } - - if (tex.is_valid() && texture.has("type")) { - - String type=texture["type"]; - if (type=="DIFFUSE") - mat->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,tex); - else if (type=="SPECULAR") - mat->set_texture(FixedSpatialMaterial::PARAM_SPECULAR,tex); - else if (type=="SHININESS") - mat->set_texture(FixedSpatialMaterial::PARAM_SPECULAR_EXP,tex); - else if (type=="NORMAL") - mat->set_texture(FixedSpatialMaterial::PARAM_NORMAL,tex); - else if (type=="EMISSIVE") - mat->set_texture(FixedSpatialMaterial::PARAM_EMISSION,tex); - } - - } - } - - state.material_cache[id]=mat; - - } - -} - -void EditorSceneImporterFBXConv::_parse_surfaces(State& state) { - - for(int i=0;i<state.meshes.size();i++) { - - Dictionary mesh = state.meshes[i]; - - ERR_CONTINUE(!mesh.has("attributes")); - ERR_CONTINUE(!mesh.has("vertices")); - ERR_CONTINUE(!mesh.has("parts")); - - print_line("MESH #"+itos(i)); - - Array attrlist=mesh["attributes"]; - Array vertices=mesh["vertices"]; - bool exists[Mesh::ARRAY_MAX]; - int ofs[Mesh::ARRAY_MAX]; - int weight_max=0; - int binormal_ofs=-1; - int weight_ofs[4]; - - for(int j=0;j<Mesh::ARRAY_MAX;j++) { - exists[j]=false; - ofs[j]=0; - } - exists[Mesh::ARRAY_INDEX]=true; - float stride=0; - - for(int j=0;j<attrlist.size();j++) { - - String attr=attrlist[j]; - if (attr=="POSITION") { - exists[Mesh::ARRAY_VERTEX]=true; - ofs[Mesh::ARRAY_VERTEX]=stride; - stride+=3; - } else if (attr=="NORMAL") { - exists[Mesh::ARRAY_NORMAL]=true; - ofs[Mesh::ARRAY_NORMAL]=stride; - stride+=3; - } else if (attr=="COLOR") { - exists[Mesh::ARRAY_COLOR]=true; - ofs[Mesh::ARRAY_COLOR]=stride; - stride+=4; - } else if (attr=="COLORPACKED") { - stride+=1; //ignore - } else if (attr=="TANGENT") { - exists[Mesh::ARRAY_TANGENT]=true; - ofs[Mesh::ARRAY_TANGENT]=stride; - stride+=3; - } else if (attr=="BINORMAL") { - binormal_ofs=stride; - stride+=3; - } else if (attr=="TEXCOORD0") { - exists[Mesh::ARRAY_TEX_UV]=true; - ofs[Mesh::ARRAY_TEX_UV]=stride; - stride+=2; - } else if (attr=="TEXCOORD1") { - exists[Mesh::ARRAY_TEX_UV2]=true; - ofs[Mesh::ARRAY_TEX_UV2]=stride; - stride+=2; - } else if (attr.begins_with("TEXCOORD")) { - stride+=2; - } else if (attr.begins_with("BLENDWEIGHT")) { - int idx=attr.replace("BLENDWEIGHT","").to_int(); - if (idx==0) { - exists[Mesh::ARRAY_BONES]=true; - ofs[Mesh::ARRAY_BONES]=stride; - exists[Mesh::ARRAY_WEIGHTS]=true; - ofs[Mesh::ARRAY_WEIGHTS]=stride+1; - } if (idx<4) { - weight_ofs[idx]=stride; - weight_max=MAX(weight_max,idx+1); - } - - stride+=2; - } - - print_line("ATTR "+attr+" OFS: "+itos(stride)); - - } - - Array parts=mesh["parts"]; - - for(int j=0;j<parts.size();j++) { - - - - Dictionary part=parts[j]; - ERR_CONTINUE(!part.has("indices")); - ERR_CONTINUE(!part.has("id")); - - print_line("PART: "+String(part["id"])); - Array indices=part["indices"]; - Map<int,int> iarray; - Map<int,int> array; - - for(int k=0;k<indices.size();k++) { - - int idx = indices[k]; - if (!iarray.has(idx)) { - int map_to=array.size(); - iarray[idx]=map_to; - array[map_to]=idx; - } - } - - print_line("indices total "+itos(indices.size())+" vertices used: "+itos(array.size())); - - Array arrays; - arrays.resize(Mesh::ARRAY_MAX); - - - - for(int k=0;k<Mesh::ARRAY_MAX;k++) { - - - if (!exists[k]) - continue; - print_line("exists: "+itos(k)); - int lofs = ofs[k]; - switch(k) { - - case Mesh::ARRAY_VERTEX: - case Mesh::ARRAY_NORMAL: { - - PoolVector<Vector3> vtx; - vtx.resize(array.size()); - { - int len=array.size(); - PoolVector<Vector3>::Write w = vtx.write(); - for(int l=0;l<len;l++) { - - int pos = array[l]; - w[l].x=vertices[pos*stride+lofs+0]; - w[l].y=vertices[pos*stride+lofs+1]; - w[l].z=vertices[pos*stride+lofs+2]; - } - } - arrays[k]=vtx; - - } break; - case Mesh::ARRAY_TANGENT: { - - if (binormal_ofs<0) - break; - - PoolVector<float> tangents; - tangents.resize(array.size()*4); - { - int len=array.size(); - - PoolVector<float>::Write w = tangents.write(); - for(int l=0;l<len;l++) { - - int pos = array[l]; - Vector3 n; - n.x=vertices[pos*stride+ofs[Mesh::ARRAY_NORMAL]+0]; - n.y=vertices[pos*stride+ofs[Mesh::ARRAY_NORMAL]+1]; - n.z=vertices[pos*stride+ofs[Mesh::ARRAY_NORMAL]+2]; - Vector3 t; - t.x=vertices[pos*stride+lofs+0]; - t.y=vertices[pos*stride+lofs+1]; - t.z=vertices[pos*stride+lofs+2]; - Vector3 bi; - bi.x=vertices[pos*stride+binormal_ofs+0]; - bi.y=vertices[pos*stride+binormal_ofs+1]; - bi.z=vertices[pos*stride+binormal_ofs+2]; - float d = bi.dot(n.cross(t)); - - w[l*4+0]=t.x; - w[l*4+1]=t.y; - w[l*4+2]=t.z; - w[l*4+3]=d; - - } - } - arrays[k]=tangents; - - } break; - case Mesh::ARRAY_COLOR: { - - PoolVector<Color> cols; - cols.resize(array.size()); - { - int len=array.size(); - PoolVector<Color>::Write w = cols.write(); - for(int l=0;l<len;l++) { - - int pos = array[l]; - w[l].r=vertices[pos*stride+lofs+0]; - w[l].g=vertices[pos*stride+lofs+1]; - w[l].b=vertices[pos*stride+lofs+2]; - w[l].a=vertices[pos*stride+lofs+3]; - } - } - arrays[k]=cols; - - } break; - case Mesh::ARRAY_TEX_UV: - case Mesh::ARRAY_TEX_UV2: { - - PoolVector<Vector2> uvs; - uvs.resize(array.size()); - { - int len=array.size(); - PoolVector<Vector2>::Write w = uvs.write(); - for(int l=0;l<len;l++) { - - int pos = array[l]; - w[l].x=vertices[pos*stride+lofs+0]; - w[l].y=vertices[pos*stride+lofs+1]; - w[l].y=1.0-w[l].y; - } - } - arrays[k]=uvs; - - } break; - case Mesh::ARRAY_BONES: - case Mesh::ARRAY_WEIGHTS: { - - PoolVector<float> arr; - arr.resize(array.size()*4); - int po=k==Mesh::ARRAY_WEIGHTS?1:0; - lofs=ofs[Mesh::ARRAY_BONES]; - { - int len=array.size(); - - PoolVector<float>::Write w = arr.write(); - for(int l=0;l<len;l++) { - - int pos = array[l]; - - for(int m=0;m<4;m++) { - - float val=0; - if (m<=weight_max) - val=vertices[pos*stride+lofs+m*2+po]; - w[l*4+m]=val; - } - } - } - - arrays[k]=arr; - } break; - case Mesh::ARRAY_INDEX: { - - PoolVector<int> arr; - arr.resize(indices.size()); - { - int len=indices.size(); - - PoolVector<int>::Write w = arr.write(); - for(int l=0;l<len;l++) { - - w[l]=iarray[ indices[l] ]; - } - } - - arrays[k]=arr; - - } break; - - - } - - - } - - Mesh::PrimitiveType pt=Mesh::PRIMITIVE_TRIANGLES; - - if (part.has("type")) { - String type=part["type"]; - if (type=="LINES") - pt=Mesh::PRIMITIVE_LINES; - else if (type=="POINTS") - pt=Mesh::PRIMITIVE_POINTS; - else if (type=="TRIANGLE_STRIP") - pt=Mesh::PRIMITIVE_TRIANGLE_STRIP; - else if (type=="LINE_STRIP") - pt=Mesh::PRIMITIVE_LINE_STRIP; - } - - if (pt==Mesh::PRIMITIVE_TRIANGLES) { - PoolVector<int> ia=arrays[Mesh::ARRAY_INDEX]; - int len=ia.size(); - { - PoolVector<int>::Write w=ia.write(); - for(int l=0;l<len;l+=3) { - SWAP(w[l+1],w[l+2]); - } - } - arrays[Mesh::ARRAY_INDEX]=ia; - - - } - SurfaceInfo si; - si.array=arrays; - si.primitive=pt; - state.surface_cache[_id(part["id"])]=si; - - } - } -} - - -Error EditorSceneImporterFBXConv::_parse_animations(State& state) { - - AnimationPlayer *ap = memnew( AnimationPlayer ); - - state.scene->add_child(ap); - ap->set_owner(state.scene); - - for(int i=0;i<state.animations.size();i++) { - - Dictionary anim = state.animations[i]; - ERR_CONTINUE(!anim.has("id")); - Ref<Animation> an = memnew( Animation ); - an->set_name(_id(anim["id"])); - - - if (anim.has("bones")) { - - Array bone_tracks = anim["bones"]; - for(int j=0;j<bone_tracks.size();j++) { - Dictionary bone_track=bone_tracks[j]; - String bone = bone_track["boneId"]; - if (!bone_track.has("keyframes")) - continue; - if (!state.bones.has(bone)) - continue; - - Skeleton *sk = state.bones[bone].skeleton; - - if (!sk) - continue; - int bone_idx=sk->find_bone(bone); - if (bone_idx==-1) - continue; - - - - String path = state.scene->get_path_to(sk); - path+=":"+bone; - an->add_track(Animation::TYPE_TRANSFORM); - int tidx = an->get_track_count()-1; - an->track_set_path(tidx,path); - - - Dictionary parent_xform_dict; - Dictionary xform_dict; - - if (state.bones.has(bone)) { - xform_dict=state.bones[bone].node; - } - - - Array parent_keyframes; - if (sk->get_bone_parent(bone_idx)!=-1) { - String parent_name = sk->get_bone_name(sk->get_bone_parent(bone_idx)); - if (state.bones.has(parent_name)) { - parent_xform_dict=state.bones[parent_name].node; - } - - print_line("parent for "+bone+"? "+parent_name+" XFD: "+String(Variant(parent_xform_dict))); - for(int k=0;k<bone_tracks.size();k++) { - Dictionary d = bone_tracks[k]; - if (d["boneId"]==parent_name) { - parent_keyframes=d["keyframes"]; - print_line("found keyframes"); - break; - } - } - - - } - - print_line("BONE XFD "+String(Variant(xform_dict))); - - Array keyframes=bone_track["keyframes"]; - - for(int k=0;k<keyframes.size();k++) { - - Dictionary key=keyframes[k]; - Transform xform=_get_transform_mixed(key,xform_dict); - float time = key["keytime"]; - time=time/1000.0; -#if 0 - if (parent_keyframes.size()) { - //localize - print_line(itos(k)+" localizate for: "+bone); - - float prev_kt=-1; - float kt; - int idx=0; - - for(int l=0;l<parent_keyframes.size();l++) { - - Dictionary d=parent_keyframes[l]; - kt=d["keytime"]; - kt=kt/1000.0; - if (kt>time) - break; - prev_kt=kt; - idx++; - - } - - Transform t; - if (idx==0) { - t=_get_transform_mixed(parent_keyframes[0],parent_xform_dict); - } else if (idx==parent_keyframes.size()){ - t=_get_transform_mixed(parent_keyframes[idx-1],parent_xform_dict); - } else { - t=_get_transform_mixed(parent_keyframes[idx-1],parent_xform_dict); - float d = (time-prev_kt)/(kt-prev_kt); - if (d>0) { - Transform t2=_get_transform_mixed(parent_keyframes[idx],parent_xform_dict); - t=t.interpolate_with(t2,d); - } else { - print_line("exact: "+rtos(kt)); - } - } - - xform = t.affine_inverse() * xform; //localize - } else if (!parent_xform_dict.empty()) { - Transform t = _get_transform(parent_xform_dict); - xform = t.affine_inverse() * xform; //localize - } -#endif - - xform = sk->get_bone_rest(bone_idx).affine_inverse() * xform; - - - Quat q = xform.basis; - q.normalize(); - Vector3 s = xform.basis.get_scale(); - Vector3 l = xform.origin; - - - - an->transform_track_insert_key(tidx,time,l,q,s); - - } - - } - - - } - - - ap->add_animation(_id(anim["id"]),an); - - } - - return OK; -} - -Error EditorSceneImporterFBXConv::_parse_json(State& state, const String &p_path) { - - //not the happiest.... - Vector<uint8_t> data = FileAccess::get_file_as_array(p_path); - ERR_FAIL_COND_V(!data.size(),ERR_FILE_CANT_OPEN); - String str; - bool utferr = str.parse_utf8((const char*)data.ptr(),data.size()); - ERR_FAIL_COND_V(utferr,ERR_PARSE_ERROR); - - Dictionary dict; - Error err = dict.parse_json(str); - str=String(); //free mem immediately - ERR_FAIL_COND_V(err,err); - - if (dict.has("meshes")) - state.meshes=dict["meshes"]; - if (dict.has("materials")) - state.materials=dict["materials"]; - if (dict.has("nodes")) - state.nodes=dict["nodes"]; - if (dict.has("animations")) - state.animations=dict["animations"]; - - - state.scene = memnew( Spatial ); - _detect_bones(state); - _parse_surfaces(state); - _parse_materials(state); - err = _parse_nodes(state,state.nodes,state.scene); - if (err) - return err; - - if (state.import_animations) { - err = _parse_animations(state); - if (err) - return err; - } - - print_line("JSON PARSED O-K!"); - - return OK; -} - -Error EditorSceneImporterFBXConv::_parse_fbx(State& state,const String& p_path) { - - state.base_path=p_path.get_base_dir(); - - if (p_path.to_lower().ends_with("g3dj")) { - return _parse_json(state,p_path.basename()+".g3dj"); - } - - String tool = EDITOR_DEF("fbxconv/path",""); - ERR_FAIL_COND_V( !FileAccess::exists(tool),ERR_UNCONFIGURED); - String wine = EDITOR_DEF("fbxconv/use_wine",""); - - List<String> args; - String path=p_path; - if (wine!="") { - List<String> wpargs; - wpargs.push_back("-w"); - wpargs.push_back(p_path); - String pipe; //winepath to convert to windows path - int wpres; - Error wperr = OS::get_singleton()->execute(wine+"path",wpargs,true,NULL,&pipe,&wpres); - ERR_FAIL_COND_V(wperr!=OK,ERR_CANT_CREATE); - ERR_FAIL_COND_V(wpres!=0,ERR_CANT_CREATE); - path=pipe.strip_edges(); - args.push_back(tool); - tool=wine; - } - - args.push_back("-o"); - args.push_back("G3DJ"); - args.push_back(path); - - int res; - Error err = OS::get_singleton()->execute(tool,args,true,NULL,NULL,&res); - ERR_FAIL_COND_V(err!=OK,ERR_CANT_CREATE); - ERR_FAIL_COND_V(res!=0,ERR_CANT_CREATE); - - return _parse_json(state,p_path.basename()+".g3dj"); - - -} - -Node* EditorSceneImporterFBXConv::import_scene(const String& p_path,uint32_t p_flags,List<String> *r_missing_deps,Error* r_err){ - - State state; - state.scene=NULL; - state.missing_deps=r_missing_deps; - state.import_animations=p_flags&IMPORT_ANIMATION; - Error err = _parse_fbx(state,p_path); - if (err!=OK) { - if (r_err) - *r_err=err; - return NULL; - } - - - return state.scene; -} -Ref<Animation> EditorSceneImporterFBXConv::import_animation(const String& p_path,uint32_t p_flags){ - - - return Ref<Animation>(); -} - - -EditorSceneImporterFBXConv::EditorSceneImporterFBXConv() { - - EDITOR_DEF("fbxconv/path",""); -#ifndef WINDOWS_ENABLED - EDITOR_DEF("fbxconv/use_wine",""); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"fbxconv/use_wine",PROPERTY_HINT_GLOBAL_FILE)); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"fbxconv/path",PROPERTY_HINT_GLOBAL_FILE)); -#else - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"fbxconv/path",PROPERTY_HINT_GLOBAL_FILE,"exe")); -#endif - -} -#endif diff --git a/tools/editor/io_plugins/editor_scene_importer_fbxconv.h b/tools/editor/io_plugins/editor_scene_importer_fbxconv.h deleted file mode 100644 index 1bf96ba0e5..0000000000 --- a/tools/editor/io_plugins/editor_scene_importer_fbxconv.h +++ /dev/null @@ -1,111 +0,0 @@ -/*************************************************************************/ -/* editor_scene_importer_fbxconv.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITOR_SCENE_IMPORTER_FBXCONV_H -#define EDITOR_SCENE_IMPORTER_FBXCONV_H - -#include "tools/editor/io_plugins/editor_scene_import_plugin.h" -#include "scene/3d/skeleton.h" - -#if 0 - -class EditorSceneImporterFBXConv : public EditorSceneImporter { - - GDCLASS(EditorSceneImporterFBXConv,EditorSceneImporter ); - - - struct BoneInfo { - - Skeleton *skeleton; - Transform rest; - int index; - bool has_anim_chan; - bool has_rest; - Dictionary node; - BoneInfo() { - has_rest=false; - skeleton=NULL; - index=-1; - has_anim_chan=false; - } - }; - - struct SurfaceInfo { - Array array; - Mesh::PrimitiveType primitive; - }; - - struct State { - - Node *scene; - Array meshes; - Array materials; - Array nodes; - Array animations; - Map<String,BoneInfo > bones; - Map<String,Skeleton*> skeletons; - Map<String,Ref<Mesh> > mesh_cache; - Map<String,SurfaceInfo> surface_cache; - Map<String,Ref<Material> > material_cache; - Map<String,Ref<Texture> > texture_cache; - List<String> *missing_deps; - String base_path; - bool import_animations; - }; - - String _id(const String& p_id) const; - - Transform _get_transform_mixed(const Dictionary& d, const Dictionary& dbase); - Transform _get_transform(const Dictionary& d); - Color _get_color(const Array& a); - void _detect_bones_in_nodes(State& state,const Array& p_nodes); - void _detect_bones(State& state); - - Error _parse_bones(State& state,const Array &p_bones,Skeleton* p_skeleton); - void _parse_skeletons(const String& p_name,State& state, const Array &p_nodes, Skeleton*p_skeleton=NULL, int p_parent=-1); - - void _add_surface(State& state,Ref<Mesh>& m,const Dictionary &part); - Error _parse_nodes(State& state,const Array &p_nodes,Node* p_base); - Error _parse_animations(State& state); - void _parse_materials(State& state); - void _parse_surfaces(State& state); - Error _parse_json(State& state,const String& p_path); - Error _parse_fbx(State &state, const String &p_path); - -public: - - virtual uint32_t get_import_flags() const; - virtual void get_extensions(List<String> *r_extensions) const; - virtual Node* import_scene(const String& p_path,uint32_t p_flags,List<String> *r_missing_deps=NULL,Error* r_err=NULL); - virtual Ref<Animation> import_animation(const String& p_path,uint32_t p_flags); - - EditorSceneImporterFBXConv(); -}; - -#endif // EDITOR_SCENE_IMPORTER_FBXCONV_H -#endif diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp deleted file mode 100644 index cc8d47c6a9..0000000000 --- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp +++ /dev/null @@ -1,1893 +0,0 @@ -/*************************************************************************/ -/* editor_texture_import_plugin.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 "editor_texture_import_plugin.h" -#if 0 -#include "io/image_loader.h" -#include "tools/editor/editor_node.h" -#include "io/resource_saver.h" -#include "editor_atlas.h" -#include "tools/editor/editor_settings.h" -#include "io/md5.h" -#include "io/marshalls.h" -#include "global_config.h" -#include "scene/gui/check_button.h" -#include "scene/gui/button_group.h" -#include "scene/gui/margin_container.h" -#include "scene/io/resource_format_image.h" - -static const char *flag_names[]={ - ("Streaming Format"), - ("Fix Border Alpha"), - ("Alpha Bit Hint"), - ("Compress Extra (PVRTC2)"), - ("No MipMaps"), - ("Repeat"), - ("Filter (Magnifying)"), - ("Premultiply Alpha"), - ("Convert SRGB->Linear"), - ("Convert NormalMap to XY"), - ("Use Anisotropy"), - NULL -}; - -#if 0 // not used -static const char *flag_short_names[]={ - "Stream", - "FixBorder", - "AlphBit", - "ExtComp", - "NoMipMap", - "Repeat", - "Filter", - "PMAlpha", - "ToLinear", - "ToRG", - "Anisoropic", - NULL -}; -#endif - - -void EditorImportTextureOptions::set_format(EditorTextureImportPlugin::ImageFormat p_format) { - - updating=true; - format->select(p_format); - if (p_format==EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { - quality_vb->show(); - } else { - quality_vb->hide(); - } - - updating=false; - -} - -EditorTextureImportPlugin::ImageFormat EditorImportTextureOptions::get_format() const{ - - return (EditorTextureImportPlugin::ImageFormat)format->get_selected(); - -} - -void EditorImportTextureOptions::set_flags(uint32_t p_flags){ - - updating=true; - for(int i=0;i<items.size();i++) { - - items[i]->set_checked(0,p_flags&(1<<i)); - } - updating=false; - -} - -void EditorImportTextureOptions::set_quality(float p_quality) { - - quality->set_value(p_quality); -} - -float EditorImportTextureOptions::get_quality() const { - - return quality->get_value(); -} - - -uint32_t EditorImportTextureOptions::get_flags() const{ - - uint32_t f=0; - for(int i=0;i<items.size();i++) { - - if (items[i]->is_checked(0)) - f|=(1<<i); - } - - return f; -} - -void EditorImportTextureOptions::_changedp(int p_value) { - - _changed(); -} - -void EditorImportTextureOptions::_changed() { - - if (updating) - return; - if (format->get_selected()==EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { - quality_vb->show(); - } else { - quality_vb->hide(); - } - - emit_signal("changed"); -} - - -void EditorImportTextureOptions::_bind_methods() { - - ClassDB::bind_method("_changed",&EditorImportTextureOptions::_changed); - ClassDB::bind_method("_changedp",&EditorImportTextureOptions::_changedp); - - ADD_SIGNAL(MethodInfo("changed")); -} - - -void EditorImportTextureOptions::_notification(int p_what) { - - if (p_what==NOTIFICATION_ENTER_TREE) { - - flags->connect("item_edited",this,"_changed"); - format->connect("item_selected",this,"_changedp"); - } -} - -void EditorImportTextureOptions::show_2d_notice() { - - //notice_for_2d->show(); -} - -EditorImportTextureOptions::EditorImportTextureOptions() { - - - add_constant_override("separation",3); - updating=false; - format = memnew( OptionButton ); - - format->add_item(TTR("Uncompressed"),EditorTextureImportPlugin::IMAGE_FORMAT_UNCOMPRESSED); - format->add_item(TTR("Compress Lossless (PNG)"),EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS); - format->add_item(TTR("Compress Lossy (WebP)"),EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); - format->add_item(TTR("Compress (VRAM)"),EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM); - - - add_margin_child(TTR("Texture Format"),format); - - quality_vb = memnew( VBoxContainer ); - - HBoxContainer *quality_hb = memnew(HBoxContainer); - HSlider *hs = memnew( HSlider ); - hs->set_h_size_flags(SIZE_EXPAND_FILL); - hs->set_stretch_ratio(0.8); - quality_hb->add_child(hs); - quality_hb->set_h_size_flags(SIZE_EXPAND_FILL); - SpinBox *sb = memnew( SpinBox ); - sb->set_h_size_flags(SIZE_EXPAND_FILL); - sb->set_stretch_ratio(0.2); - quality_hb->add_child(sb); - sb->share(hs); - hs->set_min(0); - hs->set_max(1.0); - hs->set_step(0.01); - hs->set_value(0.7); - quality=hs; - quality_vb->add_margin_child(TTR("Texture Compression Quality (WebP):"),quality_hb); - - add_child(quality_vb); - - flags = memnew( Tree ); - flags->set_hide_root(true); - TreeItem *root = flags->create_item(); - - - - const char ** fname=flag_names; - - while( *fname ) { - - TreeItem*ti = flags->create_item(root); - ti->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); - ti->set_text(0,*fname); - ti->set_editable(0,true); - items.push_back(ti); - fname++; - } - - add_margin_child(TTR("Texture Options"),flags,true); - - -} - -/////////////////////////////////////////////////////////// - - - - -class EditorTextureImportDialog : public ConfirmationDialog { - - GDCLASS(EditorTextureImportDialog,ConfirmationDialog); - - - - HBoxContainer *mode_hb; - CheckBox *mode_check[EditorTextureImportPlugin::MODE_MAX]; - - EditorImportTextureOptions *texture_options; - - EditorTextureImportPlugin::Mode mode; - //EditorNode *editor; - - LineEdit *import_path; - LineEdit *save_path; - EditorFileDialog *file_select; - EditorFileDialog *save_file_select; - EditorDirDialog *save_select; - OptionButton *texture_action; - ConfirmationDialog *error_dialog; - CheckButton *crop_source; - SpinBox *size; - - MarginContainer *size_mc; - Label* size_label; - - Label* source_label; - Label *notice_for_2d; - - EditorTextureImportPlugin *plugin; - - void _mode_changed(int p_mode); - void _choose_files(const Vector<String>& p_path); - void _choose_file(const String& p_path); - void _choose_save_dir(const String& p_path); - void _browse(); - void _browse_target(); - void _import(); - - -protected: - - void _notification(int p_what); - static void _bind_methods(); -public: - - - void setup_multiple_import_3d(const Vector<String>& p_path,const String& p_dest) { - - _mode_changed(EditorTextureImportPlugin::MODE_TEXTURE_3D); - _choose_files(p_path); - _choose_save_dir(p_dest); - } - - void add_sources_and_dest(const Vector<String>& p_path,const String& p_dest) { - - _choose_files(p_path); - _choose_save_dir(p_dest); - } - - Error import(const String& p_from, const String& p_to, const String& p_preset); - void popup_import(const String &p_from=String()); - EditorTextureImportDialog(EditorTextureImportPlugin *p_plugin=NULL); -}; - - -///////////////////////////////////////////////////////// - - - - -void EditorTextureImportDialog::_choose_files(const Vector<String>& p_path) { - - String files; - for(int i=0;i<p_path.size();i++) { - - if (i>0) - files+=","; - files+=p_path[i]; - } - /* - if (p_path.size()) { - String srctex=p_path[0]; - String ipath = EditorImportDB::get_singleton()->find_source_path(srctex); - - if (ipath!="") - save_path->set_text(ipath.get_base_dir()); - }*/ - import_path->set_text(files); - -} - - - -void EditorTextureImportDialog::_choose_file(const String& p_path) { - - - import_path->set_text(p_path); - -} -void EditorTextureImportDialog::_choose_save_dir(const String& p_path) { - - save_path->set_text(p_path); -} - - -void EditorTextureImportDialog::_import() { - - - //ImportMonitorBlock imb; - - Vector<String> files=import_path->get_text().split(","); - - if (!files.size()) { - - error_dialog->set_text(TTR("Please specify some files!")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - } - - String dst_path=save_path->get_text(); - - if (save_path->get_text().strip_edges()=="") { - error_dialog->set_text(TTR("Target path is empty.")); - error_dialog->popup_centered_minsize(); - return; - } - - if (!save_path->get_text().begins_with("res://")) { - error_dialog->set_text(TTR("Target path must be a complete resource path.")); - error_dialog->popup_centered_minsize(); - return; - } - - - if (mode!=EditorTextureImportPlugin::MODE_ATLAS && mode!=EditorTextureImportPlugin::MODE_LARGE && !DirAccess::exists(save_path->get_text())) { - error_dialog->set_text(TTR("Target path must exist.")); - error_dialog->popup_centered_minsize(); - return; - } - - if (mode==EditorTextureImportPlugin::MODE_ATLAS) { //atlas - - if (files.size()==0) { - - error_dialog->set_text(TTR("At least one file needed for Atlas.")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - - } - String dst_file = dst_path; - //dst_file=dst_file.basename()+".tex"; - Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); - //imd->set_editor(); - for(int i=0;i<files.size();i++) { - imd->add_source(EditorImportPlugin::validate_source_path(files[i])); - } - imd->set_option("format",texture_options->get_format()); - imd->set_option("flags",texture_options->get_flags()); - imd->set_option("quality",texture_options->get_quality()); - imd->set_option("atlas",true); - imd->set_option("atlas_size",int(size->get_value())); - imd->set_option("large",false); - imd->set_option("crop",crop_source->is_pressed()); - imd->set_option("mode",mode); - - Error err = plugin->import(dst_file,imd); - if (err) { - - error_dialog->set_text(TTR("Error importing:")+" "+dst_file.get_file()); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - - } - } else if (mode==EditorTextureImportPlugin::MODE_LARGE) { //large - - if (files.size()!=1) { - - error_dialog->set_text(TTR("Only one file is required for large texture.")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - - } - String dst_file = dst_path; - //dst_file=dst_file.basename()+".tex"; - Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); - //imd->set_editor(); - for(int i=0;i<files.size();i++) { - imd->add_source(EditorImportPlugin::validate_source_path(files[i])); - } - imd->set_option("format",texture_options->get_format()); - imd->set_option("flags",texture_options->get_flags()); - imd->set_option("quality",texture_options->get_quality()); - imd->set_option("atlas",false); - imd->set_option("large",true); - imd->set_option("large_cell_size",int(size->get_value())); - imd->set_option("crop",crop_source->is_pressed()); - imd->set_option("mode",mode); - - Error err = plugin->import(dst_file,imd); - if (err) { - - error_dialog->set_text(TTR("Error importing:")+" "+dst_file.get_file()); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - - } - } else { - - - for(int i=0;i<files.size();i++) { - - String dst_file = dst_path.plus_file(files[i].get_file()); - dst_file=dst_file.get_basename()+".tex"; - Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); - //imd->set_editor(); - imd->add_source(EditorImportPlugin::validate_source_path(files[i])); - imd->set_option("format",texture_options->get_format()); - imd->set_option("flags",texture_options->get_flags()); - imd->set_option("quality",texture_options->get_quality()); - imd->set_option("atlas",false); - imd->set_option("large",false); - imd->set_option("mode",mode); - - Error err = plugin->import(dst_file,imd); - if (err) { - - error_dialog->set_text(TTR("Error importing:")+" "+dst_file.get_file()); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - - } - } - } - - hide(); -} - -void EditorTextureImportDialog::_browse() { - - file_select->popup_centered_ratio(); -} - -void EditorTextureImportDialog::_browse_target() { - - if (mode==EditorTextureImportPlugin::MODE_ATLAS || mode==EditorTextureImportPlugin::MODE_LARGE) { - save_file_select->popup_centered_ratio(); - } else { - save_select->popup_centered_ratio(); - } - -} - - -void EditorTextureImportDialog::popup_import(const String& p_from) { - - popup_centered(Size2(600,500)*EDSCALE); - if (p_from!="") { - Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from); - ERR_FAIL_COND(!rimd.is_valid()); - - if (rimd->has_option("mode")) { - //new imported stuff uses this option - _mode_changed(rimd->get_option("mode")); - } else { - //this one is for compatibility, will have to guess it - if (rimd->has_option("atlas") && rimd->get_option("atlas")) { - _mode_changed(EditorTextureImportPlugin::MODE_ATLAS); - } else if (rimd->has_option("large") && rimd->get_option("large")) { - _mode_changed(EditorTextureImportPlugin::MODE_LARGE); - } else { - //guess by usage of mipmaps..? - _mode_changed(EditorTextureImportPlugin::MODE_TEXTURE_2D); - } - - } - - if (mode==EditorTextureImportPlugin::MODE_ATLAS || mode==EditorTextureImportPlugin::MODE_LARGE) - save_path->set_text(p_from); - else - save_path->set_text(p_from.get_base_dir()); - - texture_options->set_format(EditorTextureImportPlugin::ImageFormat(int(rimd->get_option("format")))); - texture_options->set_flags(rimd->get_option("flags")); - texture_options->set_quality(rimd->get_option("quality")); - String src = ""; - for(int i=0;i<rimd->get_source_count();i++) { - if (i>0) - src+=","; - src+=EditorImportPlugin::expand_source_path(rimd->get_source_path(i)); - } - import_path->set_text(src); - } -} - - -void EditorTextureImportDialog::_notification(int p_what) { - - - if (p_what==NOTIFICATION_ENTER_TREE) { - - - List<String> extensions; - ImageLoader::get_recognized_extensions(&extensions); - //ResourceLoader::get_recognized_extensions_for_type("PackedTexture",&extensions); - file_select->clear_filters(); - for(int i=0;i<extensions.size();i++) { - - file_select->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); - } - } -} - -Error EditorTextureImportDialog::import(const String& p_from, const String& p_to, const String& p_preset) { - - - import_path->set_text(p_from); - save_path->set_text(p_to); - _import(); - - return OK; -} - -void EditorTextureImportDialog::_mode_changed(int p_mode) { - - mode = EditorTextureImportPlugin::Mode(p_mode); - - for(int i=0;i<EditorTextureImportPlugin::MODE_MAX;i++) { - mode_check[i]->set_pressed(i==mode); - } - - if (p_mode==EditorTextureImportPlugin::MODE_ATLAS) { - - size_label->set_text(TTR("Max Texture Size:")); - size->set_value(2048); - crop_source->show(); - size_label->show(); - size->show(); - - texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); - texture_options->set_quality(0.7); - texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); - set_title(TTR("Import Textures for Atlas (2D)")); - - } else { - crop_source->hide(); - } - - - if (p_mode==EditorTextureImportPlugin::MODE_LARGE) { - - size_label->set_text(TTR("Cell Size:")); - size->set_value(256); - size_label->show(); - size->show(); - - file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); - save_file_select->add_filter("*.ltex;"+TTR("Large Texture")); - - texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); - texture_options->set_quality(0.7); - texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS); - set_title(TTR("Import Large Textures (2D)")); - source_label->set_text(TTR("Source Texture")); - - } else { - file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); - save_file_select->add_filter("*.tex;"+TTR("Base Atlas Texture")); - source_label->set_text(TTR("Source Texture(s)")); - } - - if (p_mode==EditorTextureImportPlugin::MODE_TEXTURE_2D) { - - size_label->hide(); - size->hide(); - - texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); - texture_options->set_quality(0.7); - texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); - notice_for_2d->show(); - set_title(TTR("Import Textures for 2D")); - - } else { - notice_for_2d->hide(); - } - - if (p_mode==EditorTextureImportPlugin::MODE_TEXTURE_3D) { - - size_label->hide(); - size->hide(); - //texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_); - //texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS); - texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_FILTER|EditorTextureImportPlugin::IMAGE_FLAG_REPEAT); - texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM); - set_title(TTR("Import Textures for 3D")); - } -} - -void EditorTextureImportDialog::_bind_methods() { - - - ClassDB::bind_method("_choose_files",&EditorTextureImportDialog::_choose_files); - ClassDB::bind_method("_choose_file",&EditorTextureImportDialog::_choose_file); - ClassDB::bind_method("_choose_save_dir",&EditorTextureImportDialog::_choose_save_dir); - ClassDB::bind_method("_import",&EditorTextureImportDialog::_import); - ClassDB::bind_method("_browse",&EditorTextureImportDialog::_browse); - ClassDB::bind_method("_browse_target",&EditorTextureImportDialog::_browse_target); - ClassDB::bind_method("_mode_changed",&EditorTextureImportDialog::_mode_changed); - //ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); -} - -EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* p_plugin) { - - - - - - plugin=p_plugin; - set_title(TTR("Import Textures")); - - mode_hb = memnew( HBoxContainer ); - add_child(mode_hb); - //set_child_rect(mode_hb); - - VBoxContainer *vbcg = memnew( VBoxContainer); - - - mode_hb->add_child(vbcg); - mode_hb->add_constant_override("separation",15); - VBoxContainer *bg = memnew( VBoxContainer ); - vbcg->add_margin_child("Import Mode",bg); - - for(int i=0;i<EditorTextureImportPlugin::MODE_MAX;i++) { - String mode_name[EditorTextureImportPlugin::MODE_MAX]={ - TTR("2D Texture"), - TTR("3D Texture"), - TTR("Atlas Texture"), - TTR("Large Texture") - }; - - - mode_check[i]=memnew(CheckBox); - bg->add_child(mode_check[i]); - mode_check[i]->set_text(mode_name[i]); - mode_check[i]->connect("pressed",this,"_mode_changed",varray(i)); - } - - VBoxContainer *vbc = memnew(VBoxContainer); - mode_hb->add_child(vbc); - vbc->set_h_size_flags(SIZE_EXPAND_FILL); - vbc->add_constant_override("separation",4); - - notice_for_2d = memnew( Label ); - notice_for_2d->set_text(TTR("NOTICE: Importing 2D textures is not mandatory. Just copy png/jpg files to the project.")); - //notice_for_2d->set_custom_minimum_size(Size2(0,50)); - notice_for_2d->set_autowrap(true); - notice_for_2d->hide(); - vbcg->add_child(notice_for_2d); - notice_for_2d->set_v_size_flags(SIZE_EXPAND_FILL); - notice_for_2d->set_valign(Label::VALIGN_BOTTOM); - - VBoxContainer *source_vb=memnew(VBoxContainer); - MarginContainer *source_mc = vbc->add_margin_child(TTR("Source Texture(s):"),source_vb); - - source_label = vbc->get_child(source_mc->get_index()-1)->cast_to<Label>(); - - HBoxContainer *hbc = memnew( HBoxContainer ); - source_vb->add_child(hbc); - - import_path = memnew( LineEdit ); - import_path->set_h_size_flags(SIZE_EXPAND_FILL); - hbc->add_child(import_path); - crop_source = memnew( CheckButton ); - crop_source->set_pressed(true); - source_vb->add_child(crop_source); - crop_source->set_text(TTR("Crop empty space.")); - - - Button * import_choose = memnew( Button ); - import_choose->set_text(" .. "); - hbc->add_child(import_choose); - - import_choose->connect("pressed", this,"_browse"); - - hbc = memnew( HBoxContainer ); - vbc->add_margin_child(TTR("Target Path:"),hbc); - - size = memnew( SpinBox ); - size->set_min(128); - size->set_max(16384); - - - size->set_value(256); - size_mc=vbc->add_margin_child(TTR("Cell Size:"),size); - size_label=vbc->get_child(size_mc->get_index()-1)->cast_to<Label>(); - - - save_path = memnew( LineEdit ); - save_path->set_h_size_flags(SIZE_EXPAND_FILL); - hbc->add_child(save_path); - - Button * save_choose = memnew( Button ); - save_choose->set_text(" .. "); - hbc->add_child(save_choose); - - save_choose->connect("pressed", this,"_browse_target"); - - file_select = memnew(EditorFileDialog); - file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - add_child(file_select); - - file_select->connect("files_selected", this,"_choose_files"); - file_select->connect("file_selected", this,"_choose_file"); - - save_file_select = memnew(EditorFileDialog); - save_file_select->set_access(EditorFileDialog::ACCESS_RESOURCES); - add_child(save_file_select); - save_file_select->set_mode(EditorFileDialog::MODE_SAVE_FILE); - save_file_select->clear_filters(); - - save_file_select->connect("file_selected", this,"_choose_save_dir"); - - save_select = memnew( EditorDirDialog ); - add_child(save_select); - - //save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); - save_select->connect("dir_selected", this,"_choose_save_dir"); - - get_ok()->connect("pressed", this,"_import"); - get_ok()->set_text(TTR("Import")); - - //move stuff up - /* - for(int i=0;i<4;i++) - vbc->move_child( vbc->get_child( vbc->get_child_count() -1), 0); - */ - - error_dialog = memnew ( ConfirmationDialog ); - add_child(error_dialog); - error_dialog->get_ok()->set_text(TTR("Accept")); - //error_dialog->get_cancel()->hide(); - - set_hide_on_ok(false); - - texture_options = memnew( EditorImportTextureOptions ); - vbc->add_child(texture_options); - texture_options->set_v_size_flags(SIZE_EXPAND_FILL); - - _mode_changed(EditorTextureImportPlugin::MODE_TEXTURE_3D); - - - //GLOBAL_DEF("import/shared_textures","res://"); - //Globals::get_singleton()->set_custom_property_info("import/shared_textures",PropertyInfo(Variant::STRING,"import/shared_textures",PROPERTY_HINT_DIR)); - - -} - - - -/////////////////////////////////////////////////////////// - - -String EditorTextureImportPlugin::get_name() const { - - return "texture"; -#if 0 //old names, kept for compatibility reference - switch(mode) { - case MODE_TEXTURE_2D: { - - return "texture_2d"; - } break; - case MODE_TEXTURE_3D: { - - return "texture_3d"; - - } break; - case MODE_ATLAS: { - - return "texture_atlas"; - } break; - case MODE_LARGE: { - - return "texture_large"; - } break; - - } - - - return ""; -#endif -} - -String EditorTextureImportPlugin::get_visible_name() const { - - return TTR("Texture"); - -} -void EditorTextureImportPlugin::import_dialog(const String& p_from) { - - dialog->popup_import(p_from); -} - -void EditorTextureImportPlugin::compress_image(EditorExportPlatform::ImageCompression p_mode,Image& image,bool p_smaller) { - - - switch(p_mode) { - case EditorExportPlatform::IMAGE_COMPRESSION_NONE: { - - //do absolutely nothing - - } break; - case EditorExportPlatform::IMAGE_COMPRESSION_BC: { - - - // for maximum compatibility, BC shall always use mipmaps and be PO2 - image.resize_to_po2(); - if (!image.has_mipmaps()) - image.generate_mipmaps(); - - image.compress(Image::COMPRESS_S3TC); - /* - if (has_alpha) { - - if (flags&IMAGE_FLAG_ALPHA_BIT) { - image.convert(Image::FORMAT_DXT5); - } else { - image.convert(Image::FORMAT_DXT3); - } - } else { - - image.convert(Image::FORMAT_DXT1); - }*/ - - - } break; - case EditorExportPlatform::IMAGE_COMPRESSION_PVRTC: - case EditorExportPlatform::IMAGE_COMPRESSION_PVRTC_SQUARE: { - - // for maximum compatibility (hi apple!), PVRT shall always - // use mipmaps, be PO2 and square - - if (!image.has_mipmaps()) - image.generate_mipmaps(); - image.resize_to_po2(true); - - if (p_smaller) { - - image.compress(Image::COMPRESS_PVRTC2); - //image.convert(has_alpha ? Image::FORMAT_PVRTC2A : Image::FORMAT_PVRTC2); - } else { - image.compress(Image::COMPRESS_PVRTC4); - //image.convert(has_alpha ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4); - } - - } break; - case EditorExportPlatform::IMAGE_COMPRESSION_ETC1: { - - image.resize_to_po2(); //square or not? - if (!image.has_mipmaps()) - image.generate_mipmaps(); - if (!image.detect_alpha()) { - //ETC1 is only opaque - image.compress(Image::COMPRESS_ETC); - } - - } break; - case EditorExportPlatform::IMAGE_COMPRESSION_ETC2: { - - - } break; - } - - -} - -Error EditorTextureImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from) { - - - return import2(p_path,p_from,EditorExportPlatform::IMAGE_COMPRESSION_BC,false); -} - - -Error EditorTextureImportPlugin::_process_texture_data(Ref<ImageTexture> &texture,int format, float quality,int flags,EditorExportPlatform::ImageCompression p_compr,int tex_flags,float shrink) { - - - if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS || format==IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { - - Image image=texture->get_data(); - ERR_FAIL_COND_V(image.empty(),ERR_INVALID_DATA); - - bool has_alpha=image.detect_alpha(); - if (!has_alpha && image.get_format()==Image::FORMAT_RGBA8) { - - image.convert(Image::FORMAT_RGB8); - - } - - if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_FIX_BORDER_ALPHA) { - - image.fix_alpha_edges(); - } - - if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_PREMULT_ALPHA) { - - image.premultiply_alpha(); - } - - if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) { - image.normalmap_to_xy(); - } - - /* - if ((image.get_format()==Image::FORMAT_RGB8 || image.get_format()==Image::FORMAT_RGBA8) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { - - image.srgb_to_linear(); - } - */ - - if (shrink>1) { - - int orig_w=image.get_width(); - int orig_h=image.get_height(); - image.resize(orig_w/shrink,orig_h/shrink,Image::INTERPOLATE_CUBIC); - texture->create_from_image(image,tex_flags); - texture->set_size_override(Size2(orig_w,orig_h)); - - - } else { - - texture->create_from_image(image,tex_flags); - } - - - if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS) { - texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSLESS); - } else { - texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY); - } - - - - texture->set_lossy_storage_quality(quality); - - - } else { - - - Image image=texture->get_data(); - ERR_FAIL_COND_V(image.empty(),ERR_INVALID_DATA); - - - bool has_alpha=image.detect_alpha(); - if (!has_alpha && image.get_format()==Image::FORMAT_RGBA8) { - - image.convert(Image::FORMAT_RGB8); - - } - - if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_FIX_BORDER_ALPHA) { - - image.fix_alpha_edges(); - } - - if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_PREMULT_ALPHA) { - - image.premultiply_alpha(); - } - - if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) { - image.normalmap_to_xy(); - } - - /* - if ((image.get_format()==Image::FORMAT_RGB8 || image.get_format()==Image::FORMAT_RGBA8) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { - - print_line("CONVERT BECAUSE: "+itos(flags)); - image.srgb_to_linear(); - } - */ - - int orig_w=image.get_width(); - int orig_h=image.get_height(); - - if (shrink>1) { - image.resize(orig_w/shrink,orig_h/shrink,Image::INTERPOLATE_CUBIC); - texture->create_from_image(image,tex_flags); - texture->set_size_override(Size2(orig_w,orig_h)); - } - - if (!(flags&IMAGE_FLAG_NO_MIPMAPS)) { - image.generate_mipmaps(); - - } - - if (format!=IMAGE_FORMAT_UNCOMPRESSED) { - - compress_image(p_compr,image,flags&IMAGE_FLAG_COMPRESS_EXTRA); - } - - - texture->create_from_image(image,tex_flags); - - - if (shrink>1 || (format!=IMAGE_FORMAT_UNCOMPRESSED && (image.get_width()!=orig_w || image.get_height()!=orig_h))) { - texture->set_size_override(Size2(orig_w,orig_h)); - } - - //uint32_t save_flags=ResourceSaver::FLAG_COMPRESS; - } - - return OK; -} - - -Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<ResourceImportMetadata>& p_from,EditorExportPlatform::ImageCompression p_compr, bool p_external){ - - - - ERR_FAIL_COND_V(p_from->get_source_count()==0,ERR_INVALID_PARAMETER); - - Ref<ResourceImportMetadata> from=p_from; - - Ref<ImageTexture> texture; - Vector<Ref<AtlasTexture> > atlases; - bool atlas = from->get_option("atlas"); - bool large = from->get_option("large"); - - int flags=from->get_option("flags"); - int format=from->get_option("format"); - float quality=from->get_option("quality"); - - uint32_t tex_flags=0; - - if (flags&EditorTextureImportPlugin::IMAGE_FLAG_REPEAT) - tex_flags|=Texture::FLAG_REPEAT; - if (flags&EditorTextureImportPlugin::IMAGE_FLAG_FILTER) - tex_flags|=Texture::FLAG_FILTER; - if (!(flags&EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS)) - tex_flags|=Texture::FLAG_MIPMAPS; - if (flags&EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_TO_LINEAR) - tex_flags|=Texture::FLAG_CONVERT_TO_LINEAR; - if (flags&EditorTextureImportPlugin::IMAGE_FLAG_USE_ANISOTROPY) - tex_flags|=Texture::FLAG_ANISOTROPIC_FILTER; - - print_line("path: "+p_path+" flags: "+itos(tex_flags)); - float shrink=1; - if (from->has_option("shrink")) - shrink=from->get_option("shrink"); - - if (large) { - ERR_FAIL_COND_V(from->get_source_count()!=1,ERR_INVALID_PARAMETER); - - String src_path = EditorImportPlugin::expand_source_path(from->get_source_path(0)); - - - int cell_size=from->get_option("large_cell_size"); - ERR_FAIL_COND_V(cell_size<128 || cell_size>16384,ERR_CANT_OPEN); - - EditorProgress pg("ltex",TTR("Import Large Texture"),3); - - pg.step(TTR("Load Source Image"),0); - Image img; - Error err = ImageLoader::load_image(src_path,&img); - if (err) { - return err; - } - - pg.step(TTR("Slicing"),1); - - Map<Vector2,Image> pieces; - for(int i=0;i<img.get_width();i+=cell_size) { - int w = MIN(img.get_width()-i,cell_size); - for(int j=0;j<img.get_height();j+=cell_size) { - int h = MIN(img.get_height()-j,cell_size); - - Image piece(w,h,0,img.get_format()); - piece.blit_rect(img,Rect2(i,j,w,h),Point2(0,0)); - if (!piece.is_invisible()) { - pieces[Vector2(i,j)]=piece; - //print_line("ADDING PIECE AT "+Vector2(i,j)); - } - } - } - - Ref<LargeTexture> existing; - if (ResourceCache::has(p_path)) { - existing = ResourceCache::get(p_path); - } - - if (existing.is_valid()) { - existing->clear(); - } else { - existing = Ref<LargeTexture>(memnew( LargeTexture )); - } - - existing->set_size(Size2(img.get_width(),img.get_height())); - pg.step(TTR("Inserting"),2); - - for (Map<Vector2,Image>::Element *E=pieces.front();E;E=E->next()) { - - Ref<ImageTexture> imgtex = Ref<ImageTexture>( memnew( ImageTexture ) ); - imgtex->create_from_image(E->get(),tex_flags); - _process_texture_data(imgtex,format,quality,flags,p_compr,tex_flags,shrink); - existing->add_piece(E->key(),imgtex); - } - - if (!p_external) { - from->set_editor(get_name()); - from->set_source_md5(0,FileAccess::get_md5(src_path)); - existing->set_path(p_path); - existing->set_import_metadata(from); - } - pg.step(TTR("Saving"),3); - - err = ResourceSaver::save(p_path,existing); - if (err!=OK) { - EditorNode::add_io_error(TTR("Couldn't save large texture:")+" "+p_path); - return err; - } - - return OK; - - - } else if (atlas) { - - //prepare atlas! - Vector< Image > sources; - Vector< Image > tsources; - bool alpha=false; - bool crop = from->get_option("crop"); - - EditorProgress ep("make_atlas",TTR("Build Atlas For:")+" "+p_path.get_file(),from->get_source_count()+3); - - print_line("sources: "+itos(from->get_source_count())); - - for(int i=0;i<from->get_source_count();i++) { - - String path = EditorImportPlugin::expand_source_path(from->get_source_path(i)); - String md5 = FileAccess::get_md5(path); - from->set_source_md5(i,FileAccess::get_md5(path)); - ep.step(TTR("Loading Image:")+" "+path,i); - print_line("source path: "+path+" md5 "+md5); - Image src; - Error err = ImageLoader::load_image(path,&src); - if (err) { - EditorNode::add_io_error(TTR("Couldn't load image:")+" "+path); - return err; - } - - if (src.detect_alpha()) - alpha=true; - - tsources.push_back(src); - } - ep.step(TTR("Converting Images"),sources.size()); - - - Map<uint64_t,int> source_md5; - Map<int,List<int> > source_map; - - for(int i=0;i<tsources.size();i++) { - - Image src = tsources[i]; - - if (alpha) { - src.convert(Image::FORMAT_RGBA8); - } else { - src.convert(Image::FORMAT_RGB8); - } - - PoolVector<uint8_t> data = src.get_data(); - MD5_CTX md5; - PoolVector<uint8_t>::Read r=data.read(); - MD5Init(&md5); - int len=data.size(); - for(int j=0;j<len;j++) { - uint8_t b = r[j]; - b>>=2; //to aid in comparing - MD5Update(&md5,(unsigned char*)&b,1); - } - MD5Final(&md5); - uint64_t *cmp = (uint64_t*)md5.digest; //less bits, but still useful for this - - tsources[i]=Image(); //clear - - if (source_md5.has(*cmp)) { - int sidx=source_md5[*cmp]; - source_map[sidx].push_back(i); - print_line("REUSING "+from->get_source_path(i)); - - } else { - int sidx=sources.size(); - source_md5[*cmp]=sidx; - sources.push_back(src); - List<int> sm; - sm.push_back(i); - source_map[sidx]=sm; - - } - - - } - - //texturepacker is not really good for optimizing, so.. - //will at some point likely replace with my own - //first, will find the nearest to a square packing - int border=1; - - Vector<Size2i> src_sizes; - Vector<Rect2> crops; - - ep.step(TTR("Cropping Images"),sources.size()+1); - - for(int j=0;j<sources.size();j++) { - - Size2i s; - if (crop) { - Rect2 crop = sources[j].get_used_rect(); - print_line("CROP: "+crop); - s=crop.size; - crops.push_back(crop); - } else { - - s=Size2i(sources[j].get_width(),sources[j].get_height()); - } - s+=Size2i(border*2,border*2); - src_sizes.push_back(s); //add a line to constraint width - } - - Vector<Point2i> dst_positions; - Size2i dst_size; - EditorAtlas::fit(src_sizes,dst_positions,dst_size); - - print_line("size that worked: "+itos(dst_size.width)+","+itos(dst_size.height)); - - ep.step(TTR("Blitting Images"),sources.size()+2); - - bool blit_to_po2=tex_flags&Texture::FLAG_MIPMAPS; - int atlas_w=dst_size.width; - int atlas_h=dst_size.height; - if (blit_to_po2) { - atlas_w=nearest_power_of_2(dst_size.width); - atlas_h=nearest_power_of_2(dst_size.height); - } - Image atlas; - atlas.create(atlas_w,atlas_h,0,alpha?Image::FORMAT_RGBA8:Image::FORMAT_RGB8); - - - atlases.resize(from->get_source_count()); - - for(int i=0;i<sources.size();i++) { - - int x=dst_positions[i].x; - int y=dst_positions[i].y; - - Size2 sz = Size2(sources[i].get_width(),sources[i].get_height()); - - Rect2 region; - Rect2 margin; - - if (crop && sz!=crops[i].size) { - Rect2 rect = crops[i]; - rect.size=sz-rect.size; - region=Rect2(x+border,y+border,crops[i].size.width,crops[i].size.height); - margin=rect; - atlas.blit_rect(sources[i],crops[i],Point2(x+border,y+border)); - } else { - region=Rect2(x+border,y+border,sz.x,sz.y); - atlas.blit_rect(sources[i],Rect2(0,0,sources[i].get_width(),sources[i].get_height()),Point2(x+border,y+border)); - } - - ERR_CONTINUE( !source_map.has(i) ); - for (List<int>::Element *E=source_map[i].front();E;E=E->next()) { - - String apath; - String spath = from->get_source_path(E->get()).get_file(); - - if (p_external) { - apath = p_path.get_base_dir().plus_file(spath.get_basename()+"."+from->get_source_path(E->get()).md5_text()+".atex"); - } else { - apath = p_path.get_base_dir().plus_file(spath.get_basename()+".atex"); - } - - Ref<AtlasTexture> at; - - if (ResourceCache::has(apath)) { - - at = Ref<AtlasTexture>( ResourceCache::get(apath)->cast_to<AtlasTexture>() ); - } else { - - at = Ref<AtlasTexture>( memnew( AtlasTexture ) ); - - } - at->set_region(region); - at->set_margin(margin); - at->set_path(apath); - atlases[E->get()]=at; - - } - } - if (ResourceCache::has(p_path)) { - texture = Ref<ImageTexture> ( ResourceCache::get(p_path)->cast_to<ImageTexture>() ); - } else { - texture = Ref<ImageTexture>( memnew( ImageTexture ) ); - } - texture->create_from_image(atlas,tex_flags); - - } else { - ERR_FAIL_COND_V(from->get_source_count()!=1,ERR_INVALID_PARAMETER); - - String src_path = EditorImportPlugin::expand_source_path(from->get_source_path(0)); - - if (ResourceCache::has(p_path)) { - Resource *r = ResourceCache::get(p_path); - - texture = Ref<ImageTexture> ( r->cast_to<ImageTexture>() ); - - Image img; - Error err = img.load(src_path); - ERR_FAIL_COND_V(err!=OK,ERR_CANT_OPEN); - texture->create_from_image(img); - } else { - texture=ResourceLoader::load(src_path,"ImageTexture"); - } - - ERR_FAIL_COND_V(texture.is_null(),ERR_CANT_OPEN); - if (!p_external) - from->set_source_md5(0,FileAccess::get_md5(src_path)); - - } - - - - if (!p_external) { - from->set_editor(get_name()); - texture->set_path(p_path); - texture->set_import_metadata(from); - } - - if (atlas) { - - if (p_external) { - //used by exporter - Array rects; - for(int i=0;i<atlases.size();i++) { - rects.push_back(atlases[i]->get_region()); - rects.push_back(atlases[i]->get_margin()); - } - from->set_option("rects",rects); - - } else { - //used by importer - for(int i=0;i<atlases.size();i++) { - String apath = atlases[i]->get_path(); - atlases[i]->set_atlas(texture); - Error err = ResourceSaver::save(apath,atlases[i]); - if (err) { - EditorNode::add_io_error(TTR("Couldn't save atlas image:")+" "+apath); - return err; - } - //from->set_source_md5(i,FileAccess::get_md5(apath)); - } - } - } - - bool compress=false; -#if 1 - - _process_texture_data(texture,format,quality,flags,p_compr,tex_flags,shrink); -#else - if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS || format==IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { - - Image image=texture->get_data(); - ERR_FAIL_COND_V(image.empty(),ERR_INVALID_DATA); - - bool has_alpha=image.detect_alpha(); - if (!has_alpha && image.get_format()==Image::FORMAT_RGBA8) { - - image.convert(Image::FORMAT_RGB8); - - } - - if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_FIX_BORDER_ALPHA) { - - image.fix_alpha_edges(); - } - - if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_PREMULT_ALPHA) { - - image.premultiply_alpha(); - } - - if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) { - image.normalmap_to_xy(); - } - - /* - if ((image.get_format()==Image::FORMAT_RGB8 || image.get_format()==Image::FORMAT_RGBA8) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { - - image.srgb_to_linear(); - } - */ - - if (shrink>1) { - - int orig_w=image.get_width(); - int orig_h=image.get_height(); - image.resize(orig_w/shrink,orig_h/shrink); - texture->create_from_image(image,tex_flags); - texture->set_size_override(Size2(orig_w,orig_h)); - - - } else { - - texture->create_from_image(image,tex_flags); - } - - - if (format==IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS) { - texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSLESS); - } else { - texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY); - } - - - - texture->set_lossy_storage_quality(quality); - - - } else { - - - Image image=texture->get_data(); - ERR_FAIL_COND_V(image.empty(),ERR_INVALID_DATA); - - - bool has_alpha=image.detect_alpha(); - if (!has_alpha && image.get_format()==Image::FORMAT_RGBA8) { - - image.convert(Image::FORMAT_RGB8); - - } - - if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_FIX_BORDER_ALPHA) { - - image.fix_alpha_edges(); - } - - if (image.get_format()==Image::FORMAT_RGBA8 && flags&IMAGE_FLAG_PREMULT_ALPHA) { - - image.premultiply_alpha(); - } - - if (flags&IMAGE_FLAG_CONVERT_NORMAL_TO_XY) { - image.normalmap_to_xy(); - } - - /* - if ((image.get_format()==Image::FORMAT_RGB8 || image.get_format()==Image::FORMAT_RGBA8) && flags&IMAGE_FLAG_CONVERT_TO_LINEAR) { - - print_line("CONVERT BECAUSE: "+itos(flags)); - image.srgb_to_linear(); - } - */ - - int orig_w=image.get_width(); - int orig_h=image.get_height(); - - if (shrink>1) { - image.resize(orig_w/shrink,orig_h/shrink); - texture->create_from_image(image,tex_flags); - texture->set_size_override(Size2(orig_w,orig_h)); - } - - if (!(flags&IMAGE_FLAG_NO_MIPMAPS)) { - image.generate_mipmaps(); - - } - - if (format!=IMAGE_FORMAT_UNCOMPRESSED) { - - compress_image(p_compr,image,flags&IMAGE_FLAG_COMPRESS_EXTRA); - } - - - texture->create_from_image(image,tex_flags); - - - if (shrink>1 || (format!=IMAGE_FORMAT_UNCOMPRESSED && (image.get_width()!=orig_w || image.get_height()!=orig_h))) { - texture->set_size_override(Size2(orig_w,orig_h)); - } - - compress=true; - - - } -#endif - uint32_t save_flags=0; - if (compress) - save_flags=ResourceSaver::FLAG_COMPRESS; - - Error err = ResourceSaver::save(p_path,texture,save_flags); - if (err!=OK) { - EditorNode::add_io_error(TTR("Couldn't save converted texture:")+" "+p_path); - return err; - } - - return OK; -} - -Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, const Ref<EditorExportPlatform> &p_platform) { - - - Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); - - if (rimd.is_null()) { - - StringName group = EditorImportExport::get_singleton()->image_get_export_group(p_path); - - if (group!=StringName()) { - //handled by export group - rimd = Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) ); - - int group_format=0; - float group_lossy_quality=EditorImportExport::get_singleton()->image_export_group_get_lossy_quality(group); - int group_shrink=EditorImportExport::get_singleton()->image_export_group_get_shrink(group); - group_shrink*=EditorImportExport::get_singleton()->get_export_image_shrink(); - - switch(EditorImportExport::get_singleton()->image_export_group_get_image_action(group)) { - case EditorImportExport::IMAGE_ACTION_NONE: { - - switch(EditorImportExport::get_singleton()->get_export_image_action()) { - case EditorImportExport::IMAGE_ACTION_NONE: { - - group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS; //? - - } break; //use default - case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: { - group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY; - } break; //use default - case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: { - group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM; - } break; //use default - } - - group_lossy_quality=EditorImportExport::get_singleton()->get_export_image_quality(); - - } break; //use default - case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: { - group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY; - } break; //use default - case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: { - group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM; - } break; //use default - case EditorImportExport::IMAGE_ACTION_KEEP: { - return Vector<uint8_t>(); - } break; //use default - } - - String validated_path=EditorImportPlugin::validate_source_path(p_path); - - int flags=texture_flags_to_export_flags(ResourceFormatLoaderImage::load_image_flags(validated_path)); - flags|=IMAGE_FLAG_FIX_BORDER_ALPHA; - - print_line("group format"+itos(group_format)); - rimd->set_option("format",group_format); - rimd->set_option("flags",flags); - rimd->set_option("quality",group_lossy_quality); - rimd->set_option("atlas",false); - rimd->set_option("shrink",group_shrink); - rimd->add_source(validated_path,FileAccess::get_md5(p_path)); - - } else if (EditorImportExport::get_singleton()->get_image_formats().has(p_path.get_extension().to_lower()) && EditorImportExport::get_singleton()->get_export_image_action()!=EditorImportExport::IMAGE_ACTION_NONE) { - //handled by general image export settings - - rimd = Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) ); - - switch(EditorImportExport::get_singleton()->get_export_image_action()) { - case EditorImportExport::IMAGE_ACTION_COMPRESS_DISK: rimd->set_option("format",IMAGE_FORMAT_COMPRESS_DISK_LOSSY); break; - case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: rimd->set_option("format",IMAGE_FORMAT_COMPRESS_RAM); break; - } - - String validated_path=EditorImportPlugin::validate_source_path(p_path); - - int flags=texture_flags_to_export_flags(ResourceFormatLoaderImage::load_image_flags(validated_path)); - flags|=IMAGE_FLAG_FIX_BORDER_ALPHA; - - rimd->set_option("shrink",EditorImportExport::get_singleton()->get_export_image_shrink()); - rimd->set_option("flags",flags); - rimd->set_option("quality",EditorImportExport::get_singleton()->get_export_image_quality()); - rimd->set_option("atlas",false); - rimd->add_source(validated_path,FileAccess::get_md5(p_path)); - - } else { - return Vector<uint8_t>(); - } - } - - int fmt = rimd->get_option("format"); - - if (fmt!=IMAGE_FORMAT_COMPRESS_RAM && fmt!=IMAGE_FORMAT_COMPRESS_DISK_LOSSY) { - print_line("no compress ram or lossy"); - return Vector<uint8_t>(); //pointless to do anything, since no need to reconvert - } - - uint32_t flags = rimd->get_option("flags"); - uint8_t shrink = rimd->has_option("shrink") ? rimd->get_option("shrink"): Variant(1); - uint8_t format = rimd->get_option("format"); - uint8_t comp = (format==EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM)?uint8_t(p_platform->get_image_compression()):uint8_t(255); - - MD5_CTX ctx; - uint8_t f4[4]; - encode_uint32(flags,&f4[0]); - MD5Init(&ctx); - String gp = GlobalConfig::get_singleton()->globalize_path(p_path); - CharString cs = gp.utf8(); - MD5Update(&ctx,(unsigned char*)cs.get_data(),cs.length()); - MD5Update(&ctx,f4,4); - MD5Update(&ctx,&format,1); - MD5Update(&ctx,&comp,1); - MD5Update(&ctx,&shrink,1); - MD5Final(&ctx); - - - - uint64_t sd=0; - String smd5; - - String md5 = String::md5(ctx.digest); - print_line(p_path+" MD5: "+md5+" FLAGS: "+itos(flags)); - - String tmp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/"); - - bool valid=false; - { - //if existing, make sure it's valid - FileAccessRef f = FileAccess::open(tmp_path+"imgexp-"+md5+".txt",FileAccess::READ); - if (f) { - - uint64_t d = f->get_line().strip_edges().to_int64(); - sd = FileAccess::get_modified_time(p_path); - - if (d==sd) { - valid=true; - } else { - String cmd5 = f->get_line().strip_edges(); - smd5 = FileAccess::get_md5(p_path); - if (cmd5==smd5) { - valid=true; - } - } - - - } - } - - if (!valid) { - //cache failed, convert - Error err = import2(tmp_path+"imgexp-"+md5+".tex",rimd,p_platform->get_image_compression(),true); - ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>()); - FileAccessRef f = FileAccess::open(tmp_path+"imgexp-"+md5+".txt",FileAccess::WRITE); - - if (sd==0) - sd = FileAccess::get_modified_time(p_path); - if (smd5==String()) - smd5 = FileAccess::get_md5(p_path); - - f->store_line(String::num(sd)); - f->store_line(smd5); - f->store_line(gp); //source path for reference - } - - - Vector<uint8_t> ret; - FileAccessRef f = FileAccess::open(tmp_path+"imgexp-"+md5+".tex",FileAccess::READ); - ERR_FAIL_COND_V(!f,ret); - - ret.resize(f->get_len()); - f->get_buffer(ret.ptr(),ret.size()); - - return ret; -} - -uint32_t EditorTextureImportPlugin::texture_flags_to_export_flags(uint32_t p_tex_flags) const { - - uint32_t flags=0; - - if (!(p_tex_flags&Texture::FLAG_MIPMAPS)) { - flags|=IMAGE_FLAG_NO_MIPMAPS; - } - if (p_tex_flags&Texture::FLAG_REPEAT) { - flags|=IMAGE_FLAG_REPEAT; - } - if (p_tex_flags&Texture::FLAG_FILTER) { - flags|=IMAGE_FLAG_FILTER; - } - if (p_tex_flags&Texture::FLAG_ANISOTROPIC_FILTER) { - flags|=IMAGE_FLAG_USE_ANISOTROPY; - } - if (p_tex_flags&Texture::FLAG_CONVERT_TO_LINEAR) { - flags|=IMAGE_FLAG_CONVERT_TO_LINEAR; - } - /* // no correspondence yet - if (p_tex_flags&Texture::TEXTURE_FLAG_MIRRORED_REPEAT) { - flags|=; - }*/ - - return flags; -} - -void EditorTextureImportPlugin::import_from_drop(const Vector<String>& p_drop,const String& p_dest_path) { - - Vector<String> valid; - - List<String> valid_extensions; - ImageLoader::get_recognized_extensions(&valid_extensions); - for(int i=0;i<p_drop.size();i++) { - - String extension=p_drop[i].get_extension().to_lower(); - - for (List<String>::Element *E=valid_extensions.front();E;E=E->next()) { - - if (E->get()==extension) { - valid.push_back(p_drop[i]); - break; - } - } - } - - if (valid.size()) { - dialog->popup_import(); - dialog->setup_multiple_import_3d(valid,p_dest_path); - } -} - -void EditorTextureImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { - - Vector<String> valid; - - - for(int i=0;i<p_list.size();i++) { - - Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_list[i]); - String type = rimd->get_editor(); - if (type=="texture" || type.begins_with("texture_")) { - - if ((rimd->has_option("atlas") && rimd->get_option("atlas")) || (rimd->has_option("large") && rimd->get_option("large"))) { - continue; - } - - valid.push_back(p_list[i]); - } - } - - if (valid.size()) { - - dialog->popup_import(valid[0]); - - Vector<String> sources; - for(int i=0;i<valid.size();i++) { - int idx; - EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->find_file(valid[i],&idx); - if (efsd) { - for(int j=0;j<efsd->get_source_count(idx);j++) { - String file = expand_source_path(efsd->get_source_file(idx,j)); - if (sources.find(file)==-1) { - sources.push_back(file); - } - - } - } - } - - if (sources.size()) { - - dialog->add_sources_and_dest(sources,valid[0].get_base_dir()); - } - } -} - -bool EditorTextureImportPlugin::can_reimport_multiple_files() const { - - return true; - -} - - - -EditorTextureImportPlugin *EditorTextureImportPlugin::singleton=NULL; - -EditorTextureImportPlugin::EditorTextureImportPlugin(EditorNode *p_editor) { - - singleton=this; - editor=p_editor; - dialog = memnew( EditorTextureImportDialog(this) ); - editor->get_gui_base()->add_child(dialog); - -} - -//////////////////////////// - - - Vector<uint8_t> EditorTextureExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) { - - Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); - - if (rimd.is_valid()) { - - if (rimd->get_editor()!="") { - int compression = rimd->get_option("format"); - if (compression!=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM) - return Vector<uint8_t>(); //only useful for RAM compression to reconvert - Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name(rimd->get_editor()); - if (pl.is_valid()) { - Vector<uint8_t> ce = pl->custom_export(p_path,p_platform); - if (ce.size()) - return ce; - } - } - } else if (EditorImportExport::get_singleton()->image_get_export_group(p_path)) { - - - Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name("texture"); - if (pl.is_valid()) { - Vector<uint8_t> ce = pl->custom_export(p_path,p_platform); - if (ce.size()) { - p_path=p_path.get_basename()+".converted.tex"; - return ce; - } - } - - } else if (EditorImportExport::get_singleton()->get_export_image_action()!=EditorImportExport::IMAGE_ACTION_NONE){ - - String xt = p_path.get_extension().to_lower(); - if (EditorImportExport::get_singleton()->get_image_formats().has(xt)) { //should check for more I guess? - - Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name("texture"); - if (pl.is_valid()) { - Vector<uint8_t> ce = pl->custom_export(p_path,p_platform); - if (ce.size()) { - p_path=p_path.get_basename()+".converted.tex"; - return ce; - } - } - } - } - - return Vector<uint8_t>(); -} - -EditorTextureExportPlugin::EditorTextureExportPlugin() { - - -} -#endif diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.h b/tools/editor/io_plugins/editor_texture_import_plugin.h deleted file mode 100644 index ce15df0f18..0000000000 --- a/tools/editor/io_plugins/editor_texture_import_plugin.h +++ /dev/null @@ -1,179 +0,0 @@ -/*************************************************************************/ -/* editor_texture_import_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITOR_TEXTURE_IMPORT_PLUGIN_H -#define EDITOR_TEXTURE_IMPORT_PLUGIN_H - - - - - - -#if 0 -#include "tools/editor/editor_import_export.h" -#include "scene/gui/dialogs.h" -#include "scene/gui/tree.h" -#include "scene/gui/label.h" -#include "scene/gui/option_button.h" -#include "scene/gui/line_edit.h" -#include "scene/gui/file_dialog.h" -#include "scene/gui/progress_bar.h" -#include "scene/gui/slider.h" -#include "scene/gui/spin_box.h" -#include "tools/editor/editor_file_system.h" -#include "tools/editor/editor_dir_dialog.h" - - - -class EditorNode; -class EditorTextureImportDialog; - -class EditorTextureImportPlugin : public EditorImportPlugin { - - GDCLASS(EditorTextureImportPlugin,EditorImportPlugin); -public: - - - enum Mode { - MODE_TEXTURE_2D, - MODE_TEXTURE_3D, - MODE_ATLAS, - MODE_LARGE, - MODE_MAX - }; - - - -private: - - EditorNode *editor; - EditorTextureImportDialog *dialog; - static EditorTextureImportPlugin *singleton; - //used by other importers such as mesh - - Error _process_texture_data(Ref<ImageTexture> &texture, int format, float quality, int flags,EditorExportPlatform::ImageCompression p_compr,int tex_flags,float shrink); - void compress_image(EditorExportPlatform::ImageCompression p_mode,Image& image,bool p_smaller); - - uint32_t texture_flags_to_export_flags(uint32_t p_tex_flags) const; -public: - - - static EditorTextureImportPlugin *get_singleton() { return singleton; } - - enum ImageFormat { - - IMAGE_FORMAT_UNCOMPRESSED, - IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS, - IMAGE_FORMAT_COMPRESS_DISK_LOSSY, - IMAGE_FORMAT_COMPRESS_RAM, - }; - - enum ImageFlags { - - IMAGE_FLAG_STREAM_FORMAT=1, - IMAGE_FLAG_FIX_BORDER_ALPHA=2, - IMAGE_FLAG_ALPHA_BIT=4, //hint for compressions that use a bit for alpha - IMAGE_FLAG_COMPRESS_EXTRA=8, // used for pvrtc2 - IMAGE_FLAG_NO_MIPMAPS=16, //normal for 2D games - IMAGE_FLAG_REPEAT=32, //usually disabled in 2D - IMAGE_FLAG_FILTER=64, //almost always enabled - IMAGE_FLAG_PREMULT_ALPHA=128,//almost always enabled - IMAGE_FLAG_CONVERT_TO_LINEAR=256, //convert image to linear - IMAGE_FLAG_CONVERT_NORMAL_TO_XY=512, //convert image to linear - IMAGE_FLAG_USE_ANISOTROPY=1024, //convert image to linear - }; - - virtual String get_name() const; - virtual String get_visible_name() const; - virtual void import_dialog(const String& p_from=""); - virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); - virtual Error import2(const String& p_path, const Ref<ResourceImportMetadata>& p_from,EditorExportPlatform::ImageCompression p_compr, bool p_external=false); - virtual Vector<uint8_t> custom_export(const String& p_path,const Ref<EditorExportPlatform> &p_platform); - - virtual void import_from_drop(const Vector<String>& p_drop,const String& p_dest_path); - virtual void reimport_multiple_files(const Vector<String>& p_list); - virtual bool can_reimport_multiple_files() const; - - EditorTextureImportPlugin(EditorNode* p_editor=NULL); -}; - - -class EditorTextureExportPlugin : public EditorExportPlugin { - - GDCLASS( EditorTextureExportPlugin, EditorExportPlugin); - - -public: - - virtual Vector<uint8_t> custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform); - EditorTextureExportPlugin(); -}; - -class EditorImportTextureOptions : public VBoxContainer { - - GDCLASS( EditorImportTextureOptions, VBoxContainer ); - - - OptionButton *format; - VBoxContainer *quality_vb; - HSlider *quality; - Tree *flags; - Vector<TreeItem*> items; - - - bool updating; - - void _changedp(int p_value); - void _changed(); - - -protected: - static void _bind_methods(); - void _notification(int p_what); - -public: - - - - void set_format(EditorTextureImportPlugin::ImageFormat p_format); - EditorTextureImportPlugin::ImageFormat get_format() const; - - void set_flags(uint32_t p_flags); - uint32_t get_flags() const; - - void set_quality(float p_quality); - float get_quality() const; - - void show_2d_notice(); - - EditorImportTextureOptions(); - - -}; -#endif // EDITOR_TEXTURE_IMPORT_PLUGIN_H -#endif diff --git a/tools/editor/io_plugins/editor_translation_import_plugin.cpp b/tools/editor/io_plugins/editor_translation_import_plugin.cpp deleted file mode 100644 index 5ecb0b1abf..0000000000 --- a/tools/editor/io_plugins/editor_translation_import_plugin.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/*************************************************************************/ -/* editor_translation_import_plugin.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 "editor_translation_import_plugin.h" - -#if 0 -#include "scene/gui/file_dialog.h" -#include "tools/editor/editor_dir_dialog.h" -#include "tools/editor/editor_node.h" -#include "tools/editor/property_editor.h" -//#include "scene/resources/sample.h" -#include "io/resource_saver.h" -#include "os/file_access.h" -#include "translation.h" -#include "compressed_translation.h" -#include "tools/editor/project_settings.h" - - -class EditorTranslationImportDialog : public ConfirmationDialog { - - GDCLASS(EditorTranslationImportDialog,ConfirmationDialog); - - EditorTranslationImportPlugin *plugin; - - LineEdit *import_path; - LineEdit *save_path; - EditorFileDialog *file_select; - CheckButton *ignore_first; - CheckButton *compress; - CheckButton *add_to_project; - EditorDirDialog *save_select; - ConfirmationDialog *error_dialog; - Vector<TreeItem*> items; - Tree *columns; - -public: - - void _choose_file(const String& p_path) { - - import_path->set_text(p_path); - FileAccess *f = FileAccess::open(p_path,FileAccess::READ); - if (!f) { - - error_dialog->set_text(TTR("Invalid source!")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - - } - - Vector<String> csvh = f->get_csv_line(); - memdelete(f); - - if (csvh.size()<2) { - - error_dialog->set_text(TTR("Invalid translation source!")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - return; - - } - - columns->clear(); - columns->set_columns(2); - TreeItem *root = columns->create_item(); - columns->set_hide_root(true); - columns->set_column_titles_visible(true); - columns->set_column_title(0,TTR("Column")); - columns->set_column_title(1,TTR("Language")); - Vector<String> langs = TranslationServer::get_all_locales(); - Vector<String> names = TranslationServer::get_all_locale_names(); - if (csvh[0]=="") - ignore_first->set_pressed(true); - - - items.clear(); - - for(int i=1;i<csvh.size();i++) { - - TreeItem *ti = columns->create_item(root); - - ti->set_editable(0,true); - ti->set_selectable(0,false); - ti->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); - ti->set_checked(0,true); - ti->set_text(0,itos(i)); - items.push_back(ti); - - String lname = csvh[i].to_lower().strip_edges(); - int idx=-1; - String hint; - for(int j=0;j<langs.size();j++) { - - if (langs[j]==lname.substr(0,langs[j].length()).to_lower()) { - idx=j; - } - if (j>0) { - hint+=","; - } - hint+=names[j].replace(","," "); - } - - ti->set_cell_mode(1,TreeItem::CELL_MODE_RANGE); - ti->set_text(1,hint); - ti->set_editable(1,true); - - - if (idx!=-1) { - ignore_first->set_pressed(true); - ti->set_range(1,idx); - } else { - - //not found, maybe used stupid name - if (lname.begins_with("br")) //brazilian - ti->set_range(1,langs.find("pt")); - else if (lname.begins_with("ch")) //chinese - ti->set_range(1,langs.find("zh")); - else if (lname.begins_with("sp")) //spanish - ti->set_range(1,langs.find("es")); - else if (lname.begins_with("kr"))// kprean - ti->set_range(1,langs.find("ko")); - else if (i==0) - ti->set_range(1,langs.find("en")); - else - ti->set_range(1,langs.find("es")); - } - - ti->set_metadata(1,names[ti->get_range(1)]); - } - - - - } - void _choose_save_dir(const String& p_path) { - - save_path->set_text(p_path); - } - - void _browse() { - - file_select->popup_centered_ratio(); - } - - void _browse_target() { - - save_select->popup_centered_ratio(); - - } - - - void popup_import(const String& p_from) { - - popup_centered(Size2(400,400)*EDSCALE); - - if (p_from!="") { - - Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from); - ERR_FAIL_COND(!rimd.is_valid()); - ERR_FAIL_COND(rimd->get_source_count()!=1); - _choose_file(EditorImportPlugin::expand_source_path(rimd->get_source_path(0))); - _choose_save_dir(p_from.get_base_dir()); - String locale = rimd->get_option("locale"); - bool skip_first=rimd->get_option("skip_first"); - bool compressed = rimd->get_option("compress"); - - int idx=-1; - - for(int i=0;i<items.size();i++) { - - String il = TranslationServer::get_all_locales()[items[i]->get_range(1)]; - if (il==locale) { - idx=i; - break; - } - } - - if (idx!=-1) { - idx=rimd->get_option("index"); - } - - for(int i=0;i<items.size();i++) { - - if (i==idx) { - - Vector<String> locs = TranslationServer::get_all_locales(); - for(int j=0;j<locs.size();j++) { - if (locs[j]==locale) { - items[i]->set_range(1,j); - } - - } - items[i]->set_checked(0,true); - } else { - items[i]->set_checked(0,false); - - } - } - - ignore_first->set_pressed(skip_first); - compress->set_pressed(compressed); - - - - } - - } - - - void _import() { - - - if (items.size()==0) { - error_dialog->set_text(TTR("No items to import!")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - } - - if (!save_path->get_text().begins_with("res://")) { - error_dialog->set_text(TTR("No target path!")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - } - - EditorProgress progress("import_xl",TTR("Import Translations"),items.size()); - for(int i=0;i<items.size();i++) { - - progress.step(items[i]->get_metadata(1),i); - if (!items[i]->is_checked(0)) - continue; - - String locale = TranslationServer::get_all_locales()[items[i]->get_range(1)]; - Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata ); - imd->add_source(EditorImportPlugin::validate_source_path(import_path->get_text())); - imd->set_option("locale",locale); - imd->set_option("index",i); - imd->set_option("skip_first",ignore_first->is_pressed()); - imd->set_option("compress",compress->is_pressed()); - - String savefile = save_path->get_text().plus_file(import_path->get_text().get_file().get_basename()+"."+locale+".xl"); - Error err = plugin->import(savefile,imd); - if (err!=OK) { - error_dialog->set_text(TTR("Couldn't import!")); - error_dialog->popup_centered(Size2(200,100)*EDSCALE); - } else if (add_to_project->is_pressed()) { - - ProjectSettings::get_singleton()->add_translation(savefile); - } - } - hide(); - - } - - - void _notification(int p_what) { - - - if (p_what==NOTIFICATION_ENTER_TREE) { - - - } - } - - static void _bind_methods() { - - - ClassDB::bind_method("_choose_file",&EditorTranslationImportDialog::_choose_file); - ClassDB::bind_method("_choose_save_dir",&EditorTranslationImportDialog::_choose_save_dir); - ClassDB::bind_method("_import",&EditorTranslationImportDialog::_import); - ClassDB::bind_method("_browse",&EditorTranslationImportDialog::_browse); - ClassDB::bind_method("_browse_target",&EditorTranslationImportDialog::_browse_target); - //ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); - } - - EditorTranslationImportDialog(EditorTranslationImportPlugin *p_plugin) { - - plugin=p_plugin; - - - set_title(TTR("Import Translation")); - - VBoxContainer *vbc = memnew( VBoxContainer ); - add_child(vbc); - //set_child_rect(vbc); - - - - VBoxContainer *csvb = memnew( VBoxContainer ); - - HBoxContainer *hbc = memnew( HBoxContainer ); - csvb->add_child(hbc); - vbc->add_margin_child(TTR("Source CSV:"),csvb); - - import_path = memnew( LineEdit ); - import_path->set_h_size_flags(SIZE_EXPAND_FILL); - hbc->add_child(import_path); - ignore_first = memnew( CheckButton ); - ignore_first->set_text(TTR("Ignore First Row")); - csvb->add_child(ignore_first); - - Button * import_choose = memnew( Button ); - import_choose->set_text(" .. "); - hbc->add_child(import_choose); - - import_choose->connect("pressed", this,"_browse"); - - VBoxContainer *tcomp = memnew( VBoxContainer); - hbc = memnew( HBoxContainer ); - tcomp->add_child(hbc); - vbc->add_margin_child(TTR("Target Path:"),tcomp); - - save_path = memnew( LineEdit ); - save_path->set_h_size_flags(SIZE_EXPAND_FILL); - hbc->add_child(save_path); - - Button * save_choose = memnew( Button ); - save_choose->set_text(" .. "); - hbc->add_child(save_choose); - - save_choose->connect("pressed", this,"_browse_target"); - - compress = memnew( CheckButton); - compress->set_pressed(true); - compress->set_text(TTR("Compress")); - tcomp->add_child(compress); - - add_to_project = memnew( CheckButton); - add_to_project->set_pressed(true); - add_to_project->set_text(TTR("Add to Project (godot.cfg)")); - tcomp->add_child(add_to_project); - - file_select = memnew(EditorFileDialog); - file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - add_child(file_select); - file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); - file_select->connect("file_selected", this,"_choose_file"); - file_select->add_filter("*.csv ; Translation CSV"); - save_select = memnew( EditorDirDialog ); - add_child(save_select); - - //save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); - save_select->connect("dir_selected", this,"_choose_save_dir"); - - get_ok()->connect("pressed", this,"_import"); - get_ok()->set_text(TTR("Import")); - - - error_dialog = memnew ( ConfirmationDialog ); - add_child(error_dialog); - error_dialog->get_ok()->set_text(TTR("Accept")); - //error_dialog->get_cancel()->hide(); - - set_hide_on_ok(false); - - columns = memnew( Tree ); - vbc->add_margin_child(TTR("Import Languages:"),columns,true); - } - - ~EditorTranslationImportDialog() { - - } - -}; - - -String EditorTranslationImportPlugin::get_name() const { - - return "translation"; -} -String EditorTranslationImportPlugin::get_visible_name() const { - - return TTR("Translation"); -} -void EditorTranslationImportPlugin::import_dialog(const String& p_from) { - - dialog->popup_import(p_from); -} - - - -void EditorTranslationImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { - - - for(int i=0;i<p_drop.size();i++) { - String ext = p_drop[i].get_extension().to_lower(); - - if (ext=="csv") { - - import_dialog(); - dialog->_choose_file(p_drop[i]); - dialog->_choose_save_dir(p_dest_path); - break; - } - } - - -} - -Error EditorTranslationImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from) { - - Ref<ResourceImportMetadata> from = p_from; - ERR_FAIL_COND_V( from->get_source_count()!=1, ERR_INVALID_PARAMETER); - - String source = EditorImportPlugin::expand_source_path( from->get_source_path(0) ); - - FileAccessRef f = FileAccess::open(source,FileAccess::READ); - - ERR_FAIL_COND_V( !f, ERR_INVALID_PARAMETER ); - - bool skip_first = from->get_option("skip_first"); - int index = from->get_option("index"); - index+=1; - String locale = from->get_option("locale"); - - Ref<Translation> translation = memnew( Translation ); - - translation->set_locale( locale ); - - Vector<String> line = f->get_csv_line(); - - while(line.size()>1) { - - if (!skip_first) { - ERR_FAIL_INDEX_V(index,line.size(),ERR_INVALID_DATA ); - translation->add_message(line[0].strip_edges(),line[index]); - - } else { - - skip_first=false; - } - - line = f->get_csv_line(); - } - - from->set_source_md5(0,FileAccess::get_md5(source)); - from->set_editor(get_name()); - - String dst_path = p_path; - - if (from->get_option("compress")) { - - Ref<PHashTranslation> cxl = memnew( PHashTranslation ); - cxl->generate( translation ); - translation=cxl; - } - - translation->set_import_metadata(from); - return ResourceSaver::save(dst_path,translation); - -} - - -EditorTranslationImportPlugin::EditorTranslationImportPlugin(EditorNode* p_editor) { - - dialog = memnew(EditorTranslationImportDialog(this)); - p_editor->get_gui_base()->add_child(dialog); -} - -#endif diff --git a/tools/editor/io_plugins/editor_translation_import_plugin.h b/tools/editor/io_plugins/editor_translation_import_plugin.h deleted file mode 100644 index 22065599b9..0000000000 --- a/tools/editor/io_plugins/editor_translation_import_plugin.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************/ -/* editor_translation_import_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITOR_TRANSLATION_IMPORT_PLUGIN_H -#define EDITOR_TRANSLATION_IMPORT_PLUGIN_H - -#include "tools/editor/editor_export.h" -#include "scene/resources/font.h" -#if 0 -class EditorNode; -class EditorTranslationImportDialog; - -class EditorTranslationImportPlugin : public EditorImportPlugin { - - GDCLASS(EditorTranslationImportPlugin,EditorImportPlugin); - - EditorTranslationImportDialog *dialog; -public: - - virtual String get_name() const; - virtual String get_visible_name() const; - virtual void import_dialog(const String& p_from=""); - virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); - void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); - - - EditorTranslationImportPlugin(EditorNode* p_editor); -}; - -#endif -#endif // EDITOR_TRANSLATION_IMPORT_PLUGIN_H diff --git a/tools/editor/plugins/animation_player_editor_plugin.cpp b/tools/editor/plugins/animation_player_editor_plugin.cpp deleted file mode 100644 index 71173038e9..0000000000 --- a/tools/editor/plugins/animation_player_editor_plugin.cpp +++ /dev/null @@ -1,1604 +0,0 @@ -/*************************************************************************/ -/* animation_player_editor_plugin.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 "animation_player_editor_plugin.h" - -#include "global_config.h" -#include "io/resource_loader.h" -#include "io/resource_saver.h" -#include "os/keyboard.h" -#include "tools/editor/editor_settings.h" -#include "tools/editor/animation_editor.h" - -void AnimationPlayerEditor::_node_removed(Node *p_node) { - - if (player && player == p_node) { - player=NULL; - - set_process(false); - - key_editor->set_animation(Ref<Animation>()); - key_editor->set_root(NULL); - key_editor->show_select_node_warning(true); - _update_player(); - //editor->animation_editor_make_visible(false); - - } -} - -void AnimationPlayerEditor::_gui_input(InputEvent p_event) { - - -} - -void AnimationPlayerEditor::_notification(int p_what) { - - if (p_what==NOTIFICATION_PROCESS) { - - if (!player) - return; - - updating = true; - - if (player->is_playing()) { - - { - String animname=player->get_current_animation(); - - if (player->has_animation(animname)) { - Ref<Animation> anim = player->get_animation(animname); - if (!anim.is_null()) { - - frame->set_max(anim->get_length()); - } - } - } - frame->set_value(player->get_current_animation_pos()); - key_editor->set_anim_pos(player->get_current_animation_pos()); - EditorNode::get_singleton()->get_property_editor()->refresh(); - - } else if (last_active) { - //need the last frame after it stopped - - frame->set_value(player->get_current_animation_pos()); - } - - last_active=player->is_playing(); - //seek->set_val(player->get_pos()); - updating = false; - } - - if (p_what==NOTIFICATION_ENTER_TREE) { - - //editor->connect("hide_animation_player_editors",this,"_hide_anim_editors"); - add_anim->set_icon( get_icon("New","EditorIcons") ); - rename_anim->set_icon( get_icon("Rename","EditorIcons") ); - duplicate_anim->set_icon( get_icon("Duplicate","EditorIcons") ); - autoplay->set_icon( get_icon("AutoPlay","EditorIcons") ); - load_anim->set_icon( get_icon("Folder","EditorIcons") ); - save_anim->set_icon(get_icon("Save", "EditorIcons")); - save_anim->get_popup()->connect("id_pressed", this, "_animation_save_menu"); - remove_anim->set_icon( get_icon("Remove","EditorIcons") ); - - blend_anim->set_icon( get_icon("Blend","EditorIcons") ); - play->set_icon( get_icon("PlayStart","EditorIcons") ); - play_from->set_icon( get_icon("Play","EditorIcons") ); - play_bw->set_icon( get_icon("PlayStartBackwards","EditorIcons") ); - play_bw_from->set_icon( get_icon("PlayBackwards","EditorIcons") ); - - autoplay_icon=get_icon("AutoPlay","EditorIcons"); - stop->set_icon( get_icon("Stop","EditorIcons") ); - resource_edit_anim->set_icon( get_icon("EditResource","EditorIcons") ); - pin->set_icon(get_icon("Pin","EditorIcons") ); - tool_anim->set_icon(get_icon("Tools","EditorIcons")); - tool_anim->get_popup()->connect("id_pressed",this,"_animation_tool_menu"); - - blend_editor.next->connect("item_selected", this, "_blend_editor_next_changed"); - - nodename->set_icon(get_icon("AnimationPlayer","EditorIcons")); - -/* - anim_editor_load->set_normal_texture( get_icon("AnimGet","EditorIcons")); - anim_editor_store->set_normal_texture( get_icon("AnimSet","EditorIcons")); - anim_editor_load->set_pressed_texture( get_icon("AnimGet","EditorIcons")); - anim_editor_store->set_pressed_texture( get_icon("AnimSet","EditorIcons")); - anim_editor_load->set_hover_texture( get_icon("AnimGetHl","EditorIcons")); - anim_editor_store->set_hover_texture( get_icon("AnimSetHl","EditorIcons")); -*/ - - get_tree()->connect("node_removed",this,"_node_removed"); - } -} - -void AnimationPlayerEditor::_autoplay_pressed() { - - if (updating) - return; - if (animation->get_item_count()==0) { - return; - } - - String current = animation->get_item_text( animation->get_selected() ); - if (player->get_autoplay()==current) { - //unset - undo_redo->create_action(TTR("Toggle Autoplay")); - undo_redo->add_do_method(player,"set_autoplay",""); - undo_redo->add_undo_method(player,"set_autoplay",player->get_autoplay()); - undo_redo->add_do_method(this,"_animation_player_changed",player); - undo_redo->add_undo_method(this,"_animation_player_changed",player); - undo_redo->commit_action(); - - - } else { - //set - undo_redo->create_action(TTR("Toggle Autoplay")); - undo_redo->add_do_method(player,"set_autoplay",current); - undo_redo->add_undo_method(player,"set_autoplay",player->get_autoplay()); - undo_redo->add_do_method(this,"_animation_player_changed",player); - undo_redo->add_undo_method(this,"_animation_player_changed",player); - undo_redo->commit_action(); - } - -} - -void AnimationPlayerEditor::_play_pressed() { - - String current; - if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { - - current = animation->get_item_text( animation->get_selected() ); - } - - if (current!="") { - - if (current==player->get_current_animation()) - player->stop(); //so it wont blend with itself - player->play(current ); - } - - //unstop - stop->set_pressed(false); - //unpause - //pause->set_pressed(false); -} - -void AnimationPlayerEditor::_play_from_pressed() { - - String current; - if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { - - current = animation->get_item_text( animation->get_selected() ); - } - - if (current!="") { - - float time = player->get_current_animation_pos(); - - if (current==player->get_current_animation() && player->is_playing()) { - - player->stop(); //so it wont blend with itself - } - - player->play( current ); - player->seek(time); - } - - //unstop - stop->set_pressed(false); - //unpause - //pause->set_pressed(false); -} - - -void AnimationPlayerEditor::_play_bw_pressed() { - - String current; - if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { - - current = animation->get_item_text( animation->get_selected() ); - } - - if (current!="") { - - if (current==player->get_current_animation()) - player->stop(); //so it wont blend with itself - player->play(current,-1,-1,true); - } - - //unstop - stop->set_pressed(false); - //unpause - //pause->set_pressed(false); -} - -void AnimationPlayerEditor::_play_bw_from_pressed() { - - String current; - if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { - - current = animation->get_item_text( animation->get_selected() ); - } - - if (current!="") { - - float time = player->get_current_animation_pos(); - if (current==player->get_current_animation()) - player->stop(); //so it wont blend with itself - - player->play(current,-1,-1,true); - player->seek(time); - } - - //unstop - stop->set_pressed(false); - //unpause - //pause->set_pressed(false); -} -void AnimationPlayerEditor::_stop_pressed() { - - player->stop(false); - play->set_pressed(false); - stop->set_pressed(true); - //pause->set_pressed(false); - //player->set_pause(false); -} - -void AnimationPlayerEditor::_pause_pressed() { - - //player->set_pause( pause->is_pressed() ); -} -void AnimationPlayerEditor::_animation_selected(int p_which) { - - if (updating) - return; - // when selecting an animation, the idea is that the only interesting behavior - // ui-wise is that it should play/blend the next one if currently playing - String current; - if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { - - current = animation->get_item_text( animation->get_selected() ); - } - - if (current!="") { - - - player->set_current_animation( current ); - - Ref<Animation> anim = player->get_animation(current); - { - - key_editor->set_animation(anim); - Node *root = player->get_node(player->get_root()); - if (root) { - key_editor->set_root(root); - } - } - frame->set_max(anim->get_length()); - if (anim->get_step()) - frame->set_step(anim->get_step()); - else - frame->set_step(0.00001); - - - - } else { - key_editor->set_animation(Ref<Animation>()); - key_editor->set_root(NULL); - - } - - - autoplay->set_pressed(current==player->get_autoplay()); -} - -void AnimationPlayerEditor::_animation_new() { - - renaming=false; - name_title->set_text(TTR("New Animation Name:")); - - int count=1; - String base=TTR("New Anim"); - while(true) { - String attempt = base; - if (count>1) - attempt+=" ("+itos(count)+")"; - if (player->has_animation(attempt)) { - count++; - continue; - } - base=attempt; - break; - } - - name->set_text(base); - name_dialog->popup_centered(Size2(300,90)); - name->select_all(); - name->grab_focus(); -} -void AnimationPlayerEditor::_animation_rename() { - - if (animation->get_item_count()==0) - return; - int selected = animation->get_selected(); - String selected_name = animation->get_item_text(selected); - - name_title->set_text(TTR("Change Animation Name:")); - name->set_text(selected_name); - renaming=true; - name_dialog->popup_centered(Size2(300,90)); - name->select_all(); - name->grab_focus(); - -} -void AnimationPlayerEditor::_animation_load() { - ERR_FAIL_COND(!player); - file->set_mode( EditorFileDialog::MODE_OPEN_FILE ); - file->clear_filters(); - List<String> extensions; - - ResourceLoader::get_recognized_extensions_for_type("Animation",&extensions); - for (List<String>::Element *E=extensions.front();E;E=E->next()) { - - file->add_filter("*."+E->get()+" ; "+E->get().to_upper() ); - - } - - file->popup_centered_ratio(); - current_option = RESOURCE_LOAD; -} - - -void AnimationPlayerEditor::_animation_save_in_path(const Ref<Resource>& p_resource, const String& p_path) { - - int flg = 0; - if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) - flg |= ResourceSaver::FLAG_COMPRESS; - /* - if (EditorSettings::get_singleton()->get("filesystem/on_save/save_paths_as_relative")) - flg |= ResourceSaver::FLAG_RELATIVE_PATHS; - */ - - String path = GlobalConfig::get_singleton()->localize_path(p_path); - Error err = ResourceSaver::save(path, p_resource, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS); - - if (err != OK) { - accept->set_text(TTR("Error saving resource!")); - accept->popup_centered_minsize(); - return; - } - //EditorFileSystem::get_singleton()->update_file(path,p_resource->get_type()); - - ((Resource*)p_resource.ptr())->set_path(path); - editor->emit_signal("resource_saved", p_resource); - -} - -void AnimationPlayerEditor::_animation_save(const Ref<Resource>& p_resource) { - - if (p_resource->get_path().is_resource_file()) { - _animation_save_in_path(p_resource, p_resource->get_path()); - } - else { - _animation_save_as(p_resource); - } -} - -void AnimationPlayerEditor::_animation_save_as(const Ref<Resource>& p_resource) { - - file->set_mode(EditorFileDialog::MODE_SAVE_FILE); - - List<String> extensions; - ResourceSaver::get_recognized_extensions(p_resource, &extensions); - file->clear_filters(); - for (int i = 0; i<extensions.size(); i++) { - - file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper()); - } - - //file->set_current_path(current_path); - if (p_resource->get_path() != "") { - file->set_current_path(p_resource->get_path()); - if (extensions.size()) { - String ext = p_resource->get_path().get_extension().to_lower(); - if (extensions.find(ext) == NULL) { - file->set_current_path(p_resource->get_path().replacen("." + ext, "." + extensions.front()->get())); - } - } - } - else { - - String existing; - if (extensions.size()) { - if( p_resource->get_name() != "" ) { - existing = p_resource->get_name() + "." + extensions.front()->get().to_lower(); - } - else { - existing = "new_" + p_resource->get_class().to_lower() + "." + extensions.front()->get().to_lower(); - } - } - file->set_current_path(existing); - - } - file->popup_centered_ratio(); - file->set_title(TTR("Save Resource As..")); - current_option = RESOURCE_SAVE; -} - -void AnimationPlayerEditor::_animation_remove() { - - if (animation->get_item_count() == 0) - return; - - delete_dialog->set_text(TTR("Delete Animation?")); - delete_dialog->popup_centered_minsize(); -} - -void AnimationPlayerEditor::_animation_remove_confirmed() { - - String current = animation->get_item_text(animation->get_selected()); - Ref<Animation> anim = player->get_animation(current); - - undo_redo->create_action(TTR("Remove Animation")); - undo_redo->add_do_method(player, "remove_animation", current); - undo_redo->add_undo_method(player, "add_animation", current, anim); - undo_redo->add_do_method(this, "_animation_player_changed", player); - undo_redo->add_undo_method(this, "_animation_player_changed", player); - undo_redo->commit_action(); -} - -void AnimationPlayerEditor::_select_anim_by_name(const String& p_anim) { - - int idx=-1; - for(int i=0;i<animation->get_item_count();i++) { - - if (animation->get_item_text(i)==p_anim) { - - idx=i; - break; - } - } - - ERR_FAIL_COND(idx==-1); - - - animation->select(idx); - - _animation_selected(idx); - -} - -void AnimationPlayerEditor::_animation_name_edited() { - - player->stop(); - - String new_name = name->get_text(); - if (new_name=="" || new_name.find(":")!=-1 || new_name.find("/")!=-1) { - error_dialog->set_text(TTR("ERROR: Invalid animation name!")); - error_dialog->popup_centered_minsize(); - return; - } - - if (renaming && animation->get_item_count()>0 && animation->get_item_text(animation->get_selected())==new_name) { - name_dialog->hide(); - return; - } - - if (player->has_animation(new_name)) { - error_dialog->set_text(TTR("ERROR: Animation name already exists!")); - error_dialog->popup_centered_minsize(); - return; - } - - if (renaming) { - String current = animation->get_item_text(animation->get_selected()); - Ref<Animation> anim = player->get_animation(current); - - undo_redo->create_action(TTR("Rename Animation")); - undo_redo->add_do_method(player,"rename_animation",current,new_name); - undo_redo->add_do_method(anim.ptr(),"set_name",new_name); - undo_redo->add_undo_method(player,"rename_animation",new_name,current); - undo_redo->add_undo_method(anim.ptr(),"set_name",current); - undo_redo->add_do_method(this,"_animation_player_changed",player); - undo_redo->add_undo_method(this,"_animation_player_changed",player); - undo_redo->commit_action(); - - _select_anim_by_name(new_name); - - } else { - - Ref<Animation> new_anim = Ref<Animation>(memnew( Animation )); - new_anim->set_name(new_name); - - undo_redo->create_action(TTR("Add Animation")); - undo_redo->add_do_method(player,"add_animation",new_name,new_anim); - undo_redo->add_undo_method(player,"remove_animation",new_name); - undo_redo->add_do_method(this,"_animation_player_changed",player); - undo_redo->add_undo_method(this,"_animation_player_changed",player); - undo_redo->commit_action(); - - _select_anim_by_name(new_name); - - } - - name_dialog->hide(); -} - - -void AnimationPlayerEditor::_blend_editor_next_changed(const int p_idx) { - - if (animation->get_item_count()==0) - return; - - String current = animation->get_item_text(animation->get_selected()); - - undo_redo->create_action(TTR("Blend Next Changed")); - undo_redo->add_do_method(player,"animation_set_next",current,blend_editor.next->get_item_text(p_idx)); - undo_redo->add_undo_method(player,"animation_set_next",current,player->animation_get_next(current)); - undo_redo->add_do_method(this,"_animation_player_changed",player); - undo_redo->add_undo_method(this,"_animation_player_changed",player); - undo_redo->commit_action(); -} - -void AnimationPlayerEditor::_animation_blend() { - - if (updating_blends) - return; - - blend_editor.tree->clear(); - - if (animation->get_item_count()==0) - return; - - String current = animation->get_item_text(animation->get_selected()); - - blend_editor.dialog->popup_centered(Size2(400,400)); - - blend_editor.tree->set_hide_root(true); - blend_editor.tree->set_column_min_width(0,10); - blend_editor.tree->set_column_min_width(1,3); - - List<StringName> anims; - player->get_animation_list(&anims); - TreeItem *root = blend_editor.tree->create_item(); - updating_blends=true; - - int i = 0; - bool anim_found = false; - blend_editor.next->clear(); - blend_editor.next->add_item("", i); - - for(List<StringName>::Element *E=anims.front();E;E=E->next()) { - - String to=E->get(); - TreeItem *blend=blend_editor.tree->create_item(root); - blend->set_editable(0,false); - blend->set_editable(1,true); - blend->set_text(0,to); - blend->set_cell_mode(1,TreeItem::CELL_MODE_RANGE); - blend->set_range_config(1,0,3600,0.001); - blend->set_range(1,player->get_blend_time(current,to)); - - i++; - blend_editor.next->add_item(to, i); - if (to == player->animation_get_next(current)) { - blend_editor.next->select(i); - anim_found = true; - } - } - - // make sure we reset it else it becomes out of sync and could contain a deleted animation - if (!anim_found) { - blend_editor.next->select(0); - player->animation_set_next(current, blend_editor.next->get_item_text(0)); - } - - updating_blends=false; -} - -void AnimationPlayerEditor::_blend_edited() { - - if (updating_blends) - return; - - if (animation->get_item_count()==0) - return; - - String current = animation->get_item_text(animation->get_selected()); - - TreeItem *selected = blend_editor.tree->get_edited(); - if (!selected) - return; - - updating_blends=true; - String to=selected->get_text(0); - float blend_time = selected->get_range(1); - float prev_blend_time = player->get_blend_time(current,to); - - undo_redo->create_action(TTR("Change Blend Time")); - undo_redo->add_do_method(player,"set_blend_time",current,to,blend_time); - undo_redo->add_undo_method(player,"set_blend_time",current,to,prev_blend_time); - undo_redo->add_do_method(this,"_animation_player_changed",player); - undo_redo->add_undo_method(this,"_animation_player_changed",player); - undo_redo->commit_action(); - updating_blends=false; -} - -void AnimationPlayerEditor::ensure_visibility() { - - if (player && pin->is_pressed()) - return; // another player is pinned, don't reset - - _animation_edit(); -} - -Dictionary AnimationPlayerEditor::get_state() const { - - - Dictionary d; - - d["visible"]=is_visible_in_tree(); - if (EditorNode::get_singleton()->get_edited_scene() && is_visible_in_tree() && player) { - d["player"]=EditorNode::get_singleton()->get_edited_scene()->get_path_to(player); - d["animation"]=player->get_current_animation(); - - } - - return d; - -} -void AnimationPlayerEditor::set_state(const Dictionary& p_state) { - - if (p_state.has("visible") && p_state["visible"]) { - - if (!EditorNode::get_singleton()->get_edited_scene()) - return; - - Node *n = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["player"]); - if (n && n->cast_to<AnimationPlayer>() && EditorNode::get_singleton()->get_editor_selection()->is_selected(n)) { - player=n->cast_to<AnimationPlayer>(); - _update_player(); - show(); - set_process(true); - ensure_visibility(); - //EditorNode::get_singleton()->animation_panel_make_visible(true); - - if (p_state.has("animation")) { - String anim = p_state["animation"]; - _select_anim_by_name(anim); - _animation_edit(); - } - - } - } - -} - - -void AnimationPlayerEditor::_animation_resource_edit() { - - if (animation->get_item_count()) { - String current = animation->get_item_text(animation->get_selected()); - Ref<Animation> anim = player->get_animation(current); - editor->edit_resource(anim); - } - -} - -void AnimationPlayerEditor::_animation_edit() { - - if (animation->get_item_count()) { - String current = animation->get_item_text(animation->get_selected()); - Ref<Animation> anim = player->get_animation(current); - key_editor->set_animation(anim); - Node *root = player->get_node(player->get_root()); - if (root) { - key_editor->set_root(root); - } - - } else { - - key_editor->set_animation(Ref<Animation>()); - key_editor->set_root(NULL); - - } - -} -void AnimationPlayerEditor::_dialog_action(String p_file) { - - switch (current_option) { - case RESOURCE_LOAD: { - ERR_FAIL_COND(!player); - - Ref<Resource> res = ResourceLoader::load(p_file, "Animation"); - ERR_FAIL_COND(res.is_null()); - ERR_FAIL_COND(!res->is_class("Animation")); - if (p_file.find_last("/") != -1) { - - p_file = p_file.substr(p_file.find_last("/") + 1, p_file.length()); - - } - if (p_file.find_last("\\") != -1) { - - p_file = p_file.substr(p_file.find_last("\\") + 1, p_file.length()); - - } - - if (p_file.find(".") != -1) - p_file = p_file.substr(0, p_file.find(".")); - - undo_redo->create_action(TTR("Load Animation")); - undo_redo->add_do_method(player, "add_animation", p_file, res); - undo_redo->add_undo_method(player, "remove_animation", p_file); - if (player->has_animation(p_file)) { - undo_redo->add_undo_method(player, "add_animation", p_file, player->get_animation(p_file)); - - } - undo_redo->add_do_method(this, "_animation_player_changed", player); - undo_redo->add_undo_method(this, "_animation_player_changed", player); - undo_redo->commit_action(); - break; - } - case RESOURCE_SAVE: { - - String current = animation->get_item_text(animation->get_selected()); - if (current != "") { - Ref<Animation> anim = player->get_animation(current); - - ERR_FAIL_COND(!anim->cast_to<Resource>()) - - RES current_res = RES(anim->cast_to<Resource>()); - - _animation_save_in_path(current_res, p_file); - } - } - } -} - -void AnimationPlayerEditor::_scale_changed(const String& p_scale) { - - player->set_speed_scale(p_scale.to_double()); -} - -void AnimationPlayerEditor::_update_animation() { - - // the purpose of _update_animation is to reflect the current state - // of the animation player in the current editor.. - - updating=true; - - - if (player->is_playing()) { - - play->set_pressed(true); - stop->set_pressed(false); - - } else { - - play->set_pressed(false); - stop->set_pressed(true); - } - - scale->set_text( String::num(player->get_speed_scale(),2) ); - String current=player->get_current_animation(); - - for (int i=0;i<animation->get_item_count();i++) { - - if (animation->get_item_text(i)==current) { - animation->select(i); - break; - } - } - - updating=false; -} - -void AnimationPlayerEditor::_update_player() { - - - updating=true; - List<StringName> animlist; - if (player) - player->get_animation_list(&animlist); - - animation->clear(); - if (player) - nodename->set_text(player->get_name()); - else - nodename->set_text("<empty>"); - - - add_anim->set_disabled(player==NULL); - load_anim->set_disabled(player==NULL); - stop->set_disabled(animlist.size()==0); - play->set_disabled(animlist.size()==0); - play_bw->set_disabled(animlist.size()==0); - play_bw_from->set_disabled(animlist.size()==0); - play_from->set_disabled(animlist.size()==0); - autoplay->set_disabled(animlist.size()==0); - duplicate_anim->set_disabled(animlist.size()==0); - rename_anim->set_disabled(animlist.size()==0); - blend_anim->set_disabled(animlist.size()==0); - remove_anim->set_disabled(animlist.size()==0); - resource_edit_anim->set_disabled(animlist.size()==0); - save_anim->set_disabled(animlist.size() == 0); - tool_anim->set_disabled(player==NULL); - - - int active_idx=-1; - for (List<StringName>::Element *E=animlist.front();E;E=E->next()) { - - if (player->get_autoplay()==E->get()) - animation->add_icon_item(autoplay_icon,E->get()); - else - animation->add_item(E->get()); - - if (player->get_current_animation()==E->get()) - active_idx=animation->get_item_count()-1; - - } - - if (!player) - return; - - updating=false; - if (active_idx!=-1) { - animation->select(active_idx); - autoplay->set_pressed(animation->get_item_text(active_idx)==player->get_autoplay()); - _animation_selected(active_idx); - - } else if (animation->get_item_count()>0){ - - animation->select(0); - autoplay->set_pressed(animation->get_item_text(0)==player->get_autoplay()); - _animation_selected(0); - } - - //pause->set_pressed(player->is_paused()); - - - if (animation->get_item_count()) { - String current = animation->get_item_text(animation->get_selected()); - Ref<Animation> anim = player->get_animation(current); - key_editor->set_animation(anim); - Node *root = player->get_node(player->get_root()); - if (root) { - key_editor->set_root(root); - } - - } - - _update_animation(); -} - - - -void AnimationPlayerEditor::edit(AnimationPlayer *p_player) { - - - if (player && pin->is_pressed()) - return; //ignore, pinned - player=p_player; - - if (player) { - _update_player(); - key_editor->show_select_node_warning(false); - } else { - key_editor->show_select_node_warning(true); - - //hide(); - - } - -} - - -void AnimationPlayerEditor::_animation_duplicate() { - - - if (!animation->get_item_count()) - return; - - String current = animation->get_item_text(animation->get_selected()); - Ref<Animation> anim = player->get_animation(current); - if (!anim.is_valid()) - return; - - Ref<Animation> new_anim = memnew( Animation ); - List<PropertyInfo> plist; - anim->get_property_list(&plist); - for (List<PropertyInfo>::Element *E=plist.front();E;E=E->next()) { - - if (E->get().usage&PROPERTY_USAGE_STORAGE) { - - new_anim->set(E->get().name, anim->get(E->get().name)); - } - } - new_anim->set_path(""); - - String new_name = current; - while(player->has_animation(new_name)) { - - new_name=new_name+" (copy)"; - } - - - undo_redo->create_action(TTR("Duplicate Animation")); - undo_redo->add_do_method(player,"add_animation",new_name,new_anim); - undo_redo->add_undo_method(player,"remove_animation",new_name); - undo_redo->add_do_method(player,"animation_set_next",new_name,player->animation_get_next(current)); - undo_redo->add_do_method(this,"_animation_player_changed",player); - undo_redo->add_undo_method(this,"_animation_player_changed",player); - undo_redo->commit_action(); - - - for(int i=0;i<animation->get_item_count();i++) { - - if (animation->get_item_text(i)==new_name) { - - animation->select(i); - _animation_selected(i); - return; - } - } - -} - -void AnimationPlayerEditor::_seek_value_changed(float p_value,bool p_set) { - - if (updating || !player || player->is_playing()) { - return; - }; - - - updating=true; - String current=player->get_current_animation(); //animation->get_item_text( animation->get_selected() ); - if (current == "" || !player->has_animation(current)) { - updating=false; - current=""; - return; - }; - - Ref<Animation> anim; - anim=player->get_animation(current); - - float pos = anim->get_length() * (p_value / frame->get_max()); - float step = anim->get_step(); - if (step) { - pos=Math::stepify(pos, step); - if (pos<0) - pos=0; - if (pos>=anim->get_length()) - pos=anim->get_length(); - } - - if (player->is_valid() && !p_set) { - float cpos = player->get_current_animation_pos(); - - player->seek_delta(pos,pos-cpos); - } else { - player->seek(pos,true); - } - - - key_editor->set_anim_pos(pos); - - updating=true; -}; - -void AnimationPlayerEditor::_animation_player_changed(Object *p_pl) { - - if (player==p_pl && is_visible_in_tree()) { - - _update_player(); - if (blend_editor.dialog->is_visible_in_tree()) - _animation_blend(); //update - } -} - - - -void AnimationPlayerEditor::_list_changed() { - - if(is_visible_in_tree()) - _update_player(); -} -#if 0 -void AnimationPlayerEditor::_editor_store() { - - if (animation->get_item_count()==0) - return; - String current = animation->get_item_text(animation->get_selected()); - Ref<Animation> anim = player->get_animation(current); - - if (key_editor->get_current_animation()==anim) - return; //already there - - - undo_redo->create_action("Store anim in editor"); - undo_redo->add_do_method(key_editor,"set_animation",anim); - undo_redo->add_undo_method(key_editor,"remove_animation",anim); - undo_redo->commit_action(); -} - -void AnimationPlayerEditor::_editor_load(){ - - Ref<Animation> anim = key_editor->get_current_animation(); - if (anim.is_null()) - return; - - String existing = player->find_animation(anim); - if (existing!="") { - _select_anim_by_name(existing); - return; //already has - } - - int count=1; - String base=anim->get_name(); - bool noname=false; - if (base=="") { - base="New Anim"; - noname=true; - } - - while(true) { - String attempt = base; - if (count>1) - attempt+=" ("+itos(count)+")"; - if (player->has_animation(attempt)) { - count++; - continue; - } - base=attempt; - break; - } - - if (noname) - anim->set_name(base); - - undo_redo->create_action("Add Animation From Editor"); - undo_redo->add_do_method(player,"add_animation",base,anim); - undo_redo->add_undo_method(player,"remove_animation",base); - undo_redo->add_do_method(this,"_animation_player_changed",player); - undo_redo->add_undo_method(this,"_animation_player_changed",player); - undo_redo->commit_action(); - - _select_anim_by_name(base); - - -} -#endif - -void AnimationPlayerEditor::_animation_key_editor_anim_len_changed(float p_len) { - - - frame->set_max(p_len); - -} - -void AnimationPlayerEditor::_animation_key_editor_anim_step_changed(float p_len) { - - if (p_len) - frame->set_step(p_len); - else - frame->set_step(0.00001); - -} - - -void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos,bool p_drag) { - - if (!is_visible_in_tree()) - return; - if (!player) - return; - - if (player->is_playing() ) - return; - - updating=true; - frame->set_value(p_pos); - updating=false; - _seek_value_changed(p_pos,!p_drag); - - EditorNode::get_singleton()->get_property_editor()->refresh(); - - - - //seekit -} - -void AnimationPlayerEditor::_hide_anim_editors() { - - player=NULL; - hide(); - set_process(false); - - key_editor->set_animation(Ref<Animation>()); - key_editor->set_root(NULL); - key_editor->show_select_node_warning(true); - //editor->animation_editor_make_visible(false); - -} - - -void AnimationPlayerEditor::_animation_tool_menu(int p_option) { - - switch(p_option) { - - case TOOL_COPY_ANIM: { - - if (!animation->get_item_count()) { - error_dialog->set_text(TTR("ERROR: No animation to copy!")); - error_dialog->popup_centered_minsize(); - return; - } - - String current = animation->get_item_text(animation->get_selected()); - Ref<Animation> anim = player->get_animation(current); - //editor->edit_resource(anim); - EditorSettings::get_singleton()->set_resource_clipboard(anim); - - } break; - case TOOL_PASTE_ANIM: { - - Ref<Animation> anim = EditorSettings::get_singleton()->get_resource_clipboard(); - if (!anim.is_valid()) { - error_dialog->set_text(TTR("ERROR: No animation resource on clipboard!")); - error_dialog->popup_centered_minsize(); - return; - } - - String name = anim->get_name(); - if (name=="") { - name=TTR("Pasted Animation"); - } - - int idx=1; - String base = name; - while (player->has_animation(name)) { - - idx++; - name=base+" "+itos(idx); - } - - undo_redo->create_action(TTR("Paste Animation")); - undo_redo->add_do_method(player,"add_animation",name,anim); - undo_redo->add_undo_method(player,"remove_animation",name); - undo_redo->add_do_method(this,"_animation_player_changed",player); - undo_redo->add_undo_method(this,"_animation_player_changed",player); - undo_redo->commit_action(); - - _select_anim_by_name(name); - - - } break; - case TOOL_EDIT_RESOURCE: { - - if (!animation->get_item_count()) { - error_dialog->set_text(TTR("ERROR: No animation to edit!")); - error_dialog->popup_centered_minsize(); - return; - } - - String current = animation->get_item_text(animation->get_selected()); - Ref<Animation> anim = player->get_animation(current); - editor->edit_resource(anim); - - } break; - - } -} - -void AnimationPlayerEditor::_animation_save_menu(int p_option) { - - String current = animation->get_item_text(animation->get_selected()); - if (current != "") { - Ref<Animation> anim = player->get_animation(current); - - switch (p_option) { - case ANIM_SAVE: - _animation_save(anim); - break; - case ANIM_SAVE_AS: - _animation_save_as(anim); - break; - } - } -} - -void AnimationPlayerEditor::_unhandled_key_input(const InputEvent& p_ev) { - - if (is_visible_in_tree() && p_ev.type==InputEvent::KEY && p_ev.key.pressed && !p_ev.key.echo && !p_ev.key.mod.alt && !p_ev.key.mod.control && !p_ev.key.mod.meta) { - - switch(p_ev.key.scancode) { - - case KEY_A: { - if (!p_ev.key.mod.shift) - _play_bw_from_pressed(); - else - _play_bw_pressed(); - } break; - case KEY_S: { - _stop_pressed(); - } break; - case KEY_D: { - if (!p_ev.key.mod.shift) - _play_from_pressed(); - else - _play_pressed(); - } break; - } - } -} - -void AnimationPlayerEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_gui_input"),&AnimationPlayerEditor::_gui_input); - ClassDB::bind_method(D_METHOD("_node_removed"),&AnimationPlayerEditor::_node_removed); - ClassDB::bind_method(D_METHOD("_play_pressed"),&AnimationPlayerEditor::_play_pressed); - ClassDB::bind_method(D_METHOD("_play_from_pressed"),&AnimationPlayerEditor::_play_from_pressed); - ClassDB::bind_method(D_METHOD("_play_bw_pressed"),&AnimationPlayerEditor::_play_bw_pressed); - ClassDB::bind_method(D_METHOD("_play_bw_from_pressed"),&AnimationPlayerEditor::_play_bw_from_pressed); - ClassDB::bind_method(D_METHOD("_stop_pressed"),&AnimationPlayerEditor::_stop_pressed); - ClassDB::bind_method(D_METHOD("_autoplay_pressed"),&AnimationPlayerEditor::_autoplay_pressed); - ClassDB::bind_method(D_METHOD("_pause_pressed"),&AnimationPlayerEditor::_pause_pressed); - ClassDB::bind_method(D_METHOD("_animation_selected"),&AnimationPlayerEditor::_animation_selected); - ClassDB::bind_method(D_METHOD("_animation_name_edited"),&AnimationPlayerEditor::_animation_name_edited); - ClassDB::bind_method(D_METHOD("_animation_new"),&AnimationPlayerEditor::_animation_new); - ClassDB::bind_method(D_METHOD("_animation_rename"),&AnimationPlayerEditor::_animation_rename); - ClassDB::bind_method(D_METHOD("_animation_load"),&AnimationPlayerEditor::_animation_load); - ClassDB::bind_method(D_METHOD("_animation_remove"),&AnimationPlayerEditor::_animation_remove); - ClassDB::bind_method(D_METHOD("_animation_remove_confirmed"),&AnimationPlayerEditor::_animation_remove_confirmed); - ClassDB::bind_method(D_METHOD("_animation_blend"),&AnimationPlayerEditor::_animation_blend); - ClassDB::bind_method(D_METHOD("_animation_edit"),&AnimationPlayerEditor::_animation_edit); - ClassDB::bind_method(D_METHOD("_animation_resource_edit"),&AnimationPlayerEditor::_animation_resource_edit); - ClassDB::bind_method(D_METHOD("_dialog_action"),&AnimationPlayerEditor::_dialog_action); - ClassDB::bind_method(D_METHOD("_seek_value_changed"),&AnimationPlayerEditor::_seek_value_changed,DEFVAL(true)); - ClassDB::bind_method(D_METHOD("_animation_player_changed"),&AnimationPlayerEditor::_animation_player_changed); - ClassDB::bind_method(D_METHOD("_blend_edited"),&AnimationPlayerEditor::_blend_edited); - //ClassDB::bind_method(D_METHOD("_seek_frame_changed"),&AnimationPlayerEditor::_seek_frame_changed); - ClassDB::bind_method(D_METHOD("_scale_changed"),&AnimationPlayerEditor::_scale_changed); - //ClassDB::bind_method(D_METHOD("_editor_store_all"),&AnimationPlayerEditor::_editor_store_all); - //ClassDB::bind_method(D_METHOD("_editor_load_all"),&AnimationPlayerEditor::_editor_load_all); - ClassDB::bind_method(D_METHOD("_list_changed"),&AnimationPlayerEditor::_list_changed); - ClassDB::bind_method(D_METHOD("_animation_key_editor_seek"),&AnimationPlayerEditor::_animation_key_editor_seek); - ClassDB::bind_method(D_METHOD("_animation_key_editor_anim_len_changed"),&AnimationPlayerEditor::_animation_key_editor_anim_len_changed); - ClassDB::bind_method(D_METHOD("_animation_key_editor_anim_step_changed"),&AnimationPlayerEditor::_animation_key_editor_anim_step_changed); - ClassDB::bind_method(D_METHOD("_hide_anim_editors"),&AnimationPlayerEditor::_hide_anim_editors); - ClassDB::bind_method(D_METHOD("_animation_duplicate"),&AnimationPlayerEditor::_animation_duplicate); - ClassDB::bind_method(D_METHOD("_blend_editor_next_changed"),&AnimationPlayerEditor::_blend_editor_next_changed); - ClassDB::bind_method(D_METHOD("_unhandled_key_input"),&AnimationPlayerEditor::_unhandled_key_input); - ClassDB::bind_method(D_METHOD("_animation_tool_menu"),&AnimationPlayerEditor::_animation_tool_menu); - ClassDB::bind_method(D_METHOD("_animation_save_menu"), &AnimationPlayerEditor::_animation_save_menu); - - - - -} - -AnimationPlayerEditor *AnimationPlayerEditor::singleton=NULL; - -AnimationPlayer *AnimationPlayerEditor::get_player() const { - - return player; -} -AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { - editor=p_editor; - singleton=this; - - updating=false; - - set_focus_mode(FOCUS_ALL); - - player=NULL; - add_style_override("panel", get_stylebox("panel","Panel")); - - - Label * l; - - /*l= memnew( Label ); - l->set_text("Animation Player:"); - add_child(l);*/ - - HBoxContainer *hb = memnew( HBoxContainer ); - add_child(hb); - - - play_bw_from = memnew( ToolButton ); - play_bw_from->set_tooltip(TTR("Play selected animation backwards from current pos. (A)")); - hb->add_child(play_bw_from); - - play_bw = memnew( ToolButton ); - play_bw->set_tooltip(TTR("Play selected animation backwards from end. (Shift+A)")); - hb->add_child(play_bw); - - stop = memnew( ToolButton ); - stop->set_toggle_mode(true); - hb->add_child(stop); - stop->set_tooltip(TTR("Stop animation playback. (S)")); - - play = memnew( ToolButton ); - play->set_tooltip(TTR("Play selected animation from start. (Shift+D)")); - hb->add_child(play); - - - play_from = memnew( ToolButton ); - play_from->set_tooltip(TTR("Play selected animation from current pos. (D)")); - hb->add_child(play_from); - - - - //pause = memnew( Button ); - //pause->set_toggle_mode(true); - //hb->add_child(pause); - - frame = memnew( SpinBox ); - hb->add_child(frame); - frame->set_custom_minimum_size(Size2(60,0)); - frame->set_stretch_ratio(2); - frame->set_tooltip(TTR("Animation position (in seconds).")); - - hb->add_child( memnew( VSeparator)); - - scale = memnew( LineEdit ); - hb->add_child(scale); - scale->set_h_size_flags(SIZE_EXPAND_FILL); - scale->set_stretch_ratio(1); - scale->set_tooltip(TTR("Scale animation playback globally for the node.")); - scale->hide(); - - - add_anim = memnew( ToolButton ); - ED_SHORTCUT("animation_player_editor/add_animation", TTR("Create new animation in player.")); - add_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/add_animation")); - add_anim->set_tooltip(TTR("Create new animation in player.")); - - hb->add_child(add_anim); - - - load_anim = memnew( ToolButton ); - ED_SHORTCUT("animation_player_editor/load_from_disk", TTR("Load animation from disk.")); - add_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/load_from_disk")); - load_anim->set_tooltip(TTR("Load an animation from disk.")); - hb->add_child(load_anim); - - save_anim = memnew(MenuButton); - save_anim->set_tooltip(TTR("Save the current animation")); - save_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/save", TTR("Save")), ANIM_SAVE); - save_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/save_as", TTR("Save As")), ANIM_SAVE_AS); - save_anim->set_focus_mode(Control::FOCUS_NONE); - hb->add_child(save_anim); - - accept = memnew(AcceptDialog); - add_child(accept); - accept->connect("confirmed", this, "_menu_confirm_current"); - - delete_dialog = memnew(ConfirmationDialog); - add_child(delete_dialog); - delete_dialog->connect("confirmed", this, "_animation_remove_confirmed"); - - duplicate_anim = memnew( ToolButton ); - hb->add_child(duplicate_anim); - ED_SHORTCUT("animation_player_editor/duplicate_animation", TTR("Duplicate Animation")); - duplicate_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/duplicate_animation")); - duplicate_anim->set_tooltip(TTR("Duplicate Animation")); - - rename_anim = memnew( ToolButton ); - hb->add_child(rename_anim); - ED_SHORTCUT("animation_player_editor/rename_animation", TTR("Rename Animation")); - rename_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/rename_animation")); - rename_anim->set_tooltip(TTR("Rename Animation")); - - remove_anim = memnew( ToolButton ); - hb->add_child(remove_anim); - ED_SHORTCUT("animation_player_editor/remove_animation", TTR("Remove Animation")); - remove_anim->set_shortcut(ED_GET_SHORTCUT("animation_player_editor/remove_animation")); - remove_anim->set_tooltip(TTR("Remove Animation")); - - - animation = memnew( OptionButton ); - hb->add_child(animation); - animation->set_h_size_flags(SIZE_EXPAND_FILL); - animation->set_tooltip(TTR("Display list of animations in player.")); - animation->set_clip_text(true); - - autoplay = memnew( ToolButton ); - hb->add_child(autoplay); - autoplay->set_tooltip(TTR("Autoplay on Load")); - - - - blend_anim = memnew( ToolButton ); - hb->add_child(blend_anim); - blend_anim->set_tooltip(TTR("Edit Target Blend Times")); - - tool_anim = memnew( MenuButton); - //tool_anim->set_flat(false); - tool_anim->set_tooltip(TTR("Animation Tools")); - tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/copy_animation", TTR("Copy Animation")),TOOL_COPY_ANIM); - tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/paste_animation", TTR("Paste Animation")),TOOL_PASTE_ANIM); - //tool_anim->get_popup()->add_separator(); - //tool_anim->get_popup()->add_item("Edit Anim Resource",TOOL_PASTE_ANIM); - hb->add_child(tool_anim); - - nodename = memnew( Button ); - hb->add_child(nodename); - pin = memnew( ToolButton ); - pin->set_toggle_mode(true); - hb->add_child(pin); - - - - resource_edit_anim= memnew( Button ); - hb->add_child(resource_edit_anim); - resource_edit_anim->hide(); - - - file = memnew(EditorFileDialog); - add_child(file); - - name_dialog = memnew( ConfirmationDialog ); - name_dialog->set_title(TTR("Create New Animation")); - name_dialog->set_hide_on_ok(false); - add_child(name_dialog); - name = memnew( LineEdit ); - name_dialog->add_child(name); - name->set_pos(Point2(18,30)); - name->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,10); - name_dialog->register_text_enter(name); - - - l = memnew( Label ); - l->set_text(TTR("Animation Name:")); - l->set_pos( Point2(10,10) ); - - name_dialog->add_child(l); - name_title=l; - - error_dialog = memnew( ConfirmationDialog ); - error_dialog->get_ok()->set_text(TTR("Close")); - //error_dialog->get_cancel()->set_text("Close"); - error_dialog->set_text(TTR("Error!")); - add_child(error_dialog); - - name_dialog->connect("confirmed", this,"_animation_name_edited"); - - blend_editor.dialog = memnew( AcceptDialog ); - add_child(blend_editor.dialog); - blend_editor.dialog->get_ok()->set_text(TTR("Close")); - blend_editor.dialog->set_hide_on_ok(true); - VBoxContainer *blend_vb = memnew( VBoxContainer); - blend_editor.dialog->add_child(blend_vb); - //blend_editor.dialog->set_child_rect(blend_vb); - blend_editor.tree = memnew( Tree ); - blend_editor.tree->set_columns(2); - blend_vb->add_margin_child(TTR("Blend Times:"),blend_editor.tree,true); - blend_editor.next = memnew( OptionButton ); - blend_vb->add_margin_child(TTR("Next (Auto Queue):"),blend_editor.next); - blend_editor.dialog->set_title(TTR("Cross-Animation Blend Times")); - updating_blends=false; - - blend_editor.tree->connect("item_edited",this,"_blend_edited"); - - - autoplay->connect("pressed", this,"_autoplay_pressed"); - autoplay->set_toggle_mode(true); - play->connect("pressed", this,"_play_pressed"); - play_from->connect("pressed", this,"_play_from_pressed"); - play_bw->connect("pressed", this,"_play_bw_pressed"); - play_bw_from->connect("pressed", this,"_play_bw_from_pressed"); - stop->connect("pressed", this,"_stop_pressed"); - //pause->connect("pressed", this,"_pause_pressed"); - add_anim->connect("pressed", this,"_animation_new"); - rename_anim->connect("pressed", this,"_animation_rename"); - load_anim->connect("pressed", this,"_animation_load"); - duplicate_anim->connect("pressed", this,"_animation_duplicate"); - //frame->connect("text_entered", this,"_seek_frame_changed"); - - blend_anim->connect("pressed", this,"_animation_blend"); - remove_anim->connect("pressed", this,"_animation_remove"); - animation->connect("item_selected", this,"_animation_selected",Vector<Variant>(),true); - resource_edit_anim->connect("pressed", this,"_animation_resource_edit"); - file->connect("file_selected", this,"_dialog_action"); - frame->connect("value_changed", this, "_seek_value_changed",Vector<Variant>(),true); - scale->connect("text_entered", this, "_scale_changed",Vector<Variant>(),true); - - - - renaming=false; - last_active=false; - - set_process_unhandled_key_input(true); - - key_editor = memnew( AnimationKeyEditor); - add_child(key_editor); - add_constant_override("separation",get_constant("separation","VBoxContainer")); - key_editor->set_v_size_flags(SIZE_EXPAND_FILL); - key_editor->connect("timeline_changed",this,"_animation_key_editor_seek"); - key_editor->connect("animation_len_changed",this,"_animation_key_editor_anim_len_changed"); - key_editor->connect("animation_step_changed",this,"_animation_key_editor_anim_step_changed"); - - _update_player(); -} - - -void AnimationPlayerEditorPlugin::edit(Object *p_object) { - - anim_editor->set_undo_redo(&get_undo_redo()); - if (!p_object) - return; - anim_editor->edit(p_object->cast_to<AnimationPlayer>()); - - -} - -bool AnimationPlayerEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("AnimationPlayer"); -} - -void AnimationPlayerEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - - editor->make_bottom_panel_item_visible(anim_editor); - anim_editor->set_process(true); - anim_editor->ensure_visibility(); - //editor->animation_panel_make_visible(true); - } else { - - //anim_editor->hide(); - //anim_editor->set_idle_process(false); - } - -} - -AnimationPlayerEditorPlugin::AnimationPlayerEditorPlugin(EditorNode *p_node) { - - editor=p_node; - anim_editor = memnew( AnimationPlayerEditor(editor) ); - anim_editor->set_undo_redo(editor->get_undo_redo()); - - editor->add_bottom_panel_item(TTR("Animation"),anim_editor); - /* - editor->get_viewport()->add_child(anim_editor); - anim_editor->set_area_as_parent_rect(); - anim_editor->set_anchor( MARGIN_TOP, Control::ANCHOR_END); - anim_editor->set_margin( MARGIN_TOP, 75 ); - anim_editor->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END); - anim_editor->set_margin( MARGIN_RIGHT, 0 );*/ - anim_editor->hide(); - - - -} - - -AnimationPlayerEditorPlugin::~AnimationPlayerEditorPlugin() -{ -} diff --git a/tools/editor/plugins/animation_player_editor_plugin.h b/tools/editor/plugins/animation_player_editor_plugin.h deleted file mode 100644 index e28600a7ab..0000000000 --- a/tools/editor/plugins/animation_player_editor_plugin.h +++ /dev/null @@ -1,219 +0,0 @@ -/*************************************************************************/ -/* animation_player_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef ANIMATION_PLAYER_EDITOR_PLUGIN_H -#define ANIMATION_PLAYER_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/animation/animation_player.h" -#include "scene/gui/dialogs.h" -#include "scene/gui/texture_button.h" -#include "scene/gui/slider.h" -#include "scene/gui/spin_box.h" - - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ -class AnimationKeyEditor; -class AnimationPlayerEditor : public VBoxContainer { - - GDCLASS(AnimationPlayerEditor, VBoxContainer ); - - EditorNode *editor; - AnimationPlayer *player; - - enum { - TOOL_COPY_ANIM, - TOOL_PASTE_ANIM, - TOOL_EDIT_RESOURCE - }; - - enum { - ANIM_SAVE, - ANIM_SAVE_AS - }; - - enum { - RESOURCE_LOAD, - RESOURCE_SAVE - }; - - - OptionButton *animation; - Button *stop; - Button *play; - Button *play_from; - Button *play_bw; - Button *play_bw_from; - - //Button *pause; - Button *add_anim; - Button *autoplay; - Button *rename_anim; - Button *duplicate_anim; - - Button *resource_edit_anim; - Button *load_anim; - MenuButton *save_anim; - Button *blend_anim; - Button *remove_anim; - MenuButton *tool_anim; - ToolButton *pin; - Button *nodename; - SpinBox *frame; - LineEdit *scale; - LineEdit *name; - Label *name_title; - UndoRedo *undo_redo; - Ref<Texture> autoplay_icon; - bool last_active; - - EditorFileDialog *file; - AcceptDialog *accept; - ConfirmationDialog* delete_dialog; - int current_option; - - struct BlendEditor { - - AcceptDialog * dialog; - Tree *tree; - OptionButton *next; - - } blend_editor; - - - ConfirmationDialog *name_dialog; - ConfirmationDialog *error_dialog; - bool renaming; - - - bool updating; - bool updating_blends; - - AnimationKeyEditor *key_editor; - - - void _select_anim_by_name(const String& p_anim); - void _play_pressed(); - void _play_from_pressed(); - void _play_bw_pressed(); - void _play_bw_from_pressed(); - void _autoplay_pressed(); - void _stop_pressed(); - void _pause_pressed(); - void _animation_selected(int p_which); - void _animation_new(); - void _animation_rename(); - void _animation_name_edited(); - void _animation_load(); - - void _animation_save_in_path(const Ref<Resource>& p_resource, const String& p_path); - void _animation_save(const Ref<Resource>& p_resource); - void _animation_save_as(const Ref<Resource>& p_resource); - - void _animation_remove(); - void _animation_remove_confirmed(); - void _animation_blend(); - void _animation_edit(); - void _animation_duplicate(); - void _animation_resource_edit(); - void _scale_changed(const String& p_scale); - void _dialog_action(String p_file); - void _seek_frame_changed(const String& p_frame); - void _seek_value_changed(float p_value, bool p_set=false); - void _blend_editor_next_changed(const int p_idx); - - void _list_changed(); - void _update_animation(); - void _update_player(); - void _blend_edited(); - - - void _hide_anim_editors(); - - void _animation_player_changed(Object *p_pl); - - void _animation_key_editor_seek(float p_pos, bool p_drag); - void _animation_key_editor_anim_len_changed(float p_new); - void _animation_key_editor_anim_step_changed(float p_len); - - void _unhandled_key_input(const InputEvent& p_ev); - void _animation_tool_menu(int p_option); - void _animation_save_menu(int p_option); - - - AnimationPlayerEditor(); -protected: - - void _notification(int p_what); - void _gui_input(InputEvent p_event); - void _node_removed(Node *p_node); - static void _bind_methods(); -public: - - AnimationPlayer *get_player() const; - static AnimationPlayerEditor *singleton; - - AnimationKeyEditor* get_key_editor() { return key_editor; } - Dictionary get_state() const; - void set_state(const Dictionary& p_state); - - - void ensure_visibility(); - - void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo=p_undo_redo; } - void edit(AnimationPlayer *p_player); - AnimationPlayerEditor(EditorNode *p_editor); -}; - -class AnimationPlayerEditorPlugin : public EditorPlugin { - - GDCLASS( AnimationPlayerEditorPlugin, EditorPlugin ); - - AnimationPlayerEditor *anim_editor; - EditorNode *editor; - -public: - - virtual Dictionary get_state() const { return anim_editor->get_state(); } - virtual void set_state(const Dictionary& p_state) { anim_editor->set_state(p_state); } - - virtual String get_name() const { return "Anim"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - AnimationPlayerEditorPlugin(EditorNode *p_node); - ~AnimationPlayerEditorPlugin(); - -}; - -#endif // ANIMATION_PLAYER_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/animation_tree_editor_plugin.h b/tools/editor/plugins/animation_tree_editor_plugin.h deleted file mode 100644 index 253ad1878d..0000000000 --- a/tools/editor/plugins/animation_tree_editor_plugin.h +++ /dev/null @@ -1,194 +0,0 @@ -/*************************************************************************/ -/* animation_tree_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef ANIMATION_TREE_EDITOR_PLUGIN_H -#define ANIMATION_TREE_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/animation/animation_tree_player.h" -#include "scene/gui/tree.h" -#include "scene/gui/button.h" -#include "scene/gui/popup.h" -#include "tools/editor/property_editor.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -class AnimationTreeEditor : public Control { - - GDCLASS(AnimationTreeEditor, Control ); - - static const char* _node_type_names[]; - - enum ClickType { - CLICK_NONE, - CLICK_NAME, - CLICK_NODE, - CLICK_INPUT_SLOT, - CLICK_OUTPUT_SLOT, - CLICK_PARAMETER - }; - - enum { - - MENU_GRAPH_CLEAR=100, - MENU_IMPORT_ANIMATIONS=101, - NODE_DISCONNECT, - NODE_RENAME, - NODE_ERASE, - NODE_ADD_INPUT, - NODE_DELETE_INPUT, - NODE_SET_AUTOADVANCE, - NODE_CLEAR_AUTOADVANCE - }; - - bool renaming_edit; - StringName edited_node; - bool updating_edit; - Popup *edit_dialog; - HSlider *edit_scroll[2]; - LineEdit *edit_line[4]; - OptionButton *edit_option; - Label *edit_label[4]; - Button *edit_button; - Button *filter_button; - CheckButton *edit_check; - EditorFileDialog* file_dialog; - int file_op; - - void _popup_edit_dialog(); - - - void _setup_edit_dialog(const StringName& p_node); - PopupMenu *master_anim_popup; - PopupMenu *node_popup; - PopupMenu *add_popup; - HScrollBar *h_scroll; - VScrollBar *v_scroll; - MenuButton* add_menu; - - CustomPropertyEditor *property_editor; - - AnimationTreePlayer* anim_tree; - List<StringName> order; - Set<StringName> active_nodes; - - int last_x,last_y; - - Point2 offset; - ClickType click_type; - Point2 click_pos; - StringName click_node; - int click_slot; - Point2 click_motion; - ClickType rclick_type; - StringName rclick_node; - int rclick_slot; - - Button *play_button; - - Size2 _get_maximum_size(); - Size2 get_node_size(const StringName &p_node) const; - void _draw_node(const StringName& p_node); - - AcceptDialog *filter_dialog; - Tree *filter; - - - - void _draw_cos_line(const Vector2& p_from, const Vector2& p_to,const Color& p_color); - void _update_scrollbars(); - void _scroll_moved(float); - void _play_toggled(); -/* - void _node_param_changed(); - void _node_add_callback(); - void _node_add(VisualServer::AnimationTreeNodeType p_type); - void _node_edit_property(const StringName& p_node); -*/ - - void _master_anim_menu_item(int p_item); - void _node_menu_item(int p_item); - void _add_menu_item(int p_item); - - - void _filter_edited(); - void _find_paths_for_filter(const StringName& p_node,Set<String>& paths); - void _edit_filters(); - - - void _edit_oneshot_start(); - void _edit_dialog_animation_changed(); - void _edit_dialog_edit_animation(); - void _edit_dialog_changeds(String); - void _edit_dialog_changede(String); - void _edit_dialog_changedf(float); - void _edit_dialog_changed(); - void _dialog_changed() const; - ClickType _locate_click(const Point2& p_click,StringName *p_node_id,int *p_slot_index) const; - Point2 _get_slot_pos(const StringName& p_node_id,bool p_input,int p_slot); - - StringName _add_node(int p_item); - void _file_dialog_selected(String p_path); - - -protected: - void _notification(int p_what); - void _gui_input(InputEvent p_event); - static void _bind_methods(); -public: - - - virtual Size2 get_minimum_size() const; - void edit(AnimationTreePlayer *p_player); - AnimationTreeEditor(); -}; - -class AnimationTreeEditorPlugin : public EditorPlugin { - - GDCLASS( AnimationTreeEditorPlugin, EditorPlugin ); - - AnimationTreeEditor *anim_tree_editor; - EditorNode *editor; - Button *button; - -public: - - virtual String get_name() const { return "AnimTree"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - AnimationTreeEditorPlugin(EditorNode *p_node); - ~AnimationTreeEditorPlugin(); - -}; - -#endif // ANIMATION_TREE_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/baked_light_baker.cpp b/tools/editor/plugins/baked_light_baker.cpp deleted file mode 100644 index 4219e791d1..0000000000 --- a/tools/editor/plugins/baked_light_baker.cpp +++ /dev/null @@ -1,2731 +0,0 @@ -/*************************************************************************/ -/* baked_light_baker.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 "baked_light_baker.h" - -#include <stdlib.h> -#include <cmath> -#include "io/marshalls.h" -#include "tools/editor/editor_node.h" -#include "tools/editor/editor_settings.h" - -#if 0 -void baked_light_baker_add_64f(double *dst,double value); -void baked_light_baker_add_64i(int64_t *dst,int64_t value); - -//-separar en 2 testuras? -//*mejorar performance y threads -//*modos lineales -//*saturacion - -_FORCE_INLINE_ static uint64_t get_uv_normal_bit(const Vector3& p_vector) { - - int lat = Math::fast_ftoi(Math::floor(Math::acos(p_vector.dot(Vector3(0,1,0)))*6.0/Math_PI+0.5)); - - if (lat==0) { - return 60; - } else if (lat==6) { - return 61; - } - - int lon = Math::fast_ftoi(Math::floor( (Math_PI+Math::atan2(p_vector.x,p_vector.z))*12.0/(Math_PI*2.0) + 0.5))%12; - - return lon+(lat-1)*12; -} - - - -_FORCE_INLINE_ static Vector3 get_bit_normal(int p_bit) { - - if (p_bit==61) { - return Vector3(0,1,0); - } else if (p_bit==62){ - return Vector3(0,-1,0); - } - - float latang = ((p_bit / 12)+1)*Math_PI/6.0; - - Vector2 latv(Math::sin(latang),Math::cos(latang)); - - float lonang = ((p_bit%12)*Math_PI*2.0/12.0)-Math_PI; - - Vector2 lonv(Math::sin(lonang),Math::cos(lonang)); - - return Vector3(lonv.x*latv.x,latv.y,lonv.y*latv.x).normalized(); - -} - - -BakedLightBaker::MeshTexture* BakedLightBaker::_get_mat_tex(const Ref<Texture>& p_tex) { - - if (!tex_map.has(p_tex)) { - - Ref<ImageTexture> imgtex=p_tex; - if (imgtex.is_null()) - return NULL; - Image image=imgtex->get_data(); - if (image.empty()) - return NULL; - - if (image.get_format()!=Image::FORMAT_RGBA8) { - if (image.get_format()>Image::FORMAT_INDEXED_ALPHA) { - Error err = image.decompress(); - if (err) - return NULL; - } - - if (image.get_format()!=Image::FORMAT_RGBA8) - image.convert(Image::FORMAT_RGBA8); - } - - if (imgtex->get_flags()&Texture::FLAG_CONVERT_TO_LINEAR) { - Image copy = image; - copy.srgb_to_linear(); - image=copy; - } - - PoolVector<uint8_t> dvt=image.get_data(); - PoolVector<uint8_t>::Read r=dvt.read(); - MeshTexture mt; - mt.tex_w=image.get_width(); - mt.tex_h=image.get_height(); - int len = image.get_width()*image.get_height()*4; - mt.tex.resize(len); - copymem(mt.tex.ptr(),r.ptr(),len); - - textures.push_back(mt); - tex_map[p_tex]=&textures.back()->get(); - } - - return tex_map[p_tex]; -} - - -void BakedLightBaker::_add_mesh(const Ref<Mesh>& p_mesh,const Ref<Material>& p_mat_override,const Transform& p_xform,int p_baked_texture) { - - - for(int i=0;i<p_mesh->get_surface_count();i++) { - - if (p_mesh->surface_get_primitive_type(i)!=Mesh::PRIMITIVE_TRIANGLES) - continue; - Ref<Material> mat = p_mat_override.is_valid()?p_mat_override:p_mesh->surface_get_material(i); - - MeshMaterial *matptr=NULL; - int baked_tex=p_baked_texture; - - if (mat.is_valid()) { - - if (!mat_map.has(mat)) { - - MeshMaterial mm; - - Ref<FixedSpatialMaterial> fm = mat; - if (fm.is_valid()) { - //fixed route - mm.diffuse.color=fm->get_parameter(FixedSpatialMaterial::PARAM_DIFFUSE); - if (linear_color) - mm.diffuse.color=mm.diffuse.color.to_linear(); - mm.diffuse.tex=_get_mat_tex(fm->get_texture(FixedSpatialMaterial::PARAM_DIFFUSE)); - mm.specular.color=fm->get_parameter(FixedSpatialMaterial::PARAM_SPECULAR); - if (linear_color) - mm.specular.color=mm.specular.color.to_linear(); - - mm.specular.tex=_get_mat_tex(fm->get_texture(FixedSpatialMaterial::PARAM_SPECULAR)); - } else { - - mm.diffuse.color=Color(1,1,1,1); - mm.diffuse.tex=NULL; - mm.specular.color=Color(0,0,0,1); - mm.specular.tex=NULL; - } - - materials.push_back(mm); - mat_map[mat]=&materials.back()->get(); - - } - - matptr=mat_map[mat]; - - } - - - int facecount=0; - - - if (p_mesh->surface_get_format(i)&Mesh::ARRAY_FORMAT_INDEX) { - - facecount=p_mesh->surface_get_array_index_len(i); - } else { - - facecount=p_mesh->surface_get_array_len(i); - } - - ERR_CONTINUE((facecount==0 || (facecount%3)!=0)); - - facecount/=3; - - int tbase=triangles.size(); - triangles.resize(facecount+tbase); - - - Array a = p_mesh->surface_get_arrays(i); - - PoolVector<Vector3> vertices = a[Mesh::ARRAY_VERTEX]; - PoolVector<Vector3>::Read vr=vertices.read(); - PoolVector<Vector2> uv; - PoolVector<Vector2>::Read uvr; - PoolVector<Vector2> uv2; - PoolVector<Vector2>::Read uv2r; - PoolVector<Vector3> normal; - PoolVector<Vector3>::Read normalr; - bool read_uv=false; - bool read_normal=false; - - if (p_mesh->surface_get_format(i)&Mesh::ARRAY_FORMAT_TEX_UV) { - - uv=a[Mesh::ARRAY_TEX_UV]; - uvr=uv.read(); - read_uv=true; - - if (mat.is_valid() && mat->get_flag(Material::FLAG_LIGHTMAP_ON_UV2) && p_mesh->surface_get_format(i)&Mesh::ARRAY_FORMAT_TEX_UV2) { - - uv2=a[Mesh::ARRAY_TEX_UV2]; - uv2r=uv2.read(); - - } else { - uv2r=uv.read(); - if (baked_light->get_transfer_lightmaps_only_to_uv2()) { - baked_tex=-1; - } - } - } - - if (p_mesh->surface_get_format(i)&Mesh::ARRAY_FORMAT_NORMAL) { - - normal=a[Mesh::ARRAY_NORMAL]; - normalr=normal.read(); - read_normal=true; - } - - Matrix3 normal_xform = p_xform.basis.inverse().transposed(); - - - if (p_mesh->surface_get_format(i)&Mesh::ARRAY_FORMAT_INDEX) { - - PoolVector<int> indices = a[Mesh::ARRAY_INDEX]; - PoolVector<int>::Read ir = indices.read(); - - for(int i=0;i<facecount;i++) { - Triangle &t=triangles[tbase+i]; - t.vertices[0]=p_xform.xform(vr[ ir[i*3+0] ]); - t.vertices[1]=p_xform.xform(vr[ ir[i*3+1] ]); - t.vertices[2]=p_xform.xform(vr[ ir[i*3+2] ]); - t.material=matptr; - t.baked_texture=baked_tex; - if (read_uv) { - - t.uvs[0]=uvr[ ir[i*3+0] ]; - t.uvs[1]=uvr[ ir[i*3+1] ]; - t.uvs[2]=uvr[ ir[i*3+2] ]; - - t.bake_uvs[0]=uv2r[ ir[i*3+0] ]; - t.bake_uvs[1]=uv2r[ ir[i*3+1] ]; - t.bake_uvs[2]=uv2r[ ir[i*3+2] ]; - } - if (read_normal) { - - t.normals[0]=normal_xform.xform(normalr[ ir[i*3+0] ]).normalized(); - t.normals[1]=normal_xform.xform(normalr[ ir[i*3+1] ]).normalized(); - t.normals[2]=normal_xform.xform(normalr[ ir[i*3+2] ]).normalized(); - } - } - - } else { - - for(int i=0;i<facecount;i++) { - Triangle &t=triangles[tbase+i]; - t.vertices[0]=p_xform.xform(vr[ i*3+0 ]); - t.vertices[1]=p_xform.xform(vr[ i*3+1 ]); - t.vertices[2]=p_xform.xform(vr[ i*3+2 ]); - t.material=matptr; - t.baked_texture=baked_tex; - if (read_uv) { - - t.uvs[0]=uvr[ i*3+0 ]; - t.uvs[1]=uvr[ i*3+1 ]; - t.uvs[2]=uvr[ i*3+2 ]; - - t.bake_uvs[0]=uv2r[ i*3+0 ]; - t.bake_uvs[1]=uv2r[ i*3+1 ]; - t.bake_uvs[2]=uv2r[ i*3+2 ]; - - } - if (read_normal) { - - t.normals[0]=normal_xform.xform(normalr[ i*3+0 ]).normalized(); - t.normals[1]=normal_xform.xform(normalr[ i*3+1 ]).normalized(); - t.normals[2]=normal_xform.xform(normalr[ i*3+2 ]).normalized(); - } - } - } - } - -} - - -void BakedLightBaker::_parse_geometry(Node* p_node) { - - if (p_node->cast_to<MeshInstance>()) { - - MeshInstance *meshi=p_node->cast_to<MeshInstance>(); - Ref<Mesh> mesh=meshi->get_mesh(); - if (mesh.is_valid()) { - _add_mesh(mesh,meshi->get_material_override(),base_inv * meshi->get_global_transform(),meshi->get_baked_light_texture_id()); - } - } else if (p_node->cast_to<Light>()) { - - Light *dl=p_node->cast_to<Light>(); - - if (dl->get_bake_mode()!=Light::BAKE_MODE_DISABLED) { - - - LightData dirl; - dirl.type=VS::LightType(dl->get_light_type()); - dirl.diffuse=dl->get_color(DirectionalLight::COLOR_DIFFUSE); - dirl.specular=dl->get_color(DirectionalLight::COLOR_SPECULAR); - if (linear_color) - dirl.diffuse=dirl.diffuse.to_linear(); - if (linear_color) - dirl.specular=dirl.specular.to_linear(); - - dirl.energy=dl->get_parameter(DirectionalLight::PARAM_ENERGY); - dirl.pos=dl->get_global_transform().origin; - dirl.up=dl->get_global_transform().basis.get_axis(1).normalized(); - dirl.left=dl->get_global_transform().basis.get_axis(0).normalized(); - dirl.dir=-dl->get_global_transform().basis.get_axis(2).normalized(); - dirl.spot_angle=dl->get_parameter(DirectionalLight::PARAM_SPOT_ANGLE); - dirl.spot_attenuation=dl->get_parameter(DirectionalLight::PARAM_SPOT_ATTENUATION); - dirl.attenuation=dl->get_parameter(DirectionalLight::PARAM_ATTENUATION); - dirl.darkening=dl->get_parameter(DirectionalLight::PARAM_SHADOW_DARKENING); - dirl.radius=dl->get_parameter(DirectionalLight::PARAM_RADIUS); - dirl.bake_direct=dl->get_bake_mode()==Light::BAKE_MODE_FULL; - dirl.rays_thrown=0; - dirl.bake_shadow=dl->get_bake_mode()==Light::BAKE_MODE_INDIRECT_AND_SHADOWS; - lights.push_back(dirl); - } - - } else if (p_node->cast_to<Spatial>()){ - - Spatial *sp = p_node->cast_to<Spatial>(); - - Array arr = p_node->call("_get_baked_light_meshes"); - for(int i=0;i<arr.size();i+=2) { - - Transform xform=arr[i]; - Ref<Mesh> mesh=arr[i+1]; - _add_mesh(mesh,Ref<Material>(),base_inv * (sp->get_global_transform() * xform)); - } - } - - for(int i=0;i<p_node->get_child_count();i++) { - - _parse_geometry(p_node->get_child(i)); - } -} - - -void BakedLightBaker::_fix_lights() { - - - total_light_area=0; - for(int i=0;i<lights.size();i++) { - - LightData &dl=lights[i]; - - switch(dl.type) { - case VS::LIGHT_DIRECTIONAL: { - - float up_max=-1e10; - float dir_max=-1e10; - float left_max=-1e10; - float up_min=1e10; - float dir_min=1e10; - float left_min=1e10; - - for(int j=0;j<triangles.size();j++) { - - for(int k=0;k<3;k++) { - - Vector3 v = triangles[j].vertices[k]; - - float up_d = dl.up.dot(v); - float dir_d = dl.dir.dot(v); - float left_d = dl.left.dot(v); - - if (up_d>up_max) - up_max=up_d; - if (up_d<up_min) - up_min=up_d; - - if (left_d>left_max) - left_max=left_d; - if (left_d<left_min) - left_min=left_d; - - if (dir_d>dir_max) - dir_max=dir_d; - if (dir_d<dir_min) - dir_min=dir_d; - - } - } - - //make a center point, then the upvector and leftvector - dl.pos = dl.left*( left_max+left_min )*0.5 + dl.up*( up_max+up_min )*0.5 + dl.dir*(dir_min-(dir_max-dir_min)); - dl.left*=(left_max-left_min)*0.5; - dl.up*=(up_max-up_min)*0.5; - dl.length = (dir_max - dir_min)*10; //arbitrary number to keep it in scale - dl.area=dl.left.length()*2*dl.up.length()*2; - dl.constant=1.0/dl.area; - } break; - case VS::LIGHT_OMNI: - case VS::LIGHT_SPOT: { - - dl.attenuation_table.resize(ATTENUATION_CURVE_LEN); - for(int j=0;j<ATTENUATION_CURVE_LEN;j++) { - dl.attenuation_table[j]=1.0-Math::pow(j/float(ATTENUATION_CURVE_LEN),dl.attenuation); - float falloff=j*dl.radius/float(ATTENUATION_CURVE_LEN); - if (falloff==0) - falloff=0.000001; - float intensity=4*Math_PI*(falloff*falloff); - //dl.attenuation_table[j]*=falloff*falloff; - dl.attenuation_table[j]*=1.0/(3.0/intensity); - - } - if (dl.type==VS::LIGHT_OMNI) { - - dl.area=4.0*Math_PI*pow(dl.radius,2.0f); - dl.constant=1.0/3.5; - } else { - - - float r = Math::tan(Math::deg2rad(dl.spot_angle))*dl.radius; - float c = 1.0-(Math::deg2rad(dl.spot_angle)*0.5+0.5); - dl.constant=1.0/3.5; - dl.constant*=1.0/c; - - dl.area=Math_PI*r*r*c; - } - - } break; - - - } - - total_light_area+=dl.area; - } -} - -BakedLightBaker::BVH* BakedLightBaker::_parse_bvh(BVH** p_children, int p_size, int p_depth, int &max_depth) { - - if (p_depth>max_depth) { - max_depth=p_depth; - } - - if (p_size==1) { - - return p_children[0]; - } else if (p_size==0) { - - return NULL; - } - - - AABB aabb; - aabb=p_children[0]->aabb; - for(int i=1;i<p_size;i++) { - - aabb.merge_with(p_children[i]->aabb); - } - - int li=aabb.get_longest_axis_index(); - - switch(li) { - - case Vector3::AXIS_X: { - SortArray<BVH*,BVHCmpX> sort_x; - sort_x.nth_element(0,p_size,p_size/2,p_children); - //sort_x.sort(&p_bb[p_from],p_size); - } break; - case Vector3::AXIS_Y: { - SortArray<BVH*,BVHCmpY> sort_y; - sort_y.nth_element(0,p_size,p_size/2,p_children); - //sort_y.sort(&p_bb[p_from],p_size); - } break; - case Vector3::AXIS_Z: { - SortArray<BVH*,BVHCmpZ> sort_z; - sort_z.nth_element(0,p_size,p_size/2,p_children); - //sort_z.sort(&p_bb[p_from],p_size); - - } break; - } - - - BVH* left = _parse_bvh(p_children,p_size/2,p_depth+1,max_depth); - BVH* right = _parse_bvh(&p_children[p_size/2],p_size-p_size/2,p_depth+1,max_depth); - - BVH *_new = memnew(BVH); - _new->aabb=aabb; - _new->center=aabb.pos+aabb.size*0.5; - _new->children[0]=left; - _new->children[1]=right; - _new->leaf=NULL; - - return _new; -} - -void BakedLightBaker::_make_bvh() { - - Vector<BVH*> bases; - bases.resize(triangles.size()); - int max_depth=0; - for(int i=0;i<triangles.size();i++) { - bases[i]=memnew( BVH ); - bases[i]->leaf=&triangles[i]; - bases[i]->aabb.pos=triangles[i].vertices[0]; - bases[i]->aabb.expand_to(triangles[i].vertices[1]); - bases[i]->aabb.expand_to(triangles[i].vertices[2]); - triangles[i].aabb=bases[i]->aabb; - bases[i]->center=bases[i]->aabb.pos+bases[i]->aabb.size*0.5; - } - - bvh=_parse_bvh(bases.ptr(),bases.size(),1,max_depth); - - ray_stack = memnew_arr(uint32_t,max_depth); - bvh_stack = memnew_arr(BVH*,max_depth); - - bvh_depth = max_depth; -} - -void BakedLightBaker::_octree_insert(int p_octant,Triangle* p_triangle, int p_depth) { - - - - - uint32_t *stack=octant_stack; - uint32_t *ptr_stack=octantptr_stack; - Octant *octants=octant_pool.ptr(); - - stack[0]=0; - ptr_stack[0]=0; - - int stack_pos=0; - - - while(true) { - - Octant *octant=&octants[ptr_stack[stack_pos]]; - if (stack[stack_pos]<8) { - - int i = stack[stack_pos]; - stack[stack_pos]++; - - - - //fit_aabb=fit_aabb.grow(bvh->aabb.size.x*0.0001); - - int child_idx =octant->children[i]; - bool encloses; - if (!child_idx) { - - AABB aabb=octant->aabb; - aabb.size*=0.5; - if (i&1) - aabb.pos.x+=aabb.size.x; - if (i&2) - aabb.pos.y+=aabb.size.y; - if (i&4) - aabb.pos.z+=aabb.size.z; - - aabb.grow_by(cell_size*octree_extra_margin); - if (!aabb.intersects(p_triangle->aabb)) - continue; - encloses=aabb.grow(cell_size*-octree_extra_margin*2.0).encloses(p_triangle->aabb); - if (!encloses && !Face3(p_triangle->vertices[0],p_triangle->vertices[1],p_triangle->vertices[2]).intersects_aabb2(aabb)) - continue; - } else { - - Octant *child=&octants[child_idx]; - AABB aabb=child->aabb; - aabb.grow_by(cell_size*octree_extra_margin); - if (!aabb.intersects(p_triangle->aabb)) - continue; - encloses=aabb.grow(cell_size*-octree_extra_margin*2.0).encloses(p_triangle->aabb); - if (!encloses && !Face3(p_triangle->vertices[0],p_triangle->vertices[1],p_triangle->vertices[2]).intersects_aabb2(aabb)) - continue; - - } - - if (encloses) - stack[stack_pos]=8; // quick and dirty opt - - if (!child_idx) { - - - if (octant_pool_size==octant_pool.size()) { - octant_pool.resize(octant_pool_size+OCTANT_POOL_CHUNK); - octants=octant_pool.ptr(); - octant=&octants[ptr_stack[stack_pos]]; - } - child_idx=octant_pool_size++; - octant->children[i]=child_idx; - Octant *child=&octants[child_idx]; - - child->aabb=octant->aabb; - child->texture_x=0; - child->texture_y=0; - - child->aabb.size*=0.5; - if (i&1) - child->aabb.pos.x+=child->aabb.size.x; - if (i&2) - child->aabb.pos.y+=child->aabb.size.y; - if (i&4) - child->aabb.pos.z+=child->aabb.size.z; - - - child->full_accum[0]=0; - child->full_accum[1]=0; - child->full_accum[2]=0; - child->sampler_ofs=0; - - - - if (stack_pos==octree_depth-1) { - child->leaf=true; - child->offset[0]=child->aabb.pos.x+child->aabb.size.x*0.5; - child->offset[1]=child->aabb.pos.y+child->aabb.size.y*0.5; - child->offset[2]=child->aabb.pos.z+child->aabb.size.z*0.5; - child->next_leaf=leaf_list; - - - for(int ci=0;ci<8;ci++) { - child->normal_accum[ci][0]=0; - child->normal_accum[ci][1]=0; - child->normal_accum[ci][2]=0; - - } - - child->bake_neighbour=0; - child->first_neighbour=true; - leaf_list=child_idx; - cell_count++; - - for(int ci=0;ci<8;ci++) { - child->light_accum[ci][0]=0; - child->light_accum[ci][1]=0; - child->light_accum[ci][2]=0; - } - - child->parent=ptr_stack[stack_pos]; - - } else { - - child->leaf=false; - for(int j=0;j<8;j++) { - child->children[j]=0; - } - } - } - - if (!octants[child_idx].leaf) { - stack_pos++; - stack[stack_pos]=0; - ptr_stack[stack_pos]=child_idx; - } else { - - Octant *child=&octants[child_idx]; - - Vector3 n = Plane(p_triangle->vertices[0],p_triangle->vertices[1],p_triangle->vertices[2]).normal; - - - for(int ci=0;ci<8;ci++) { - - Vector3 pos = child->aabb.pos; - - if (ci&1) - pos.x+=child->aabb.size.x; - if (ci&2) - pos.y+=child->aabb.size.y; - if (ci&4) - pos.z+=child->aabb.size.z; - - - pos.x=floor((pos.x+cell_size*0.5)/cell_size); - pos.y=floor((pos.y+cell_size*0.5)/cell_size); - pos.z=floor((pos.z+cell_size*0.5)/cell_size); - - { - Map<Vector3,Vector3>::Element *E=endpoint_normal.find(pos); - if (!E) { - endpoint_normal[pos]=n; - } else { - E->get()+=n; - } - } - - { - - uint64_t bit = get_uv_normal_bit(n); - - Map<Vector3,uint64_t>::Element *E=endpoint_normal_bits.find(pos); - if (!E) { - endpoint_normal_bits[pos]=(1<<bit); - } else { - E->get()|=(1<<bit); - } - - } - - } - - } - - - } else { - stack_pos--; - if (stack_pos<0) - break; - } - } - - -} - - -void BakedLightBaker::_make_octree() { - - - AABB base = bvh->aabb; - float lal=base.get_longest_axis_size(); - //must be square because we want square blocks - base.size.x=lal; - base.size.y=lal; - base.size.z=lal; - base.grow_by(lal*0.001); //for precision - octree_aabb=base; - - cell_size=base.size.x; - for(int i=0;i<octree_depth;i++) - cell_size/=2.0; - octant_stack = memnew_arr(uint32_t,octree_depth*2 ); - octantptr_stack = memnew_arr(uint32_t,octree_depth*2 ); - - octant_pool.resize(OCTANT_POOL_CHUNK); - octant_pool_size=1; - Octant *root=octant_pool.ptr(); - root->leaf=false; - root->aabb=octree_aabb; - root->parent=-1; - for(int i=0;i<8;i++) - root->children[i]=0; - - EditorProgress ep("bake_octree",vformat(TTR("Parsing %d Triangles:"), triangles.size()),triangles.size()); - - for(int i=0;i<triangles.size();i++) { - - _octree_insert(0,&triangles[i],octree_depth-1); - if ((i%1000)==0) { - - ep.step(TTR("Triangle #")+itos(i),i); - } - } - - { - uint32_t oct_idx=leaf_list; - Octant *octants=octant_pool.ptr(); - while(oct_idx) { - - BakedLightBaker::Octant *oct = &octants[oct_idx]; - for(int ci=0;ci<8;ci++) { - - - Vector3 pos = oct->aabb.pos; - - if (ci&1) - pos.x+=oct->aabb.size.x; - if (ci&2) - pos.y+=oct->aabb.size.y; - if (ci&4) - pos.z+=oct->aabb.size.z; - - - pos.x=floor((pos.x+cell_size*0.5)/cell_size); - pos.y=floor((pos.y+cell_size*0.5)/cell_size); - pos.z=floor((pos.z+cell_size*0.5)/cell_size); - - { - Map<Vector3,Vector3>::Element *E=endpoint_normal.find(pos); - if (!E) { - //? - print_line("lolwut?"); - } else { - Vector3 n = E->get().normalized(); - oct->normal_accum[ci][0]=n.x; - oct->normal_accum[ci][1]=n.y; - oct->normal_accum[ci][2]=n.z; - - } - - } - - { - - Map<Vector3,uint64_t>::Element *E=endpoint_normal_bits.find(pos); - if (!E) { - //? - print_line("lolwut?"); - } else { - - float max_aper=0; - for(uint64_t i=0;i<62;i++) { - - if (!(E->get()&(1<<i))) - continue; - Vector3 ang_i = get_bit_normal(i); - - for(uint64_t j=0;j<62;j++) { - - if (i==j) - continue; - if (!(E->get()&(1<<j))) - continue; - Vector3 ang_j = get_bit_normal(j); - float ang = Math::acos(ang_i.dot(ang_j)); - if (ang>max_aper) - max_aper=ang; - } - } - if (max_aper>0.75*Math_PI) { - //angle too wide prevent problems and forget - oct->normal_accum[ci][0]=0; - oct->normal_accum[ci][1]=0; - oct->normal_accum[ci][2]=0; - } - } - } - - - } - - oct_idx=oct->next_leaf; - } - } - - -} - - - - - -void BakedLightBaker::_plot_light(ThreadStack& thread_stack,const Vector3& p_plot_pos, const AABB& p_plot_aabb, const Color& p_light,const Color& p_tint_light,bool p_only_full, const Plane& p_plane) { - - //stackless version - - uint32_t *stack=thread_stack.octant_stack; - uint32_t *ptr_stack=thread_stack.octantptr_stack; - Octant *octants=octant_pool.ptr(); - - stack[0]=0; - ptr_stack[0]=0; - - int stack_pos=0; - - - while(true) { - - Octant &octant=octants[ptr_stack[stack_pos]]; - - if (stack[stack_pos]==0) { - - - Vector3 pos = octant.aabb.pos + octant.aabb.size*0.5; - float md = 1<<(octree_depth - stack_pos ); - float r=cell_size*plot_size*md; - float div = 1.0/(md*md*md); - //div=1.0; - - - float d = p_plot_pos.distance_to(pos); - - if ((p_plane.distance_to(pos)>-cell_size*1.75*md) && d<=r) { - - - float intensity = 1.0 - (d/r)*(d/r); //not gauss but.. - - baked_light_baker_add_64f(&octant.full_accum[0],p_tint_light.r*intensity*div); - baked_light_baker_add_64f(&octant.full_accum[1],p_tint_light.g*intensity*div); - baked_light_baker_add_64f(&octant.full_accum[2],p_tint_light.b*intensity*div); - } - } - - if (octant.leaf) { - - - - //if (p_plane.normal.dot(octant.aabb.get_support(p_plane.normal)) < p_plane.d-CMP_EPSILON) { //octants behind are no go - - - if (!p_only_full) { - float r=cell_size*plot_size; - for(int i=0;i<8;i++) { - Vector3 pos=octant.aabb.pos; - if (i&1) - pos.x+=octant.aabb.size.x; - if (i&2) - pos.y+=octant.aabb.size.y; - if (i&4) - pos.z+=octant.aabb.size.z; - - - - float d = p_plot_pos.distance_to(pos); - - if ((p_plane.distance_to(pos)>-cell_size*1.75) && d<=r) { - - - float intensity = 1.0 - (d/r)*(d/r); //not gauss but.. - if (edge_damp>0) { - Vector3 normal = Vector3(octant.normal_accum[i][0],octant.normal_accum[i][1],octant.normal_accum[i][2]); - if (normal.x>0 || normal.y>0 || normal.z>0) { - - float damp = Math::abs(p_plane.normal.dot(normal)); - intensity*=pow(damp,edge_damp); - - } - } - - //intensity*=1.0-Math::abs(p_plane.distance_to(pos))/(plot_size*cell_size); - //intensity = Math::cos(d*Math_PI*0.5/r); - - baked_light_baker_add_64f(&octant.light_accum[i][0],p_light.r*intensity); - baked_light_baker_add_64f(&octant.light_accum[i][1],p_light.g*intensity); - baked_light_baker_add_64f(&octant.light_accum[i][2],p_light.b*intensity); - - - } - } - } - - stack_pos--; - } else if (stack[stack_pos]<8) { - - int i = stack[stack_pos]; - stack[stack_pos]++; - - if (!octant.children[i]) { - continue; - } - - Octant &child=octants[octant.children[i]]; - - if (!child.aabb.intersects(p_plot_aabb)) - continue; - - if (child.aabb.encloses(p_plot_aabb)) { - stack[stack_pos]=8; //don't test the rest - } - - stack_pos++; - stack[stack_pos]=0; - ptr_stack[stack_pos]=octant.children[i]; - } else { - stack_pos--; - if (stack_pos<0) - break; - } - } - - -} - - -float BakedLightBaker::_throw_ray(ThreadStack& thread_stack,bool p_bake_direct,const Vector3& p_begin, const Vector3& p_end,float p_rest,const Color& p_light,float *p_att_curve,float p_att_pos,int p_att_curve_len,int p_bounces,bool p_first_bounce,bool p_only_dist) { - - - uint32_t* stack = thread_stack.ray_stack; - BVH **bstack = thread_stack.bvh_stack; - - enum { - TEST_AABB_BIT=0, - VISIT_LEFT_BIT=1, - VISIT_RIGHT_BIT=2, - VISIT_DONE_BIT=3, - - - }; - - Vector3 n = (p_end-p_begin); - float len=n.length(); - if (len==0) - return 0; - n/=len; - - - - real_t d=1e10; - bool inters=false; - Vector3 r_normal; - Vector3 r_point; - Vector3 end=p_end; - - Triangle *triangle=NULL; - - /* - for(int i=0;i<max_depth;i++) - stack[i]=0; - */ - - int level=0; - //AABB ray_aabb; - //ray_aabb.pos=p_begin; - //ray_aabb.expand_to(p_end); - - - bstack[0]=bvh; - stack[0]=TEST_AABB_BIT; - - - while(true) { - - uint32_t mode = stack[level]; - const BVH &b = *bstack[level]; - bool done=false; - - switch(mode) { - case TEST_AABB_BIT: { - - if (b.leaf) { - - - Face3 f3(b.leaf->vertices[0],b.leaf->vertices[1],b.leaf->vertices[2]); - - - Vector3 res; - - if (f3.intersects_segment(p_begin,end,&res)) { - - - float nd = n.dot(res); - if (nd<d) { - - d=nd; - r_point=res; - end=res; - len=(p_begin-end).length(); - r_normal=f3.get_plane().get_normal(); - triangle=b.leaf; - inters=true; - } - - } - - stack[level]=VISIT_DONE_BIT; - } else { - - - bool valid = b.aabb.smits_intersect_ray(p_begin,n,0,len); - //bool valid = b.aabb.intersects_segment(p_begin,p_end); - //bool valid = b.aabb.intersects(ray_aabb); - - if (!valid) { - - stack[level]=VISIT_DONE_BIT; - - } else { - - stack[level]=VISIT_LEFT_BIT; - } - } - - } continue; - case VISIT_LEFT_BIT: { - - stack[level]=VISIT_RIGHT_BIT; - bstack[level+1]=b.children[0]; - stack[level+1]=TEST_AABB_BIT; - level++; - - } continue; - case VISIT_RIGHT_BIT: { - - stack[level]=VISIT_DONE_BIT; - bstack[level+1]=b.children[1]; - stack[level+1]=TEST_AABB_BIT; - level++; - } continue; - case VISIT_DONE_BIT: { - - if (level==0) { - done=true; - break; - } else - level--; - - } continue; - } - - - if (done) - break; - } - - - - if (inters) { - - if (p_only_dist) { - - return p_begin.distance_to(r_point); - } - - - //should check if there is normals first - Vector2 uv; - if (true) { - - triangle->get_uv_and_normal(r_point,uv,r_normal); - - } else { - - } - - if (n.dot(r_normal)>0) - return -1; - - if (n.dot(r_normal)>0) - r_normal=-r_normal; - - - //ok... - Color diffuse_at_point(0.8,0.8,0.8); - Color specular_at_point(0.0,0.0,0.0); - - - float dist = p_begin.distance_to(r_point); - - AABB aabb; - aabb.pos=r_point; - aabb.pos-=Vector3(1,1,1)*cell_size*plot_size; - aabb.size=Vector3(2,2,2)*cell_size*plot_size; - - Color res_light=p_light; - float att=1.0; - float dp=(1.0-normal_damp)*n.dot(-r_normal)+normal_damp; - - if (p_att_curve) { - - p_att_pos+=dist; - int cpos = Math::fast_ftoi((p_att_pos/p_att_curve_len)*ATTENUATION_CURVE_LEN); - cpos=CLAMP(cpos,0,ATTENUATION_CURVE_LEN-1); - att=p_att_curve[cpos]; - } - - - res_light.r*=dp; - res_light.g*=dp; - res_light.b*=dp; - - //light is plotted before multiplication with diffuse, this way - //the multiplication can happen with more detail in the shader - - - - if (triangle->material) { - - //triangle->get_uv(r_point); - - diffuse_at_point=triangle->material->diffuse.get_color(uv); - specular_at_point=triangle->material->specular.get_color(uv); - } - - - diffuse_at_point.r=res_light.r*diffuse_at_point.r; - diffuse_at_point.g=res_light.g*diffuse_at_point.g; - diffuse_at_point.b=res_light.b*diffuse_at_point.b; - - if (p_bounces>0) { - - - p_rest-=dist; - if (p_rest<CMP_EPSILON) - return 0; - - if (r_normal==-n) - return 0; //todo change a little - - r_point+=r_normal*0.01; - - - - - specular_at_point.r=res_light.r*specular_at_point.r; - specular_at_point.g=res_light.g*specular_at_point.g; - specular_at_point.b=res_light.b*specular_at_point.b; - - - - if (use_diffuse && (diffuse_at_point.r>CMP_EPSILON || diffuse_at_point.g>CMP_EPSILON || diffuse_at_point.b>CMP_EPSILON)) { - //diffuse bounce - - Vector3 c1=r_normal.cross(n).normalized(); - Vector3 c2=r_normal.cross(c1).normalized(); - double r1 = double(rand())/RAND_MAX; - double r2 = double(rand())/RAND_MAX; - double r3 = double(rand())/RAND_MAX; -#if 0 - Vector3 next = - ((c1*(r1-0.5)) + (c2*(r2-0.5)) + (r_normal*(r3-0.5))).normalized()*0.5 + r_normal*0.5; - - if (next==Vector3()) - next=r_normal; - Vector3 rn=next.normalized(); - -#else - Vector3 rn = ((c1*(r1-0.5)) + (c2*(r2-0.5)) + (r_normal*r3*0.5)).normalized(); -#endif - - - _throw_ray(thread_stack,p_bake_direct,r_point,r_point+rn*p_rest,p_rest,diffuse_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1); - } - - if (use_specular && (specular_at_point.r>CMP_EPSILON || specular_at_point.g>CMP_EPSILON || specular_at_point.b>CMP_EPSILON)) { - //specular bounce - - //Vector3 c1=r_normal.cross(n).normalized(); - //Vector3 c2=r_normal.cross(c1).normalized(); - - Vector3 rn = n - r_normal *r_normal.dot(n) * 2.0; - - _throw_ray(thread_stack,p_bake_direct,r_point,r_point+rn*p_rest,p_rest,specular_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1); - } - } - - //specular later - //_plot_light_point(r_point,octree,octree_aabb,p_light); - - - Color plot_light=res_light.linear_interpolate(diffuse_at_point,tint); - plot_light.r*=att; - plot_light.g*=att; - plot_light.b*=att; - Color tint_light=diffuse_at_point; - tint_light.r*=att; - tint_light.g*=att; - tint_light.b*=att; - - bool skip=false; - - if (!p_first_bounce || p_bake_direct) { - - - float r = plot_size * cell_size*2; - if (dist<r) { - //avoid accumulaiton of light on corners - //plot_light=plot_light.linear_interpolate(Color(0,0,0,0),1.0-sd/plot_size*plot_size); - skip=true; - - } else { - - - Vector3 c1=r_normal.cross(n).normalized(); - Vector3 c2=r_normal.cross(c1).normalized(); - double r1 = double(rand())/RAND_MAX; - double r2 = double(rand())/RAND_MAX; - double r3 = double(rand())/RAND_MAX; - Vector3 rn = ((c1*(r1-0.5)) + (c2*(r2-0.5)) + (r_normal*r3*0.25)).normalized(); - float d =_throw_ray(thread_stack,p_bake_direct,r_point,r_point+rn*p_rest,p_rest,diffuse_at_point,p_att_curve,p_att_pos,p_att_curve_len,p_bounces-1,false,true); - r = plot_size*cell_size*ao_radius; - if (d>0 && d<r) { - //avoid accumulaiton of light on corners - //plot_light=plot_light.linear_interpolate(Color(0,0,0,0),1.0-sd/plot_size*plot_size); - skip=true; - - } else { - //plot_light=Color(0,0,0,0); - } - } - } - - - Plane plane(r_point,r_normal); - if (!skip) - _plot_light(thread_stack,r_point,aabb,plot_light,tint_light,!(!p_first_bounce || p_bake_direct),plane); - - - return dist; - } - - return -1; - -} - - - - -void BakedLightBaker::_make_octree_texture() { - - - BakedLightBaker::Octant *octants=octant_pool.ptr(); - - //find neighbours first, to have a better idea of what amount of space is needed - { - - Vector<OctantHash> octant_hashing; - octant_hashing.resize(octant_pool_size); - Vector<uint32_t> hash_table; - int hash_table_size=Math::larger_prime(16384); - hash_table.resize(hash_table_size); - uint32_t*hashptr = hash_table.ptr(); - OctantHash*octhashptr = octant_hashing.ptr(); - - for(int i=0;i<hash_table_size;i++) - hashptr[i]=0; - - - //step 1 add to hash table - - uint32_t oct_idx=leaf_list; - - - while(oct_idx) { - - BakedLightBaker::Octant *oct = &octants[oct_idx]; - uint64_t base=0; - Vector3 pos = oct->aabb.pos - octree_aabb.pos; //make sure is always positive - base=int((pos.x+cell_size*0.5)/cell_size); - base<<=16; - base|=int((pos.y+cell_size*0.5)/cell_size); - base<<=16; - base|=int((pos.z+cell_size*0.5)/cell_size); - - uint32_t hash = HashMapHasherDefault::hash(base); - uint32_t idx = hash % hash_table_size; - octhashptr[oct_idx].next=hashptr[idx]; - octhashptr[oct_idx].hash=hash; - octhashptr[oct_idx].value=base; - hashptr[idx]=oct_idx; - - oct_idx=oct->next_leaf; - - } - - //step 2 find neighbours - oct_idx=leaf_list; - int neighbours=0; - - - while(oct_idx) { - - BakedLightBaker::Octant *oct = &octants[oct_idx]; - Vector3 pos = oct->aabb.pos - octree_aabb.pos; //make sure is always positive - pos.x+=cell_size; - uint64_t base=0; - base=int((pos.x+cell_size*0.5)/cell_size); - base<<=16; - base|=int((pos.y+cell_size*0.5)/cell_size); - base<<=16; - base|=int((pos.z+cell_size*0.5)/cell_size); - - uint32_t hash = HashMapHasherDefault::hash(base); - uint32_t idx = hash % hash_table_size; - - uint32_t bucket = hashptr[idx]; - - while(bucket) { - - if (octhashptr[bucket].value==base) { - - oct->bake_neighbour=bucket; - octants[bucket].first_neighbour=false; - neighbours++; - break; - } - - bucket = octhashptr[bucket].next; - } - - oct_idx=oct->next_leaf; - - } - - print_line("octant with neighbour: "+itos(neighbours)); - - } - - - //ok let's try to just create a texture - - int otex_w=256; - - while (true) { - - - - uint32_t oct_idx=leaf_list; - - int row=0; - - - print_line("begin at row "+itos(row)); - int longest_line_reused=0; - int col=0; - int processed=0; - - //reset - while(oct_idx) { - - BakedLightBaker::Octant *oct = &octants[oct_idx]; - oct->texture_x=0; - oct->texture_y=0; - oct_idx=oct->next_leaf; - - } - - oct_idx=leaf_list; - //assign - while(oct_idx) { - - BakedLightBaker::Octant *oct = &octants[oct_idx]; - if (oct->first_neighbour && oct->texture_x==0 && oct->texture_y==0) { - //was not processed - uint32_t current_idx=oct_idx; - int reused=0; - - while(current_idx) { - BakedLightBaker::Octant *o = &octants[current_idx]; - if (col+1 >= otex_w) { - col=0; - row+=4; - } - o->texture_x=col; - o->texture_y=row; - processed++; - - if (o->bake_neighbour) { - reused++; - } - col+=o->bake_neighbour ? 1 : 2; //reuse neighbour - current_idx=o->bake_neighbour; - } - - if (reused>longest_line_reused) { - longest_line_reused=reused; - } - } - oct_idx=oct->next_leaf; - } - - row+=4; - - if (otex_w < row) { - - otex_w*=2; - } else { - - baked_light_texture_w=otex_w; - baked_light_texture_h=nearest_power_of_2(row); - print_line("w: "+itos(otex_w)); - print_line("h: "+itos(row)); - break; - } - - - } - - - { - - otex_w=(1<<lattice_size)*(1<<lattice_size)*2; //make sure lattice fits horizontally - Vector3 lattice_cell_size=octree_aabb.size; - for(int i=0;i<lattice_size;i++) { - - lattice_cell_size*=0.5; - } - - - - while(true) { - - //let's plot the leafs first, given the octree is not so obvious which size it will have - int row=4+4*(1<<lattice_size); - int col=0; - - col=0; - row+=4; - print_line("end at row "+itos(row)); - - //put octree, no need for recursion, just loop backwards. - int regular_octants=0; - for(int i=octant_pool_size-1;i>=0;i--) { - - BakedLightBaker::Octant *oct = &octants[i]; - if (oct->leaf) //ignore leaf - continue; - if (oct->aabb.size.x>lattice_cell_size.x*1.1) { //bigger than latice, skip - oct->texture_x=0; - oct->texture_y=0; - } else if (oct->aabb.size.x>lattice_cell_size.x*0.8) { - //this is the initial lattice - Vector3 pos = oct->aabb.pos - octree_aabb.pos; //make sure is always positive - int x = int((pos.x+lattice_cell_size.x*0.5)/lattice_cell_size.x); - int y = int((pos.y+lattice_cell_size.y*0.5)/lattice_cell_size.y); - int z = int((pos.z+lattice_cell_size.z*0.5)/lattice_cell_size.z); - //bug net - ERR_FAIL_INDEX(x,(1<<lattice_size)); - ERR_FAIL_INDEX(y,(1<<lattice_size)); - ERR_FAIL_INDEX(z,(1<<lattice_size)); - - /*int ofs = z*(1<<lattice_size)*(1<<lattice_size)+y*(1<<lattice_size)+x; - ofs*=4; - oct->texture_x=ofs%otex_w; - oct->texture_y=(ofs/otex_w)*4+4; - */ - - oct->texture_x=(x+(1<<lattice_size)*z)*2; - oct->texture_y=4+y*4; - //print_line("pos: "+itos(x)+","+itos(y)+","+itos(z)+" - ofs"+itos(oct->texture_x)+","+itos(oct->texture_y)); - - - } else { - //an everyday regular octant - - if (col+2 > otex_w) { - col=0; - row+=4; - } - - oct->texture_x=col; - oct->texture_y=row; - col+=2; - regular_octants++; - - - } - } - print_line("octants end at row "+itos(row)+" totalling"+itos(regular_octants)); - - //ok evaluation. - - if (otex_w<=2048 && row>2048) { //too big upwards, try bigger texture - otex_w*=2; - continue; - } else { - baked_octree_texture_w=otex_w; - baked_octree_texture_h=row+4; - break; - } - - } - - - } - - - baked_octree_texture_h=nearest_power_of_2(baked_octree_texture_h); - print_line("RESULT! "+itos(baked_octree_texture_w)+","+itos(baked_octree_texture_h)); - -} - - - - - - - - -double BakedLightBaker::get_normalization(int p_light_idx) const { - - double nrg=0; - - const LightData &dl=lights[p_light_idx]; - double cell_area = cell_size*cell_size; - //nrg+= /*dl.energy */ (dl.rays_thrown * cell_area / dl.area); - nrg=dl.rays_thrown * cell_area; - nrg*=(Math_PI*plot_size*plot_size)*0.5; // damping of radial linear gradient kernel - nrg*=dl.constant; - //nrg*=5; - - - return nrg; -} - - - -double BakedLightBaker::get_modifier(int p_light_idx) const { - - double nrg=0; - - const LightData &dl=lights[p_light_idx]; - double cell_area = cell_size*cell_size; - //nrg+= /*dl.energy */ (dl.rays_thrown * cell_area / dl.area); - nrg=cell_area; - nrg*=(Math_PI*plot_size*plot_size)*0.5; // damping of radial linear gradient kernel - nrg*=dl.constant; - //nrg*=5; - - - return nrg; -} - -void BakedLightBaker::throw_rays(ThreadStack& thread_stack,int p_amount) { - - - - for(int i=0;i<lights.size();i++) { - - LightData &dl=lights[i]; - - - int amount = p_amount * total_light_area / dl.area; - double mod = 1.0/double(get_modifier(i)); - mod*=p_amount/float(amount); - - switch(dl.type) { - - case VS::LIGHT_DIRECTIONAL: { - - - for(int j=0;j<amount;j++) { - Vector3 from = dl.pos; - double r1 = double(rand())/RAND_MAX; - double r2 = double(rand())/RAND_MAX; - from+=dl.up*(r1*2.0-1.0); - from+=dl.left*(r2*2.0-1.0); - Vector3 to = from+dl.dir*dl.length; - Color col=dl.diffuse; - float m = mod*dl.energy; - col.r*=m; - col.g*=m; - col.b*=m; - - dl.rays_thrown++; - baked_light_baker_add_64i(&total_rays,1); - - _throw_ray(thread_stack,dl.bake_direct,from,to,dl.length,col,NULL,0,0,max_bounces,true); - } - } break; - case VS::LIGHT_OMNI: { - - - for(int j=0;j<amount;j++) { - Vector3 from = dl.pos; - - double r1 = double(rand())/RAND_MAX; - double r2 = double(rand())/RAND_MAX; - double r3 = double(rand())/RAND_MAX; - -#if 0 - //crap is not uniform.. - Vector3 dir = Vector3(r1*2.0-1.0,r2*2.0-1.0,r3*2.0-1.0).normalized(); - -#else - - double phi = r1*Math_PI*2.0; - double costheta = r2*2.0-1.0; - double u = r3; - - double theta = acos( costheta ); - double r = 1.0 * pow( u,1/3.0 ); - - Vector3 dir( - r * sin( theta) * cos( phi ), - r * sin( theta) * sin( phi ), - r * cos( theta ) - ); - dir.normalize(); - -#endif - Vector3 to = dl.pos+dir*dl.radius; - Color col=dl.diffuse; - float m = mod*dl.energy; - col.r*=m; - col.g*=m; - col.b*=m; - - dl.rays_thrown++; - baked_light_baker_add_64i(&total_rays,1); - _throw_ray(thread_stack,dl.bake_direct,from,to,dl.radius,col,dl.attenuation_table.ptr(),0,dl.radius,max_bounces,true); - //_throw_ray(i,from,to,dl.radius,col,NULL,0,dl.radius,max_bounces,true); - } - - } break; - case VS::LIGHT_SPOT: { - - for(int j=0;j<amount;j++) { - Vector3 from = dl.pos; - - double r1 = double(rand())/RAND_MAX; - //double r2 = double(rand())/RAND_MAX; - double r3 = double(rand())/RAND_MAX; - - float d=Math::tan(Math::deg2rad(dl.spot_angle)); - - float x = sin(r1*Math_PI*2.0)*d; - float y = cos(r1*Math_PI*2.0)*d; - - Vector3 dir = r3*(dl.dir + dl.up*y + dl.left*x) + (1.0-r3)*dl.dir; - dir.normalize(); - - - Vector3 to = dl.pos+dir*dl.radius; - Color col=dl.diffuse; - float m = mod*dl.energy; - col.r*=m; - col.g*=m; - col.b*=m; - - dl.rays_thrown++; - baked_light_baker_add_64i(&total_rays,1); - _throw_ray(thread_stack,dl.bake_direct,from,to,dl.radius,col,dl.attenuation_table.ptr(),0,dl.radius,max_bounces,true); - //_throw_ray(i,from,to,dl.radius,col,NULL,0,dl.radius,max_bounces,true); - } - - } break; - - } - } -} - - - - - - - - - - - - - -void BakedLightBaker::bake(const Ref<BakedLight> &p_light, Node* p_node) { - - if (baking) - return; - cell_count=0; - - base_inv=p_node->cast_to<Spatial>()->get_global_transform().affine_inverse(); - EditorProgress ep("bake",TTR("Light Baker Setup:"),5); - baked_light=p_light; - lattice_size=baked_light->get_initial_lattice_subdiv(); - octree_depth=baked_light->get_cell_subdivision(); - plot_size=baked_light->get_plot_size(); - max_bounces=baked_light->get_bounces(); - use_diffuse=baked_light->get_bake_flag(BakedLight::BAKE_DIFFUSE); - use_specular=baked_light->get_bake_flag(BakedLight::BAKE_SPECULAR); - use_translucency=baked_light->get_bake_flag(BakedLight::BAKE_TRANSLUCENT); - - edge_damp=baked_light->get_edge_damp(); - normal_damp=baked_light->get_normal_damp(); - octree_extra_margin=baked_light->get_cell_extra_margin(); - tint=baked_light->get_tint(); - ao_radius=baked_light->get_ao_radius(); - ao_strength=baked_light->get_ao_strength(); - linear_color=baked_light->get_bake_flag(BakedLight::BAKE_LINEAR_COLOR); - - baked_textures.clear(); - for(int i=0;i<baked_light->get_lightmaps_count();i++) { - BakeTexture bt; - bt.width=baked_light->get_lightmap_gen_size(i).x; - bt.height=baked_light->get_lightmap_gen_size(i).y; - baked_textures.push_back(bt); - } - - - ep.step(TTR("Parsing Geometry"),0); - _parse_geometry(p_node); - mat_map.clear(); - tex_map.clear(); - print_line("\ttotal triangles: "+itos(triangles.size())); - // no geometry - if (triangles.size() == 0) { - return; - } - ep.step(TTR("Fixing Lights"),1); - _fix_lights(); - ep.step(TTR("Making BVH"),2); - _make_bvh(); - ep.step(TTR("Creating Light Octree"),3); - _make_octree(); - ep.step(TTR("Creating Octree Texture"),4); - _make_octree_texture(); - baking=true; - _start_thread(); - -} - - -void BakedLightBaker::update_octree_sampler(PoolVector<int> &p_sampler) { - - BakedLightBaker::Octant *octants=octant_pool.ptr(); - double norm = 1.0/double(total_rays); - - - - if (p_sampler.size()==0 || first_bake_to_map) { - - Vector<int> tmp_smp; - tmp_smp.resize(32); //32 for header - - for(int i=0;i<32;i++) { - tmp_smp[i]=0; - } - - for(int i=octant_pool_size-1;i>=0;i--) { - - if (i==0) - tmp_smp[1]=tmp_smp.size(); - - Octant &octant=octants[i]; - octant.sampler_ofs = tmp_smp.size(); - int idxcol[2]={0,0}; - - int r = CLAMP((octant.full_accum[0]*norm)*2048,0,32767); - int g = CLAMP((octant.full_accum[1]*norm)*2048,0,32767); - int b = CLAMP((octant.full_accum[2]*norm)*2048,0,32767); - - idxcol[0]|=r; - idxcol[1]|=(g<<16)|b; - - if (octant.leaf) { - tmp_smp.push_back(idxcol[0]); - tmp_smp.push_back(idxcol[1]); - } else { - - for(int j=0;j<8;j++) { - if (octant.children[j]) { - idxcol[0]|=(1<<(j+16)); - } - } - tmp_smp.push_back(idxcol[0]); - tmp_smp.push_back(idxcol[1]); - for(int j=0;j<8;j++) { - if (octant.children[j]) { - tmp_smp.push_back(octants[octant.children[j]].sampler_ofs); - if (octants[octant.children[j]].sampler_ofs==0) { - print_line("FUUUUUUUUCK"); - } - } - } - } - - } - - p_sampler.resize(tmp_smp.size()); - PoolVector<int>::Write w = p_sampler.write(); - int ss = tmp_smp.size(); - for(int i=0;i<ss;i++) { - w[i]=tmp_smp[i]; - } - - first_bake_to_map=false; - - } - - double gamma = baked_light->get_gamma_adjust(); - double mult = baked_light->get_energy_multiplier(); - float saturation = baked_light->get_saturation(); - - PoolVector<int>::Write w = p_sampler.write(); - - encode_uint32(octree_depth,(uint8_t*)&w[2]); - encode_uint32(linear_color,(uint8_t*)&w[3]); - - encode_float(octree_aabb.pos.x,(uint8_t*)&w[4]); - encode_float(octree_aabb.pos.y,(uint8_t*)&w[5]); - encode_float(octree_aabb.pos.z,(uint8_t*)&w[6]); - encode_float(octree_aabb.size.x,(uint8_t*)&w[7]); - encode_float(octree_aabb.size.y,(uint8_t*)&w[8]); - encode_float(octree_aabb.size.z,(uint8_t*)&w[9]); - - //norm*=multiplier; - - for(int i=octant_pool_size-1;i>=0;i--) { - - Octant &octant=octants[i]; - int idxcol[2]={w[octant.sampler_ofs],w[octant.sampler_ofs+1]}; - - double rf=pow(octant.full_accum[0]*norm*mult,gamma); - double gf=pow(octant.full_accum[1]*norm*mult,gamma); - double bf=pow(octant.full_accum[2]*norm*mult,gamma); - - double gray = (rf+gf+bf)/3.0; - rf = gray + (rf-gray)*saturation; - gf = gray + (gf-gray)*saturation; - bf = gray + (bf-gray)*saturation; - - - int r = CLAMP((rf)*2048,0,32767); - int g = CLAMP((gf)*2048,0,32767); - int b = CLAMP((bf)*2048,0,32767); - - idxcol[0]=((idxcol[0]>>16)<<16)|r; - idxcol[1]=(g<<16)|b; - w[octant.sampler_ofs]=idxcol[0]; - w[octant.sampler_ofs+1]=idxcol[1]; - } - -} - -void BakedLightBaker::update_octree_images(PoolVector<uint8_t> &p_octree,PoolVector<uint8_t> &p_light) { - - - int len = baked_octree_texture_w*baked_octree_texture_h*4; - p_octree.resize(len); - - int ilen = baked_light_texture_w*baked_light_texture_h*4; - p_light.resize(ilen); - - - PoolVector<uint8_t>::Write w = p_octree.write(); - zeromem(w.ptr(),len); - - PoolVector<uint8_t>::Write iw = p_light.write(); - zeromem(iw.ptr(),ilen); - - float gamma = baked_light->get_gamma_adjust(); - float mult = baked_light->get_energy_multiplier(); - - for(int i=0;i<len;i+=4) { - w[i+0]=0xFF; - w[i+1]=0; - w[i+2]=0xFF; - w[i+3]=0xFF; - } - - for(int i=0;i<ilen;i+=4) { - iw[i+0]=0xFF; - iw[i+1]=0; - iw[i+2]=0xFF; - iw[i+3]=0xFF; - } - - float multiplier=1.0; - - if (baked_light->get_format()==BakedLight::FORMAT_HDR8) - multiplier=8; - encode_uint32(baked_octree_texture_w,&w[0]); - encode_uint32(baked_octree_texture_h,&w[4]); - encode_uint32(0,&w[8]); - encode_float(1<<lattice_size,&w[12]); - encode_uint32(octree_depth-lattice_size,&w[16]); - encode_uint32(multiplier,&w[20]); - encode_uint16(baked_light_texture_w,&w[24]); //if present, use the baked light texture - encode_uint16(baked_light_texture_h,&w[26]); - encode_uint32(0,&w[28]); //baked light texture format - - encode_float(octree_aabb.pos.x,&w[32]); - encode_float(octree_aabb.pos.y,&w[36]); - encode_float(octree_aabb.pos.z,&w[40]); - encode_float(octree_aabb.size.x,&w[44]); - encode_float(octree_aabb.size.y,&w[48]); - encode_float(octree_aabb.size.z,&w[52]); - - - BakedLightBaker::Octant *octants=octant_pool.ptr(); - int octant_count=octant_pool_size; - uint8_t *ptr = w.ptr(); - uint8_t *lptr = iw.ptr(); - - - int child_offsets[8]={ - 0, - 4, - baked_octree_texture_w*4, - baked_octree_texture_w*4+4, - baked_octree_texture_w*8+0, - baked_octree_texture_w*8+4, - baked_octree_texture_w*8+baked_octree_texture_w*4, - baked_octree_texture_w*8+baked_octree_texture_w*4+4, - }; - - int lchild_offsets[8]={ - 0, - 4, - baked_light_texture_w*4, - baked_light_texture_w*4+4, - baked_light_texture_w*8+0, - baked_light_texture_w*8+4, - baked_light_texture_w*8+baked_light_texture_w*4, - baked_light_texture_w*8+baked_light_texture_w*4+4, - }; - - /*Vector<double> norm_arr; - norm_arr.resize(lights.size()); - - for(int i=0;i<lights.size();i++) { - norm_arr[i] = 1.0/get_normalization(i); - } - - const double *normptr=norm_arr.ptr(); -*/ - double norm = 1.0/double(total_rays); - mult/=multiplier; - double saturation = baked_light->get_saturation(); - - for(int i=0;i<octant_count;i++) { - - Octant &oct=octants[i]; - if (oct.texture_x==0 && oct.texture_y==0) - continue; - - - if (oct.leaf) { - - int ofs = (oct.texture_y * baked_light_texture_w + oct.texture_x)<<2; - ERR_CONTINUE(ofs<0 || ofs >ilen); - //write colors - for(int j=0;j<8;j++) { - - /* - if (!oct.children[j]) - continue; - */ - uint8_t *iptr=&lptr[ofs+lchild_offsets[j]]; - - float r=oct.light_accum[j][0]*norm; - float g=oct.light_accum[j][1]*norm; - float b=oct.light_accum[j][2]*norm; - - r=pow(r*mult,gamma); - g=pow(g*mult,gamma); - b=pow(b*mult,gamma); - - double gray = (r+g+b)/3.0; - r = gray + (r-gray)*saturation; - g = gray + (g-gray)*saturation; - b = gray + (b-gray)*saturation; - - float ic[3]={ - r, - g, - b, - }; - iptr[0]=CLAMP(ic[0]*255.0,0,255); - iptr[1]=CLAMP(ic[1]*255.0,0,255); - iptr[2]=CLAMP(ic[2]*255.0,0,255); - iptr[3]=255; - } - - } else { - - int ofs = (oct.texture_y * baked_octree_texture_w + oct.texture_x)<<2; - ERR_CONTINUE(ofs<0 || ofs >len); - - //write indices - for(int j=0;j<8;j++) { - - if (!oct.children[j]) - continue; - Octant&choct=octants[oct.children[j]]; - uint8_t *iptr=&ptr[ofs+child_offsets[j]]; - - iptr[0]=choct.texture_x>>8; - iptr[1]=choct.texture_x&0xFF; - iptr[2]=choct.texture_y>>8; - iptr[3]=choct.texture_y&0xFF; - - } - } - - } - - -} - - -void BakedLightBaker::_free_bvh(BVH* p_bvh) { - - if (!p_bvh->leaf) { - if (p_bvh->children[0]) - _free_bvh(p_bvh->children[0]); - if (p_bvh->children[1]) - _free_bvh(p_bvh->children[1]); - } - - memdelete(p_bvh); - -} - - -bool BakedLightBaker::is_baking() { - - return baking; -} - -void BakedLightBaker::set_pause(bool p_pause){ - - if (paused==p_pause) - return; - - paused=p_pause; - - if (paused) { - _stop_thread(); - } else { - _start_thread(); - } -} -bool BakedLightBaker::is_paused() { - - return paused; - -} - -void BakedLightBaker::_bake_thread_func(void *arg) { - - BakedLightBaker *ble = (BakedLightBaker*)arg; - - - - ThreadStack thread_stack; - - thread_stack.ray_stack = memnew_arr(uint32_t,ble->bvh_depth); - thread_stack.bvh_stack = memnew_arr(BVH*,ble->bvh_depth); - thread_stack.octant_stack = memnew_arr(uint32_t,ble->octree_depth*2 ); - thread_stack.octantptr_stack = memnew_arr(uint32_t,ble->octree_depth*2 ); - - while(!ble->bake_thread_exit) { - - ble->throw_rays(thread_stack,1000); - } - - memdelete_arr(thread_stack.ray_stack ); - memdelete_arr(thread_stack.bvh_stack ); - memdelete_arr(thread_stack.octant_stack ); - memdelete_arr(thread_stack.octantptr_stack ); - -} - -void BakedLightBaker::_start_thread() { - - if (threads.size()!=0) - return; - bake_thread_exit=false; - - int thread_count = EDITOR_DEF("light_baker/custom_bake_threads",0); - if (thread_count<=0 || thread_count>64) - thread_count=OS::get_singleton()->get_processor_count(); - - //thread_count=1; - threads.resize(thread_count); - for(int i=0;i<threads.size();i++) { - threads[i]=Thread::create(_bake_thread_func,this); - } -} - -void BakedLightBaker::_stop_thread() { - - if (threads.size()==0) - return; - bake_thread_exit=true; - for(int i=0;i<threads.size();i++) { - Thread::wait_to_finish(threads[i]); - memdelete(threads[i]); - } - threads.clear(); -} - -void BakedLightBaker::_plot_pixel_to_lightmap(int x, int y, int width, int height, uint8_t *image, const Vector3& p_pos,const Vector3& p_normal,double *p_norm_ptr,float mult,float gamma) { - - - uint8_t *ptr = &image[(y*width+x)*4]; - //int lc = lights.size(); - double norm = 1.0/double(total_rays); - - - Color color; - - Octant *octants=octant_pool.ptr(); - - - int octant_idx=0; - - - while(true) { - - Octant &octant=octants[octant_idx]; - - if (octant.leaf) { - - Vector3 lpos = p_pos-octant.aabb.pos; - lpos/=octant.aabb.size; - - Vector3 cols[8]; - - for(int i=0;i<8;i++) { - - cols[i].x+=octant.light_accum[i][0]*norm; - cols[i].y+=octant.light_accum[i][1]*norm; - cols[i].z+=octant.light_accum[i][2]*norm; - } - - - /*Vector3 final = (cols[0] + (cols[1] - cols[0]) * lpos.y); - final = final + ((cols[2] + (cols[3] - cols[2]) * lpos.y) - final)*lpos.x; - - Vector3 final2 = (cols[4+0] + (cols[4+1] - cols[4+0]) * lpos.y); - final2 = final2 + ((cols[4+2] + (cols[4+3] - cols[4+2]) * lpos.y) - final2)*lpos.x;*/ - - Vector3 finala = cols[0].linear_interpolate(cols[1],lpos.x); - Vector3 finalb = cols[2].linear_interpolate(cols[3],lpos.x); - Vector3 final = finala.linear_interpolate(finalb,lpos.y); - - Vector3 final2a = cols[4+0].linear_interpolate(cols[4+1],lpos.x); - Vector3 final2b = cols[4+2].linear_interpolate(cols[4+3],lpos.x); - Vector3 final2 = final2a.linear_interpolate(final2b,lpos.y); - - final = final.linear_interpolate(final2,lpos.z); - if (baked_light->get_format()==BakedLight::FORMAT_HDR8) - final*=8.0; - - - color.r=pow(final.x*mult,gamma); - color.g=pow(final.y*mult,gamma); - color.b=pow(final.z*mult,gamma); - color.a=1.0; - - int lc = lights.size(); - LightData *lv = lights.ptr(); - for(int i=0;i<lc;i++) { - //shadow baking - if (!lv[i].bake_shadow) - continue; - Vector3 from = p_pos+p_normal*0.01; - Vector3 to; - float att=0; - switch(lv[i].type) { - case VS::LIGHT_DIRECTIONAL: { - to=from-lv[i].dir*lv[i].length; - } break; - case VS::LIGHT_OMNI: { - to=lv[i].pos; - float d = MIN(lv[i].radius,to.distance_to(from))/lv[i].radius; - att=d;//1.0-d; - } break; - default: continue; - } - - uint32_t* stack = ray_stack; - BVH **bstack = bvh_stack; - - enum { - TEST_RAY_BIT=0, - VISIT_LEFT_BIT=1, - VISIT_RIGHT_BIT=2, - VISIT_DONE_BIT=3, - - - }; - - bool intersected=false; - - int level=0; - - Vector3 n = (to-from); - float len=n.length(); - if (len==0) - continue; - n/=len; - - bstack[0]=bvh; - stack[0]=TEST_RAY_BIT; - - - while(!intersected) { - - uint32_t mode = stack[level]; - const BVH &b = *bstack[level]; - bool done=false; - - switch(mode) { - case TEST_RAY_BIT: { - - if (b.leaf) { - - - Face3 f3(b.leaf->vertices[0],b.leaf->vertices[1],b.leaf->vertices[2]); - - - Vector3 res; - - if (f3.intersects_segment(from,to)) { - intersected=true; - done=true; - } - - stack[level]=VISIT_DONE_BIT; - } else { - - - bool valid = b.aabb.smits_intersect_ray(from,n,0,len); - //bool valid = b.aabb.intersects_segment(p_begin,p_end); - //bool valid = b.aabb.intersects(ray_aabb); - - if (!valid) { - - stack[level]=VISIT_DONE_BIT; - - } else { - - stack[level]=VISIT_LEFT_BIT; - } - } - - } continue; - case VISIT_LEFT_BIT: { - - stack[level]=VISIT_RIGHT_BIT; - bstack[level+1]=b.children[0]; - stack[level+1]=TEST_RAY_BIT; - level++; - - } continue; - case VISIT_RIGHT_BIT: { - - stack[level]=VISIT_DONE_BIT; - bstack[level+1]=b.children[1]; - stack[level+1]=TEST_RAY_BIT; - level++; - } continue; - case VISIT_DONE_BIT: { - - if (level==0) { - done=true; - break; - } else - level--; - - } continue; - } - - - if (done) - break; - } - - - - if (intersected) { - - color.a=Math::lerp(MAX(0.01,lv[i].darkening),1.0,att); - } - - } - - break; - } else { - - Vector3 lpos = p_pos - octant.aabb.pos; - Vector3 half = octant.aabb.size * 0.5; - - int ofs=0; - - if (lpos.x >= half.x) - ofs|=1; - if (lpos.y >= half.y) - ofs|=2; - if (lpos.z >= half.z) - ofs|=4; - - octant_idx = octant.children[ofs]; - - if (octant_idx==0) - return; - - } - } - - ptr[0]=CLAMP(color.r*255.0,0,255); - ptr[1]=CLAMP(color.g*255.0,0,255); - ptr[2]=CLAMP(color.b*255.0,0,255); - ptr[3]=CLAMP(color.a*255.0,0,255); - -} - - -Error BakedLightBaker::transfer_to_lightmaps() { - - if (!triangles.size() || baked_textures.size()==0) - return ERR_UNCONFIGURED; - - EditorProgress ep("transfer_to_lightmaps",TTR("Transfer to Lightmaps:"),baked_textures.size()*2+triangles.size()); - - for(int i=0;i<baked_textures.size();i++) { - - ERR_FAIL_COND_V( baked_textures[i].width<=0 || baked_textures[i].height<=0,ERR_UNCONFIGURED ); - - baked_textures[i].data.resize( baked_textures[i].width*baked_textures[i].height*4 ); - zeromem(baked_textures[i].data.ptr(),baked_textures[i].data.size()); - ep.step(TTR("Allocating Texture #")+itos(i+1),i); - } - - Vector<double> norm_arr; - norm_arr.resize(lights.size()); - - for(int i=0;i<lights.size();i++) { - norm_arr[i] = 1.0/get_normalization(i); - } - float gamma = baked_light->get_gamma_adjust(); - float mult = baked_light->get_energy_multiplier(); - - for(int i=0;i<triangles.size();i++) { - - if (i%200==0) { - ep.step(TTR("Baking Triangle #")+itos(i),i+baked_textures.size()); - } - Triangle &t=triangles[i]; - if (t.baked_texture<0 || t.baked_texture>=baked_textures.size()) - continue; - - BakeTexture &bt=baked_textures[t.baked_texture]; - Vector3 normal = Plane(t.vertices[0],t.vertices[1],t.vertices[2]).normal; - - - int x[3]; - int y[3]; - - Vector3 vertices[3]={ - t.vertices[0], - t.vertices[1], - t.vertices[2] - }; - - for(int j=0;j<3;j++) { - - x[j]=t.bake_uvs[j].x*bt.width; - y[j]=t.bake_uvs[j].y*bt.height; - x[j]=CLAMP(x[j],0,bt.width-1); - y[j]=CLAMP(y[j],0,bt.height-1); - } - - - { - - // sort the points vertically - if (y[1] > y[2]) { - SWAP(x[1], x[2]); - SWAP(y[1], y[2]); - SWAP(vertices[1],vertices[2]); - } - if (y[0] > y[1]) { - SWAP(x[0], x[1]); - SWAP(y[0], y[1]); - SWAP(vertices[0],vertices[1]); - } - if (y[1] > y[2]) { - SWAP(x[1], x[2]); - SWAP(y[1], y[2]); - SWAP(vertices[1],vertices[2]); - } - - double dx_far = double(x[2] - x[0]) / (y[2] - y[0] + 1); - double dx_upper = double(x[1] - x[0]) / (y[1] - y[0] + 1); - double dx_low = double(x[2] - x[1]) / (y[2] - y[1] + 1); - double xf = x[0]; - double xt = x[0] + dx_upper; // if y[0] == y[1], special case - for (int yi = y[0]; yi <= (y[2] > bt.height-1 ? bt.height-1 : y[2]); yi++) - { - if (yi >= 0) { - for (int xi = (xf > 0 ? int(xf) : 0); xi <= (xt < bt.width ? xt : bt.width-1) ; xi++) { - //pixels[int(x + y * width)] = color; - - Vector2 v0 = Vector2(x[1]-x[0],y[1]-y[0]); - Vector2 v1 = Vector2(x[2]-x[0],y[2]-y[0]); - //vertices[2] - vertices[0]; - Vector2 v2 = Vector2(xi-x[0],yi-y[0]); - float d00 = v0.dot( v0); - float d01 = v0.dot( v1); - float d11 = v1.dot( v1); - float d20 = v2.dot( v0); - float d21 = v2.dot( v1); - float denom = (d00 * d11 - d01 * d01); - Vector3 pos; - if (denom==0) { - pos=t.vertices[0]; - } else { - float v = (d11 * d20 - d01 * d21) / denom; - float w = (d00 * d21 - d01 * d20) / denom; - float u = 1.0f - v - w; - pos = vertices[0]*u + vertices[1]*v + vertices[2]*w; - } - _plot_pixel_to_lightmap(xi,yi,bt.width,bt.height,bt.data.ptr(),pos,normal,norm_arr.ptr(),mult,gamma); - - } - - for (int xi = (xf < bt.width ? int(xf) : bt.width-1); xi >= (xt > 0 ? xt : 0); xi--) { - //pixels[int(x + y * width)] = color; - Vector2 v0 = Vector2(x[1]-x[0],y[1]-y[0]); - Vector2 v1 = Vector2(x[2]-x[0],y[2]-y[0]); - //vertices[2] - vertices[0]; - Vector2 v2 = Vector2(xi-x[0],yi-y[0]); - float d00 = v0.dot( v0); - float d01 = v0.dot( v1); - float d11 = v1.dot( v1); - float d20 = v2.dot( v0); - float d21 = v2.dot( v1); - float denom = (d00 * d11 - d01 * d01); - Vector3 pos; - if (denom==0) { - pos=t.vertices[0]; - } else { - float v = (d11 * d20 - d01 * d21) / denom; - float w = (d00 * d21 - d01 * d20) / denom; - float u = 1.0f - v - w; - pos = vertices[0]*u + vertices[1]*v + vertices[2]*w; - } - - _plot_pixel_to_lightmap(xi,yi,bt.width,bt.height,bt.data.ptr(),pos,normal,norm_arr.ptr(),mult,gamma); - - } - } - xf += dx_far; - if (yi < y[1]) - xt += dx_upper; - else - xt += dx_low; - } - } - - } - - - for(int i=0;i<baked_textures.size();i++) { - - - { - - ep.step(TTR("Post-Processing Texture #")+itos(i),i+baked_textures.size()+triangles.size()); - - BakeTexture &bt=baked_textures[i]; - - Vector<uint8_t> copy_data=bt.data; - uint8_t *data=bt.data.ptr(); - const int max_radius=8; - const int shadow_radius=2; - const int max_dist=0x7FFFFFFF; - - for(int x=0;x<bt.width;x++) { - - for(int y=0;y<bt.height;y++) { - - - uint8_t a = copy_data[(y*bt.width+x)*4+3]; - - if (a>0) { - //blur shadow - - int from_x = MAX(0,x-shadow_radius); - int to_x = MIN(bt.width-1,x+shadow_radius); - int from_y = MAX(0,y-shadow_radius); - int to_y = MIN(bt.height-1,y+shadow_radius); - - int sum=0; - int sumc=0; - - for(int k=from_y;k<=to_y;k++) { - for(int l=from_x;l<=to_x;l++) { - - const uint8_t * rp = ©_data[(k*bt.width+l)<<2]; - - sum+=rp[3]; - sumc++; - } - } - - sum/=sumc; - data[(y*bt.width+x)*4+3]=sum; - - } else { - - int closest_dist=max_dist; - uint8_t closest_color[4]; - - int from_x = MAX(0,x-max_radius); - int to_x = MIN(bt.width-1,x+max_radius); - int from_y = MAX(0,y-max_radius); - int to_y = MIN(bt.height-1,y+max_radius); - - for(int k=from_y;k<=to_y;k++) { - for(int l=from_x;l<=to_x;l++) { - - int dy = y-k; - int dx = x-l; - int dist = dy*dy+dx*dx; - if (dist>=closest_dist) - continue; - - const uint8_t * rp = ©_data[(k*bt.width+l)<<2]; - - if (rp[3]==0) - continue; - - closest_dist=dist; - closest_color[0]=rp[0]; - closest_color[1]=rp[1]; - closest_color[2]=rp[2]; - closest_color[3]=rp[3]; - } - } - - - if (closest_dist!=max_dist) { - - data[(y*bt.width+x)*4+0]=closest_color[0]; - data[(y*bt.width+x)*4+1]=closest_color[1]; - data[(y*bt.width+x)*4+2]=closest_color[2]; - data[(y*bt.width+x)*4+3]=closest_color[3]; - } - } - } - } - } - - PoolVector<uint8_t> dv; - dv.resize(baked_textures[i].data.size()); - { - PoolVector<uint8_t>::Write w = dv.write(); - copymem(w.ptr(),baked_textures[i].data.ptr(),baked_textures[i].data.size()); - } - - Image img(baked_textures[i].width,baked_textures[i].height,0,Image::FORMAT_RGBA8,dv); - Ref<ImageTexture> tex = memnew( ImageTexture ); - tex->create_from_image(img); - baked_light->set_lightmap_texture(i,tex); - } - - - return OK; -} - -void BakedLightBaker::clear() { - - - - _stop_thread(); - - if (bvh) - _free_bvh(bvh); - - if (ray_stack) - memdelete_arr(ray_stack); - if (octant_stack) - memdelete_arr(octant_stack); - if (octantptr_stack) - memdelete_arr(octantptr_stack); - if (bvh_stack) - memdelete_arr(bvh_stack); -/* - * ??? - for(int i=0;i<octant_pool.size();i++) { - /* - if (octant_pool[i].leaf) { - memdelete_arr( octant_pool[i].light ); - } - Vector<double> norm_arr; - norm_arr.resize(lights.size()); - */ - - for(int i=0;i<lights.size();i++) { - norm_arr[i] = 1.0/get_normalization(i); - } - - const double *normptr=norm_arr.ptr(); - } -*/ - octant_pool.clear(); - octant_pool_size=0; - bvh=NULL; - leaf_list=0; - cell_count=0; - ray_stack=NULL; - octant_stack=NULL; - octantptr_stack=NULL; - bvh_stack=NULL; - materials.clear(); - materials.clear(); - textures.clear(); - lights.clear(); - triangles.clear(); - endpoint_normal.clear(); - endpoint_normal_bits.clear(); - baked_octree_texture_w=0; - baked_octree_texture_h=0; - paused=false; - baking=false; - - bake_thread_exit=false; - first_bake_to_map=true; - baked_light=Ref<BakedLight>(); - total_rays=0; - -} - -BakedLightBaker::BakedLightBaker() { - octree_depth=9; - lattice_size=4; - octant_pool.clear(); - octant_pool_size=0; - bvh=NULL; - leaf_list=0; - cell_count=0; - ray_stack=NULL; - bvh_stack=NULL; - octant_stack=NULL; - octantptr_stack=NULL; - plot_size=2.5; - max_bounces=2; - materials.clear(); - baked_octree_texture_w=0; - baked_octree_texture_h=0; - paused=false; - baking=false; - - bake_thread_exit=false; - total_rays=0; - first_bake_to_map=true; - linear_color=false; - -} - -BakedLightBaker::~BakedLightBaker() { - - clear(); -} -#endif diff --git a/tools/editor/plugins/baked_light_editor_plugin.h b/tools/editor/plugins/baked_light_editor_plugin.h deleted file mode 100644 index e311fe9f17..0000000000 --- a/tools/editor/plugins/baked_light_editor_plugin.h +++ /dev/null @@ -1,120 +0,0 @@ -/*************************************************************************/ -/* baked_light_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef BAKED_LIGHT_EDITOR_PLUGIN_H -#define BAKED_LIGHT_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "tools/editor/plugins/baked_light_baker.h" -#include "scene/gui/spin_box.h" - - - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -#if 0 - -class MeshInstance; - -class BakedLightEditor : public Control { - - GDCLASS(BakedLightEditor, Control ); - - - float update_timeout; - PoolVector<uint8_t> octree_texture; - PoolVector<uint8_t> light_texture; - PoolVector<int> octree_sampler; - - BakedLightBaker *baker; - AcceptDialog *err_dialog; - - HBoxContainer *bake_hbox; - Button *button_bake; - Button *button_reset; - Button *button_make_lightmaps; - Label *bake_info; - - uint64_t last_rays_time; - - - - BakedLightInstance *node; - - enum Menu { - - MENU_OPTION_BAKE, - MENU_OPTION_CLEAR - }; - - void _bake_lightmaps(); - - void _bake_pressed(); - void _clear_pressed(); - - void _end_baking(); - void _menu_option(int); - -friend class BakedLightEditorPlugin; -protected: - void _node_removed(Node *p_node); - static void _bind_methods(); - void _notification(int p_what); -public: - - void edit(BakedLightInstance *p_baked_light); - BakedLightEditor(); - ~BakedLightEditor(); -}; - -class BakedLightEditorPlugin : public EditorPlugin { - - GDCLASS( BakedLightEditorPlugin, EditorPlugin ); - - BakedLightEditor *baked_light_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "BakedLight"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - BakedLightEditorPlugin(EditorNode *p_node); - ~BakedLightEditorPlugin(); - -}; - -#endif // MULTIMESH_EDITOR_PLUGIN_H -#endif - diff --git a/tools/editor/plugins/camera_editor_plugin.h b/tools/editor/plugins/camera_editor_plugin.h deleted file mode 100644 index 7e79d0ec74..0000000000 --- a/tools/editor/plugins/camera_editor_plugin.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************/ -/* camera_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef CAMERA_EDITOR_PLUGIN_H -#define CAMERA_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/3d/camera.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -class CameraEditor : public Control { - - GDCLASS(CameraEditor, Control ); - - Panel *panel; - Button * preview; - Node *node; - - void _pressed(); -protected: - void _notification(int p_what); - void _node_removed(Node *p_node); - static void _bind_methods(); -public: - - void edit(Node *p_camera); - CameraEditor(); -}; - -class CameraEditorPlugin : public EditorPlugin { - - GDCLASS( CameraEditorPlugin, EditorPlugin ); - - //CameraEditor *camera_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "Camera"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - CameraEditorPlugin(EditorNode *p_node); - ~CameraEditorPlugin(); - -}; - -#endif // CAMERA_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp deleted file mode 100644 index 8af925db7a..0000000000 --- a/tools/editor/plugins/canvas_item_editor_plugin.cpp +++ /dev/null @@ -1,4063 +0,0 @@ -/*************************************************************************/ -/* canvas_item_editor_plugin.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 "canvas_item_editor_plugin.h" - -#include "print_string.h" -#include "tools/editor/editor_node.h" -#include "os/keyboard.h" -#include "scene/main/viewport.h" -#include "scene/main/canvas_layer.h" -#include "scene/2d/sprite.h" -#include "scene/2d/light_2d.h" -#include "scene/2d/particles_2d.h" -#include "scene/2d/polygon_2d.h" -#include "scene/2d/screen_button.h" -#include "global_config.h" -#include "os/input.h" -#include "tools/editor/editor_settings.h" -#include "scene/gui/grid_container.h" -#include "scene/gui/patch_9_rect.h" -#include "tools/editor/animation_editor.h" -#include "tools/editor/plugins/animation_player_editor_plugin.h" -#include "tools/editor/script_editor_debugger.h" -#include "tools/editor/plugins/script_editor_plugin.h" -#include "scene/resources/packed_scene.h" - - -#define MIN_ZOOM 0.01 -#define MAX_ZOOM 100 - - -class SnapDialog : public ConfirmationDialog { - - GDCLASS(SnapDialog,ConfirmationDialog); - -friend class CanvasItemEditor; - - SpinBox *grid_offset_x; - SpinBox *grid_offset_y; - SpinBox *grid_step_x; - SpinBox *grid_step_y; - SpinBox *rotation_offset; - SpinBox *rotation_step; - -public: - SnapDialog() : ConfirmationDialog() { - const int SPIN_BOX_GRID_RANGE = 256; - const int SPIN_BOX_ROTATION_RANGE = 360; - Label *label; - VBoxContainer *container; - GridContainer *child_container; - - set_title(TTR("Configure Snap")); - get_ok()->set_text(TTR("Close")); - - container = memnew( VBoxContainer ); - add_child(container); - //set_child_rect(container); - - child_container = memnew( GridContainer ); - child_container->set_columns(3); - container->add_child(child_container); - - label = memnew( Label ); - label->set_text(TTR("Grid Offset:")); - child_container->add_child(label); - label->set_h_size_flags(SIZE_EXPAND_FILL); - - grid_offset_x = memnew( SpinBox ); - grid_offset_x->set_min(-SPIN_BOX_GRID_RANGE); - grid_offset_x->set_max(SPIN_BOX_GRID_RANGE); - grid_offset_x->set_suffix("px"); - child_container->add_child(grid_offset_x); - - grid_offset_y = memnew( SpinBox ); - grid_offset_y->set_min(-SPIN_BOX_GRID_RANGE); - grid_offset_y->set_max(SPIN_BOX_GRID_RANGE); - grid_offset_y->set_suffix("px"); - child_container->add_child(grid_offset_y); - - label = memnew( Label ); - label->set_text(TTR("Grid Step:")); - child_container->add_child(label); - label->set_h_size_flags(SIZE_EXPAND_FILL); - - grid_step_x = memnew( SpinBox ); - grid_step_x->set_min(-SPIN_BOX_GRID_RANGE); - grid_step_x->set_max(SPIN_BOX_GRID_RANGE); - grid_step_x->set_suffix("px"); - child_container->add_child(grid_step_x); - - grid_step_y = memnew( SpinBox ); - grid_step_y->set_min(-SPIN_BOX_GRID_RANGE); - grid_step_y->set_max(SPIN_BOX_GRID_RANGE); - grid_step_y->set_suffix("px"); - child_container->add_child(grid_step_y); - - container->add_child( memnew( HSeparator ) ); - - child_container = memnew( GridContainer ); - child_container->set_columns(2); - container->add_child(child_container); - - label = memnew( Label ); - label->set_text(TTR("Rotation Offset:")); - child_container->add_child(label); - label->set_h_size_flags(SIZE_EXPAND_FILL); - - rotation_offset = memnew( SpinBox ); - rotation_offset->set_min(-SPIN_BOX_ROTATION_RANGE); - rotation_offset->set_max(SPIN_BOX_ROTATION_RANGE); - rotation_offset->set_suffix("deg"); - child_container->add_child(rotation_offset); - - label = memnew( Label ); - label->set_text(TTR("Rotation Step:")); - child_container->add_child(label); - label->set_h_size_flags(SIZE_EXPAND_FILL); - - rotation_step = memnew( SpinBox ); - rotation_step->set_min(-SPIN_BOX_ROTATION_RANGE); - rotation_step->set_max(SPIN_BOX_ROTATION_RANGE); - rotation_step->set_suffix("deg"); - child_container->add_child(rotation_step); - } - - void set_fields(const Point2 p_grid_offset, const Size2 p_grid_step, const float p_rotation_offset, const float p_rotation_step) { - grid_offset_x->set_value(p_grid_offset.x); - grid_offset_y->set_value(p_grid_offset.y); - grid_step_x->set_value(p_grid_step.x); - grid_step_y->set_value(p_grid_step.y); - rotation_offset->set_value(p_rotation_offset * (180 / Math_PI)); - rotation_step->set_value(p_rotation_step * (180 / Math_PI)); - } - - void get_fields(Point2 &p_grid_offset, Size2 &p_grid_step, float &p_rotation_offset, float &p_rotation_step) { - p_grid_offset.x = grid_offset_x->get_value(); - p_grid_offset.y = grid_offset_y->get_value(); - p_grid_step.x = grid_step_x->get_value(); - p_grid_step.y = grid_step_y->get_value(); - p_rotation_offset = rotation_offset->get_value() / (180 / Math_PI); - p_rotation_step = rotation_step->get_value() / (180 / Math_PI); - } -}; - -void CanvasItemEditor::_edit_set_pivot(const Vector2& mouse_pos) { - List<Node*> &selection = editor_selection->get_selected_node_list(); - - undo_redo->create_action(TTR("Move Pivot")); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - Node2D *n2d = E->get()->cast_to<Node2D>(); - - if (n2d && n2d->edit_has_pivot()) { - - Vector2 offset = n2d->edit_get_pivot(); - Vector2 gpos = n2d->get_global_position(); - - Vector2 local_mouse_pos = n2d->get_canvas_transform().affine_inverse().xform(mouse_pos); - - Vector2 motion_ofs = gpos-local_mouse_pos; - - undo_redo->add_do_method(n2d,"set_global_pos",local_mouse_pos); - undo_redo->add_do_method(n2d,"edit_set_pivot",offset+n2d->get_global_transform().affine_inverse().basis_xform(motion_ofs)); - undo_redo->add_undo_method(n2d,"set_global_pos",gpos); - undo_redo->add_undo_method(n2d,"edit_set_pivot",offset); - for(int i=0;i<n2d->get_child_count();i++) { - Node2D *n2dc = n2d->get_child(i)->cast_to<Node2D>(); - if (!n2dc) - continue; - - undo_redo->add_do_method(n2dc,"set_global_pos",n2dc->get_global_position()); - undo_redo->add_undo_method(n2dc,"set_global_pos",n2dc->get_global_position()); - - } - - } - - } - - undo_redo->commit_action(); - -} - -void CanvasItemEditor::_unhandled_key_input(const InputEvent& p_ev) { - - if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack()) - return; - - if (p_ev.key.mod.control) - return; - - if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_V && drag==DRAG_NONE && can_move_pivot) { - - if (p_ev.key.mod.shift) { - //move drag pivot - drag=DRAG_PIVOT; - } else if (!Input::get_singleton()->is_mouse_button_pressed(0)) { - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - Vector2 mouse_pos = viewport->get_local_mouse_pos(); - if (selection.size() && viewport->get_rect().has_point(mouse_pos)) { - //just in case, make it work if over viewport - mouse_pos=transform.affine_inverse().xform(mouse_pos); - mouse_pos=snap_point(mouse_pos); - - _edit_set_pivot(mouse_pos); - } - - } - } - -} - -void CanvasItemEditor::_tool_select(int p_index) { - - - ToolButton *tb[TOOL_MAX]={select_button,list_select_button,move_button,rotate_button,pivot_button,pan_button}; - for(int i=0;i<TOOL_MAX;i++) { - - tb[i]->set_pressed(i==p_index); - } - - - viewport->update(); - tool=(Tool)p_index; - -} - -Object *CanvasItemEditor::_get_editor_data(Object *p_what) { - - CanvasItem *ci = p_what->cast_to<CanvasItem>(); - if (!ci) - return NULL; - - return memnew( CanvasItemEditorSelectedItem ); -} - -inline float _snap_scalar(float p_offset, float p_step, bool p_snap_relative, float p_target, float p_start) { - float offset = p_snap_relative ? p_start : p_offset; - return p_step != 0 ? Math::stepify(p_target - offset, p_step) + offset : p_target; -} - -Vector2 CanvasItemEditor::snap_point(Vector2 p_target, Vector2 p_start) const { - if (snap_grid) { - p_target.x = _snap_scalar(snap_offset.x, snap_step.x, snap_relative, p_target.x, p_start.x); - p_target.y = _snap_scalar(snap_offset.y, snap_step.y, snap_relative, p_target.y, p_start.y); - } - if (snap_pixel) - p_target = p_target.snapped(Size2(1, 1)); - - return p_target; -} - -float CanvasItemEditor::snap_angle(float p_target, float p_start) const { - return snap_rotation ? _snap_scalar(snap_rotation_offset, snap_rotation_step, snap_relative, p_target, p_start) : p_target; -} - -Dictionary CanvasItemEditor::get_state() const { - - Dictionary state; - state["zoom"]=zoom; - state["ofs"]=Point2(h_scroll->get_value(),v_scroll->get_value()); - //state["ofs"]=-transform.get_origin(); - state["snap_offset"]=snap_offset; - state["snap_step"]=snap_step; - state["snap_rotation_offset"]=snap_rotation_offset; - state["snap_rotation_step"]=snap_rotation_step; - state["snap_grid"]=snap_grid; - state["snap_show_grid"]=snap_show_grid; - state["snap_rotation"]=snap_rotation; - state["snap_relative"]=snap_relative; - state["snap_pixel"]=snap_pixel; - state["skeleton_show_bones"]=skeleton_show_bones; - return state; -} -void CanvasItemEditor::set_state(const Dictionary& p_state){ - - Dictionary state=p_state; - if (state.has("zoom")) { - zoom=p_state["zoom"]; - } - - if (state.has("ofs")) { - _update_scrollbars(); // i wonder how safe is calling this here.. - Point2 ofs=p_state["ofs"]; - h_scroll->set_value(ofs.x); - v_scroll->set_value(ofs.y); - } - - if (state.has("snap_step")) { - snap_step=state["snap_step"]; - } - - if (state.has("snap_offset")) { - snap_offset=state["snap_offset"]; - } - - if (state.has("snap_rotation_step")) { - snap_rotation_step=state["snap_rotation_step"]; - } - - if (state.has("snap_rotation_offset")) { - snap_rotation_offset=state["snap_rotation_offset"]; - } - - if (state.has("snap_grid")) { - snap_grid=state["snap_grid"]; - int idx = edit_menu->get_popup()->get_item_index(SNAP_USE); - edit_menu->get_popup()->set_item_checked(idx,snap_grid); - } - - if (state.has("snap_show_grid")) { - snap_show_grid=state["snap_show_grid"]; - int idx = edit_menu->get_popup()->get_item_index(SNAP_SHOW_GRID); - edit_menu->get_popup()->set_item_checked(idx,snap_show_grid); - } - - if (state.has("snap_rotation")) { - snap_rotation=state["snap_rotation"]; - int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_ROTATION); - edit_menu->get_popup()->set_item_checked(idx,snap_rotation); - } - - if (state.has("snap_relative")) { - snap_relative=state["snap_relative"]; - int idx = edit_menu->get_popup()->get_item_index(SNAP_RELATIVE); - edit_menu->get_popup()->set_item_checked(idx,snap_relative); - } - - if (state.has("snap_pixel")) { - snap_pixel=state["snap_pixel"]; - int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_PIXEL); - edit_menu->get_popup()->set_item_checked(idx,snap_pixel); - } - - if (state.has("skeleton_show_bones")) { - skeleton_show_bones=state["skeleton_show_bones"]; - int idx = skeleton_menu->get_item_index(SKELETON_SHOW_BONES); - skeleton_menu->set_item_checked(idx,skeleton_show_bones); - } -} - - -void CanvasItemEditor::_add_canvas_item(CanvasItem *p_canvas_item) { - - editor_selection->add_node(p_canvas_item); -#if 0 - if (canvas_items.has(p_canvas_item)) - return; - - canvas_items.insert(p_canvas_item,p_info); - p_canvas_item->connect("hide",this,"_visibility_changed",varray(p_canvas_item->get_instance_ID()),CONNECT_ONESHOT); -#endif -} - -void CanvasItemEditor::_remove_canvas_item(CanvasItem *p_canvas_item) { - - editor_selection->remove_node(p_canvas_item); -#if 0 - p_canvas_item->disconnect("hide",this,"_visibility_changed"); - canvas_items.erase(p_canvas_item); -#endif - -} -void CanvasItemEditor::_clear_canvas_items() { - - editor_selection->clear(); -#if 0 - while(canvas_items.size()) - _remove_canvas_item(canvas_items.front()->key()); -#endif -} - -void CanvasItemEditor::_visibility_changed(ObjectID p_canvas_item) { -#if 0 - Object *c = ObjectDB::get_instance(p_canvas_item); - if (!c) - return; - CanvasItem *ct = c->cast_to<CanvasItem>(); - if (!ct) - return; - canvas_items.erase(ct); - //_remove_canvas_item(ct); - update(); -#endif -} - - -void CanvasItemEditor::_node_removed(Node *p_node) { -#if 0 - CanvasItem *canvas_item = (CanvasItem*)p_node; //not a good cast, but safe - if (canvas_items.has(canvas_item)) - _remove_canvas_item(canvas_item); - - update(); -#endif -} - -void CanvasItemEditor::_keying_changed() { - - if (AnimationPlayerEditor::singleton->get_key_editor()->is_visible_in_tree()) - animation_hb->show(); - else - animation_hb->hide(); -} - -bool CanvasItemEditor::_is_part_of_subscene(CanvasItem *p_item) { - - Node* scene_node = get_tree()->get_edited_scene_root(); - Node* item_owner = p_item->get_owner(); - - return item_owner && item_owner!=scene_node && p_item!=scene_node && item_owner->get_filename()!=""; -} - -// slow but modern computers should have no problem -CanvasItem* CanvasItemEditor::_select_canvas_item_at_pos(const Point2& p_pos,Node* p_node,const Transform2D& p_parent_xform,const Transform2D& p_canvas_xform) { - - if (!p_node) - return NULL; - if (p_node->cast_to<Viewport>()) - return NULL; - - CanvasItem *c=p_node->cast_to<CanvasItem>(); - - - for (int i=p_node->get_child_count()-1;i>=0;i--) { - - CanvasItem *r=NULL; - - if (c && !c->is_set_as_toplevel()) - r=_select_canvas_item_at_pos(p_pos,p_node->get_child(i),p_parent_xform * c->get_transform(),p_canvas_xform); - else { - CanvasLayer *cl = p_node->cast_to<CanvasLayer>(); - r=_select_canvas_item_at_pos(p_pos,p_node->get_child(i),transform ,cl ? cl->get_transform() : p_canvas_xform); //use base transform - } - - if (r) - return r; - } - - if (c && c->is_visible_in_tree() && !c->has_meta("_edit_lock_") && !_is_part_of_subscene(c) && !c->cast_to<CanvasLayer>()) { - - Rect2 rect = c->get_item_rect(); - Point2 local_pos = (p_parent_xform * p_canvas_xform * c->get_transform()).affine_inverse().xform(p_pos); - - - if (rect.has_point(local_pos)) - return c; - - } - - return NULL; -} - -void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos,Node* p_node,const Transform2D& p_parent_xform,const Transform2D& p_canvas_xform, Vector<_SelectResult> &r_items) { - if (!p_node) - return; - if (p_node->cast_to<Viewport>()) - return; - - CanvasItem *c=p_node->cast_to<CanvasItem>(); - - for (int i=p_node->get_child_count()-1;i>=0;i--) { - - if (c && !c->is_set_as_toplevel()) - _find_canvas_items_at_pos(p_pos,p_node->get_child(i),p_parent_xform * c->get_transform(),p_canvas_xform, r_items); - else { - CanvasLayer *cl = p_node->cast_to<CanvasLayer>(); - _find_canvas_items_at_pos(p_pos,p_node->get_child(i),transform ,cl ? cl->get_transform() : p_canvas_xform, r_items); //use base transform - } - } - - - if (c && c->is_visible_in_tree() && !c->has_meta("_edit_lock_") && !c->cast_to<CanvasLayer>()) { - - Rect2 rect = c->get_item_rect(); - Point2 local_pos = (p_parent_xform * p_canvas_xform * c->get_transform()).affine_inverse().xform(p_pos); - - - if (rect.has_point(local_pos)) { - Node2D *node=c->cast_to<Node2D>(); - - _SelectResult res; - res.item=c; - res.z=node?node->get_z():0; - res.has_z=node; - r_items.push_back(res); - } - - } - - return; -} - -void CanvasItemEditor::_find_canvas_items_at_rect(const Rect2& p_rect,Node* p_node,const Transform2D& p_parent_xform,const Transform2D& p_canvas_xform,List<CanvasItem*> *r_items) { - - if (!p_node) - return; - if (p_node->cast_to<Viewport>()) - return; - - CanvasItem *c=p_node->cast_to<CanvasItem>(); - - - bool inherited=p_node!=get_tree()->get_edited_scene_root() && p_node->get_filename()!=""; - bool editable=false; - if (inherited){ - editable=EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node); - } - bool lock_children=p_node->has_meta("_edit_group_") && p_node->get_meta("_edit_group_"); - if (!lock_children && (!inherited || editable)) { - for (int i=p_node->get_child_count()-1;i>=0;i--) { - - if (c && !c->is_set_as_toplevel()) - _find_canvas_items_at_rect(p_rect,p_node->get_child(i),p_parent_xform * c->get_transform(),p_canvas_xform,r_items); - else { - CanvasLayer *cl = p_node->cast_to<CanvasLayer>(); - _find_canvas_items_at_rect(p_rect,p_node->get_child(i),transform,cl?cl->get_transform():p_canvas_xform,r_items); - } - } - } - - if (c && c->is_visible_in_tree() && !c->has_meta("_edit_lock_") && !c->cast_to<CanvasLayer>()) { - - Rect2 rect = c->get_item_rect(); - Transform2D xform = p_parent_xform * p_canvas_xform * c->get_transform(); - - if ( p_rect.has_point( xform.xform( rect.pos ) ) && - p_rect.has_point( xform.xform( rect.pos+Vector2(rect.size.x,0) ) ) && - p_rect.has_point( xform.xform( rect.pos+Vector2(rect.size.x,rect.size.y) ) ) && - p_rect.has_point( xform.xform( rect.pos+Vector2(0,rect.size.y) ) ) ) { - - r_items->push_back(c); - - } - } - - -} - -bool CanvasItemEditor::_select(CanvasItem *item, Point2 p_click_pos, bool p_append, bool p_drag) { - - if (p_append) { - //additive selection - - if (!item) { - - if (p_drag) { - drag_from=transform.affine_inverse().xform(p_click_pos); - - box_selecting=true; - box_selecting_to=drag_from; - } - - return false; //nothing to add - } - - if (editor_selection->is_selected(item)) { - //already in here, erase it - editor_selection->remove_node(item); - //_remove_canvas_item(c); - - viewport->update(); - return false; - - } - _append_canvas_item(item); - viewport->update(); - - return true; - - } else { - //regular selection - - if (!item) { - //clear because nothing clicked - editor_selection->clear(); - - if (p_drag) { - drag_from=transform.affine_inverse().xform(p_click_pos); - - box_selecting=true; - box_selecting_to=drag_from; - } - - viewport->update(); - return false; - } - - if (!editor_selection->is_selected(item)) { - //select a new one and clear previous selection - editor_selection->clear(); - editor_selection->add_node(item); - //reselect - if (get_tree()->is_editor_hint()) { - editor->call("edit_node",item); - } - - } - - if (p_drag) { - //prepare to move! - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - if (!se) - continue; - - se->undo_state=canvas_item->edit_get_state(); - if (canvas_item->cast_to<Node2D>()) - se->undo_pivot=canvas_item->cast_to<Node2D>()->edit_get_pivot(); - - } - - drag=DRAG_ALL; - drag_from=transform.affine_inverse().xform(p_click_pos); - drag_point_from=_find_topleftmost_point(); - } - - viewport->update(); - - return true; - - } -} - -void CanvasItemEditor::_key_move(const Vector2& p_dir, bool p_snap, KeyMoveMODE p_move_mode) { - - - if (drag!=DRAG_NONE) - return; - - if (editor_selection->get_selected_node_list().empty()) - return; - - undo_redo->create_action(TTR("Move Action"),UndoRedo::MERGE_ENDS); - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - if (!se) - continue; - - if (canvas_item->has_meta("_edit_lock_")) - continue; - - - Vector2 drag = p_dir; - if (p_snap) - drag*=snap_step; - - undo_redo->add_undo_method(canvas_item,"edit_set_state",canvas_item->edit_get_state()); - - if (p_move_mode == MOVE_VIEW_BASE) { - - // drag = transform.affine_inverse().basis_xform(p_dir); // zoom sensitive - drag = canvas_item->get_global_transform_with_canvas().affine_inverse().basis_xform(drag); - Rect2 local_rect = canvas_item->get_item_rect(); - local_rect.pos+=drag; - undo_redo->add_do_method(canvas_item,"edit_set_rect",local_rect); - - } else { // p_move_mode==MOVE_LOCAL_BASE || p_move_mode==MOVE_LOCAL_WITH_ROT - - if (Node2D *node_2d = canvas_item->cast_to<Node2D>()) { - - if (p_move_mode == MOVE_LOCAL_WITH_ROT) { - Transform2D m; - m.rotate( node_2d->get_rotation() ); - drag = m.xform(drag); - } - node_2d->set_position(node_2d->get_position() + drag); - - } else if (Control *control = canvas_item->cast_to<Control>()) { - - control->set_pos(control->get_pos()+drag); - } - } - } - - undo_redo->commit_action(); -} - -Point2 CanvasItemEditor::_find_topleftmost_point() { - - - - Vector2 tl=Point2(1e10,1e10); - Rect2 r2; - r2.pos=tl; - - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - - - - Rect2 rect=canvas_item->get_item_rect(); - Transform2D xform=canvas_item->get_global_transform_with_canvas(); - - r2.expand_to(xform.xform(rect.pos)); - r2.expand_to(xform.xform(rect.pos+Vector2(rect.size.x,0))); - r2.expand_to(xform.xform(rect.pos+rect.size)); - r2.expand_to(xform.xform(rect.pos+Vector2(0,rect.size.y))); - - } - - return r2.pos; -} - - - -int CanvasItemEditor::get_item_count() { - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - int ic=0; - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - ic++; - }; - - return ic; -} - -CanvasItem *CanvasItemEditor::get_single_item() { - - - Map<Node*,Object*> &selection = editor_selection->get_selection(); - - CanvasItem *single_item=NULL; - - for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->key()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - if (single_item) - return NULL; //morethan one - - single_item=canvas_item; - }; - - return single_item; -} - -CanvasItemEditor::DragType CanvasItemEditor::_find_drag_type(const Transform2D& p_xform, const Rect2& p_local_rect, const Point2& p_click, Vector2& r_point) { - - CanvasItem *canvas_item = get_single_item(); - - ERR_FAIL_COND_V(!canvas_item,DRAG_NONE); - - Rect2 rect=canvas_item->get_item_rect(); - Transform2D xforml=canvas_item->get_global_transform_with_canvas(); - Transform2D xform=transform * xforml; - - Vector2 endpoints[4]={ - - xform.xform(rect.pos), - xform.xform(rect.pos+Vector2(rect.size.x,0)), - xform.xform(rect.pos+rect.size), - xform.xform(rect.pos+Vector2(0,rect.size.y)) - }; - - Vector2 endpointsl[4]={ - - xforml.xform(rect.pos), - xforml.xform(rect.pos+Vector2(rect.size.x,0)), - xforml.xform(rect.pos+rect.size), - xforml.xform(rect.pos+Vector2(0,rect.size.y)) - }; - - DragType dragger[]={ - DRAG_TOP_LEFT, - DRAG_TOP, - DRAG_TOP_RIGHT, - DRAG_RIGHT, - DRAG_BOTTOM_RIGHT, - DRAG_BOTTOM, - DRAG_BOTTOM_LEFT, - DRAG_LEFT - }; - - float radius = (select_handle->get_size().width/2)*1.5; - - //try draggers - - for(int i=0;i<4;i++) { - - int prev = (i+3)%4; - int next = (i+1)%4; - - r_point=endpointsl[i]; - - Vector2 ofs = ((endpoints[i] - endpoints[prev]).normalized() + ((endpoints[i] - endpoints[next]).normalized())).normalized(); - ofs*=1.4144*(select_handle->get_size().width/2); - - ofs+=endpoints[i]; - - if (ofs.distance_to(p_click)<radius) - return dragger[i*2]; - - ofs = (endpoints[i]+endpoints[next])/2; - ofs += (endpoints[next]-endpoints[i]).tangent().normalized()*(select_handle->get_size().width/2); - - r_point=(endpointsl[i]+endpointsl[next])/2; - - - if (ofs.distance_to(p_click)<radius) - return dragger[i*2+1]; - - } - - /* - if (rect.has_point(xform.affine_inverse().xform(p_click))) { - r_point=_find_topleftmost_point(); - return DRAG_ALL; - }*/ - - //try draggers - - return DRAG_NONE; -} - -void CanvasItemEditor::incbeg(float& beg,float &end, float inc, float minsize,bool p_symmetric) { - - if (minsize<0) { - - beg+=inc; - if (p_symmetric) - end-=inc; - } else { - - if (p_symmetric) { - beg+=inc; - end-=inc; - if (end-beg < minsize) { - float center = (beg+end)/2.0; - beg=center-minsize/2.0; - end=center+minsize/2.0; - } - - } else { - if (end-(beg+inc) < minsize) - beg=end-minsize; - else - beg+=inc; - } - - } -} - -void CanvasItemEditor::incend(float &beg,float& end, float inc, float minsize,bool p_symmetric) { - - if (minsize<0) { - - end+=inc; - if (p_symmetric) - beg-=inc; - } else { - - if (p_symmetric) { - - end+=inc; - beg-=inc; - if (end-beg < minsize) { - float center = (beg+end)/2.0; - beg=center-minsize/2.0; - end=center+minsize/2.0; - } - - } else { - if ((end+inc)-beg < minsize) - end=beg+minsize; - else - end+=inc; - } - - } -} - -void CanvasItemEditor::_append_canvas_item(CanvasItem *c) { - - editor_selection->add_node(c); - -} - - -void CanvasItemEditor::_snap_changed() { - ((SnapDialog *)snap_dialog)->get_fields(snap_offset, snap_step, snap_rotation_offset, snap_rotation_step); - viewport->update(); -} - -void CanvasItemEditor::_dialog_value_changed(double) { - - if (updating_value_dialog) - return; - - switch(last_option) { - - case ZOOM_SET: { - - zoom=dialog_val->get_value()/100.0; - _update_scroll(0); - viewport->update(); - - } break; - default:{} - } -} - -void CanvasItemEditor::_selection_result_pressed(int p_result) { - - if (selection_results.size() <= p_result) - return; - - CanvasItem *item=selection_results[p_result].item; - - if (item) - _select(item, Point2(), additive_selection, false); -} - -void CanvasItemEditor::_selection_menu_hide() { - - selection_results.clear(); - selection_menu->clear(); - selection_menu->set_size(Vector2(0, 0)); -} - -bool CanvasItemEditor::get_remove_list(List<Node*> *p_list) { - - - return false;//!p_list->empty(); -} - - -void CanvasItemEditor::_list_select(const InputEventMouseButton& b) { - - Point2 click=Point2(b.x,b.y); - - Node* scene = editor->get_edited_scene(); - if (!scene) - return; - - _find_canvas_items_at_pos(click, scene,transform,Transform2D(), selection_results); - - for(int i=0;i<selection_results.size();i++) { - CanvasItem *item=selection_results[i].item; - if (item!=scene && item->get_owner()!=scene && !scene->is_editable_instance(item->get_owner())) { - //invalid result - selection_results.remove(i); - i--; - } - - } - - if (selection_results.size() == 1) { - - CanvasItem *item = selection_results[0].item; - selection_results.clear(); - - additive_selection=b.mod.shift; - if (!_select(item, click, additive_selection, false)) - return; - - } else if (!selection_results.empty()) { - - selection_results.sort(); - - NodePath root_path = get_tree()->get_edited_scene_root()->get_path(); - StringName root_name = root_path.get_name(root_path.get_name_count()-1); - - for (int i = 0; i < selection_results.size(); i++) { - - CanvasItem *item=selection_results[i].item; - - - Ref<Texture> icon; - if (item->has_meta("_editor_icon")) - icon=item->get_meta("_editor_icon"); - else - icon=get_icon( has_icon(item->get_class(),"EditorIcons")?item->get_class():String("Object"),"EditorIcons"); - - String node_path="/"+root_name+"/"+root_path.rel_path_to(item->get_path()); - - selection_menu->add_item(item->get_name()); - selection_menu->set_item_icon(i, icon ); - selection_menu->set_item_metadata(i, node_path); - selection_menu->set_item_tooltip(i,String(item->get_name())+ - "\nType: "+item->get_class()+"\nPath: "+node_path); - } - - additive_selection=b.mod.shift; - - selection_menu->set_global_pos(Vector2( b.global_x, b.global_y )); - selection_menu->popup(); - selection_menu->call_deferred("grab_click_focus"); - selection_menu->set_invalidate_click_until_motion(); - - - return; - } - -} - -void CanvasItemEditor::_viewport_gui_input(const InputEvent& p_event) { - - { - - EditorNode *en = editor; - EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); - - if (!over_plugin_list->empty()) { - bool discard = over_plugin_list->forward_gui_input(transform,p_event); - if (discard) { - accept_event(); - return; - } - } - } - - - if (p_event.type==InputEvent::MOUSE_BUTTON) { - - const InputEventMouseButton &b=p_event.mouse_button; - - - if (b.button_index==BUTTON_WHEEL_DOWN) { - - if (zoom<MIN_ZOOM) - return; - - float prev_zoom=zoom; - zoom=zoom*0.95; - { - Point2 ofs(b.x,b.y); - ofs = ofs/prev_zoom - ofs/zoom; - h_scroll->set_value( h_scroll->get_value() + ofs.x ); - v_scroll->set_value( v_scroll->get_value() + ofs.y ); - } - _update_scroll(0); - viewport->update(); - return; - } - - if (b.button_index==BUTTON_WHEEL_UP) { - - if (zoom>MAX_ZOOM) - return; - - float prev_zoom=zoom; - zoom=zoom*(1.0/0.95); - { - Point2 ofs(b.x,b.y); - ofs = ofs/prev_zoom - ofs/zoom; - h_scroll->set_value( h_scroll->get_value() + ofs.x ); - v_scroll->set_value( v_scroll->get_value() + ofs.y ); - } - - _update_scroll(0); - viewport->update(); - return; - } - - if (b.button_index==BUTTON_RIGHT) { - - - if (b.pressed && (tool==TOOL_SELECT && b.mod.alt)) { - - _list_select(b); - return; - } - - if (get_item_count() > 0 && drag!=DRAG_NONE) { - //cancel drag - - if (bone_ik_list.size()) { - - for(List<BoneIK>::Element *E=bone_ik_list.back();E;E=E->prev()) { - - E->get().node->edit_set_state(E->get().orig_state); - } - - bone_ik_list.clear(); - - } else { - - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - - CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - if (!se) - continue; - - canvas_item->edit_set_state(se->undo_state); - if (canvas_item->cast_to<Node2D>()) - canvas_item->cast_to<Node2D>()->edit_set_pivot(se->undo_pivot); - - } - } - - drag=DRAG_NONE; - viewport->update(); - can_move_pivot=false; - - } else if (box_selecting) { - box_selecting=false; - viewport->update(); - } else if (b.pressed) { -#if 0 - ref_item = NULL; - Node* scene = get_scene()->get_root_node()->cast_to<EditorNode>()->get_edited_scene(); - if ( scene ) ref_item =_select_canvas_item_at_pos( Point2( b.x, b.y ), scene, transform ); -#endif - //popup->set_pos(Point2(b.x,b.y)); - //popup->popup(); - } - return; - } - /* - if (!canvas_items.size()) - return; - */ - - if (b.button_index==BUTTON_LEFT && tool==TOOL_LIST_SELECT) { - if (b.pressed) - _list_select(b); - return; - } - - - if (b.button_index==BUTTON_LEFT && tool==TOOL_EDIT_PIVOT) { - if (b.pressed) { - - Point2 mouse_pos(b.x,b.y); - mouse_pos=transform.affine_inverse().xform(mouse_pos); - mouse_pos=snap_point(mouse_pos); - _edit_set_pivot(mouse_pos); - } - return; - } - - - - if (tool==TOOL_PAN || b.button_index!=BUTTON_LEFT || Input::get_singleton()->is_key_pressed(KEY_SPACE)) - return; - - if (!b.pressed) { - - if (drag!=DRAG_NONE) { - - if (undo_redo) { - - - if (bone_ik_list.size()) { - - - undo_redo->create_action(TTR("Edit IK Chain")); - - for(List<BoneIK>::Element *E=bone_ik_list.back();E;E=E->prev()) { - - undo_redo->add_do_method(E->get().node,"edit_set_state",E->get().node->edit_get_state()); - undo_redo->add_undo_method(E->get().node,"edit_set_state",E->get().orig_state); - } - - undo_redo->add_do_method(viewport,"update"); - undo_redo->add_undo_method(viewport,"update"); - - bone_ik_list.clear(); - - undo_redo->commit_action(); - } else { - - undo_redo->create_action(TTR("Edit CanvasItem")); - - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - if (!se) - continue; - - Variant state=canvas_item->edit_get_state(); - undo_redo->add_do_method(canvas_item,"edit_set_state",state); - undo_redo->add_undo_method(canvas_item,"edit_set_state",se->undo_state); - if (canvas_item->cast_to<Node2D>()) { - Node2D *pvt = canvas_item->cast_to<Node2D>(); - if (pvt->edit_has_pivot()) { - undo_redo->add_do_method(canvas_item,"edit_set_pivot",pvt->edit_get_pivot()); - undo_redo->add_undo_method(canvas_item,"edit_set_pivot",se->undo_pivot); - } - } - } - undo_redo->commit_action(); - } - } - - drag=DRAG_NONE; - viewport->update(); - can_move_pivot=false; - - } - - if (box_selecting) { -#if 0 - if ( ! b.mod.shift ) _clear_canvas_items(); - if ( box_selection_end() ) return; -#endif - - Node* scene = editor->get_edited_scene(); - if (scene) { - - List<CanvasItem*> selitems; - - Point2 bsfrom = transform.xform(drag_from); - Point2 bsto= transform.xform(box_selecting_to); - if (bsfrom.x>bsto.x) - SWAP(bsfrom.x,bsto.x); - if (bsfrom.y>bsto.y) - SWAP(bsfrom.y,bsto.y); - - _find_canvas_items_at_rect(Rect2(bsfrom,bsto-bsfrom),scene,transform,Transform2D(),&selitems); - - for(List<CanvasItem*>::Element *E=selitems.front();E;E=E->next()) { - - _append_canvas_item(E->get()); - } - - } - - box_selecting=false; - viewport->update(); - - } - return; - } - - - Map<ObjectID,BoneList>::Element *Cbone=NULL; //closest - - { - bone_ik_list.clear(); - float closest_dist=1e20; - int bone_width = EditorSettings::get_singleton()->get("editors/2d/bone_width"); - for(Map<ObjectID,BoneList>::Element *E=bone_list.front();E;E=E->next()) { - - if (E->get().from == E->get().to) - continue; - Vector2 s[2]={ - E->get().from, - E->get().to - }; - - Vector2 p = Geometry::get_closest_point_to_segment_2d(Vector2(b.x,b.y),s); - float d = p.distance_to(Vector2(b.x,b.y)); - if (d<bone_width && d<closest_dist) { - Cbone=E; - closest_dist=d; - } - } - - if (Cbone) { - Node2D *b=NULL; - Object* obj=ObjectDB::get_instance(Cbone->get().bone); - if (obj) - b=obj->cast_to<Node2D>(); - - if (b) { - - - bool ik_found=false; - bool first=true; - - - - while(b) { - - CanvasItem *pi=b->get_parent_item(); - if (!pi) - break; - - float len=pi->get_global_transform().get_origin().distance_to(b->get_global_position()); - b=pi->cast_to<Node2D>(); - if (!b) - break; - - if (first) { - - bone_orig_xform=b->get_global_transform(); - first=false; - } - - BoneIK bik; - bik.node=b; - bik.len=len; - bik.orig_state=b->edit_get_state(); - - bone_ik_list.push_back(bik); - - if (b->has_meta("_edit_ik_")) { - - ik_found=bone_ik_list.size()>1; - break; - } - - if (!pi->has_meta("_edit_bone_")) - break; - - } - - if (!ik_found) - bone_ik_list.clear(); - - } - } - } - - CanvasItem *single_item = get_single_item(); - - if (single_item) { - //try single canvas_item edit - - CanvasItem *canvas_item = single_item; - CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - ERR_FAIL_COND(!se); - - - Point2 click(b.x,b.y); - - if ((b.mod.control && tool==TOOL_SELECT) || tool==TOOL_ROTATE) { - - drag=DRAG_ROTATE; - drag_from=transform.affine_inverse().xform(click); - se->undo_state=canvas_item->edit_get_state(); - if (canvas_item->cast_to<Node2D>()) - se->undo_pivot=canvas_item->cast_to<Node2D>()->edit_get_pivot(); - if (canvas_item->cast_to<Control>()) - se->undo_pivot=Vector2(); - return; - } - - Transform2D xform = transform * canvas_item->get_global_transform_with_canvas(); - Rect2 rect=canvas_item->get_item_rect(); - //float handle_radius = handle_len * 1.4144; //magic number, guess what it means! - - if (tool==TOOL_SELECT) { - drag = _find_drag_type(xform,rect,click,drag_point_from); - - if (b.doubleclick) { - - if (canvas_item->get_filename()!="" && canvas_item!=editor->get_edited_scene()) { - - editor->open_request(canvas_item->get_filename()); - return; - } - } - - if (drag!=DRAG_NONE && (!Cbone || drag!=DRAG_ALL)) { - drag_from=transform.affine_inverse().xform(click); - se->undo_state=canvas_item->edit_get_state(); - if (canvas_item->cast_to<Node2D>()) - se->undo_pivot=canvas_item->cast_to<Node2D>()->edit_get_pivot(); - - return; - } - } else { - - drag=DRAG_NONE; - } - } - - //multi canvas_item edit - - - Point2 click=Point2(b.x,b.y); - - if ((b.mod.alt || tool==TOOL_MOVE) && get_item_count()) { - - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - if (!se) - continue; - - se->undo_state=canvas_item->edit_get_state(); - if (canvas_item->cast_to<Node2D>()) - se->undo_pivot=canvas_item->cast_to<Node2D>()->edit_get_pivot(); - - } - - - drag=DRAG_ALL; - drag_from=transform.affine_inverse().xform(click); - drag_point_from=_find_topleftmost_point(); - viewport->update(); - return; - - } - - Node* scene = editor->get_edited_scene(); - if (!scene) - return; - - /* - if (current_window) { - //no window.... ? - click-=current_window->get_scroll(); - }*/ - CanvasItem *c=NULL; - - if (Cbone) { - - Object* obj=ObjectDB::get_instance(Cbone->get().bone); - if (obj) - c=obj->cast_to<CanvasItem>(); - if (c) - c=c->get_parent_item(); - - - } - if (!c) { - c =_select_canvas_item_at_pos(click, scene,transform,Transform2D()); - - - CanvasItem* cn = c; - - while(cn) { - if (cn->has_meta("_edit_group_")) { - c=cn; - } - cn=cn->get_parent_item(); - } - } - - Node* n = c; - - while ((n && n != scene && n->get_owner() != scene) || (n && !n->is_class("CanvasItem"))) { - n = n->get_parent(); - }; - c = n->cast_to<CanvasItem>(); -#if 0 - if ( b.pressed ) box_selection_start( click ); -#endif - - additive_selection=b.mod.shift; - if (!_select(c, click, additive_selection)) - return; - - } - - if (p_event.type==InputEvent::MOUSE_MOTION) { - - if (!viewport->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) - viewport->call_deferred("grab_focus"); - - const InputEventMouseMotion &m=p_event.mouse_motion; - - if (box_selecting) { - - box_selecting_to=transform.affine_inverse().xform(Point2(m.x,m.y)); - viewport->update(); - return; - - } - - - if (drag==DRAG_NONE) { - - - if ( (m.button_mask&BUTTON_MASK_LEFT && tool == TOOL_PAN) || m.button_mask&BUTTON_MASK_MIDDLE || (m.button_mask&BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE))) { - h_scroll->set_value( h_scroll->get_value() - m.relative_x/zoom); - v_scroll->set_value( v_scroll->get_value() - m.relative_y/zoom); - } - - return; - - } - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - if (!se) - continue; - - bool dragging_bone = drag==DRAG_ALL && selection.size()==1 && bone_ik_list.size(); - - - if (!dragging_bone) { - canvas_item->edit_set_state(se->undo_state); //reset state and reapply - if (canvas_item->cast_to<Node2D>()) - canvas_item->cast_to<Node2D>()->edit_set_pivot(se->undo_pivot); - } - - - Vector2 dfrom = drag_from; - Vector2 dto = transform.affine_inverse().xform(Point2(m.x,m.y)); - if (canvas_item->has_meta("_edit_lock_")) - continue; - - - if (drag==DRAG_ROTATE) { - - Vector2 center = canvas_item->get_global_transform_with_canvas().get_origin(); - { - Node2D *node = canvas_item->cast_to<Node2D>(); - - - if (node) { - real_t angle = node->get_rotation(); - node->set_rotation(snap_angle( angle + (dfrom - center).angle_to(dto-center), angle )); - display_rotate_to = dto; - display_rotate_from = center; - viewport->update(); - } - } - - { - Control *node = canvas_item->cast_to<Control>(); - - - if (node) { - real_t angle = node->get_rotation(); - node->set_rotation(snap_angle( angle + (dfrom - center).angle_to(dto-center), angle )); - display_rotate_to = dto; - display_rotate_from = center; - viewport->update(); - } - } - - continue; - } - - - bool uniform = m.mod.shift; - bool symmetric=m.mod.alt; - - dto = dto - (drag == DRAG_ALL ? drag_from - drag_point_from : Vector2(0, 0)); - - if(uniform && drag == DRAG_ALL) { - if(ABS(dto.x - drag_point_from.x) > ABS(dto.y - drag_point_from.y)) { - dto.y = drag_point_from.y; - } else { - dto.x = drag_point_from.x; - } - } - - dfrom = drag_point_from; - dto = snap_point(dto, drag_point_from); - - Vector2 drag_vector = - canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dto) - - canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dfrom); - - Rect2 local_rect = canvas_item->get_item_rect(); - Vector2 begin=local_rect.pos; - Vector2 end=local_rect.pos+local_rect.size; - Vector2 minsize = canvas_item->edit_get_minimum_size(); - - if (uniform) { - float aspect = local_rect.size.aspect(); - switch(drag) { - case DRAG_BOTTOM_LEFT: - case DRAG_TOP_RIGHT: { - if (aspect > 1.0) { // width > height, take x as reference - drag_vector.y = -drag_vector.x/aspect; - } else { // height > width, take y as reference - drag_vector.x = -drag_vector.y*aspect; - } - } break; - case DRAG_BOTTOM_RIGHT: - case DRAG_TOP_LEFT: { - if (aspect > 1.0) { // width > height, take x as reference - drag_vector.y = drag_vector.x/aspect; - } else { // height > width, take y as reference - drag_vector.x = drag_vector.y*aspect; - } - } break; - default: {} - } - } - - switch(drag) { - case DRAG_ALL: { - begin+=drag_vector; - end+=drag_vector; - } break; - case DRAG_RIGHT: { - - incend(begin.x,end.x,drag_vector.x,minsize.x,symmetric); - - } break; - case DRAG_BOTTOM: { - - incend(begin.y,end.y,drag_vector.y,minsize.y,symmetric); - - } break; - case DRAG_BOTTOM_RIGHT: { - - incend(begin.x,end.x,drag_vector.x,minsize.x,symmetric); - incend(begin.y,end.y,drag_vector.y,minsize.y,symmetric); - } break; - case DRAG_TOP_LEFT: { - - incbeg(begin.x,end.x,drag_vector.x,minsize.x,symmetric); - incbeg(begin.y,end.y,drag_vector.y,minsize.y,symmetric); - } break; - case DRAG_TOP: { - - incbeg(begin.y,end.y,drag_vector.y,minsize.y,symmetric); - - } break; - case DRAG_LEFT: { - - incbeg(begin.x,end.x,drag_vector.x,minsize.x,symmetric); - - } break; - case DRAG_TOP_RIGHT: { - - incbeg(begin.y,end.y,drag_vector.y,minsize.y,symmetric); - incend(begin.x,end.x,drag_vector.x,minsize.x,symmetric); - - } break; - case DRAG_BOTTOM_LEFT: { - - incbeg(begin.x,end.x,drag_vector.x,minsize.x,symmetric); - incend(begin.y,end.y,drag_vector.y,minsize.y,symmetric); - } break; - case DRAG_PIVOT: { - - if (canvas_item->cast_to<Node2D>()) { - Node2D *n2d =canvas_item->cast_to<Node2D>(); - n2d->edit_set_pivot(se->undo_pivot+drag_vector); - - } - continue; - } break; - - default:{} - } - - - - if (!dragging_bone) { - - local_rect.pos=begin; - local_rect.size=end-begin; - canvas_item->edit_set_rect(local_rect); - - } else { - //ok, all that had to be done was done, now solve IK - - - - - Node2D *n2d = canvas_item->cast_to<Node2D>(); - Transform2D final_xform = bone_orig_xform; - - - - if (n2d) { - - float total_len = 0; - for (List<BoneIK>::Element *E=bone_ik_list.front();E;E=E->next()) { - if (E->prev()) - total_len+=E->get().len; - E->get().pos = E->get().node->get_global_transform().get_origin(); - } - - { - - final_xform.elements[2]+=dto-dfrom;//final_xform.affine_inverse().basis_xform_inv(drag_vector); - //n2d->set_global_transform(final_xform); - - } - - - CanvasItem *last = bone_ik_list.back()->get().node; - if (!last) - break; - - Vector2 root_pos = last->get_global_transform().get_origin(); - Vector2 leaf_pos = final_xform.get_origin(); - - if ((leaf_pos.distance_to(root_pos)) > total_len) { - //oops dude you went too far - //print_line("TOO FAR!"); - Vector2 rel = leaf_pos - root_pos; - rel = rel.normalized() * total_len; - leaf_pos=root_pos+rel; - - } - - bone_ik_list.front()->get().pos=leaf_pos; - - //print_line("BONE IK LIST "+itos(bone_ik_list.size())); - - - if (bone_ik_list.size()>2) { - int solver_iterations=64; - float solver_k=0.3; - - for(int i=0;i<solver_iterations;i++) { - - for (List<BoneIK>::Element *E=bone_ik_list.front();E;E=E->next()) { - - - - if (E==bone_ik_list.back()) { - - break; - } - - float len = E->next()->get().len; - - if (E->next()==bone_ik_list.back()) { - - //print_line("back"); - - Vector2 rel = E->get().pos - E->next()->get().pos; - //print_line("PREV "+E->get().pos); - Vector2 desired = E->next()->get().pos+rel.normalized()*len; - //print_line("DESIRED "+desired); - E->get().pos=E->get().pos.linear_interpolate(desired,solver_k); - //print_line("POST "+E->get().pos); - - - } else if (E==bone_ik_list.front()) { - //only adjust parent - //print_line("front"); - Vector2 rel = E->next()->get().pos - E->get().pos; - //print_line("PREV "+E->next()->get().pos); - Vector2 desired = E->get().pos+rel.normalized()*len; - //print_line("DESIRED "+desired); - E->next()->get().pos=E->next()->get().pos.linear_interpolate(desired,solver_k); - //print_line("POST "+E->next()->get().pos); - } else { - - Vector2 rel = E->next()->get().pos - E->get().pos; - Vector2 cen = (E->next()->get().pos + E->get().pos)*0.5; - rel=rel.linear_interpolate(rel.normalized()*len,solver_k); - rel*=0.5; - E->next()->get().pos=cen+rel; - E->get().pos=cen-rel; - //print_line("mid"); - - } - } - } - } - } - - for (List<BoneIK>::Element *E=bone_ik_list.back();E;E=E->prev()) { - - Node2D *n = E->get().node; - - if (!E->prev()) { - //last goes to what it was - final_xform.set_origin(n->get_global_position()); - n->set_global_transform(final_xform); - - } else { - Vector2 rel = (E->prev()->get().node->get_global_position() - n->get_global_position()).normalized(); - Vector2 rel2 = (E->prev()->get().pos - E->get().pos).normalized(); - float rot = rel.angle_to(rel2); - if (n->get_global_transform().basis_determinant()<0) { - //mirrored, rotate the other way - rot=-rot; - } - - n->rotate(rot); - } - - } - - - - break; - } - } - } - - if (p_event.type==InputEvent::KEY) { - - const InputEventKey &k=p_event.key; - - if (k.pressed && drag==DRAG_NONE) { - - KeyMoveMODE move_mode = MOVE_VIEW_BASE; - if (k.mod.alt) move_mode = MOVE_LOCAL_BASE; - if (k.mod.control || k.mod.meta) move_mode = MOVE_LOCAL_WITH_ROT; - - if (k.scancode==KEY_UP) - _key_move( Vector2(0,-1), k.mod.shift, move_mode ); - else if (k.scancode==KEY_DOWN) - _key_move( Vector2(0,1), k.mod.shift, move_mode ); - else if (k.scancode==KEY_LEFT) - _key_move( Vector2(-1,0), k.mod.shift, move_mode ); - else if (k.scancode==KEY_RIGHT) - _key_move( Vector2(1,0), k.mod.shift, move_mode ); - else if (k.scancode==KEY_ESCAPE) { - editor_selection->clear(); - viewport->update(); - } - else - return; - - accept_event(); - } - - } - - - - -} - -void CanvasItemEditor::_viewport_draw() { - - // TODO fetch the viewport? - - Ref<Texture> pivot = get_icon("EditorPivot","EditorIcons"); - _update_scrollbars(); - RID ci=viewport->get_canvas_item(); - - if (snap_show_grid) { - Size2 s = viewport->get_size(); - int last_cell; - Transform2D xform = transform.affine_inverse(); - - if (snap_step.x!=0) { - for(int i=0;i<s.width;i++) { - int cell = Math::fast_ftoi(Math::floor((xform.xform(Vector2(i,0)).x-snap_offset.x)/snap_step.x)); - if (i==0) - last_cell=cell; - if (last_cell!=cell) - viewport->draw_line(Point2(i,0),Point2(i,s.height),Color(0.3,0.7,1,0.3)); - last_cell=cell; - } - } - - if (snap_step.y!=0) { - for(int i=0;i<s.height;i++) { - int cell = Math::fast_ftoi(Math::floor((xform.xform(Vector2(0,i)).y-snap_offset.y)/snap_step.y)); - if (i==0) - last_cell=cell; - if (last_cell!=cell) - viewport->draw_line(Point2(0,i),Point2(s.width,i),Color(0.3,0.7,1,0.3)); - last_cell=cell; - } - } - } - - if (viewport->has_focus()) { - Size2 size = viewport->get_size(); - if (v_scroll->is_visible_in_tree()) - size.width-=v_scroll->get_size().width; - if (h_scroll->is_visible_in_tree()) - size.height-=h_scroll->get_size().height; - - get_stylebox("EditorFocus","EditorStyles")->draw(ci,Rect2(Point2(),size)); - } - - Ref<Texture> lock = get_icon("Lock","EditorIcons"); - Ref<Texture> group = get_icon("Group","EditorIcons"); - - - bool single = get_single_item()!=NULL; - - Map<Node*,Object*> &selection = editor_selection->get_selection(); - - bool pivot_found=false; - - for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { - - - CanvasItem *canvas_item = E->key()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - if (!se) - continue; - - - Rect2 rect=canvas_item->get_item_rect(); - - Transform2D xform=transform * canvas_item->get_global_transform_with_canvas(); - VisualServer::get_singleton()->canvas_item_add_set_transform(ci,xform); - - Vector2 endpoints[4]={ - - xform.xform(rect.pos), - xform.xform(rect.pos+Vector2(rect.size.x,0)), - xform.xform(rect.pos+rect.size), - xform.xform(rect.pos+Vector2(0,rect.size.y)) - }; - - Color c = Color(1,0.6,0.4,0.7); - - VisualServer::get_singleton()->canvas_item_add_set_transform(ci,Transform2D()); - - for(int i=0;i<4;i++) { - viewport->draw_line(endpoints[i],endpoints[(i+1)%4],c,2); - } - - if (single && (tool==TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_ROTATE || tool==TOOL_EDIT_PIVOT)) { //kind of sucks - - if (canvas_item->cast_to<Node2D>()) { - - - if (canvas_item->cast_to<Node2D>()->edit_has_pivot()) { - viewport->draw_texture(pivot,xform.get_origin()+(-pivot->get_size()/2).floor()); - can_move_pivot=true; - pivot_found=true; - } - - } - - - if (tool==TOOL_SELECT) { - - - for(int i=0;i<4;i++) { - - int prev = (i+3)%4; - int next = (i+1)%4; - - Vector2 ofs = ((endpoints[i] - endpoints[prev]).normalized() + ((endpoints[i] - endpoints[next]).normalized())).normalized(); - ofs*=1.4144*(select_handle->get_size().width/2); - - select_handle->draw(ci,(endpoints[i]+ofs-(select_handle->get_size()/2)).floor()); - - ofs = (endpoints[i]+endpoints[next])/2; - ofs += (endpoints[next]-endpoints[i]).tangent().normalized()*(select_handle->get_size().width/2); - - select_handle->draw(ci,(ofs-(select_handle->get_size()/2)).floor()); - - } - - } - } - - - - //DRAW_EMPTY_RECT( Rect2( current_window->get_scroll()-Point2(1,1), get_size()+Size2(2,2)), Color(0.8,0.8,1.0,0.8) ); - //E->get().last_rect = rect; - } - - pivot_button->set_disabled(!pivot_found); - VisualServer::get_singleton()->canvas_item_add_set_transform(ci,Transform2D()); - - - - Color x_axis_color(1.0,0.4,0.4,0.6); - Color y_axis_color(0.4,1.0,0.4,0.6); - Color area_axis_color(0.4,0.4,1.0,0.4); - Color rotate_color(0.4,0.7,1.0,0.8); - - VisualServer::get_singleton()->canvas_item_add_line(ci,Point2(h_scroll->get_min(),0)+transform.get_origin(),Point2(h_scroll->get_max(),0)+transform.get_origin(),x_axis_color); - VisualServer::get_singleton()->canvas_item_add_line(ci,Point2(0,v_scroll->get_min())+transform.get_origin(),Point2(0,v_scroll->get_max())+transform.get_origin(),y_axis_color); - - - if (box_selecting) { - - Point2 bsfrom = transform.xform(drag_from); - Point2 bsto= transform.xform(box_selecting_to); - - - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(bsfrom,bsto-bsfrom),Color(0.7,0.7,1.0,0.3)); - } - - if (drag==DRAG_ROTATE) { - VisualServer::get_singleton()->canvas_item_add_line(ci,transform.xform(display_rotate_from), transform.xform(display_rotate_to),rotate_color); - } - - Size2 screen_size = Size2( GlobalConfig::get_singleton()->get("display/window/width"), GlobalConfig::get_singleton()->get("display/window/height") ); - - Vector2 screen_endpoints[4]= { - transform.xform(Vector2(0,0)), - transform.xform(Vector2(screen_size.width,0)), - transform.xform(Vector2(screen_size.width,screen_size.height)), - transform.xform(Vector2(0,screen_size.height)) - }; - - for(int i=0;i<4;i++) { - - VisualServer::get_singleton()->canvas_item_add_line(ci,screen_endpoints[i], screen_endpoints[(i+1)%4],area_axis_color); - - } - - for(List<LockList>::Element*E=lock_list.front();E;E=E->next()) { - - Vector2 ofs = transform.xform(E->get().pos); - if (E->get().lock) { - - lock->draw(ci,ofs); - ofs.x+=lock->get_width(); - } - if (E->get().group) { - - group->draw(ci,ofs); - } - - } - - { - - EditorNode *en = editor; - EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); - - if (!over_plugin_list->empty()) { - - over_plugin_list->forward_draw_over_canvas(transform,viewport); - - } - } - - if (skeleton_show_bones) { - int bone_width = EditorSettings::get_singleton()->get("editors/2d/bone_width"); - Color bone_color1 = EditorSettings::get_singleton()->get("editors/2d/bone_color1"); - Color bone_color2 = EditorSettings::get_singleton()->get("editors/2d/bone_color2"); - Color bone_ik_color = EditorSettings::get_singleton()->get("editors/2d/bone_ik_color"); - Color bone_selected_color = EditorSettings::get_singleton()->get("editors/2d/bone_selected_color"); - - for(Map<ObjectID,BoneList>::Element*E=bone_list.front();E;E=E->next()) { - - E->get().from=Vector2(); - E->get().to=Vector2(); - - Object *obj = ObjectDB::get_instance(E->get().bone); - if (!obj) - continue; - - Node2D* n2d = obj->cast_to<Node2D>(); - if (!n2d) - continue; - - if (!n2d->get_parent()) - continue; - - CanvasItem *pi = n2d->get_parent_item(); - - - Node2D* pn2d=n2d->get_parent()->cast_to<Node2D>(); - - if (!pn2d) - continue; - - Vector2 from = transform.xform(pn2d->get_global_position()); - Vector2 to = transform.xform(n2d->get_global_position()); - - E->get().from=from; - E->get().to=to; - - Vector2 rel = to-from; - Vector2 relt = rel.tangent().normalized()*bone_width; - - - - Vector<Vector2> bone_shape; - bone_shape.push_back(from); - bone_shape.push_back(from+rel*0.2+relt); - bone_shape.push_back(to); - bone_shape.push_back(from+rel*0.2-relt); - Vector<Color> colors; - if (pi->has_meta("_edit_ik_")) { - - colors.push_back(bone_ik_color); - colors.push_back(bone_ik_color); - colors.push_back(bone_ik_color); - colors.push_back(bone_ik_color); - } else { - colors.push_back(bone_color1); - colors.push_back(bone_color2); - colors.push_back(bone_color1); - colors.push_back(bone_color2); - } - - - VisualServer::get_singleton()->canvas_item_add_primitive(ci,bone_shape,colors,Vector<Vector2>(),RID()); - - if (editor_selection->is_selected(pi)) { - for(int i=0;i<bone_shape.size();i++) { - - VisualServer::get_singleton()->canvas_item_add_line(ci,bone_shape[i],bone_shape[(i+1)%bone_shape.size()],bone_selected_color,2); - } - } - - } - } -} - -void CanvasItemEditor::_notification(int p_what) { - - if (p_what==NOTIFICATION_FIXED_PROCESS) { - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - bool all_control=true; - bool has_control=false; - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - if (canvas_item->cast_to<Control>()) - has_control=true; - else - all_control=false; - - CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - if (!se) - continue; - - Rect2 r=canvas_item->get_item_rect(); - - Transform2D xform = canvas_item->get_transform(); - - if (r != se->prev_rect || xform!=se->prev_xform) { - viewport->update(); - se->prev_rect=r; - se->prev_xform=xform; - } - - } - - bool show_anchor = all_control && has_control; - if (show_anchor != anchor_menu->is_visible()) { - if (show_anchor) - anchor_menu->show(); - else - anchor_menu->hide(); - } - - for(Map<ObjectID,BoneList>::Element *E=bone_list.front();E;E=E->next()) { - - Object *b = ObjectDB::get_instance(E->get().bone); - if (!b) { - - viewport->update(); - break; - } - - Node2D *b2 = b->cast_to<Node2D>(); - if (!b2) { - continue; - } - - if (b2->get_global_transform()!=E->get().xform) { - - E->get().xform=b2->get_global_transform(); - viewport->update(); - } - } - } - - if (p_what==NOTIFICATION_ENTER_TREE) { - - select_sb->set_texture( get_icon("EditorRect2D","EditorIcons") ); - for(int i=0;i<4;i++) { - select_sb->set_margin_size(Margin(i),4); - select_sb->set_default_margin(Margin(i),4); - } - - select_button->set_icon( get_icon("ToolSelect","EditorIcons")); - list_select_button->set_icon( get_icon("ListSelect","EditorIcons")); - move_button->set_icon( get_icon("ToolMove","EditorIcons")); - rotate_button->set_icon( get_icon("ToolRotate","EditorIcons")); - pan_button->set_icon( get_icon("ToolPan", "EditorIcons")); - pivot_button->set_icon( get_icon("EditPivot", "EditorIcons")); - select_handle=get_icon("EditorHandle","EditorIcons"); - lock_button->set_icon(get_icon("Lock","EditorIcons")); - unlock_button->set_icon(get_icon("Unlock","EditorIcons")); - group_button->set_icon(get_icon("Group","EditorIcons")); - ungroup_button->set_icon(get_icon("Ungroup","EditorIcons")); - key_insert_button->set_icon(get_icon("Key","EditorIcons")); - - - //anchor_menu->add_icon_override("Align Top Left"); - anchor_menu->set_icon(get_icon("Anchor","EditorIcons")); - PopupMenu *p=anchor_menu->get_popup(); - - p->add_icon_item(get_icon("ControlAlignTopLeft","EditorIcons"),"Top Left",ANCHOR_ALIGN_TOP_LEFT); - p->add_icon_item(get_icon("ControlAlignTopRight","EditorIcons"),"Top Right",ANCHOR_ALIGN_TOP_RIGHT); - p->add_icon_item(get_icon("ControlAlignBottomRight","EditorIcons"),"Bottom Right",ANCHOR_ALIGN_BOTTOM_RIGHT); - p->add_icon_item(get_icon("ControlAlignBottomLeft","EditorIcons"),"Bottom Left",ANCHOR_ALIGN_BOTTOM_LEFT); - p->add_separator(); - p->add_icon_item(get_icon("ControlAlignLeftCenter","EditorIcons"),"Center Left",ANCHOR_ALIGN_CENTER_LEFT); - p->add_icon_item(get_icon("ControlAlignTopCenter","EditorIcons"),"Center Top",ANCHOR_ALIGN_CENTER_TOP); - p->add_icon_item(get_icon("ControlAlignRightCenter","EditorIcons"),"Center Right",ANCHOR_ALIGN_CENTER_RIGHT); - p->add_icon_item(get_icon("ControlAlignBottomCenter","EditorIcons"),"Center Bottom",ANCHOR_ALIGN_CENTER_BOTTOM); - p->add_icon_item(get_icon("ControlAlignCenter","EditorIcons"),"Center",ANCHOR_ALIGN_CENTER); - p->add_separator(); - p->add_icon_item(get_icon("ControlAlignLeftWide","EditorIcons"),"Left Wide",ANCHOR_ALIGN_LEFT_WIDE); - p->add_icon_item(get_icon("ControlAlignTopWide","EditorIcons"),"Top Wide",ANCHOR_ALIGN_TOP_WIDE); - p->add_icon_item(get_icon("ControlAlignRightWide","EditorIcons"),"Right Wide",ANCHOR_ALIGN_RIGHT_WIDE); - p->add_icon_item(get_icon("ControlAlignBottomWide","EditorIcons"),"Bottom Wide",ANCHOR_ALIGN_BOTTOM_WIDE); - p->add_icon_item(get_icon("ControlVcenterWide","EditorIcons"),"VCenter Wide ",ANCHOR_ALIGN_VCENTER_WIDE); - p->add_icon_item(get_icon("ControlHcenterWide","EditorIcons"),"HCenter Wide ",ANCHOR_ALIGN_HCENTER_WIDE); - p->add_separator(); - p->add_icon_item(get_icon("ControlAlignWide","EditorIcons"),"Full Rect",ANCHOR_ALIGN_WIDE); - - - AnimationPlayerEditor::singleton->get_key_editor()->connect("visibility_changed",this,"_keying_changed"); - _keying_changed(); - } - - if (p_what==NOTIFICATION_READY) { - - get_tree()->connect("node_removed",this,"_node_removed"); - } - - if (p_what==NOTIFICATION_DRAW) { - - - - } -} - -void CanvasItemEditor::edit(CanvasItem *p_canvas_item) { - - drag=DRAG_NONE; - - editor_selection->clear();//_clear_canvas_items(); - editor_selection->add_node(p_canvas_item); - //_add_canvas_item(p_canvas_item); - viewport->update(); - -} - - -void CanvasItemEditor::_find_canvas_items_span(Node *p_node, Rect2& r_rect, const Transform2D& p_xform) { - - - - if (!p_node) - return; - - CanvasItem *c=p_node->cast_to<CanvasItem>(); - - - for (int i=p_node->get_child_count()-1;i>=0;i--) { - - //CanvasItem *r=NULL; - - if (c && !c->is_set_as_toplevel()) - _find_canvas_items_span(p_node->get_child(i),r_rect,p_xform * c->get_transform()); - else - _find_canvas_items_span(p_node->get_child(i),r_rect,Transform2D()); - } - - - - if (c && c->is_visible_in_tree()) { - - Rect2 rect = c->get_item_rect(); - Transform2D xform = p_xform * c->get_transform(); - - - LockList lock; - lock.lock=c->has_meta("_edit_lock_"); - lock.group=c->has_meta("_edit_group_"); - - if (lock.group || lock.lock) { - lock.pos=xform.xform(rect.pos); - lock_list.push_back(lock); - } - - if (c->has_meta("_edit_bone_")) { - - ObjectID id = c->get_instance_ID(); - if (!bone_list.has(id)) { - BoneList bone; - bone.bone=id; - bone_list[id]=bone; - } - - bone_list[id].last_pass=bone_last_frame; - } - - r_rect.expand_to( xform.xform(rect.pos) ); - r_rect.expand_to( xform.xform(rect.pos+Point2(rect.size.x,0)) ); - r_rect.expand_to( xform.xform(rect.pos+Point2(0,rect.size.y)) ); - r_rect.expand_to( xform.xform(rect.pos+rect.size) ); - - } - -} - -void CanvasItemEditor::_update_scrollbars() { - - - updating_scroll=true; - - Size2 size = viewport->get_size(); - Size2 hmin = h_scroll->get_minimum_size(); - Size2 vmin = v_scroll->get_minimum_size(); - - v_scroll->set_begin( Point2(size.width - vmin.width, 0) ); - v_scroll->set_end( Point2(size.width, size.height) ); - - h_scroll->set_begin( Point2( 0, size.height - hmin.height) ); - h_scroll->set_end( Point2(size.width-vmin.width, size.height) ); - - - Size2 screen_rect = Size2( GlobalConfig::get_singleton()->get("display/window/width"), GlobalConfig::get_singleton()->get("display/window/height") ); - - - Rect2 local_rect = Rect2(Point2(),viewport->get_size()-Size2(vmin.width,hmin.height)); - - Rect2 canvas_item_rect=Rect2(Point2(),screen_rect); - - lock_list.clear(); - bone_last_frame++; - - - - if (editor->get_edited_scene()) - _find_canvas_items_span(editor->get_edited_scene(),canvas_item_rect,Transform2D()); - - List<Map<ObjectID,BoneList>::Element*> bone_to_erase; - - for(Map<ObjectID,BoneList>::Element*E=bone_list.front();E;E=E->next()) { - - if (E->get().last_pass!=bone_last_frame) { - bone_to_erase.push_back(E); - } - } - - while(bone_to_erase.size()) { - bone_list.erase(bone_to_erase.front()->get()); - bone_to_erase.pop_front(); - } - - //expand area so it's easier to do animations and stuff at 0,0 - canvas_item_rect.size+=screen_rect*2; - canvas_item_rect.pos-=screen_rect; - - Point2 ofs; - - - if (canvas_item_rect.size.height <= (local_rect.size.y/zoom)) { - - v_scroll->hide(); - ofs.y=canvas_item_rect.pos.y; - } else { - - v_scroll->show(); - v_scroll->set_min(canvas_item_rect.pos.y); - v_scroll->set_max(canvas_item_rect.pos.y+canvas_item_rect.size.y); - v_scroll->set_page(local_rect.size.y/zoom); - if (first_update) { - //so 0,0 is visible - v_scroll->set_value(-10); - h_scroll->set_value(-10); - first_update=false; - - } - - ofs.y=v_scroll->get_value(); - } - - if (canvas_item_rect.size.width <= (local_rect.size.x/zoom)) { - - h_scroll->hide(); - ofs.x=canvas_item_rect.pos.x; - } else { - - h_scroll->show(); - h_scroll->set_min(canvas_item_rect.pos.x); - h_scroll->set_max(canvas_item_rect.pos.x+canvas_item_rect.size.x); - h_scroll->set_page(local_rect.size.x/zoom); - ofs.x=h_scroll->get_value(); - } - - //transform=Matrix32(); - transform.elements[2]=-ofs*zoom; - - editor->get_scene_root()->set_global_canvas_transform(transform); - - - updating_scroll=false; - - //transform.scale_basis(Vector2(zoom,zoom)); - - -} - -void CanvasItemEditor::_update_scroll(float) { - - - if (updating_scroll) - return; - - Point2 ofs; - ofs.x=h_scroll->get_value(); - ofs.y=v_scroll->get_value(); - - //current_window->set_scroll(-ofs); - - transform=Transform2D(); - - transform.scale_basis(Size2(zoom,zoom)); - transform.elements[2]=-ofs; - - editor->get_scene_root()->set_global_canvas_transform(transform); - - - viewport->update(); - -} - -void CanvasItemEditor::_set_anchor(Control::AnchorType p_left,Control::AnchorType p_top,Control::AnchorType p_right,Control::AnchorType p_bottom) { - List<Node*> &selection = editor_selection->get_selected_node_list(); - - undo_redo->create_action(TTR("Change Anchors")); - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - Control *c = E->get()->cast_to<Control>(); - - undo_redo->add_do_method(c,"set_anchor",MARGIN_LEFT,p_left); - undo_redo->add_do_method(c,"set_anchor",MARGIN_TOP,p_top); - undo_redo->add_do_method(c,"set_anchor",MARGIN_RIGHT,p_right); - undo_redo->add_do_method(c,"set_anchor",MARGIN_BOTTOM,p_bottom); - undo_redo->add_undo_method(c,"set_anchor",MARGIN_LEFT,c->get_anchor(MARGIN_LEFT)); - undo_redo->add_undo_method(c,"set_anchor",MARGIN_TOP,c->get_anchor(MARGIN_TOP)); - undo_redo->add_undo_method(c,"set_anchor",MARGIN_RIGHT,c->get_anchor(MARGIN_RIGHT)); - undo_redo->add_undo_method(c,"set_anchor",MARGIN_BOTTOM,c->get_anchor(MARGIN_BOTTOM)); - } - - undo_redo->commit_action(); - -} - -void CanvasItemEditor::_popup_callback(int p_op) { - - last_option=MenuOption(p_op); - switch(p_op) { - - case SNAP_USE: { - snap_grid = !snap_grid; - int idx = edit_menu->get_popup()->get_item_index(SNAP_USE); - edit_menu->get_popup()->set_item_checked(idx,snap_grid); - } break; - case SNAP_SHOW_GRID: { - snap_show_grid = !snap_show_grid; - int idx = edit_menu->get_popup()->get_item_index(SNAP_SHOW_GRID); - edit_menu->get_popup()->set_item_checked(idx,snap_show_grid); - viewport->update(); - } break; - case SNAP_USE_ROTATION: { - snap_rotation = !snap_rotation; - int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_ROTATION); - edit_menu->get_popup()->set_item_checked(idx,snap_rotation); - } break; - case SNAP_RELATIVE: { - snap_relative = !snap_relative; - int idx = edit_menu->get_popup()->get_item_index(SNAP_RELATIVE); - edit_menu->get_popup()->set_item_checked(idx,snap_relative); - } break; - case SNAP_USE_PIXEL: { - snap_pixel = !snap_pixel; - int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_PIXEL); - edit_menu->get_popup()->set_item_checked(idx,snap_pixel); - } break; - case SNAP_CONFIGURE: { - ((SnapDialog *)snap_dialog)->set_fields(snap_offset, snap_step, snap_rotation_offset, snap_rotation_step); - snap_dialog->popup_centered(Size2(220,160)); - } break; - case SKELETON_SHOW_BONES: { - skeleton_show_bones = !skeleton_show_bones; - int idx = skeleton_menu->get_item_index(SKELETON_SHOW_BONES); - skeleton_menu->set_item_checked(idx,skeleton_show_bones); - viewport->update(); - } break; - case ZOOM_IN: { - if (zoom>MAX_ZOOM) - return; - zoom=zoom*(1.0/0.5); - _update_scroll(0); - viewport->update(); - return; - } break; - case ZOOM_OUT: { - if (zoom<MIN_ZOOM) - return; - - zoom=zoom*0.5; - _update_scroll(0); - viewport->update(); - return; - - } break; - case ZOOM_RESET: { - - zoom=1; - _update_scroll(0); - viewport->update(); - return; - - } break; - case ZOOM_SET: { - - updating_value_dialog=true; - - dialog_label->set_text(TTR("Zoom (%):")); - dialog_val->set_min(0.1); - dialog_val->set_step(0.1); - dialog_val->set_max(800); - dialog_val->set_value(zoom*100); - value_dialog->popup_centered(Size2(200,85)); - updating_value_dialog=false; - - - } break; - case LOCK_SELECTED: { - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - canvas_item->set_meta("_edit_lock_",true); - emit_signal("item_lock_status_changed"); - } - viewport->update(); - } break; - case UNLOCK_SELECTED: { - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - - canvas_item->set_meta("_edit_lock_",Variant()); - emit_signal("item_lock_status_changed"); - } - - viewport->update(); - - } break; - case GROUP_SELECTED: { - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - canvas_item->set_meta("_edit_group_",true); - emit_signal("item_group_status_changed"); - } - viewport->update(); - } break; - case UNGROUP_SELECTED: { - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - canvas_item->set_meta("_edit_group_",Variant()); - emit_signal("item_group_status_changed"); - } - - viewport->update(); - - } break; - - case EXPAND_TO_PARENT: { - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - - Control *c = canvas_item->cast_to<Control>(); - if (!c) - continue; - c->set_area_as_parent_rect(); - - } - - viewport->update(); - - } break; - - case ALIGN_VERTICAL: { -#if 0 - if ( ref_item && canvas_items.size() > 1 ) { - Vector2 ref_pos = ref_item->get_global_transform().elements[2]; - Rect2 ref_r = ref_item->get_item_rect(); - for ( CanvasItemMap::Element *E = canvas_items.front(); E; E = E->next() ) { - CanvasItem *it_curr = E->key(); - if ( it_curr == ref_item ) continue; - Vector2 v = it_curr->get_global_transform().elements[2]; - Rect2 r = it_curr->get_item_rect(); - r.pos.x = ( ref_pos.x + ref_r.size.x / 2 ) - ( v.x + r.size.x / 2 ); - it_curr->edit_set_rect( r ); - } - viewport->update(); - } -#endif - } break; - - case ALIGN_HORIZONTAL: { -#if 0 - if ( ref_item && canvas_items.size() > 1 ) { - Vector2 ref_pos = ref_item->get_global_transform().elements[2]; - Rect2 ref_r = ref_item->get_item_rect(); - for ( CanvasItemMap::Element *E = canvas_items.front(); E; E = E->next() ) { - CanvasItem *it_curr = E->key(); - if ( it_curr == ref_item ) continue; - Vector2 v = it_curr->get_global_transform().elements[2]; - Rect2 r = it_curr->get_item_rect(); - r.pos.y = ( ref_pos.y + ref_r.size.y / 2 ) - ( v.y + r.size.y / 2 ); - it_curr->edit_set_rect( r ); - } - viewport->update(); - } -#endif - } break; - - case SPACE_HORIZONTAL: { - //space_selected_items< proj_vector2_x, compare_items_x >(); - } break; - - case SPACE_VERTICAL: { - //space_selected_items< proj_vector2_y, compare_items_y >(); - } break; - case ANCHOR_ALIGN_TOP_LEFT: { - _set_anchor(ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_BEGIN); - } break; - case ANCHOR_ALIGN_TOP_RIGHT: { - _set_anchor(ANCHOR_END,ANCHOR_BEGIN,ANCHOR_END,ANCHOR_BEGIN); - } break; - case ANCHOR_ALIGN_BOTTOM_LEFT: { - _set_anchor(ANCHOR_BEGIN,ANCHOR_END,ANCHOR_BEGIN,ANCHOR_END); - } break; - case ANCHOR_ALIGN_BOTTOM_RIGHT: { - _set_anchor(ANCHOR_END,ANCHOR_END,ANCHOR_END,ANCHOR_END); - } break; - case ANCHOR_ALIGN_CENTER_LEFT: { - _set_anchor(ANCHOR_BEGIN,ANCHOR_CENTER,ANCHOR_BEGIN,ANCHOR_CENTER); - } break; - case ANCHOR_ALIGN_CENTER_RIGHT: { - - _set_anchor(ANCHOR_END,ANCHOR_CENTER,ANCHOR_END,ANCHOR_CENTER); - } break; - case ANCHOR_ALIGN_CENTER_TOP: { - _set_anchor(ANCHOR_CENTER,ANCHOR_BEGIN,ANCHOR_CENTER,ANCHOR_BEGIN); - } break; - case ANCHOR_ALIGN_CENTER_BOTTOM: { - _set_anchor(ANCHOR_CENTER,ANCHOR_END,ANCHOR_CENTER,ANCHOR_END); - } break; - case ANCHOR_ALIGN_CENTER: { - _set_anchor(ANCHOR_CENTER,ANCHOR_CENTER,ANCHOR_CENTER,ANCHOR_CENTER); - } break; - case ANCHOR_ALIGN_TOP_WIDE: { - _set_anchor(ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_END,ANCHOR_BEGIN); - } break; - case ANCHOR_ALIGN_LEFT_WIDE: { - _set_anchor(ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_END); - } break; - case ANCHOR_ALIGN_RIGHT_WIDE: { - _set_anchor(ANCHOR_END,ANCHOR_BEGIN,ANCHOR_END,ANCHOR_END); - } break; - case ANCHOR_ALIGN_BOTTOM_WIDE: { - _set_anchor(ANCHOR_BEGIN,ANCHOR_END,ANCHOR_END,ANCHOR_END); - } break; - case ANCHOR_ALIGN_VCENTER_WIDE: { - _set_anchor(ANCHOR_CENTER,ANCHOR_BEGIN,ANCHOR_CENTER,ANCHOR_END); - } break; - case ANCHOR_ALIGN_HCENTER_WIDE: { - _set_anchor(ANCHOR_BEGIN,ANCHOR_CENTER,ANCHOR_END,ANCHOR_CENTER); - } break; - case ANCHOR_ALIGN_WIDE: { - _set_anchor(ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_END,ANCHOR_END); - } break; - - case ANIM_INSERT_KEY: - case ANIM_INSERT_KEY_EXISTING: { - - bool existing = p_op==ANIM_INSERT_KEY_EXISTING; - - Map<Node*,Object*> &selection = editor_selection->get_selection(); - - for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->key()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - if (canvas_item->cast_to<Node2D>()) { - Node2D *n2d = canvas_item->cast_to<Node2D>(); - - if (key_pos) - AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(n2d,"transform/pos",n2d->get_position(),existing); - if (key_rot) - AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(n2d,"transform/rot",Math::rad2deg(n2d->get_rotation()),existing); - if (key_scale) - AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(n2d,"transform/scale",n2d->get_scale(),existing); - - - if (n2d->has_meta("_edit_bone_") && n2d->get_parent_item()) { - //look for an IK chain - List<Node2D*> ik_chain; - - Node2D *n = n2d->get_parent_item()->cast_to<Node2D>(); - bool has_chain=false; - - while(n) { - - ik_chain.push_back(n); - if (n->has_meta("_edit_ik_")) { - has_chain=true; - break; - } - - if (!n->get_parent_item()) - break; - n=n->get_parent_item()->cast_to<Node2D>(); - } - - if (has_chain && ik_chain.size()) { - - for(List<Node2D*>::Element *F=ik_chain.front();F;F=F->next()) { - - if (key_pos) - AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(F->get(),"transform/pos",F->get()->get_position(),existing); - if (key_rot) - AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(F->get(),"transform/rot",Math::rad2deg(F->get()->get_rotation()),existing); - if (key_scale) - AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(F->get(),"transform/scale",F->get()->get_scale(),existing); - - - } - } - } - - } else if (canvas_item->cast_to<Control>()) { - - Control *ctrl = canvas_item->cast_to<Control>(); - - if (key_pos) - AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(ctrl,"rect/pos",ctrl->get_pos(),existing); - if (key_scale) - AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(ctrl,"rect/size",ctrl->get_size(),existing); - } - - } - - } break; - case ANIM_INSERT_POS: { - - key_pos = key_loc_button->is_pressed(); - } break; - case ANIM_INSERT_ROT: { - - key_rot = key_rot_button->is_pressed(); - } break; - case ANIM_INSERT_SCALE: { - - key_scale = key_scale_button->is_pressed(); - } break; - /* - case ANIM_INSERT_POS_ROT - case ANIM_INSERT_POS_SCALE: - case ANIM_INSERT_ROT_SCALE: - case ANIM_INSERT_POS_ROT_SCALE: { - - static const bool key_toggles[7][3]={ - {true,false,false}, - {false,true,false}, - {false,false,true}, - {true,true,false}, - {true,false,true}, - {false,true,true}, - {true,true,true} - }; - key_pos=key_toggles[p_op-ANIM_INSERT_POS][0]; - key_rot=key_toggles[p_op-ANIM_INSERT_POS][1]; - key_scale=key_toggles[p_op-ANIM_INSERT_POS][2]; - - for(int i=ANIM_INSERT_POS;i<=ANIM_INSERT_POS_ROT_SCALE;i++) { - int idx = animation_menu->get_popup()->get_item_index(i); - animation_menu->get_popup()->set_item_checked(idx,i==p_op); - } - - } break;*/ - case ANIM_COPY_POSE: { - - pose_clipboard.clear(); - - - Map<Node*,Object*> &selection = editor_selection->get_selection(); - - for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->key()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - - if (canvas_item->cast_to<Node2D>()) { - - Node2D *n2d = canvas_item->cast_to<Node2D>(); - PoseClipboard pc; - pc.pos=n2d->get_position(); - pc.rot=n2d->get_rotation(); - pc.scale=n2d->get_scale(); - pc.id=n2d->get_instance_ID(); - pose_clipboard.push_back(pc); - } - } - - - } break; - case ANIM_PASTE_POSE: { - - if (!pose_clipboard.size()) - break; - - undo_redo->create_action(TTR("Paste Pose")); - for (List<PoseClipboard>::Element *E=pose_clipboard.front();E;E=E->next()) { - - Object *o = ObjectDB::get_instance(E->get().id); - if (!o) - continue; - Node2D *n2d = o->cast_to<Node2D>(); - if (!n2d) - continue; - undo_redo->add_do_method(n2d,"set_pos",E->get().pos); - undo_redo->add_do_method(n2d,"set_rot",E->get().rot); - undo_redo->add_do_method(n2d,"set_scale",E->get().scale); - undo_redo->add_undo_method(n2d,"set_pos",n2d->get_position()); - undo_redo->add_undo_method(n2d,"set_rot",n2d->get_rotation()); - undo_redo->add_undo_method(n2d,"set_scale",n2d->get_scale()); - } - undo_redo->commit_action(); - - } break; - case ANIM_CLEAR_POSE: { - - Map<Node*,Object*> &selection = editor_selection->get_selection(); - - for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->key()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - if (canvas_item->cast_to<Node2D>()) { - Node2D *n2d = canvas_item->cast_to<Node2D>(); - - if (key_pos) - n2d->set_position(Vector2()); - if (key_rot) - n2d->set_rotation(0); - if (key_scale) - n2d->set_scale(Vector2(1,1)); - } else if (canvas_item->cast_to<Control>()) { - - Control *ctrl = canvas_item->cast_to<Control>(); - - if (key_pos) - ctrl->set_pos(Point2()); - /* - if (key_scale) - AnimationPlayerEditor::singleton->get_key_editor()->insert_node_value_key(ctrl,"rect/size",ctrl->get_size()); - */ - } - - } - - - } break; - case VIEW_CENTER_TO_SELECTION: - case VIEW_FRAME_TO_SELECTION: { - - _focus_selection(p_op); - - } break; - case SKELETON_MAKE_BONES: { - - - - Map<Node*,Object*> &selection = editor_selection->get_selection(); - - for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { - - Node2D *n2d = E->key()->cast_to<Node2D>(); - if (!n2d) - continue; - if (!n2d->is_visible_in_tree()) - continue; - if (!n2d->get_parent_item()) - continue; - - n2d->set_meta("_edit_bone_",true); - if (!skeleton_show_bones) - skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES)); - - } - viewport->update(); - - } break; - case SKELETON_CLEAR_BONES: { - - Map<Node*,Object*> &selection = editor_selection->get_selection(); - - for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { - - Node2D *n2d = E->key()->cast_to<Node2D>(); - if (!n2d) - continue; - if (!n2d->is_visible_in_tree()) - continue; - - n2d->set_meta("_edit_bone_",Variant()); - if (!skeleton_show_bones) - skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES)); - - } - viewport->update(); - - } break; - case SKELETON_SET_IK_CHAIN: { - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>(); - if (!canvas_item || !canvas_item->is_visible_in_tree()) - continue; - - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - canvas_item->set_meta("_edit_ik_",true); - if (!skeleton_show_bones) - skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES)); - - } - - viewport->update(); - - } break; - case SKELETON_CLEAR_IK_CHAIN: { - - Map<Node*,Object*> &selection = editor_selection->get_selection(); - - for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { - - CanvasItem *n2d = E->key()->cast_to<CanvasItem>(); - if (!n2d) - continue; - if (!n2d->is_visible_in_tree()) - continue; - - n2d->set_meta("_edit_ik_",Variant()); - if (!skeleton_show_bones) - skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES)); - - } - viewport->update(); - - } break; - - } -} -#if 0 -template< class P, class C > void CanvasItemEditor::space_selected_items() { - P p; - if ( canvas_items.size() > 2 ) { - Vector< CanvasItem * > items; - for ( CanvasItemMap::Element *E = canvas_items.front(); E; E = E->next() ) { - CanvasItem *it_curr = E->key(); - items.push_back( it_curr ); - } - items.sort_custom< C >(); - - float width_s = p.get( items[0]->get_item_rect().size ); - float width_e = p.get( items[ items.size() - 1 ]->get_item_rect().size ); - float start_x = p.get( items[0]->get_global_transform().elements[2] ) + ( width_s / 2 ); - float end_x = p.get( items[ items.size() - 1 ]->get_global_transform().elements[2] ) + ( width_e / 2 ); - float sp = ( end_x - start_x ) / ( items.size() - 1 ); - - for ( int i = 0; i < items.size(); i++ ) { - CanvasItem *it_curr = items[i]; - Vector2 v = it_curr->get_global_transform().elements[2]; - Rect2 r = it_curr->get_item_rect(); - p.set( r.pos, ( start_x + sp * i ) - ( p.get( v ) + p.get( r.size ) / 2 ) ); - it_curr->edit_set_rect( r ); - } - viewport->update(); - } -} -#endif - - -void CanvasItemEditor::_focus_selection(int p_op) { - Vector2 center(0.f, 0.f); - Rect2 rect; - int count = 0; - - Map<Node*,Object*> &selection = editor_selection->get_selection(); - for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { - CanvasItem *canvas_item = E->key()->cast_to<CanvasItem>(); - if (!canvas_item) continue; - if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root()) - continue; - - - // counting invisible items, for now - //if (!canvas_item->is_visible_in_tree()) continue; - ++count; - - Rect2 item_rect = canvas_item->get_item_rect(); - - Vector2 pos = canvas_item->get_global_transform().get_origin(); - Vector2 scale = canvas_item->get_global_transform().get_scale(); - real_t angle = canvas_item->get_global_transform().get_rotation(); - - Transform2D t(angle, Vector2(0.f,0.f)); - item_rect = t.xform(item_rect); - Rect2 canvas_item_rect(pos + scale*item_rect.pos, scale*item_rect.size); - if (count == 1) { - rect = canvas_item_rect; - } else { - rect = rect.merge(canvas_item_rect); - } - }; - if (count==0) return; - - if (p_op == VIEW_CENTER_TO_SELECTION) { - - center = rect.pos + rect.size/2; - Vector2 offset = viewport->get_size()/2 - editor->get_scene_root()->get_global_canvas_transform().xform(center); - h_scroll->set_value(h_scroll->get_value() - offset.x/zoom); - v_scroll->set_value(v_scroll->get_value() - offset.y/zoom); - - } else { // VIEW_FRAME_TO_SELECTION - - if (rect.size.x > CMP_EPSILON && rect.size.y > CMP_EPSILON) { - float scale_x = viewport->get_size().x/rect.size.x; - float scale_y = viewport->get_size().y/rect.size.y; - zoom = scale_x < scale_y? scale_x:scale_y; - zoom *= 0.90; - _update_scroll(0); - call_deferred("_popup_callback", VIEW_CENTER_TO_SELECTION); - } - } -} - - -void CanvasItemEditor::_bind_methods() { - - ClassDB::bind_method("_node_removed",&CanvasItemEditor::_node_removed); - ClassDB::bind_method("_update_scroll",&CanvasItemEditor::_update_scroll); - ClassDB::bind_method("_popup_callback",&CanvasItemEditor::_popup_callback); - ClassDB::bind_method("_visibility_changed",&CanvasItemEditor::_visibility_changed); - ClassDB::bind_method("_dialog_value_changed",&CanvasItemEditor::_dialog_value_changed); - ClassDB::bind_method("_get_editor_data",&CanvasItemEditor::_get_editor_data); - ClassDB::bind_method("_tool_select",&CanvasItemEditor::_tool_select); - ClassDB::bind_method("_keying_changed",&CanvasItemEditor::_keying_changed); - ClassDB::bind_method("_unhandled_key_input",&CanvasItemEditor::_unhandled_key_input); - ClassDB::bind_method("_viewport_draw",&CanvasItemEditor::_viewport_draw); - ClassDB::bind_method("_viewport_gui_input",&CanvasItemEditor::_viewport_gui_input); - ClassDB::bind_method("_snap_changed",&CanvasItemEditor::_snap_changed); - ClassDB::bind_method(D_METHOD("_selection_result_pressed"),&CanvasItemEditor::_selection_result_pressed); - ClassDB::bind_method(D_METHOD("_selection_menu_hide"),&CanvasItemEditor::_selection_menu_hide); - - ADD_SIGNAL( MethodInfo("item_lock_status_changed") ); - ADD_SIGNAL( MethodInfo("item_group_status_changed") ); - -} - -#if 0 -void CanvasItemEditor::end_drag() { - print_line( "end drag" ); - - if (undo_redo) { - - undo_redo->create_action("Edit CanvasItem"); - for(CanvasItemMap::Element *E=canvas_items.front();E;E=E->next()) { - CanvasItem *canvas_item = E->key(); - Variant state=canvas_item->edit_get_state(); - undo_redo->add_do_method(canvas_item,"edit_set_state",state); - undo_redo->add_undo_method(canvas_item,"edit_set_state",E->get().undo_state); - } - undo_redo->commit_action(); - } - - drag=DRAG_NONE; - viewport->update(); -} - -void CanvasItemEditor::box_selection_start( Point2 &click ) { - print_line( "box selection start" ); - - drag_from=transform.affine_inverse().xform(click); - - box_selecting=true; - box_selecting_to=drag_from; - viewport->update(); -} - -bool CanvasItemEditor::box_selection_end() { - print_line( "box selection end" ); - - Node* scene = get_scene()->get_root_node()->cast_to<EditorNode>()->get_edited_scene(); - if (scene) { - - List<CanvasItem*> selitems; - - Point2 bsfrom = transform.xform(drag_from); - Point2 bsto= transform.xform(box_selecting_to); - if (bsfrom.x>bsto.x) - SWAP(bsfrom.x,bsto.x); - if (bsfrom.y>bsto.y) - SWAP(bsfrom.y,bsto.y); - - if ( bsfrom.distance_to( bsto ) < 3 ) { - print_line( "box selection too small" ); - box_selecting=false; - viewport->update(); - return false; - } - - _find_canvas_items_at_rect(Rect2(bsfrom,bsto-bsfrom),scene,transform,&selitems); - - for(List<CanvasItem*>::Element *E=selitems.front();E;E=E->next()) { - - _append_canvas_item(E->get()); - } - - } - - box_selecting=false; - viewport->update(); - - return true; -} -#endif - -void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) { - - hb->add_child(p_control); -} - -HSplitContainer *CanvasItemEditor::get_palette_split() { - - return palette_split; -} - -VSplitContainer *CanvasItemEditor::get_bottom_split() { - - return bottom_split; -} - - -void CanvasItemEditor::focus_selection() { - _focus_selection(VIEW_CENTER_TO_SELECTION); -} - - -CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { - - tool = TOOL_SELECT; - undo_redo=p_editor->get_undo_redo(); - editor=p_editor; - editor_selection=p_editor->get_editor_selection(); - editor_selection->add_editor_plugin(this); - editor_selection->connect("selection_changed",this,"update"); - - - hb = memnew( HBoxContainer ); - add_child( hb ); - hb->set_area_as_parent_rect(); - - bottom_split = memnew( VSplitContainer ); - bottom_split->set_v_size_flags(SIZE_EXPAND_FILL); - add_child(bottom_split); - - palette_split = memnew( HSplitContainer); - palette_split->set_v_size_flags(SIZE_EXPAND_FILL); - bottom_split->add_child(palette_split); - - Control *vp_base = memnew (Control); - vp_base->set_v_size_flags(SIZE_EXPAND_FILL); - palette_split->add_child(vp_base); - - ViewportContainer *vp = memnew (ViewportContainer); - vp->set_stretch(true); - vp_base->add_child(vp); - vp->set_area_as_parent_rect(); - vp->add_child(p_editor->get_scene_root()); - - - viewport = memnew( CanvasItemEditorViewport(p_editor, this) ); - vp_base->add_child(viewport); - viewport->set_area_as_parent_rect(); - viewport->set_clip_contents(true); - - h_scroll = memnew( HScrollBar ); - v_scroll = memnew( VScrollBar ); - - viewport->add_child(h_scroll); - viewport->add_child(v_scroll); - viewport->connect("draw",this,"_viewport_draw"); - viewport->connect("gui_input",this,"_viewport_gui_input"); - - - h_scroll->connect("value_changed", this,"_update_scroll",Vector<Variant>(),Object::CONNECT_DEFERRED); - v_scroll->connect("value_changed", this,"_update_scroll",Vector<Variant>(),Object::CONNECT_DEFERRED); - - h_scroll->hide(); - v_scroll->hide(); - updating_scroll=false; - viewport->set_focus_mode(FOCUS_ALL); - handle_len=10; - first_update=true; - - - select_button = memnew( ToolButton ); - select_button->set_toggle_mode(true); - hb->add_child(select_button); - select_button->connect("pressed",this,"_tool_select",make_binds(TOOL_SELECT)); - select_button->set_pressed(true); - select_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/select_mode",TTR("Select Mode"),KEY_Q)); - select_button->set_tooltip(TTR("Select Mode")+" $sc\n"+keycode_get_string(KEY_MASK_CMD)+TTR("Drag: Rotate")+"\n"+TTR("Alt+Drag: Move")+"\n"+TTR("Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving).")+"\n"+TTR("Alt+RMB: Depth list selection")); - - - move_button = memnew( ToolButton ); - move_button->set_toggle_mode(true); - hb->add_child(move_button); - move_button->connect("pressed",this,"_tool_select",make_binds(TOOL_MOVE)); - move_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/move_mode",TTR("Move Mode"),KEY_W)); - move_button->set_tooltip(TTR("Move Mode")); - - rotate_button = memnew( ToolButton ); - rotate_button->set_toggle_mode(true); - hb->add_child(rotate_button); - rotate_button->connect("pressed",this,"_tool_select",make_binds(TOOL_ROTATE)); - rotate_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/rotate_mode",TTR("Rotate Mode"),KEY_E)); - rotate_button->set_tooltip(TTR("Rotate Mode")); - - hb->add_child(memnew(VSeparator)); - - list_select_button = memnew( ToolButton ); - list_select_button->set_toggle_mode(true); - hb->add_child(list_select_button); - list_select_button->connect("pressed",this,"_tool_select",make_binds(TOOL_LIST_SELECT)); - list_select_button->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode).")); - - pivot_button = memnew( ToolButton ); - pivot_button->set_toggle_mode(true); - hb->add_child(pivot_button); - pivot_button->connect("pressed",this,"_tool_select",make_binds(TOOL_EDIT_PIVOT)); - pivot_button->set_tooltip(TTR("Click to change object's rotation pivot.")); - - pan_button = memnew( ToolButton ); - pan_button->set_toggle_mode(true); - hb->add_child(pan_button); - pan_button->connect("pressed",this,"_tool_select",make_binds(TOOL_PAN)); - pan_button->set_tooltip(TTR("Pan Mode")); - - hb->add_child(memnew(VSeparator)); - - lock_button = memnew( ToolButton ); - hb->add_child(lock_button); - - lock_button->connect("pressed",this,"_popup_callback",varray(LOCK_SELECTED)); - lock_button->set_tooltip(TTR("Lock the selected object in place (can't be moved).")); - - unlock_button = memnew( ToolButton ); - hb->add_child(unlock_button); - unlock_button->connect("pressed",this,"_popup_callback",varray(UNLOCK_SELECTED)); - unlock_button->set_tooltip(TTR("Unlock the selected object (can be moved).")); - - group_button = memnew( ToolButton ); - hb->add_child(group_button); - group_button->connect("pressed",this,"_popup_callback",varray(GROUP_SELECTED)); - group_button->set_tooltip(TTR("Makes sure the object's children are not selectable.")); - - ungroup_button = memnew( ToolButton ); - hb->add_child(ungroup_button); - ungroup_button->connect("pressed",this,"_popup_callback",varray(UNGROUP_SELECTED)); - ungroup_button->set_tooltip(TTR("Restores the object's children's ability to be selected.")); - - hb->add_child(memnew(VSeparator)); - - edit_menu = memnew( MenuButton ); - edit_menu->set_text(TTR("Edit")); - hb->add_child(edit_menu); - edit_menu->get_popup()->connect("id_pressed", this,"_popup_callback"); - - PopupMenu *p; - p = edit_menu->get_popup(); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_snap", TTR("Use Snap")), SNAP_USE); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_grid", TTR("Show Grid")), SNAP_SHOW_GRID); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_relative", TTR("Snap Relative")), SNAP_RELATIVE); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/configure_snap", TTR("Configure Snap..")), SNAP_CONFIGURE); - p->add_separator(); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL); - p->add_separator(); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/expand_to_parent", TTR("Expand to Parent"), KEY_MASK_CMD | KEY_P), EXPAND_TO_PARENT); - p->add_separator(); - p->add_submenu_item(TTR("Skeleton.."),"skeleton"); - skeleton_menu = memnew(PopupMenu); - p->add_child(skeleton_menu); - skeleton_menu->set_name("skeleton"); - skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Bones"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B ),SKELETON_MAKE_BONES); - skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_bones", TTR("Clear Bones")), SKELETON_CLEAR_BONES); - skeleton_menu->add_separator(); - skeleton_menu->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_show_bones", TTR("Show Bones")), SKELETON_SHOW_BONES); - skeleton_menu->add_separator(); - skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_set_ik_chain", TTR("Make IK Chain")), SKELETON_SET_IK_CHAIN); - skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_ik_chain", TTR("Clear IK Chain")), SKELETON_CLEAR_IK_CHAIN); - skeleton_menu->connect("id_pressed", this,"_popup_callback"); - - - /* - p->add_item("Align Horizontal",ALIGN_HORIZONTAL); - p->add_item("Align Vertical",ALIGN_VERTICAL); - p->add_item("Space Horizontal",SPACE_HORIZONTAL); - p->add_item("Space Vertical",SPACE_VERTICAL);*/ - - view_menu = memnew( MenuButton ); - view_menu->set_text(TTR("View")); - hb->add_child(view_menu); - view_menu->get_popup()->connect("id_pressed", this,"_popup_callback"); - - p = view_menu->get_popup(); - - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_in", TTR("Zoom In")), ZOOM_IN); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_out", TTR("Zoom Out")), ZOOM_OUT); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", TTR("Zoom Reset")), ZOOM_RESET); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_set", TTR("Zoom Set..")), ZOOM_SET); - p->add_separator(); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/center_selection", TTR("Center Selection"), KEY_F), VIEW_CENTER_TO_SELECTION); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTR("Frame Selection"), KEY_MASK_SHIFT | KEY_F), VIEW_FRAME_TO_SELECTION); - - anchor_menu = memnew( MenuButton ); - anchor_menu->set_text(TTR("Anchor")); - hb->add_child(anchor_menu); - anchor_menu->get_popup()->connect("id_pressed", this,"_popup_callback"); - anchor_menu->hide(); - - //p = anchor_menu->get_popup(); - - - - animation_hb = memnew( HBoxContainer ); - hb->add_child(animation_hb); - animation_hb->add_child( memnew( VSeparator )); - animation_hb->hide(); - - key_loc_button = memnew( Button("loc")); - key_loc_button->set_toggle_mode(true); - key_loc_button->set_pressed(true); - key_loc_button->set_focus_mode(FOCUS_NONE); - key_loc_button->add_color_override("font_color",Color(1,0.6,0.6)); - key_loc_button->add_color_override("font_color_pressed",Color(0.6,1,0.6)); - key_loc_button->connect("pressed",this,"_popup_callback",varray(ANIM_INSERT_POS)); - animation_hb->add_child(key_loc_button); - key_rot_button = memnew( Button("rot")); - key_rot_button->set_toggle_mode(true); - key_rot_button->set_pressed(true); - key_rot_button->set_focus_mode(FOCUS_NONE); - key_rot_button->add_color_override("font_color",Color(1,0.6,0.6)); - key_rot_button->add_color_override("font_color_pressed",Color(0.6,1,0.6)); - key_rot_button->connect("pressed",this,"_popup_callback",varray(ANIM_INSERT_ROT)); - animation_hb->add_child(key_rot_button); - key_scale_button = memnew( Button("scl")); - key_scale_button->set_toggle_mode(true); - key_scale_button->set_focus_mode(FOCUS_NONE); - key_scale_button->add_color_override("font_color",Color(1,0.6,0.6)); - key_scale_button->add_color_override("font_color_pressed",Color(0.6,1,0.6)); - key_scale_button->connect("pressed",this,"_popup_callback",varray(ANIM_INSERT_SCALE)); - animation_hb->add_child(key_scale_button); - key_insert_button = memnew( Button ); - key_insert_button->set_focus_mode(FOCUS_NONE); - key_insert_button->connect("pressed",this,"_popup_callback",varray(ANIM_INSERT_KEY)); - key_insert_button->set_tooltip(TTR("Insert Keys")); - key_insert_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/anim_insert_key", TTR("Insert Key"), KEY_INSERT)); - - animation_hb->add_child(key_insert_button); - - animation_menu = memnew( MenuButton ); - animation_menu->set_text(TTR("Animation")); - animation_hb->add_child(animation_menu); - animation_menu->get_popup()->connect("id_pressed", this,"_popup_callback"); - - p = animation_menu->get_popup(); - - p->add_shortcut(ED_GET_SHORTCUT("canvas_item_editor/anim_insert_key"), ANIM_INSERT_KEY); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_insert_key_existing_tracks", TTR("Insert Key (Existing Tracks)"), KEY_MASK_CMD+KEY_INSERT), ANIM_INSERT_KEY_EXISTING); - p->add_separator(); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_copy_pose", TTR("Copy Pose")), ANIM_COPY_POSE); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_paste_pose", TTR("Paste Pose")), ANIM_PASTE_POSE); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/anim_clear_pose", TTR("Clear Pose"), KEY_MASK_SHIFT | KEY_K), ANIM_CLEAR_POSE); - - snap_dialog = memnew( SnapDialog ); - snap_dialog->connect("confirmed",this,"_snap_changed"); - add_child(snap_dialog); - - value_dialog = memnew( AcceptDialog ); - value_dialog->set_title(TTR("Set a Value")); - value_dialog->get_ok()->set_text(TTR("Close")); - add_child(value_dialog); - - Label *l = memnew(Label); - l->set_text(TTR("Snap (Pixels):")); - l->set_pos(Point2(5,5)); - value_dialog->add_child(l); - dialog_label=l; - - dialog_val=memnew(SpinBox); - dialog_val->set_anchor(MARGIN_RIGHT,ANCHOR_END); - dialog_val->set_begin(Point2(15,25)); - dialog_val->set_end(Point2(10,25)); - value_dialog->add_child(dialog_val); - dialog_val->connect("value_changed",this,"_dialog_value_changed"); - select_sb = Ref<StyleBoxTexture>( memnew( StyleBoxTexture) ); - - selection_menu = memnew( PopupMenu ); - add_child(selection_menu); - selection_menu->set_custom_minimum_size(Vector2(100, 0)); - selection_menu->connect("id_pressed", this, "_selection_result_pressed"); - selection_menu->connect("popup_hide", this, "_selection_menu_hide"); - - key_pos=true; - key_rot=true; - key_scale=false; - - zoom=1; - snap_offset=Vector2(0, 0); - snap_step=Vector2(10, 10); - snap_rotation_offset=0; - snap_rotation_step=15 / (180 / Math_PI); - snap_grid=false; - snap_show_grid=false; - snap_rotation=false; - snap_pixel=false; - skeleton_show_bones=true; - skeleton_menu->set_item_checked(skeleton_menu->get_item_index(SKELETON_SHOW_BONES),true); - updating_value_dialog=false; - box_selecting=false; - //zoom=0.5; - singleton=this; - - set_process_unhandled_key_input(true); - can_move_pivot=false; - drag=DRAG_NONE; - bone_last_frame=0; - additive_selection=false; -} - -CanvasItemEditor *CanvasItemEditor::singleton=NULL; - -void CanvasItemEditorPlugin::edit(Object *p_object) { - - canvas_item_editor->set_undo_redo(&get_undo_redo()); - canvas_item_editor->edit(p_object->cast_to<CanvasItem>()); -} - -bool CanvasItemEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("CanvasItem"); -} - -void CanvasItemEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - canvas_item_editor->show(); - canvas_item_editor->set_fixed_process(true); - VisualServer::get_singleton()->viewport_set_hide_canvas(editor->get_scene_root()->get_viewport_rid(),false); - canvas_item_editor->viewport->grab_focus(); - - } else { - - canvas_item_editor->hide(); - canvas_item_editor->set_fixed_process(false); - VisualServer::get_singleton()->viewport_set_hide_canvas(editor->get_scene_root()->get_viewport_rid(),true); - } - -} - -Dictionary CanvasItemEditorPlugin::get_state() const { - - return canvas_item_editor->get_state(); -} -void CanvasItemEditorPlugin::set_state(const Dictionary& p_state) { - - canvas_item_editor->set_state(p_state); -} - -CanvasItemEditorPlugin::CanvasItemEditorPlugin(EditorNode *p_node) { - - editor=p_node; - canvas_item_editor = memnew( CanvasItemEditor(editor) ); - canvas_item_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); - editor->get_viewport()->add_child(canvas_item_editor); - canvas_item_editor->set_area_as_parent_rect(); - canvas_item_editor->hide(); - -} - - -CanvasItemEditorPlugin::~CanvasItemEditorPlugin() -{ -} - - -void CanvasItemEditorViewport::_on_mouse_exit() { - if (!selector->is_visible()){ - _remove_preview(); - } -} - -void CanvasItemEditorViewport::_on_select_type(Object* selected) { - CheckBox* check = selected->cast_to<CheckBox>(); - String type = check->get_text(); - selector_label->set_text(vformat(TTR("Add %s"),type)); - label->set_text(vformat(TTR("Adding %s..."),type)); -} - -void CanvasItemEditorViewport::_on_change_type() { - if (!button_group->get_pressed_button()) - return; - - CheckBox* check=button_group->get_pressed_button()->cast_to<CheckBox>(); - default_type=check->get_text(); - _perform_drop_data(); - selector->hide(); -} - -void CanvasItemEditorViewport::_create_preview(const Vector<String>& files) const { - label->set_pos(get_global_pos()+Point2(14,14)); - label_desc->set_pos(label->get_pos()+Point2(0,label->get_size().height)); - for (int i=0;i<files.size();i++) { - String path=files[i]; - RES res=ResourceLoader::load(path); - String type=res->get_class(); - if (type=="ImageTexture" || type=="PackedScene") { - if (type=="ImageTexture") { - Ref<ImageTexture> texture=Ref<ImageTexture> ( ResourceCache::get(path)->cast_to<ImageTexture>() ); - Sprite* sprite=memnew(Sprite); - sprite->set_texture(texture); - sprite->set_modulate(Color(1,1,1,0.7f)); - preview->add_child(sprite); - label->show(); - label_desc->show(); - } else if (type=="PackedScene") { - Ref<PackedScene> scn=ResourceLoader::load(path); - if (scn.is_valid()){ - Node* instance=scn->instance(); - if (instance){ - preview->add_child(instance); - } - } - } - editor->get_scene_root()->add_child(preview); - } - } -} - -void CanvasItemEditorViewport::_remove_preview() { - if (preview->get_parent()){ - editor->get_scene_root()->remove_child(preview); - for (int i=preview->get_child_count()-1;i>=0;i--){ - Node* node=preview->get_child(i); - memdelete(node); - } - label->hide(); - label_desc->hide(); - } -} - -bool CanvasItemEditorViewport::_cyclical_dependency_exists(const String& p_target_scene_path, Node* p_desired_node) { - if (p_desired_node->get_filename()==p_target_scene_path) { - return true; - } - - int childCount=p_desired_node->get_child_count(); - for (int i=0;i<childCount;i++) { - Node* child=p_desired_node->get_child(i); - if(_cyclical_dependency_exists(p_target_scene_path,child)) { - return true; - } - } - return false; -} - -void CanvasItemEditorViewport::_create_nodes(Node* parent, Node* child, String& path, const Point2& p_point) { - child->set_name(path.get_file().get_basename()); - Ref<ImageTexture> texture=Ref<ImageTexture> ( ResourceCache::get(path)->cast_to<ImageTexture>() ); - Size2 texture_size = texture->get_size(); - - editor_data->get_undo_redo().add_do_method(parent,"add_child",child); - editor_data->get_undo_redo().add_do_method(child,"set_owner",editor->get_edited_scene()); - editor_data->get_undo_redo().add_do_reference(child); - editor_data->get_undo_redo().add_undo_method(parent,"remove_child",child); - - String new_name=parent->validate_child_name(child); - ScriptEditorDebugger *sed=ScriptEditor::get_singleton()->get_debugger(); - editor_data->get_undo_redo().add_do_method(sed,"live_debug_create_node",editor->get_edited_scene()->get_path_to(parent),child->get_class(),new_name); - editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(editor->get_edited_scene()->get_path_to(parent))+"/"+new_name)); - - // handle with different property for texture - String property = "texture"; - List<PropertyInfo> props; - child->get_property_list(&props); - for(const List<PropertyInfo>::Element *E=props.front();E;E=E->next() ) { - if (E->get().name=="config/texture") { // Particles2D - property="config/texture"; - break; - } else if (E->get().name=="texture/texture") { // Polygon2D - property="texture/texture"; - break; - } else if (E->get().name=="normal") { // TouchScreenButton - property="normal"; - break; - } - } - editor_data->get_undo_redo().add_do_property(child,property,texture); - - // make visible for certain node type - if (default_type=="Patch9Rect") { - editor_data->get_undo_redo().add_do_property(child,"rect/size",texture_size); - } else if (default_type=="Polygon2D") { - PoolVector<Vector2> list; - list.push_back(Vector2(0,0)); - list.push_back(Vector2(texture_size.width,0)); - list.push_back(Vector2(texture_size.width,texture_size.height)); - list.push_back(Vector2(0,texture_size.height)); - editor_data->get_undo_redo().add_do_property(child,"polygon",list); - } - - // locate at preview position - Point2 pos; - if (parent->has_method("get_global_pos")) { - pos=parent->call("get_global_pos"); - } - Transform2D trans=canvas->get_canvas_transform(); - Point2 target_pos = (p_point-trans.get_origin())/trans.get_scale().x-pos; - if (default_type=="Polygon2D" || default_type=="TouchScreenButton" || default_type=="TextureRect" || default_type=="Patch9Rect") { - target_pos -= texture_size/2; - } - editor_data->get_undo_redo().add_do_method(child,"set_pos",target_pos); -} - -bool CanvasItemEditorViewport::_create_instance(Node* parent, String& path, const Point2& p_point) { - Ref<PackedScene> sdata=ResourceLoader::load(path); - if (!sdata.is_valid()) { // invalid scene - return false; - } - - Node* instanced_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); - if (!instanced_scene) { // error on instancing - return false; - } - - if (editor->get_edited_scene()->get_filename()!="") { // cyclical instancing - if (_cyclical_dependency_exists(editor->get_edited_scene()->get_filename(), instanced_scene)) { - memdelete(instanced_scene); - return false; - } - } - - instanced_scene->set_filename( GlobalConfig::get_singleton()->localize_path(path) ); - - editor_data->get_undo_redo().add_do_method(parent,"add_child",instanced_scene); - editor_data->get_undo_redo().add_do_method(instanced_scene,"set_owner",editor->get_edited_scene()); - editor_data->get_undo_redo().add_do_reference(instanced_scene); - editor_data->get_undo_redo().add_undo_method(parent,"remove_child",instanced_scene); - - String new_name=parent->validate_child_name(instanced_scene); - ScriptEditorDebugger *sed=ScriptEditor::get_singleton()->get_debugger(); - editor_data->get_undo_redo().add_do_method(sed,"live_debug_instance_node",editor->get_edited_scene()->get_path_to(parent),path,new_name); - editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(editor->get_edited_scene()->get_path_to(parent))+"/"+new_name)); - - Point2 pos; - Node2D* parent_node2d=parent->cast_to<Node2D>(); - if (parent_node2d) { - pos=parent_node2d->get_global_position(); - } else { - Control* parent_control=parent->cast_to<Control>(); - if (parent_control) { - pos=parent_control->get_global_pos(); - } - } - Transform2D trans=canvas->get_canvas_transform(); - editor_data->get_undo_redo().add_do_method(instanced_scene,"set_pos",(p_point-trans.get_origin())/trans.get_scale().x-pos); - - return true; -} - -void CanvasItemEditorViewport::_perform_drop_data(){ - _remove_preview(); - - Vector<String> error_files; - - editor_data->get_undo_redo().create_action(TTR("Create Node")); - - for (int i=0;i<selected_files.size();i++) { - String path=selected_files[i]; - RES res=ResourceLoader::load(path); - if (res.is_null()) { - continue; - } - String type=res->get_class(); - if (type=="ImageTexture") { - Node* child; - if (default_type=="Light2D") child=memnew(Light2D); - else if (default_type=="Particles2D") child=memnew(Particles2D); - else if (default_type=="Polygon2D") child=memnew(Polygon2D); - else if (default_type=="TouchScreenButton") child=memnew(TouchScreenButton); - else if (default_type=="TextureRect") child=memnew(TextureRect); - else if (default_type=="Patch9Rect") child=memnew(NinePatchRect); - else child=memnew(Sprite); // default - - _create_nodes(target_node, child, path, drop_pos); - } else if (type=="PackedScene") { - bool success=_create_instance(target_node, path, drop_pos); - if (!success) { - error_files.push_back(path); - } - } - } - - editor_data->get_undo_redo().commit_action(); - - if (error_files.size()>0) { - String files_str; - for (int i=0;i<error_files.size();i++) { - files_str += error_files[i].get_file().get_basename() + ","; - } - files_str=files_str.substr(0,files_str.length()-1); - accept->get_ok()->set_text(TTR("Ugh")); - accept->set_text(vformat(TTR("Error instancing scene from %s"),files_str.c_str())); - accept->popup_centered_minsize(); - } -} - -bool CanvasItemEditorViewport::can_drop_data(const Point2& p_point,const Variant& p_data) const { - Dictionary d=p_data; - if (d.has("type")) { - if (String(d["type"])=="files") { - Vector<String> files=d["files"]; - bool can_instance=false; - for (int i=0;i<files.size();i++) { // check if dragged files contain resource or scene can be created at least one - RES res=ResourceLoader::load(files[i]); - if (res.is_null()) { - continue; - } - String type=res->get_class(); - if (type=="PackedScene") { - Ref<PackedScene> sdata=ResourceLoader::load(files[i]); - Node* instanced_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); - if (!instanced_scene) { - continue; - } - memdelete(instanced_scene); - } - can_instance=true; - break; - } - if (can_instance) { - if (!preview->get_parent()){ // create preview only once - _create_preview(files); - } - Transform2D trans=canvas->get_canvas_transform(); - preview->set_position((p_point-trans.get_origin())/trans.get_scale().x); - label->set_text(vformat(TTR("Adding %s..."),default_type)); - } - return can_instance; - } - } - label->hide(); - return false; -} - -void CanvasItemEditorViewport::drop_data(const Point2& p_point,const Variant& p_data) { - bool is_shift=Input::get_singleton()->is_key_pressed(KEY_SHIFT); - bool is_alt=Input::get_singleton()->is_key_pressed(KEY_ALT); - - selected_files.clear(); - Dictionary d=p_data; - if (d.has("type") && String(d["type"])=="files"){ - selected_files=d["files"]; - } - - List<Node*> list=editor->get_editor_selection()->get_selected_node_list(); - if (list.size()==0) { - accept->get_ok()->set_text(TTR("OK :(")); - accept->set_text(TTR("No parent to instance a child at.")); - accept->popup_centered_minsize(); - _remove_preview(); - return; - } - if (list.size()!=1) { - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text(TTR("This operation requires a single selected node.")); - accept->popup_centered_minsize(); - _remove_preview(); - return; - } - - target_node=list[0]; - if (is_shift && target_node!=editor->get_edited_scene()) { - target_node=target_node->get_parent(); - } - drop_pos=p_point; - - if (is_alt) { - List<BaseButton*> btn_list; - button_group->get_buttons(&btn_list); - - for (int i=0;i<btn_list.size();i++) { - CheckBox* check=btn_list[i]->cast_to<CheckBox>(); - check->set_pressed(check->get_text()==default_type); - } - selector_label->set_text(vformat(TTR("Add %s"),default_type)); - selector->popup_centered_minsize(); - } else { - _perform_drop_data(); - } -} - -void CanvasItemEditorViewport::_notification(int p_what) { - if (p_what==NOTIFICATION_ENTER_TREE) { - connect("mouse_exited",this,"_on_mouse_exit"); - } else if (p_what==NOTIFICATION_EXIT_TREE) { - disconnect("mouse_exited",this,"_on_mouse_exit"); - } -} - -void CanvasItemEditorViewport::_bind_methods() { - ClassDB::bind_method(D_METHOD("_on_select_type"),&CanvasItemEditorViewport::_on_select_type); - ClassDB::bind_method(D_METHOD("_on_change_type"),&CanvasItemEditorViewport::_on_change_type); - ClassDB::bind_method(D_METHOD("_on_mouse_exit"),&CanvasItemEditorViewport::_on_mouse_exit); -} - -CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasItemEditor* p_canvas) { - default_type="Sprite"; - // Node2D - types.push_back("Sprite"); - types.push_back("Light2D"); - types.push_back("Particles2D"); - types.push_back("Polygon2D"); - types.push_back("TouchScreenButton"); - // Control - types.push_back("TextureRect"); - types.push_back("Patch9Rect"); - - target_node=NULL; - editor=p_node; - editor_data=editor->get_scene_tree_dock()->get_editor_data(); - canvas=p_canvas; - preview=memnew( Node2D ); - accept=memnew( AcceptDialog ); - editor->get_gui_base()->add_child(accept); - - selector=memnew( WindowDialog ); - selector->set_title(TTR("Change default type")); - - VBoxContainer* vbc=memnew(VBoxContainer); - vbc->add_constant_override("separation",10*EDSCALE); - vbc->set_custom_minimum_size(Size2(200,260)*EDSCALE); - - selector_label=memnew(Label); - selector_label->set_align(Label::ALIGN_CENTER); - selector_label->set_valign(Label::VALIGN_BOTTOM); - selector_label->set_custom_minimum_size(Size2(0,30)*EDSCALE); - vbc->add_child(selector_label); - - button_group.instance(); - - btn_group=memnew( VBoxContainer ); - btn_group->set_h_size_flags(0); - btn_group->connect("button_selected", this, "_on_select_type"); - - for (int i=0;i<types.size();i++) { - CheckBox* check=memnew(CheckBox); - check->set_text(types[i]); - btn_group->add_child(check); - check->set_button_group(button_group); - } - vbc->add_child(btn_group); - - Button* ok=memnew(Button); - ok->set_text(TTR("OK")); - ok->set_h_size_flags(0); - vbc->add_child(ok); - ok->connect("pressed", this, "_on_change_type"); - - selector->add_child(vbc); - editor->get_gui_base()->add_child(selector); - - label=memnew(Label); - label->add_color_override("font_color", Color(1,1,0,1)); - label->add_color_override("font_color_shadow", Color(0,0,0,1)); - label->add_constant_override("shadow_as_outline", 1*EDSCALE); - label->hide(); - editor->get_gui_base()->add_child(label); - - label_desc=memnew(Label); - label_desc->set_text(TTR("Drag & drop + Shift : Add node as sibling\nDrag & drop + Alt : Change node type")); - label_desc->add_color_override("font_color", Color(0.6,0.6,0.6,1)); - label_desc->add_color_override("font_color_shadow", Color(0.2,0.2,0.2,1)); - label_desc->add_constant_override("shadow_as_outline", 1*EDSCALE); - label_desc->add_constant_override("line_spacing", 0); - label_desc->hide(); - editor->get_gui_base()->add_child(label_desc); -} diff --git a/tools/editor/plugins/canvas_item_editor_plugin.h b/tools/editor/plugins/canvas_item_editor_plugin.h deleted file mode 100644 index dac8af5ae9..0000000000 --- a/tools/editor/plugins/canvas_item_editor_plugin.h +++ /dev/null @@ -1,503 +0,0 @@ -/*************************************************************************/ -/* canvas_item_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef CONTROL_EDITOR_PLUGIN_H -#define CONTROL_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/gui/button_group.h" -#include "scene/gui/check_box.h" -#include "scene/gui/label.h" -#include "scene/gui/spin_box.h" -#include "scene/gui/panel_container.h" -#include "scene/gui/box_container.h" -#include "scene/2d/canvas_item.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -class CanvasItemEditorViewport; - -class CanvasItemEditorSelectedItem : public Object { - - GDCLASS(CanvasItemEditorSelectedItem,Object); -public: - Variant undo_state; - Vector2 undo_pivot; - - Transform2D prev_xform; - float prev_rot; - Rect2 prev_rect; - - CanvasItemEditorSelectedItem() { prev_rot=0; } -}; - -class CanvasItemEditor : public VBoxContainer { - - GDCLASS(CanvasItemEditor, VBoxContainer ); - - EditorNode *editor; - - - enum Tool { - - TOOL_SELECT, - TOOL_LIST_SELECT, - TOOL_MOVE, - TOOL_ROTATE, - TOOL_EDIT_PIVOT, - TOOL_PAN, - TOOL_MAX - }; - - enum MenuOption { - SNAP_USE, - SNAP_SHOW_GRID, - SNAP_USE_ROTATION, - SNAP_RELATIVE, - SNAP_CONFIGURE, - SNAP_USE_PIXEL, - ZOOM_IN, - ZOOM_OUT, - ZOOM_RESET, - ZOOM_SET, - LOCK_SELECTED, - UNLOCK_SELECTED, - GROUP_SELECTED, - UNGROUP_SELECTED, - ALIGN_HORIZONTAL, - ALIGN_VERTICAL, - ANCHOR_ALIGN_TOP_LEFT, - ANCHOR_ALIGN_TOP_RIGHT, - ANCHOR_ALIGN_BOTTOM_LEFT, - ANCHOR_ALIGN_BOTTOM_RIGHT, - ANCHOR_ALIGN_CENTER_LEFT, - ANCHOR_ALIGN_CENTER_RIGHT, - ANCHOR_ALIGN_CENTER_TOP, - ANCHOR_ALIGN_CENTER_BOTTOM, - ANCHOR_ALIGN_CENTER, - ANCHOR_ALIGN_TOP_WIDE, - ANCHOR_ALIGN_LEFT_WIDE, - ANCHOR_ALIGN_RIGHT_WIDE, - ANCHOR_ALIGN_BOTTOM_WIDE, - ANCHOR_ALIGN_VCENTER_WIDE, - ANCHOR_ALIGN_HCENTER_WIDE, - ANCHOR_ALIGN_WIDE, - - SPACE_HORIZONTAL, - SPACE_VERTICAL, - EXPAND_TO_PARENT, - ANIM_INSERT_KEY, - ANIM_INSERT_KEY_EXISTING, - ANIM_INSERT_POS, - ANIM_INSERT_ROT, - ANIM_INSERT_SCALE, - ANIM_COPY_POSE, - ANIM_PASTE_POSE, - ANIM_CLEAR_POSE, - VIEW_CENTER_TO_SELECTION, - VIEW_FRAME_TO_SELECTION, - SKELETON_MAKE_BONES, - SKELETON_CLEAR_BONES, - SKELETON_SHOW_BONES, - SKELETON_SET_IK_CHAIN, - SKELETON_CLEAR_IK_CHAIN - - }; - - enum DragType { - DRAG_NONE, - DRAG_LEFT, - DRAG_TOP_LEFT, - DRAG_TOP, - DRAG_TOP_RIGHT, - DRAG_RIGHT, - DRAG_BOTTOM_RIGHT, - DRAG_BOTTOM, - DRAG_BOTTOM_LEFT, - DRAG_ALL, - DRAG_ROTATE, - DRAG_PIVOT, - - }; - - enum KeyMoveMODE { - MOVE_VIEW_BASE, - MOVE_LOCAL_BASE, - MOVE_LOCAL_WITH_ROT - }; - - EditorSelection *editor_selection; - bool additive_selection; - - Tool tool; - bool first_update; - Control *viewport; - - bool can_move_pivot; - - HScrollBar *h_scroll; - VScrollBar *v_scroll; - HBoxContainer *hb; - - Transform2D transform; - float zoom; - Vector2 snap_offset; - Vector2 snap_step; - float snap_rotation_step; - float snap_rotation_offset; - bool snap_grid; - bool snap_show_grid; - bool snap_rotation; - bool snap_relative; - bool snap_pixel; - bool skeleton_show_bones; - bool box_selecting; - Point2 box_selecting_to; - bool key_pos; - bool key_rot; - bool key_scale; - - void _tool_select(int p_index); - - - MenuOption last_option; - - struct _SelectResult { - - CanvasItem* item; - float z; - bool has_z; - _FORCE_INLINE_ bool operator<(const _SelectResult& p_rr) const { - return has_z && p_rr.has_z ? p_rr.z < z : p_rr.has_z; - } - }; - - Vector<_SelectResult> selection_results; - - struct LockList { - Point2 pos; - bool lock; - bool group; - LockList() { lock=false; group=false; } - }; - - List<LockList> lock_list; - - struct BoneList { - - Transform2D xform; - Vector2 from; - Vector2 to; - ObjectID bone; - uint64_t last_pass; - }; - - uint64_t bone_last_frame; - Map<ObjectID,BoneList> bone_list; - - Transform2D bone_orig_xform; - - struct BoneIK { - - Variant orig_state; - Vector2 pos; - float len; - Node2D *node; - }; - - List<BoneIK> bone_ik_list; - - struct PoseClipboard { - - Vector2 pos; - Vector2 scale; - float rot; - ObjectID id; - }; - - List<PoseClipboard> pose_clipboard; - - ToolButton *select_button; - ToolButton *list_select_button; - ToolButton *move_button; - ToolButton *rotate_button; - - ToolButton *pivot_button; - ToolButton *pan_button; - - ToolButton *lock_button; - ToolButton *unlock_button; - - ToolButton *group_button; - ToolButton *ungroup_button; - - MenuButton *edit_menu; - PopupMenu *skeleton_menu; - MenuButton *view_menu; - HBoxContainer *animation_hb; - MenuButton *animation_menu; - MenuButton *anchor_menu; - - Button *key_loc_button; - Button *key_rot_button; - Button *key_scale_button; - Button *key_insert_button; - - PopupMenu *selection_menu; - - - //PopupMenu *popup; - DragType drag; - Point2 drag_from; - Point2 drag_point_from; - bool updating_value_dialog; - Point2 display_rotate_from; - Point2 display_rotate_to; -#if 0 - struct EditInfo { - - Variant undo_state; - - Matrix32 prev_xform; - float prev_rot; - Rect2 prev_rect; - EditInfo() { prev_rot=0; } - }; - - typedef Map<CanvasItem*,EditInfo> CanvasItemMap; - CanvasItemMap canvas_items; -#endif - Ref<StyleBoxTexture> select_sb; - Ref<Texture> select_handle; - - - int handle_len; - bool _is_part_of_subscene(CanvasItem *p_item); - CanvasItem* _select_canvas_item_at_pos(const Point2 &p_pos,Node* p_node,const Transform2D& p_parent_xform,const Transform2D& p_canvas_xform); - void _find_canvas_items_at_pos(const Point2 &p_pos,Node* p_node,const Transform2D& p_parent_xform,const Transform2D& p_canvas_xform, Vector<_SelectResult> &r_items); - void _find_canvas_items_at_rect(const Rect2& p_rect,Node* p_node,const Transform2D& p_parent_xform,const Transform2D& p_canvas_xform,List<CanvasItem*> *r_items); - - bool _select(CanvasItem *item, Point2 p_click_pos, bool p_append, bool p_drag=true); - - ConfirmationDialog *snap_dialog; - - AcceptDialog *value_dialog; - Label *dialog_label; - SpinBox *dialog_val; - - CanvasItem *ref_item; - - void _edit_set_pivot(const Vector2& mouse_pos); - void _add_canvas_item(CanvasItem *p_canvas_item); - void _remove_canvas_item(CanvasItem *p_canvas_item); - void _clear_canvas_items(); - void _visibility_changed(ObjectID p_canvas_item); - void _key_move(const Vector2& p_dir, bool p_snap, KeyMoveMODE p_move_mode); - void _list_select(const InputEventMouseButton& b); - - DragType _find_drag_type(const Transform2D& p_xform, const Rect2& p_local_rect, const Point2& p_click, Vector2& r_point); - - void _popup_callback(int p_op); - bool updating_scroll; - void _update_scroll(float); - void _update_scrollbars(); - void incbeg(float& beg,float& end, float inc, float minsize,bool p_symmetric); - void incend(float& beg,float& end, float inc, float minsize,bool p_symmetric); - - void _append_canvas_item(CanvasItem *p_item); - void _dialog_value_changed(double); - void _snap_changed(); - void _selection_result_pressed(int); - void _selection_menu_hide(); - - UndoRedo *undo_redo; - - Point2 _find_topleftmost_point(); - - - void _find_canvas_items_span(Node *p_node, Rect2& r_rect, const Transform2D& p_xform); - - - Object *_get_editor_data(Object *p_what); - - CanvasItem *get_single_item(); - int get_item_count(); - void _keying_changed(); - - void _unhandled_key_input(const InputEvent& p_ev); - - void _viewport_gui_input(const InputEvent& p_event); - void _viewport_draw(); - - void _focus_selection(int p_op); - - void _set_anchor(Control::AnchorType p_left,Control::AnchorType p_top,Control::AnchorType p_right,Control::AnchorType p_bottom); - - HSplitContainer *palette_split; - VSplitContainer *bottom_split; - -friend class CanvasItemEditorPlugin; -protected: - - - void _notification(int p_what); - - void _node_removed(Node *p_node); - static void _bind_methods(); - void end_drag(); - void box_selection_start( Point2 &click ); - bool box_selection_end(); - - HBoxContainer *get_panel_hb() { return hb; } - - struct compare_items_x { - bool operator()( const CanvasItem *a, const CanvasItem *b ) const { - return a->get_global_transform().elements[2].x < b->get_global_transform().elements[2].x; - } - }; - - struct compare_items_y { - bool operator()( const CanvasItem *a, const CanvasItem *b ) const { - return a->get_global_transform().elements[2].y < b->get_global_transform().elements[2].y; - } - }; - - struct proj_vector2_x { - float get( const Vector2 &v ) { return v.x; } - void set( Vector2 &v, float f ) { v.x = f; } - }; - - struct proj_vector2_y { - float get( const Vector2 &v ) { return v.y; } - void set( Vector2 &v, float f ) { v.y = f; } - }; - - template< class P, class C > void space_selected_items(); - - static CanvasItemEditor *singleton; -public: - - Vector2 snap_point(Vector2 p_target, Vector2 p_start = Vector2(0, 0)) const; - float snap_angle(float p_target, float p_start = 0) const; - - Transform2D get_canvas_transform() const { return transform; } - - static CanvasItemEditor *get_singleton() { return singleton; } - Dictionary get_state() const; - void set_state(const Dictionary& p_state); - - void add_control_to_menu_panel(Control *p_control); - - HSplitContainer *get_palette_split(); - VSplitContainer *get_bottom_split(); - - Control *get_viewport_control() { return viewport; } - - bool get_remove_list(List<Node*> *p_list); - void set_undo_redo(UndoRedo *p_undo_redo) {undo_redo=p_undo_redo; } - void edit(CanvasItem *p_canvas_item); - - void focus_selection(); - - CanvasItemEditor(EditorNode *p_editor); -}; - -class CanvasItemEditorPlugin : public EditorPlugin { - - GDCLASS( CanvasItemEditorPlugin, EditorPlugin ); - - CanvasItemEditor *canvas_item_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "2D"; } - bool has_main_screen() const { return true; } - virtual void edit(Object *p_object); - virtual bool handles(Object *p_object) const; - virtual void make_visible(bool p_visible); - virtual bool get_remove_list(List<Node*> *p_list) { return canvas_item_editor->get_remove_list(p_list); } - virtual Dictionary get_state() const; - virtual void set_state(const Dictionary& p_state); - - CanvasItemEditor *get_canvas_item_editor() { return canvas_item_editor; } - - CanvasItemEditorPlugin(EditorNode *p_node); - ~CanvasItemEditorPlugin(); - -}; - -class CanvasItemEditorViewport : public Control { - GDCLASS( CanvasItemEditorViewport, Control ); - - String default_type; - Vector<String> types; - - Vector<String> selected_files; - Node* target_node; - Point2 drop_pos; - - EditorNode* editor; - EditorData* editor_data; - CanvasItemEditor* canvas; - Node2D* preview; - AcceptDialog* accept; - WindowDialog* selector; - Label* selector_label; - Label* label; - Label* label_desc; - VBoxContainer* btn_group; - Ref<ButtonGroup> button_group; - - void _on_mouse_exit(); - void _on_select_type(Object* selected); - void _on_change_type(); - - void _create_preview(const Vector<String>& files) const; - void _remove_preview(); - - bool _cyclical_dependency_exists(const String& p_target_scene_path, Node* p_desired_node); - void _create_nodes(Node* parent, Node* child, String& path, const Point2& p_point); - bool _create_instance(Node* parent, String& path, const Point2& p_point); - void _perform_drop_data(); - - static void _bind_methods(); - -protected: - void _notification(int p_what); - -public: - virtual bool can_drop_data(const Point2& p_point,const Variant& p_data) const; - virtual void drop_data(const Point2& p_point,const Variant& p_data); - - CanvasItemEditorViewport(EditorNode *p_node, CanvasItemEditor* p_canvas); -}; - -#endif diff --git a/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp deleted file mode 100644 index 1149cdcfe1..0000000000 --- a/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp +++ /dev/null @@ -1,482 +0,0 @@ -/*************************************************************************/ -/* collision_polygon_2d_editor_plugin.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 "collision_polygon_2d_editor_plugin.h" - -#include "canvas_item_editor_plugin.h" -#include "os/file_access.h" -#include "tools/editor/editor_settings.h" - - -void CollisionPolygon2DEditor::_notification(int p_what) { - - switch(p_what) { - - case NOTIFICATION_READY: { - - button_create->set_icon( get_icon("Edit","EditorIcons")); - button_edit->set_icon( get_icon("MovePoint","EditorIcons")); - button_edit->set_pressed(true); - get_tree()->connect("node_removed",this,"_node_removed"); - - } break; - case NOTIFICATION_FIXED_PROCESS: { - - - } break; - } - -} -void CollisionPolygon2DEditor::_node_removed(Node *p_node) { - - if(p_node==node) { - node=NULL; - hide(); - canvas_item_editor->get_viewport_control()->update(); - } - -} - - -void CollisionPolygon2DEditor::_menu_option(int p_option) { - - switch(p_option) { - - case MODE_CREATE: { - - mode=MODE_CREATE; - button_create->set_pressed(true); - button_edit->set_pressed(false); - } break; - case MODE_EDIT: { - - mode=MODE_EDIT; - button_create->set_pressed(false); - button_edit->set_pressed(true); - } break; - - } -} - -void CollisionPolygon2DEditor::_wip_close() { - - undo_redo->create_action(TTR("Create Poly")); - undo_redo->add_undo_method(node,"set_polygon",node->get_polygon()); - undo_redo->add_do_method(node,"set_polygon",wip); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - wip.clear(); - wip_active=false; - mode=MODE_EDIT; - button_edit->set_pressed(true); - button_create->set_pressed(false); - edited_point=-1; -} - -bool CollisionPolygon2DEditor::forward_gui_input(const InputEvent& p_event) { - - - if (!node) - return false; - - switch(p_event.type) { - - case InputEvent::MOUSE_BUTTON: { - - const InputEventMouseButton &mb=p_event.mouse_button; - - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - - - Vector2 gpoint = Point2(mb.x,mb.y); - Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); - cpoint=canvas_item_editor->snap_point(cpoint); - cpoint = node->get_global_transform().affine_inverse().xform(cpoint); - - Vector<Vector2> poly = node->get_polygon(); - - //first check if a point is to be added (segment split) - real_t grab_treshold=EDITOR_DEF("editors/poly_editor/point_grab_radius",8); - - switch(mode) { - - - case MODE_CREATE: { - - if (mb.button_index==BUTTON_LEFT && mb.pressed) { - - - if (!wip_active) { - - wip.clear(); - wip.push_back( cpoint ); - wip_active=true; - edited_point_pos=cpoint; - canvas_item_editor->get_viewport_control()->update(); - edited_point=1; - return true; - } else { - - - if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) { - //wip closed - _wip_close(); - - return true; - } else { - - wip.push_back( cpoint ); - edited_point=wip.size(); - canvas_item_editor->get_viewport_control()->update(); - return true; - - //add wip point - } - } - } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { - _wip_close(); - } - - - - } break; - - case MODE_EDIT: { - - if (mb.button_index==BUTTON_LEFT) { - if (mb.pressed) { - - if (mb.mod.control) { - - - if (poly.size() < 3) { - - undo_redo->create_action(TTR("Edit Poly")); - undo_redo->add_undo_method(node,"set_polygon",poly); - poly.push_back(cpoint); - undo_redo->add_do_method(node,"set_polygon",poly); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - return true; - } - - //search edges - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 points[2] ={ xform.xform(poly[i]), - xform.xform(poly[(i+1)%poly.size()]) }; - - Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points); - if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2) - continue; //not valid to reuse point - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - - } - - if (closest_idx>=0) { - - pre_move_edit=poly; - poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos)); - edited_point=closest_idx+1; - edited_point_pos=xform.affine_inverse().xform(closest_pos); - node->set_polygon(poly); - canvas_item_editor->get_viewport_control()->update(); - return true; - } - } else { - - //look for points to move - - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 cp =xform.xform(poly[i]); - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - } - - if (closest_idx>=0) { - - pre_move_edit=poly; - edited_point=closest_idx; - edited_point_pos=xform.affine_inverse().xform(closest_pos); - canvas_item_editor->get_viewport_control()->update(); - return true; - } - } - } else { - - if (edited_point!=-1) { - - //apply - - ERR_FAIL_INDEX_V(edited_point,poly.size(),false); - poly[edited_point]=edited_point_pos; - undo_redo->create_action(TTR("Edit Poly")); - undo_redo->add_do_method(node,"set_polygon",poly); - undo_redo->add_undo_method(node,"set_polygon",pre_move_edit); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - - edited_point=-1; - return true; - } - } - } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { - - - - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 cp =xform.xform(poly[i]); - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - } - - if (closest_idx>=0) { - - - undo_redo->create_action(TTR("Edit Poly (Remove Point)")); - undo_redo->add_undo_method(node,"set_polygon",poly); - poly.remove(closest_idx); - undo_redo->add_do_method(node,"set_polygon",poly); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - return true; - } - - } - - - - } break; - } - - - - } break; - case InputEvent::MOUSE_MOTION: { - - const InputEventMouseMotion &mm=p_event.mouse_motion; - - if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { - - Vector2 gpoint = Point2(mm.x,mm.y); - Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); - cpoint=canvas_item_editor->snap_point(cpoint); - edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint); - - canvas_item_editor->get_viewport_control()->update(); - - } - - } break; - } - - return false; -} -void CollisionPolygon2DEditor::_canvas_draw() { - - if (!node) - return; - - Control *vpc = canvas_item_editor->get_viewport_control(); - - Vector<Vector2> poly; - - if (wip_active) - poly=wip; - else - poly=node->get_polygon(); - - - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - Ref<Texture> handle= get_icon("EditorHandle","EditorIcons"); - - for(int i=0;i<poly.size();i++) { - - - Vector2 p,p2; - p = i==edited_point ? edited_point_pos : poly[i]; - if ((wip_active && i==poly.size()-1) || (((i+1)%poly.size())==edited_point)) - p2=edited_point_pos; - else - p2 = poly[(i+1)%poly.size()]; - - Vector2 point = xform.xform(p); - Vector2 next_point = xform.xform(p2); - - Color col=Color(1,0.3,0.1,0.8); - vpc->draw_line(point,next_point,col,2); - vpc->draw_texture(handle,point-handle->get_size()*0.5); - } -} - - - -void CollisionPolygon2DEditor::edit(Node *p_collision_polygon) { - - if (!canvas_item_editor) { - canvas_item_editor=CanvasItemEditor::get_singleton(); - } - - if (p_collision_polygon) { - - node=p_collision_polygon->cast_to<CollisionPolygon2D>(); - if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) - canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw"); - wip.clear(); - wip_active=false; - edited_point=-1; - canvas_item_editor->get_viewport_control()->update(); - - } else { - node=NULL; - - if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) - canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw"); - - } - -} - -void CollisionPolygon2DEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_menu_option"),&CollisionPolygon2DEditor::_menu_option); - ClassDB::bind_method(D_METHOD("_canvas_draw"),&CollisionPolygon2DEditor::_canvas_draw); - ClassDB::bind_method(D_METHOD("_node_removed"),&CollisionPolygon2DEditor::_node_removed); - -} - -CollisionPolygon2DEditor::CollisionPolygon2DEditor(EditorNode *p_editor) { - - node=NULL; - canvas_item_editor=NULL; - editor=p_editor; - undo_redo = editor->get_undo_redo(); - - add_child( memnew( VSeparator )); - button_create = memnew( ToolButton ); - add_child(button_create); - button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE)); - button_create->set_toggle_mode(true); - button_create->set_tooltip(TTR("Create a new polygon from scratch.")); - - button_edit = memnew( ToolButton ); - add_child(button_edit); - button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT)); - button_edit->set_toggle_mode(true); - button_edit->set_tooltip("Edit existing polygon:\nLMB: Move Point.\nCtrl+LMB: Split Segment.\nRMB: Erase Point."); - - //add_constant_override("separation",0); - -#if 0 - options = memnew( MenuButton ); - add_child(options); - options->set_area_as_parent_rect(); - options->set_text("Polygon"); - //options->get_popup()->add_item("Parse BBCode",PARSE_BBCODE); - options->get_popup()->connect("id_pressed", this,"_menu_option"); -#endif - - mode = MODE_EDIT; - wip_active=false; - -} - - -void CollisionPolygon2DEditorPlugin::edit(Object *p_object) { - - collision_polygon_editor->edit(p_object->cast_to<Node>()); -} - -bool CollisionPolygon2DEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("CollisionPolygon2D"); -} - -void CollisionPolygon2DEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - collision_polygon_editor->show(); - } else { - - collision_polygon_editor->hide(); - collision_polygon_editor->edit(NULL); - } - -} - -CollisionPolygon2DEditorPlugin::CollisionPolygon2DEditorPlugin(EditorNode *p_node) { - - editor=p_node; - collision_polygon_editor = memnew( CollisionPolygon2DEditor(p_node) ); - CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); - - collision_polygon_editor->hide(); - - - -} - - -CollisionPolygon2DEditorPlugin::~CollisionPolygon2DEditorPlugin() -{ -} - diff --git a/tools/editor/plugins/collision_polygon_2d_editor_plugin.h b/tools/editor/plugins/collision_polygon_2d_editor_plugin.h deleted file mode 100644 index 2c573c1dcf..0000000000 --- a/tools/editor/plugins/collision_polygon_2d_editor_plugin.h +++ /dev/null @@ -1,111 +0,0 @@ -/*************************************************************************/ -/* collision_polygon_2d_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef COLLISION_POLYGON_2D_EDITOR_PLUGIN_H -#define COLLISION_POLYGON_2D_EDITOR_PLUGIN_H - - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/2d/collision_polygon_2d.h" -#include "scene/gui/tool_button.h" -#include "scene/gui/button_group.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ -class CanvasItemEditor; - -class CollisionPolygon2DEditor : public HBoxContainer { - - GDCLASS(CollisionPolygon2DEditor, HBoxContainer ); - - UndoRedo *undo_redo; - enum Mode { - - MODE_CREATE, - MODE_EDIT, - - }; - - Mode mode; - - ToolButton *button_create; - ToolButton *button_edit; - - CanvasItemEditor *canvas_item_editor; - EditorNode *editor; - Panel *panel; - CollisionPolygon2D *node; - MenuButton *options; - - int edited_point; - Vector2 edited_point_pos; - Vector<Vector2> pre_move_edit; - Vector<Vector2> wip; - bool wip_active; - - - void _wip_close(); - void _canvas_draw(); - void _menu_option(int p_option); - -protected: - void _notification(int p_what); - void _node_removed(Node *p_node); - static void _bind_methods(); -public: - - bool forward_gui_input(const InputEvent& p_event); - void edit(Node *p_collision_polygon); - CollisionPolygon2DEditor(EditorNode *p_editor); -}; - -class CollisionPolygon2DEditorPlugin : public EditorPlugin { - - GDCLASS( CollisionPolygon2DEditorPlugin, EditorPlugin ); - - CollisionPolygon2DEditor *collision_polygon_editor; - EditorNode *editor; - -public: - - virtual bool forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); } - - virtual String get_name() const { return "CollisionPolygon2D"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - CollisionPolygon2DEditorPlugin(EditorNode *p_node); - ~CollisionPolygon2DEditorPlugin(); - -}; - -#endif // COLLISION_POLYGON_2D_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/collision_polygon_editor_plugin.cpp b/tools/editor/plugins/collision_polygon_editor_plugin.cpp deleted file mode 100644 index 406c12b00a..0000000000 --- a/tools/editor/plugins/collision_polygon_editor_plugin.cpp +++ /dev/null @@ -1,648 +0,0 @@ -/*************************************************************************/ -/* collision_polygon_editor_plugin.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 "collision_polygon_editor_plugin.h" - -#include "spatial_editor_plugin.h" -#include "os/file_access.h" -#include "tools/editor/editor_settings.h" -#include "scene/3d/camera.h" -#include "canvas_item_editor_plugin.h" - -#if 0 - -void CollisionPolygonEditor::_notification(int p_what) { - - switch(p_what) { - - case NOTIFICATION_READY: { - - button_create->set_icon( get_icon("Edit","EditorIcons")); - button_edit->set_icon( get_icon("MovePoint","EditorIcons")); - button_edit->set_pressed(true); - get_tree()->connect("node_removed",this,"_node_removed"); - - - } break; - case NOTIFICATION_PROCESS: { - - if (node->get_depth() != prev_depth) { - _polygon_draw(); - prev_depth=node->get_depth(); - } - - } break; - } - -} -void CollisionPolygonEditor::_node_removed(Node *p_node) { - - if(p_node==node) { - node=NULL; - if (imgeom->get_parent()==p_node) - p_node->remove_child(imgeom); - hide(); - set_process(false); - } - -} - - -void CollisionPolygonEditor::_menu_option(int p_option) { - - switch(p_option) { - - case MODE_CREATE: { - - mode=MODE_CREATE; - button_create->set_pressed(true); - button_edit->set_pressed(false); - } break; - case MODE_EDIT: { - - mode=MODE_EDIT; - button_create->set_pressed(false); - button_edit->set_pressed(true); - } break; - - } -} - -void CollisionPolygonEditor::_wip_close() { - - undo_redo->create_action(TTR("Create Poly3D")); - undo_redo->add_undo_method(node,"set_polygon",node->get_polygon()); - undo_redo->add_do_method(node,"set_polygon",wip); - undo_redo->add_do_method(this,"_polygon_draw"); - undo_redo->add_undo_method(this,"_polygon_draw"); - wip.clear(); - wip_active=false; - mode=MODE_EDIT; - button_edit->set_pressed(true); - button_create->set_pressed(false); - edited_point=-1; - undo_redo->commit_action(); - -} - -bool CollisionPolygonEditor::forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event) { - - if (!node) - return false; - - Transform gt = node->get_global_transform(); - Transform gi = gt.affine_inverse(); - float depth = node->get_depth()*0.5; - Vector3 n = gt.basis.get_axis(2).normalized(); - Plane p(gt.origin+n*depth,n); - - - switch(p_event.type) { - - case InputEvent::MOUSE_BUTTON: { - - const InputEventMouseButton &mb=p_event.mouse_button; - - - - Vector2 gpoint=Point2(mb.x,mb.y); - Vector3 ray_from = p_camera->project_ray_origin(gpoint); - Vector3 ray_dir = p_camera->project_ray_normal(gpoint); - - Vector3 spoint; - - if (!p.intersects_ray(ray_from,ray_dir,&spoint)) - break; - - spoint = gi.xform(spoint); - - Vector2 cpoint(spoint.x,spoint.y); - - cpoint=CanvasItemEditor::get_singleton()->snap_point(cpoint); - - Vector<Vector2> poly = node->get_polygon(); - - //first check if a point is to be added (segment split) - real_t grab_treshold=EDITOR_DEF("editors/poly_editor/point_grab_radius",8); - - switch(mode) { - - - case MODE_CREATE: { - - if (mb.button_index==BUTTON_LEFT && mb.pressed) { - - - if (!wip_active) { - - wip.clear(); - wip.push_back( cpoint ); - wip_active=true; - edited_point_pos=cpoint; - _polygon_draw(); - edited_point=1; - return true; - } else { - - - if (wip.size()>1 && p_camera->unproject_position(gt.xform(Vector3(wip[0].x,wip[0].y,depth))).distance_to(gpoint)<grab_treshold) { - //wip closed - _wip_close(); - - return true; - } else { - - wip.push_back( cpoint ); - edited_point=wip.size(); - _polygon_draw(); - return true; - - //add wip point - } - } - } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { - _wip_close(); - } - - - - } break; - - case MODE_EDIT: { - - if (mb.button_index==BUTTON_LEFT) { - if (mb.pressed) { - - if (mb.mod.control) { - - - if (poly.size() < 3) { - - undo_redo->create_action(TTR("Edit Poly")); - undo_redo->add_undo_method(node,"set_polygon",poly); - poly.push_back(cpoint); - undo_redo->add_do_method(node,"set_polygon",poly); - undo_redo->add_do_method(this,"_polygon_draw"); - undo_redo->add_undo_method(this,"_polygon_draw"); - undo_redo->commit_action(); - return true; - } - - //search edges - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 points[2] ={ - p_camera->unproject_position(gt.xform(Vector3(poly[i].x,poly[i].y,depth))), - p_camera->unproject_position(gt.xform(Vector3(poly[(i+1)%poly.size()].x,poly[(i+1)%poly.size()].y,depth))) - }; - - Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points); - if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2) - continue; //not valid to reuse point - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - - } - - if (closest_idx>=0) { - - pre_move_edit=poly; - poly.insert(closest_idx+1,cpoint); - edited_point=closest_idx+1; - edited_point_pos=cpoint; - node->set_polygon(poly); - _polygon_draw(); - return true; - } - } else { - - //look for points to move - - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x,poly[i].y,depth))); - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - } - - if (closest_idx>=0) { - - pre_move_edit=poly; - edited_point=closest_idx; - edited_point_pos=poly[closest_idx]; - _polygon_draw(); - return true; - } - } - } else { - - if (edited_point!=-1) { - - //apply - - ERR_FAIL_INDEX_V(edited_point,poly.size(),false); - poly[edited_point]=edited_point_pos; - undo_redo->create_action(TTR("Edit Poly")); - undo_redo->add_do_method(node,"set_polygon",poly); - undo_redo->add_undo_method(node,"set_polygon",pre_move_edit); - undo_redo->add_do_method(this,"_polygon_draw"); - undo_redo->add_undo_method(this,"_polygon_draw"); - undo_redo->commit_action(); - - edited_point=-1; - return true; - } - } - } if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { - - - - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x,poly[i].y,depth))); - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - } - - if (closest_idx>=0) { - - - undo_redo->create_action(TTR("Edit Poly (Remove Point)")); - undo_redo->add_undo_method(node,"set_polygon",poly); - poly.remove(closest_idx); - undo_redo->add_do_method(node,"set_polygon",poly); - undo_redo->add_do_method(this,"_polygon_draw"); - undo_redo->add_undo_method(this,"_polygon_draw"); - undo_redo->commit_action(); - return true; - } - - } - - - - } break; - } - - - - } break; - case InputEvent::MOUSE_MOTION: { - - const InputEventMouseMotion &mm=p_event.mouse_motion; - - if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { - - Vector2 gpoint = Point2(mm.x,mm.y); - - Vector3 ray_from = p_camera->project_ray_origin(gpoint); - Vector3 ray_dir = p_camera->project_ray_normal(gpoint); - - Vector3 spoint; - - if (!p.intersects_ray(ray_from,ray_dir,&spoint)) - break; - - spoint = gi.xform(spoint); - - Vector2 cpoint(spoint.x,spoint.y); - - cpoint=CanvasItemEditor::get_singleton()->snap_point(cpoint); - edited_point_pos = cpoint; - - _polygon_draw(); - - } - - } break; - } - - return false; -} -void CollisionPolygonEditor::_polygon_draw() { - - if (!node) - return; - - Vector<Vector2> poly; - - if (wip_active) - poly=wip; - else - poly=node->get_polygon(); - - - float depth = node->get_depth()*0.5; - - imgeom->clear(); - imgeom->set_material_override(line_material); - imgeom->begin(Mesh::PRIMITIVE_LINES,Ref<Texture>()); - - - Rect2 rect; - - for(int i=0;i<poly.size();i++) { - - - Vector2 p,p2; - p = i==edited_point ? edited_point_pos : poly[i]; - if ((wip_active && i==poly.size()-1) || (((i+1)%poly.size())==edited_point)) - p2=edited_point_pos; - else - p2 = poly[(i+1)%poly.size()]; - - if (i==0) - rect.pos=p; - else - rect.expand_to(p); - - Vector3 point = Vector3(p.x,p.y,depth); - Vector3 next_point = Vector3(p2.x,p2.y,depth); - - imgeom->set_color(Color(1,0.3,0.1,0.8)); - imgeom->add_vertex(point); - imgeom->set_color(Color(1,0.3,0.1,0.8)); - imgeom->add_vertex(next_point); - - //Color col=Color(1,0.3,0.1,0.8); - //vpc->draw_line(point,next_point,col,2); - //vpc->draw_texture(handle,point-handle->get_size()*0.5); - } - - rect=rect.grow(1); - - AABB r; - r.pos.x=rect.pos.x; - r.pos.y=rect.pos.y; - r.pos.z=depth; - r.size.x=rect.size.x; - r.size.y=rect.size.y; - r.size.z=0; - - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos); - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos+Vector3(0.3,0,0)); - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos); - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos+Vector3(0.0,0.3,0)); - - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0)); - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0)-Vector3(0.3,0,0)); - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0)); - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0)+Vector3(0,0.3,0)); - - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0)); - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0)-Vector3(0,0.3,0)); - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0)); - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0)+Vector3(0.3,0,0)); - - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos+r.size); - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos+r.size-Vector3(0.3,0,0)); - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos+r.size); - imgeom->set_color(Color(0.8,0.8,0.8,0.2)); - imgeom->add_vertex(r.pos+r.size-Vector3(0.0,0.3,0)); - - imgeom->end(); - - - while(m->get_surface_count()) { - m->surface_remove(0); - } - - if (poly.size()==0) - return; - - Array a; - a.resize(Mesh::ARRAY_MAX); - PoolVector<Vector3> va; - { - - va.resize(poly.size()); - PoolVector<Vector3>::Write w=va.write(); - for(int i=0;i<poly.size();i++) { - - - Vector2 p,p2; - p = i==edited_point ? edited_point_pos : poly[i]; - - Vector3 point = Vector3(p.x,p.y,depth); - w[i]=point; - } - } - a[Mesh::ARRAY_VERTEX]=va; - m->add_surface(Mesh::PRIMITIVE_POINTS,a); - m->surface_set_material(0,handle_material); - -} - - - -void CollisionPolygonEditor::edit(Node *p_collision_polygon) { - - - - if (p_collision_polygon) { - - node=p_collision_polygon->cast_to<CollisionPolygon>(); - wip.clear(); - wip_active=false; - edited_point=-1; - p_collision_polygon->add_child(imgeom); - _polygon_draw(); - set_process(true); - prev_depth=-1; - - } else { - node=NULL; - - if (imgeom->get_parent()) - imgeom->get_parent()->remove_child(imgeom); - - set_process(false); - } - -} - -void CollisionPolygonEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_menu_option"),&CollisionPolygonEditor::_menu_option); - ClassDB::bind_method(D_METHOD("_polygon_draw"),&CollisionPolygonEditor::_polygon_draw); - ClassDB::bind_method(D_METHOD("_node_removed"),&CollisionPolygonEditor::_node_removed); - -} - -CollisionPolygonEditor::CollisionPolygonEditor(EditorNode *p_editor) { - - - node=NULL; - editor=p_editor; - undo_redo = editor->get_undo_redo(); - - add_child( memnew( VSeparator )); - button_create = memnew( ToolButton ); - add_child(button_create); - button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE)); - button_create->set_toggle_mode(true); - - button_edit = memnew( ToolButton ); - add_child(button_edit); - button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT)); - button_edit->set_toggle_mode(true); - - //add_constant_override("separation",0); - -#if 0 - options = memnew( MenuButton ); - add_child(options); - options->set_area_as_parent_rect(); - options->set_text("Polygon"); - //options->get_popup()->add_item("Parse BBCode",PARSE_BBCODE); - options->get_popup()->connect("id_pressed", this,"_menu_option"); -#endif - - mode = MODE_EDIT; - wip_active=false; - imgeom = memnew( ImmediateGeometry ); - imgeom->set_transform(Transform(Matrix3(),Vector3(0,0,0.00001))); - - - line_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial )); - line_material->set_flag(Material::FLAG_UNSHADED, true); - line_material->set_line_width(3.0); - line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true); - line_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, true); - line_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1)); - - - - - handle_material = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial )); - handle_material->set_flag(Material::FLAG_UNSHADED, true); - handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_POINT_SIZE, true); - handle_material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1)); - handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_ALPHA, true); - handle_material->set_fixed_flag(FixedSpatialMaterial::FLAG_USE_COLOR_ARRAY, false); - Ref<Texture> handle=editor->get_gui_base()->get_icon("Editor3DHandle","EditorIcons"); - handle_material->set_point_size(handle->get_width()); - handle_material->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,handle); - - pointsm = memnew( MeshInstance ); - imgeom->add_child(pointsm); - m = Ref<Mesh>( memnew( Mesh ) ); - pointsm->set_mesh(m); - pointsm->set_transform(Transform(Matrix3(),Vector3(0,0,0.00001))); - - -} - -CollisionPolygonEditor::~CollisionPolygonEditor() { - - memdelete( imgeom ); -} - - -void CollisionPolygonEditorPlugin::edit(Object *p_object) { - - collision_polygon_editor->edit(p_object->cast_to<Node>()); -} - -bool CollisionPolygonEditorPlugin::handles(Object *p_object) const { - - return p_object->is_type("CollisionPolygon"); -} - -void CollisionPolygonEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - collision_polygon_editor->show(); - } else { - - collision_polygon_editor->hide(); - collision_polygon_editor->edit(NULL); - } - -} - -CollisionPolygonEditorPlugin::CollisionPolygonEditorPlugin(EditorNode *p_node) { - - editor=p_node; - collision_polygon_editor = memnew( CollisionPolygonEditor(p_node) ); - SpatialEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); - - collision_polygon_editor->hide(); - - - -} - - -CollisionPolygonEditorPlugin::~CollisionPolygonEditorPlugin() -{ -} - -#endif diff --git a/tools/editor/plugins/collision_polygon_editor_plugin.h b/tools/editor/plugins/collision_polygon_editor_plugin.h deleted file mode 100644 index cd722048db..0000000000 --- a/tools/editor/plugins/collision_polygon_editor_plugin.h +++ /dev/null @@ -1,123 +0,0 @@ -/*************************************************************************/ -/* collision_polygon_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef COLLISION_POLYGON_EDITOR_PLUGIN_H -#define COLLISION_POLYGON_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/3d/collision_polygon.h" -#include "scene/3d/immediate_geometry.h" -#include "scene/3d/mesh_instance.h" -#include "scene/gui/tool_button.h" -#include "scene/gui/button_group.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -#if 0 -class CanvasItemEditor; - -class CollisionPolygonEditor : public HBoxContainer { - - GDCLASS(CollisionPolygonEditor, HBoxContainer ); - - UndoRedo *undo_redo; - enum Mode { - - MODE_CREATE, - MODE_EDIT, - - }; - - Mode mode; - - ToolButton *button_create; - ToolButton *button_edit; - - - Ref<FixedSpatialMaterial> line_material; - Ref<FixedSpatialMaterial> handle_material; - - EditorNode *editor; - Panel *panel; - CollisionPolygon *node; - ImmediateGeometry *imgeom; - MeshInstance *pointsm; - Ref<Mesh> m; - - MenuButton *options; - - int edited_point; - Vector2 edited_point_pos; - Vector<Vector2> pre_move_edit; - Vector<Vector2> wip; - bool wip_active; - - float prev_depth; - - void _wip_close(); - void _polygon_draw(); - void _menu_option(int p_option); - -protected: - void _notification(int p_what); - void _node_removed(Node *p_node); - static void _bind_methods(); -public: - - virtual bool forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event); - void edit(Node *p_collision_polygon); - CollisionPolygonEditor(EditorNode *p_editor); - ~CollisionPolygonEditor(); -}; - -class CollisionPolygonEditorPlugin : public EditorPlugin { - - GDCLASS( CollisionPolygonEditorPlugin, EditorPlugin ); - - CollisionPolygonEditor *collision_polygon_editor; - EditorNode *editor; - -public: - - virtual bool forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event) { return collision_polygon_editor->forward_spatial_gui_input(p_camera,p_event); } - - virtual String get_name() const { return "CollisionPolygon"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - CollisionPolygonEditorPlugin(EditorNode *p_node); - ~CollisionPolygonEditorPlugin(); - -}; -#endif -#endif // COLLISION_POLYGON_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/collision_shape_2d_editor_plugin.h b/tools/editor/plugins/collision_shape_2d_editor_plugin.h deleted file mode 100644 index 37708db5e0..0000000000 --- a/tools/editor/plugins/collision_shape_2d_editor_plugin.h +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************/ -/* collision_shape_2d_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef COLLISION_SHAPE_2D_EDITOR_PLUGIN_H -#define COLLISION_SHAPE_2D_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" - -#include "scene/2d/collision_shape_2d.h" - -class CanvasItemEditor; - -class CollisionShape2DEditor : public Control { - GDCLASS(CollisionShape2DEditor, Control); - - enum ShapeType { - CAPSULE_SHAPE, - CIRCLE_SHAPE, - CONCAVE_POLYGON_SHAPE, - CONVEX_POLYGON_SHAPE, - LINE_SHAPE, - RAY_SHAPE, - RECTANGLE_SHAPE, - SEGMENT_SHAPE - }; - - EditorNode* editor; - UndoRedo* undo_redo; - CanvasItemEditor* canvas_item_editor; - CollisionShape2D* node; - - Vector<Point2> handles; - - int shape_type; - int edit_handle; - bool pressed; - Variant original; - - Variant get_handle_value(int idx) const; - void set_handle(int idx, Point2& p_point); - void commit_handle(int idx, Variant& p_org); - - void _get_current_shape_type(); - void _canvas_draw(); - -protected: - static void _bind_methods(); - -public: - bool forward_gui_input(const InputEvent& p_event); - void edit(Node* p_node); - - CollisionShape2DEditor(EditorNode* p_editor); -}; - -class CollisionShape2DEditorPlugin : public EditorPlugin { - GDCLASS(CollisionShape2DEditorPlugin, EditorPlugin); - - CollisionShape2DEditor* collision_shape_2d_editor; - EditorNode* editor; - -public: - virtual bool forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return collision_shape_2d_editor->forward_gui_input(p_event); } - - virtual String get_name() const { return "CollisionShape2D"; } - bool has_main_screen() const { return false; } - virtual void edit(Object* p_obj); - virtual bool handles(Object* p_obj) const; - virtual void make_visible(bool visible); - - CollisionShape2DEditorPlugin(EditorNode* p_editor); - ~CollisionShape2DEditorPlugin(); -}; - -#endif //COLLISION_SHAPE_2D_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/color_ramp_editor_plugin.h b/tools/editor/plugins/color_ramp_editor_plugin.h deleted file mode 100644 index 2f55ad65f1..0000000000 --- a/tools/editor/plugins/color_ramp_editor_plugin.h +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************/ -/* color_ramp_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_ -#define TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_ - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/gui/color_ramp_edit.h" - -class ColorRampEditorPlugin : public EditorPlugin { - - GDCLASS( ColorRampEditorPlugin, EditorPlugin ); - - bool _2d; - Ref<ColorRamp> color_ramp_ref; - ColorRampEdit *ramp_editor; - EditorNode *editor; - -protected: - static void _bind_methods(); - void _ramp_changed(); - void _undo_redo_color_ramp(const Vector<float>& offsets, const Vector<Color>& colors); - -public: - virtual String get_name() const { return "ColorRamp"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - ColorRampEditorPlugin(EditorNode *p_node); - ~ColorRampEditorPlugin(); - -}; - -#endif /* TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_ */ diff --git a/tools/editor/plugins/cube_grid_theme_editor_plugin.cpp b/tools/editor/plugins/cube_grid_theme_editor_plugin.cpp deleted file mode 100644 index 563b8298eb..0000000000 --- a/tools/editor/plugins/cube_grid_theme_editor_plugin.cpp +++ /dev/null @@ -1,357 +0,0 @@ -/*************************************************************************/ -/* cube_grid_theme_editor_plugin.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 "cube_grid_theme_editor_plugin.h" - -#if 0 -#include "scene/3d/mesh_instance.h" -#include "scene/3d/physics_body.h" -#include "scene/main/viewport.h" -#include "scene/resources/packed_scene.h" -#include "tools/editor/editor_node.h" -#include "main/main.h" -#include "tools/editor/editor_settings.h" -#include "scene/3d/navigation_mesh.h" - -void MeshLibraryEditor::edit(const Ref<MeshLibrary>& p_theme) { - - theme=p_theme; - if (theme.is_valid()) - menu->get_popup()->set_item_disabled(menu->get_popup()->get_item_index(MENU_OPTION_UPDATE_FROM_SCENE),!theme->has_meta("_editor_source_scene")); - -} - -void MeshLibraryEditor::_menu_confirm() { - - - switch(option) { - - case MENU_OPTION_REMOVE_ITEM: { - - theme->remove_item(to_erase); - } break; - case MENU_OPTION_UPDATE_FROM_SCENE: { - String existing = theme->get_meta("_editor_source_scene"); - ERR_FAIL_COND(existing==""); - _import_scene_cbk(existing); - - } break; - default: {}; - } - -} - - -void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, bool p_merge) { - - if (!p_merge) - p_library->clear(); - - - for(int i=0;i<p_scene->get_child_count();i++) { - - - Node *child = p_scene->get_child(i); - - if (!child->cast_to<MeshInstance>()) { - if (child->get_child_count()>0) { - child=child->get_child(0); - if (!child->cast_to<MeshInstance>()) { - continue; - } - - } else - continue; - - - } - - MeshInstance *mi = child->cast_to<MeshInstance>(); - Ref<Mesh> mesh=mi->get_mesh(); - if (mesh.is_null()) - continue; - - int id = p_library->find_item_name(mi->get_name()); - if (id<0) { - - id=p_library->get_last_unused_item_id(); - p_library->create_item(id); - p_library->set_item_name(id,mi->get_name()); - } - - - p_library->set_item_mesh(id,mesh); - - Ref<Shape> collision; - - - for(int j=0;j<mi->get_child_count();j++) { -#if 1 - Node *child2 = mi->get_child(j); - if (!child2->cast_to<StaticBody>()) - continue; - StaticBody *sb = child2->cast_to<StaticBody>(); - if (sb->get_shape_count()==0) - continue; - collision=sb->get_shape(0); - if (!collision.is_null()) - break; -#endif - } - - if (!collision.is_null()) { - - p_library->set_item_shape(id,collision); - } - Ref<NavigationMesh> navmesh; - for(int j=0;j<mi->get_child_count();j++) { - Node *child2 = mi->get_child(j); - if (!child2->cast_to<NavigationMeshInstance>()) - continue; - NavigationMeshInstance *sb = child2->cast_to<NavigationMeshInstance>(); - navmesh=sb->get_navigation_mesh(); - if (!navmesh.is_null()) - break; - } - if(!navmesh.is_null()){ - p_library->set_item_navmesh(id, navmesh); - } - } - - //generate previews! - - if (1) { - Vector<int> ids = p_library->get_item_list(); - RID vp = VS::get_singleton()->viewport_create(); - VS::ViewportRect vr; - vr.x=0; - vr.y=0; - vr.width=EditorSettings::get_singleton()->get("editors/grid_map/preview_size"); - vr.height=EditorSettings::get_singleton()->get("editors/grid_map/preview_size"); - VS::get_singleton()->viewport_set_rect(vp,vr); - VS::get_singleton()->viewport_set_as_render_target(vp,true); - VS::get_singleton()->viewport_set_render_target_update_mode(vp,VS::RENDER_TARGET_UPDATE_ALWAYS); - RID scen = VS::get_singleton()->scenario_create(); - VS::get_singleton()->viewport_set_scenario(vp,scen); - RID cam = VS::get_singleton()->camera_create(); - VS::get_singleton()->camera_set_transform(cam, Transform() ); - VS::get_singleton()->viewport_attach_camera(vp,cam); - RID light = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); - RID lightinst = VS::get_singleton()->instance_create2(light,scen); - VS::get_singleton()->camera_set_orthogonal(cam,1.0,0.01,1000.0); - - - EditorProgress ep("mlib",TTR("Creating Mesh Library"),ids.size()); - - for(int i=0;i<ids.size();i++) { - - int id=ids[i]; - Ref<Mesh> mesh = p_library->get_item_mesh(id); - if (!mesh.is_valid()) - continue; - AABB aabb= mesh->get_aabb(); - print_line("aabb: "+aabb); - Vector3 ofs = aabb.pos + aabb.size*0.5; - aabb.pos-=ofs; - Transform xform; - xform.basis=Matrix3().rotated(Vector3(0,1,0),-Math_PI*0.25); - xform.basis = Matrix3().rotated(Vector3(1,0,0),Math_PI*0.25)*xform.basis; - AABB rot_aabb = xform.xform(aabb); - print_line("rot_aabb: "+rot_aabb); - float m = MAX(rot_aabb.size.x,rot_aabb.size.y)*0.5; - if (m==0) - continue; - m=1.0/m; - m*=0.5; - print_line("scale: "+rtos(m)); - xform.basis.scale(Vector3(m,m,m)); - xform.origin=-xform.basis.xform(ofs); //-ofs*m; - xform.origin.z-=rot_aabb.size.z*2; - RID inst = VS::get_singleton()->instance_create2(mesh->get_rid(),scen); - VS::get_singleton()->instance_set_transform(inst,xform); - ep.step(TTR("Thumbnail.."),i); - VS::get_singleton()->viewport_queue_screen_capture(vp); - Main::iteration(); - Image img = VS::get_singleton()->viewport_get_screen_capture(vp); - ERR_CONTINUE(img.empty()); - Ref<ImageTexture> it( memnew( ImageTexture )); - it->create_from_image(img); - p_library->set_item_preview(id,it); - - //print_line("loaded image, size: "+rtos(m)+" dist: "+rtos(dist)+" empty?"+itos(img.empty())+" w: "+itos(it->get_width())+" h: "+itos(it->get_height())); - VS::get_singleton()->free(inst); - } - - VS::get_singleton()->free(lightinst); - VS::get_singleton()->free(light); - VS::get_singleton()->free(vp); - VS::get_singleton()->free(cam); - VS::get_singleton()->free(scen); - } - - -} - - -void MeshLibraryEditor::_import_scene_cbk(const String& p_str) { - - - print_line("Impot Callback!"); - - Ref<PackedScene> ps = ResourceLoader::load(p_str,"PackedScene"); - ERR_FAIL_COND(ps.is_null()); - Node *scene = ps->instance(); - - _import_scene(scene,theme,option==MENU_OPTION_UPDATE_FROM_SCENE); - - memdelete(scene); - theme->set_meta("_editor_source_scene",p_str); - menu->get_popup()->set_item_disabled(menu->get_popup()->get_item_index(MENU_OPTION_UPDATE_FROM_SCENE),false); - -} - -Error MeshLibraryEditor::update_library_file(Node *p_base_scene, Ref<MeshLibrary> ml,bool p_merge) { - - _import_scene(p_base_scene,ml,p_merge); - return OK; -} - - -void MeshLibraryEditor::_menu_cbk(int p_option) { - - option=p_option; - switch(p_option) { - - case MENU_OPTION_ADD_ITEM: { - - theme->create_item(theme->get_last_unused_item_id()); - } break; - case MENU_OPTION_REMOVE_ITEM: { - - String p = editor->get_property_editor()->get_selected_path(); - if (p.begins_with("/MeshLibrary/item") && p.get_slice_count("/")>=3) { - - to_erase = p.get_slice("/",3).to_int(); - cd->set_text(vformat(TTR("Remove item %d?"),to_erase)); - cd->popup_centered(Size2(300,60)); - } - } break; - case MENU_OPTION_IMPORT_FROM_SCENE: { - - file->popup_centered_ratio(); - } break; - case MENU_OPTION_UPDATE_FROM_SCENE: { - - cd->set_text("Update from existing scene?:\n"+String(theme->get_meta("_editor_source_scene"))); - cd->popup_centered(Size2(500,60)); - } break; - } -} - - -void MeshLibraryEditor::_bind_methods() { - - ClassDB::bind_method("_menu_cbk",&MeshLibraryEditor::_menu_cbk); - ClassDB::bind_method("_menu_confirm",&MeshLibraryEditor::_menu_confirm); - ClassDB::bind_method("_import_scene_cbk",&MeshLibraryEditor::_import_scene_cbk); -} - -MeshLibraryEditor::MeshLibraryEditor(EditorNode *p_editor) { - - file = memnew( EditorFileDialog ); - file->set_mode(EditorFileDialog::MODE_OPEN_FILE); - //not for now? - List<String> extensions; - ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions); - file->clear_filters(); - file->set_title(TTR("Import Scene")); - for(int i=0;i<extensions.size();i++) { - - file->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); - } - add_child(file); - file->connect("file_selected",this,"_import_scene_cbk"); - - Panel *panel = memnew( Panel ); - panel->set_area_as_parent_rect(); - add_child(panel); - MenuButton * options = memnew( MenuButton ); - panel->add_child(options); - options->set_pos(Point2(1,1)); - options->set_text("Theme"); - options->get_popup()->add_item(TTR("Add Item"),MENU_OPTION_ADD_ITEM); - options->get_popup()->add_item(TTR("Remove Selected Item"),MENU_OPTION_REMOVE_ITEM); - options->get_popup()->add_separator(); - options->get_popup()->add_item(TTR("Import from Scene"),MENU_OPTION_IMPORT_FROM_SCENE); - options->get_popup()->add_item(TTR("Update from Scene"),MENU_OPTION_UPDATE_FROM_SCENE); - options->get_popup()->set_item_disabled(options->get_popup()->get_item_index(MENU_OPTION_UPDATE_FROM_SCENE),true); - options->get_popup()->connect("id_pressed", this,"_menu_cbk"); - menu=options; - editor=p_editor; - cd = memnew(ConfirmationDialog); - add_child(cd); - cd->get_ok()->connect("pressed", this,"_menu_confirm"); - -} - -void MeshLibraryEditorPlugin::edit(Object *p_node) { - - if (p_node && p_node->cast_to<MeshLibrary>()) { - theme_editor->edit( p_node->cast_to<MeshLibrary>() ); - theme_editor->show(); - } else - theme_editor->hide(); -} - -bool MeshLibraryEditorPlugin::handles(Object *p_node) const{ - - return p_node->is_type("MeshLibrary"); -} - -void MeshLibraryEditorPlugin::make_visible(bool p_visible){ - - if (p_visible) - theme_editor->show(); - else - theme_editor->hide(); -} - -MeshLibraryEditorPlugin::MeshLibraryEditorPlugin(EditorNode *p_node) { - - EDITOR_DEF("editors/grid_map/preview_size",64); - theme_editor = memnew( MeshLibraryEditor(p_node) ); - - p_node->get_viewport()->add_child(theme_editor); - theme_editor->set_area_as_parent_rect(); - theme_editor->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END ); - theme_editor->set_anchor( MARGIN_BOTTOM, Control::ANCHOR_BEGIN ); - theme_editor->set_end( Point2(0,22) ); - theme_editor->hide(); - -} -#endif diff --git a/tools/editor/plugins/cube_grid_theme_editor_plugin.h b/tools/editor/plugins/cube_grid_theme_editor_plugin.h deleted file mode 100644 index f32f601023..0000000000 --- a/tools/editor/plugins/cube_grid_theme_editor_plugin.h +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************/ -/* cube_grid_theme_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef CUBE_GRID_THEME_EDITOR_PLUGIN_H -#define CUBE_GRID_THEME_EDITOR_PLUGIN_H - -#include "scene/resources/mesh_library.h" -#include "tools/editor/editor_node.h" - -#if 0 -class MeshLibraryEditor : public Control { - - GDCLASS( MeshLibraryEditor, Control ); - - Ref<MeshLibrary> theme; - - EditorNode *editor; - MenuButton *menu; - ConfirmationDialog *cd; - EditorFileDialog *file; - int to_erase; - - enum { - - MENU_OPTION_ADD_ITEM, - MENU_OPTION_REMOVE_ITEM, - MENU_OPTION_UPDATE_FROM_SCENE, - MENU_OPTION_IMPORT_FROM_SCENE - }; - - int option; - void _import_scene_cbk(const String& p_str); - void _menu_cbk(int p_option); - void _menu_confirm(); - - static void _import_scene(Node *p_scene, Ref<MeshLibrary> p_library, bool p_merge); - -protected: - static void _bind_methods(); -public: - - void edit(const Ref<MeshLibrary>& p_theme); - static Error update_library_file(Node *p_base_scene, Ref<MeshLibrary> ml,bool p_merge=true); - - MeshLibraryEditor(EditorNode *p_editor); -}; - - - -class MeshLibraryEditorPlugin : public EditorPlugin { - - GDCLASS( MeshLibraryEditorPlugin, EditorPlugin ); - - MeshLibraryEditor *theme_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "MeshLibrary"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - MeshLibraryEditorPlugin(EditorNode *p_node); - -}; - - -#endif // CUBE_GRID_THEME_EDITOR_PLUGIN_H -#endif diff --git a/tools/editor/plugins/editor_preview_plugins.cpp b/tools/editor/plugins/editor_preview_plugins.cpp deleted file mode 100644 index 5d9b281874..0000000000 --- a/tools/editor/plugins/editor_preview_plugins.cpp +++ /dev/null @@ -1,907 +0,0 @@ -/*************************************************************************/ -/* editor_preview_plugins.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 "editor_preview_plugins.h" - -#include "io/resource_loader.h" -#include "tools/editor/editor_settings.h" -#include "io/file_access_memory.h" -#include "os/os.h" -#include "scene/resources/material.h" -//#include "scene/resources/sample.h" -#include "scene/resources/mesh.h" -#include "scene/resources/bit_mask.h" -#include "tools/editor/editor_scale.h" - -#if 0 -bool EditorTexturePreviewPlugin::handles(const String& p_type) const { - - return (ClassDB::is_type(p_type,"ImageTexture") || ClassDB::is_type(p_type, "AtlasTexture")); -} - -Ref<Texture> EditorTexturePreviewPlugin::generate(const RES& p_from) { - - Image img; - Ref<AtlasTexture> atex = p_from; - if (atex.is_valid()) { - Ref<ImageTexture> tex = atex->get_atlas(); - if (!tex.is_valid()) { - return Ref<Texture>(); - } - Image atlas = tex->get_data(); - img = atlas.get_rect(atex->get_region()); - } - else { - Ref<ImageTexture> tex = p_from; - img = tex->get_data(); - } - - if (img.empty()) - return Ref<Texture>(); - - img.clear_mipmaps(); - - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size*=EDSCALE; - if (img.is_compressed()) { - if (img.decompress()!=OK) - return Ref<Texture>(); - } else if (img.get_format()!=Image::FORMAT_RGB8 && img.get_format()!=Image::FORMAT_RGBA8) { - img.convert(Image::FORMAT_RGBA8); - } - - int width,height; - if (img.get_width() > thumbnail_size && img.get_width() >= img.get_height()) { - - width=thumbnail_size; - height = img.get_height() * thumbnail_size / img.get_width(); - } else if (img.get_height() > thumbnail_size && img.get_height() >= img.get_width()) { - - height=thumbnail_size; - width = img.get_width() * thumbnail_size / img.get_height(); - } else { - - width=img.get_width(); - height=img.get_height(); - } - - img.resize(width,height); - - Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); - - ptex->create_from_image(img,0); - return ptex; - -} - -EditorTexturePreviewPlugin::EditorTexturePreviewPlugin() { - - -} - -//////////////////////////////////////////////////////////////////////////// - -bool EditorBitmapPreviewPlugin::handles(const String& p_type) const { - - return ClassDB::is_type(p_type,"BitMap"); -} - -Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES& p_from) { - - Ref<BitMap> bm =p_from; - - if (bm->get_size()==Size2()) { - return Ref<Texture>(); - } - - PoolVector<uint8_t> data; - - data.resize(bm->get_size().width*bm->get_size().height); - - { - PoolVector<uint8_t>::Write w=data.write(); - - for(int i=0;i<bm->get_size().width;i++) { - for(int j=0;j<bm->get_size().height;j++) { - if (bm->get_bit(Point2i(i,j))) { - w[j*bm->get_size().width+i]=255; - } else { - w[j*bm->get_size().width+i]=0; - - } - } - - } - } - - - Image img(bm->get_size().width,bm->get_size().height,0,Image::FORMAT_L8,data); - - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size*=EDSCALE; - if (img.is_compressed()) { - if (img.decompress()!=OK) - return Ref<Texture>(); - } else if (img.get_format()!=Image::FORMAT_RGB8 && img.get_format()!=Image::FORMAT_RGBA8) { - img.convert(Image::FORMAT_RGBA8); - } - - int width,height; - if (img.get_width() > thumbnail_size && img.get_width() >= img.get_height()) { - - width=thumbnail_size; - height = img.get_height() * thumbnail_size / img.get_width(); - } else if (img.get_height() > thumbnail_size && img.get_height() >= img.get_width()) { - - height=thumbnail_size; - width = img.get_width() * thumbnail_size / img.get_height(); - } else { - - width=img.get_width(); - height=img.get_height(); - } - - img.resize(width,height); - - Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); - - ptex->create_from_image(img,0); - return ptex; - -} - -EditorBitmapPreviewPlugin::EditorBitmapPreviewPlugin() { - - -} - -/////////////////////////////////////////////////////////////////////////// - - -Ref<Texture> EditorPackedScenePreviewPlugin::_gen_from_imd(Ref<ResourceImportMetadata> p_imd) { - - if (p_imd.is_null()) { - return Ref<Texture>(); - } - - if (!p_imd->has_option("thumbnail")) - return Ref<Texture>(); - - Variant tn = p_imd->get_option("thumbnail"); - //print_line(Variant::get_type_name(tn.get_type())); - PoolVector<uint8_t> thumbnail = tn; - - int len = thumbnail.size(); - if (len==0) - return Ref<Texture>(); - - - PoolVector<uint8_t>::Read r = thumbnail.read(); - - Image img(r.ptr(),len); - if (img.empty()) - return Ref<Texture>(); - - Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); - ptex->create_from_image(img,0); - return ptex; - -} - -bool EditorPackedScenePreviewPlugin::handles(const String& p_type) const { - - return ClassDB::is_type(p_type,"PackedScene"); -} -Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES& p_from) { - - Ref<ResourceImportMetadata> imd = p_from->get_import_metadata(); - return _gen_from_imd(imd); -} - -Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String& p_path) { - - Ref<ResourceImportMetadata> imd = ResourceLoader::load_import_metadata(p_path); - return _gen_from_imd(imd); -} - -EditorPackedScenePreviewPlugin::EditorPackedScenePreviewPlugin() { - -} - -////////////////////////////////////////////////////////////////// - -bool EditorMaterialPreviewPlugin::handles(const String& p_type) const { - - return ClassDB::is_type(p_type,"Material"); //any material -} - -Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES& p_from) { - - Ref<Material> material = p_from; - ERR_FAIL_COND_V(material.is_null(),Ref<Texture>()); - - VS::get_singleton()->mesh_surface_set_material(sphere,0,material->get_rid()); - - VS::get_singleton()->viewport_queue_screen_capture(viewport); - VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_ONCE); //once used for capture - //print_line("queue capture!"); - Image img; - - int timeout=1000; - while(timeout) { - //print_line("try capture?"); - OS::get_singleton()->delay_usec(10); - img = VS::get_singleton()->viewport_get_screen_capture(viewport); - if (!img.empty()) - break; - timeout--; - } - - //print_line("captured!"); - VS::get_singleton()->mesh_surface_set_material(sphere,0,RID()); - - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size*=EDSCALE; - img.resize(thumbnail_size,thumbnail_size); - - Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); - ptex->create_from_image(img,0); - return ptex; -} - -EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() { - - scenario = VS::get_singleton()->scenario_create(); - - viewport = VS::get_singleton()->viewport_create(); - VS::get_singleton()->viewport_set_as_render_target(viewport,true); - VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_DISABLED); - VS::get_singleton()->viewport_set_scenario(viewport,scenario); - VS::ViewportRect vr; - vr.x=0; - vr.y=0; - vr.width=128; - vr.height=128; - VS::get_singleton()->viewport_set_rect(viewport,vr); - - camera = VS::get_singleton()->camera_create(); - VS::get_singleton()->viewport_attach_camera(viewport,camera); - VS::get_singleton()->camera_set_transform(camera,Transform(Matrix3(),Vector3(0,0,3))); - VS::get_singleton()->camera_set_perspective(camera,45,0.1,10); - - light = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); - light_instance = VS::get_singleton()->instance_create2(light,scenario); - VS::get_singleton()->instance_set_transform(light_instance,Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0))); - - light2 = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); - VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_DIFFUSE,Color(0.7,0.7,0.7)); - VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_SPECULAR,Color(0.0,0.0,0.0)); - light_instance2 = VS::get_singleton()->instance_create2(light2,scenario); - - VS::get_singleton()->instance_set_transform(light_instance2,Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1))); - - sphere = VS::get_singleton()->mesh_create(); - sphere_instance = VS::get_singleton()->instance_create2(sphere,scenario); - - int lats=32; - int lons=32; - float radius=1.0; - - PoolVector<Vector3> vertices; - PoolVector<Vector3> normals; - PoolVector<Vector2> uvs; - PoolVector<float> tangents; - Matrix3 tt = Matrix3(Vector3(0,1,0),Math_PI*0.5); - - for(int i = 1; i <= lats; i++) { - double lat0 = Math_PI * (-0.5 + (double) (i - 1) / lats); - double z0 = Math::sin(lat0); - double zr0 = Math::cos(lat0); - - double lat1 = Math_PI * (-0.5 + (double) i / lats); - double z1 = Math::sin(lat1); - double zr1 = Math::cos(lat1); - - for(int j = lons; j >= 1; j--) { - - double lng0 = 2 * Math_PI * (double) (j - 1) / lons; - double x0 = Math::cos(lng0); - double y0 = Math::sin(lng0); - - double lng1 = 2 * Math_PI * (double) (j) / lons; - double x1 = Math::cos(lng1); - double y1 = Math::sin(lng1); - - - Vector3 v[4]={ - Vector3(x1 * zr0, z0, y1 *zr0), - Vector3(x1 * zr1, z1, y1 *zr1), - Vector3(x0 * zr1, z1, y0 *zr1), - Vector3(x0 * zr0, z0, y0 *zr0) - }; - -#define ADD_POINT(m_idx) \ - normals.push_back(v[m_idx]);\ - vertices.push_back(v[m_idx]*radius);\ - { Vector2 uv(Math::atan2(v[m_idx].x,v[m_idx].z),Math::atan2(-v[m_idx].y,v[m_idx].z));\ - uv/=Math_PI;\ - uv*=4.0;\ - uv=uv*0.5+Vector2(0.5,0.5);\ - uvs.push_back(uv);\ - }\ - { Vector3 t = tt.xform(v[m_idx]);\ - tangents.push_back(t.x);\ - tangents.push_back(t.y);\ - tangents.push_back(t.z);\ - tangents.push_back(1.0);\ - } - - - - ADD_POINT(0); - ADD_POINT(1); - ADD_POINT(2); - - ADD_POINT(2); - ADD_POINT(3); - ADD_POINT(0); - } - } - - Array arr; - arr.resize(VS::ARRAY_MAX); - arr[VS::ARRAY_VERTEX]=vertices; - arr[VS::ARRAY_NORMAL]=normals; - arr[VS::ARRAY_TANGENT]=tangents; - arr[VS::ARRAY_TEX_UV]=uvs; - VS::get_singleton()->mesh_add_surface(sphere,VS::PRIMITIVE_TRIANGLES,arr); - -} - -EditorMaterialPreviewPlugin::~EditorMaterialPreviewPlugin() { - - VS::get_singleton()->free(sphere); - VS::get_singleton()->free(sphere_instance); - VS::get_singleton()->free(viewport); - VS::get_singleton()->free(light); - VS::get_singleton()->free(light_instance); - VS::get_singleton()->free(light2); - VS::get_singleton()->free(light_instance2); - VS::get_singleton()->free(camera); - VS::get_singleton()->free(scenario); - -} - -/////////////////////////////////////////////////////////////////////////// - -static bool _is_text_char(CharType c) { - - return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_'; -} - -bool EditorScriptPreviewPlugin::handles(const String& p_type) const { - - return ClassDB::is_type(p_type,"Script"); -} - -Ref<Texture> EditorScriptPreviewPlugin::generate(const RES& p_from) { - - - Ref<Script> scr = p_from; - if (scr.is_null()) - return Ref<Texture>(); - - String code = scr->get_source_code().strip_edges(); - if (code=="") - return Ref<Texture>(); - - List<String> kwors; - scr->get_language()->get_reserved_words(&kwors); - - Set<String> keywords; - - for(List<String>::Element *E=kwors.front();E;E=E->next()) { - - keywords.insert(E->get()); - - } - - - int line = 0; - int col=0; - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size*=EDSCALE; - Image img(thumbnail_size,thumbnail_size,0,Image::FORMAT_RGBA8); - - - - Color bg_color = EditorSettings::get_singleton()->get("text_editor/highlighting/background_color"); - bg_color.a=1.0; - Color keyword_color = EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"); - Color text_color = EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"); - Color symbol_color = EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"); - - - for(int i=0;i<thumbnail_size;i++) { - for(int j=0;j<thumbnail_size;j++) { - img.put_pixel(i,j,bg_color); - } - - } - - bool prev_is_text=false; - bool in_keyword=false; - for(int i=0;i<code.length();i++) { - - CharType c = code[i]; - if (c>32) { - if (col<thumbnail_size) { - Color color = text_color; - - if (c!='_' && ((c>='!' && c<='/') || (c>=':' && c<='@') || (c>='[' && c<='`') || (c>='{' && c<='~') || c=='\t')) { - //make symbol a little visible - color=symbol_color; - in_keyword=false; - } else if (!prev_is_text && _is_text_char(c)) { - int pos = i; - - while(_is_text_char(code[pos])) { - pos++; - } - ///print_line("from "+itos(i)+" to "+itos(pos)); - String word = code.substr(i,pos-i); - //print_line("found word: "+word); - if (keywords.has(word)) - in_keyword=true; - - } else if (!_is_text_char(c)) { - in_keyword=false; - } - - if (in_keyword) - color=keyword_color; - - Color ul=color; - ul.a*=0.5; - img.put_pixel(col,line*2,bg_color.blend(ul)); - img.put_pixel(col,line*2+1,color); - - prev_is_text=_is_text_char(c); - } - } else { - - prev_is_text=false; - in_keyword=false; - - if (c=='\n') { - col=0; - line++; - if (line>=thumbnail_size/2) - break; - } else if (c=='\t') { - col+=3; - } - } - col++; - } - - Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture)); - - ptex->create_from_image(img,0); - return ptex; - -} - -EditorScriptPreviewPlugin::EditorScriptPreviewPlugin() { - - -} -/////////////////////////////////////////////////////////////////// -#if 0 -bool EditorSamplePreviewPlugin::handles(const String& p_type) const { - - return ClassDB::is_type(p_type,"Sample"); -} - -Ref<Texture> EditorSamplePreviewPlugin::generate(const RES& p_from) { - - Ref<Sample> smp =p_from; - ERR_FAIL_COND_V(smp.is_null(),Ref<Texture>()); - - - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size*=EDSCALE; - PoolVector<uint8_t> img; - int w = thumbnail_size; - int h = thumbnail_size; - img.resize(w*h*3); - - PoolVector<uint8_t>::Write imgdata = img.write(); - uint8_t * imgw = imgdata.ptr(); - PoolVector<uint8_t> data = smp->get_data(); - PoolVector<uint8_t>::Read sampledata = data.read(); - const uint8_t *sdata=sampledata.ptr(); - - bool stereo = smp->is_stereo(); - bool _16=smp->get_format()==Sample::FORMAT_PCM16; - int len = smp->get_length(); - - if (len<1) - return Ref<Texture>(); - - if (smp->get_format()==Sample::FORMAT_IMA_ADPCM) { - - struct IMA_ADPCM_State { - - int16_t step_index; - int32_t predictor; - /* values at loop point */ - int16_t loop_step_index; - int32_t loop_predictor; - int32_t last_nibble; - int32_t loop_pos; - int32_t window_ofs; - const uint8_t *ptr; - } ima_adpcm; - - ima_adpcm.step_index=0; - ima_adpcm.predictor=0; - ima_adpcm.loop_step_index=0; - ima_adpcm.loop_predictor=0; - ima_adpcm.last_nibble=-1; - ima_adpcm.loop_pos=0x7FFFFFFF; - ima_adpcm.window_ofs=0; - ima_adpcm.ptr=NULL; - - - for(int i=0;i<w;i++) { - - float max[2]={-1e10,-1e10}; - float min[2]={1e10,1e10}; - int from = i*len/w; - int to = (i+1)*len/w; - if (to>=len) - to=len-1; - - for(int j=from;j<to;j++) { - - while(j>ima_adpcm.last_nibble) { - - static const int16_t _ima_adpcm_step_table[89] = { - 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, - 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, - 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, - 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, - 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, - 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, - 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, - 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 - }; - - static const int8_t _ima_adpcm_index_table[16] = { - -1, -1, -1, -1, 2, 4, 6, 8, - -1, -1, -1, -1, 2, 4, 6, 8 - }; - - int16_t nibble,diff,step; - - ima_adpcm.last_nibble++; - const uint8_t *src_ptr=sdata; - - int ofs = ima_adpcm.last_nibble>>1; - - if (stereo) - ofs*=2; - - - nibble = (ima_adpcm.last_nibble&1)? - (src_ptr[ofs]>>4):(src_ptr[ofs]&0xF); - step=_ima_adpcm_step_table[ima_adpcm.step_index]; - - ima_adpcm.step_index += _ima_adpcm_index_table[nibble]; - if (ima_adpcm.step_index<0) - ima_adpcm.step_index=0; - if (ima_adpcm.step_index>88) - ima_adpcm.step_index=88; - - diff = step >> 3 ; - if (nibble & 1) - diff += step >> 2 ; - if (nibble & 2) - diff += step >> 1 ; - if (nibble & 4) - diff += step ; - if (nibble & 8) - diff = -diff ; - - ima_adpcm.predictor+=diff; - if (ima_adpcm.predictor<-0x8000) - ima_adpcm.predictor=-0x8000; - else if (ima_adpcm.predictor>0x7FFF) - ima_adpcm.predictor=0x7FFF; - - - /* store loop if there */ - if (ima_adpcm.last_nibble==ima_adpcm.loop_pos) { - - ima_adpcm.loop_step_index = ima_adpcm.step_index; - ima_adpcm.loop_predictor = ima_adpcm.predictor; - } - - } - - float v=ima_adpcm.predictor/32767.0; - if (v>max[0]) - max[0]=v; - if (v<min[0]) - min[0]=v; - } - max[0]*=0.8; - min[0]*=0.8; - - for(int j=0;j<h;j++) { - float v = (j/(float)h) * 2.0 - 1.0; - uint8_t* imgofs = &imgw[(uint64_t(j)*w+i)*3]; - if (v>min[0] && v<max[0]) { - imgofs[0]=255; - imgofs[1]=150; - imgofs[2]=80; - } else { - imgofs[0]=0; - imgofs[1]=0; - imgofs[2]=0; - } - } - } - } else { - for(int i=0;i<w;i++) { - // i trust gcc will optimize this loop - float max[2]={-1e10,-1e10}; - float min[2]={1e10,1e10}; - int c=stereo?2:1; - int from = uint64_t(i)*len/w; - int to = (uint64_t(i)+1)*len/w; - if (to>=len) - to=len-1; - - if (_16) { - const int16_t*src =(const int16_t*)sdata; - - for(int j=0;j<c;j++) { - - for(int k=from;k<=to;k++) { - - float v = src[uint64_t(k)*c+j]/32768.0; - if (v>max[j]) - max[j]=v; - if (v<min[j]) - min[j]=v; - } - - } - } else { - - const int8_t*src =(const int8_t*)sdata; - - for(int j=0;j<c;j++) { - - for(int k=from;k<=to;k++) { - - float v = src[uint64_t(k)*c+j]/128.0; - if (v>max[j]) - max[j]=v; - if (v<min[j]) - min[j]=v; - } - - } - } - - max[0]*=0.8; - max[1]*=0.8; - min[0]*=0.8; - min[1]*=0.8; - - if (!stereo) { - for(int j=0;j<h;j++) { - float v = (j/(float)h) * 2.0 - 1.0; - uint8_t* imgofs = &imgw[(j*w+i)*3]; - if (v>min[0] && v<max[0]) { - imgofs[0]=255; - imgofs[1]=150; - imgofs[2]=80; - } else { - imgofs[0]=0; - imgofs[1]=0; - imgofs[2]=0; - } - } - } else { - - for(int j=0;j<h;j++) { - - int half; - float v; - if (j<(h/2)) { - half=0; - v = (j/(float)(h/2)) * 2.0 - 1.0; - } else { - half=1; - if( (float)(h/2) != 0 ) { - v = ((j-(h/2))/(float)(h/2)) * 2.0 - 1.0; - } else { - v = ((j-(h/2))/(float)(1/2)) * 2.0 - 1.0; - } - } - - uint8_t* imgofs = &imgw[(j*w+i)*3]; - if (v>min[half] && v<max[half]) { - imgofs[0]=255; - imgofs[1]=150; - imgofs[2]=80; - } else { - imgofs[0]=0; - imgofs[1]=0; - imgofs[2]=0; - } - } - - } - - } - } - - imgdata = PoolVector<uint8_t>::Write(); - - Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture)); - ptex->create_from_image(Image(w,h,0,Image::FORMAT_RGB8,img),0); - return ptex; - -} - -EditorSamplePreviewPlugin::EditorSamplePreviewPlugin() { - - -} -#endif -/////////////////////////////////////////////////////////////////////////// - -bool EditorMeshPreviewPlugin::handles(const String& p_type) const { - - return ClassDB::is_type(p_type,"Mesh"); //any Mesh -} - -Ref<Texture> EditorMeshPreviewPlugin::generate(const RES& p_from) { - - Ref<Mesh> mesh = p_from; - ERR_FAIL_COND_V(mesh.is_null(),Ref<Texture>()); - - VS::get_singleton()->instance_set_base(mesh_instance,mesh->get_rid()); - - AABB aabb= mesh->get_aabb(); - Vector3 ofs = aabb.pos + aabb.size*0.5; - aabb.pos-=ofs; - Transform xform; - xform.basis=Matrix3().rotated(Vector3(0,1,0),-Math_PI*0.125); - xform.basis = Matrix3().rotated(Vector3(1,0,0),Math_PI*0.125)*xform.basis; - AABB rot_aabb = xform.xform(aabb); - float m = MAX(rot_aabb.size.x,rot_aabb.size.y)*0.5; - if (m==0) - return Ref<Texture>(); - m=1.0/m; - m*=0.5; - //print_line("scale: "+rtos(m)); - xform.basis.scale(Vector3(m,m,m)); - xform.origin=-xform.basis.xform(ofs); //-ofs*m; - xform.origin.z-=rot_aabb.size.z*2; - VS::get_singleton()->instance_set_transform(mesh_instance,xform); - - - - VS::get_singleton()->viewport_queue_screen_capture(viewport); - VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_ONCE); //once used for capture - //print_line("queue capture!"); - Image img; - - int timeout=1000; - while(timeout) { - //print_line("try capture?"); - OS::get_singleton()->delay_usec(10); - img = VS::get_singleton()->viewport_get_screen_capture(viewport); - if (!img.empty()) - break; - timeout--; - } - - //print_line("captured!"); - VS::get_singleton()->instance_set_base(mesh_instance,RID()); - - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size*=EDSCALE; - img.resize(thumbnail_size,thumbnail_size); - - Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture )); - ptex->create_from_image(img,0); - return ptex; -} - -EditorMeshPreviewPlugin::EditorMeshPreviewPlugin() { - - scenario = VS::get_singleton()->scenario_create(); - viewport = VS::get_singleton()->viewport_create(); - VS::get_singleton()->viewport_set_as_render_target(viewport,true); - VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_DISABLED); - VS::get_singleton()->viewport_set_scenario(viewport,scenario); - VS::ViewportRect vr; - vr.x=0; - vr.y=0; - vr.width=128; - vr.height=128; - VS::get_singleton()->viewport_set_rect(viewport,vr); - - camera = VS::get_singleton()->camera_create(); - VS::get_singleton()->viewport_attach_camera(viewport,camera); - VS::get_singleton()->camera_set_transform(camera,Transform(Matrix3(),Vector3(0,0,3))); - //VS::get_singleton()->camera_set_perspective(camera,45,0.1,10); - VS::get_singleton()->camera_set_orthogonal(camera,1.0,0.01,1000.0); - - light = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); - light_instance = VS::get_singleton()->instance_create2(light,scenario); - VS::get_singleton()->instance_set_transform(light_instance,Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0))); - - light2 = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL); - VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_DIFFUSE,Color(0.7,0.7,0.7)); - VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_SPECULAR,Color(0.0,0.0,0.0)); - light_instance2 = VS::get_singleton()->instance_create2(light2,scenario); - - VS::get_singleton()->instance_set_transform(light_instance2,Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1))); - - //sphere = VS::get_singleton()->mesh_create(); - mesh_instance = VS::get_singleton()->instance_create(); - VS::get_singleton()->instance_set_scenario(mesh_instance,scenario); - - - -} - - -EditorMeshPreviewPlugin::~EditorMeshPreviewPlugin() { - - //VS::get_singleton()->free(sphere); - VS::get_singleton()->free(mesh_instance); - VS::get_singleton()->free(viewport); - VS::get_singleton()->free(light); - VS::get_singleton()->free(light_instance); - VS::get_singleton()->free(light2); - VS::get_singleton()->free(light_instance2); - VS::get_singleton()->free(camera); - VS::get_singleton()->free(scenario); - -} -#endif diff --git a/tools/editor/plugins/editor_preview_plugins.h b/tools/editor/plugins/editor_preview_plugins.h deleted file mode 100644 index 078e4cf8b5..0000000000 --- a/tools/editor/plugins/editor_preview_plugins.h +++ /dev/null @@ -1,128 +0,0 @@ -/*************************************************************************/ -/* editor_preview_plugins.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef EDITORPREVIEWPLUGINS_H -#define EDITORPREVIEWPLUGINS_H - -#include "tools/editor/editor_resource_preview.h" - -#if 0 -class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator { -public: - - virtual bool handles(const String& p_type) const; - virtual Ref<Texture> generate(const RES& p_from); - - EditorTexturePreviewPlugin(); -}; - - -class EditorBitmapPreviewPlugin : public EditorResourcePreviewGenerator { -public: - - virtual bool handles(const String& p_type) const; - virtual Ref<Texture> generate(const RES& p_from); - - EditorBitmapPreviewPlugin(); -}; - - - -class EditorPackedScenePreviewPlugin : public EditorResourcePreviewGenerator { - - Ref<Texture> _gen_from_imd(Ref<ResourceImportMetadata> p_imd); -public: - - virtual bool handles(const String& p_type) const; - virtual Ref<Texture> generate(const RES& p_from); - virtual Ref<Texture> generate_from_path(const String& p_path); - - EditorPackedScenePreviewPlugin(); -}; - -class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator { - - RID scenario; - RID sphere; - RID sphere_instance; - RID viewport; - RID light; - RID light_instance; - RID light2; - RID light_instance2; - RID camera; -public: - - virtual bool handles(const String& p_type) const; - virtual Ref<Texture> generate(const RES& p_from); - - EditorMaterialPreviewPlugin(); - ~EditorMaterialPreviewPlugin(); -}; - -class EditorScriptPreviewPlugin : public EditorResourcePreviewGenerator { -public: - - virtual bool handles(const String& p_type) const; - virtual Ref<Texture> generate(const RES& p_from); - - EditorScriptPreviewPlugin(); -}; - -#if 0 -class EditorSamplePreviewPlugin : public EditorResourcePreviewGenerator { -public: - - virtual bool handles(const String& p_type) const; - virtual Ref<Texture> generate(const RES& p_from); - - EditorSamplePreviewPlugin(); -}; - -#endif -class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator { - - RID scenario; - RID mesh_instance; - RID viewport; - RID light; - RID light_instance; - RID light2; - RID light_instance2; - RID camera; -public: - - virtual bool handles(const String& p_type) const; - virtual Ref<Texture> generate(const RES& p_from); - - EditorMeshPreviewPlugin(); - ~EditorMeshPreviewPlugin(); -}; - -#endif -#endif // EDITORPREVIEWPLUGINS_H diff --git a/tools/editor/plugins/gi_probe_editor_plugin.h b/tools/editor/plugins/gi_probe_editor_plugin.h deleted file mode 100644 index 35e0b93aae..0000000000 --- a/tools/editor/plugins/gi_probe_editor_plugin.h +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************/ -/* gi_probe_editor_plugin.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. */ -/*************************************************************************/ -#ifndef GIPROBEEDITORPLUGIN_H -#define GIPROBEEDITORPLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/resources/material.h" -#include "scene/3d/gi_probe.h" - - - -class GIProbeEditorPlugin : public EditorPlugin { - - GDCLASS( GIProbeEditorPlugin, EditorPlugin ); - - GIProbe *gi_probe; - - Button *bake; - EditorNode *editor; - - void _bake(); -protected: - - static void _bind_methods(); -public: - - virtual String get_name() const { return "GIProbe"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - GIProbeEditorPlugin(EditorNode *p_node); - ~GIProbeEditorPlugin(); - -}; - -#endif // GIPROBEEDITORPLUGIN_H diff --git a/tools/editor/plugins/item_list_editor_plugin.h b/tools/editor/plugins/item_list_editor_plugin.h deleted file mode 100644 index 74700d615e..0000000000 --- a/tools/editor/plugins/item_list_editor_plugin.h +++ /dev/null @@ -1,230 +0,0 @@ -/*************************************************************************/ -/* item_list_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef ITEM_LIST_EDITOR_PLUGIN_H -#define ITEM_LIST_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "canvas_item_editor_plugin.h" - -#include "scene/gui/option_button.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/popup_menu.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - - -class ItemListPlugin : public Object { - - GDCLASS(ItemListPlugin,Object); - -protected: - - bool _set(const StringName& p_name, const Variant& p_value); - bool _get(const StringName& p_name,Variant &r_ret) const; - void _get_property_list( List<PropertyInfo> *p_list) const; - -public: - - enum Flags { - - FLAG_ICON=1, - FLAG_CHECKABLE=2, - FLAG_ID=4, - FLAG_ENABLE=8, - FLAG_SEPARATOR=16 - }; - - virtual void set_object(Object *p_object)=0; - virtual bool handles(Object *p_object) const=0; - - virtual int get_flags() const=0; - - virtual void set_item_text(int p_idx, const String& p_text) {} - virtual String get_item_text(int p_idx) const{ return ""; }; - - virtual void set_item_icon(int p_idx, const Ref<Texture>& p_tex) {} - virtual Ref<Texture> get_item_icon(int p_idx) const{ return Ref<Texture>(); }; - - virtual void set_item_checkable(int p_idx, bool p_check) {} - virtual bool is_item_checkable(int p_idx) const{ return false; }; - - virtual void set_item_checked(int p_idx, bool p_checked) {} - virtual bool is_item_checked(int p_idx) const{ return false; }; - - virtual void set_item_enabled(int p_idx, int p_enabled) {} - virtual bool is_item_enabled(int p_idx) const{ return false; }; - - virtual void set_item_id(int p_idx, int p_id) {} - virtual int get_item_id(int p_idx) const{ return -1; }; - - virtual void set_item_separator(int p_idx, bool p_separator) {} - virtual bool is_item_separator(int p_idx) const { return false; }; - - virtual void add_item()=0; - virtual int get_item_count() const=0; - virtual void erase(int p_idx)=0; - - ItemListPlugin() {} -}; - -/////////////////////////////////////////////////////////////// - -class ItemListOptionButtonPlugin : public ItemListPlugin { - - GDCLASS(ItemListOptionButtonPlugin,ItemListPlugin); - - OptionButton *ob; -public: - - virtual void set_object(Object *p_object); - virtual bool handles(Object *p_object) const; - virtual int get_flags() const; - - virtual void set_item_text(int p_idx, const String& p_text) { ob->set_item_text(p_idx,p_text); } - virtual String get_item_text(int p_idx) const { return ob->get_item_text(p_idx); } - - virtual void set_item_icon(int p_idx, const Ref<Texture>& p_tex) { ob->set_item_icon(p_idx, p_tex); } - virtual Ref<Texture> get_item_icon(int p_idx) const { return ob->get_item_icon(p_idx); } - - virtual void set_item_enabled(int p_idx, int p_enabled) { ob->set_item_disabled(p_idx, !p_enabled); } - virtual bool is_item_enabled(int p_idx) const { return !ob->is_item_disabled(p_idx); } - - virtual void set_item_id(int p_idx, int p_id) { ob->set_item_ID(p_idx,p_id); } - virtual int get_item_id(int p_idx) const { return ob->get_item_ID(p_idx); } - - virtual void add_item(); - virtual int get_item_count() const; - virtual void erase(int p_idx); - - ItemListOptionButtonPlugin(); -}; - -class ItemListPopupMenuPlugin : public ItemListPlugin { - - GDCLASS(ItemListPopupMenuPlugin,ItemListPlugin); - - PopupMenu *pp; -public: - - virtual void set_object(Object *p_object); - virtual bool handles(Object *p_object) const; - virtual int get_flags() const; - - virtual void set_item_text(int p_idx, const String& p_text) { pp->set_item_text(p_idx,p_text); } - virtual String get_item_text(int p_idx) const { return pp->get_item_text(p_idx); } - - virtual void set_item_icon(int p_idx, const Ref<Texture>& p_tex) { pp->set_item_icon(p_idx,p_tex); } - virtual Ref<Texture> get_item_icon(int p_idx) const { return pp->get_item_icon(p_idx); } - - virtual void set_item_checkable(int p_idx, bool p_check) { pp->set_item_as_checkable(p_idx,p_check); } - virtual bool is_item_checkable(int p_idx) const { return pp->is_item_checkable(p_idx); } - - virtual void set_item_checked(int p_idx, bool p_checked) { pp->set_item_checked(p_idx,p_checked); } - virtual bool is_item_checked(int p_idx) const { return pp->is_item_checked(p_idx); } - - virtual void set_item_enabled(int p_idx, int p_enabled) { pp->set_item_disabled(p_idx,!p_enabled); } - virtual bool is_item_enabled(int p_idx) const { return !pp->is_item_disabled(p_idx); } - - virtual void set_item_id(int p_idx, int p_id) { pp->set_item_ID(p_idx,p_idx); } - virtual int get_item_id(int p_idx) const { return pp->get_item_ID(p_idx); } - - virtual void set_item_separator(int p_idx, bool p_separator) { pp->set_item_as_separator(p_idx,p_separator); } - virtual bool is_item_separator(int p_idx) const { return pp->is_item_separator(p_idx); } - - virtual void add_item(); - virtual int get_item_count() const; - virtual void erase(int p_idx); - - ItemListPopupMenuPlugin(); -}; - -/////////////////////////////////////////////////////////////// - -class ItemListEditor : public HBoxContainer { - - GDCLASS(ItemListEditor,HBoxContainer); - - Node *item_list; - - ToolButton *toolbar_button; - - AcceptDialog *dialog; - PropertyEditor *property_editor; - Tree *tree; - Button *add_button; - Button *del_button; - - int selected_idx; - - Vector<ItemListPlugin*> item_plugins; - - void _edit_items(); - - void _add_pressed(); - void _delete_pressed(); - - void _node_removed(Node *p_node); - -protected: - - void _notification(int p_notification); - static void _bind_methods(); -public: - - void edit(Node *p_item_list); - bool handles(Object *p_object) const; - void add_plugin(ItemListPlugin* p_plugin) { item_plugins.push_back(p_plugin); } - ItemListEditor(); - ~ItemListEditor(); -}; - -class ItemListEditorPlugin : public EditorPlugin { - - GDCLASS(ItemListEditorPlugin,EditorPlugin); - - ItemListEditor *item_list_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "ItemList"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - ItemListEditorPlugin(EditorNode *p_node); - ~ItemListEditorPlugin(); - -}; - -#endif // ITEM_LIST_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp b/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp deleted file mode 100644 index cc8bb63d78..0000000000 --- a/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp +++ /dev/null @@ -1,518 +0,0 @@ -/*************************************************************************/ -/* light_occluder_2d_editor_plugin.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 "light_occluder_2d_editor_plugin.h" - -#include "canvas_item_editor_plugin.h" -#include "os/file_access.h" -#include "tools/editor/editor_settings.h" - -void LightOccluder2DEditor::_notification(int p_what) { - - switch(p_what) { - - case NOTIFICATION_READY: { - - button_create->set_icon( get_icon("Edit","EditorIcons")); - button_edit->set_icon( get_icon("MovePoint","EditorIcons")); - button_edit->set_pressed(true); - get_tree()->connect("node_removed",this,"_node_removed"); - create_poly->connect("confirmed",this,"_create_poly"); - - } break; - case NOTIFICATION_FIXED_PROCESS: { - - - } break; - } - -} -void LightOccluder2DEditor::_node_removed(Node *p_node) { - - if(p_node==node) { - node=NULL; - hide(); - canvas_item_editor->get_viewport_control()->update(); - } - -} - - -void LightOccluder2DEditor::_menu_option(int p_option) { - - switch(p_option) { - - case MODE_CREATE: { - - mode=MODE_CREATE; - button_create->set_pressed(true); - button_edit->set_pressed(false); - } break; - case MODE_EDIT: { - - mode=MODE_EDIT; - button_create->set_pressed(false); - button_edit->set_pressed(true); - } break; - - } -} - -void LightOccluder2DEditor::_wip_close(bool p_closed) { - - undo_redo->create_action(TTR("Create Poly")); - undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",node->get_occluder_polygon()->get_polygon()); - undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",wip); - undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_closed",node->get_occluder_polygon()->is_closed()); - undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_closed",p_closed); - - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - wip.clear(); - wip_active=false; - mode=MODE_EDIT; - button_edit->set_pressed(true); - button_create->set_pressed(false); - edited_point=-1; -} - -bool LightOccluder2DEditor::forward_gui_input(const InputEvent& p_event) { - - - if (!node) - return false; - - if (node->get_occluder_polygon().is_null()) { - if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { - create_poly->set_text("No OccluderPolygon2D resource on this node.\nCreate and assign one?"); - create_poly->popup_centered_minsize(); - } - return (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1); - } - switch(p_event.type) { - - case InputEvent::MOUSE_BUTTON: { - - const InputEventMouseButton &mb=p_event.mouse_button; - - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - - - Vector2 gpoint = Point2(mb.x,mb.y); - Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); - cpoint=canvas_item_editor->snap_point(cpoint); - cpoint = node->get_global_transform().affine_inverse().xform(cpoint); - - Vector<Vector2> poly = Variant(node->get_occluder_polygon()->get_polygon()); - - //first check if a point is to be added (segment split) - real_t grab_treshold=EDITOR_DEF("editors/poly_editor/point_grab_radius",8); - - switch(mode) { - - - case MODE_CREATE: { - - if (mb.button_index==BUTTON_LEFT && mb.pressed) { - - - if (!wip_active) { - - wip.clear(); - wip.push_back( cpoint ); - wip_active=true; - edited_point_pos=cpoint; - canvas_item_editor->get_viewport_control()->update(); - edited_point=1; - return true; - } else { - - - if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) { - //wip closed - _wip_close(true); - - return true; - } else if (wip.size()>1 && xform.xform(wip[wip.size()-1]).distance_to(gpoint)<grab_treshold) { - //wip closed - _wip_close(false); - return true; - - } else { - - wip.push_back( cpoint ); - edited_point=wip.size(); - canvas_item_editor->get_viewport_control()->update(); - return true; - - //add wip point - } - } - } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { - _wip_close(true); - } - - - - } break; - - case MODE_EDIT: { - - if (mb.button_index==BUTTON_LEFT) { - if (mb.pressed) { - - if (mb.mod.control) { - - - if (poly.size() < 3) { - - undo_redo->create_action(TTR("Edit Poly")); - undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); - poly.push_back(cpoint); - undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - return true; - } - - //search edges - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 points[2] ={ xform.xform(poly[i]), - xform.xform(poly[(i+1)%poly.size()]) }; - - Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points); - if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2) - continue; //not valid to reuse point - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - - } - - if (closest_idx>=0) { - - pre_move_edit=poly; - poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos)); - edited_point=closest_idx+1; - edited_point_pos=xform.affine_inverse().xform(closest_pos); - node->get_occluder_polygon()->set_polygon(Variant(poly)); - canvas_item_editor->get_viewport_control()->update(); - return true; - } - } else { - - //look for points to move - - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 cp =xform.xform(poly[i]); - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - } - - if (closest_idx>=0) { - - pre_move_edit=poly; - edited_point=closest_idx; - edited_point_pos=xform.affine_inverse().xform(closest_pos); - canvas_item_editor->get_viewport_control()->update(); - return true; - } - } - } else { - - if (edited_point!=-1) { - - //apply - - ERR_FAIL_INDEX_V(edited_point,poly.size(),false); - poly[edited_point]=edited_point_pos; - undo_redo->create_action(TTR("Edit Poly")); - undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); - undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",pre_move_edit); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - - edited_point=-1; - return true; - } - } - } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { - - - - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 cp =xform.xform(poly[i]); - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - } - - if (closest_idx>=0) { - - - undo_redo->create_action(TTR("Edit Poly (Remove Point)")); - undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); - poly.remove(closest_idx); - undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - return true; - } - - } - - - - } break; - } - - - - } break; - case InputEvent::MOUSE_MOTION: { - - const InputEventMouseMotion &mm=p_event.mouse_motion; - - if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { - - Vector2 gpoint = Point2(mm.x,mm.y); - Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); - cpoint=canvas_item_editor->snap_point(cpoint); - edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint); - - canvas_item_editor->get_viewport_control()->update(); - - } - - } break; - } - - return false; -} -void LightOccluder2DEditor::_canvas_draw() { - - if (!node || !node->get_occluder_polygon().is_valid()) - return; - - Control *vpc = canvas_item_editor->get_viewport_control(); - - Vector<Vector2> poly; - - if (wip_active) - poly=wip; - else - poly=Variant(node->get_occluder_polygon()->get_polygon()); - - - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - Ref<Texture> handle= get_icon("EditorHandle","EditorIcons"); - - for(int i=0;i<poly.size();i++) { - - - Vector2 p,p2; - p = i==edited_point ? edited_point_pos : poly[i]; - if ((wip_active && i==poly.size()-1) || (((i+1)%poly.size())==edited_point)) - p2=edited_point_pos; - else - p2 = poly[(i+1)%poly.size()]; - - Vector2 point = xform.xform(p); - Vector2 next_point = xform.xform(p2); - - Color col=Color(1,0.3,0.1,0.8); - - if (i==poly.size()-1 && (!node->get_occluder_polygon()->is_closed() || wip_active)) { - - } else { - vpc->draw_line(point,next_point,col,2); - } - vpc->draw_texture(handle,point-handle->get_size()*0.5); - } -} - - - -void LightOccluder2DEditor::edit(Node *p_collision_polygon) { - - if (!canvas_item_editor) { - canvas_item_editor=CanvasItemEditor::get_singleton(); - } - - if (p_collision_polygon) { - - node=p_collision_polygon->cast_to<LightOccluder2D>(); - if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) - canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw"); - wip.clear(); - wip_active=false; - edited_point=-1; - canvas_item_editor->get_viewport_control()->update(); - } else { - node=NULL; - - if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) - canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw"); - - } - -} - -void LightOccluder2DEditor::_create_poly() { - - if (!node) - return; - undo_redo->create_action(TTR("Create Occluder Polygon")); - undo_redo->add_do_method(node,"set_occluder_polygon",Ref<OccluderPolygon2D>(memnew( OccluderPolygon2D))); - undo_redo->add_undo_method(node,"set_occluder_polygon",Variant(REF())); - undo_redo->commit_action(); -} - -void LightOccluder2DEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_menu_option"),&LightOccluder2DEditor::_menu_option); - ClassDB::bind_method(D_METHOD("_canvas_draw"),&LightOccluder2DEditor::_canvas_draw); - ClassDB::bind_method(D_METHOD("_node_removed"),&LightOccluder2DEditor::_node_removed); - ClassDB::bind_method(D_METHOD("_create_poly"),&LightOccluder2DEditor::_create_poly); - -} - - -LightOccluder2DEditor::LightOccluder2DEditor(EditorNode *p_editor) { - - node=NULL; - canvas_item_editor=NULL; - editor=p_editor; - undo_redo = editor->get_undo_redo(); - - add_child( memnew( VSeparator )); - button_create = memnew( ToolButton ); - add_child(button_create); - button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE)); - button_create->set_toggle_mode(true); - button_create->set_tooltip(TTR("Create a new polygon from scratch.")); - - button_edit = memnew( ToolButton ); - add_child(button_edit); - button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT)); - button_edit->set_toggle_mode(true); - button_edit->set_tooltip(TTR("Edit existing polygon:")+"\n"+TTR("LMB: Move Point.")+"\n"+TTR("Ctrl+LMB: Split Segment.")+"\n"+TTR("RMB: Erase Point.")); - - create_poly = memnew( ConfirmationDialog ); - add_child(create_poly); - create_poly->get_ok()->set_text(TTR("Create")); - - - //add_constant_override("separation",0); - -#if 0 - options = memnew( MenuButton ); - add_child(options); - options->set_area_as_parent_rect(); - options->set_text("Polygon"); - //options->get_popup()->add_item("Parse BBCode",PARSE_BBCODE); - options->get_popup()->connect("id_pressed", this,"_menu_option"); -#endif - - mode = MODE_EDIT; - wip_active=false; - -} - - -void LightOccluder2DEditorPlugin::edit(Object *p_object) { - - collision_polygon_editor->edit(p_object->cast_to<Node>()); -} - -bool LightOccluder2DEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("LightOccluder2D"); -} - -void LightOccluder2DEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - collision_polygon_editor->show(); - } else { - - collision_polygon_editor->hide(); - collision_polygon_editor->edit(NULL); - } - -} - -LightOccluder2DEditorPlugin::LightOccluder2DEditorPlugin(EditorNode *p_node) { - - editor=p_node; - collision_polygon_editor = memnew( LightOccluder2DEditor(p_node) ); - CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); - - collision_polygon_editor->hide(); - - - -} - - -LightOccluder2DEditorPlugin::~LightOccluder2DEditorPlugin() -{ -} - diff --git a/tools/editor/plugins/light_occluder_2d_editor_plugin.h b/tools/editor/plugins/light_occluder_2d_editor_plugin.h deleted file mode 100644 index 431c01fe75..0000000000 --- a/tools/editor/plugins/light_occluder_2d_editor_plugin.h +++ /dev/null @@ -1,115 +0,0 @@ -/*************************************************************************/ -/* light_occluder_2d_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H -#define LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H - - - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/2d/light_occluder_2d.h" -#include "scene/gui/tool_button.h" -#include "scene/gui/button_group.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ -class CanvasItemEditor; - -class LightOccluder2DEditor : public HBoxContainer { - - GDCLASS(LightOccluder2DEditor, HBoxContainer ); - - UndoRedo *undo_redo; - enum Mode { - - MODE_CREATE, - MODE_EDIT, - - }; - - Mode mode; - - ToolButton *button_create; - ToolButton *button_edit; - - CanvasItemEditor *canvas_item_editor; - EditorNode *editor; - Panel *panel; - LightOccluder2D *node; - MenuButton *options; - - int edited_point; - Vector2 edited_point_pos; - Vector<Vector2> pre_move_edit; - Vector<Vector2> wip; - bool wip_active; - - ConfirmationDialog *create_poly; - - void _wip_close(bool p_closed); - void _canvas_draw(); - void _menu_option(int p_option); - void _create_poly(); - -protected: - void _notification(int p_what); - void _node_removed(Node *p_node); - static void _bind_methods(); -public: - - Vector2 snap_point(const Vector2& p_point) const; - bool forward_gui_input(const InputEvent& p_event); - void edit(Node *p_collision_polygon); - LightOccluder2DEditor(EditorNode *p_editor); -}; - -class LightOccluder2DEditorPlugin : public EditorPlugin { - - GDCLASS( LightOccluder2DEditorPlugin, EditorPlugin ); - - LightOccluder2DEditor *collision_polygon_editor; - EditorNode *editor; - -public: - - virtual bool forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); } - - virtual String get_name() const { return "LightOccluder2D"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - LightOccluder2DEditorPlugin(EditorNode *p_node); - ~LightOccluder2DEditorPlugin(); - -}; - -#endif // LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/line_2d_editor_plugin.cpp b/tools/editor/plugins/line_2d_editor_plugin.cpp deleted file mode 100644 index c90d1c4754..0000000000 --- a/tools/editor/plugins/line_2d_editor_plugin.cpp +++ /dev/null @@ -1,283 +0,0 @@ -#include "line_2d_editor_plugin.h" - -#include "canvas_item_editor_plugin.h" -#include "os/file_access.h" -#include "tools/editor/editor_settings.h" -#include "os/keyboard.h" - - -//---------------------------------------------------------------------------- -// Line2DEditor -//---------------------------------------------------------------------------- - -void Line2DEditor::_node_removed(Node *p_node) { - if(p_node == node) { - node=NULL; - hide(); - } -} - -void Line2DEditor::_notification(int p_what) { - switch(p_what) { - case NOTIFICATION_VISIBILITY_CHANGED: - // This widget is not a child but should have the same visibility state - base_hb->set_visible(is_visible()); - break; - } -} - -Vector2 Line2DEditor::mouse_to_local_pos(Vector2 gpoint, bool alt) { - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - return !alt? canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)) - : node->get_global_transform().affine_inverse().xform( - canvas_item_editor->snap_point( - canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)) ); -} - -int Line2DEditor::get_point_index_at(Vector2 gpos) { - ERR_FAIL_COND_V(node == 0, -1); - - real_t grab_treshold = EDITOR_DEF("poly_editor/point_grab_radius", 8); - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - - for(int i = 0; i < node->get_point_count(); ++i) { - Point2 p = xform.xform( node->get_point_pos(i) ); - if(gpos.distance_to(p) < grab_treshold) { - return i; - } - } - - return -1; -} - -bool Line2DEditor::forward_gui_input(const InputEvent& p_event) { - - if (!node) - return false; - - if (!node->is_visible()) - return false; - - switch(p_event.type) { - - case InputEvent::MOUSE_BUTTON: { - - const InputEventMouseButton &mb = p_event.mouse_button; - - Vector2 gpoint = Point2(mb.x,mb.y); - Vector2 cpoint = mouse_to_local_pos(gpoint, mb.mod.alt); - - if(mb.pressed && _dragging == false) { - int i = get_point_index_at(gpoint); - if(i != -1) { - if (mb.button_index == BUTTON_LEFT && !mb.mod.shift && mode == MODE_EDIT) { - _dragging = true; - action_point = i; - moving_from = node->get_point_pos(i); - moving_screen_from = gpoint; - } - else if((mb.button_index == BUTTON_RIGHT && mode == MODE_EDIT) || (mb.button_index == BUTTON_LEFT && mode == MODE_DELETE)) { - undo_redo->create_action(TTR("Remove Point from Line2D")); - undo_redo->add_do_method(node, "remove_point", i); - undo_redo->add_undo_method(node, "add_point", node->get_point_pos(i), i); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update"); - undo_redo->commit_action(); - } - return true; - } - } - - if(mb.pressed && mb.button_index == BUTTON_LEFT && ((mb.mod.command && mode == MODE_EDIT) || mode == MODE_CREATE)) { - - undo_redo->create_action(TTR("Add Point to Line2D")); - undo_redo->add_do_method(node, "add_point", cpoint); - undo_redo->add_undo_method(node, "remove_point", node->get_point_count()); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update"); - undo_redo->commit_action(); - - _dragging = true; - action_point = node->get_point_count()-1; - moving_from = node->get_point_pos(action_point); - moving_screen_from = gpoint; - - canvas_item_editor->get_viewport_control()->update(); - - return true; - } - - if(!mb.pressed && mb.button_index == BUTTON_LEFT && _dragging) { - undo_redo->create_action(TTR("Move Point in Line2D")); - undo_redo->add_do_method(node, "set_point_pos", action_point, cpoint); - undo_redo->add_undo_method(node, "set_point_pos", action_point, moving_from); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update"); - undo_redo->commit_action(); - _dragging = false; - return true; - } - } - break; - - case InputEvent::MOUSE_MOTION: { - if (_dragging) { - const InputEventMouseMotion &mm = p_event.mouse_motion; - Vector2 cpoint = mouse_to_local_pos(Vector2(mm.x, mm.y), mm.mod.alt); - node->set_point_pos(action_point,cpoint); - canvas_item_editor->get_viewport_control()->update(); - return true; - } - } - break; - } - - return false; -} - -void Line2DEditor::_canvas_draw() { - - if (!node) - return; - - if (!node->is_visible()) - return; - - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons"); - Size2 handle_size = handle->get_size(); - - int len = node->get_point_count(); - Control *vpc = canvas_item_editor->get_viewport_control(); - - for(int i=0; i < len; ++i) { - Vector2 point = xform.xform(node->get_point_pos(i)); - vpc->draw_texture_rect(handle, Rect2(point - handle_size * 0.5, handle_size), false); - } -} - -void Line2DEditor::_node_visibility_changed() { - if (!node) - return; - canvas_item_editor->get_viewport_control()->update(); -} - -void Line2DEditor::edit(Node *p_line2d) { - - if (!canvas_item_editor) - canvas_item_editor = CanvasItemEditor::get_singleton(); - - if (p_line2d) { - node = p_line2d->cast_to<Line2D>(); - if (!canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw")) - canvas_item_editor->get_viewport_control()->connect("draw", this, "_canvas_draw"); - if (!node->is_connected("visibility_changed", this, "_node_visibility_changed")) - node->connect("visibility_changed", this, "_node_visibility_changed"); - } - else { - if (canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw")) - canvas_item_editor->get_viewport_control()->disconnect("draw", this, "_canvas_draw"); - // node may have been deleted at this point - if (node && node->is_connected("visibility_changed", this, "_node_visibility_changed")) - node->disconnect("visibility_changed", this, "_node_visibility_changed"); - node = NULL; - } -} - -void Line2DEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_canvas_draw"), &Line2DEditor::_canvas_draw); - ClassDB::bind_method(D_METHOD("_node_visibility_changed"), &Line2DEditor::_node_visibility_changed); - ClassDB::bind_method(D_METHOD("_mode_selected"), &Line2DEditor::_mode_selected); -} - -void Line2DEditor::_mode_selected(int p_mode) { - for(unsigned int i = 0; i < _MODE_COUNT; ++i) { - toolbar_buttons[i]->set_pressed(i == p_mode); - } - mode = Mode(p_mode); -} - -Line2DEditor::Line2DEditor(EditorNode *p_editor) { - - canvas_item_editor = NULL; - editor = p_editor; - undo_redo = editor->get_undo_redo(); - - _dragging = false; - - base_hb = memnew( HBoxContainer ); - CanvasItemEditor::get_singleton()->add_control_to_menu_panel(base_hb); - - sep = memnew( VSeparator); - base_hb->add_child(sep); - - { - ToolButton * b = memnew(ToolButton); - b->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveEdit", "EditorIcons")); - b->set_toggle_mode(true); - b->set_focus_mode(Control::FOCUS_NONE); - b->set_tooltip( - TTR("Select Points")+"\n" - + TTR("Shift+Drag: Select Control Points")+"\n" - + keycode_get_string(KEY_MASK_CMD) - + TTR("Click: Add Point")+"\n" - + TTR("Right Click: Delete Point")); - b->connect("pressed", this, "_mode_selected", varray(MODE_EDIT)); - toolbar_buttons[MODE_EDIT] = b; - base_hb->add_child(b); - } - - { - ToolButton * b = memnew(ToolButton); - b->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveCreate", "EditorIcons")); - b->set_toggle_mode(true); - b->set_focus_mode(Control::FOCUS_NONE); - b->set_tooltip(TTR("Add Point (in empty space)")+"\n"+TTR("Split Segment (in line)")); - b->connect("pressed", this, "_mode_selected", varray(MODE_CREATE)); - toolbar_buttons[MODE_CREATE] = b; - base_hb->add_child(b); - } - - { - ToolButton * b = memnew( ToolButton ); - b->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveDelete", "EditorIcons")); - b->set_toggle_mode(true); - b->set_focus_mode(Control::FOCUS_NONE); - b->set_tooltip(TTR("Delete Point")); - b->connect("pressed", this, "_mode_selected", varray(MODE_DELETE)); - toolbar_buttons[MODE_DELETE] = b; - base_hb->add_child(b); - } - - base_hb->hide(); - hide(); - - _mode_selected(MODE_CREATE); -} - -//---------------------------------------------------------------------------- -// Line2DEditorPlugin -//---------------------------------------------------------------------------- - -void Line2DEditorPlugin::edit(Object *p_object) { - line2d_editor->edit(p_object->cast_to<Node>()); -} - -bool Line2DEditorPlugin::handles(Object *p_object) const { - return p_object->is_class("Line2D"); -} - -void Line2DEditorPlugin::make_visible(bool p_visible) { - line2d_editor->set_visible(p_visible); - if(p_visible == false) - line2d_editor->edit(NULL); -} - -Line2DEditorPlugin::Line2DEditorPlugin(EditorNode *p_node) { - editor=p_node; - line2d_editor = memnew( Line2DEditor(p_node) ); - CanvasItemEditor::get_singleton()->add_control_to_menu_panel(line2d_editor); - line2d_editor->hide(); -} - - diff --git a/tools/editor/plugins/line_2d_editor_plugin.h b/tools/editor/plugins/line_2d_editor_plugin.h deleted file mode 100644 index 231f4c6ca7..0000000000 --- a/tools/editor/plugins/line_2d_editor_plugin.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef LINE_2D_EDITOR_PLUGIN_H -#define LINE_2D_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/2d/path_2d.h" -#include "scene/gui/tool_button.h" -#include "scene/gui/button_group.h" -#include "scene/2d/line_2d.h" - - -class CanvasItemEditor; - -class Line2DEditor : public HBoxContainer { - GDCLASS(Line2DEditor, HBoxContainer) - -public: - bool forward_gui_input(const InputEvent& p_event); - void edit(Node *p_line2d); - Line2DEditor(EditorNode *p_editor); - -protected: - void _node_removed(Node *p_node); - void _notification(int p_what); - - Vector2 mouse_to_local_pos(Vector2 mpos); - - static void _bind_methods(); - -private: - void _mode_selected(int p_mode); - void _canvas_draw(); - void _node_visibility_changed(); - - int get_point_index_at(Vector2 gpos); - Vector2 mouse_to_local_pos(Vector2 gpos, bool alt); - - UndoRedo *undo_redo; - - CanvasItemEditor *canvas_item_editor; - EditorNode *editor; - Panel *panel; - Line2D *node; - - HBoxContainer *base_hb; - Separator *sep; - - enum Mode { - MODE_CREATE = 0, - MODE_EDIT, - MODE_DELETE, - _MODE_COUNT - }; - - Mode mode; - ToolButton* toolbar_buttons[_MODE_COUNT]; - - bool _dragging; - int action_point; - Point2 moving_from; - Point2 moving_screen_from; -}; - -class Line2DEditorPlugin : public EditorPlugin { - GDCLASS( Line2DEditorPlugin, EditorPlugin ) - -public: - virtual bool forward_canvas_gui_input( - const Transform2D& p_canvas_xform, - const InputEvent& p_event) - { - return line2d_editor->forward_gui_input(p_event); - } - - virtual String get_name() const { return "Line2D"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - Line2DEditorPlugin(EditorNode *p_node); - -private: - Line2DEditor *line2d_editor; - EditorNode *editor; - -}; - -#endif // LINE_2D_EDITOR_PLUGIN_H - diff --git a/tools/editor/plugins/material_editor_plugin.h b/tools/editor/plugins/material_editor_plugin.h deleted file mode 100644 index 5daae124e0..0000000000 --- a/tools/editor/plugins/material_editor_plugin.h +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************/ -/* material_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef MATERIAL_EDITOR_PLUGIN_H -#define MATERIAL_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/resources/material.h" -#include "scene/3d/light.h" -#include "scene/3d/mesh_instance.h" -#include "scene/3d/camera.h" - -#if 0 -class MaterialEditor : public Control { - - GDCLASS(MaterialEditor, Control); - - - Viewport *viewport; - MeshInstance *sphere_instance; - MeshInstance *box_instance; - DirectionalLight *light1; - DirectionalLight *light2; - Camera *camera; - - Ref<Mesh> sphere_mesh; - Ref<Mesh> box_mesh; - - TextureButton *sphere_switch; - TextureButton *box_switch; - - TextureButton *light_1_switch; - TextureButton *light_2_switch; - - - Ref<Material> material; - - - void _button_pressed(Node* p_button); - bool first_enter; - -protected: - void _notification(int p_what); - void _gui_input(InputEvent p_event); - static void _bind_methods(); -public: - - void edit(Ref<Material> p_material); - MaterialEditor(); -}; - - -class MaterialEditorPlugin : public EditorPlugin { - - GDCLASS( MaterialEditorPlugin, EditorPlugin ); - - MaterialEditor *material_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "Material"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - MaterialEditorPlugin(EditorNode *p_node); - ~MaterialEditorPlugin(); - -}; - -#endif // MATERIAL_EDITOR_PLUGIN_H -#endif diff --git a/tools/editor/plugins/mesh_editor_plugin.h b/tools/editor/plugins/mesh_editor_plugin.h deleted file mode 100644 index 136290ffd4..0000000000 --- a/tools/editor/plugins/mesh_editor_plugin.h +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************/ -/* mesh_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef MESH_EDITOR_PLUGIN_H -#define MESH_EDITOR_PLUGIN_H - -#if 0 - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/resources/material.h" -#include "scene/3d/light.h" -#include "scene/3d/mesh_instance.h" -#include "scene/3d/camera.h" - -class MeshEditor : public Control { - - GDCLASS(MeshEditor, Control); - - - - float rot_x; - float rot_y; - - Viewport *viewport; - MeshInstance *mesh_instance; - DirectionalLight *light1; - DirectionalLight *light2; - Camera *camera; - - Ref<Mesh> mesh; - - - TextureButton *light_1_switch; - TextureButton *light_2_switch; - - void _button_pressed(Node* p_button); - bool first_enter; - - void _update_rotation(); -protected: - void _notification(int p_what); - void _gui_input(InputEvent p_event); - static void _bind_methods(); -public: - - void edit(Ref<Mesh> p_mesh); - MeshEditor(); -}; - - -class MeshEditorPlugin : public EditorPlugin { - - GDCLASS( MeshEditorPlugin, EditorPlugin ); - - MeshEditor *mesh_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "Mesh"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - MeshEditorPlugin(EditorNode *p_node); - ~MeshEditorPlugin(); - -}; - -#endif // MESH_EDITOR_PLUGIN_H -#endif diff --git a/tools/editor/plugins/mesh_instance_editor_plugin.h b/tools/editor/plugins/mesh_instance_editor_plugin.h deleted file mode 100644 index 441d4d1d3f..0000000000 --- a/tools/editor/plugins/mesh_instance_editor_plugin.h +++ /dev/null @@ -1,97 +0,0 @@ -/*************************************************************************/ -/* mesh_instance_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef MESH_INSTANCE_EDITOR_PLUGIN_H -#define MESH_INSTANCE_EDITOR_PLUGIN_H - - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/3d/mesh_instance.h" -#include "scene/gui/spin_box.h" - - -class MeshInstanceEditor : public Node { - - GDCLASS(MeshInstanceEditor, Node ); - - - enum Menu { - - MENU_OPTION_CREATE_STATIC_TRIMESH_BODY, - MENU_OPTION_CREATE_STATIC_CONVEX_BODY, - MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE, - MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE, - MENU_OPTION_CREATE_NAVMESH, - MENU_OPTION_CREATE_OUTLINE_MESH, - }; - - MeshInstance *node; - - MenuButton *options; - - ConfirmationDialog *outline_dialog; - SpinBox *outline_size; - - AcceptDialog *err_dialog; - - void _menu_option(int p_option); - void _create_outline_mesh(); - -friend class MeshInstanceEditorPlugin; - -protected: - void _node_removed(Node *p_node); - static void _bind_methods(); -public: - - void edit(MeshInstance *p_mesh); - MeshInstanceEditor(); -}; - -class MeshInstanceEditorPlugin : public EditorPlugin { - - GDCLASS( MeshInstanceEditorPlugin, EditorPlugin ); - - MeshInstanceEditor *mesh_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "MeshInstance"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - MeshInstanceEditorPlugin(EditorNode *p_node); - ~MeshInstanceEditorPlugin(); - -}; - -#endif // MESH_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/multimesh_editor_plugin.h b/tools/editor/plugins/multimesh_editor_plugin.h deleted file mode 100644 index e322850238..0000000000 --- a/tools/editor/plugins/multimesh_editor_plugin.h +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************/ -/* multimesh_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef MULTIMESH_EDITOR_PLUGIN_H -#define MULTIMESH_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/3d/multimesh_instance.h" -#include "scene/gui/spin_box.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -class MultiMeshEditor : public Control { - - GDCLASS(MultiMeshEditor, Control ); - -friend class MultiMeshEditorPlugin; - - AcceptDialog *err_dialog; - MenuButton * options; - MultiMeshInstance *_last_pp_node; - bool browsing_source; - - Panel *panel; - MultiMeshInstance *node; - - LineEdit *surface_source; - LineEdit *mesh_source; - - SceneTreeDialog *std; - - ConfirmationDialog *populate_dialog; - OptionButton *populate_axis; - HSlider *populate_rotate_random; - HSlider *populate_tilt_random; - SpinBox *populate_scale_random; - SpinBox *populate_scale; - SpinBox *populate_amount; - - enum Menu { - - MENU_OPTION_POPULATE - }; - - void _browsed(const NodePath& p_path); - void _menu_option(int); - void _populate(); - void _browse(bool p_source); - -protected: - void _node_removed(Node *p_node); - static void _bind_methods(); -public: - - void edit(MultiMeshInstance *p_multimesh); - MultiMeshEditor(); -}; - -class MultiMeshEditorPlugin : public EditorPlugin { - - GDCLASS( MultiMeshEditorPlugin, EditorPlugin ); - - MultiMeshEditor *multimesh_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "MultiMesh"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - MultiMeshEditorPlugin(EditorNode *p_node); - ~MultiMeshEditorPlugin(); - -}; - -#endif // MULTIMESH_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/navigation_polygon_editor_plugin.cpp b/tools/editor/plugins/navigation_polygon_editor_plugin.cpp deleted file mode 100644 index dfc9b2d6e2..0000000000 --- a/tools/editor/plugins/navigation_polygon_editor_plugin.cpp +++ /dev/null @@ -1,566 +0,0 @@ -/*************************************************************************/ -/* navigation_polygon_editor_plugin.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 "navigation_polygon_editor_plugin.h" - -#include "canvas_item_editor_plugin.h" -#include "os/file_access.h" -#include "tools/editor/editor_settings.h" - -void NavigationPolygonEditor::_notification(int p_what) { - - switch(p_what) { - - case NOTIFICATION_READY: { - - button_create->set_icon( get_icon("Edit","EditorIcons")); - button_edit->set_icon( get_icon("MovePoint","EditorIcons")); - button_edit->set_pressed(true); - get_tree()->connect("node_removed",this,"_node_removed"); - create_nav->connect("confirmed",this,"_create_nav"); - - } break; - case NOTIFICATION_FIXED_PROCESS: { - - - } break; - } - -} -void NavigationPolygonEditor::_node_removed(Node *p_node) { - - if(p_node==node) { - node=NULL; - hide(); - canvas_item_editor->get_viewport_control()->update(); - } - -} - -void NavigationPolygonEditor::_create_nav() { - - if (!node) - return; - - undo_redo->create_action(TTR("Create Navigation Polygon")); - undo_redo->add_do_method(node,"set_navigation_polygon",Ref<NavigationPolygon>(memnew( NavigationPolygon))); - undo_redo->add_undo_method(node,"set_navigation_polygon",Variant(REF())); - undo_redo->commit_action(); -} - -void NavigationPolygonEditor::_menu_option(int p_option) { - - switch(p_option) { - - case MODE_CREATE: { - - mode=MODE_CREATE; - button_create->set_pressed(true); - button_edit->set_pressed(false); - } break; - case MODE_EDIT: { - - mode=MODE_EDIT; - button_create->set_pressed(false); - button_edit->set_pressed(true); - } break; - - } -} - -void NavigationPolygonEditor::_wip_close() { - - - if (wip.size()>=3) { - - undo_redo->create_action(TTR("Create Poly")); - undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"remove_outline",node->get_navigation_polygon()->get_outline_count()); - undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"add_outline",wip); - undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); - undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - mode=MODE_EDIT; - button_edit->set_pressed(true); - button_create->set_pressed(false); - } - - wip.clear(); - wip_active=false; - edited_point=-1; -} - -bool NavigationPolygonEditor::forward_gui_input(const InputEvent& p_event) { - - - if (!node) - return false; - - if (node->get_navigation_polygon().is_null()) { - if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { - create_nav->set_text("No NavigationPolygon resource on this node.\nCreate and assign one?"); - create_nav->popup_centered_minsize(); - } - return (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1); - } - - - switch(p_event.type) { - - case InputEvent::MOUSE_BUTTON: { - - const InputEventMouseButton &mb=p_event.mouse_button; - - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - - - Vector2 gpoint = Point2(mb.x,mb.y); - Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); - cpoint=canvas_item_editor->snap_point(cpoint); - cpoint = node->get_global_transform().affine_inverse().xform(cpoint); - - - - //first check if a point is to be added (segment split) - real_t grab_treshold=EDITOR_DEF("editors/poly_editor/point_grab_radius",8); - - switch(mode) { - - - case MODE_CREATE: { - - if (mb.button_index==BUTTON_LEFT && mb.pressed) { - - - if (!wip_active) { - - wip.clear(); - wip.push_back( cpoint ); - wip_active=true; - edited_point_pos=cpoint; - edited_outline=-1; - canvas_item_editor->get_viewport_control()->update(); - edited_point=1; - return true; - } else { - - - if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) { - //wip closed - _wip_close(); - - return true; - } else { - - wip.push_back( cpoint ); - edited_point=wip.size(); - canvas_item_editor->get_viewport_control()->update(); - return true; - - //add wip point - } - } - } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { - _wip_close(); - } - - - - } break; - - case MODE_EDIT: { - - if (mb.button_index==BUTTON_LEFT) { - if (mb.pressed) { - - if (mb.mod.control) { - - - //search edges - int closest_outline=-1; - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - - for(int j=0;j<node->get_navigation_polygon()->get_outline_count();j++) { - - - PoolVector<Vector2> points=node->get_navigation_polygon()->get_outline(j); - - int pc=points.size(); - PoolVector<Vector2>::Read poly=points.read(); - - for(int i=0;i<pc;i++) { - - Vector2 points[2] ={ xform.xform(poly[i]), - xform.xform(poly[(i+1)%pc]) }; - - Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points); - if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2) - continue; //not valid to reuse point - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_outline=j; - closest_pos=cp; - closest_idx=i; - } - - - } - } - - if (closest_idx>=0) { - - pre_move_edit=node->get_navigation_polygon()->get_outline(closest_outline); - PoolVector<Point2> poly = pre_move_edit; - poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos)); - edited_point=closest_idx+1; - edited_outline=closest_outline; - edited_point_pos=xform.affine_inverse().xform(closest_pos); - node->get_navigation_polygon()->set_outline(closest_outline,poly); - canvas_item_editor->get_viewport_control()->update(); - return true; - } - } else { - - //look for points to move - int closest_outline=-1; - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - - for(int j=0;j<node->get_navigation_polygon()->get_outline_count();j++) { - - - PoolVector<Vector2> points=node->get_navigation_polygon()->get_outline(j); - - int pc=points.size(); - PoolVector<Vector2>::Read poly=points.read(); - - for(int i=0;i<pc;i++) { - - - Vector2 cp =xform.xform(poly[i]); - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_outline=j; - closest_idx=i; - } - } - } - - if (closest_idx>=0) { - - pre_move_edit=node->get_navigation_polygon()->get_outline(closest_outline); - edited_point=closest_idx; - edited_outline=closest_outline; - edited_point_pos=xform.affine_inverse().xform(closest_pos); - canvas_item_editor->get_viewport_control()->update(); - return true; - } - } - } else { - - if (edited_point!=-1) { - - //apply - - PoolVector<Vector2> poly = node->get_navigation_polygon()->get_outline(edited_outline); - ERR_FAIL_INDEX_V(edited_point,poly.size(),false); - poly.set(edited_point,edited_point_pos); - undo_redo->create_action(TTR("Edit Poly")); - undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"set_outline",edited_outline,poly); - undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"set_outline",edited_outline,pre_move_edit); - undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); - undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - - edited_point=-1; - return true; - } - } - } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { - - int closest_outline=-1; - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - - for(int j=0;j<node->get_navigation_polygon()->get_outline_count();j++) { - - - PoolVector<Vector2> points=node->get_navigation_polygon()->get_outline(j); - - int pc=points.size(); - PoolVector<Vector2>::Read poly=points.read(); - - for(int i=0;i<pc;i++) { - - - Vector2 cp =xform.xform(poly[i]); - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_outline=j; - closest_idx=i; - } - } - } - - if (closest_idx>=0) { - - - PoolVector<Vector2> poly = node->get_navigation_polygon()->get_outline(closest_outline); - - if (poly.size()>3) { - undo_redo->create_action(TTR("Edit Poly (Remove Point)")); - undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"set_outline",closest_outline,poly); - poly.remove(closest_idx); - undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"set_outline",closest_outline,poly); - undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); - undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - } else { - - undo_redo->create_action(TTR("Remove Poly And Point")); - undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"add_outline_at_index",poly,closest_outline); - poly.remove(closest_idx); - undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"remove_outline",closest_outline); - undo_redo->add_do_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); - undo_redo->add_undo_method(node->get_navigation_polygon().ptr(),"make_polygons_from_outlines"); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - - } - return true; - } - } - - - - } break; - } - - - - } break; - case InputEvent::MOUSE_MOTION: { - - const InputEventMouseMotion &mm=p_event.mouse_motion; - - if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { - - Vector2 gpoint = Point2(mm.x,mm.y); - Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); - cpoint=canvas_item_editor->snap_point(cpoint); - edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint); - - canvas_item_editor->get_viewport_control()->update(); - - } - - } break; - } - - return false; -} -void NavigationPolygonEditor::_canvas_draw() { - - if (!node) - return; - - Control *vpc = canvas_item_editor->get_viewport_control(); - if (node->get_navigation_polygon().is_null()) - return; - - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - Ref<Texture> handle= get_icon("EditorHandle","EditorIcons"); - - - - for(int j=-1;j<node->get_navigation_polygon()->get_outline_count();j++) { - Vector<Vector2> poly; - - if (wip_active && j==edited_outline) { - poly=wip; - } else { - if (j==-1) - continue; - poly = Variant(node->get_navigation_polygon()->get_outline(j)); - } - - for(int i=0;i<poly.size();i++) { - - - Vector2 p,p2; - p = (j==edited_outline && i==edited_point) ? edited_point_pos : poly[i]; - if (j==edited_outline && ((wip_active && i==poly.size()-1) || (((i+1)%poly.size())==edited_point))) - p2=edited_point_pos; - else - p2 = poly[(i+1)%poly.size()]; - - Vector2 point = xform.xform(p); - Vector2 next_point = xform.xform(p2); - - Color col=Color(1,0.3,0.1,0.8); - vpc->draw_line(point,next_point,col,2); - vpc->draw_texture(handle,point-handle->get_size()*0.5); - } - } -} - - - -void NavigationPolygonEditor::edit(Node *p_collision_polygon) { - - if (!canvas_item_editor) { - canvas_item_editor=CanvasItemEditor::get_singleton(); - } - - if (p_collision_polygon) { - - node=p_collision_polygon->cast_to<NavigationPolygonInstance>(); - if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) - canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw"); - wip.clear(); - wip_active=false; - edited_point=-1; - canvas_item_editor->get_viewport_control()->update(); - - } else { - node=NULL; - - if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) - canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw"); - - } - -} - -void NavigationPolygonEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_menu_option"),&NavigationPolygonEditor::_menu_option); - ClassDB::bind_method(D_METHOD("_canvas_draw"),&NavigationPolygonEditor::_canvas_draw); - ClassDB::bind_method(D_METHOD("_node_removed"),&NavigationPolygonEditor::_node_removed); - ClassDB::bind_method(D_METHOD("_create_nav"),&NavigationPolygonEditor::_create_nav); - -} - -NavigationPolygonEditor::NavigationPolygonEditor(EditorNode *p_editor) { - node=NULL; - canvas_item_editor=NULL; - editor=p_editor; - undo_redo = editor->get_undo_redo(); - - add_child( memnew( VSeparator )); - button_create = memnew( ToolButton ); - add_child(button_create); - button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE)); - button_create->set_toggle_mode(true); - button_create->set_tooltip(TTR("Create a new polygon from scratch.")); - - button_edit = memnew( ToolButton ); - add_child(button_edit); - button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT)); - button_edit->set_toggle_mode(true); - button_edit->set_tooltip(TTR("Edit existing polygon:")+"\n"+TTR("LMB: Move Point.")+"\n"+TTR("Ctrl+LMB: Split Segment.")+"\n"+TTR("RMB: Erase Point.")); - create_nav = memnew( ConfirmationDialog ); - add_child(create_nav); - create_nav->get_ok()->set_text(TTR("Create")); - - - //add_constant_override("separation",0); - -#if 0 - options = memnew( MenuButton ); - add_child(options); - options->set_area_as_parent_rect(); - options->set_text("Polygon"); - //options->get_popup()->add_item("Parse BBCode",PARSE_BBCODE); - options->get_popup()->connect("id_pressed", this,"_menu_option"); -#endif - - mode = MODE_EDIT; - wip_active=false; - edited_outline=-1; - -} - - -void NavigationPolygonEditorPlugin::edit(Object *p_object) { - - collision_polygon_editor->edit(p_object->cast_to<Node>()); -} - -bool NavigationPolygonEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("NavigationPolygonInstance"); -} - -void NavigationPolygonEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - collision_polygon_editor->show(); - } else { - - collision_polygon_editor->hide(); - collision_polygon_editor->edit(NULL); - } - -} - -NavigationPolygonEditorPlugin::NavigationPolygonEditorPlugin(EditorNode *p_node) { - - editor=p_node; - collision_polygon_editor = memnew( NavigationPolygonEditor(p_node) ); - CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); - - collision_polygon_editor->hide(); - - - -} - - -NavigationPolygonEditorPlugin::~NavigationPolygonEditorPlugin() -{ -} - diff --git a/tools/editor/plugins/navigation_polygon_editor_plugin.h b/tools/editor/plugins/navigation_polygon_editor_plugin.h deleted file mode 100644 index 50df4df744..0000000000 --- a/tools/editor/plugins/navigation_polygon_editor_plugin.h +++ /dev/null @@ -1,118 +0,0 @@ -/*************************************************************************/ -/* navigation_polygon_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef NAVIGATIONPOLYGONEDITORPLUGIN_H -#define NAVIGATIONPOLYGONEDITORPLUGIN_H - - - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/2d/navigation_polygon.h" -#include "scene/gui/tool_button.h" -#include "scene/gui/button_group.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ -class CanvasItemEditor; - -class NavigationPolygonEditor : public HBoxContainer { - - GDCLASS(NavigationPolygonEditor, HBoxContainer ); - - UndoRedo *undo_redo; - enum Mode { - - MODE_CREATE, - MODE_EDIT, - - }; - - Mode mode; - - ToolButton *button_create; - ToolButton *button_edit; - - ConfirmationDialog *create_nav; - - CanvasItemEditor *canvas_item_editor; - EditorNode *editor; - Panel *panel; - NavigationPolygonInstance *node; - MenuButton *options; - - int edited_outline; - int edited_point; - Vector2 edited_point_pos; - PoolVector<Vector2> pre_move_edit; - Vector<Vector2> wip; - bool wip_active; - - - void _wip_close(); - void _canvas_draw(); - void _create_nav(); - - void _menu_option(int p_option); - -protected: - void _notification(int p_what); - void _node_removed(Node *p_node); - static void _bind_methods(); -public: - - bool forward_gui_input(const InputEvent& p_event); - void edit(Node *p_collision_polygon); - NavigationPolygonEditor(EditorNode *p_editor); -}; - -class NavigationPolygonEditorPlugin : public EditorPlugin { - - GDCLASS( NavigationPolygonEditorPlugin, EditorPlugin ); - - NavigationPolygonEditor *collision_polygon_editor; - EditorNode *editor; - -public: - - virtual bool forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); } - - virtual String get_name() const { return "NavigationPolygonInstance"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - NavigationPolygonEditorPlugin(EditorNode *p_node); - ~NavigationPolygonEditorPlugin(); - -}; - - -#endif // NAVIGATIONPOLYGONEDITORPLUGIN_H diff --git a/tools/editor/plugins/particles_2d_editor_plugin.h b/tools/editor/plugins/particles_2d_editor_plugin.h deleted file mode 100644 index c532a5fe73..0000000000 --- a/tools/editor/plugins/particles_2d_editor_plugin.h +++ /dev/null @@ -1,82 +0,0 @@ -/*************************************************************************/ -/* particles_2d_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef PARTICLES_2D_EDITOR_PLUGIN_H -#define PARTICLES_2D_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/2d/collision_polygon_2d.h" - -#include "scene/gui/box_container.h" -#include "scene/gui/file_dialog.h" -#include "scene/2d/particles_2d.h" - -class Particles2DEditorPlugin : public EditorPlugin { - - GDCLASS( Particles2DEditorPlugin, EditorPlugin ); - - enum { - - MENU_LOAD_EMISSION_MASK, - MENU_CLEAR_EMISSION_MASK - }; - - Particles2D *particles; - - EditorFileDialog *file; - EditorNode *editor; - - HBoxContainer *toolbar; - MenuButton *menu; - - SpinBox *epoints; - - UndoRedo *undo_redo; - void _file_selected(const String& p_file); - void _menu_callback(int p_idx); -protected: - void _notification(int p_what); - static void _bind_methods(); - -public: - - - virtual String get_name() const { return "Particles2D"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - Particles2DEditorPlugin(EditorNode *p_node); - ~Particles2DEditorPlugin(); - -}; - - -#endif // PARTICLES_2D_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/particles_editor_plugin.cpp b/tools/editor/plugins/particles_editor_plugin.cpp deleted file mode 100644 index fd5ec5b5b9..0000000000 --- a/tools/editor/plugins/particles_editor_plugin.cpp +++ /dev/null @@ -1,461 +0,0 @@ -/*************************************************************************/ -/* particles_editor_plugin.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. */ -/*************************************************************************/ - -#if 0 -#include "particles_editor_plugin.h" -#include "io/resource_loader.h" -#include "servers/visual/particle_system_sw.h" -#include "tools/editor/plugins/spatial_editor_plugin.h" - - -void ParticlesEditor::_node_removed(Node *p_node) { - - if(p_node==node) { - node=NULL; - hide(); - } - -} - - -void ParticlesEditor::_resource_seleted(const String& p_res) { - - //print_line("selected resource path: "+p_res); -} - -void ParticlesEditor::_node_selected(const NodePath& p_path){ - - - Node *sel = get_node(p_path); - if (!sel) - return; - - VisualInstance *vi = sel->cast_to<VisualInstance>(); - if (!vi) { - - err_dialog->set_text(TTR("Node does not contain geometry.")); - err_dialog->popup_centered_minsize(); - return; - } - - geometry = vi->get_faces(VisualInstance::FACES_SOLID); - - if (geometry.size()==0) { - - err_dialog->set_text(TTR("Node does not contain geometry (faces).")); - err_dialog->popup_centered_minsize(); - return; - - } - - Transform geom_xform = node->get_global_transform().affine_inverse() * vi->get_global_transform(); - - int gc = geometry.size(); - PoolVector<Face3>::Write w = geometry.write(); - - - for(int i=0;i<gc;i++) { - for(int j=0;j<3;j++) { - w[i].vertex[j] = geom_xform.xform( w[i].vertex[j] ); - } - } - - - w = PoolVector<Face3>::Write(); - - emission_dialog->popup_centered(Size2(300,130)); -} - - -/* - -void ParticlesEditor::_populate() { - - if(!node) - return; - - - if (node->get_particles().is_null()) - return; - - node->get_particles()->set_instance_count(populate_amount->get_text().to_int()); - node->populate_parent(populate_rotate_random->get_val(),populate_tilt_random->get_val(),populate_scale_random->get_text().to_double(),populate_scale->get_text().to_double()); - -} -*/ - -void ParticlesEditor::_notification(int p_notification) { - - if (p_notification==NOTIFICATION_ENTER_TREE) { - options->set_icon(options->get_popup()->get_icon("Particles","EditorIcons")); - - } -} - - -void ParticlesEditor::_menu_option(int p_option) { - - - switch(p_option) { - - case MENU_OPTION_GENERATE_AABB: { - - Transform globalizer = node->get_global_transform(); - ParticleSystemSW pssw; - for(int i=0;i<VS::PARTICLE_VAR_MAX;i++) { - - pssw.particle_vars[i]=node->get_variable((Particles::Variable)i); - pssw.particle_randomness[i]=node->get_randomness((Particles::Variable)i); - } - - pssw.emission_half_extents=node->get_emission_half_extents(); - pssw.emission_points=node->get_emission_points(); - pssw.emission_base_velocity=node->get_emission_base_velocity(); - pssw.amount=node->get_amount(); - pssw.gravity_normal=node->get_gravity_normal(); - pssw.emitting=true; - pssw.height_from_velocity=node->has_height_from_velocity(); - pssw.color_phase_count=1; - - - ParticleSystemProcessSW pp; - float delta=0.01; - float lifetime=pssw.particle_vars[VS::PARTICLE_LIFETIME]; - - - Transform localizer = globalizer.affine_inverse(); - AABB aabb; - for(float t=0;t<lifetime;t+=delta) { - - pp.process(&pssw,globalizer,delta); - for(int i=0;i<pp.particle_data.size();i++) { - - Vector3 p = localizer.xform(pp.particle_data[i].pos); - - if (t==0 && i==0) - aabb.pos=p; - else - aabb.expand_to(p); - } - } - - aabb.grow_by( aabb.get_longest_axis_size()*0.2); - - node->set_visibility_aabb(aabb); - - - } break; - case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH: { - - - emission_file_dialog->popup_centered_ratio(); - - } break; - - case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE: { -/* - Node *root = get_scene()->get_root_node(); - ERR_FAIL_COND(!root); - EditorNode *en = root->cast_to<EditorNode>(); - ERR_FAIL_COND(!en); - Node * node = en->get_edited_scene(); -*/ - emission_tree_dialog->popup_centered_ratio(); - - } break; - } -} - - -void ParticlesEditor::edit(Particles *p_particles) { - - node=p_particles; - -} - -void ParticlesEditor::_generate_emission_points() { - - /// hacer codigo aca - PoolVector<Vector3> points; - - if (emission_fill->get_selected()==0) { - - float area_accum=0; - Map<float,int> triangle_area_map; - print_line("geometry size: "+itos(geometry.size())); - - for(int i=0;i<geometry.size();i++) { - - float area = geometry[i].get_area(); - if (area<CMP_EPSILON) - continue; - triangle_area_map[area_accum]=i; - area_accum+=area; - } - - if (!triangle_area_map.size() || area_accum==0) { - - err_dialog->set_text(TTR("Faces contain no area!")); - err_dialog->popup_centered_minsize(); - return; - } - - int emissor_count=emission_amount->get_val(); - - for(int i=0;i<emissor_count;i++) { - - float areapos = Math::random(0,area_accum); - - Map<float,int>::Element *E = triangle_area_map.find_closest(areapos); - ERR_FAIL_COND(!E) - int index = E->get(); - ERR_FAIL_INDEX(index,geometry.size()); - - // ok FINALLY get face - Face3 face = geometry[index]; - //now compute some position inside the face... - - Vector3 pos = face.get_random_point_inside(); - - points.push_back(pos); - } - } else { - - int gcount = geometry.size(); - - if (gcount==0) { - - err_dialog->set_text(TTR("No faces!")); - err_dialog->popup_centered_minsize(); - return; - } - - PoolVector<Face3>::Read r = geometry.read(); - - AABB aabb; - - for(int i=0;i<gcount;i++) { - - for(int j=0;j<3;j++) { - - if (i==0 && j==0) - aabb.pos=r[i].vertex[j]; - else - aabb.expand_to(r[i].vertex[j]); - } - } - - int emissor_count=emission_amount->get_val(); - - for(int i=0;i<emissor_count;i++) { - - int attempts=5; - - for(int j=0;j<attempts;j++) { - - Vector3 dir; - dir[Math::rand()%3]=1.0; - Vector3 ofs = Vector3(1,1,1)-dir; - ofs=(Vector3(1,1,1)-dir)*Vector3(Math::randf(),Math::randf(),Math::randf())*aabb.size; - ofs+=aabb.pos; - - Vector3 ofsv = ofs + aabb.size * dir; - - //space it a little - ofs -= dir; - ofsv += dir; - - float max=-1e7,min=1e7; - - for(int k=0;k<gcount;k++) { - - const Face3& f3 = r[k]; - - Vector3 res; - if (f3.intersects_segment(ofs,ofsv,&res)) { - - res-=ofs; - float d = dir.dot(res); - - if (d<min) - min=d; - if (d>max) - max=d; - - } - } - - - if (max<min) - continue; //lost attempt - - float val = min + (max-min)*Math::randf(); - - Vector3 point = ofs + dir * val; - - points.push_back(point); - break; - } - } - } - - //print_line("point count: "+itos(points.size())); - node->set_emission_points(points); - -} - -void ParticlesEditor::_bind_methods() { - - ClassDB::bind_method("_menu_option",&ParticlesEditor::_menu_option); - ClassDB::bind_method("_resource_seleted",&ParticlesEditor::_resource_seleted); - ClassDB::bind_method("_node_selected",&ParticlesEditor::_node_selected); - ClassDB::bind_method("_generate_emission_points",&ParticlesEditor::_generate_emission_points); - - //ClassDB::bind_method("_populate",&ParticlesEditor::_populate); - -} - -ParticlesEditor::ParticlesEditor() { - - particles_editor_hb = memnew ( HBoxContainer ); - SpatialEditor::get_singleton()->add_control_to_menu_panel(particles_editor_hb); - options = memnew( MenuButton ); - particles_editor_hb->add_child(options); - particles_editor_hb->hide(); - - options->set_text("Particles"); - options->get_popup()->add_item(TTR("Generate AABB"),MENU_OPTION_GENERATE_AABB); - options->get_popup()->add_separator(); - options->get_popup()->add_item(TTR("Create Emitter From Mesh"),MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH); - options->get_popup()->add_item(TTR("Create Emitter From Node"),MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE); - options->get_popup()->add_item(TTR("Clear Emitter"),MENU_OPTION_CLEAR_EMISSION_VOLUME); - - options->get_popup()->connect("id_pressed", this,"_menu_option"); - - emission_dialog = memnew( ConfirmationDialog ); - emission_dialog->set_title(TTR("Create Emitter")); - add_child(emission_dialog); - Label *l = memnew(Label); - l->set_pos(Point2(5,5)); - l->set_text(TTR("Emission Positions:")); - emission_dialog->add_child(l); - - - emission_amount = memnew( SpinBox ); - emission_amount->set_anchor(MARGIN_RIGHT,ANCHOR_END); - emission_amount->set_begin( Point2(20,23)); - emission_amount->set_end( Point2(5,25)); - emission_amount->set_min(1); - emission_amount->set_max(65536); - emission_amount->set_val(512); - emission_dialog->add_child(emission_amount); - emission_dialog->get_ok()->set_text(TTR("Create")); - emission_dialog->connect("confirmed",this,"_generate_emission_points"); - - l = memnew(Label); - l->set_pos(Point2(5,50)); - l->set_text(TTR("Emission Fill:")); - emission_dialog->add_child(l); - - emission_fill = memnew( OptionButton ); - emission_fill->set_anchor(MARGIN_RIGHT,ANCHOR_END); - emission_fill->set_begin( Point2(20,70)); - emission_fill->set_end( Point2(5,75)); - emission_fill->add_item(TTR("Surface")); - emission_fill->add_item(TTR("Volume")); - emission_dialog->add_child(emission_fill); - - err_dialog = memnew( ConfirmationDialog ); - //err_dialog->get_cancel()->hide(); - add_child(err_dialog); - - - emission_file_dialog = memnew( EditorFileDialog ); - add_child(emission_file_dialog); - emission_file_dialog->connect("file_selected",this,"_resource_seleted"); - emission_tree_dialog = memnew( SceneTreeDialog ); - add_child(emission_tree_dialog); - emission_tree_dialog->connect("selected",this,"_node_selected"); - - List<String> extensions; - ResourceLoader::get_recognized_extensions_for_type("Mesh",&extensions); - - emission_file_dialog->clear_filters(); - for(int i=0;i<extensions.size();i++) { - - emission_file_dialog->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); - } - - emission_file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE); - - //options->set_anchor(MARGIN_LEFT,Control::ANCHOR_END); - //options->set_anchor(MARGIN_RIGHT,Control::ANCHOR_END); - -} - - -void ParticlesEditorPlugin::edit(Object *p_object) { - - particles_editor->edit(p_object->cast_to<Particles>()); -} - -bool ParticlesEditorPlugin::handles(Object *p_object) const { - - return p_object->is_type("Particles"); -} - -void ParticlesEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - particles_editor->show(); - particles_editor->particles_editor_hb->show(); - } else { - particles_editor->particles_editor_hb->hide(); - particles_editor->hide(); - particles_editor->edit(NULL); - } - -} - -ParticlesEditorPlugin::ParticlesEditorPlugin(EditorNode *p_node) { - - editor=p_node; - particles_editor = memnew( ParticlesEditor ); - editor->get_viewport()->add_child(particles_editor); - - particles_editor->hide(); -} - - -ParticlesEditorPlugin::~ParticlesEditorPlugin() -{ -} - - -#endif diff --git a/tools/editor/plugins/particles_editor_plugin.h b/tools/editor/plugins/particles_editor_plugin.h deleted file mode 100644 index c32fbe5ada..0000000000 --- a/tools/editor/plugins/particles_editor_plugin.h +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************/ -/* particles_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef PARTICLES_EDITOR_PLUGIN_H -#define PARTICLES_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/3d/particles.h" -#include "scene/gui/spin_box.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ -#if 0 -class ParticlesEditor : public Control { - - GDCLASS(ParticlesEditor, Control ); - - Panel *panel; - MenuButton *options; - HBoxContainer *particles_editor_hb; - Particles *node; - - - EditorFileDialog *emission_file_dialog; - SceneTreeDialog *emission_tree_dialog; - - ConfirmationDialog *err_dialog; - - ConfirmationDialog *emission_dialog; - SpinBox *emission_amount; - OptionButton *emission_fill; - - - - - enum Menu { - - MENU_OPTION_GENERATE_AABB, - MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE, - MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_MESH, - MENU_OPTION_CLEAR_EMISSION_VOLUME, - - }; - - PoolVector<Face3> geometry; - - void _generate_emission_points(); - void _resource_seleted(const String& p_res); - void _node_selected(const NodePath& p_path); - - void _menu_option(int); - - void _populate(); - -friend class ParticlesEditorPlugin; - -protected: - - void _notification(int p_notification); - void _node_removed(Node *p_node); - static void _bind_methods(); -public: - - void edit(Particles *p_particles); - ParticlesEditor(); -}; - -class ParticlesEditorPlugin : public EditorPlugin { - - GDCLASS( ParticlesEditorPlugin, EditorPlugin ); - - ParticlesEditor *particles_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "Particles"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - ParticlesEditorPlugin(EditorNode *p_node); - ~ParticlesEditorPlugin(); - -}; - -#endif // PARTICLES_EDITOR_PLUGIN_H -#endif diff --git a/tools/editor/plugins/path_2d_editor_plugin.cpp b/tools/editor/plugins/path_2d_editor_plugin.cpp deleted file mode 100644 index 88dded72ae..0000000000 --- a/tools/editor/plugins/path_2d_editor_plugin.cpp +++ /dev/null @@ -1,718 +0,0 @@ -/*************************************************************************/ -/* path_2d_editor_plugin.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 "path_2d_editor_plugin.h" - -#include "canvas_item_editor_plugin.h" -#include "os/file_access.h" -#include "tools/editor/editor_settings.h" -#include "os/keyboard.h" -void Path2DEditor::_notification(int p_what) { - - switch(p_what) { - - case NOTIFICATION_READY: { - - //button_create->set_icon( get_icon("Edit","EditorIcons")); - //button_edit->set_icon( get_icon("MovePoint","EditorIcons")); - //set_pressed_button(button_edit); - //button_edit->set_pressed(true); - - - } break; - case NOTIFICATION_FIXED_PROCESS: { - - - } break; - } - -} -void Path2DEditor::_node_removed(Node *p_node) { - - if(p_node==node) { - node=NULL; - hide(); - } - -} - - -bool Path2DEditor::forward_gui_input(const InputEvent& p_event) { - - if (!node) - return false; - - if (!node->is_visible_in_tree()) - return false; - - if (!node->get_curve().is_valid()) - return false; - - switch(p_event.type) { - - case InputEvent::MOUSE_BUTTON: { - - const InputEventMouseButton &mb=p_event.mouse_button; - - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - - Vector2 gpoint = Point2(mb.x,mb.y); - Vector2 cpoint = !mb.mod.alt? canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)) - : node->get_global_transform().affine_inverse().xform( canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)) ); - - //first check if a point is to be added (segment split) - real_t grab_treshold=EDITOR_DEF("editors/poly_editor/point_grab_radius",8); - - - - // Test move point!! - - if ( mb.pressed && action==ACTION_NONE ) { - - Ref<Curve2D> curve = node->get_curve(); - - for(int i=0;i<curve->get_point_count();i++) { - - bool pointunder=false; - - { - Point2 p = xform.xform( curve->get_point_pos(i) ); - if (gpoint.distance_to(p) < grab_treshold ) { - - if (mb.button_index==BUTTON_LEFT && !mb.mod.shift && mode==MODE_EDIT) { - - action=ACTION_MOVING_POINT; - action_point=i; - moving_from=curve->get_point_pos(i); - moving_screen_from=gpoint; - return true; - } else if ((mb.button_index==BUTTON_RIGHT && mode==MODE_EDIT) || (mb.button_index==BUTTON_LEFT && mode==MODE_DELETE)) { - - undo_redo->create_action(TTR("Remove Point from Curve")); - undo_redo->add_do_method(curve.ptr(),"remove_point",i); - undo_redo->add_undo_method(curve.ptr(),"add_point",curve->get_point_pos(i),curve->get_point_in(i),curve->get_point_out(i),i); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - return true; - } else - pointunder=true; - } - } - - if (mb.button_index==BUTTON_LEFT && i<(curve->get_point_count()-1)) { - Point2 p = xform.xform( curve->get_point_pos(i)+curve->get_point_out(i) ); - if (gpoint.distance_to(p) < grab_treshold && (mode == MODE_EDIT || mode==MODE_EDIT_CURVE) ) { - - action=ACTION_MOVING_OUT; - action_point=i; - moving_from=curve->get_point_out(i); - moving_screen_from=gpoint; - return true; - } - } - - if (mb.button_index==BUTTON_LEFT && i>0) { - Point2 p = xform.xform( curve->get_point_pos(i)+curve->get_point_in(i) ); - if (gpoint.distance_to(p) < grab_treshold && (mode == MODE_EDIT || mode==MODE_EDIT_CURVE)) { - - action=ACTION_MOVING_IN; - action_point=i; - moving_from=curve->get_point_in(i); - moving_screen_from=gpoint; - return true; - } - } - - if (pointunder) - return true; - - } - - } - - // Test add point in empty space! - - if ( mb.pressed && mb.button_index==BUTTON_LEFT && ((mb.mod.command && mode == MODE_EDIT) || mode == MODE_CREATE)) { - - Ref<Curve2D> curve = node->get_curve(); - - undo_redo->create_action(TTR("Add Point to Curve")); - undo_redo->add_do_method(curve.ptr(),"add_point",cpoint); - undo_redo->add_undo_method(curve.ptr(),"remove_point",curve->get_point_count()); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - - action=ACTION_MOVING_POINT; - action_point=curve->get_point_count()-1; - moving_from=curve->get_point_pos(action_point); - moving_screen_from=gpoint; - - canvas_item_editor->get_viewport_control()->update(); - - return true; - } - - if ( !mb.pressed && mb.button_index==BUTTON_LEFT && action!=ACTION_NONE) { - - - Ref<Curve2D> curve = node->get_curve(); - - Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from); - switch(action) { - - case ACTION_MOVING_POINT: { - - - undo_redo->create_action(TTR("Move Point in Curve")); - undo_redo->add_do_method(curve.ptr(),"set_point_pos",action_point,cpoint); - undo_redo->add_undo_method(curve.ptr(),"set_point_pos",action_point,moving_from); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - - } break; - case ACTION_MOVING_IN: { - - undo_redo->create_action(TTR("Move In-Control in Curve")); - undo_redo->add_do_method(curve.ptr(),"set_point_in",action_point,new_pos); - undo_redo->add_undo_method(curve.ptr(),"set_point_in",action_point,moving_from); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - - } break; - case ACTION_MOVING_OUT: { - - undo_redo->create_action(TTR("Move Out-Control in Curve")); - undo_redo->add_do_method(curve.ptr(),"set_point_out",action_point,new_pos); - undo_redo->add_undo_method(curve.ptr(),"set_point_out",action_point,moving_from); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - - } break; - - } - - action=ACTION_NONE; - - return true; - } - - -#if 0 - switch(mode) { - - - case MODE_CREATE: { - - if (mb.button_index==BUTTON_LEFT && mb.pressed) { - - - if (!wip_active) { - - wip.clear(); - wip.push_back( canvas_item_editor->snap_point(cpoint) ); - wip_active=true; - edited_point_pos=canvas_item_editor->snap_point(cpoint); - canvas_item_editor->update(); - edited_point=1; - return true; - } else { - - if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) { - //wip closed - _wip_close(); - - return true; - } else { - - wip.push_back( canvas_item_editor->snap_point(cpoint) ); - edited_point=wip.size(); - canvas_item_editor->update(); - return true; - - //add wip point - } - } - } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { - _wip_close(); - } - - - - } break; - - case MODE_EDIT: { - - if (mb.button_index==BUTTON_LEFT) { - if (mb.pressed) { - - if (mb.mod.control) { - - - if (poly.size() < 3) { - - undo_redo->create_action(TTR("Edit Poly")); - undo_redo->add_undo_method(node,"set_polygon",poly); - poly.push_back(cpoint); - undo_redo->add_do_method(node,"set_polygon",poly); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - return true; - } - - //search edges - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 points[2] ={ xform.xform(poly[i]), - xform.xform(poly[(i+1)%poly.size()]) }; - - Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points); - if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2) - continue; //not valid to reuse point - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - - } - - if (closest_idx>=0) { - - pre_move_edit=poly; - poly.insert(closest_idx+1,canvas_item_editor->snap_point(xform.affine_inverse().xform(closest_pos))); - edited_point=closest_idx+1; - edited_point_pos=canvas_item_editor->snap_point(xform.affine_inverse().xform(closest_pos)); - node->set_polygon(poly); - canvas_item_editor->update(); - return true; - } - } else { - - //look for points to move - - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 cp =xform.xform(poly[i]); - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - } - - if (closest_idx>=0) { - - pre_move_edit=poly; - edited_point=closest_idx; - edited_point_pos=xform.affine_inverse().xform(closest_pos); - canvas_item_editor->update(); - return true; - } - } - } else { - - if (edited_point!=-1) { - - //apply - - ERR_FAIL_INDEX_V(edited_point,poly.size(),false); - poly[edited_point]=edited_point_pos; - undo_redo->create_action(TTR("Edit Poly")); - undo_redo->add_do_method(node,"set_polygon",poly); - undo_redo->add_undo_method(node,"set_polygon",pre_move_edit); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - - edited_point=-1; - return true; - } - } - } if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { - - - - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 cp =xform.xform(poly[i]); - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - } - - if (closest_idx>=0) { - - - undo_redo->create_action(TTR("Edit Poly (Remove Point)")); - undo_redo->add_undo_method(node,"set_polygon",poly); - poly.remove(closest_idx); - undo_redo->add_do_method(node,"set_polygon",poly); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - return true; - } - - } - - - - } break; - } - - -#endif - } break; - case InputEvent::MOUSE_MOTION: { - - const InputEventMouseMotion &mm=p_event.mouse_motion; - - - if ( action!=ACTION_NONE) { - - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - Vector2 gpoint = Point2(mm.x,mm.y); - Vector2 cpoint = !mm.mod.alt? canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)) - : node->get_global_transform().affine_inverse().xform( canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)) ); - - Ref<Curve2D> curve = node->get_curve(); - - Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from); - - switch(action) { - - case ACTION_MOVING_POINT: { - - curve->set_point_pos(action_point,cpoint); - } break; - case ACTION_MOVING_IN: { - - curve->set_point_in(action_point,new_pos); - - } break; - case ACTION_MOVING_OUT: { - - curve->set_point_out(action_point,new_pos); - - } break; - } - - - canvas_item_editor->get_viewport_control()->update(); - return true; - } - -#if 0 - if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { - - - Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - - Vector2 gpoint = Point2(mm.x,mm.y); - edited_point_pos = canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)); - canvas_item_editor->update(); - - } -#endif - } break; - } - - return false; -} -void Path2DEditor::_canvas_draw() { - - if (!node) - return ; - - if (!node->is_visible_in_tree()) - return; - - if (!node->get_curve().is_valid()) - return ; - - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - Ref<Texture> handle= get_icon("EditorHandle","EditorIcons"); - Size2 handle_size = handle->get_size(); - - Ref<Curve2D> curve = node->get_curve(); - - int len = curve->get_point_count(); - Control *vpc = canvas_item_editor->get_viewport_control(); - - - for(int i=0;i<len;i++) { - - - Vector2 point = xform.xform(curve->get_point_pos(i)); - vpc->draw_texture_rect(handle,Rect2(point-handle_size*0.5,handle_size),false,Color(1,1,1,1)); - - if (i<len-1) { - Vector2 pointout = xform.xform(curve->get_point_pos(i)+curve->get_point_out(i)); - vpc->draw_line(point,pointout,Color(0.5,0.5,1.0,0.8),1.0); - vpc->draw_texture_rect(handle, Rect2(pointout-handle_size*0.5,handle_size),false,Color(1,0.5,1,0.3)); - } - - if (i>0) { - Vector2 pointin = xform.xform(curve->get_point_pos(i)+curve->get_point_in(i)); - vpc->draw_line(point,pointin,Color(0.5,0.5,1.0,0.8),1.0); - vpc->draw_texture_rect(handle, Rect2(pointin-handle_size*0.5,handle_size),false,Color(1,0.5,1,0.3)); - } - - } - -} - -void Path2DEditor::_node_visibility_changed() { - if (!node) - return; - - canvas_item_editor->get_viewport_control()->update(); -} - -void Path2DEditor::edit(Node *p_path2d) { - - if (!canvas_item_editor) { - canvas_item_editor=CanvasItemEditor::get_singleton(); - } - - if (p_path2d) { - - node=p_path2d->cast_to<Path2D>(); - if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) - canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw"); - if (!node->is_connected("visibility_changed", this, "_node_visibility_changed")) - node->connect("visibility_changed", this, "_node_visibility_changed"); - - - } else { - - if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) - canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw"); - - // node may have been deleted at this point - if (node && node->is_connected("visibility_changed", this, "_node_visibility_changed")) - node->disconnect("visibility_changed", this, "_node_visibility_changed"); - node=NULL; - } - -} - -void Path2DEditor::_bind_methods() { - - //ClassDB::bind_method(D_METHOD("_menu_option"),&Path2DEditor::_menu_option); - ClassDB::bind_method(D_METHOD("_canvas_draw"),&Path2DEditor::_canvas_draw); - ClassDB::bind_method(D_METHOD("_node_visibility_changed"),&Path2DEditor::_node_visibility_changed); - ClassDB::bind_method(D_METHOD("_mode_selected"),&Path2DEditor::_mode_selected); -} - -void Path2DEditor::_mode_selected(int p_mode) { - - if (p_mode==MODE_CREATE) { - - curve_create->set_pressed(true); - curve_edit->set_pressed(false); - curve_edit_curve->set_pressed(false); - curve_del->set_pressed(false); - } else if (p_mode==MODE_EDIT) { - - curve_create->set_pressed(false); - curve_edit->set_pressed(true); - curve_edit_curve->set_pressed(false); - curve_del->set_pressed(false); - } else if (p_mode==MODE_EDIT_CURVE) { - - curve_create->set_pressed(false); - curve_edit->set_pressed(false); - curve_edit_curve->set_pressed(true); - curve_del->set_pressed(false); - } else if (p_mode==MODE_DELETE) { - - curve_create->set_pressed(false); - curve_edit->set_pressed(false); - curve_edit_curve->set_pressed(false); - curve_del->set_pressed(true); - } else if (p_mode==ACTION_CLOSE) { - - //? - - if (!node->get_curve().is_valid()) - return ; - if (node->get_curve()->get_point_count()<3) - return; - - Vector2 begin = node->get_curve()->get_point_pos(0); - Vector2 end = node->get_curve()->get_point_pos( node->get_curve()->get_point_count() -1 ); - if (begin.distance_to(end)<CMP_EPSILON) - return; - - undo_redo->create_action(TTR("Remove Point from Curve")); - undo_redo->add_do_method(node->get_curve().ptr(),"add_point",begin); - undo_redo->add_undo_method(node->get_curve().ptr(),"remove_point",node->get_curve()->get_point_count()); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - return; - } - - mode=Mode(p_mode); - -} - -Path2DEditor::Path2DEditor(EditorNode *p_editor) { - - canvas_item_editor=NULL; - editor=p_editor; - undo_redo = editor->get_undo_redo(); - - mode=MODE_EDIT; - - action=ACTION_NONE; -#if 0 - options = memnew( MenuButton ); - add_child(options); - options->set_area_as_parent_rect(); - options->set_text("Polygon"); - //options->get_popup()->add_item("Parse BBCode",PARSE_BBCODE); - options->get_popup()->connect("id_pressed", this,"_menu_option"); -#endif - - base_hb = memnew( HBoxContainer ); - CanvasItemEditor::get_singleton()->add_control_to_menu_panel(base_hb); - - sep = memnew( VSeparator); - base_hb->add_child(sep); - curve_edit = memnew( ToolButton ); - curve_edit->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveEdit","EditorIcons")); - curve_edit->set_toggle_mode(true); - curve_edit->set_focus_mode(Control::FOCUS_NONE); - curve_edit->set_tooltip(TTR("Select Points")+"\n"+TTR("Shift+Drag: Select Control Points")+"\n"+keycode_get_string(KEY_MASK_CMD)+TTR("Click: Add Point")+"\n"+TTR("Right Click: Delete Point")); - curve_edit->connect("pressed",this,"_mode_selected",varray(MODE_EDIT)); - base_hb->add_child(curve_edit); - curve_edit_curve = memnew( ToolButton ); - curve_edit_curve->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveCurve","EditorIcons")); - curve_edit_curve->set_toggle_mode(true); - curve_edit_curve->set_focus_mode(Control::FOCUS_NONE); - curve_edit_curve->set_tooltip(TTR("Select Control Points (Shift+Drag)")); - curve_edit_curve->connect("pressed",this,"_mode_selected",varray(MODE_EDIT_CURVE)); - base_hb->add_child(curve_edit_curve); - curve_create = memnew( ToolButton ); - curve_create->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveCreate","EditorIcons")); - curve_create->set_toggle_mode(true); - curve_create->set_focus_mode(Control::FOCUS_NONE); - curve_create->set_tooltip(TTR("Add Point (in empty space)")+"\n"+TTR("Split Segment (in curve)")); - curve_create->connect("pressed",this,"_mode_selected",varray(MODE_CREATE)); - base_hb->add_child(curve_create); - curve_del = memnew( ToolButton ); - curve_del->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveDelete","EditorIcons")); - curve_del->set_toggle_mode(true); - curve_del->set_focus_mode(Control::FOCUS_NONE); - curve_del->set_tooltip(TTR("Delete Point")); - curve_del->connect("pressed",this,"_mode_selected",varray(MODE_DELETE)); - base_hb->add_child(curve_del); - curve_close = memnew( ToolButton ); - curve_close->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveClose","EditorIcons")); - curve_close->set_focus_mode(Control::FOCUS_NONE); - curve_close->set_tooltip(TTR("Close Curve")); - curve_close->connect("pressed",this,"_mode_selected",varray(ACTION_CLOSE)); - base_hb->add_child(curve_close); - base_hb->hide(); - - - - curve_edit->set_pressed(true); - - -} - - -void Path2DEditorPlugin::edit(Object *p_object) { - - path2d_editor->edit(p_object->cast_to<Node>()); -} - -bool Path2DEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("Path2D"); -} - -void Path2DEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - path2d_editor->show(); - path2d_editor->base_hb->show(); - - } else { - - path2d_editor->hide(); - path2d_editor->base_hb->hide(); - path2d_editor->edit(NULL); - } - -} - -Path2DEditorPlugin::Path2DEditorPlugin(EditorNode *p_node) { - - editor=p_node; - path2d_editor = memnew( Path2DEditor(p_node) ); - CanvasItemEditor::get_singleton()->add_control_to_menu_panel(path2d_editor); - path2d_editor->hide(); - - -} - - -Path2DEditorPlugin::~Path2DEditorPlugin() -{ -} - diff --git a/tools/editor/plugins/path_2d_editor_plugin.h b/tools/editor/plugins/path_2d_editor_plugin.h deleted file mode 100644 index aa940e4edf..0000000000 --- a/tools/editor/plugins/path_2d_editor_plugin.h +++ /dev/null @@ -1,126 +0,0 @@ -/*************************************************************************/ -/* path_2d_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef PATH_2D_EDITOR_PLUGIN_H -#define PATH_2D_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/2d/path_2d.h" -#include "scene/gui/tool_button.h" -#include "scene/gui/button_group.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ -class CanvasItemEditor; - -class Path2DEditor : public HBoxContainer { - - GDCLASS(Path2DEditor, HBoxContainer); - - UndoRedo *undo_redo; - - CanvasItemEditor *canvas_item_editor; - EditorNode *editor; - Panel *panel; - Path2D *node; - - HBoxContainer *base_hb; - Separator *sep; - - enum Mode { - MODE_CREATE, - MODE_EDIT, - MODE_EDIT_CURVE, - MODE_DELETE, - ACTION_CLOSE - }; - - Mode mode; - ToolButton *curve_create; - ToolButton *curve_edit; - ToolButton *curve_edit_curve; - ToolButton *curve_del; - ToolButton *curve_close; - - enum Action { - - ACTION_NONE, - ACTION_MOVING_POINT, - ACTION_MOVING_IN, - ACTION_MOVING_OUT, - }; - - - Action action; - int action_point; - Point2 moving_from; - Point2 moving_screen_from; - - void _mode_selected(int p_mode); - - void _canvas_draw(); - void _node_visibility_changed(); -friend class Path2DEditorPlugin; -protected: - void _notification(int p_what); - void _node_removed(Node *p_node); - static void _bind_methods(); -public: - - bool forward_gui_input(const InputEvent& p_event); - void edit(Node *p_path2d); - Path2DEditor(EditorNode *p_editor); -}; - -class Path2DEditorPlugin : public EditorPlugin { - - GDCLASS( Path2DEditorPlugin, EditorPlugin ); - - Path2DEditor *path2d_editor; - EditorNode *editor; - -public: - - virtual bool forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return path2d_editor->forward_gui_input(p_event); } - - virtual String get_name() const { return "Path2D"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - Path2DEditorPlugin(EditorNode *p_node); - ~Path2DEditorPlugin(); - -}; - - - -#endif // PATH_2D_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/path_editor_plugin.h b/tools/editor/plugins/path_editor_plugin.h deleted file mode 100644 index 79e978dc1d..0000000000 --- a/tools/editor/plugins/path_editor_plugin.h +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************/ -/* path_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef PATH_EDITOR_PLUGIN_H -#define PATH_EDITOR_PLUGIN_H - - -#include "tools/editor/spatial_editor_gizmos.h" -#include "scene/3d/path.h" -# if 0 -class PathSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(PathSpatialGizmo,EditorSpatialGizmo); - - Path* path; - mutable Vector3 original; - -public: - - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); - virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); - - void redraw(); - PathSpatialGizmo(Path* p_path=NULL); - -}; - -class PathEditorPlugin : public EditorPlugin { - - GDCLASS( PathEditorPlugin, EditorPlugin ); - - - Separator *sep; - ToolButton *curve_create; - ToolButton *curve_edit; - ToolButton *curve_del; - ToolButton *curve_close; - - EditorNode *editor; - - - Path *path; - - void _mode_changed(int p_idx); - void _close_curve(); -protected: - void _notification(int p_what); - static void _bind_methods(); - -public: - - Path *get_edited_path() { return path; } - - static PathEditorPlugin* singleton; - Ref<FixedSpatialMaterial> path_material; - Ref<FixedSpatialMaterial> path_thin_material; - virtual bool forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event); - - //virtual bool forward_gui_input(const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); } - virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial* p_spatial); - virtual String get_name() const { return "Path"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - PathEditorPlugin(EditorNode *p_node); - ~PathEditorPlugin(); - -}; - -#endif -#endif // PATH_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/polygon_2d_editor_plugin.cpp b/tools/editor/plugins/polygon_2d_editor_plugin.cpp deleted file mode 100644 index efb3e6c4bc..0000000000 --- a/tools/editor/plugins/polygon_2d_editor_plugin.cpp +++ /dev/null @@ -1,1028 +0,0 @@ -/*************************************************************************/ -/* polygon_2d_editor_plugin.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 "polygon_2d_editor_plugin.h" - -#include "canvas_item_editor_plugin.h" -#include "os/file_access.h" -#include "tools/editor/editor_settings.h" -#include "os/keyboard.h" -#include "os/input.h" - -void Polygon2DEditor::_notification(int p_what) { - - switch(p_what) { - - case NOTIFICATION_READY: { - - button_create->set_icon( get_icon("Edit","EditorIcons")); - button_edit->set_icon( get_icon("MovePoint","EditorIcons")); - button_edit->set_pressed(true); - button_uv->set_icon( get_icon("Uv","EditorIcons")); - - uv_button[UV_MODE_EDIT_POINT]->set_icon(get_icon("ToolSelect","EditorIcons")); - uv_button[UV_MODE_MOVE]->set_icon(get_icon("ToolMove","EditorIcons")); - uv_button[UV_MODE_ROTATE]->set_icon(get_icon("ToolRotate","EditorIcons")); - uv_button[UV_MODE_SCALE]->set_icon(get_icon("ToolScale","EditorIcons")); - - b_snap_grid->set_icon( get_icon("Grid", "EditorIcons")); - b_snap_enable->set_icon( get_icon("Snap", "EditorIcons")); - uv_icon_zoom->set_texture( get_icon("Zoom", "EditorIcons")); - - get_tree()->connect("node_removed", this, "_node_removed"); - - } break; - case NOTIFICATION_FIXED_PROCESS: { - - - } break; - } - -} -void Polygon2DEditor::_node_removed(Node *p_node) { - - if(p_node==node) { - edit(NULL); - hide(); - - canvas_item_editor->get_viewport_control()->update(); - } - -} - - -void Polygon2DEditor::_menu_option(int p_option) { - - switch(p_option) { - - case MODE_CREATE: { - - mode=MODE_CREATE; - button_create->set_pressed(true); - button_edit->set_pressed(false); - } break; - case MODE_EDIT: { - - mode=MODE_EDIT; - button_create->set_pressed(false); - button_edit->set_pressed(true); - } break; - case MODE_EDIT_UV: { - - if (node->get_texture().is_null()) { - - error->set_text("No texture in this polygon.\nSet a texture to be able to edit UV."); - error->popup_centered_minsize(); - return; - } - - - PoolVector<Vector2> points = node->get_polygon(); - PoolVector<Vector2> uvs = node->get_uv(); - if (uvs.size()!=points.size()) { - undo_redo->create_action(TTR("Create UV Map")); - undo_redo->add_do_method(node,"set_uv",points); - undo_redo->add_undo_method(node,"set_uv",uvs); - undo_redo->add_do_method(uv_edit_draw,"update"); - undo_redo->add_undo_method(uv_edit_draw,"update"); - undo_redo->commit_action(); - - } - - - uv_edit->popup_centered_ratio(0.85); - } break; - case UVEDIT_POLYGON_TO_UV: { - - PoolVector<Vector2> points = node->get_polygon(); - if (points.size()==0) - break; - PoolVector<Vector2> uvs = node->get_uv(); - undo_redo->create_action(TTR("Create UV Map")); - undo_redo->add_do_method(node,"set_uv",points); - undo_redo->add_undo_method(node,"set_uv",uvs); - undo_redo->add_do_method(uv_edit_draw,"update"); - undo_redo->add_undo_method(uv_edit_draw,"update"); - undo_redo->commit_action(); - - - } break; - case UVEDIT_UV_TO_POLYGON: { - - PoolVector<Vector2> points = node->get_polygon(); - PoolVector<Vector2> uvs = node->get_uv(); - if (uvs.size()==0) - break; - - undo_redo->create_action(TTR("Create UV Map")); - undo_redo->add_do_method(node,"set_polygon",uvs); - undo_redo->add_undo_method(node,"set_polygon",points); - undo_redo->add_do_method(uv_edit_draw,"update"); - undo_redo->add_undo_method(uv_edit_draw,"update"); - undo_redo->commit_action(); - - } break; - case UVEDIT_UV_CLEAR: { - - PoolVector<Vector2> uvs = node->get_uv(); - if (uvs.size()==0) - break; - undo_redo->create_action(TTR("Create UV Map")); - undo_redo->add_do_method(node,"set_uv",PoolVector<Vector2>()); - undo_redo->add_undo_method(node,"set_uv",uvs); - undo_redo->add_do_method(uv_edit_draw,"update"); - undo_redo->add_undo_method(uv_edit_draw,"update"); - undo_redo->commit_action(); - - } break; - - - } -} - -void Polygon2DEditor::_set_use_snap(bool p_use) -{ - use_snap=p_use; -} - -void Polygon2DEditor::_set_show_grid(bool p_show) -{ - snap_show_grid=p_show; - uv_edit_draw->update(); -} - -void Polygon2DEditor::_set_snap_off_x(float p_val) -{ - snap_offset.x=p_val; - uv_edit_draw->update(); -} - -void Polygon2DEditor::_set_snap_off_y(float p_val) -{ - snap_offset.y=p_val; - uv_edit_draw->update(); -} - -void Polygon2DEditor::_set_snap_step_x(float p_val) -{ - snap_step.x=p_val; - uv_edit_draw->update(); -} - -void Polygon2DEditor::_set_snap_step_y(float p_val) -{ - snap_step.y=p_val; - uv_edit_draw->update(); -} - -void Polygon2DEditor::_wip_close() { - - undo_redo->create_action(TTR("Create Poly")); - undo_redo->add_undo_method(node,"set_polygon",node->get_polygon()); - undo_redo->add_do_method(node,"set_polygon",wip); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - wip.clear(); - wip_active=false; - mode=MODE_EDIT; - button_edit->set_pressed(true); - button_create->set_pressed(false); - edited_point=-1; -} - -bool Polygon2DEditor::forward_gui_input(const InputEvent& p_event) { - - if (node==NULL) - return false; - - switch(p_event.type) { - - case InputEvent::MOUSE_BUTTON: { - - const InputEventMouseButton &mb=p_event.mouse_button; - - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - - - Vector2 gpoint = Point2(mb.x,mb.y); - Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); - cpoint=canvas_item_editor->snap_point(cpoint); - cpoint = node->get_global_transform().affine_inverse().xform(cpoint); - - - Vector<Vector2> poly = Variant(node->get_polygon()); - - //first check if a point is to be added (segment split) - real_t grab_treshold=EDITOR_DEF("editors/poly_editor/point_grab_radius",8); - - switch(mode) { - - - case MODE_CREATE: { - - if (mb.button_index==BUTTON_LEFT && mb.pressed) { - - - if (!wip_active) { - - wip.clear(); - wip.push_back( cpoint-node->get_offset() ); - wip_active=true; - edited_point_pos=cpoint; - canvas_item_editor->get_viewport_control()->update(); - edited_point=1; - return true; - } else { - - - if (wip.size()>1 && xform.xform(wip[0]+node->get_offset()).distance_to(gpoint)<grab_treshold) { - //wip closed - _wip_close(); - - return true; - } else { - - wip.push_back( cpoint-node->get_offset() ); - edited_point=wip.size(); - canvas_item_editor->get_viewport_control()->update(); - return true; - - //add wip point - } - } - } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) { - _wip_close(); - } - - - - } break; - - case MODE_EDIT: { - - if (mb.button_index==BUTTON_LEFT) { - if (mb.pressed) { - - if (mb.mod.control) { - - - if (poly.size() < 3) { - - undo_redo->create_action(TTR("Edit Poly")); - undo_redo->add_undo_method(node,"set_polygon",poly); - poly.push_back(cpoint); - undo_redo->add_do_method(node,"set_polygon",poly); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - return true; - } - - //search edges - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 points[2] ={ xform.xform(poly[i]+node->get_offset()), - xform.xform(poly[(i+1)%poly.size()]+node->get_offset()) }; - - Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points); - if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2) - continue; //not valid to reuse point - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - - } - - if (closest_idx>=0) { - - pre_move_edit=poly; - poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos)-node->get_offset()); - edited_point=closest_idx+1; - edited_point_pos=xform.affine_inverse().xform(closest_pos); - node->set_polygon(Variant(poly)); - canvas_item_editor->get_viewport_control()->update(); - return true; - } - } else { - - //look for points to move - - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 cp =xform.xform(poly[i]+node->get_offset()); - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - } - - if (closest_idx>=0) { - - pre_move_edit=poly; - edited_point=closest_idx; - edited_point_pos=xform.affine_inverse().xform(closest_pos); - canvas_item_editor->get_viewport_control()->update(); - return true; - } - } - } else { - - if (edited_point!=-1) { - - //apply - - ERR_FAIL_INDEX_V(edited_point,poly.size(),false); - poly[edited_point]=edited_point_pos-node->get_offset(); - undo_redo->create_action(TTR("Edit Poly")); - undo_redo->add_do_method(node,"set_polygon",poly); - undo_redo->add_undo_method(node,"set_polygon",pre_move_edit); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - - edited_point=-1; - return true; - } - } - } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) { - - - - int closest_idx=-1; - Vector2 closest_pos; - real_t closest_dist=1e10; - for(int i=0;i<poly.size();i++) { - - Vector2 cp =xform.xform(poly[i]+node->get_offset()); - - real_t d = cp.distance_to(gpoint); - if (d<closest_dist && d<grab_treshold) { - closest_dist=d; - closest_pos=cp; - closest_idx=i; - } - - } - - if (closest_idx>=0) { - - - undo_redo->create_action(TTR("Edit Poly (Remove Point)")); - undo_redo->add_undo_method(node,"set_polygon",poly); - poly.remove(closest_idx); - undo_redo->add_do_method(node,"set_polygon",poly); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update"); - undo_redo->commit_action(); - return true; - } - - } - - - - } break; - } - - - - } break; - case InputEvent::MOUSE_MOTION: { - - const InputEventMouseMotion &mm=p_event.mouse_motion; - - if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) { - - Vector2 gpoint = Point2(mm.x,mm.y); - Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); - cpoint=canvas_item_editor->snap_point(cpoint); - edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint); - - canvas_item_editor->get_viewport_control()->update(); - - } - - } break; - } - - return false; -} -void Polygon2DEditor::_canvas_draw() { - - if (!node) - return; - - Control *vpc = canvas_item_editor->get_viewport_control(); - - Vector<Vector2> poly; - - if (wip_active) - poly=wip; - else - poly=Variant(node->get_polygon()); - - - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - Ref<Texture> handle= get_icon("EditorHandle","EditorIcons"); - - for(int i=0;i<poly.size();i++) { - - - Vector2 p,p2; - p = i==edited_point ? edited_point_pos : (poly[i]+node->get_offset()); - if ((wip_active && i==poly.size()-1) || (((i+1)%poly.size())==edited_point)) - p2=edited_point_pos; - else - p2 = poly[(i+1)%poly.size()]+node->get_offset(); - - Vector2 point = xform.xform(p); - Vector2 next_point = xform.xform(p2); - - Color col=Color(1,0.3,0.1,0.8); - vpc->draw_line(point,next_point,col,2); - vpc->draw_texture(handle,point-handle->get_size()*0.5); - } -} - - -void Polygon2DEditor::_uv_mode(int p_mode) { - - - uv_mode=UVMode(p_mode); - for(int i=0;i<UV_MODE_MAX;i++) { - uv_button[i]->set_pressed(p_mode==i); - } -} - - -void Polygon2DEditor::_uv_input(const InputEvent& p_input) { - - - Transform2D mtx; - mtx.elements[2]=-uv_draw_ofs; - mtx.scale_basis(Vector2(uv_draw_zoom,uv_draw_zoom)); - - if (p_input.type==InputEvent::MOUSE_BUTTON) { - - - const InputEventMouseButton &mb=p_input.mouse_button; - - if (mb.button_index==BUTTON_LEFT) { - - - if (mb.pressed) { - - uv_drag_from=Vector2(mb.x,mb.y); - uv_drag=true; - uv_prev=node->get_uv(); - uv_move_current=uv_mode; - if (uv_move_current==UV_MODE_EDIT_POINT) { - - if (mb.mod.shift && mb.mod.command) - uv_move_current=UV_MODE_SCALE; - else if (mb.mod.shift) - uv_move_current=UV_MODE_MOVE; - else if (mb.mod.command) - uv_move_current=UV_MODE_ROTATE; - } - - if (uv_move_current==UV_MODE_EDIT_POINT) { - - uv_drag_index=-1; - for(int i=0;i<uv_prev.size();i++) { - - Vector2 tuv=mtx.xform(uv_prev[i]); - if (tuv.distance_to(Vector2(mb.x,mb.y))<8) { - uv_drag_from=tuv; - uv_drag_index=i; - } - } - - if (uv_drag_index==-1) { - uv_drag=false; - } - - } - } else if (uv_drag) { - - undo_redo->create_action(TTR("Transform UV Map")); - undo_redo->add_do_method(node,"set_uv",node->get_uv()); - undo_redo->add_undo_method(node,"set_uv",uv_prev); - undo_redo->add_do_method(uv_edit_draw,"update"); - undo_redo->add_undo_method(uv_edit_draw,"update"); - undo_redo->commit_action(); - - uv_drag=false; - } - - } else if (mb.button_index==BUTTON_RIGHT && mb.pressed) { - - if (uv_drag) { - - uv_drag=false; - node->set_uv(uv_prev); - uv_edit_draw->update(); - } - - } else if (mb.button_index==BUTTON_WHEEL_UP && mb.pressed) { - - uv_zoom->set_value( uv_zoom->get_value()/0.9 ); - } else if (mb.button_index==BUTTON_WHEEL_DOWN && mb.pressed) { - - uv_zoom->set_value( uv_zoom->get_value()*0.9); - } - - } else if (p_input.type==InputEvent::MOUSE_MOTION) { - - const InputEventMouseMotion &mm=p_input.mouse_motion; - - if (mm.button_mask&BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { - - Vector2 drag(mm.relative_x,mm.relative_y); - uv_hscroll->set_value( uv_hscroll->get_value()-drag.x ); - uv_vscroll->set_value( uv_vscroll->get_value()-drag.y ); - - } else if (uv_drag) { - - Vector2 uv_drag_to=snap_point(Vector2(mm.x,mm.y)); - Vector2 drag = mtx.affine_inverse().xform(uv_drag_to) - mtx.affine_inverse().xform(uv_drag_from); - - - switch(uv_move_current) { - - case UV_MODE_EDIT_POINT: { - - PoolVector<Vector2> uv_new=uv_prev; - uv_new.set( uv_drag_index, uv_new[uv_drag_index]+drag ); - node->set_uv(uv_new); - } break; - case UV_MODE_MOVE: { - - PoolVector<Vector2> uv_new=uv_prev; - for(int i=0;i<uv_new.size();i++) - uv_new.set( i, uv_new[i]+drag ); - - node->set_uv(uv_new); - - - } break; - case UV_MODE_ROTATE: { - - Vector2 center; - PoolVector<Vector2> uv_new=uv_prev; - - for(int i=0;i<uv_new.size();i++) - center+=uv_prev[i]; - center/=uv_new.size(); - - float angle = (uv_drag_from - mtx.xform(center)).normalized().angle_to( (uv_drag_to - mtx.xform(center)).normalized() ); - - for(int i=0;i<uv_new.size();i++) { - Vector2 rel = uv_prev[i] - center; - rel=rel.rotated(angle); - uv_new.set(i,center+rel); - } - - node->set_uv(uv_new); - - } break; - case UV_MODE_SCALE: { - - Vector2 center; - PoolVector<Vector2> uv_new=uv_prev; - - for(int i=0;i<uv_new.size();i++) - center+=uv_prev[i]; - center/=uv_new.size(); - - float from_dist = uv_drag_from.distance_to(mtx.xform(center)); - float to_dist = uv_drag_to.distance_to(mtx.xform(center)); - if (from_dist<2) - break; - - float scale = to_dist/from_dist; - - - for(int i=0;i<uv_new.size();i++) { - Vector2 rel = uv_prev[i] - center; - rel=rel*scale; - uv_new.set(i,center+rel); - } - - node->set_uv(uv_new); - } break; - - - } - uv_edit_draw->update(); - } - - } - -} - - -void Polygon2DEditor::_uv_scroll_changed(float) { - - if (updating_uv_scroll) - return; - - uv_draw_ofs.x=uv_hscroll->get_value(); - uv_draw_ofs.y=uv_vscroll->get_value(); - uv_draw_zoom=uv_zoom->get_value(); - uv_edit_draw->update(); -} - -void Polygon2DEditor::_uv_draw() { - - Ref<Texture> base_tex = node->get_texture(); - if (base_tex.is_null()) - return; - - Transform2D mtx; - mtx.elements[2]=-uv_draw_ofs; - mtx.scale_basis(Vector2(uv_draw_zoom,uv_draw_zoom)); - - VS::get_singleton()->canvas_item_add_set_transform(uv_edit_draw->get_canvas_item(),mtx); - uv_edit_draw->draw_texture(base_tex,Point2()); - VS::get_singleton()->canvas_item_add_set_transform(uv_edit_draw->get_canvas_item(),Transform2D()); - - if (snap_show_grid) { - Size2 s = uv_edit_draw->get_size(); - int last_cell; - - if (snap_step.x!=0) { - for(int i=0;i<s.width;i++) { - int cell = Math::fast_ftoi(Math::floor((mtx.affine_inverse().xform(Vector2(i,0)).x-snap_offset.x)/snap_step.x)); - if (i==0) - last_cell=cell; - if (last_cell!=cell) - uv_edit_draw->draw_line(Point2(i,0),Point2(i,s.height),Color(0.3,0.7,1,0.3)); - last_cell=cell; - } - } - - if (snap_step.y!=0) { - for(int i=0;i<s.height;i++) { - int cell = Math::fast_ftoi(Math::floor((mtx.affine_inverse().xform(Vector2(0,i)).y-snap_offset.y)/snap_step.y)); - if (i==0) - last_cell=cell; - if (last_cell!=cell) - uv_edit_draw->draw_line(Point2(0,i),Point2(s.width,i),Color(0.3,0.7,1,0.3)); - last_cell=cell; - } - } - } - - PoolVector<Vector2> uvs = node->get_uv(); - Ref<Texture> handle = get_icon("EditorHandle","EditorIcons"); - - Rect2 rect(Point2(),mtx.basis_xform(base_tex->get_size())); - rect.expand_to(mtx.basis_xform(uv_edit_draw->get_size())); - - for(int i=0;i<uvs.size();i++) { - - int next = (i+1)%uvs.size(); - uv_edit_draw->draw_line(mtx.xform(uvs[i]),mtx.xform(uvs[next]),Color(0.9,0.5,0.5),2); - uv_edit_draw->draw_texture(handle,mtx.xform(uvs[i])-handle->get_size()*0.5); - rect.expand_to(mtx.basis_xform(uvs[i])); - } - - rect=rect.grow(200); - updating_uv_scroll=true; - uv_hscroll->set_min(rect.pos.x); - uv_hscroll->set_max(rect.pos.x+rect.size.x); - uv_hscroll->set_page(uv_edit_draw->get_size().x); - uv_hscroll->set_value(uv_draw_ofs.x); - uv_hscroll->set_step(0.001); - - uv_vscroll->set_min(rect.pos.y); - uv_vscroll->set_max(rect.pos.y+rect.size.y); - uv_vscroll->set_page(uv_edit_draw->get_size().y); - uv_vscroll->set_value(uv_draw_ofs.y); - uv_vscroll->set_step(0.001); - updating_uv_scroll=false; - -} - -void Polygon2DEditor::edit(Node *p_collision_polygon) { - - if (!canvas_item_editor) { - canvas_item_editor=CanvasItemEditor::get_singleton(); - } - - if (p_collision_polygon) { - - node=p_collision_polygon->cast_to<Polygon2D>(); - if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) - canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw"); - - wip.clear(); - wip_active=false; - edited_point=-1; - - } else { - - node=NULL; - - if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) - canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw"); - - } - -} - -void Polygon2DEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_menu_option"),&Polygon2DEditor::_menu_option); - ClassDB::bind_method(D_METHOD("_canvas_draw"),&Polygon2DEditor::_canvas_draw); - ClassDB::bind_method(D_METHOD("_uv_mode"),&Polygon2DEditor::_uv_mode); - ClassDB::bind_method(D_METHOD("_uv_draw"),&Polygon2DEditor::_uv_draw); - ClassDB::bind_method(D_METHOD("_uv_input"),&Polygon2DEditor::_uv_input); - ClassDB::bind_method(D_METHOD("_uv_scroll_changed"),&Polygon2DEditor::_uv_scroll_changed); - ClassDB::bind_method(D_METHOD("_node_removed"),&Polygon2DEditor::_node_removed); - ClassDB::bind_method(D_METHOD("_set_use_snap"),&Polygon2DEditor::_set_use_snap); - ClassDB::bind_method(D_METHOD("_set_show_grid"),&Polygon2DEditor::_set_show_grid); - ClassDB::bind_method(D_METHOD("_set_snap_off_x"),&Polygon2DEditor::_set_snap_off_x); - ClassDB::bind_method(D_METHOD("_set_snap_off_y"),&Polygon2DEditor::_set_snap_off_y); - ClassDB::bind_method(D_METHOD("_set_snap_step_x"),&Polygon2DEditor::_set_snap_step_x); - ClassDB::bind_method(D_METHOD("_set_snap_step_y"),&Polygon2DEditor::_set_snap_step_y); - - -} - -inline float _snap_scalar(float p_offset, float p_step, float p_target) { - return p_step != 0 ? Math::stepify(p_target - p_offset, p_step) + p_offset : p_target; -} - -Vector2 Polygon2DEditor::snap_point(Vector2 p_target) const { - if (use_snap) { - p_target.x = _snap_scalar(snap_offset.x*uv_draw_zoom-uv_draw_ofs.x, snap_step.x*uv_draw_zoom, p_target.x); - p_target.y = _snap_scalar(snap_offset.y*uv_draw_zoom-uv_draw_ofs.y, snap_step.y*uv_draw_zoom, p_target.y); - } - - return p_target; -} - -Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) { - - node=NULL; - canvas_item_editor=NULL; - editor=p_editor; - undo_redo = editor->get_undo_redo(); - - snap_step=Vector2(10,10); - use_snap=false; - snap_show_grid=false; - - add_child( memnew( VSeparator )); - button_create = memnew( ToolButton ); - add_child(button_create); - button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE)); - button_create->set_toggle_mode(true); - - button_edit = memnew( ToolButton ); - add_child(button_edit); - button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT)); - button_edit->set_toggle_mode(true); - - button_uv = memnew( ToolButton ); - add_child(button_uv); - button_uv->connect("pressed",this,"_menu_option",varray(MODE_EDIT_UV)); - - //add_constant_override("separation",0); - -#if 0 - options = memnew( MenuButton ); - add_child(options); - options->set_area_as_parent_rect(); - options->set_text("Polygon"); - //options->get_popup()->add_item("Parse BBCode",PARSE_BBCODE); - options->get_popup()->connect("id_pressed", this,"_menu_option"); -#endif - - mode = MODE_EDIT; - wip_active=false; - - uv_mode=UV_MODE_EDIT_POINT; - uv_edit = memnew( AcceptDialog ); - add_child(uv_edit); - uv_edit->set_title(TTR("Polygon 2D UV Editor")); - uv_edit->set_self_modulate(Color(1,1,1,0.9)); - - VBoxContainer *uv_main_vb = memnew( VBoxContainer ); - uv_edit->add_child(uv_main_vb); - //uv_edit->set_child_rect(uv_main_vb); - HBoxContainer *uv_mode_hb = memnew( HBoxContainer ); - uv_main_vb->add_child(uv_mode_hb); - for(int i=0;i<UV_MODE_MAX;i++) { - - uv_button[i]=memnew( ToolButton ); - uv_button[i]->set_toggle_mode(true); - uv_mode_hb->add_child(uv_button[i]); - uv_button[i]->connect("pressed",this,"_uv_mode",varray(i)); - uv_button[i]->set_focus_mode(FOCUS_NONE); - } - - uv_button[0]->set_tooltip(TTR("Move Point")+"\n"+TTR("Ctrl: Rotate")+"\n"+TTR("Shift: Move All")+"\n"+TTR("Shift+Ctrl: Scale")); - uv_button[1]->set_tooltip(TTR("Move Polygon")); - uv_button[2]->set_tooltip(TTR("Rotate Polygon")); - uv_button[3]->set_tooltip(TTR("Scale Polygon")); - - uv_button[0]->set_pressed(true); - HBoxContainer *uv_main_hb = memnew( HBoxContainer ); - uv_main_vb->add_child(uv_main_hb); - uv_edit_draw = memnew( Control ); - uv_main_hb->add_child(uv_edit_draw); - uv_main_hb->set_v_size_flags(SIZE_EXPAND_FILL); - uv_edit_draw->set_h_size_flags(SIZE_EXPAND_FILL); - uv_menu = memnew( MenuButton ); - uv_mode_hb->add_child(uv_menu); - uv_menu->set_text(TTR("Edit")); - uv_menu->get_popup()->add_item(TTR("Polygon->UV"),UVEDIT_POLYGON_TO_UV); - uv_menu->get_popup()->add_item(TTR("UV->Polygon"),UVEDIT_UV_TO_POLYGON); - uv_menu->get_popup()->add_separator(); - uv_menu->get_popup()->add_item(TTR("Clear UV"),UVEDIT_UV_CLEAR); - uv_menu->get_popup()->connect("id_pressed",this,"_menu_option"); - - uv_mode_hb->add_child( memnew( VSeparator )); - - b_snap_enable = memnew( ToolButton ); - uv_mode_hb->add_child(b_snap_enable); - b_snap_enable->set_text(TTR("Snap")); - b_snap_enable->set_focus_mode(FOCUS_NONE); - b_snap_enable->set_toggle_mode(true); - b_snap_enable->set_pressed(use_snap); - b_snap_enable->set_tooltip(TTR("Enable Snap")); - b_snap_enable->connect("toggled",this,"_set_use_snap"); - - b_snap_grid = memnew( ToolButton ); - uv_mode_hb->add_child(b_snap_grid); - b_snap_grid->set_text(TTR("Grid")); - b_snap_grid->set_focus_mode(FOCUS_NONE); - b_snap_grid->set_toggle_mode(true); - b_snap_grid->set_pressed(snap_show_grid); - b_snap_grid->set_tooltip(TTR("Show Grid")); - b_snap_grid->connect("toggled",this,"_set_show_grid"); - - uv_mode_hb->add_child( memnew( VSeparator )); - uv_mode_hb->add_child( memnew( Label(TTR("Grid Offset:")) ) ); - - SpinBox *sb_off_x = memnew( SpinBox ); - sb_off_x->set_min(-256); - sb_off_x->set_max(256); - sb_off_x->set_step(1); - sb_off_x->set_value(snap_offset.x); - sb_off_x->set_suffix("px"); - sb_off_x->connect("value_changed", this, "_set_snap_off_x"); - uv_mode_hb->add_child(sb_off_x); - - SpinBox *sb_off_y = memnew( SpinBox ); - sb_off_y->set_min(-256); - sb_off_y->set_max(256); - sb_off_y->set_step(1); - sb_off_y->set_value(snap_offset.y); - sb_off_y->set_suffix("px"); - sb_off_y->connect("value_changed", this, "_set_snap_off_y"); - uv_mode_hb->add_child(sb_off_y); - - uv_mode_hb->add_child( memnew( VSeparator )); - uv_mode_hb->add_child( memnew( Label(TTR("Grid Step:")) ) ); - - SpinBox *sb_step_x = memnew( SpinBox ); - sb_step_x->set_min(-256); - sb_step_x->set_max(256); - sb_step_x->set_step(1); - sb_step_x->set_value(snap_step.x); - sb_step_x->set_suffix("px"); - sb_step_x->connect("value_changed", this, "_set_snap_step_x"); - uv_mode_hb->add_child(sb_step_x); - - SpinBox *sb_step_y = memnew( SpinBox ); - sb_step_y->set_min(-256); - sb_step_y->set_max(256); - sb_step_y->set_step(1); - sb_step_y->set_value(snap_step.y); - sb_step_y->set_suffix("px"); - sb_step_y->connect("value_changed", this, "_set_snap_step_y"); - uv_mode_hb->add_child(sb_step_y); - - uv_mode_hb->add_child( memnew( VSeparator )); - uv_icon_zoom = memnew( TextureRect ); - uv_mode_hb->add_child( uv_icon_zoom ); - uv_zoom = memnew( HSlider ); - uv_zoom->set_min(0.01); - uv_zoom->set_max(4); - uv_zoom->set_value(1); - uv_zoom->set_step(0.01); - uv_mode_hb->add_child(uv_zoom); - uv_zoom->set_custom_minimum_size(Size2(200,0)); - uv_zoom_value = memnew( SpinBox ); - uv_zoom->share(uv_zoom_value); - uv_zoom_value->set_custom_minimum_size(Size2(50,0)); - uv_mode_hb->add_child(uv_zoom_value); - uv_zoom->connect("value_changed",this,"_uv_scroll_changed"); - - - - uv_vscroll = memnew( VScrollBar); - uv_main_hb->add_child(uv_vscroll); - uv_vscroll->connect("value_changed",this,"_uv_scroll_changed"); - uv_hscroll = memnew( HScrollBar ); - uv_main_vb->add_child(uv_hscroll); - uv_hscroll->connect("value_changed",this,"_uv_scroll_changed"); - - uv_edit_draw->connect("draw",this,"_uv_draw"); - uv_edit_draw->connect("gui_input",this,"_uv_input"); - uv_draw_zoom=1.0; - uv_drag_index=-1; - uv_drag=false; - updating_uv_scroll=false; - - error = memnew( AcceptDialog); - add_child(error); - - uv_edit_draw->set_clip_contents(true); - -} - - -void Polygon2DEditorPlugin::edit(Object *p_object) { - - - collision_polygon_editor->edit(p_object->cast_to<Node>()); -} - -bool Polygon2DEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("Polygon2D"); -} - -void Polygon2DEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - collision_polygon_editor->show(); - } else { - - collision_polygon_editor->hide(); - collision_polygon_editor->edit(NULL); - } - -} - -Polygon2DEditorPlugin::Polygon2DEditorPlugin(EditorNode *p_node) { - - editor=p_node; - collision_polygon_editor = memnew( Polygon2DEditor(p_node) ); - CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor); - - collision_polygon_editor->hide(); - -} - - -Polygon2DEditorPlugin::~Polygon2DEditorPlugin() -{ -} - diff --git a/tools/editor/plugins/polygon_2d_editor_plugin.h b/tools/editor/plugins/polygon_2d_editor_plugin.h deleted file mode 100644 index 6011ee1f87..0000000000 --- a/tools/editor/plugins/polygon_2d_editor_plugin.h +++ /dev/null @@ -1,167 +0,0 @@ -/*************************************************************************/ -/* polygon_2d_editor_plugin.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. */ -/*************************************************************************/ -#ifndef POLYGON_2D_EDITOR_PLUGIN_H -#define POLYGON_2D_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/2d/polygon_2d.h" -#include "scene/gui/tool_button.h" -#include "scene/gui/button_group.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ -class CanvasItemEditor; - -class Polygon2DEditor : public HBoxContainer { - - GDCLASS(Polygon2DEditor, HBoxContainer ); - - UndoRedo *undo_redo; - enum Mode { - - MODE_CREATE, - MODE_EDIT, - MODE_EDIT_UV, - UVEDIT_POLYGON_TO_UV, - UVEDIT_UV_TO_POLYGON, - UVEDIT_UV_CLEAR - - }; - - enum UVMode { - UV_MODE_EDIT_POINT, - UV_MODE_MOVE, - UV_MODE_ROTATE, - UV_MODE_SCALE, - UV_MODE_MAX - }; - - Mode mode; - - UVMode uv_mode; - AcceptDialog *uv_edit; - ToolButton *uv_button[4]; - ToolButton *b_snap_enable; - ToolButton *b_snap_grid; - Control *uv_edit_draw; - HSlider *uv_zoom; - SpinBox *uv_zoom_value; - HScrollBar *uv_hscroll; - VScrollBar *uv_vscroll; - MenuButton *uv_menu; - TextureRect *uv_icon_zoom; - - Vector2 uv_draw_ofs; - float uv_draw_zoom; - PoolVector<Vector2> uv_prev; - int uv_drag_index; - bool uv_drag; - UVMode uv_move_current; - Vector2 uv_drag_from; - bool updating_uv_scroll; - - - - AcceptDialog *error; - - ToolButton *button_create; - ToolButton *button_edit; - ToolButton *button_uv; - - CanvasItemEditor *canvas_item_editor; - EditorNode *editor; - Panel *panel; - Polygon2D *node; - MenuButton *options; - - int edited_point; - Vector2 edited_point_pos; - Vector<Vector2> pre_move_edit; - Vector<Vector2> wip; - bool wip_active; - - bool use_snap; - bool snap_show_grid; - Vector2 snap_offset; - Vector2 snap_step; - - void _uv_scroll_changed(float); - void _uv_input(const InputEvent& p_input); - void _uv_draw(); - void _uv_mode(int p_mode); - void _wip_close(); - void _canvas_draw(); - void _menu_option(int p_option); - - void _set_use_snap(bool p_use); - void _set_show_grid(bool p_show); - void _set_snap_off_x(float p_val); - void _set_snap_off_y(float p_val); - void _set_snap_step_x(float p_val); - void _set_snap_step_y(float p_val); - -protected: - void _notification(int p_what); - void _node_removed(Node *p_node); - static void _bind_methods(); - - Vector2 snap_point(Vector2 p_target) const; - -public: - - bool forward_gui_input(const InputEvent& p_event); - void edit(Node *p_collision_polygon); - Polygon2DEditor(EditorNode *p_editor); -}; - -class Polygon2DEditorPlugin : public EditorPlugin { - - GDCLASS( Polygon2DEditorPlugin, EditorPlugin ); - - Polygon2DEditor *collision_polygon_editor; - EditorNode *editor; - -public: - - virtual bool forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); } - - virtual String get_name() const { return "Polygon2D"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - Polygon2DEditorPlugin(EditorNode *p_node); - ~Polygon2DEditorPlugin(); - -}; - -#endif // POLYGON_2D_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/resource_preloader_editor_plugin.cpp b/tools/editor/plugins/resource_preloader_editor_plugin.cpp deleted file mode 100644 index de2245d98f..0000000000 --- a/tools/editor/plugins/resource_preloader_editor_plugin.cpp +++ /dev/null @@ -1,507 +0,0 @@ -/*************************************************************************/ -/* resource_preloader_editor_plugin.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 "resource_preloader_editor_plugin.h" - -#include "io/resource_loader.h" -#include "global_config.h" -#include "tools/editor/editor_settings.h" - - -void ResourcePreloaderEditor::_gui_input(InputEvent p_event) { - - -} - -void ResourcePreloaderEditor::_notification(int p_what) { - - if (p_what==NOTIFICATION_FIXED_PROCESS) { - - } - - if (p_what==NOTIFICATION_ENTER_TREE) { - load->set_icon( get_icon("Folder","EditorIcons") ); - _delete->set_icon( get_icon("Del","EditorIcons") ); - } - - if (p_what==NOTIFICATION_READY) { - - //NodePath("/root")->connect("node_removed", this,"_node_removed",Vector<Variant>(),true); - } - - if (p_what==NOTIFICATION_DRAW) { - - } -} - -void ResourcePreloaderEditor::_files_load_request(const Vector<String>& p_paths) { - - for(int i=0;i<p_paths.size();i++) { - - String path = p_paths[i]; - - RES resource; - resource = ResourceLoader::load(path); - - if (resource.is_null()) { - dialog->set_text(TTR("ERROR: Couldn't load resource!")); - dialog->set_title(TTR("Error!")); - //dialog->get_cancel()->set_text("Close"); - dialog->get_ok()->set_text(TTR("Close")); - dialog->popup_centered_minsize(); - return; ///beh should show an error i guess - } - - - String basename = path.get_file().get_basename(); - String name=basename; - int counter=1; - while(preloader->has_resource(name)) { - counter++; - name=basename+" "+itos(counter); - } - - undo_redo->create_action(TTR("Add Resource")); - undo_redo->add_do_method(preloader,"add_resource",name,resource); - undo_redo->add_undo_method(preloader,"remove_resource",name); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - } -} - -void ResourcePreloaderEditor::_load_pressed() { - - loading_scene=false; - - file->clear_filters(); - List<String> extensions; - ResourceLoader::get_recognized_extensions_for_type("",&extensions); - for(int i=0;i<extensions.size();i++) - file->add_filter("*."+extensions[i]); - - file->set_mode(EditorFileDialog::MODE_OPEN_FILES); - - file->popup_centered_ratio(); - -} - - -void ResourcePreloaderEditor::_item_edited() { - - if (!tree->get_selected()) - return; - - TreeItem *s = tree->get_selected(); - - if (tree->get_selected_column()==0) { - // renamed - String old_name=s->get_metadata(0); - String new_name=s->get_text(0); - if (old_name==new_name) - return; - - if (new_name=="" || new_name.find("\\")!=-1 || new_name.find("/")!=-1 || preloader->has_resource(new_name)) { - - s->set_text(0,old_name); - return; - } - - RES samp = preloader->get_resource(old_name); - undo_redo->create_action(TTR("Rename Resource")); - undo_redo->add_do_method(preloader,"remove_resource",old_name); - undo_redo->add_do_method(preloader,"add_resource",new_name,samp); - undo_redo->add_undo_method(preloader,"remove_resource",new_name); - undo_redo->add_undo_method(preloader,"add_resource",old_name,samp); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - - } - - -} - -void ResourcePreloaderEditor::_delete_confirm_pressed() { - - if (!tree->get_selected()) - return; - - String to_remove = tree->get_selected()->get_text(0); - undo_redo->create_action(TTR("Delete Resource")); - undo_redo->add_do_method(preloader,"remove_resource",to_remove); - undo_redo->add_undo_method(preloader,"add_resource",to_remove,preloader->get_resource(to_remove)); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); -} - - -void ResourcePreloaderEditor::_paste_pressed() { - - RES r=EditorSettings::get_singleton()->get_resource_clipboard(); - if (!r.is_valid()) { - dialog->set_text(TTR("Resource clipboard is empty!")); - dialog->set_title(TTR("Error!")); - //dialog->get_cancel()->set_text("Close"); - dialog->get_ok()->set_text(TTR("Close")); - dialog->popup_centered_minsize(); - return; ///beh should show an error i guess - } - - String name = r->get_name(); - if (name=="") - name=r->get_path().get_file(); - if (name=="") - name=r->get_class(); - - String basename = name; - int counter=1; - while(preloader->has_resource(name)) { - counter++; - name=basename+" "+itos(counter); - } - - undo_redo->create_action(TTR("Paste Resource")); - undo_redo->add_do_method(preloader,"add_resource",name,r); - undo_redo->add_undo_method(preloader,"remove_resource",name); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - -} - - -void ResourcePreloaderEditor::_delete_pressed() { - - - if (!tree->get_selected()) - return; - - _delete_confirm_pressed(); //it has undo.. why bother with a dialog.. - /* - dialog->set_title("Confirm..."); - dialog->set_text("Remove Resource '"+tree->get_selected()->get_text(0)+"' ?"); - //dialog->get_cancel()->set_text("Cancel"); - //dialog->get_ok()->show(); - dialog->get_ok()->set_text("Remove"); - dialog->popup_centered(Size2(300,60));*/ - -} - - -void ResourcePreloaderEditor::_update_library() { - - tree->clear(); - tree->set_hide_root(true); - TreeItem *root = tree->create_item(NULL); - - List<StringName> rnames; - preloader->get_resource_list(&rnames); - - List<String> names; - for(List<StringName>::Element *E=rnames.front();E;E=E->next()) { - names.push_back(E->get()); - } - - names.sort(); - - for(List<String>::Element *E=names.front();E;E=E->next()) { - - TreeItem *ti = tree->create_item(root); - ti->set_cell_mode(0,TreeItem::CELL_MODE_STRING); - ti->set_editable(0,true); - ti->set_selectable(0,true); - ti->set_text(0,E->get()); - ti->set_metadata(0,E->get()); - - - - RES r = preloader->get_resource(E->get()); - - ERR_CONTINUE(r.is_null()); - - ti->set_tooltip(0,r->get_path()); - String type = r->get_class(); - ti->set_text(1,type); - ti->set_selectable(1,false); - - if (has_icon(type,"EditorIcons")) - ti->set_icon( 1, get_icon(type,"EditorIcons") ); - - } - - //player->add_resource("default",resource); -} - - - -void ResourcePreloaderEditor::edit(ResourcePreloader* p_preloader) { - - preloader=p_preloader; - - - if (p_preloader) { - _update_library(); - } else { - - hide(); - set_fixed_process(false); - } - -} - - - -Variant ResourcePreloaderEditor::get_drag_data_fw(const Point2& p_point,Control* p_from) { - - TreeItem*ti =tree->get_item_at_pos(p_point); - if (!ti) - return Variant(); - - String name = ti->get_metadata(0); - - RES res = preloader->get_resource(name); - if (!res.is_valid()) - return Variant(); - - return EditorNode::get_singleton()->drag_resource(res,p_from); - -} - -bool ResourcePreloaderEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const { - - - - Dictionary d = p_data; - - if (!d.has("type")) - return false; - - if (d.has("from") && (Object*)(d["from"])==tree) - return false; - - if (String(d["type"])=="resource" && d.has("resource")) { - RES r=d["resource"]; - - return r.is_valid(); - } - - - if (String(d["type"])=="files") { - - Vector<String> files = d["files"]; - - if (files.size()==0) - return false; - - return true; - - } - return false; -} - -void ResourcePreloaderEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) { - - if (!can_drop_data_fw(p_point,p_data,p_from)) - return; - - Dictionary d = p_data; - - if (!d.has("type")) - return; - - - if (String(d["type"])=="resource" && d.has("resource")) { - RES r=d["resource"]; - - if (r.is_valid()) { - - String basename; - if (r->get_name()!="") { - basename=r->get_name(); - } else if (r->get_path().is_resource_file()) { - basename = r->get_path().get_basename(); - } else { - basename="Resource"; - } - - String name=basename; - int counter=0; - while(preloader->has_resource(name)) { - counter++; - name=basename+"_"+itos(counter); - } - - undo_redo->create_action(TTR("Add Resource")); - undo_redo->add_do_method(preloader,"add_resource",name,r); - undo_redo->add_undo_method(preloader,"remove_resource",name); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - } - } - - - if (String(d["type"])=="files") { - - Vector<String> files = d["files"]; - - _files_load_request(files); - } -} - - - -void ResourcePreloaderEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_gui_input"),&ResourcePreloaderEditor::_gui_input); - ClassDB::bind_method(D_METHOD("_load_pressed"),&ResourcePreloaderEditor::_load_pressed); - ClassDB::bind_method(D_METHOD("_item_edited"),&ResourcePreloaderEditor::_item_edited); - ClassDB::bind_method(D_METHOD("_delete_pressed"),&ResourcePreloaderEditor::_delete_pressed); - ClassDB::bind_method(D_METHOD("_paste_pressed"),&ResourcePreloaderEditor::_paste_pressed); - ClassDB::bind_method(D_METHOD("_delete_confirm_pressed"),&ResourcePreloaderEditor::_delete_confirm_pressed); - ClassDB::bind_method(D_METHOD("_files_load_request"),&ResourcePreloaderEditor::_files_load_request); - ClassDB::bind_method(D_METHOD("_update_library"),&ResourcePreloaderEditor::_update_library); - - - ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &ResourcePreloaderEditor::get_drag_data_fw); - ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &ResourcePreloaderEditor::can_drop_data_fw); - ClassDB::bind_method(D_METHOD("drop_data_fw"), &ResourcePreloaderEditor::drop_data_fw); - - -} - -ResourcePreloaderEditor::ResourcePreloaderEditor() { - - //add_style_override("panel", get_stylebox("panel","Panel")); - - VBoxContainer *vbc = memnew( VBoxContainer ); - add_child(vbc); - - HBoxContainer *hbc = memnew( HBoxContainer ); - vbc->add_child(hbc); - - load = memnew( Button ); - load->set_tooltip(TTR("Load Resource")); - hbc->add_child(load); - - - - _delete = memnew( Button ); - hbc->add_child(_delete); - - paste = memnew( Button ); - paste->set_text(TTR("Paste")); - hbc->add_child(paste); - - file = memnew( EditorFileDialog ); - add_child(file); - - - tree = memnew( Tree ); - tree->set_columns(2); - tree->set_column_min_width(0,3); - tree->set_column_min_width(1,1); - tree->set_column_expand(0,true); - tree->set_column_expand(1,true); - tree->set_v_size_flags(SIZE_EXPAND_FILL); - - tree->set_drag_forwarding(this); - vbc->add_child(tree); - - dialog = memnew( AcceptDialog ); - add_child( dialog ); - - load->connect("pressed", this,"_load_pressed"); - _delete->connect("pressed", this,"_delete_pressed"); - paste->connect("pressed", this,"_paste_pressed"); - file->connect("files_selected", this,"_files_load_request"); - //dialog->connect("confirmed", this,"_delete_confirm_pressed"); - tree->connect("item_edited", this,"_item_edited"); - loading_scene=false; - -} - - -void ResourcePreloaderEditorPlugin::edit(Object *p_object) { - - preloader_editor->set_undo_redo(&get_undo_redo()); - ResourcePreloader * s = p_object->cast_to<ResourcePreloader>(); - if (!s) - return; - - preloader_editor->edit(s); -} - -bool ResourcePreloaderEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("ResourcePreloader"); -} - -void ResourcePreloaderEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - //preloader_editor->show(); - button->show(); - editor->make_bottom_panel_item_visible(preloader_editor); - //preloader_editor->set_process(true); - } else { - - if (preloader_editor->is_visible_in_tree()) - editor->hide_bottom_panel(); - button->hide(); - //preloader_editor->hide(); - //preloader_editor->set_process(false); - } - -} - -ResourcePreloaderEditorPlugin::ResourcePreloaderEditorPlugin(EditorNode *p_node) { - - editor=p_node; - preloader_editor = memnew( ResourcePreloaderEditor ); - preloader_editor->set_custom_minimum_size(Size2(0,250)); - - button=editor->add_bottom_panel_item("ResourcePreloader",preloader_editor); - button->hide(); - - //preloader_editor->set_anchor( MARGIN_TOP, Control::ANCHOR_END); - //preloader_editor->set_margin( MARGIN_TOP, 120 ); - - - - -} - - -ResourcePreloaderEditorPlugin::~ResourcePreloaderEditorPlugin() -{ -} - - diff --git a/tools/editor/plugins/resource_preloader_editor_plugin.h b/tools/editor/plugins/resource_preloader_editor_plugin.h deleted file mode 100644 index 6990301ded..0000000000 --- a/tools/editor/plugins/resource_preloader_editor_plugin.h +++ /dev/null @@ -1,108 +0,0 @@ -/*************************************************************************/ -/* resource_preloader_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef RESOURCE_PRELOADER_EDITOR_PLUGIN_H -#define RESOURCE_PRELOADER_EDITOR_PLUGIN_H - - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/gui/tree.h" -#include "scene/main/resource_preloader.h" -#include "scene/gui/file_dialog.h" -#include "scene/gui/dialogs.h" - - -class ResourcePreloaderEditor : public PanelContainer { - - GDCLASS(ResourcePreloaderEditor, PanelContainer ); - - Button *load; - Button *_delete; - Button *paste; - Tree *tree; - bool loading_scene; - - - EditorFileDialog *file; - - AcceptDialog *dialog; - - ResourcePreloader *preloader; - - - void _load_pressed(); - void _load_scene_pressed(); - void _files_load_request(const Vector<String>& p_paths); - void _paste_pressed(); - void _delete_pressed(); - void _delete_confirm_pressed(); - void _update_library(); - void _item_edited(); - - UndoRedo *undo_redo; - - Variant get_drag_data_fw(const Point2& p_point,Control* p_from); - bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; - void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); - - -protected: - void _notification(int p_what); - void _gui_input(InputEvent p_event); - static void _bind_methods(); -public: - - void set_undo_redo(UndoRedo *p_undo_redo) {undo_redo=p_undo_redo; } - - void edit(ResourcePreloader* p_preloader); - ResourcePreloaderEditor(); -}; - -class ResourcePreloaderEditorPlugin : public EditorPlugin { - - GDCLASS( ResourcePreloaderEditorPlugin, EditorPlugin ); - - ResourcePreloaderEditor *preloader_editor; - EditorNode *editor; - Button *button; - -public: - - virtual String get_name() const { return "ResourcePreloader"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - ResourcePreloaderEditorPlugin(EditorNode *p_node); - ~ResourcePreloaderEditorPlugin(); - -}; - -#endif // RESOURCE_PRELOADER_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/rich_text_editor_plugin.h b/tools/editor/plugins/rich_text_editor_plugin.h deleted file mode 100644 index cf97d7517c..0000000000 --- a/tools/editor/plugins/rich_text_editor_plugin.h +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************/ -/* rich_text_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef RICH_TEXT_EDITOR_PLUGIN_H -#define RICH_TEXT_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/gui/rich_text_label.h" -#include "scene/gui/file_dialog.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -class RichTextEditor : public Control { - - GDCLASS(RichTextEditor, Control ); - - friend class RichTextEditorPlugin; - - enum { - - PARSE_BBCODE, - CLEAR - }; - - Panel *panel; - MenuButton *options; - RichTextLabel *node; - EditorFileDialog *file_dialog; - - void _file_selected(const String& p_path); - void _menu_option(int p_option); - -protected: - void _notification(int p_what); - void _node_removed(Node *p_node); - static void _bind_methods(); -public: - - void edit(Node *p_rich_text); - RichTextEditor(); -}; - -class RichTextEditorPlugin : public EditorPlugin { - - GDCLASS( RichTextEditorPlugin, EditorPlugin ); - - RichTextEditor *rich_text_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "RichText"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - RichTextEditorPlugin(EditorNode *p_node); - ~RichTextEditorPlugin(); - -}; - -#endif // RICH_TEXT_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/sample_editor_plugin.cpp b/tools/editor/plugins/sample_editor_plugin.cpp deleted file mode 100644 index 9445095771..0000000000 --- a/tools/editor/plugins/sample_editor_plugin.cpp +++ /dev/null @@ -1,451 +0,0 @@ -/*************************************************************************/ -/* sample_editor_plugin.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 "sample_editor_plugin.h" - -#if 0 -#include "io/resource_loader.h" -#include "global_config.h" -#include "tools/editor/editor_settings.h" - - - - -void SampleEditor::_gui_input(InputEvent p_event) { - - -} - -void SampleEditor::_notification(int p_what) { - - if (p_what==NOTIFICATION_FIXED_PROCESS) { - - } - - if (p_what==NOTIFICATION_ENTER_TREE) { - play->set_icon( get_icon("Play","EditorIcons") ); - stop->set_icon( get_icon("Stop","EditorIcons") ); - } - - if (p_what==NOTIFICATION_READY) { - - //get_scene()->connect("node_removed",this,"_node_removed"); - - } - - if (p_what==NOTIFICATION_DRAW) { - - } -} - -void SampleEditor::_play_pressed() { - - player->play("default",true); - stop->set_pressed(false); - play->set_pressed(true); -} -void SampleEditor::_stop_pressed() { - - player->stop_all(); - play->set_pressed(false); -} - -void SampleEditor::generate_preview_texture(const Ref<Sample>& p_sample,Ref<ImageTexture> &p_texture) { - - - PoolVector<uint8_t> data = p_sample->get_data(); - - PoolVector<uint8_t> img; - int w = p_texture->get_width(); - int h = p_texture->get_height(); - img.resize(w*h*3); - PoolVector<uint8_t>::Write imgdata = img.write(); - uint8_t * imgw = imgdata.ptr(); - PoolVector<uint8_t>::Read sampledata = data.read(); - const uint8_t *sdata=sampledata.ptr(); - - bool stereo = p_sample->is_stereo(); - bool _16=p_sample->get_format()==Sample::FORMAT_PCM16; - int len = p_sample->get_length(); - - if (len<1) - return; - - if (p_sample->get_format()==Sample::FORMAT_IMA_ADPCM) { - - - struct IMA_ADPCM_State { - - int16_t step_index; - int32_t predictor; - /* values at loop point */ - int16_t loop_step_index; - int32_t loop_predictor; - int32_t last_nibble; - int32_t loop_pos; - int32_t window_ofs; - const uint8_t *ptr; - } ima_adpcm; - - ima_adpcm.step_index=0; - ima_adpcm.predictor=0; - ima_adpcm.loop_step_index=0; - ima_adpcm.loop_predictor=0; - ima_adpcm.last_nibble=-1; - ima_adpcm.loop_pos=0x7FFFFFFF; - ima_adpcm.window_ofs=0; - ima_adpcm.ptr=NULL; - - - for(int i=0;i<w;i++) { - - float max[2]={-1e10,-1e10}; - float min[2]={1e10,1e10}; - int from = i*len/w; - int to = (i+1)*len/w; - if (to>=len) - to=len-1; - - for(int j=from;j<to;j++) { - - while(j>ima_adpcm.last_nibble) { - - static const int16_t _ima_adpcm_step_table[89] = { - 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, - 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, - 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, - 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, - 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, - 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, - 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, - 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 - }; - - static const int8_t _ima_adpcm_index_table[16] = { - -1, -1, -1, -1, 2, 4, 6, 8, - -1, -1, -1, -1, 2, 4, 6, 8 - }; - - int16_t nibble,diff,step; - - ima_adpcm.last_nibble++; - const uint8_t *src_ptr=sdata; - - int ofs = ima_adpcm.last_nibble>>1; - - if (stereo) - ofs*=2; - - nibble = (ima_adpcm.last_nibble&1)? - (src_ptr[ofs]>>4):(src_ptr[ofs]&0xF); - - step=_ima_adpcm_step_table[ima_adpcm.step_index]; - - ima_adpcm.step_index += _ima_adpcm_index_table[nibble]; - if (ima_adpcm.step_index<0) - ima_adpcm.step_index=0; - if (ima_adpcm.step_index>88) - ima_adpcm.step_index=88; - - diff = step >> 3 ; - if (nibble & 1) - diff += step >> 2 ; - if (nibble & 2) - diff += step >> 1 ; - if (nibble & 4) - diff += step ; - if (nibble & 8) - diff = -diff ; - - ima_adpcm.predictor+=diff; - if (ima_adpcm.predictor<-0x8000) - ima_adpcm.predictor=-0x8000; - else if (ima_adpcm.predictor>0x7FFF) - ima_adpcm.predictor=0x7FFF; - - - /* store loop if there */ - if (ima_adpcm.last_nibble==ima_adpcm.loop_pos) { - - ima_adpcm.loop_step_index = ima_adpcm.step_index; - ima_adpcm.loop_predictor = ima_adpcm.predictor; - } - - } - - float v=ima_adpcm.predictor/32767.0; - if (v>max[0]) - max[0]=v; - if (v<min[0]) - min[0]=v; - } - - for(int j=0;j<h;j++) { - float v = (j/(float)h) * 2.0 - 1.0; - uint8_t* imgofs = &imgw[(uint64_t(j)*w+i)*3]; - if (v>min[0] && v<max[0]) { - imgofs[0]=255; - imgofs[1]=150; - imgofs[2]=80; - } else { - imgofs[0]=0; - imgofs[1]=0; - imgofs[2]=0; - } - } - } - } else { - for(int i=0;i<w;i++) { - // i trust gcc will optimize this loop - float max[2]={-1e10,-1e10}; - float min[2]={1e10,1e10}; - int c=stereo?2:1; - int from = uint64_t(i)*len/w; - int to = (uint64_t(i)+1)*len/w; - if (to>=len) - to=len-1; - - if (_16) { - const int16_t*src =(const int16_t*)sdata; - - for(int j=0;j<c;j++) { - - for(int k=from;k<=to;k++) { - - float v = src[uint64_t(k)*c+j]/32768.0; - if (v>max[j]) - max[j]=v; - if (v<min[j]) - min[j]=v; - } - - } - } else { - - const int8_t*src =(const int8_t*)sdata; - - for(int j=0;j<c;j++) { - - for(int k=from;k<=to;k++) { - - float v = src[uint64_t(k)*c+j]/128.0; - if (v>max[j]) - max[j]=v; - if (v<min[j]) - min[j]=v; - } - - } - } - - if (!stereo) { - for(int j=0;j<h;j++) { - float v = (j/(float)h) * 2.0 - 1.0; - uint8_t* imgofs = &imgw[(uint64_t(j)*w+i)*3]; - if (v>min[0] && v<max[0]) { - imgofs[0]=255; - imgofs[1]=150; - imgofs[2]=80; - } else { - imgofs[0]=0; - imgofs[1]=0; - imgofs[2]=0; - } - } - } else { - - for(int j=0;j<h;j++) { - - int half; - float v; - if (j<(h/2)) { - half=0; - v = (j/(float)(h/2)) * 2.0 - 1.0; - } else { - half=1; - v = ((j-(h/2))/(float)(h/2)) * 2.0 - 1.0; - } - - uint8_t* imgofs = &imgw[(uint64_t(j)*w+i)*3]; - if (v>min[half] && v<max[half]) { - imgofs[0]=255; - imgofs[1]=150; - imgofs[2]=80; - } else { - imgofs[0]=0; - imgofs[1]=0; - imgofs[2]=0; - } - } - - } - - } - } - - imgdata = PoolVector<uint8_t>::Write(); - - - p_texture->set_data(Image(w,h,0,Image::FORMAT_RGB8,img)); - -} - -void SampleEditor::_update_sample() { - - player->stop_all(); - - generate_preview_texture(sample,peakdisplay); - info_label->set_text(TTR("Length:")+" "+String::num(sample->get_length()/(float)sample->get_mix_rate(),2)+"s"); - - if (library->has_sample("default")) - library->remove_sample("default"); - - library->add_sample("default",sample); -} - - - -void SampleEditor::edit(Ref<Sample> p_sample) { - - sample=p_sample; - - if (!sample.is_null()) - _update_sample(); - else { - - hide(); - set_fixed_process(false); - } - -} - - - -void SampleEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_gui_input"),&SampleEditor::_gui_input); - ClassDB::bind_method(D_METHOD("_play_pressed"),&SampleEditor::_play_pressed); - ClassDB::bind_method(D_METHOD("_stop_pressed"),&SampleEditor::_stop_pressed); - -} - -SampleEditor::SampleEditor() { - - player = memnew(SamplePlayer); - add_child(player); - add_style_override("panel", get_stylebox("panel","Panel")); - library = Ref<SampleLibrary>(memnew(SampleLibrary)); - player->set_sample_library(library); - sample_texframe = memnew( TextureRect ); - add_child(sample_texframe); - sample_texframe->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,5); - sample_texframe->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,5); - sample_texframe->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,30); - sample_texframe->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,5); - - info_label = memnew( Label ); - sample_texframe->add_child(info_label); - info_label->set_area_as_parent_rect(); - info_label->set_anchor_and_margin(MARGIN_TOP,ANCHOR_END,15); - info_label->set_margin(MARGIN_BOTTOM,4); - info_label->set_margin(MARGIN_RIGHT,4); - info_label->set_align(Label::ALIGN_RIGHT); - - - play = memnew( Button ); - - play->set_pos(Point2( 5, 5 )); - play->set_size( Size2(1,1 ) ); - play->set_toggle_mode(true); - add_child(play); - - stop = memnew( Button ); - - stop->set_pos(Point2( 35, 5 )); - stop->set_size( Size2(1,1 ) ); - stop->set_toggle_mode(true); - add_child(stop); - - peakdisplay=Ref<ImageTexture>( memnew( ImageTexture) ); - peakdisplay->create( EDITOR_DEF("editors/sample_editor/preview_width",512),EDITOR_DEF("editors/sample_editor/preview_height",128),Image::FORMAT_RGB8); - sample_texframe->set_expand(true); - sample_texframe->set_texture(peakdisplay); - - play->connect("pressed", this,"_play_pressed"); - stop->connect("pressed", this,"_stop_pressed"); - - set_custom_minimum_size(Size2(1,150)*EDSCALE); - -} - - -void SampleEditorPlugin::edit(Object *p_object) { - - Sample * s = p_object->cast_to<Sample>(); - if (!s) - return; - - sample_editor->edit(Ref<Sample>(s)); -} - -bool SampleEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("Sample"); -} - -void SampleEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - sample_editor->show(); - //sample_editor->set_process(true); - } else { - - sample_editor->hide(); - //sample_editor->set_process(false); - } - -} - -SampleEditorPlugin::SampleEditorPlugin(EditorNode *p_node) { - - editor=p_node; - sample_editor = memnew( SampleEditor ); - add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,sample_editor); - sample_editor->hide(); - - - -} - - -SampleEditorPlugin::~SampleEditorPlugin() -{ -} - -#endif diff --git a/tools/editor/plugins/sample_editor_plugin.h b/tools/editor/plugins/sample_editor_plugin.h deleted file mode 100644 index 651cd14a84..0000000000 --- a/tools/editor/plugins/sample_editor_plugin.h +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************/ -/* sample_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef SAMPLE_EDITOR_PLUGIN_H -#define SAMPLE_EDITOR_PLUGIN_H - -#if 0 -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/audio/sample_player.h" -#include "scene/resources/sample.h" -#include "scene/resources/sample_library.h" - - -class SampleEditor : public Panel { - - GDCLASS(SampleEditor, Panel ); - - - SamplePlayer *player; - Label *info_label; - Ref<ImageTexture> peakdisplay; - Ref<Sample> sample; - Ref<SampleLibrary> library; - TextureRect *sample_texframe; - Button *stop; - Button *play; - - void _play_pressed(); - void _stop_pressed(); - void _update_sample(); - -protected: - void _notification(int p_what); - void _gui_input(InputEvent p_event); - static void _bind_methods(); -public: - - static void generate_preview_texture(const Ref<Sample>& p_sample,Ref<ImageTexture> &p_texture); - void edit(Ref<Sample> p_sample); - SampleEditor(); -}; - - -class SampleEditorPlugin : public EditorPlugin { - - GDCLASS( SampleEditorPlugin, EditorPlugin ); - - SampleEditor *sample_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "Sample"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - SampleEditorPlugin(EditorNode *p_node); - ~SampleEditorPlugin(); - -}; - -#endif - -#endif // SAMPLE_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/sample_library_editor_plugin.cpp b/tools/editor/plugins/sample_library_editor_plugin.cpp deleted file mode 100644 index b996cafd1f..0000000000 --- a/tools/editor/plugins/sample_library_editor_plugin.cpp +++ /dev/null @@ -1,546 +0,0 @@ -/*************************************************************************/ -/* sample_library_editor_plugin.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. */ -/*************************************************************************/ - -#if 0 -#include "sample_library_editor_plugin.h" - -#include "io/resource_loader.h" -#include "global_config.h" -#include "tools/editor/editor_settings.h" -#include "scene/main/viewport.h" -#include "sample_editor_plugin.h" - - -void SampleLibraryEditor::_gui_input(InputEvent p_event) { - - -} - -void SampleLibraryEditor::_notification(int p_what) { - - if (p_what==NOTIFICATION_PROCESS) { - if (is_playing && !player->is_active()) { - TreeItem *tl=last_sample_playing->cast_to<TreeItem>(); - tl->set_button(0,0,get_icon("Play","EditorIcons")); - is_playing = false; - set_process(false); - } - } - - if (p_what==NOTIFICATION_ENTER_TREE) { - load->set_icon( get_icon("Folder","EditorIcons") ); - load->set_tooltip(TTR("Open Sample File(s)")); - } - - if (p_what==NOTIFICATION_READY) { - - //NodePath("/root")->connect("node_removed", this,"_node_removed",Vector<Variant>(),true); - } - - if (p_what==NOTIFICATION_DRAW) { - - } -} - -void SampleLibraryEditor::_file_load_request(const PoolVector<String>& p_path) { - - - for(int i=0;i<p_path.size();i++) { - - String path = p_path[i]; - Ref<Sample> sample = ResourceLoader::load(path,"Sample"); - if (sample.is_null()) { - dialog->set_text(TTR("ERROR: Couldn't load sample!")); - dialog->set_title(TTR("Error!")); - //dialog->get_cancel()->set_text("Close"); - dialog->get_ok()->set_text(TTR("Close")); - dialog->popup_centered_minsize(); - return; ///beh should show an error i guess - } - String basename = path.get_file().get_basename(); - String name=basename; - int counter=0; - while(sample_library->has_sample(name)) { - counter++; - name=basename+"_"+itos(counter); - } - - undo_redo->create_action(TTR("Add Sample")); - undo_redo->add_do_method(sample_library.operator->(),"add_sample",name,sample); - undo_redo->add_undo_method(sample_library.operator->(),"remove_sample",name); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - } -} - -void SampleLibraryEditor::_load_pressed() { - - file->popup_centered_ratio(); - -} - -void SampleLibraryEditor::_button_pressed(Object *p_item,int p_column, int p_id) { - - TreeItem *ti=p_item->cast_to<TreeItem>(); - String name = ti->get_text(0); - - if (p_column==0) { // Play/Stop - - String btn_type; - if(!is_playing) { - is_playing = true; - btn_type = TTR("Stop"); - player->play(name,true); - last_sample_playing = p_item; - set_process(true); - } else { - player->stop_all(); - if(last_sample_playing != p_item){ - TreeItem *tl=last_sample_playing->cast_to<TreeItem>(); - tl->set_button(p_column,0,get_icon("Play","EditorIcons")); - btn_type = TTR("Stop"); - player->play(name,true); - last_sample_playing = p_item; - } else { - btn_type = TTR("Play"); - is_playing = false; - } - } - ti->set_button(p_column,0,get_icon(btn_type,"EditorIcons")); - } else if (p_column==1) { // Edit - - get_tree()->get_root()->get_child(0)->call("_resource_selected",sample_library->get_sample(name)); - } else if (p_column==5) { // Delete - - ti->select(0); - _delete_pressed(); - } - - -} - - - - - -void SampleLibraryEditor::_item_edited() { - - if (!tree->get_selected()) - return; - - TreeItem *s = tree->get_selected(); - - if (tree->get_selected_column()==0) { // Name - // renamed - String old_name=s->get_metadata(0); - String new_name=s->get_text(0); - if (old_name==new_name) - return; - - if (new_name=="" || new_name.find("\\")!=-1 || new_name.find("/")!=-1 || sample_library->has_sample(new_name)) { - - s->set_text(0,old_name); - return; - } - - Ref<Sample> samp = sample_library->get_sample(old_name); - undo_redo->create_action(TTR("Rename Sample")); - undo_redo->add_do_method(sample_library.operator->(),"remove_sample",old_name); - undo_redo->add_do_method(sample_library.operator->(),"add_sample",new_name,samp); - undo_redo->add_undo_method(sample_library.operator->(),"remove_sample",new_name); - undo_redo->add_undo_method(sample_library.operator->(),"add_sample",old_name,samp); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - - } else if (tree->get_selected_column()==3) { // Volume dB - - StringName n = s->get_text(0); - sample_library->sample_set_volume_db(n,s->get_range(3)); - - } else if (tree->get_selected_column()==4) { // Pitch scale - - StringName n = s->get_text(0); - sample_library->sample_set_pitch_scale(n,s->get_range(4)); - - } - - -} - -void SampleLibraryEditor::_delete_pressed() { - - if (!tree->get_selected()) - return; - - String to_remove = tree->get_selected()->get_text(0); - undo_redo->create_action(TTR("Delete Sample")); - undo_redo->add_do_method(sample_library.operator->(),"remove_sample",to_remove); - undo_redo->add_undo_method(sample_library.operator->(),"add_sample",to_remove,sample_library->get_sample(to_remove)); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); -} - - -void SampleLibraryEditor::_update_library() { - - player->stop_all(); - - tree->clear(); - tree->set_hide_root(true); - TreeItem *root = tree->create_item(NULL); - - List<StringName> names; - sample_library->get_sample_list(&names); - names.sort_custom<StringName::AlphCompare>(); - - for(List<StringName>::Element *E=names.front();E;E=E->next()) { - - TreeItem *ti = tree->create_item(root); - - // Name + Play/Stop - ti->set_cell_mode(0,TreeItem::CELL_MODE_STRING); - ti->set_editable(0,true); - ti->set_selectable(0,true); - ti->set_text(0,E->get()); - ti->set_metadata(0,E->get()); - ti->add_button(0,get_icon("Play","EditorIcons")); - - Ref<Sample> smp = sample_library->get_sample(E->get()); - - // Preview/edit - Ref<ImageTexture> preview( memnew( ImageTexture )); - preview->create(128,16,Image::FORMAT_RGB8); - SampleEditor::generate_preview_texture(smp,preview); - ti->set_cell_mode(1,TreeItem::CELL_MODE_ICON); - ti->set_selectable(1,false); - ti->set_editable(1,false); - ti->set_icon(1,preview); - ti->add_button(1,get_icon("Edit","EditorIcons")); - - // Format - ti->set_cell_mode(2,TreeItem::CELL_MODE_STRING); - ti->set_editable(2,false); - ti->set_selectable(2,false); - ti->set_text(2,String()+(smp->get_format()==Sample::FORMAT_PCM16?TTR("16 Bits")+", ":(smp->get_format()==Sample::FORMAT_PCM8?TTR("8 Bits")+", ":"IMA-ADPCM,"))+(smp->is_stereo()?TTR("Stereo"):TTR("Mono"))); - - // Volume dB - ti->set_cell_mode(3,TreeItem::CELL_MODE_RANGE); - ti->set_range_config(3,-60,24,0.01); - ti->set_selectable(3,true); - ti->set_editable(3,true); - ti->set_range(3,sample_library->sample_get_volume_db(E->get())); - - // Pitch scale - ti->set_cell_mode(4,TreeItem::CELL_MODE_RANGE); - ti->set_range_config(4,0.01,100,0.01); - ti->set_selectable(4,true); - ti->set_editable(4,true); - ti->set_range(4,sample_library->sample_get_pitch_scale(E->get())); - - // Delete - ti->set_cell_mode(5,TreeItem::CELL_MODE_STRING); - ti->add_button(5,get_icon("Remove","EditorIcons")); - - } - - //player->add_sample("default",sample); -} - - - -void SampleLibraryEditor::edit(Ref<SampleLibrary> p_sample_library) { - - sample_library=p_sample_library; - - - if (!sample_library.is_null()) { - player->set_sample_library(sample_library); - _update_library(); - } else { - - hide(); - } - -} - -Variant SampleLibraryEditor::get_drag_data_fw(const Point2& p_point,Control* p_from) { - - TreeItem*ti =tree->get_item_at_pos(p_point); - if (!ti) - return Variant(); - - String name = ti->get_metadata(0); - - RES res = sample_library->get_sample(name); - if (!res.is_valid()) - return Variant(); - - return EditorNode::get_singleton()->drag_resource(res,p_from); - - -} - -bool SampleLibraryEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const { - - - - Dictionary d = p_data; - - if (!d.has("type")) - return false; - - if (d.has("from") && (Object*)(d["from"])==tree) - return false; - - if (String(d["type"])=="resource" && d.has("resource")) { - RES r=d["resource"]; - - Ref<Sample> sample = r; - - if (sample.is_valid()) { - - return true; - } - } - - - if (String(d["type"])=="files") { - - Vector<String> files = d["files"]; - - if (files.size()==0) - return false; - - for(int i=0;i<files.size();i++) { - String file = files[0]; - String ftype = EditorFileSystem::get_singleton()->get_file_type(file); - - if (ftype!="Sample") { - return false; - } - - } - - return true; - - } - return false; -} - -void SampleLibraryEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) { - - if (!can_drop_data_fw(p_point,p_data,p_from)) - return; - - Dictionary d = p_data; - - if (!d.has("type")) - return; - - - if (String(d["type"])=="resource" && d.has("resource")) { - RES r=d["resource"]; - - Ref<Sample> sample = r; - - if (sample.is_valid()) { - - String basename; - if (sample->get_name()!="") { - basename=sample->get_name(); - } else if (sample->get_path().is_resource_file()) { - basename = sample->get_path().get_basename(); - } else { - basename="Sample"; - } - - String name=basename; - int counter=0; - while(sample_library->has_sample(name)) { - counter++; - name=basename+"_"+itos(counter); - } - - undo_redo->create_action(TTR("Add Sample")); - undo_redo->add_do_method(sample_library.operator->(),"add_sample",name,sample); - undo_redo->add_undo_method(sample_library.operator->(),"remove_sample",name); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - } - } - - - if (String(d["type"])=="files") { - - PoolVector<String> files = d["files"]; - - _file_load_request(files); - - } - -} - - -void SampleLibraryEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_gui_input"),&SampleLibraryEditor::_gui_input); - ClassDB::bind_method(D_METHOD("_load_pressed"),&SampleLibraryEditor::_load_pressed); - ClassDB::bind_method(D_METHOD("_item_edited"),&SampleLibraryEditor::_item_edited); - ClassDB::bind_method(D_METHOD("_delete_pressed"),&SampleLibraryEditor::_delete_pressed); - ClassDB::bind_method(D_METHOD("_file_load_request"),&SampleLibraryEditor::_file_load_request); - ClassDB::bind_method(D_METHOD("_update_library"),&SampleLibraryEditor::_update_library); - ClassDB::bind_method(D_METHOD("_button_pressed"),&SampleLibraryEditor::_button_pressed); - - ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &SampleLibraryEditor::get_drag_data_fw); - ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SampleLibraryEditor::can_drop_data_fw); - ClassDB::bind_method(D_METHOD("drop_data_fw"), &SampleLibraryEditor::drop_data_fw); - -} - -SampleLibraryEditor::SampleLibraryEditor() { - - player = memnew(SamplePlayer); - add_child(player); - add_style_override("panel", get_stylebox("panel","Panel")); - - - load = memnew( Button ); - load->set_pos(Point2( 5, 5 )); - load->set_size( Size2(1,1 ) ); - add_child(load); - - file = memnew( EditorFileDialog ); - add_child(file); - List<String> extensions; - ResourceLoader::get_recognized_extensions_for_type("Sample",&extensions); - for(int i=0;i<extensions.size();i++) - file->add_filter("*."+extensions[i]); - file->set_mode(EditorFileDialog::MODE_OPEN_FILES); - - tree = memnew( Tree ); - tree->set_columns(6); - add_child(tree); - tree->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,5); - tree->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,5); - tree->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,30); - tree->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,5); - tree->set_column_titles_visible(true); - tree->set_column_title(0,TTR("Name")); - tree->set_column_title(1,TTR("Preview")); - tree->set_column_title(2,TTR("Format")); - tree->set_column_title(3,"dB"); - tree->set_column_title(4,TTR("Pitch")); - tree->set_column_title(5,""); - - tree->set_column_min_width(1,150); - tree->set_column_min_width(2,100); - tree->set_column_min_width(3,50); - tree->set_column_min_width(4,50); - tree->set_column_min_width(5,32); - tree->set_column_expand(1,false); - tree->set_column_expand(2,false); - tree->set_column_expand(3,false); - tree->set_column_expand(4,false); - tree->set_column_expand(5,false); - - tree->set_drag_forwarding(this); - - dialog = memnew( ConfirmationDialog ); - add_child( dialog ); - - tree->connect("button_pressed",this,"_button_pressed"); - load->connect("pressed", this,"_load_pressed"); - file->connect("files_selected", this,"_file_load_request"); - tree->connect("item_edited", this,"_item_edited"); - - is_playing = false; -} - - -void SampleLibraryEditorPlugin::edit(Object *p_object) { - - sample_library_editor->set_undo_redo(&get_undo_redo()); - SampleLibrary * s = p_object->cast_to<SampleLibrary>(); - if (!s) - return; - - sample_library_editor->edit(Ref<SampleLibrary>(s)); -} - -bool SampleLibraryEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("SampleLibrary"); -} - -void SampleLibraryEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - //sample_library_editor->show(); - button->show(); - editor->make_bottom_panel_item_visible(sample_library_editor); - //sample_library_editor->set_process(true); - } else { - - if (sample_library_editor->is_visible_in_tree()) - editor->hide_bottom_panel(); - button->hide(); - - //sample_library_editor->set_process(false); - } - -} - -SampleLibraryEditorPlugin::SampleLibraryEditorPlugin(EditorNode *p_node) { - - editor=p_node; - sample_library_editor = memnew( SampleLibraryEditor ); - - //editor->get_viewport()->add_child(sample_library_editor); - sample_library_editor->set_custom_minimum_size(Size2(0,250)); - button=p_node->add_bottom_panel_item("SampleLibrary",sample_library_editor); - button->hide(); - - //sample_library_editor->set_area_as_parent_rect(); - //sample_library_editor->set_anchor( MARGIN_TOP, Control::ANCHOR_END); - //sample_library_editor->set_margin( MARGIN_TOP, 120 ); - //sample_library_editor->hide(); - - - -} - - -SampleLibraryEditorPlugin::~SampleLibraryEditorPlugin() -{ -} -#endif diff --git a/tools/editor/plugins/sample_library_editor_plugin.h b/tools/editor/plugins/sample_library_editor_plugin.h deleted file mode 100644 index 35028df859..0000000000 --- a/tools/editor/plugins/sample_library_editor_plugin.h +++ /dev/null @@ -1,108 +0,0 @@ -/*************************************************************************/ -/* sample_library_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef SAMPLE_LIBRARY_EDITOR_PLUGIN_H -#define SAMPLE_LIBRARY_EDITOR_PLUGIN_H - - -#if 0 -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/audio/sample_player.h" -#include "scene/resources/sample.h" -#include "scene/gui/tree.h" -#include "scene/gui/file_dialog.h" -#include "scene/gui/dialogs.h" - - -class SampleLibraryEditor : public Panel { - - GDCLASS(SampleLibraryEditor, Panel ); - - - - SamplePlayer *player; - Ref<SampleLibrary> sample_library; - Button *load; - Tree *tree; - bool is_playing; - Object *last_sample_playing; - - EditorFileDialog *file; - - ConfirmationDialog *dialog; - - - void _load_pressed(); - void _file_load_request(const PoolVector<String>& p_path); - void _delete_pressed(); - void _update_library(); - void _item_edited(); - - UndoRedo *undo_redo; - - void _button_pressed(Object *p_item,int p_column, int p_id); - - Variant get_drag_data_fw(const Point2& p_point,Control* p_from); - bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; - void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); - -protected: - void _notification(int p_what); - void _gui_input(InputEvent p_event); - static void _bind_methods(); -public: - - void set_undo_redo(UndoRedo *p_undo_redo) {undo_redo=p_undo_redo; } - void edit(Ref<SampleLibrary> p_sample); - SampleLibraryEditor(); -}; - -class SampleLibraryEditorPlugin : public EditorPlugin { - - GDCLASS( SampleLibraryEditorPlugin, EditorPlugin ); - - SampleLibraryEditor *sample_library_editor; - EditorNode *editor; - Button *button; - -public: - - virtual String get_name() const { return "SampleLibrary"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - SampleLibraryEditorPlugin(EditorNode *p_node); - ~SampleLibraryEditorPlugin(); - -}; - -#endif -#endif // SAMPLE_LIBRARY_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/sample_player_editor_plugin.h b/tools/editor/plugins/sample_player_editor_plugin.h deleted file mode 100644 index ba1684497c..0000000000 --- a/tools/editor/plugins/sample_player_editor_plugin.h +++ /dev/null @@ -1,90 +0,0 @@ -/*************************************************************************/ -/* sample_player_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef SAMPLE_PLAYER_EDITOR_PLUGIN_H -#define SAMPLE_PLAYER_EDITOR_PLUGIN_H - -#if 0 - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/3d/spatial_sample_player.h" -#include "scene/gui/option_button.h" -#include "scene/audio/sample_player.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -class SamplePlayerEditor : public Control { - - GDCLASS(SamplePlayerEditor, Control ); - - Panel *panel; - Button * play; - Button * stop; - OptionButton *samples; - Node *node; - - - void _update_sample_library(); - void _play(); - void _stop(); - -protected: - void _notification(int p_what); - void _node_removed(Node *p_node); - static void _bind_methods(); -public: - - void edit(Node *p_sample_player); - SamplePlayerEditor(); -}; - -class SamplePlayerEditorPlugin : public EditorPlugin { - - GDCLASS( SamplePlayerEditorPlugin, EditorPlugin ); - - SamplePlayerEditor *sample_player_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "SamplePlayer"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - SamplePlayerEditorPlugin(EditorNode *p_node); - ~SamplePlayerEditorPlugin(); - -}; - -#endif -#endif // SAMPLE_PLAYER_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp deleted file mode 100644 index c7639dd4d3..0000000000 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ /dev/null @@ -1,2491 +0,0 @@ -/*************************************************************************/ -/* script_editor_plugin.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 "script_editor_plugin.h" - -#include "tools/editor/editor_settings.h" -#include "io/resource_loader.h" -#include "io/resource_saver.h" -#include "os/keyboard.h" -#include "os/os.h" -#include "tools/editor/editor_node.h" -#include "tools/editor/script_editor_debugger.h" -#include "global_config.h" -#include "os/file_access.h" -#include "scene/main/viewport.h" -#include "os/keyboard.h" -#include "os/input.h" - -/*** SCRIPT EDITOR ****/ - - - -void ScriptEditorBase::_bind_methods() { - - ADD_SIGNAL(MethodInfo("name_changed")); - ADD_SIGNAL(MethodInfo("request_help_search",PropertyInfo(Variant::STRING,"topic"))); - ADD_SIGNAL(MethodInfo("request_open_script_at_line",PropertyInfo(Variant::OBJECT,"script"),PropertyInfo(Variant::INT,"line"))); - ADD_SIGNAL(MethodInfo("request_save_history")); - ADD_SIGNAL(MethodInfo("go_to_help",PropertyInfo(Variant::STRING,"what"))); - -} - -static bool _can_open_in_editor(Script* p_script) { - - String path = p_script->get_path(); - - if (path.find("::")!=-1) { - //refuse handling this if it can't be edited - - bool valid=false; - for(int i=0;i<EditorNode::get_singleton()->get_editor_data().get_edited_scene_count();i++) { - if (path.begins_with(EditorNode::get_singleton()->get_editor_data().get_scene_path(i))) { - valid=true; - break; - } - } - - return valid; - } - - return true; -} - - -class EditorScriptCodeCompletionCache : public ScriptCodeCompletionCache { - - - struct Cache { - uint64_t time_loaded; - RES cache; - }; - - Map<String,Cache> cached; - - -public: - - uint64_t max_time_cache; - int max_cache_size; - - void cleanup() { - - List< Map<String,Cache>::Element * > to_clean; - - - Map<String,Cache>::Element *I=cached.front(); - while(I) { - if ((OS::get_singleton()->get_ticks_msec()-I->get().time_loaded)>max_time_cache) { - to_clean.push_back(I); - } - I=I->next(); - } - - while(to_clean.front()) { - cached.erase(to_clean.front()->get()); - to_clean.pop_front(); - } - } - - RES get_cached_resource(const String& p_path) { - - Map<String,Cache>::Element *E=cached.find(p_path); - if (!E) { - - Cache c; - c.cache=ResourceLoader::load(p_path); - E=cached.insert(p_path,c); - } - - E->get().time_loaded=OS::get_singleton()->get_ticks_msec(); - - if (cached.size()>max_cache_size) { - uint64_t older; - Map<String,Cache>::Element *O=cached.front(); - older=O->get().time_loaded; - Map<String,Cache>::Element *I=O; - while(I) { - if (I->get().time_loaded<older) { - older = I->get().time_loaded; - O=I; - } - I=I->next(); - } - - if (O!=E) {//should never heppane.. - cached.erase(O); - } - } - - return E->get().cache; - } - - - EditorScriptCodeCompletionCache() { - - max_cache_size=128; - max_time_cache=5*60*1000; //minutes, five - } - -}; - -#define SORT_SCRIPT_LIST - -void ScriptEditorQuickOpen::popup(const Vector<String>& p_functions, bool p_dontclear) { - - popup_centered_ratio(0.6); - if (p_dontclear) - search_box->select_all(); - else - search_box->clear(); - search_box->grab_focus(); - functions=p_functions; - _update_search(); - - -} - - -void ScriptEditorQuickOpen::_text_changed(const String& p_newtext) { - - _update_search(); -} - -void ScriptEditorQuickOpen::_sbox_input(const InputEvent& p_ie) { - - if (p_ie.type==InputEvent::KEY && ( - p_ie.key.scancode == KEY_UP || - p_ie.key.scancode == KEY_DOWN || - p_ie.key.scancode == KEY_PAGEUP || - p_ie.key.scancode == KEY_PAGEDOWN ) ) { - - search_options->call("_gui_input",p_ie); - search_box->accept_event(); - } - -} - - - -void ScriptEditorQuickOpen::_update_search() { - - - search_options->clear(); - TreeItem *root = search_options->create_item(); - - for(int i=0;i<functions.size();i++) { - - String file = functions[i]; - if ((search_box->get_text()=="" || file.findn(search_box->get_text())!=-1)) { - - TreeItem *ti = search_options->create_item(root); - ti->set_text(0,file); - if (root->get_children()==ti) - ti->select(0); - - } - } - - get_ok()->set_disabled(root->get_children()==NULL); - -} - -void ScriptEditorQuickOpen::_confirmed() { - - TreeItem *ti = search_options->get_selected(); - if (!ti) - return; - int line = ti->get_text(0).get_slice(":",1).to_int(); - - emit_signal("goto_line",line-1); - hide(); -} - -void ScriptEditorQuickOpen::_notification(int p_what) { - - if (p_what==NOTIFICATION_ENTER_TREE) { - - connect("confirmed",this,"_confirmed"); - - - } -} - - - - -void ScriptEditorQuickOpen::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_text_changed"),&ScriptEditorQuickOpen::_text_changed); - ClassDB::bind_method(D_METHOD("_confirmed"),&ScriptEditorQuickOpen::_confirmed); - ClassDB::bind_method(D_METHOD("_sbox_input"),&ScriptEditorQuickOpen::_sbox_input); - - ADD_SIGNAL(MethodInfo("goto_line",PropertyInfo(Variant::INT,"line"))); - -} - - -ScriptEditorQuickOpen::ScriptEditorQuickOpen() { - - - VBoxContainer *vbc = memnew( VBoxContainer ); - add_child(vbc); - //set_child_rect(vbc); - search_box = memnew( LineEdit ); - vbc->add_margin_child(TTR("Search:"),search_box); - search_box->connect("text_changed",this,"_text_changed"); - search_box->connect("gui_input",this,"_sbox_input"); - search_options = memnew( Tree ); - vbc->add_margin_child(TTR("Matches:"),search_options,true); - get_ok()->set_text(TTR("Open")); - get_ok()->set_disabled(true); - register_text_enter(search_box); - set_hide_on_ok(false); - search_options->connect("item_activated",this,"_confirmed"); - search_options->set_hide_root(true); -} - - -///////////////////////////////// - -ScriptEditor *ScriptEditor::script_editor=NULL; - -/*** SCRIPT EDITOR ******/ - -String ScriptEditor::_get_debug_tooltip(const String&p_text,Node *_se) { - - //ScriptEditorBase *se=_se->cast_to<ScriptEditorBase>(); - - String val = debugger->get_var_value(p_text); - if (val!=String()) { - return p_text+": "+val; - } else { - - return String(); - } -} - -void ScriptEditor::_breaked(bool p_breaked,bool p_can_debug) { - - if (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) { - return; - } - - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_NEXT), !(p_breaked && p_can_debug)); - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_STEP), !(p_breaked && p_can_debug) ); - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_BREAK), p_breaked ); - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), !p_breaked ); - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (!se) { - - continue; - } - - se->set_debugger_active(p_breaked); - } - -} - -void ScriptEditor::_show_debugger(bool p_show) { - - //debug_menu->get_popup()->set_item_checked( debug_menu->get_popup()->get_item_index(DEBUG_SHOW), p_show); -} - -void ScriptEditor::_script_created(Ref<Script> p_script) { - editor->push_item(p_script.operator->()); -} - - -void ScriptEditor::_goto_script_line2(int p_line) { - - int selected = tab_container->get_current_tab(); - if (selected<0 || selected>=tab_container->get_child_count()) - return; - - ScriptEditorBase *current = tab_container->get_child(selected)->cast_to<ScriptEditorBase>(); - if (!current) - return; - - current->goto_line(p_line); - -} - -void ScriptEditor::_goto_script_line(REF p_script,int p_line) { - - - editor->push_item(p_script.ptr()); - - int selected = tab_container->get_current_tab(); - if (selected<0 || selected>=tab_container->get_child_count()) - return; - - ScriptEditorBase *current = tab_container->get_child(selected)->cast_to<ScriptEditorBase>(); - if (!current) - return; - - current->goto_line(p_line,true); - -} - - -void ScriptEditor::_update_history_arrows() { - - script_back->set_disabled( history_pos<=0 ); - script_forward->set_disabled( history_pos>=history.size()-1 ); -} - -void ScriptEditor::_save_history() { - - - if (history_pos>=0 && history_pos<history.size() && history[history_pos].control==tab_container->get_current_tab_control()) { - - Node *n = tab_container->get_current_tab_control(); - - if (n->cast_to<ScriptEditorBase>()) { - - history[history_pos].state=n->cast_to<ScriptEditorBase>()->get_edit_state(); - } - if (n->cast_to<EditorHelp>()) { - - history[history_pos].state=n->cast_to<EditorHelp>()->get_scroll(); - } - } - - history.resize(history_pos+1); - ScriptHistory sh; - sh.control=tab_container->get_current_tab_control(); - sh.state=Variant(); - - history.push_back(sh); - history_pos++; - - _update_history_arrows(); -} - - -void ScriptEditor::_go_to_tab(int p_idx) { - - Node *cn = tab_container->get_child(p_idx); - if (!cn) - return; - Control *c = cn->cast_to<Control>(); - if (!c) - return; - - if (history_pos>=0 && history_pos<history.size() && history[history_pos].control==tab_container->get_current_tab_control()) { - - Node *n = tab_container->get_current_tab_control(); - - if (n->cast_to<ScriptEditorBase>()) { - - history[history_pos].state=n->cast_to<ScriptEditorBase>()->get_edit_state(); - } - if (n->cast_to<EditorHelp>()) { - - history[history_pos].state=n->cast_to<EditorHelp>()->get_scroll(); - } - } - - history.resize(history_pos+1); - ScriptHistory sh; - sh.control=c; - sh.state=Variant(); - - history.push_back(sh); - history_pos++; - - - tab_container->set_current_tab(p_idx); - - c = tab_container->get_current_tab_control(); - - if (c->cast_to<ScriptEditorBase>()) { - - script_name_label->set_text(c->cast_to<ScriptEditorBase>()->get_name()); - script_icon->set_texture(c->cast_to<ScriptEditorBase>()->get_icon()); - if (is_visible_in_tree()) - c->cast_to<ScriptEditorBase>()->ensure_focus(); - } - if (c->cast_to<EditorHelp>()) { - - script_name_label->set_text(c->cast_to<EditorHelp>()->get_class()); - script_icon->set_texture(get_icon("Help","EditorIcons")); - if (is_visible_in_tree()) - c->cast_to<EditorHelp>()->set_focused(); - } - - - - c->set_meta("__editor_pass",++edit_pass); - _update_history_arrows(); - _update_script_colors(); - _update_selected_editor_menu(); -} - -void ScriptEditor::_close_tab(int p_idx, bool p_save) { - - int selected = p_idx; - if (selected<0 || selected>=tab_container->get_child_count()) - return; - - Node *tselected = tab_container->get_child(selected); - ScriptEditorBase *current = tab_container->get_child(selected)->cast_to<ScriptEditorBase>(); - if (current) { - if (p_save) { - apply_scripts(); - } - if (current->get_edit_menu()) { - memdelete(current->get_edit_menu()); - } - } - - //remove from history - history.resize(history_pos+1); - - for(int i=0;i<history.size();i++) { - if (history[i].control==tselected) { - history.remove(i); - i--; - history_pos--; - } - } - - if (history_pos>=history.size()) { - history_pos=history.size()-1; - } - - int idx = tab_container->get_current_tab(); - memdelete(tselected); - if (idx>=tab_container->get_child_count()) - idx=tab_container->get_child_count()-1; - if (idx>=0) { - - if (history_pos>=0) { - idx = history[history_pos].control->get_index(); - } - tab_container->set_current_tab(idx); - - //script_list->select(idx); - } - - - _update_history_arrows(); - - - - _update_script_names(); - _save_layout(); -} - -void ScriptEditor::_close_current_tab() { - - _close_tab(tab_container->get_current_tab()); - -} - -void ScriptEditor::_close_discard_current_tab(const String& p_str) { - _close_tab(tab_container->get_current_tab(), false); - erase_tab_confirm->hide(); -} - -void ScriptEditor::_close_docs_tab() { - - int child_count = tab_container->get_child_count(); - for (int i = child_count-1; i>=0; i--) { - - EditorHelp *se = tab_container->get_child(i)->cast_to<EditorHelp>(); - - if (se) { - _close_tab(i); - } - - } - -} - -void ScriptEditor::_close_all_tabs() { - - int child_count = tab_container->get_child_count(); - for (int i = child_count-1; i>=0; i--) { - - tab_container->set_current_tab(i); - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - - if (se) { - - // Maybe there are unsaved changes - if (se->is_unsaved()) { - _ask_close_current_unsaved_tab(se); - continue; - } - - } - - _close_current_tab(); - } - -} - -void ScriptEditor::_ask_close_current_unsaved_tab(ScriptEditorBase *current) { - erase_tab_confirm->set_text("Close and save changes?\n\""+current->get_name()+"\""); - erase_tab_confirm->popup_centered_minsize(); -} - - -void ScriptEditor::_resave_scripts(const String& p_str) { - - apply_scripts(); - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (!se) - continue; - - - Ref<Script> script = se->get_edited_script(); - - if (script->get_path()=="" || script->get_path().find("local://")!=-1 || script->get_path().find("::")!=-1) - continue; //internal script, who cares - - if (trim_trailing_whitespace_on_save) { - se->trim_trailing_whitespace(); - } - editor->save_resource(script); - se->tag_saved_version(); - } - - disk_changed->hide(); - -} - -void ScriptEditor::_reload_scripts(){ - - - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (!se) { - - continue; - } - - - Ref<Script> script = se->get_edited_script(); - - if (script->get_path()=="" || script->get_path().find("local://")!=-1 || script->get_path().find("::")!=-1) { - - continue; //internal script, who cares - } - - - uint64_t last_date = script->get_last_modified_time(); - uint64_t date = FileAccess::get_modified_time(script->get_path()); - - //printf("last date: %lli vs date: %lli\n",last_date,date); - if (last_date==date) { - continue; - } - - - Ref<Script> rel_script = ResourceLoader::load(script->get_path(),script->get_class(),true); - ERR_CONTINUE(!rel_script.is_valid()); - script->set_source_code( rel_script->get_source_code() ); - script->set_last_modified_time( rel_script->get_last_modified_time() ); - script->reload(); - se->reload_text(); - - - } - - disk_changed->hide(); - _update_script_names(); - -} - - - -void ScriptEditor::_res_saved_callback(const Ref<Resource>& p_res) { - - - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (!se) { - - continue; - } - - - Ref<Script> script = se->get_edited_script(); - - if (script->get_path()=="" || script->get_path().find("local://")!=-1 || script->get_path().find("::")!=-1) { - continue; //internal script, who cares - } - - if (script==p_res) { - - se->tag_saved_version(); - } - - } - - _update_script_names(); - - - if (!pending_auto_reload && auto_reload_running_scripts) { - call_deferred("_live_auto_reload_running_scripts"); - pending_auto_reload=true; - } -} - -void ScriptEditor::_live_auto_reload_running_scripts() { - pending_auto_reload=false; - debugger->reload_scripts(); -} - - -bool ScriptEditor::_test_script_times_on_disk(Ref<Script> p_for_script) { - - - disk_changed_list->clear(); - TreeItem *r = disk_changed_list->create_item(); - disk_changed_list->set_hide_root(true); - - bool need_ask=false; - bool need_reload=false; - bool use_autoreload=bool(EDITOR_DEF("text_editor/files/auto_reload_scripts_on_external_change",false)); - - - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (se) { - - Ref<Script> script = se->get_edited_script(); - - if (p_for_script.is_valid() && p_for_script!=script) - continue; - - if (script->get_path()=="" || script->get_path().find("local://")!=-1 || script->get_path().find("::")!=-1) - continue; //internal script, who cares - - - uint64_t last_date = script->get_last_modified_time(); - uint64_t date = FileAccess::get_modified_time(script->get_path()); - - //printf("last date: %lli vs date: %lli\n",last_date,date); - if (last_date!=date) { - - TreeItem *ti = disk_changed_list->create_item(r); - ti->set_text(0,script->get_path().get_file()); - - if (!use_autoreload || se->is_unsaved()) { - need_ask=true; - } - need_reload=true; - //r->set_metadata(0,); - } - } - } - - - - if (need_reload) { - if (!need_ask) { - script_editor->_reload_scripts(); - need_reload=false; - } else { - disk_changed->call_deferred("popup_centered_ratio",0.5); - } - } - - return need_reload; -} - - -void ScriptEditor::_file_dialog_action(String p_file) { - - switch (file_dialog_option) { - case FILE_SAVE_THEME_AS: { - if(!EditorSettings::get_singleton()->save_text_editor_theme_as(p_file)) { - editor->show_warning(TTR("Error while saving theme"), TTR("Error saving")); - } - } break; - case FILE_IMPORT_THEME: { - if(!EditorSettings::get_singleton()->import_text_editor_theme(p_file)) { - editor->show_warning(TTR("Error importing theme"), TTR("Error importing")); - } - } break; - } - file_dialog_option = -1; -} - -void ScriptEditor::_menu_option(int p_option) { - - - switch(p_option) { - case FILE_NEW: { - script_create_dialog->config("Node", ".gd"); - script_create_dialog->popup_centered(Size2(300, 300)*EDSCALE); - } break; - case FILE_OPEN: { - - editor->open_resource("Script"); - return; - } break; - case FILE_SAVE_ALL: { - - if (_test_script_times_on_disk()) - return; - - save_all_scripts(); - } break; - case FILE_IMPORT_THEME: { - file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE); - file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - file_dialog_option = FILE_IMPORT_THEME; - file_dialog->clear_filters(); - file_dialog->add_filter("*.tet"); - file_dialog->popup_centered_ratio(); - file_dialog->set_title(TTR("Import Theme")); - } break; - case FILE_RELOAD_THEME: { - EditorSettings::get_singleton()->load_text_editor_theme(); - } break; - case FILE_SAVE_THEME: { - if(!EditorSettings::get_singleton()->save_text_editor_theme()) { - editor->show_warning(TTR("Error while saving theme"), TTR("Error saving")); - } - } break; - case FILE_SAVE_THEME_AS: { - file_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE); - file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); - file_dialog_option = FILE_SAVE_THEME_AS; - file_dialog->clear_filters(); - file_dialog->add_filter("*.tet"); - file_dialog->set_current_path(EditorSettings::get_singleton()->get_settings_path() + "/text_editor_themes/" + EditorSettings::get_singleton()->get("text_editor/theme/color_theme")); - file_dialog->popup_centered_ratio(); - file_dialog->set_title(TTR("Save Theme As..")); - } break; - case SEARCH_HELP: { - - help_search_dialog->popup(); - } break; - case SEARCH_CLASSES: { - - String current; - - if (tab_container->get_tab_count()>0) { - EditorHelp *eh = tab_container->get_child( tab_container->get_current_tab() )->cast_to<EditorHelp>(); - if (eh) { - current=eh->get_class(); - } - } - - help_index->popup(); - - if (current!="") { - help_index->call_deferred("select_class",current); - } - } break; - case SEARCH_WEBSITE: { - - OS::get_singleton()->shell_open("http://docs.godotengine.org/"); - } break; - - case WINDOW_NEXT: { - - _history_forward(); - } break; - case WINDOW_PREV: { - _history_back(); - } break; - case DEBUG_SHOW: { - if (debugger) { - bool visible = debug_menu->get_popup()->is_item_checked( debug_menu->get_popup()->get_item_index(DEBUG_SHOW) ); - debug_menu->get_popup()->set_item_checked( debug_menu->get_popup()->get_item_index(DEBUG_SHOW), !visible); - if (visible) - debugger->hide(); - else - debugger->show(); - } - } break; - case DEBUG_SHOW_KEEP_OPEN: { - bool visible = debug_menu->get_popup()->is_item_checked( debug_menu->get_popup()->get_item_index(DEBUG_SHOW_KEEP_OPEN) ); - if (debugger) - debugger->set_hide_on_stop(visible); - debug_menu->get_popup()->set_item_checked( debug_menu->get_popup()->get_item_index(DEBUG_SHOW_KEEP_OPEN), !visible); - } break; - } - - - int selected = tab_container->get_current_tab(); - if (selected<0 || selected>=tab_container->get_child_count()) - return; - - ScriptEditorBase *current = tab_container->get_child(selected)->cast_to<ScriptEditorBase>(); - if (current) { - - switch(p_option) { - case FILE_NEW: { - script_create_dialog->config("Node", ".gd"); - script_create_dialog->popup_centered(Size2(300, 300)*EDSCALE); - } break; - case FILE_SAVE: { - - if (_test_script_times_on_disk()) - return; - - if (trim_trailing_whitespace_on_save) - current->trim_trailing_whitespace(); - editor->save_resource( current->get_edited_script() ); - - } break; - case FILE_SAVE_AS: { - - current->trim_trailing_whitespace(); - editor->push_item(current->get_edited_script()->cast_to<Object>()); - editor->save_resource_as( current->get_edited_script() ); - - } break; - - case FILE_TOOL_RELOAD: - case FILE_TOOL_RELOAD_SOFT: { - - current->reload(p_option==FILE_TOOL_RELOAD_SOFT); - - } break; - - case FILE_CLOSE: { - if (current->is_unsaved()) { - _ask_close_current_unsaved_tab(current); - } else { - _close_current_tab(); - } - } break; - case CLOSE_DOCS: { - _close_docs_tab(); - } break; - case CLOSE_ALL: { - _close_all_tabs(); - } break; - case DEBUG_NEXT: { - - if (debugger) - debugger->debug_next(); - } break; - case DEBUG_STEP: { - - if (debugger) - debugger->debug_step(); - - } break; - case DEBUG_BREAK: { - - if (debugger) - debugger->debug_break(); - - } break; - case DEBUG_CONTINUE: { - - if (debugger) - debugger->debug_continue(); - - } break; - case WINDOW_MOVE_LEFT: { - - if (tab_container->get_current_tab()>0) { - tab_container->call_deferred("set_current_tab",tab_container->get_current_tab()-1); - script_list->call_deferred("select",tab_container->get_current_tab()-1); - tab_container->move_child(current,tab_container->get_current_tab()-1); - _update_script_names(); - } - } break; - case WINDOW_MOVE_RIGHT: { - - if (tab_container->get_current_tab()<tab_container->get_child_count()-1) { - tab_container->call_deferred("set_current_tab",tab_container->get_current_tab()+1); - script_list->call_deferred("select",tab_container->get_current_tab()+1); - tab_container->move_child(current,tab_container->get_current_tab()+1); - _update_script_names(); - } - - - } break; - - default: { - - if (p_option>=WINDOW_SELECT_BASE) { - - tab_container->set_current_tab(p_option-WINDOW_SELECT_BASE); - script_list->select(p_option-WINDOW_SELECT_BASE); - - } - } - } - } - - EditorHelp *help = tab_container->get_current_tab_control()->cast_to<EditorHelp>(); - if (help) { - - switch(p_option) { - - case HELP_SEARCH_FIND: { - help->popup_search(); - } break; - case HELP_SEARCH_FIND_NEXT: { - help->search_again(); - } break; - case FILE_CLOSE: { - _close_current_tab(); - } break; - case CLOSE_DOCS: { - _close_docs_tab(); - } break; - case CLOSE_ALL: { - _close_all_tabs(); - } break; - - - } - } - - -} - -void ScriptEditor::_tab_changed(int p_which) { - - ensure_select_current(); -} - -void ScriptEditor::_notification(int p_what) { - - if (p_what==NOTIFICATION_ENTER_TREE) { - - editor->connect("play_pressed",this,"_editor_play"); - editor->connect("pause_pressed",this,"_editor_pause"); - editor->connect("stop_pressed",this,"_editor_stop"); - editor->connect("script_add_function_request",this,"_add_callback"); - editor->connect("resource_saved",this,"_res_saved_callback"); - script_list->connect("item_selected",this,"_script_selected"); - script_split->connect("dragged",this,"_script_split_dragged"); - autosave_timer->connect("timeout",this,"_autosave_scripts"); - { - float autosave_time = EditorSettings::get_singleton()->get("text_editor/files/autosave_interval_secs"); - if (autosave_time>0) { - autosave_timer->set_wait_time(autosave_time); - autosave_timer->start(); - } else { - autosave_timer->stop(); - } - } - - EditorSettings::get_singleton()->connect("settings_changed",this,"_editor_settings_changed"); - help_search->set_icon(get_icon("Help","EditorIcons")); - site_search->set_icon(get_icon("Godot","EditorIcons")); - class_search->set_icon(get_icon("ClassList","EditorIcons")); - - script_forward->set_icon(get_icon("Forward","EditorIcons")); - script_back->set_icon(get_icon("Back","EditorIcons")); - - - - - } - - if (p_what==NOTIFICATION_READY) { - - get_tree()->connect("tree_changed",this,"_tree_changed"); - editor->connect("request_help",this,"_request_help"); - } - - if (p_what==NOTIFICATION_EXIT_TREE) { - - editor->disconnect("play_pressed",this,"_editor_play"); - editor->disconnect("pause_pressed",this,"_editor_pause"); - editor->disconnect("stop_pressed",this,"_editor_stop"); - - } - - if (p_what==MainLoop::NOTIFICATION_WM_FOCUS_IN) { - - _test_script_times_on_disk(); - _update_modified_scripts_for_external_editor(); - } - - if (p_what==NOTIFICATION_PROCESS) { - - } - -} - -bool ScriptEditor::can_take_away_focus() const { - - int selected = tab_container->get_current_tab(); - if (selected<0 || selected>=tab_container->get_child_count()) - return true; - - ScriptEditorBase *current = tab_container->get_child(selected)->cast_to<ScriptEditorBase>(); - if (!current) - return true; - - - return current->can_lose_focus_on_node_selection(); - -} - -void ScriptEditor::close_builtin_scripts_from_scene(const String& p_scene) { - - - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - - if (se) { - - Ref<Script> script = se->get_edited_script(); - if (!script.is_valid()) - continue; - - if (script->get_path().find("::")!=-1 && script->get_path().begins_with(p_scene)) { //is an internal script and belongs to scene being closed - _close_tab(i); - i--; - - } - } - - } - - -} - -void ScriptEditor::edited_scene_changed() { - - _update_modified_scripts_for_external_editor(); - -} - -static const Node * _find_node_with_script(const Node* p_node, const RefPtr & p_script) { - - if (p_node->get_script()==p_script) - return p_node; - - for(int i=0;i<p_node->get_child_count();i++) { - - const Node *result = _find_node_with_script(p_node->get_child(i),p_script); - if (result) - return result; - } - - return NULL; -} - -Dictionary ScriptEditor::get_state() const { - - - //apply_scripts(); - - Dictionary state; -#if 0 - Array paths; - int open=-1; - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptTextEditor *se = tab_container->get_child(i)->cast_to<ScriptTextEditor>(); - if (!se) - continue; - - - Ref<Script> script = se->get_edited_script(); - if (script->get_path()!="" && script->get_path().find("local://")==-1 && script->get_path().find("::")==-1) { - - paths.push_back(script->get_path()); - } else { - - - const Node *owner = _find_node_with_script(get_tree()->get_root(),script.get_ref_ptr()); - if (owner) - paths.push_back(owner->get_path()); - - } - - if (i==tab_container->get_current_tab()) - open=i; - } - - if (paths.size()) - state["sources"]=paths; - if (open!=-1) - state["current"]=open; - -#endif - return state; -} -void ScriptEditor::set_state(const Dictionary& p_state) { - -#if 0 - print_line("attempt set state: "+String(Variant(p_state))); - - if (!p_state.has("sources")) - return; //bleh - - Array sources = p_state["sources"]; - for(int i=0;i<sources.size();i++) { - - Variant source=sources[i]; - - Ref<Script> script; - - if (source.get_type()==Variant::NODE_PATH) { - - - Node *owner=get_tree()->get_root()->get_node(source); - if (!owner) - continue; - - script = owner->get_script(); - } else if (source.get_type()==Variant::STRING) { - - - script = ResourceLoader::load(source,"Script"); - } - - - if (script.is_null()) //ah well.. - continue; - - editor->call("_resource_selected",script); - } - - if (p_state.has("current")) { - tab_container->set_current_tab(p_state["current"]); - } -#endif - -} -void ScriptEditor::clear() { -#if 0 - List<ScriptTextEditor*> stes; - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptTextEditor *se = tab_container->get_child(i)->cast_to<ScriptTextEditor>(); - if (!se) - continue; - stes.push_back(se); - - } - - while(stes.size()) { - - memdelete(stes.front()->get()); - stes.pop_front(); - } - - int idx = tab_container->get_current_tab(); - if (idx>=tab_container->get_child_count()) - idx=tab_container->get_child_count()-1; - if (idx>=0) { - tab_container->set_current_tab(idx); - script_list->select( script_list->find_metadata(idx) ); - } - -#endif - - -} - - -void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) { - - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (!se) - continue; - - List<int> bpoints; - se->get_breakpoints(&bpoints); - Ref<Script> script = se->get_edited_script(); - String base = script->get_path(); - ERR_CONTINUE( base.begins_with("local://") || base=="" ); - - for(List<int>::Element *E=bpoints.front();E;E=E->next()) { - - p_breakpoints->push_back(base+":"+itos(E->get()+1)); - } - } - -} - - - - - -void ScriptEditor::ensure_focus_current() { - - if (!is_inside_tree()) - return; - - int cidx = tab_container->get_current_tab(); - if (cidx<0 || cidx>=tab_container->get_tab_count()); - Control *c = tab_container->get_child(cidx)->cast_to<Control>(); - if (!c) - return; - ScriptEditorBase *se = c->cast_to<ScriptEditorBase>(); - if (!se) - return; - se->ensure_focus(); -} - -void ScriptEditor::_script_selected(int p_idx) { - - grab_focus_block = !Input::get_singleton()->is_mouse_button_pressed(1); //amazing hack, simply amazing - - _go_to_tab(script_list->get_item_metadata(p_idx)); - grab_focus_block=false; -} - -void ScriptEditor::ensure_select_current() { - - - if (tab_container->get_child_count() && tab_container->get_current_tab()>=0) { - - Node *current = tab_container->get_child(tab_container->get_current_tab()); - - - ScriptEditorBase *se = current->cast_to<ScriptEditorBase>(); - if (se) { - - Ref<Script> script = se->get_edited_script(); - - if (!grab_focus_block && is_visible_in_tree()) - se->ensure_focus(); - - - //edit_menu->show(); - //search_menu->show(); - - - } - - EditorHelp *eh = current->cast_to<EditorHelp>(); - - if (eh) { - //edit_menu->hide(); - //search_menu->hide(); - //script_search_menu->show(); - - } - } - - _update_selected_editor_menu(); - - - -} - -void ScriptEditor::_find_scripts(Node* p_base, Node* p_current, Set<Ref<Script> > &used) { - if (p_current!=p_base && p_current->get_owner()!=p_base) - return; - - if (p_current->get_script_instance()) { - Ref<Script> scr = p_current->get_script(); - if (scr.is_valid()) - used.insert(scr); - } - - for(int i=0;i<p_current->get_child_count();i++) { - _find_scripts(p_base,p_current->get_child(i),used); - } - -} - -struct _ScriptEditorItemData { - - String name; - String sort_key; - Ref<Texture> icon; - int index; - String tooltip; - bool used; - int category; - - - bool operator<(const _ScriptEditorItemData& id) const { - - return category==id.category?sort_key<id.sort_key:category<id.category; - } - -}; - - -void ScriptEditor::_update_script_colors() { - - bool script_temperature_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_enabled"); - bool highlight_current = EditorSettings::get_singleton()->get("text_editor/open_scripts/highlight_current_script"); - - int hist_size = EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_history_size"); - Color hot_color=EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_hot_color"); - Color cold_color=EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_cold_color"); - - for(int i=0;i<script_list->get_item_count();i++) { - - int c = script_list->get_item_metadata(i); - Node *n = tab_container->get_child(c); - if (!n) - continue; - - script_list->set_item_custom_bg_color(i,Color(0,0,0,0)); - - bool current = tab_container->get_current_tab() == c; - if (current && highlight_current) { - script_list->set_item_custom_bg_color(i, EditorSettings::get_singleton()->get("text_editor/open_scripts/current_script_background_color")); - - } else if (script_temperature_enabled) { - - if (!n->has_meta("__editor_pass")) { - continue; - } - - int pass=n->get_meta("__editor_pass"); - int h = edit_pass - pass; - if (h>hist_size) { - continue; - } - int non_zero_hist_size = ( hist_size == 0 ) ? 1 : hist_size; - float v = Math::ease((edit_pass-pass)/float(non_zero_hist_size),0.4); - - script_list->set_item_custom_bg_color(i,hot_color.linear_interpolate(cold_color,v)); - } - } -} - -void ScriptEditor::_update_script_names() { - - if (restoring_layout) - return; - - waiting_update_names=false; - Set<Ref<Script> > used; - Node* edited = EditorNode::get_singleton()->get_edited_scene(); - if (edited) { - _find_scripts(edited,edited,used); - } - - script_list->clear(); - bool split_script_help = EditorSettings::get_singleton()->get("text_editor/open_scripts/group_help_pages"); - ScriptSortBy sort_by = (ScriptSortBy) (int) EditorSettings::get_singleton()->get("text_editor/open_scripts/sort_scripts_by"); - ScriptListName display_as = (ScriptListName) (int) EditorSettings::get_singleton()->get("text_editor/open_scripts/list_script_names_as"); - - Vector<_ScriptEditorItemData> sedata; - - for(int i=0;i<tab_container->get_child_count();i++) { - - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (se) { - - String name = se->get_name(); - Ref<Texture> icon = se->get_icon(); - String path = se->get_edited_script()->get_path(); - - _ScriptEditorItemData sd; - sd.icon=icon; - sd.name=name; - sd.tooltip=path; - sd.index=i; - sd.used=used.has(se->get_edited_script()); - sd.category=0; - - switch (sort_by) { - case SORT_BY_NAME: { - sd.sort_key=name.to_lower(); - } break; - case SORT_BY_PATH: { - sd.sort_key=path; - } break; - } - - switch (display_as) { - case DISPLAY_NAME: { - sd.name=name; - } break; - case DISPLAY_DIR_AND_NAME: { - if (!path.get_base_dir().get_file().empty()) { - sd.name=path.get_base_dir().get_file() + "/" + name; - } else { - sd.name=name; - } - } break; - case DISPLAY_FULL_PATH: { - sd.name=path; - } break; - } - - - sedata.push_back(sd); - } - - EditorHelp *eh = tab_container->get_child(i)->cast_to<EditorHelp>(); - if (eh) { - - String name = eh->get_class(); - Ref<Texture> icon = get_icon("Help","EditorIcons"); - String tooltip = name+" Class Reference"; - - _ScriptEditorItemData sd; - sd.icon=icon; - sd.name=name; - sd.sort_key=name; - sd.tooltip=tooltip; - sd.index=i; - sd.used=false; - sd.category=split_script_help?1:0; - sedata.push_back(sd); - - } - - } - - sedata.sort(); - - for(int i=0;i<sedata.size();i++) { - - script_list->add_item(sedata[i].name,sedata[i].icon); - int index = script_list->get_item_count()-1; - script_list->set_item_tooltip(index,sedata[i].tooltip); - script_list->set_item_metadata(index,sedata[i].index); - if (sedata[i].used) { - - script_list->set_item_custom_bg_color(index,Color(88/255.0,88/255.0,60/255.0)); - } - if (tab_container->get_current_tab()==sedata[i].index) { - script_list->select(index); - script_name_label->set_text(sedata[i].name); - script_icon->set_texture(sedata[i].icon); - - } - } - - _update_script_colors(); - - - - -} - - - -void ScriptEditor::edit(const Ref<Script>& p_script, bool p_grab_focus) { - - if (p_script.is_null()) - return; - - // refuse to open built-in if scene is not loaded - - - - - // see if already has it - - bool open_dominant = EditorSettings::get_singleton()->get("text_editor/files/open_dominant_script_on_scene_change"); - - if (p_script->get_path().is_resource_file() && bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) { - - String path = EditorSettings::get_singleton()->get("text_editor/external/exec_path"); - String flags = EditorSettings::get_singleton()->get("text_editor/external/exec_flags"); - List<String> args; - flags=flags.strip_edges(); - if (flags!=String()) { - Vector<String> flagss = flags.split(" ",false); - for(int i=0;i<flagss.size();i++) - args.push_back(flagss[i]); - } - - args.push_back(GlobalConfig::get_singleton()->globalize_path(p_script->get_path())); - Error err = OS::get_singleton()->execute(path,args,false); - if (err==OK) - return; - WARN_PRINT("Couldn't open external text editor, using internal"); - } - - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (!se) - continue; - - if (se->get_edited_script()==p_script) { - - if (open_dominant || !EditorNode::get_singleton()->is_changing_scene()) { - if (tab_container->get_current_tab()!=i) { - _go_to_tab(i); - script_list->select( script_list->find_metadata(i) ); - } - if (is_visible_in_tree()) - se->ensure_focus(); - } - return; - } - } - - // doesn't have it, make a new one - - ScriptEditorBase *se; - - for(int i=script_editor_func_count-1;i>=0;i--) { - se = script_editor_funcs[i](p_script); - if (se) - break; - } - ERR_FAIL_COND(!se); - tab_container->add_child(se); - - se->set_edited_script(p_script); - se->set_tooltip_request_func("_get_debug_tooltip",this); - if (se->get_edit_menu()) { - se->get_edit_menu()->hide(); - menu_hb->add_child(se->get_edit_menu()); - menu_hb->move_child(se->get_edit_menu(),1); - } - - - if (p_grab_focus) { - _go_to_tab(tab_container->get_tab_count()-1); - } - - - - - - _update_script_names(); - _save_layout(); - se->connect("name_changed",this,"_update_script_names"); - se->connect("request_help_search",this,"_help_search"); - se->connect("request_open_script_at_line",this,"_goto_script_line"); - se->connect("go_to_help",this,"_help_class_goto"); - se->connect("request_save_history",this,"_save_history"); - - - - - //test for modification, maybe the script was not edited but was loaded - - _test_script_times_on_disk(p_script); - _update_modified_scripts_for_external_editor(p_script); - -} - -void ScriptEditor::save_all_scripts() { - - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (!se) - continue; - - - if (!se->is_unsaved()) - continue; - - if (trim_trailing_whitespace_on_save) { - se->trim_trailing_whitespace(); - } - - Ref<Script> script = se->get_edited_script(); - if (script.is_valid()) - se->apply_code(); - - if (script->get_path()!="" && script->get_path().find("local://")==-1 &&script->get_path().find("::")==-1) { - //external script, save it - - editor->save_resource(script); - //ResourceSaver::save(script->get_path(),script); - - } - - } - - _update_script_names(); - -} - -void ScriptEditor::apply_scripts() const { - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (!se) - continue; - se->apply_code(); - } - -} - -void ScriptEditor::_editor_play() { - - debugger->start(); - debug_menu->get_popup()->grab_focus(); - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_NEXT), true ); - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_STEP), true ); - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_BREAK), false ); - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true ); - - //debugger_gui->start_listening(Globals::get_singleton()->get("debug/debug_port")); -} - -void ScriptEditor::_editor_pause() { - - -} -void ScriptEditor::_editor_stop() { - - debugger->stop(); - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_NEXT), true ); - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_STEP), true ); - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_BREAK), true ); - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true ); - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (!se) { - - continue; - } - - se->set_debugger_active(false); - } -} - - -void ScriptEditor::_add_callback(Object *p_obj, const String& p_function, const PoolStringArray& p_args) { - - //print_line("add callback! hohoho"); kinda sad to remove this - ERR_FAIL_COND(!p_obj); - Ref<Script> script = p_obj->get_script(); - ERR_FAIL_COND( !script.is_valid() ); - - editor->push_item(script.ptr()); - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (!se) - continue; - if (se->get_edited_script()!=script) - continue; - - se->add_callback(p_function,p_args); - - _go_to_tab(i); - - script_list->select( script_list->find_metadata(i) ); - - break; - - } - -} - -void ScriptEditor::_save_layout() { - - if (restoring_layout) { - return; - } - - editor->save_layout(); -} - -void ScriptEditor::_editor_settings_changed() { - - trim_trailing_whitespace_on_save = EditorSettings::get_singleton()->get("text_editor/files/trim_trailing_whitespace_on_save"); - float autosave_time = EditorSettings::get_singleton()->get("text_editor/files/autosave_interval_secs"); - if (autosave_time>0) { - autosave_timer->set_wait_time(autosave_time); - autosave_timer->start(); - } else { - autosave_timer->stop(); - } - - if (current_theme == "") { - current_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme"); - } else if (current_theme != EditorSettings::get_singleton()->get("text_editor/theme/color_theme")) { - current_theme = EditorSettings::get_singleton()->get("text_editor/theme/color_theme"); - EditorSettings::get_singleton()->load_text_editor_theme(); - } - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (!se) - continue; - - se->update_settings(); - } - _update_script_colors(); - _update_script_names(); - - ScriptServer::set_reload_scripts_on_save(EDITOR_DEF("text_editor/files/auto_reload_and_parse_scripts_on_save",true)); - -} - -void ScriptEditor::_autosave_scripts() { - - save_all_scripts(); -} - -void ScriptEditor::_tree_changed() { - - if (waiting_update_names) - return; - - waiting_update_names=true; - call_deferred("_update_script_names"); -} - -void ScriptEditor::_script_split_dragged(float) { - - _save_layout(); -} - -void ScriptEditor::_unhandled_input(const InputEvent& p_event) { - if (p_event.key.pressed || !is_visible_in_tree()) return; - if (ED_IS_SHORTCUT("script_editor/next_script", p_event)) { - int next_tab = script_list->get_current() + 1; - next_tab %= script_list->get_item_count(); - _go_to_tab(script_list->get_item_metadata(next_tab)); - _update_script_names(); - } - if (ED_IS_SHORTCUT("script_editor/prev_script", p_event)) { - int next_tab = script_list->get_current() - 1; - next_tab = next_tab >= 0 ? next_tab : script_list->get_item_count() - 1; - _go_to_tab(script_list->get_item_metadata(next_tab)); - _update_script_names(); - } -} - -void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) { - - if (!bool(EDITOR_DEF("text_editor/files/restore_scripts_on_load",true))) { - return; - } - - if (!p_layout->has_section_key("ScriptEditor","open_scripts") && !p_layout->has_section_key("ScriptEditor","open_help")) - return; - - Array scripts = p_layout->get_value("ScriptEditor","open_scripts"); - Array helps; - if (p_layout->has_section_key("ScriptEditor","open_help")) - helps=p_layout->get_value("ScriptEditor","open_help"); - - restoring_layout=true; - - for(int i=0;i<scripts.size();i++) { - - String path = scripts[i]; - if (!FileAccess::exists(path)) - continue; - Ref<Script> scr = ResourceLoader::load(path); - if (scr.is_valid()) { - edit(scr); - } - } - - for(int i=0;i<helps.size();i++) { - - String path = helps[i]; - _help_class_open(path); - } - - for(int i=0;i<tab_container->get_child_count();i++) { - tab_container->get_child(i)->set_meta("__editor_pass",Variant()); - } - - - if (p_layout->has_section_key("ScriptEditor","split_offset")) { - script_split->set_split_offset(p_layout->get_value("ScriptEditor","split_offset")); - } - - restoring_layout=false; - - _update_script_names(); -} - -void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) { - - Array scripts; - Array helps; - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (se) { - - String path = se->get_edited_script()->get_path(); - if (!path.is_resource_file()) - continue; - - scripts.push_back(path); - } - - EditorHelp *eh = tab_container->get_child(i)->cast_to<EditorHelp>(); - - if (eh) { - - helps.push_back(eh->get_class()); - } - - - } - - p_layout->set_value("ScriptEditor","open_scripts",scripts); - p_layout->set_value("ScriptEditor","open_help",helps); - p_layout->set_value("ScriptEditor","split_offset",script_split->get_split_offset()); -} - - -void ScriptEditor::_help_class_open(const String& p_class) { - - if (p_class=="") - return; - - for(int i=0;i<tab_container->get_child_count();i++) { - - EditorHelp *eh = tab_container->get_child(i)->cast_to<EditorHelp>(); - - if (eh && eh->get_class()==p_class) { - - _go_to_tab(i); - _update_script_names(); - return; - } - } - - EditorHelp * eh = memnew( EditorHelp ); - - - eh->set_name(p_class); - tab_container->add_child(eh); - _go_to_tab(tab_container->get_tab_count()-1); - eh->go_to_class(p_class,0); - eh->connect("go_to_help",this,"_help_class_goto"); - _update_script_names(); - _save_layout(); -} - -void ScriptEditor::_help_class_goto(const String& p_desc) { - - String cname=p_desc.get_slice(":",1); - - for(int i=0;i<tab_container->get_child_count();i++) { - - EditorHelp *eh = tab_container->get_child(i)->cast_to<EditorHelp>(); - - if (eh && eh->get_class()==cname) { - - _go_to_tab(i); - eh->go_to_help(p_desc); - _update_script_names(); - return; - } - } - - EditorHelp * eh = memnew( EditorHelp ); - - eh->set_name(cname); - tab_container->add_child(eh); - _go_to_tab(tab_container->get_tab_count()-1); - eh->go_to_help(p_desc); - eh->connect("go_to_help",this,"_help_class_goto"); - _update_script_names(); - _save_layout(); -} - -void ScriptEditor::_update_selected_editor_menu() { - - for(int i=0;i<tab_container->get_child_count();i++) { - - bool current = tab_container->get_current_tab() == i; - - ScriptEditorBase *se = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - if (se && se->get_edit_menu()) { - - if (current) - se->get_edit_menu()->show(); - else - se->get_edit_menu()->hide(); - } - - } - - EditorHelp *eh=tab_container->get_current_tab_control()->cast_to<EditorHelp>(); - if (eh) { - script_search_menu->show(); - } else { - script_search_menu->hide(); - } -} - -void ScriptEditor::_update_history_pos(int p_new_pos) { - - Node *n = tab_container->get_current_tab_control(); - - if (n->cast_to<ScriptEditorBase>()) { - - history[history_pos].state=n->cast_to<ScriptEditorBase>()->get_edit_state(); - } - if (n->cast_to<EditorHelp>()) { - - history[history_pos].state=n->cast_to<EditorHelp>()->get_scroll(); - } - - history_pos=p_new_pos; - tab_container->set_current_tab(history[history_pos].control->get_index()); - - n = history[history_pos].control; - - if (n->cast_to<ScriptEditorBase>()) { - - n->cast_to<ScriptEditorBase>()->set_edit_state(history[history_pos].state); - n->cast_to<ScriptEditorBase>()->ensure_focus(); - } - - if (n->cast_to<EditorHelp>()) { - - n->cast_to<EditorHelp>()->set_scroll(history[history_pos].state); - n->cast_to<EditorHelp>()->set_focused(); - } - - n->set_meta("__editor_pass",++edit_pass); - _update_script_names(); - _update_history_arrows(); - _update_selected_editor_menu(); - -} - -void ScriptEditor::_history_forward() { - - if (history_pos<history.size()-1) { - _update_history_pos(history_pos+1); - } -} - -void ScriptEditor::_history_back(){ - - if (history_pos>0) { - _update_history_pos(history_pos-1); - } - -} -void ScriptEditor::set_scene_root_script( Ref<Script> p_script ) { - - bool open_dominant = EditorSettings::get_singleton()->get("text_editor/files/open_dominant_script_on_scene_change"); - - if (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) - return; - - if (open_dominant && p_script.is_valid() && _can_open_in_editor(p_script.ptr())) { - edit(p_script); - } -} - -bool ScriptEditor::script_go_to_method(Ref<Script> p_script, const String& p_method) { - - - for (int i=0;i<tab_container->get_child_count();i++) { - ScriptEditorBase *current = tab_container->get_child(i)->cast_to<ScriptEditorBase>(); - - if (current && current->get_edited_script()==p_script) { - if (current->goto_method(p_method)) { - edit(p_script); - return true; - } - break; - } - } - return false; -} - -void ScriptEditor::set_live_auto_reload_running_scripts(bool p_enabled) { - - auto_reload_running_scripts=p_enabled; -} - -void ScriptEditor::_help_search(String p_text) { - help_search_dialog->popup(p_text); -} - -void ScriptEditor::_open_script_request(const String& p_path) { - - Ref<Script> script = ResourceLoader::load(p_path); - if (script.is_valid()) { - script_editor->edit(script,false); - } -} - -int ScriptEditor::script_editor_func_count=0; -CreateScriptEditorFunc ScriptEditor::script_editor_funcs[ScriptEditor::SCRIPT_EDITOR_FUNC_MAX]; - -void ScriptEditor::register_create_script_editor_function(CreateScriptEditorFunc p_func) { - - ERR_FAIL_COND(script_editor_func_count==SCRIPT_EDITOR_FUNC_MAX); - script_editor_funcs[script_editor_func_count++]=p_func; -} - -void ScriptEditor::_bind_methods() { - - ClassDB::bind_method("_file_dialog_action",&ScriptEditor::_file_dialog_action); - ClassDB::bind_method("_tab_changed",&ScriptEditor::_tab_changed); - ClassDB::bind_method("_menu_option",&ScriptEditor::_menu_option); - ClassDB::bind_method("_close_current_tab",&ScriptEditor::_close_current_tab); - ClassDB::bind_method("_close_discard_current_tab", &ScriptEditor::_close_discard_current_tab); - ClassDB::bind_method("_close_docs_tab", &ScriptEditor::_close_docs_tab); - ClassDB::bind_method("_close_all_tabs", &ScriptEditor::_close_all_tabs); - ClassDB::bind_method("_editor_play",&ScriptEditor::_editor_play); - ClassDB::bind_method("_editor_pause",&ScriptEditor::_editor_pause); - ClassDB::bind_method("_editor_stop",&ScriptEditor::_editor_stop); - ClassDB::bind_method("_add_callback",&ScriptEditor::_add_callback); - ClassDB::bind_method("_reload_scripts",&ScriptEditor::_reload_scripts); - ClassDB::bind_method("_resave_scripts",&ScriptEditor::_resave_scripts); - ClassDB::bind_method("_res_saved_callback",&ScriptEditor::_res_saved_callback); - ClassDB::bind_method("_goto_script_line",&ScriptEditor::_goto_script_line); - ClassDB::bind_method("_goto_script_line2",&ScriptEditor::_goto_script_line2); - ClassDB::bind_method("_help_search",&ScriptEditor::_help_search); - ClassDB::bind_method("_save_history",&ScriptEditor::_save_history); - - - - ClassDB::bind_method("_breaked",&ScriptEditor::_breaked); - ClassDB::bind_method("_show_debugger",&ScriptEditor::_show_debugger); - ClassDB::bind_method("_get_debug_tooltip",&ScriptEditor::_get_debug_tooltip); - ClassDB::bind_method("_autosave_scripts",&ScriptEditor::_autosave_scripts); - ClassDB::bind_method("_editor_settings_changed",&ScriptEditor::_editor_settings_changed); - ClassDB::bind_method("_update_script_names",&ScriptEditor::_update_script_names); - ClassDB::bind_method("_tree_changed",&ScriptEditor::_tree_changed); - ClassDB::bind_method("_script_selected",&ScriptEditor::_script_selected); - ClassDB::bind_method("_script_created",&ScriptEditor::_script_created); - ClassDB::bind_method("_script_split_dragged",&ScriptEditor::_script_split_dragged); - ClassDB::bind_method("_help_class_open",&ScriptEditor::_help_class_open); - ClassDB::bind_method("_help_class_goto",&ScriptEditor::_help_class_goto); - ClassDB::bind_method("_request_help",&ScriptEditor::_help_class_open); - ClassDB::bind_method("_history_forward",&ScriptEditor::_history_forward); - ClassDB::bind_method("_history_back",&ScriptEditor::_history_back); - ClassDB::bind_method("_live_auto_reload_running_scripts",&ScriptEditor::_live_auto_reload_running_scripts); - ClassDB::bind_method("_unhandled_input",&ScriptEditor::_unhandled_input); - -} - -ScriptEditor::ScriptEditor(EditorNode *p_editor) { - - current_theme = ""; - - completion_cache = memnew( EditorScriptCodeCompletionCache ); - restoring_layout=false; - waiting_update_names=false; - pending_auto_reload=false; - auto_reload_running_scripts=false; - editor=p_editor; - - menu_hb = memnew( HBoxContainer ); - add_child(menu_hb); - - - script_split = memnew( HSplitContainer ); - add_child(script_split); - script_split->set_v_size_flags(SIZE_EXPAND_FILL); - - script_list = memnew( ItemList ); - script_split->add_child(script_list); - script_list->set_custom_minimum_size(Size2(0,0)); - script_split->set_split_offset(140); - - tab_container = memnew( TabContainer ); - tab_container->set_tabs_visible(false); - script_split->add_child(tab_container); - - - tab_container->set_h_size_flags(SIZE_EXPAND_FILL); - - ED_SHORTCUT("script_editor/next_script", TTR("Next script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_GREATER); - ED_SHORTCUT("script_editor/prev_script", TTR("Previous script"), KEY_MASK_CMD | KEY_LESS); - set_process_unhandled_input(true); - - file_menu = memnew( MenuButton ); - menu_hb->add_child(file_menu); - file_menu->set_text(TTR("File")); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new", TTR("New")), FILE_NEW); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/open", TTR("Open")), FILE_OPEN); - file_menu->get_popup()->add_separator(); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save", TTR("Save"), KEY_MASK_ALT|KEY_MASK_CMD|KEY_S), FILE_SAVE); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_as", TTR("Save As..")), FILE_SAVE_AS); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_all", TTR("Save All"), KEY_MASK_CMD|KEY_MASK_SHIFT|KEY_MASK_ALT|KEY_S), FILE_SAVE_ALL); - file_menu->get_popup()->add_separator(); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reload_script_soft", TTR("Soft Reload Script"), KEY_MASK_CMD|KEY_MASK_SHIFT|KEY_R), FILE_TOOL_RELOAD_SOFT); - file_menu->get_popup()->add_separator(); - - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_previous", TTR("History Prev"), KEY_MASK_ALT|KEY_LEFT), WINDOW_PREV); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_next", TTR("History Next"), KEY_MASK_ALT|KEY_RIGHT), WINDOW_NEXT); - file_menu->get_popup()->add_separator(); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/import_theme", TTR("Import Theme")), FILE_IMPORT_THEME); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reload_theme", TTR("Reload Theme")), FILE_RELOAD_THEME); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_theme", TTR("Save Theme")), FILE_SAVE_THEME); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_theme_as", TTR("Save Theme As")), FILE_SAVE_THEME_AS); - file_menu->get_popup()->add_separator(); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_docs", TTR("Close Docs")), CLOSE_DOCS); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_file", TTR("Close"), KEY_MASK_CMD | KEY_W), FILE_CLOSE); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_all", TTR("Close All")), CLOSE_ALL); - file_menu->get_popup()->connect("id_pressed", this,"_menu_option"); - - - - script_search_menu = memnew( MenuButton ); - menu_hb->add_child(script_search_menu); - script_search_menu->set_text(TTR("Search")); - script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find", TTR("Find.."), KEY_MASK_CMD|KEY_F), HELP_SEARCH_FIND); - script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_next", TTR("Find Next"), KEY_F3), HELP_SEARCH_FIND_NEXT); - script_search_menu->get_popup()->connect("id_pressed", this,"_menu_option"); - script_search_menu->hide(); - - - debug_menu = memnew( MenuButton ); - menu_hb->add_child(debug_menu); - debug_menu->set_text(TTR("Debug")); - debug_menu->get_popup()->add_separator(); - debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/step_over", TTR("Step Over"), KEY_F10), DEBUG_NEXT); - debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/step_into", TTR("Step Into"), KEY_F11), DEBUG_STEP); - debug_menu->get_popup()->add_separator(); - debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/break", TTR("Break")), DEBUG_BREAK); - debug_menu->get_popup()->add_shortcut(ED_SHORTCUT("debugger/continue", TTR("Continue")), DEBUG_CONTINUE); - debug_menu->get_popup()->add_separator(); - //debug_menu->get_popup()->add_check_item("Show Debugger",DEBUG_SHOW); - debug_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("debugger/keep_debugger_open", TTR("Keep Debugger Open")), DEBUG_SHOW_KEEP_OPEN); - debug_menu->get_popup()->connect("id_pressed", this,"_menu_option"); - - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_NEXT), true); - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_STEP), true ); - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_BREAK), true ); - debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true ); - - -#if 0 - window_menu = memnew( MenuButton ); - menu_hb->add_child(window_menu); - window_menu->set_text(TTR("Window")); - window_menu->get_popup()->add_item(TTR("Close"),WINDOW_CLOSE,KEY_MASK_CMD|KEY_W); - window_menu->get_popup()->add_separator(); - window_menu->get_popup()->add_item(TTR("Move Left"),WINDOW_MOVE_LEFT,KEY_MASK_CMD|KEY_LEFT); - window_menu->get_popup()->add_item(TTR("Move Right"),WINDOW_MOVE_RIGHT,KEY_MASK_CMD|KEY_RIGHT); - window_menu->get_popup()->add_separator(); - window_menu->get_popup()->connect("id_pressed", this,"_menu_option"); - -#endif - - - menu_hb->add_spacer(); - - - script_icon = memnew( TextureRect ); - menu_hb->add_child(script_icon); - script_name_label = memnew( Label ); - menu_hb->add_child(script_name_label); - - script_icon->hide(); - script_name_label->hide(); - - menu_hb->add_spacer(); - - site_search = memnew( ToolButton ); - site_search->set_text(TTR("Tutorials")); - site_search->connect("pressed",this,"_menu_option",varray(SEARCH_WEBSITE)); - menu_hb->add_child(site_search); - site_search->set_tooltip(TTR("Open https://godotengine.org at tutorials section.")); - - class_search = memnew( ToolButton ); - class_search->set_text(TTR("Classes")); - class_search->connect("pressed",this,"_menu_option",varray(SEARCH_CLASSES)); - menu_hb->add_child(class_search); - class_search->set_tooltip(TTR("Search the class hierarchy.")); - - help_search = memnew( ToolButton ); - help_search->set_text(TTR("Search Help")); - help_search->connect("pressed",this,"_menu_option",varray(SEARCH_HELP)); - menu_hb->add_child(help_search); - help_search->set_tooltip(TTR("Search the reference documentation.")); - - menu_hb->add_child( memnew( VSeparator) ); - - script_back = memnew( ToolButton ); - script_back->connect("pressed",this,"_history_back"); - menu_hb->add_child(script_back); - script_back->set_disabled(true); - script_back->set_tooltip(TTR("Go to previous edited document.")); - - script_forward = memnew( ToolButton ); - script_forward->connect("pressed",this,"_history_forward"); - menu_hb->add_child(script_forward); - script_forward->set_disabled(true); - script_forward->set_tooltip(TTR("Go to next edited document.")); - - - - tab_container->connect("tab_changed", this,"_tab_changed"); - - erase_tab_confirm = memnew( ConfirmationDialog ); - erase_tab_confirm->get_ok()->set_text(TTR("Save")); - erase_tab_confirm->add_button(TTR("Discard"), OS::get_singleton()->get_swap_ok_cancel(), "discard"); - erase_tab_confirm->connect("confirmed", this,"_close_current_tab"); - erase_tab_confirm->connect("custom_action", this, "_close_discard_current_tab"); - add_child(erase_tab_confirm); - - script_create_dialog = memnew(ScriptCreateDialog); - script_create_dialog->set_title(TTR("Create Script")); - add_child(script_create_dialog); - script_create_dialog->connect("script_created", this, "_script_created"); - - file_dialog_option = -1; - file_dialog = memnew( EditorFileDialog ); - add_child(file_dialog); - file_dialog->connect("file_selected", this,"_file_dialog_action"); - - - debugger = memnew( ScriptEditorDebugger(editor) ); - debugger->connect("goto_script_line",this,"_goto_script_line"); - debugger->connect("show_debugger",this,"_show_debugger"); - - disk_changed = memnew( ConfirmationDialog ); - { - VBoxContainer *vbc = memnew( VBoxContainer ); - disk_changed->add_child(vbc); - //disk_changed->set_child_rect(vbc); - - Label *dl = memnew( Label ); - dl->set_text(TTR("The following files are newer on disk.\nWhat action should be taken?:")); - vbc->add_child(dl); - - disk_changed_list = memnew( Tree ); - vbc->add_child(disk_changed_list); - disk_changed_list->set_v_size_flags(SIZE_EXPAND_FILL); - - disk_changed->connect("confirmed",this,"_reload_scripts"); - disk_changed->get_ok()->set_text(TTR("Reload")); - - disk_changed->add_button(TTR("Resave"),!OS::get_singleton()->get_swap_ok_cancel(),"resave"); - disk_changed->connect("custom_action",this,"_resave_scripts"); - - - } - - add_child(disk_changed); - - script_editor=this; - - - Button *db = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Debugger"),debugger); - debugger->set_tool_button(db); - - - debugger->connect("breaked",this,"_breaked"); - - autosave_timer = memnew( Timer ); - autosave_timer->set_one_shot(false); - add_child(autosave_timer); - - grab_focus_block=false; - - help_search_dialog = memnew( EditorHelpSearch ); - add_child(help_search_dialog); - help_search_dialog->connect("go_to_help",this,"_help_class_goto"); - - - help_index = memnew( EditorHelpIndex ); - add_child(help_index); - help_index->connect("open_class",this,"_help_class_open"); - - history_pos=-1; - //debugger_gui->hide(); - - edit_pass=0; - trim_trailing_whitespace_on_save = false; - - ScriptServer::edit_request_func=_open_script_request; -} - - -ScriptEditor::~ScriptEditor() { - - memdelete(completion_cache); -} - -void ScriptEditorPlugin::edit(Object *p_object) { - - if (!p_object->cast_to<Script>()) - return; - - script_editor->edit(p_object->cast_to<Script>()); - -} - -bool ScriptEditorPlugin::handles(Object *p_object) const { - - if (p_object->cast_to<Script>()) { - - bool valid = _can_open_in_editor(p_object->cast_to<Script>()); - - if (!valid) { //user tried to open it by clicking - EditorNode::get_singleton()->show_warning(TTR("Built-in scripts can only be edited when the scene they belong to is loaded")); - } - return valid; - } - - return p_object->is_class("Script"); -} - -void ScriptEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - script_editor->show(); - script_editor->set_process(true); - script_editor->ensure_select_current(); - } else { - - script_editor->hide(); - script_editor->set_process(false); - } - -} - -void ScriptEditorPlugin::selected_notify() { - - script_editor->ensure_select_current(); -} - -Dictionary ScriptEditorPlugin::get_state() const { - - return script_editor->get_state(); -} - -void ScriptEditorPlugin::set_state(const Dictionary& p_state) { - - script_editor->set_state(p_state); -} -void ScriptEditorPlugin::clear() { - - script_editor->clear(); -} - -void ScriptEditorPlugin::save_external_data() { - - script_editor->save_all_scripts(); -} - -void ScriptEditorPlugin::apply_changes() { - - script_editor->apply_scripts(); -} - -void ScriptEditorPlugin::restore_global_state() { - - -} - -void ScriptEditorPlugin::save_global_state() { - -} - -void ScriptEditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) { - - script_editor->set_window_layout(p_layout); -} - -void ScriptEditorPlugin::get_window_layout(Ref<ConfigFile> p_layout){ - - script_editor->get_window_layout(p_layout); -} - - -void ScriptEditorPlugin::get_breakpoints(List<String> *p_breakpoints) { - - - return script_editor->get_breakpoints(p_breakpoints); -} - -void ScriptEditorPlugin::edited_scene_changed() { - - script_editor->edited_scene_changed(); -} - - - -ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) { - - editor=p_node; - script_editor = memnew( ScriptEditor(p_node) ); - editor->get_viewport()->add_child(script_editor); - script_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); - - script_editor->hide(); - - EDITOR_DEF("text_editor/files/auto_reload_scripts_on_external_change",true); - ScriptServer::set_reload_scripts_on_save(EDITOR_DEF("text_editor/files/auto_reload_and_parse_scripts_on_save",true)); - EDITOR_DEF("text_editor/files/open_dominant_script_on_scene_change",true); - EDITOR_DEF("text_editor/external/use_external_editor",false); - EDITOR_DEF("text_editor/external/exec_path",""); - EDITOR_DEF("text_editor/open_scripts/script_temperature_enabled",true); - EDITOR_DEF("text_editor/open_scripts/highlight_current_script", true); - EDITOR_DEF("text_editor/open_scripts/script_temperature_history_size",15); - EDITOR_DEF("text_editor/open_scripts/script_temperature_hot_color",Color(1,0,0,0.3)); - EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color",Color(0,0,1,0.3)); - EDITOR_DEF("text_editor/open_scripts/current_script_background_color",Color(0.81,0.81,0.14,0.63)); - EDITOR_DEF("text_editor/open_scripts/group_help_pages",true); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT,"text_editor/open_scripts/sort_scripts_by",PROPERTY_HINT_ENUM,"Name,Path")); - EDITOR_DEF("text_editor/open_scripts/sort_scripts_by",0); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT,"text_editor/open_scripts/list_script_names_as",PROPERTY_HINT_ENUM,"Name,Parent Directory And Name,Full Path")); - EDITOR_DEF("text_editor/open_scripts/list_script_names_as",0); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"text_editor/external/exec_path",PROPERTY_HINT_GLOBAL_FILE)); - EDITOR_DEF("text_editor/external/exec_flags",""); - - -} - - -ScriptEditorPlugin::~ScriptEditorPlugin() -{ -} diff --git a/tools/editor/plugins/script_editor_plugin.h b/tools/editor/plugins/script_editor_plugin.h deleted file mode 100644 index 75099fc5ec..0000000000 --- a/tools/editor/plugins/script_editor_plugin.h +++ /dev/null @@ -1,394 +0,0 @@ -/*************************************************************************/ -/* script_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef SCRIPT_EDITOR_PLUGIN_H -#define SCRIPT_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/script_create_dialog.h" -#include "scene/gui/tab_container.h" -#include "scene/gui/text_edit.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/tool_button.h" -#include "scene/gui/tree.h" -#include "scene/main/timer.h" -#include "script_language.h" -#include "tools/editor/code_editor.h" -#include "scene/gui/split_container.h" -#include "scene/gui/item_list.h" -#include "tools/editor/editor_help.h" - -class ScriptEditorQuickOpen : public ConfirmationDialog { - - GDCLASS(ScriptEditorQuickOpen,ConfirmationDialog ) - - LineEdit *search_box; - Tree *search_options; - String function; - - void _update_search(); - - void _sbox_input(const InputEvent& p_ie); - Vector<String> functions; - - - void _confirmed(); - void _text_changed(const String& p_newtext); - -protected: - - void _notification(int p_what); - static void _bind_methods(); -public: - - void popup(const Vector<String>& p_base,bool p_dontclear=false); - ScriptEditorQuickOpen(); -}; - - -class ScriptEditorDebugger; - - - -class ScriptEditorBase : public Control { - - GDCLASS( ScriptEditorBase, Control ); -protected: - static void _bind_methods(); -public: - - virtual void apply_code()=0; - virtual Ref<Script> get_edited_script() const=0; - virtual Vector<String> get_functions()=0; - virtual void set_edited_script(const Ref<Script>& p_script)=0; - virtual void reload_text()=0; - virtual String get_name()=0; - virtual Ref<Texture> get_icon()=0; - virtual bool is_unsaved()=0; - virtual Variant get_edit_state()=0; - virtual void set_edit_state(const Variant& p_state)=0; - virtual void goto_line(int p_line,bool p_with_error=false)=0; - virtual void trim_trailing_whitespace()=0; - virtual void ensure_focus()=0; - virtual void tag_saved_version()=0; - virtual void reload(bool p_soft)=0; - virtual void get_breakpoints(List<int> *p_breakpoints)=0; - virtual bool goto_method(const String& p_method)=0; - virtual void add_callback(const String& p_function,PoolStringArray p_args)=0; - virtual void update_settings()=0; - virtual void set_debugger_active(bool p_active)=0; - virtual bool can_lose_focus_on_node_selection() { return true; } - - virtual void set_tooltip_request_func(String p_method,Object* p_obj)=0; - virtual Control *get_edit_menu()=0; - - ScriptEditorBase() {} -}; - - -typedef ScriptEditorBase* (*CreateScriptEditorFunc)(const Ref<Script>& p_script); - - -class EditorScriptCodeCompletionCache; - -class ScriptEditor : public VBoxContainer { - - GDCLASS(ScriptEditor, VBoxContainer ); - - - EditorNode *editor; - enum { - FILE_NEW, - FILE_OPEN, - FILE_SAVE, - FILE_SAVE_AS, - FILE_SAVE_ALL, - FILE_IMPORT_THEME, - FILE_RELOAD_THEME, - FILE_SAVE_THEME, - FILE_SAVE_THEME_AS, - FILE_CLOSE, - CLOSE_DOCS, - CLOSE_ALL, - FILE_TOOL_RELOAD, - FILE_TOOL_RELOAD_SOFT, - DEBUG_NEXT, - DEBUG_STEP, - DEBUG_BREAK, - DEBUG_CONTINUE, - DEBUG_SHOW, - DEBUG_SHOW_KEEP_OPEN, - SEARCH_HELP, - SEARCH_CLASSES, - SEARCH_WEBSITE, - HELP_SEARCH_FIND, - HELP_SEARCH_FIND_NEXT, - WINDOW_MOVE_LEFT, - WINDOW_MOVE_RIGHT, - WINDOW_NEXT, - WINDOW_PREV, - WINDOW_SELECT_BASE=100 - }; - - enum ScriptSortBy { - SORT_BY_NAME, - SORT_BY_PATH, - }; - - enum ScriptListName { - DISPLAY_NAME, - DISPLAY_DIR_AND_NAME, - DISPLAY_FULL_PATH, - }; - - HBoxContainer *menu_hb; - MenuButton *file_menu; - MenuButton *edit_menu; - MenuButton *script_search_menu; - MenuButton *debug_menu; - Timer *autosave_timer; - uint64_t idle; - - Button *help_search; - Button *site_search; - Button *class_search; - EditorHelpSearch *help_search_dialog; - - ItemList *script_list; - HSplitContainer *script_split; - TabContainer *tab_container; - EditorFileDialog *file_dialog; - ConfirmationDialog *erase_tab_confirm; - ScriptCreateDialog *script_create_dialog; - ScriptEditorDebugger* debugger; - ToolButton *scripts_visible; - - String current_theme; - - TextureRect *script_icon; - Label *script_name_label; - - ToolButton *script_back; - ToolButton *script_forward; - - enum { - SCRIPT_EDITOR_FUNC_MAX=32 - }; - - static int script_editor_func_count; - static CreateScriptEditorFunc script_editor_funcs[SCRIPT_EDITOR_FUNC_MAX]; - - struct ScriptHistory { - - Control *control; - Variant state; - }; - - Vector<ScriptHistory> history; - int history_pos; - - - EditorHelpIndex *help_index; - - void _tab_changed(int p_which); - void _menu_option(int p_optin); - - Tree *disk_changed_list; - ConfirmationDialog *disk_changed; - - bool restoring_layout; - - String _get_debug_tooltip(const String&p_text,Node *_ste); - - void _resave_scripts(const String& p_str); - void _reload_scripts(); - - bool _test_script_times_on_disk(Ref<Script> p_for_script=Ref<Script>()); - - void _close_tab(int p_idx, bool p_save=true); - - void _close_current_tab(); - void _close_discard_current_tab(const String& p_str); - void _close_docs_tab(); - void _close_all_tabs(); - - void _ask_close_current_unsaved_tab(ScriptEditorBase *current); - - bool grab_focus_block; - - bool pending_auto_reload; - bool auto_reload_running_scripts; - void _live_auto_reload_running_scripts(); - - void _update_selected_editor_menu(); - - EditorScriptCodeCompletionCache *completion_cache; - - void _editor_play(); - void _editor_pause(); - void _editor_stop(); - - int edit_pass; - - void _add_callback(Object *p_obj, const String& p_function, const PoolStringArray& p_args); - void _res_saved_callback(const Ref<Resource>& p_res); - - bool trim_trailing_whitespace_on_save; - - void _trim_trailing_whitespace(TextEdit *tx); - - void _goto_script_line2(int p_line); - void _goto_script_line(REF p_script,int p_line); - void _breaked(bool p_breaked,bool p_can_debug); - void _show_debugger(bool p_show); - void _update_window_menu(); - void _script_created(Ref<Script> p_script); - - void _save_layout(); - void _editor_settings_changed(); - void _autosave_scripts(); - - void _update_script_names(); - - void _script_selected(int p_idx); - - void _find_scripts(Node* p_base, Node* p_current,Set<Ref<Script> >& used); - - void _tree_changed(); - - void _script_split_dragged(float); - - void _unhandled_input(const InputEvent& p_event); - - void _help_search(String p_text); - - void _history_forward(); - void _history_back(); - - bool waiting_update_names; - - void _help_class_open(const String& p_class); - void _help_class_goto(const String& p_desc); - void _update_history_arrows(); - void _save_history(); - void _go_to_tab(int p_idx); - void _update_history_pos(int p_new_pos); - void _update_script_colors(); - void _update_modified_scripts_for_external_editor(Ref<Script> p_for_script=Ref<Script>()); - - int file_dialog_option; - void _file_dialog_action(String p_file); - - static void _open_script_request(const String& p_path); - - static ScriptEditor *script_editor; -protected: - void _notification(int p_what); - static void _bind_methods(); -public: - - static ScriptEditor *get_singleton() { return script_editor; } - - void ensure_focus_current(); - void apply_scripts() const; - - void ensure_select_current(); - void edit(const Ref<Script>& p_script,bool p_grab_focus=true); - - Dictionary get_state() const; - void set_state(const Dictionary& p_state); - void clear(); - - void get_breakpoints(List<String> *p_breakpoints); - - //void swap_lines(TextEdit *tx, int line1, int line2); - - void save_all_scripts(); - - void set_window_layout(Ref<ConfigFile> p_layout); - void get_window_layout(Ref<ConfigFile> p_layout); - - void set_scene_root_script( Ref<Script> p_script ); - - bool script_go_to_method(Ref<Script> p_script, const String& p_method); - - virtual void edited_scene_changed(); - - void close_builtin_scripts_from_scene(const String& p_scene); - - void goto_help(const String& p_desc) { _help_class_goto(p_desc); } - - bool can_take_away_focus() const; - - ScriptEditorDebugger *get_debugger() { return debugger; } - void set_live_auto_reload_running_scripts(bool p_enabled); - - static void register_create_script_editor_function(CreateScriptEditorFunc p_func); - ScriptEditor(EditorNode *p_editor); - ~ScriptEditor(); -}; - -class ScriptEditorPlugin : public EditorPlugin { - - GDCLASS( ScriptEditorPlugin, EditorPlugin ); - - ScriptEditor *script_editor; - EditorNode *editor; -public: - - virtual String get_name() const { return "Script"; } - bool has_main_screen() const { return true; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - virtual void selected_notify(); - - Dictionary get_state() const; - virtual void set_state(const Dictionary& p_state); - virtual void clear(); - - virtual void save_external_data(); - virtual void apply_changes(); - - virtual void restore_global_state(); - virtual void save_global_state(); - - virtual void set_window_layout(Ref<ConfigFile> p_layout); - virtual void get_window_layout(Ref<ConfigFile> p_layout); - - virtual void get_breakpoints(List<String> *p_breakpoints); - - - virtual void edited_scene_changed(); - - ScriptEditorPlugin(EditorNode *p_node); - ~ScriptEditorPlugin(); - -}; - -#endif // SCRIPT_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/script_text_editor.cpp b/tools/editor/plugins/script_text_editor.cpp deleted file mode 100644 index 9ec6266419..0000000000 --- a/tools/editor/plugins/script_text_editor.cpp +++ /dev/null @@ -1,1401 +0,0 @@ -/*************************************************************************/ -/* script_text_editor.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 "script_text_editor.h" - -#include "tools/editor/editor_settings.h" -#include "os/keyboard.h" -#include "tools/editor/script_editor_debugger.h" -#include "tools/editor/editor_node.h" - -Vector<String> ScriptTextEditor::get_functions() { - - - String errortxt; - int line=-1,col; - TextEdit *te=code_editor->get_text_edit(); - String text = te->get_text(); - List<String> fnc; - - if (script->get_language()->validate(text,line,col,errortxt,script->get_path(),&fnc)) { - - //if valid rewrite functions to latest - functions.clear(); - for (List<String>::Element *E=fnc.front();E;E=E->next()) { - - functions.push_back(E->get()); - } - - - } - - return functions; -} - -void ScriptTextEditor::apply_code() { - - if (script.is_null()) - return; - //print_line("applying code"); - script->set_source_code(code_editor->get_text_edit()->get_text()); - script->update_exports(); -} - -Ref<Script> ScriptTextEditor::get_edited_script() const { - - return script; -} - -bool ScriptTextEditor::goto_method(const String& p_method) { - - - Vector<String> functions = get_functions(); - - String method_search = p_method + ":"; - - for (int i=0;i<functions.size();i++) { - String function=functions[i]; - - if (function.begins_with(method_search)) { - - int line=function.get_slice(":",1).to_int(); - goto_line(line-1); - return true; - } - } - - return false; -} - -void ScriptTextEditor::_load_theme_settings() { - - TextEdit *text_edit = code_editor->get_text_edit(); - - text_edit->clear_colors(); - - /* keyword color */ - - - text_edit->add_color_override("background_color", EDITOR_DEF("text_editor/highlighting/background_color",Color(0,0,0,0))); - text_edit->add_color_override("completion_background_color", EDITOR_DEF("text_editor/highlighting/completion_background_color", Color(0,0,0,0))); - text_edit->add_color_override("completion_selected_color", EDITOR_DEF("text_editor/highlighting/completion_selected_color", Color::html("434244"))); - text_edit->add_color_override("completion_existing_color", EDITOR_DEF("text_editor/highlighting/completion_existing_color", Color::html("21dfdfdf"))); - text_edit->add_color_override("completion_scroll_color", EDITOR_DEF("text_editor/highlighting/completion_scroll_color", Color::html("ffffff"))); - text_edit->add_color_override("completion_font_color", EDITOR_DEF("text_editor/highlighting/completion_font_color", Color::html("aaaaaa"))); - text_edit->add_color_override("font_color",EDITOR_DEF("text_editor/highlighting/text_color",Color(0,0,0))); - text_edit->add_color_override("line_number_color",EDITOR_DEF("text_editor/highlighting/line_number_color",Color(0,0,0))); - text_edit->add_color_override("caret_color",EDITOR_DEF("text_editor/highlighting/caret_color",Color(0,0,0))); - text_edit->add_color_override("caret_background_color",EDITOR_DEF("text_editor/highlighting/caret_background_color",Color(0,0,0))); - text_edit->add_color_override("font_selected_color",EDITOR_DEF("text_editor/highlighting/text_selected_color",Color(1,1,1))); - text_edit->add_color_override("selection_color",EDITOR_DEF("text_editor/highlighting/selection_color",Color(0.2,0.2,1))); - text_edit->add_color_override("brace_mismatch_color",EDITOR_DEF("text_editor/highlighting/brace_mismatch_color",Color(1,0.2,0.2))); - text_edit->add_color_override("current_line_color",EDITOR_DEF("text_editor/highlighting/current_line_color",Color(0.3,0.5,0.8,0.15))); - text_edit->add_color_override("line_length_guideline_color", EDITOR_DEF("text_editor/highlighting/line_length_guideline_color", Color(0,0,0))); - text_edit->add_color_override("word_highlighted_color",EDITOR_DEF("text_editor/highlighting/word_highlighted_color",Color(0.8,0.9,0.9,0.15))); - text_edit->add_color_override("number_color",EDITOR_DEF("text_editor/highlighting/number_color",Color(0.9,0.6,0.0,2))); - text_edit->add_color_override("function_color",EDITOR_DEF("text_editor/highlighting/function_color",Color(0.4,0.6,0.8))); - text_edit->add_color_override("member_variable_color",EDITOR_DEF("text_editor/highlighting/member_variable_color",Color(0.9,0.3,0.3))); - text_edit->add_color_override("mark_color", EDITOR_DEF("text_editor/highlighting/mark_color", Color(1.0,0.4,0.4,0.4))); - text_edit->add_color_override("breakpoint_color", EDITOR_DEF("text_editor/highlighting/breakpoint_color", Color(0.8,0.8,0.4,0.2))); - text_edit->add_color_override("search_result_color",EDITOR_DEF("text_editor/highlighting/search_result_color",Color(0.05,0.25,0.05,1))); - text_edit->add_color_override("search_result_border_color",EDITOR_DEF("text_editor/highlighting/search_result_border_color",Color(0.1,0.45,0.1,1))); - text_edit->add_color_override("symbol_color",EDITOR_DEF("text_editor/highlighting/symbol_color",Color::hex(0x005291ff))); - text_edit->add_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing",4)); - - Color keyword_color= EDITOR_DEF("text_editor/highlighting/keyword_color",Color(0.5,0.0,0.2)); - - List<String> keywords; - script->get_language()->get_reserved_words(&keywords); - for(List<String>::Element *E=keywords.front();E;E=E->next()) { - - text_edit->add_keyword_color(E->get(),keyword_color); - } - - //colorize core types - Color basetype_color= EDITOR_DEF("text_editor/highlighting/base_type_color",Color(0.3,0.3,0.0)); - - text_edit->add_keyword_color("Vector2",basetype_color); - text_edit->add_keyword_color("Vector3",basetype_color); - text_edit->add_keyword_color("Plane",basetype_color); - text_edit->add_keyword_color("Quat",basetype_color); - text_edit->add_keyword_color("AABB",basetype_color); - text_edit->add_keyword_color("Matrix3",basetype_color); - text_edit->add_keyword_color("Transform",basetype_color); - text_edit->add_keyword_color("Color",basetype_color); - text_edit->add_keyword_color("Image",basetype_color); - text_edit->add_keyword_color("InputEvent",basetype_color); - text_edit->add_keyword_color("Rect2",basetype_color); - text_edit->add_keyword_color("NodePath",basetype_color); - - //colorize engine types - Color type_color= EDITOR_DEF("text_editor/highlighting/engine_type_color",Color(0.0,0.2,0.4)); - - List<StringName> types; - ClassDB::get_class_list(&types); - - for(List<StringName>::Element *E=types.front();E;E=E->next()) { - - String n = E->get(); - if (n.begins_with("_")) - n = n.substr(1, n.length()); - - text_edit->add_keyword_color(n,type_color); - } - - //colorize comments - Color comment_color = EDITOR_DEF("text_editor/highlighting/comment_color",Color::hex(0x797e7eff)); - List<String> comments; - script->get_language()->get_comment_delimiters(&comments); - - for(List<String>::Element *E=comments.front();E;E=E->next()) { - - String comment = E->get(); - String beg = comment.get_slice(" ",0); - String end = comment.get_slice_count(" ")>1?comment.get_slice(" ",1):String(); - - text_edit->add_color_region(beg,end,comment_color,end==""); - } - - //colorize strings - Color string_color = EDITOR_DEF("text_editor/highlighting/string_color",Color::hex(0x6b6f00ff)); - List<String> strings; - script->get_language()->get_string_delimiters(&strings); - - for (List<String>::Element *E=strings.front();E;E=E->next()) { - - String string = E->get(); - String beg = string.get_slice(" ",0); - String end = string.get_slice_count(" ")>1?string.get_slice(" ",1):String(); - text_edit->add_color_region(beg,end,string_color,end==""); - } -} - - -void ScriptTextEditor::reload_text() { - - ERR_FAIL_COND(script.is_null()) ; - - TextEdit *te = code_editor->get_text_edit(); - int column = te->cursor_get_column(); - int row = te->cursor_get_line(); - int h = te->get_h_scroll(); - int v = te->get_v_scroll(); - - te->set_text(script->get_source_code()); - te->clear_undo_history(); - te->cursor_set_line(row); - te->cursor_set_column(column); - te->set_h_scroll(h); - te->set_v_scroll(v); - - te->tag_saved_version(); - - code_editor->update_line_and_column(); - -} - -void ScriptTextEditor::_notification(int p_what) { - - if (p_what==NOTIFICATION_READY) { - - //emit_signal("name_changed"); - } -} - -void ScriptTextEditor::add_callback(const String& p_function,PoolStringArray p_args) { - - String code = code_editor->get_text_edit()->get_text(); - int pos = script->get_language()->find_function(p_function,code); - if (pos==-1) { - //does not exist - code_editor->get_text_edit()->deselect(); - pos=code_editor->get_text_edit()->get_line_count()+2; - String func = script->get_language()->make_function("",p_function,p_args); - //code=code+func; - code_editor->get_text_edit()->cursor_set_line(pos+1); - code_editor->get_text_edit()->cursor_set_column(1000000); //none shall be that big - code_editor->get_text_edit()->insert_text_at_cursor("\n\n"+func); - } - code_editor->get_text_edit()->cursor_set_line(pos); - code_editor->get_text_edit()->cursor_set_column(1); -} - -void ScriptTextEditor::update_settings() { - - code_editor->update_editor_settings(); -} - -bool ScriptTextEditor::is_unsaved() { - - return code_editor->get_text_edit()->get_version()!=code_editor->get_text_edit()->get_saved_version(); -} - -Variant ScriptTextEditor::get_edit_state() { - - Dictionary state; - - state["scroll_pos"]=code_editor->get_text_edit()->get_v_scroll(); - state["column"]=code_editor->get_text_edit()->cursor_get_column(); - state["row"]=code_editor->get_text_edit()->cursor_get_line(); - - return state; -} - -void ScriptTextEditor::trim_trailing_whitespace() { - - TextEdit *tx = code_editor->get_text_edit(); - - bool trimed_whitespace = false; - for (int i = 0; i < tx->get_line_count(); i++) { - String line = tx->get_line(i); - if (line.ends_with(" ") || line.ends_with("\t")) { - - if (!trimed_whitespace) { - tx->begin_complex_operation(); - trimed_whitespace = true; - } - - int end = 0; - for (int j = line.length() - 1; j > -1; j--) { - if (line[j] != ' ' && line[j] != '\t') { - end = j+1; - break; - } - } - tx->set_line(i, line.substr(0, end)); - } - } - if (trimed_whitespace) { - tx->end_complex_operation(); - tx->update(); - } -} - -void ScriptTextEditor::tag_saved_version() { - - code_editor->get_text_edit()->tag_saved_version(); -} - -void ScriptTextEditor::goto_line(int p_line, bool p_with_error) { - code_editor->get_text_edit()->cursor_set_line(p_line); -} - -void ScriptTextEditor::ensure_focus() { - - code_editor->get_text_edit()->grab_focus(); -} - -void ScriptTextEditor::set_edit_state(const Variant& p_state) { - - Dictionary state=p_state; - code_editor->get_text_edit()->set_v_scroll(state["scroll_pos"]); - code_editor->get_text_edit()->cursor_set_column( state["column"]); - code_editor->get_text_edit()->cursor_set_line( state["row"] ); - code_editor->get_text_edit()->grab_focus(); - - //int scroll_pos; - //int cursor_column; - //int cursor_row; -} - -String ScriptTextEditor::get_name() { - String name; - - if (script->get_path().find("local://")==-1 && script->get_path().find("::")==-1) { - name=script->get_path().get_file(); - if (is_unsaved()) { - name+="(*)"; - } - } else if (script->get_name()!="") - name=script->get_name(); - else - name=script->get_class()+"("+itos(script->get_instance_ID())+")"; - - return name; - -} - -Ref<Texture> ScriptTextEditor::get_icon() { - - if (get_parent_control() && get_parent_control()->has_icon(script->get_class(),"EditorIcons")) { - return get_parent_control()->get_icon(script->get_class(),"EditorIcons"); - } - - return Ref<Texture>(); -} - - - -void ScriptTextEditor::set_edited_script(const Ref<Script>& p_script) { - - ERR_FAIL_COND(!script.is_null()); - - script=p_script; - - - _load_theme_settings(); - - code_editor->get_text_edit()->set_text(script->get_source_code()); - code_editor->get_text_edit()->clear_undo_history(); - code_editor->get_text_edit()->tag_saved_version(); - - emit_signal("name_changed"); - code_editor->update_line_and_column(); -} - - -void ScriptTextEditor::_validate_script() { - - String errortxt; - int line=-1,col; - TextEdit *te=code_editor->get_text_edit(); - - String text = te->get_text(); - List<String> fnc; - - if (!script->get_language()->validate(text,line,col,errortxt,script->get_path(),&fnc)) { - String error_text="error("+itos(line)+","+itos(col)+"): "+errortxt; - code_editor->set_error(error_text); - } else { - code_editor->set_error(""); - line=-1; - if (!script->is_tool()) { - script->set_source_code(text); - script->update_exports(); - //script->reload(); //will update all the variables in property editors - } - - functions.clear(); - for (List<String>::Element *E=fnc.front();E;E=E->next()) { - - functions.push_back(E->get()); - } - - } - - line--; - for(int i=0;i<te->get_line_count();i++) { - te->set_line_as_marked(i,line==i); - } - - emit_signal("name_changed"); -} - - -static Node* _find_node_for_script(Node* p_base, Node*p_current, const Ref<Script>& p_script) { - - if (p_current->get_owner()!=p_base && p_base!=p_current) - return NULL; - Ref<Script> c = p_current->get_script(); - if (c==p_script) - return p_current; - for(int i=0;i<p_current->get_child_count();i++) { - Node *found = _find_node_for_script(p_base,p_current->get_child(i),p_script); - if (found) - return found; - } - - return NULL; -} - -static void _find_changed_scripts_for_external_editor(Node* p_base, Node*p_current, Set<Ref<Script> > &r_scripts) { - - if (p_current->get_owner()!=p_base && p_base!=p_current) - return; - Ref<Script> c = p_current->get_script(); - - if (c.is_valid()) - r_scripts.insert(c); - - for(int i=0;i<p_current->get_child_count();i++) { - _find_changed_scripts_for_external_editor(p_base,p_current->get_child(i),r_scripts); - } - -} - -void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_for_script) { - - if (!bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) - return; - - Set<Ref<Script> > scripts; - - Node *base = get_tree()->get_edited_scene_root(); - if (base) { - _find_changed_scripts_for_external_editor(base,base,scripts); - } - - for (Set<Ref<Script> >::Element *E=scripts.front();E;E=E->next()) { - - Ref<Script> script = E->get(); - - if (p_for_script.is_valid() && p_for_script!=script) - continue; - - if (script->get_path()=="" || script->get_path().find("local://")!=-1 || script->get_path().find("::")!=-1) { - - continue; //internal script, who cares, though weird - } - - uint64_t last_date = script->get_last_modified_time(); - uint64_t date = FileAccess::get_modified_time(script->get_path()); - - if (last_date!=date) { - - Ref<Script> rel_script = ResourceLoader::load(script->get_path(),script->get_class(),true); - ERR_CONTINUE(!rel_script.is_valid()); - script->set_source_code( rel_script->get_source_code() ); - script->set_last_modified_time( rel_script->get_last_modified_time() ); - script->update_exports(); - } - - } -} - - -void ScriptTextEditor::_code_complete_scripts(void* p_ud,const String& p_code, List<String>* r_options) { - - ScriptTextEditor *ste = (ScriptTextEditor *)p_ud; - ste->_code_complete_script(p_code,r_options); -} - -void ScriptTextEditor::_code_complete_script(const String& p_code, List<String>* r_options) { - - if (color_panel->is_visible_in_tree()) return; - Node *base = get_tree()->get_edited_scene_root(); - if (base) { - base = _find_node_for_script(base,base,script); - } - String hint; - Error err = script->get_language()->complete_code(p_code,script->get_path().get_base_dir(),base,r_options,hint); - if (hint!="") { - code_editor->get_text_edit()->set_code_hint(hint); - } - -} - -void ScriptTextEditor::_breakpoint_toggled(int p_row) { - - ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(script->get_path(),p_row+1,code_editor->get_text_edit()->is_line_set_as_breakpoint(p_row)); - -} - -static void swap_lines(TextEdit *tx, int line1, int line2) -{ - String tmp = tx->get_line(line1); - String tmp2 = tx->get_line(line2); - tx->set_line(line2, tmp); - tx->set_line(line1, tmp2); - - tx->cursor_set_line(line2); -} - -void ScriptTextEditor::_lookup_symbol(const String& p_symbol,int p_row, int p_column) { - - Node *base = get_tree()->get_edited_scene_root(); - if (base) { - base = _find_node_for_script(base,base,script); - } - - - ScriptLanguage::LookupResult result; - if (script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(),p_symbol,script->get_path().get_base_dir(),base,result)==OK) { - - _goto_line(p_row); - - switch(result.type) { - case ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION: { - - if (result.script.is_valid()) { - emit_signal("request_open_script_at_line",result.script,result.location-1); - } else { - emit_signal("request_save_history"); - _goto_line(result.location-1); - } - } break; - case ScriptLanguage::LookupResult::RESULT_CLASS: { - emit_signal("go_to_help","class_name:"+result.class_name); - } break; - case ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT: { - - StringName cname = result.class_name; - bool success; - while(true) { - ClassDB::get_integer_constant(cname,result.class_member,&success); - if (success) { - result.class_name=cname; - cname=ClassDB::get_parent_class(cname); - } else { - break; - } - } - - - emit_signal("go_to_help","class_constant:"+result.class_name+":"+result.class_member); - - } break; - case ScriptLanguage::LookupResult::RESULT_CLASS_PROPERTY: { - emit_signal("go_to_help","class_property:"+result.class_name+":"+result.class_member); - - } break; - case ScriptLanguage::LookupResult::RESULT_CLASS_METHOD: { - - StringName cname = result.class_name; - - while(true) { - if (ClassDB::has_method(cname,result.class_member)) { - result.class_name=cname; - cname=ClassDB::get_parent_class(cname); - } else { - break; - } - } - - emit_signal("go_to_help","class_method:"+result.class_name+":"+result.class_member); - - } break; - } - - } -} - -void ScriptTextEditor::_edit_option(int p_op) { - - switch(p_op) { - case EDIT_UNDO: { - code_editor->get_text_edit()->undo(); - code_editor->get_text_edit()->call_deferred("grab_focus"); - } break; - case EDIT_REDO: { - code_editor->get_text_edit()->redo(); - code_editor->get_text_edit()->call_deferred("grab_focus"); - } break; - case EDIT_CUT: { - - code_editor->get_text_edit()->cut(); - code_editor->get_text_edit()->call_deferred("grab_focus"); - } break; - case EDIT_COPY: { - code_editor->get_text_edit()->copy(); - code_editor->get_text_edit()->call_deferred("grab_focus"); - - } break; - case EDIT_PASTE: { - code_editor->get_text_edit()->paste(); - code_editor->get_text_edit()->call_deferred("grab_focus"); - - } break; - case EDIT_SELECT_ALL: { - - code_editor->get_text_edit()->select_all(); - code_editor->get_text_edit()->call_deferred("grab_focus"); - - } break; - case EDIT_MOVE_LINE_UP: { - - TextEdit *tx = code_editor->get_text_edit(); - Ref<Script> scr = script; - if (scr.is_null()) - return; - - tx->begin_complex_operation(); - if (tx->is_selection_active()) - { - int from_line = tx->get_selection_from_line(); - int from_col = tx->get_selection_from_column(); - int to_line = tx->get_selection_to_line(); - int to_column = tx->get_selection_to_column(); - - for (int i = from_line; i <= to_line; i++) - { - int line_id = i; - int next_id = i - 1; - - if (line_id == 0 || next_id < 0) - return; - - swap_lines(tx, line_id, next_id); - } - int from_line_up = from_line > 0 ? from_line-1 : from_line; - int to_line_up = to_line > 0 ? to_line-1 : to_line; - tx->select(from_line_up, from_col, to_line_up, to_column); - } - else - { - int line_id = tx->cursor_get_line(); - int next_id = line_id - 1; - - if (line_id == 0 || next_id < 0) - return; - - swap_lines(tx, line_id, next_id); - } - tx->end_complex_operation(); - tx->update(); - - } break; - case EDIT_MOVE_LINE_DOWN: { - - TextEdit *tx = code_editor->get_text_edit(); - Ref<Script> scr = get_edited_script(); - if (scr.is_null()) - return; - - tx->begin_complex_operation(); - if (tx->is_selection_active()) - { - int from_line = tx->get_selection_from_line(); - int from_col = tx->get_selection_from_column(); - int to_line = tx->get_selection_to_line(); - int to_column = tx->get_selection_to_column(); - - for (int i = to_line; i >= from_line; i--) - { - int line_id = i; - int next_id = i + 1; - - if (line_id == tx->get_line_count()-1 || next_id > tx->get_line_count()) - return; - - swap_lines(tx, line_id, next_id); - } - int from_line_down = from_line < tx->get_line_count() ? from_line+1 : from_line; - int to_line_down = to_line < tx->get_line_count() ? to_line+1 : to_line; - tx->select(from_line_down, from_col, to_line_down, to_column); - } - else - { - int line_id = tx->cursor_get_line(); - int next_id = line_id + 1; - - if (line_id == tx->get_line_count()-1 || next_id > tx->get_line_count()) - return; - - swap_lines(tx, line_id, next_id); - } - tx->end_complex_operation(); - tx->update(); - - } break; - case EDIT_INDENT_LEFT: { - - TextEdit *tx = code_editor->get_text_edit(); - Ref<Script> scr = get_edited_script(); - if (scr.is_null()) - return; - - tx->begin_complex_operation(); - if (tx->is_selection_active()) - { - tx->indent_selection_left(); - } - else - { - int begin = tx->cursor_get_line(); - String line_text = tx->get_line(begin); - // begins with tab - if (line_text.begins_with("\t")) - { - line_text = line_text.substr(1, line_text.length()); - tx->set_line(begin, line_text); - } - // begins with 4 spaces - else if (line_text.begins_with(" ")) - { - line_text = line_text.substr(4, line_text.length()); - tx->set_line(begin, line_text); - } - } - tx->end_complex_operation(); - tx->update(); - //tx->deselect(); - - } break; - case EDIT_INDENT_RIGHT: { - - TextEdit *tx = code_editor->get_text_edit(); - Ref<Script> scr = get_edited_script(); - if (scr.is_null()) - return; - - tx->begin_complex_operation(); - if (tx->is_selection_active()) - { - tx->indent_selection_right(); - } - else - { - int begin = tx->cursor_get_line(); - String line_text = tx->get_line(begin); - line_text = '\t' + line_text; - tx->set_line(begin, line_text); - } - tx->end_complex_operation(); - tx->update(); - //tx->deselect(); - - } break; - case EDIT_CLONE_DOWN: { - - TextEdit *tx = code_editor->get_text_edit(); - Ref<Script> scr = get_edited_script(); - if (scr.is_null()) - return; - - int from_line = tx->cursor_get_line(); - int to_line = tx->cursor_get_line(); - int column = tx->cursor_get_column(); - - if (tx->is_selection_active()) { - from_line = tx->get_selection_from_line(); - to_line = tx->get_selection_to_line(); - column = tx->cursor_get_column(); - } - int next_line = to_line + 1; - - tx->begin_complex_operation(); - for (int i = from_line; i <= to_line; i++) { - - if (i >= tx->get_line_count() - 1) { - tx->set_line(i, tx->get_line(i) + "\n"); - } - String line_clone = tx->get_line(i); - tx->insert_at(line_clone, next_line); - next_line++; - } - - tx->cursor_set_column(column); - if (tx->is_selection_active()) { - tx->select(to_line + 1, tx->get_selection_from_column(), next_line - 1, tx->get_selection_to_column()); - } - - tx->end_complex_operation(); - tx->update(); - - } break; - case EDIT_TOGGLE_COMMENT: { - - TextEdit *tx = code_editor->get_text_edit(); - Ref<Script> scr = get_edited_script(); - if (scr.is_null()) - return; - - - tx->begin_complex_operation(); - if (tx->is_selection_active()) - { - int begin = tx->get_selection_from_line(); - int end = tx->get_selection_to_line(); - - // End of selection ends on the first column of the last line, ignore it. - if(tx->get_selection_to_column() == 0) - end -= 1; - - for (int i = begin; i <= end; i++) - { - String line_text = tx->get_line(i); - - if (line_text.begins_with("#")) - line_text = line_text.substr(1, line_text.length()); - else - line_text = "#" + line_text; - tx->set_line(i, line_text); - } - } - else - { - int begin = tx->cursor_get_line(); - String line_text = tx->get_line(begin); - - if (line_text.begins_with("#")) - line_text = line_text.substr(1, line_text.length()); - else - line_text = "#" + line_text; - tx->set_line(begin, line_text); - } - tx->end_complex_operation(); - tx->update(); - //tx->deselect(); - - } break; - case EDIT_COMPLETE: { - - code_editor->get_text_edit()->query_code_comple(); - - } break; - case EDIT_AUTO_INDENT: { - - TextEdit *te = code_editor->get_text_edit(); - String text = te->get_text(); - Ref<Script> scr = get_edited_script(); - if (scr.is_null()) - return; - int begin,end; - if (te->is_selection_active()) { - begin=te->get_selection_from_line(); - end=te->get_selection_to_line(); - } else { - begin=0; - end=te->get_line_count()-1; - } - scr->get_language()->auto_indent_code(text,begin,end); - te->set_text(text); - - - } break; - case EDIT_TRIM_TRAILING_WHITESAPCE: { - trim_trailing_whitespace(); - } break; - case EDIT_PICK_COLOR: { - color_panel->popup(); - } break; - - - case SEARCH_FIND: { - - code_editor->get_find_replace_bar()->popup_search(); - } break; - case SEARCH_FIND_NEXT: { - - code_editor->get_find_replace_bar()->search_next(); - } break; - case SEARCH_FIND_PREV: { - - code_editor->get_find_replace_bar()->search_prev(); - } break; - case SEARCH_REPLACE: { - - code_editor->get_find_replace_bar()->popup_replace(); - } break; - case SEARCH_LOCATE_FUNCTION: { - - quick_open->popup(get_functions()); - } break; - case SEARCH_GOTO_LINE: { - - goto_line_dialog->popup_find_line(code_editor->get_text_edit()); - } break; - case DEBUG_TOGGLE_BREAKPOINT: { - int line=code_editor->get_text_edit()->cursor_get_line(); - bool dobreak = !code_editor->get_text_edit()->is_line_set_as_breakpoint(line); - code_editor->get_text_edit()->set_line_as_breakpoint(line,dobreak); - ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(get_edited_script()->get_path(),line+1,dobreak); - } break; - case DEBUG_REMOVE_ALL_BREAKPOINTS: { - List<int> bpoints; - code_editor->get_text_edit()->get_breakpoints(&bpoints); - - for(List<int>::Element *E=bpoints.front();E;E=E->next()) { - int line = E->get(); - bool dobreak = !code_editor->get_text_edit()->is_line_set_as_breakpoint(line); - code_editor->get_text_edit()->set_line_as_breakpoint(line,dobreak); - ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(get_edited_script()->get_path(),line+1,dobreak); - } - } - case DEBUG_GOTO_NEXT_BREAKPOINT: { - List<int> bpoints; - code_editor->get_text_edit()->get_breakpoints(&bpoints); - if (bpoints.size() <= 0) { - return; - } - - int line=code_editor->get_text_edit()->cursor_get_line(); - // wrap around - if (line >= bpoints[bpoints.size() - 1]) { - code_editor->get_text_edit()->cursor_set_line(bpoints[0]); - } else { - for(List<int>::Element *E=bpoints.front();E;E=E->next()) { - int bline = E->get(); - if (bline > line) { - code_editor->get_text_edit()->cursor_set_line(bline); - return; - } - } - } - - } break; - case DEBUG_GOTO_PREV_BREAKPOINT: { - List<int> bpoints; - code_editor->get_text_edit()->get_breakpoints(&bpoints); - if (bpoints.size() <= 0) { - return; - } - - int line=code_editor->get_text_edit()->cursor_get_line(); - // wrap around - if (line <= bpoints[0]) { - code_editor->get_text_edit()->cursor_set_line(bpoints[bpoints.size() - 1]); - } else { - for(List<int>::Element *E=bpoints.back();E;E=E->prev()) { - int bline = E->get(); - if (bline < line) { - code_editor->get_text_edit()->cursor_set_line(bline); - return; - } - } - } - - } break; - - case HELP_CONTEXTUAL: { - String text = code_editor->get_text_edit()->get_selection_text(); - if (text == "") - text = code_editor->get_text_edit()->get_word_under_cursor(); - if (text != "") { - emit_signal("request_help_search",text); - } - } break; - } -} - -void ScriptTextEditor::_bind_methods() { - - ClassDB::bind_method("_validate_script",&ScriptTextEditor::_validate_script); - ClassDB::bind_method("_load_theme_settings",&ScriptTextEditor::_load_theme_settings); - ClassDB::bind_method("_breakpoint_toggled",&ScriptTextEditor::_breakpoint_toggled); - ClassDB::bind_method("_edit_option",&ScriptTextEditor::_edit_option); - ClassDB::bind_method("_goto_line",&ScriptTextEditor::_goto_line); - ClassDB::bind_method("_lookup_symbol",&ScriptTextEditor::_lookup_symbol); - ClassDB::bind_method("_text_edit_gui_input", &ScriptTextEditor::_text_edit_gui_input); - ClassDB::bind_method("_color_changed", &ScriptTextEditor::_color_changed); - - - ClassDB::bind_method("get_drag_data_fw",&ScriptTextEditor::get_drag_data_fw); - ClassDB::bind_method("can_drop_data_fw",&ScriptTextEditor::can_drop_data_fw); - ClassDB::bind_method("drop_data_fw",&ScriptTextEditor::drop_data_fw); - -} - -Control *ScriptTextEditor::get_edit_menu() { - - return edit_hb; -} - -void ScriptTextEditor::reload(bool p_soft) { - - TextEdit *te = code_editor->get_text_edit(); - Ref<Script> scr = get_edited_script(); - if (scr.is_null()) - return; - scr->set_source_code(te->get_text()); - bool soft = p_soft || scr->get_instance_base_type()=="EditorPlugin"; //always soft-reload editor plugins - - scr->get_language()->reload_tool_script(scr,soft); -} - -void ScriptTextEditor::get_breakpoints(List<int> *p_breakpoints) { - - code_editor->get_text_edit()->get_breakpoints(p_breakpoints); - -} - -void ScriptTextEditor::set_tooltip_request_func(String p_method,Object* p_obj) { - - code_editor->get_text_edit()->set_tooltip_request_func(p_obj,p_method,this); -} - -void ScriptTextEditor::set_debugger_active(bool p_active) { - - -} - - -Variant ScriptTextEditor::get_drag_data_fw(const Point2& p_point,Control* p_from) { - - return Variant(); -} - -bool ScriptTextEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const{ - - Dictionary d = p_data; - if (d.has("type") && - ( - - String(d["type"])=="resource" || - String(d["type"])=="files" || - String(d["type"])=="nodes" - ) ) { - - - return true; - } - - - return false; - -} - -#ifdef TOOLS_ENABLED - -static Node* _find_script_node(Node* p_edited_scene,Node* p_current_node,const Ref<Script> &script) { - - if (p_edited_scene!=p_current_node && p_current_node->get_owner()!=p_edited_scene) - return NULL; - - Ref<Script> scr = p_current_node->get_script(); - - if (scr.is_valid() && scr==script) - return p_current_node; - - for(int i=0;i<p_current_node->get_child_count();i++) { - Node *n = _find_script_node(p_edited_scene,p_current_node->get_child(i),script); - if (n) - return n; - } - - return NULL; -} - -#else - -static Node* _find_script_node(Node* p_edited_scene,Node* p_current_node,const Ref<Script> &script) { - - return NULL; -} -#endif - - - - -void ScriptTextEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from){ - - Dictionary d = p_data; - - if (d.has("type") && String(d["type"])=="resource") { - - Ref<Resource> res = d["resource"]; - if (!res.is_valid()) { - return; - } - - if (res->get_path().is_resource_file()) { - EditorNode::get_singleton()->show_warning("Only resources from filesystem can be dropped."); - return; - } - - code_editor->get_text_edit()->insert_text_at_cursor(res->get_path()); - - } - - if (d.has("type") && String(d["type"])=="files") { - - - Array files = d["files"]; - - String text_to_drop; - for(int i=0;i<files.size();i++) { - - if (i>0) - text_to_drop+=","; - text_to_drop+="\""+String(files[i]).c_escape()+"\""; - - } - - code_editor->get_text_edit()->insert_text_at_cursor(text_to_drop); - - } - - if (d.has("type") && String(d["type"])=="nodes") { - - Node* sn = _find_script_node(get_tree()->get_edited_scene_root(),get_tree()->get_edited_scene_root(),script); - - - if (!sn) { - EditorNode::get_singleton()->show_warning("Can't drop nodes because script '"+get_name()+"' is not used in this scene."); - return; - } - - - Array nodes = d["nodes"]; - String text_to_drop; - for(int i=0;i<nodes.size();i++) { - - if (i>0) - text_to_drop+=","; - - NodePath np = nodes[i]; - Node *node = get_node(np); - if (!node) { - continue; - } - - - - String path = sn->get_path_to(node); - text_to_drop+="\""+path.c_escape()+"\""; - - - } - - code_editor->get_text_edit()->insert_text_at_cursor(text_to_drop); - - - } - - - -} - -void ScriptTextEditor::_text_edit_gui_input(const InputEvent& ev) { - if (ev.type == InputEvent::MOUSE_BUTTON) { - InputEventMouseButton mb = ev.mouse_button; - if (mb.button_index == BUTTON_RIGHT && !mb.pressed) { - - int col, row; - TextEdit* tx = code_editor->get_text_edit(); - tx->_get_mouse_pos(Point2i(mb.global_x, mb.global_y)-tx->get_global_pos(), row, col); - Vector2 mpos = Vector2(mb.global_x, mb.global_y)-tx->get_global_pos(); - bool have_selection = (tx->get_selection_text().length() > 0); - bool have_color = (tx->get_word_at_pos(mpos) == "Color"); - if (have_color) { - - String line = tx->get_line(row); - color_line = row; - int begin = 0; - int end = 0; - bool valid = false; - for (int i = col; i < line.length(); i++) { - if (line[i] == '(') { - begin = i; - continue; - } - else if (line[i] == ')') { - end = i+1; - valid = true; - break; - } - } - if (valid) { - color_args = line.substr(begin, end-begin); - String stripped = color_args.replace(" ", "").replace("(", "").replace(")", ""); - Vector<float> color = stripped.split_floats(","); - if (color.size() > 2) { - float alpha = color.size() > 3 ? color[3] : 1.0f; - color_picker->set_pick_color(Color(color[0], color[1], color[2], alpha)); - } - color_panel->set_pos(get_global_transform().xform(get_local_mouse_pos())); - Size2 ms = Size2(300, color_picker->get_combined_minimum_size().height+10); - color_panel->set_size(ms); - } else { - have_color = false; - } - } - _make_context_menu(have_selection, have_color); - } - } -} - -void ScriptTextEditor::_color_changed(const Color& p_color) { - String new_args; - if (p_color.a == 1.0f) { - new_args = String("("+rtos(p_color.r)+", "+rtos(p_color.g)+", "+rtos(p_color.b)+")"); - } else { - new_args = String("("+rtos(p_color.r)+", "+rtos(p_color.g)+", "+rtos(p_color.b)+", "+rtos(p_color.a)+")"); - } - - String line = code_editor->get_text_edit()->get_line(color_line); - String new_line = line.replace(color_args, new_args); - color_args = new_args; - code_editor->get_text_edit()->set_line(color_line, new_line); -} - -void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color) { - - context_menu->clear(); - if (p_selection) { - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); - } - - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); - context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); - - if (p_selection) { - context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); - } - if (p_color) { - context_menu->add_separator(); - context_menu->add_item(TTR("Pick Color"), EDIT_PICK_COLOR); - } - context_menu->set_pos(get_global_transform().xform(get_local_mouse_pos())); - context_menu->set_size(Vector2(1, 1)); - context_menu->popup(); -} - -ScriptTextEditor::ScriptTextEditor() { - - code_editor = memnew( CodeTextEditor ); - add_child(code_editor); - code_editor->set_area_as_parent_rect(); - code_editor->connect("validate_script",this,"_validate_script"); - code_editor->connect("load_theme_settings",this,"_load_theme_settings"); - code_editor->set_code_complete_func(_code_complete_scripts,this); - code_editor->get_text_edit()->connect("breakpoint_toggled", this, "_breakpoint_toggled"); - code_editor->get_text_edit()->connect("symbol_lookup", this, "_lookup_symbol"); - - update_settings(); - - code_editor->get_text_edit()->set_callhint_settings( - EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line"), - EditorSettings::get_singleton()->get("text_editor/completion/callhint_tooltip_offset")); - - code_editor->get_text_edit()->set_select_identifiers_on_hover(true); - code_editor->get_text_edit()->set_context_menu_enabled(false); - code_editor->get_text_edit()->connect("gui_input", this, "_text_edit_gui_input"); - - context_menu = memnew(PopupMenu); - add_child(context_menu); - context_menu->connect("id_pressed", this, "_edit_option"); - - color_panel = memnew(PopupPanel); - add_child(color_panel); - color_picker = memnew(ColorPicker); - color_panel->add_child(color_picker); - color_panel->set_child_rect(color_picker); //NOT - color_picker->connect("color_changed", this, "_color_changed"); - - edit_hb = memnew (HBoxContainer); - - edit_menu = memnew( MenuButton ); - edit_menu->set_text(TTR("Edit")); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); - edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); - edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); - edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN); - edit_menu->get_popup()->add_separator(); -#ifdef OSX_ENABLED - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE); -#else - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE); -#endif - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/auto_indent"), EDIT_AUTO_INDENT); - edit_menu->get_popup()->connect("id_pressed", this,"_edit_option"); - edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_breakpoint"), DEBUG_TOGGLE_BREAKPOINT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_breakpoints"), DEBUG_REMOVE_ALL_BREAKPOINTS); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_breakpoint"), DEBUG_GOTO_NEXT_BREAKPOINT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_breakpoint"), DEBUG_GOTO_PREV_BREAKPOINT); - - search_menu = memnew( MenuButton ); - edit_hb->add_child(search_menu); - search_menu->set_text(TTR("Search")); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_next"), SEARCH_FIND_NEXT); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE); - search_menu->get_popup()->add_separator(); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_function"), SEARCH_LOCATE_FUNCTION); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE); - search_menu->get_popup()->add_separator(); - search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/contextual_help"), HELP_CONTEXTUAL); - - search_menu->get_popup()->connect("id_pressed", this,"_edit_option"); - - edit_hb->add_child(edit_menu); - - quick_open = memnew( ScriptEditorQuickOpen ); - add_child(quick_open); - quick_open->connect("goto_line",this,"_goto_line"); - - goto_line_dialog = memnew(GotoLineDialog); - add_child(goto_line_dialog); - - - code_editor->get_text_edit()->set_drag_forwarding(this); -} - -static ScriptEditorBase * create_editor(const Ref<Script>& p_script) { - - if (p_script->has_source_code()) { - return memnew( ScriptTextEditor ); - } - - return NULL; -} - -void ScriptTextEditor::register_editor() { - - ED_SHORTCUT("script_text_editor/undo", TTR("Undo"), KEY_MASK_CMD|KEY_Z); - ED_SHORTCUT("script_text_editor/redo", TTR("Redo"), KEY_MASK_CMD|KEY_Y); - ED_SHORTCUT("script_text_editor/cut", TTR("Cut"), KEY_MASK_CMD|KEY_X); - ED_SHORTCUT("script_text_editor/copy", TTR("Copy"), KEY_MASK_CMD|KEY_C); - ED_SHORTCUT("script_text_editor/paste", TTR("Paste"), KEY_MASK_CMD|KEY_V); - ED_SHORTCUT("script_text_editor/select_all", TTR("Select All"), KEY_MASK_CMD|KEY_A); - ED_SHORTCUT("script_text_editor/move_up", TTR("Move Up"), KEY_MASK_ALT|KEY_UP); - ED_SHORTCUT("script_text_editor/move_down", TTR("Move Down"), KEY_MASK_ALT|KEY_DOWN); - - //leave these at zero, same can be accomplished with tab/shift-tab, including selection - //the next/previous in history shortcut in this case makes a lot more sene. - - ED_SHORTCUT("script_text_editor/indent_left", TTR("Indent Left"), 0); - ED_SHORTCUT("script_text_editor/indent_right", TTR("Indent Right"), 0); - ED_SHORTCUT("script_text_editor/toggle_comment", TTR("Toggle Comment"), KEY_MASK_CMD|KEY_K); - ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD|KEY_B); -#ifdef OSX_ENABLED - ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CTRL|KEY_SPACE); -#else - ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD|KEY_SPACE); -#endif - ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CTRL|KEY_MASK_ALT|KEY_T); - ED_SHORTCUT("script_text_editor/auto_indent", TTR("Auto Indent"), KEY_MASK_CMD|KEY_I); - - ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9); - ED_SHORTCUT("script_text_editor/remove_all_breakpoints", TTR("Remove All Breakpoints"), KEY_MASK_CTRL|KEY_MASK_SHIFT|KEY_F9); - ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Goto Next Breakpoint"), KEY_MASK_CTRL|KEY_PERIOD); - ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Goto Previous Breakpoint"), KEY_MASK_CTRL|KEY_COMMA); - - ED_SHORTCUT("script_text_editor/find", TTR("Find.."), KEY_MASK_CMD|KEY_F); - ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), KEY_F3); - ED_SHORTCUT("script_text_editor/find_previous", TTR("Find Previous"), KEY_MASK_SHIFT|KEY_F3); - ED_SHORTCUT("script_text_editor/replace", TTR("Replace.."), KEY_MASK_CMD|KEY_R); - - ED_SHORTCUT("script_text_editor/goto_function", TTR("Goto Function.."), KEY_MASK_SHIFT|KEY_MASK_CMD|KEY_F); - ED_SHORTCUT("script_text_editor/goto_line", TTR("Goto Line.."), KEY_MASK_CMD|KEY_L); - - ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_SHIFT|KEY_F1); - - ScriptEditor::register_create_script_editor_function(create_editor); -} diff --git a/tools/editor/plugins/shader_editor_plugin.cpp b/tools/editor/plugins/shader_editor_plugin.cpp deleted file mode 100644 index 56a8fccb9c..0000000000 --- a/tools/editor/plugins/shader_editor_plugin.cpp +++ /dev/null @@ -1,584 +0,0 @@ -/*************************************************************************/ -/* shader_editor_plugin.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 "shader_editor_plugin.h" - -#include "tools/editor/editor_settings.h" -#include "spatial_editor_plugin.h" -#include "scene/resources/shader_graph.h" -#include "io/resource_loader.h" -#include "io/resource_saver.h" -#include "os/keyboard.h" -#include "tools/editor/editor_node.h" -#include "tools/editor/property_editor.h" -#include "os/os.h" -#include "servers/visual/shader_types.h" - -/*** SETTINGS EDITOR ****/ - - - - -/*** SCRIPT EDITOR ****/ - - -Ref<Shader> ShaderTextEditor::get_edited_shader() const { - - return shader; -} -void ShaderTextEditor::set_edited_shader(const Ref<Shader>& p_shader) { - - shader=p_shader; - - - _load_theme_settings(); - - get_text_edit()->set_text(p_shader->get_code()); - - _line_col_changed(); - - -} - - -void ShaderTextEditor::_load_theme_settings() { - - get_text_edit()->clear_colors(); - - /* keyword color */ - - get_text_edit()->add_color_override("background_color", EDITOR_DEF("text_editor/highlighting/background_color",Color(0,0,0,0))); - get_text_edit()->add_color_override("completion_background_color", EDITOR_DEF("text_editor/highlighting/completion_background_color", Color(0,0,0,0))); - get_text_edit()->add_color_override("completion_selected_color", EDITOR_DEF("text_editor/highlighting/completion_selected_color", Color::html("434244"))); - get_text_edit()->add_color_override("completion_existing_color", EDITOR_DEF("text_editor/highlighting/completion_existing_color", Color::html("21dfdfdf"))); - get_text_edit()->add_color_override("completion_scroll_color", EDITOR_DEF("text_editor/highlighting/completion_scroll_color", Color::html("ffffff"))); - get_text_edit()->add_color_override("completion_font_color", EDITOR_DEF("text_editor/highlighting/completion_font_color", Color::html("aaaaaa"))); - get_text_edit()->add_color_override("font_color",EDITOR_DEF("text_editor/highlighting/text_color",Color(0,0,0))); - get_text_edit()->add_color_override("line_number_color",EDITOR_DEF("text_editor/highlighting/line_number_color",Color(0,0,0))); - get_text_edit()->add_color_override("caret_color",EDITOR_DEF("text_editor/highlighting/caret_color",Color(0,0,0))); - get_text_edit()->add_color_override("caret_background_color",EDITOR_DEF("text_editor/highlighting/caret_background_color",Color(0,0,0))); - get_text_edit()->add_color_override("font_selected_color",EDITOR_DEF("text_editor/highlighting/text_selected_color",Color(1,1,1))); - get_text_edit()->add_color_override("selection_color",EDITOR_DEF("text_editor/highlighting/selection_color",Color(0.2,0.2,1))); - get_text_edit()->add_color_override("brace_mismatch_color",EDITOR_DEF("text_editor/highlighting/brace_mismatch_color",Color(1,0.2,0.2))); - get_text_edit()->add_color_override("current_line_color",EDITOR_DEF("text_editor/highlighting/current_line_color",Color(0.3,0.5,0.8,0.15))); - get_text_edit()->add_color_override("word_highlighted_color",EDITOR_DEF("text_editor/highlighting/word_highlighted_color",Color(0.8,0.9,0.9,0.15))); - get_text_edit()->add_color_override("number_color",EDITOR_DEF("text_editor/highlighting/number_color",Color(0.9,0.6,0.0,2))); - get_text_edit()->add_color_override("function_color",EDITOR_DEF("text_editor/highlighting/function_color",Color(0.4,0.6,0.8))); - get_text_edit()->add_color_override("member_variable_color",EDITOR_DEF("text_editor/highlighting/member_variable_color",Color(0.9,0.3,0.3))); - get_text_edit()->add_color_override("mark_color", EDITOR_DEF("text_editor/highlighting/mark_color", Color(1.0,0.4,0.4,0.4))); - get_text_edit()->add_color_override("breakpoint_color", EDITOR_DEF("text_editor/highlighting/breakpoint_color", Color(0.8,0.8,0.4,0.2))); - get_text_edit()->add_color_override("search_result_color",EDITOR_DEF("text_editor/highlighting/search_result_color",Color(0.05,0.25,0.05,1))); - get_text_edit()->add_color_override("search_result_border_color",EDITOR_DEF("text_editor/highlighting/search_result_border_color",Color(0.1,0.45,0.1,1))); - get_text_edit()->add_color_override("symbol_color",EDITOR_DEF("text_editor/highlighting/symbol_color",Color::hex(0x005291ff))); - - Color keyword_color= EDITOR_DEF("text_editor/highlighting/keyword_color",Color(0.5,0.0,0.2)); - - - List<String> keywords; - ShaderLanguage::get_keyword_list(&keywords); - - if (shader.is_valid()) { - - - for(const Map< StringName, Map<StringName,ShaderLanguage::DataType> >::Element *E=ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())).front();E;E=E->next()) { - - for (const Map<StringName,ShaderLanguage::DataType>::Element *F=E->get().front();F;F=F->next()) { - keywords.push_back(F->key()); - } - - } - - for(const Set<String>::Element *E =ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())).front();E;E=E->next()) { - - keywords.push_back(E->get()); - - } - } - - - for(List<String>::Element *E=keywords.front();E;E=E->next()) { - - get_text_edit()->add_keyword_color(E->get(),keyword_color); - } - - //colorize core types - //Color basetype_color= EDITOR_DEF("text_editor/base_type_color",Color(0.3,0.3,0.0)); - - - //colorize comments - Color comment_color = EDITOR_DEF("text_editor/highlighting/comment_color",Color::hex(0x797e7eff)); - - get_text_edit()->add_color_region("/*","*/",comment_color,false); - get_text_edit()->add_color_region("//","",comment_color,false); - - /*//colorize strings - Color string_color = EDITOR_DEF("text_editor/string_color",Color::hex(0x6b6f00ff)); - - List<String> strings; - shader->get_shader_mode()->get_string_delimiters(&strings); - - for (List<String>::Element *E=strings.front();E;E=E->next()) { - - String string = E->get(); - String beg = string.get_slice(" ",0); - String end = string.get_slice_count(" ")>1?string.get_slice(" ",1):String(); - get_text_edit()->add_color_region(beg,end,string_color,end==""); - }*/ -} - -void ShaderTextEditor::_code_complete_script(const String& p_code, List<String>* r_options) { - - print_line("code complete"); - - ShaderLanguage sl; - String calltip; - - Error err = sl.complete(p_code,ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())),ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())),r_options,calltip); - - if (calltip!="") { - get_text_edit()->set_code_hint(calltip); - } -} - -void ShaderTextEditor::_validate_script() { - - String code=get_text_edit()->get_text(); - //List<StringName> params; - //shader->get_param_list(¶ms); - - ShaderLanguage sl; - - Error err = sl.compile(code,ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())),ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode()))); - - if (err!=OK) { - String error_text="error("+itos(sl.get_error_line())+"): "+sl.get_error_text(); - set_error(error_text); - get_text_edit()->set_line_as_marked(sl.get_error_line(),true); - - } else { - for(int i=0;i<get_text_edit()->get_line_count();i++) - get_text_edit()->set_line_as_marked(i,false); - set_error(""); - } - - emit_signal("script_changed"); -} - -void ShaderTextEditor::_bind_methods() { - - - //ADD_SIGNAL( MethodInfo("script_changed") ); - -} - -ShaderTextEditor::ShaderTextEditor() { - - -} - -/*** SCRIPT EDITOR ******/ - - - -void ShaderEditor::_menu_option(int p_option) { - - - ShaderTextEditor *current = shader_editor; - - switch(p_option) { - case EDIT_UNDO: { - - - current->get_text_edit()->undo(); - } break; - case EDIT_REDO: { - current->get_text_edit()->redo(); - - } break; - case EDIT_CUT: { - - current->get_text_edit()->cut(); - } break; - case EDIT_COPY: { - current->get_text_edit()->copy(); - - } break; - case EDIT_PASTE: { - current->get_text_edit()->paste(); - - } break; - case EDIT_SELECT_ALL: { - - current->get_text_edit()->select_all(); - - } break; - case SEARCH_FIND: { - - current->get_find_replace_bar()->popup_search(); - } break; - case SEARCH_FIND_NEXT: { - - current->get_find_replace_bar()->search_next(); - } break; - case SEARCH_FIND_PREV: { - - current->get_find_replace_bar()->search_prev(); - } break; - case SEARCH_REPLACE: { - - current->get_find_replace_bar()->popup_replace(); - } break; - //case SEARCH_LOCATE_SYMBOL: { - - //} break; - case SEARCH_GOTO_LINE: { - - goto_line_dialog->popup_find_line(current->get_text_edit()); - } break; - - } -} - - -void ShaderEditor::_notification(int p_what) { - - if (p_what==NOTIFICATION_ENTER_TREE) { - - - } - if (p_what==NOTIFICATION_DRAW) { - - RID ci = get_canvas_item(); - Ref<StyleBox> style = get_stylebox("panel","Panel"); - style->draw( ci, Rect2( Point2(), get_size() ) ); - - } - -} - - - -Dictionary ShaderEditor::get_state() const { -#if 0 - apply_shaders(); - - Dictionary state; - - Array paths; - int open=-1; - - for(int i=0;i<tab_container->get_child_count();i++) { - - ShaderTextEditor *ste = tab_container->get_child(i)->cast_to<ShaderTextEditor>(); - if (!ste) - continue; - - - Ref<Shader> shader = ste->get_edited_shader(); - if (shader->get_path()!="" && shader->get_path().find("local://")==-1 && shader->get_path().find("::")==-1) { - - paths.push_back(shader->get_path()); - } else { - - - const Node *owner = _find_node_with_shader(get_root_node(),shader.get_ref_ptr()); - if (owner) - paths.push_back(owner->get_path()); - - } - - if (i==tab_container->get_current_tab()) - open=i; - } - - if (paths.size()) - state["sources"]=paths; - if (open!=-1) - state["current"]=open; - - - return state; -#endif - return Dictionary(); -} -void ShaderEditor::set_state(const Dictionary& p_state) { -#if 0 - print_line("setting state.."); - if (!p_state.has("sources")) - return; //bleh - - Array sources = p_state["sources"]; - for(int i=0;i<sources.size();i++) { - - Variant source=sources[i]; - - Ref<Shader> shader; - - if (source.get_type()==Variant::NODE_PATH) { - - print_line("cain find owner at path "+String(source)); - Node *owner=get_root_node()->get_node(source); - if (!owner) - continue; - - shader = owner->get_shader(); - } else if (source.get_type()==Variant::STRING) { - - print_line("loading at path "+String(source)); - shader = ResourceLoader::load(source,"Shader"); - } - - print_line("found shader at "+String(source)+"? - "+itos(shader.is_null())); - if (shader.is_null()) //ah well.. - continue; - - get_scene()->get_root_node()->call("_resource_selected",shader); - } - - if (p_state.has("current")) - tab_container->set_current_tab(p_state["current"]); -#endif -} -void ShaderEditor::clear() { - -} - -void ShaderEditor::_params_changed() { - - - shader_editor->_validate_script(); -} - -void ShaderEditor::_editor_settings_changed() { - - shader_editor->get_text_edit()->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/completion/auto_brace_complete")); - shader_editor->get_text_edit()->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file")); - shader_editor->get_text_edit()->set_tab_size(EditorSettings::get_singleton()->get("text_editor/indent/tab_size")); - shader_editor->get_text_edit()->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/indent/draw_tabs")); - shader_editor->get_text_edit()->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_line_numbers")); - shader_editor->get_text_edit()->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/highlighting/syntax_highlighting")); - shader_editor->get_text_edit()->set_highlight_all_occurrences(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_all_occurrences")); - shader_editor->get_text_edit()->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink")); - shader_editor->get_text_edit()->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed")); - shader_editor->get_text_edit()->add_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/theme/line_spacing")); - shader_editor->get_text_edit()->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret")); -} - -void ShaderEditor::_bind_methods() { - - ClassDB::bind_method("_editor_settings_changed",&ShaderEditor::_editor_settings_changed); - - ClassDB::bind_method("_menu_option",&ShaderEditor::_menu_option); - ClassDB::bind_method("_params_changed",&ShaderEditor::_params_changed); - ClassDB::bind_method("apply_shaders",&ShaderEditor::apply_shaders); - //ClassDB::bind_method("_close_current_tab",&ShaderEditor::_close_current_tab); -} - -void ShaderEditor::ensure_select_current() { - -/* - if (tab_container->get_child_count() && tab_container->get_current_tab()>=0) { - - ShaderTextEditor *ste = tab_container->get_child(tab_container->get_current_tab())->cast_to<ShaderTextEditor>(); - if (!ste) - return; - Ref<Shader> shader = ste->get_edited_shader(); - get_scene()->get_root_node()->call("_resource_selected",shader); - }*/ -} - -void ShaderEditor::edit(const Ref<Shader>& p_shader) { - - if (p_shader.is_null()) - return; - - - shader=p_shader; - - shader_editor->set_edited_shader(p_shader); - - //vertex_editor->set_edited_shader(shader,ShaderLanguage::SHADER_MATERIAL_VERTEX); - // see if already has it - - -} - -void ShaderEditor::save_external_data() { - - if (shader.is_null()) - return; - apply_shaders(); - - if (shader->get_path()!="" && shader->get_path().find("local://")==-1 &&shader->get_path().find("::")==-1) { - //external shader, save it - ResourceSaver::save(shader->get_path(),shader); - } -} - -void ShaderEditor::apply_shaders() { - - - if (shader.is_valid()) { - shader->set_code(shader_editor->get_text_edit()->get_text()); - shader->set_edited(true); - } -} - - -ShaderEditor::ShaderEditor() { - - - HBoxContainer *hbc = memnew( HBoxContainer); - - add_child(hbc); - - edit_menu = memnew( MenuButton ); - hbc->add_child(edit_menu); - edit_menu->set_pos(Point2(5,-1)); - edit_menu->set_text(TTR("Edit")); - edit_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/undo", TTR("Undo"), KEY_MASK_CMD|KEY_Z), EDIT_UNDO); - edit_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/redo", TTR("Redo"), KEY_MASK_CMD|KEY_Y), EDIT_REDO); - edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/cut", TTR("Cut"), KEY_MASK_CMD|KEY_X), EDIT_CUT); - edit_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/copy", TTR("Copy"), KEY_MASK_CMD|KEY_C), EDIT_COPY); - edit_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/paste", TTR("Paste"), KEY_MASK_CMD|KEY_V), EDIT_PASTE); - edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/select_all", TTR("Select All"), KEY_MASK_CMD|KEY_A), EDIT_SELECT_ALL); - edit_menu->get_popup()->connect("id_pressed", this,"_menu_option"); - - - search_menu = memnew( MenuButton ); - hbc->add_child(search_menu); - search_menu->set_pos(Point2(38,-1)); - search_menu->set_text(TTR("Search")); - search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find", TTR("Find.."), KEY_MASK_CMD|KEY_F), SEARCH_FIND); - search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_next", TTR("Find Next"), KEY_F3), SEARCH_FIND_NEXT); - search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_previous", TTR("Find Previous"), KEY_MASK_SHIFT|KEY_F3), SEARCH_FIND_PREV); - search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/replace", TTR("Replace.."), KEY_MASK_CMD|KEY_R), SEARCH_REPLACE); - search_menu->get_popup()->add_separator(); - //search_menu->get_popup()->add_item("Locate Symbol..",SEARCH_LOCATE_SYMBOL,KEY_MASK_CMD|KEY_K); - search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/goto_line", TTR("Goto Line.."), KEY_MASK_CMD|KEY_L), SEARCH_GOTO_LINE); - search_menu->get_popup()->connect("id_pressed", this,"_menu_option"); - - - goto_line_dialog = memnew(GotoLineDialog); - add_child(goto_line_dialog); - - shader_editor = memnew( ShaderTextEditor ); - add_child(shader_editor); - shader_editor->set_v_size_flags(SIZE_EXPAND_FILL); - - - shader_editor->connect("script_changed", this,"apply_shaders"); - EditorSettings::get_singleton()->connect("settings_changed",this,"_editor_settings_changed"); - - _editor_settings_changed(); -} - - -void ShaderEditorPlugin::edit(Object *p_object) { - - Shader* s = p_object->cast_to<Shader>(); - shader_editor->edit(s); - -} - -bool ShaderEditorPlugin::handles(Object *p_object) const { - - bool handles = true; - Shader *shader=p_object->cast_to<Shader>(); - /* - if (!shader || shader->cast_to<ShaderGraph>()) // Dont handle ShaderGraph's - handles = false; - */ - - return shader!=NULL; -} - -void ShaderEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - button->show(); - editor->make_bottom_panel_item_visible(shader_editor); - - } else { - - button->hide(); - if (shader_editor->is_visible_in_tree()) - editor->hide_bottom_panel(); - shader_editor->apply_shaders(); - - } - -} - -void ShaderEditorPlugin::selected_notify() { - - shader_editor->ensure_select_current(); -} - -Dictionary ShaderEditorPlugin::get_state() const { - - return shader_editor->get_state(); -} - -void ShaderEditorPlugin::set_state(const Dictionary& p_state) { - - shader_editor->set_state(p_state); -} -void ShaderEditorPlugin::clear() { - - shader_editor->clear(); -} - -void ShaderEditorPlugin::save_external_data() { - - shader_editor->save_external_data(); -} - -void ShaderEditorPlugin::apply_changes() { - - shader_editor->apply_shaders(); -} - -ShaderEditorPlugin::ShaderEditorPlugin(EditorNode *p_node) { - - - editor=p_node; - shader_editor = memnew( ShaderEditor ); - - shader_editor->set_custom_minimum_size(Size2(0,300)); - button=editor->add_bottom_panel_item("Shader",shader_editor); - -} - - -ShaderEditorPlugin::~ShaderEditorPlugin() { -} - - diff --git a/tools/editor/plugins/shader_editor_plugin.h b/tools/editor/plugins/shader_editor_plugin.h deleted file mode 100644 index e94b4d9c25..0000000000 --- a/tools/editor/plugins/shader_editor_plugin.h +++ /dev/null @@ -1,156 +0,0 @@ -/*************************************************************************/ -/* shader_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef SHADER_EDITOR_PLUGIN_H -#define SHADER_EDITOR_PLUGIN_H - -#include "tools/editor/code_editor.h" -#include "tools/editor/editor_plugin.h" -#include "scene/gui/tab_container.h" -#include "scene/gui/text_edit.h" -#include "scene/gui/menu_button.h" -#include "scene/main/timer.h" -#include "scene/resources/shader.h" -#include "servers/visual/shader_language.h" - -class ShaderTextEditor : public CodeTextEditor { - - GDCLASS( ShaderTextEditor, CodeTextEditor ); - - Ref<Shader> shader; - -protected: - - static void _bind_methods(); - virtual void _load_theme_settings(); - - virtual void _code_complete_script(const String& p_code, List<String>* r_options); - -public: - - virtual void _validate_script(); - - - Ref<Shader> get_edited_shader() const; - void set_edited_shader(const Ref<Shader>& p_shader); - ShaderTextEditor(); - -}; - - -class ShaderEditor : public VBoxContainer { - - GDCLASS(ShaderEditor, VBoxContainer ); - - enum { - - EDIT_UNDO, - EDIT_REDO, - EDIT_CUT, - EDIT_COPY, - EDIT_PASTE, - EDIT_SELECT_ALL, - SEARCH_FIND, - SEARCH_FIND_NEXT, - SEARCH_FIND_PREV, - SEARCH_REPLACE, - //SEARCH_LOCATE_SYMBOL, - SEARCH_GOTO_LINE, - - }; - - MenuButton *edit_menu; - MenuButton *search_menu; - MenuButton *settings_menu; - uint64_t idle; - - GotoLineDialog *goto_line_dialog; - ConfirmationDialog *erase_tab_confirm; - - - ShaderTextEditor *shader_editor; - - - void _menu_option(int p_optin); - void _params_changed(); - mutable Ref<Shader> shader; - - - void _editor_settings_changed(); - -protected: - void _notification(int p_what); - static void _bind_methods(); -public: - - void apply_shaders(); - - void ensure_select_current(); - void edit(const Ref<Shader>& p_shader); - - Dictionary get_state() const; - void set_state(const Dictionary& p_state); - void clear(); - - virtual Size2 get_minimum_size() const { return Size2(0,200); } - void save_external_data(); - - ShaderEditor(); -}; - -class ShaderEditorPlugin : public EditorPlugin { - - GDCLASS( ShaderEditorPlugin, EditorPlugin ); - - bool _2d; - ShaderEditor *shader_editor; - EditorNode *editor; - Button *button; - -public: - - virtual String get_name() const { return "Shader"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - virtual void selected_notify(); - - Dictionary get_state() const; - virtual void set_state(const Dictionary& p_state); - virtual void clear(); - - virtual void save_external_data(); - virtual void apply_changes(); - - ShaderEditorPlugin(EditorNode *p_node); - ~ShaderEditorPlugin(); - -}; - -#endif diff --git a/tools/editor/plugins/shader_graph_editor_plugin.h b/tools/editor/plugins/shader_graph_editor_plugin.h deleted file mode 100644 index 477a45bd1f..0000000000 --- a/tools/editor/plugins/shader_graph_editor_plugin.h +++ /dev/null @@ -1,242 +0,0 @@ -/*************************************************************************/ -/* shader_graph_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef SHADER_GRAPH_EDITOR_PLUGIN_H -#define SHADER_GRAPH_EDITOR_PLUGIN_H - - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/resources/shader.h" -#include "scene/gui/tree.h" -#include "scene/gui/button.h" -#include "scene/gui/graph_edit.h" -#include "scene/gui/popup.h" -#include "tools/editor/property_editor.h" -#include "scene/resources/shader_graph.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -#if 0 -class GraphColorRampEdit : public Control { - - GDCLASS(GraphColorRampEdit,Control); - - - struct Point { - - float offset; - Color color; - bool operator<(const Point& p_ponit) const { - return offset<p_ponit.offset; - } - }; - - PopupPanel *popup; - ColorPicker *picker; - - - bool grabbing; - int grabbed; - float grabbed_at; - Vector<Point> points; - - void _color_changed(const Color& p_color); - -protected: - void _gui_input(const InputEvent& p_event); - void _notification(int p_what); - static void _bind_methods(); -public: - - void set_ramp(const Vector<float>& p_offsets,const Vector<Color>& p_colors); - Vector<float> get_offsets() const; - Vector<Color> get_colors() const; - virtual Size2 get_minimum_size() const; - GraphColorRampEdit(); -}; - - -class GraphCurveMapEdit : public Control { - - GDCLASS(GraphCurveMapEdit,Control); - - - struct Point { - - float offset; - float height; - bool operator<(const Point& p_ponit) const { - return offset<p_ponit.offset; - } - }; - - - bool grabbing; - int grabbed; - Vector<Point> points; - - void _plot_curve(const Vector2& p_a,const Vector2& p_b,const Vector2& p_c,const Vector2& p_d); -protected: - void _gui_input(const InputEvent& p_event); - void _notification(int p_what); - static void _bind_methods(); -public: - - void set_points(const Vector<Vector2>& p_points); - Vector<Vector2> get_points() const; - virtual Size2 get_minimum_size() const; - GraphCurveMapEdit(); -}; - -class ShaderGraphView : public Control { - - GDCLASS(ShaderGraphView,Control); - - - - CustomPropertyEditor *ped_popup; - bool block_update; - - Label *status; - GraphEdit *graph_edit; - Ref<ShaderGraph> graph; - int edited_id; - int edited_def; - - ShaderGraph::ShaderType type; - - void _update_graph(); - void _create_node(int p_id); - - - ToolButton *make_label(String text, Variant::Type v_type = Variant::NIL); - ToolButton *make_editor(String text, GraphNode* gn, int p_id, int param, Variant::Type type, String p_hint=""); - - void _connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); - void _disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); - - void _node_removed(int p_id); - void _begin_node_move(); - void _node_moved(const Vector2& p_from, const Vector2& p_to,int p_id); - void _end_node_move(); - void _move_node(int p_id,const Vector2& p_to); - void _duplicate_nodes_request(); - void _duplicate_nodes(const Array &p_nodes); - void _delete_nodes_request(); - - - void _default_changed(int p_id, Node* p_button, int p_param, int v_type, String p_hint); - - void _scalar_const_changed(double p_value,int p_id); - void _vec_const_changed(double p_value, int p_id, Array p_arr); - void _rgb_const_changed(const Color& p_color, int p_id); - void _xform_const_changed(int p_id,Node* p_button); - void _scalar_op_changed(int p_op, int p_id); - void _vec_op_changed(int p_op, int p_id); - void _vec_scalar_op_changed(int p_op, int p_id); - void _rgb_op_changed(int p_op, int p_id); - void _xform_inv_rev_changed(bool p_enabled, int p_id); - void _scalar_func_changed(int p_func, int p_id); - void _vec_func_changed(int p_func, int p_id); - void _scalar_input_changed(double p_value,int p_id); - void _vec_input_changed(double p_value, int p_id, Array p_arr); - void _xform_input_changed(int p_id,Node* p_button); - void _rgb_input_changed(const Color& p_color, int p_id); - void _tex_input_change(int p_id,Node* p_button); - void _cube_input_change(int p_id); - void _input_name_changed(const String& p_name,int p_id,Node* p_line_edit); - void _tex_edited(int p_id,Node* p_button); - void _cube_edited(int p_id,Node* p_button); - void _variant_edited(); - void _comment_edited(int p_id,Node* p_button); - void _color_ramp_changed(int p_id,Node* p_ramp); - void _curve_changed(int p_id,Node* p_curve); - void _sg_updated(); - Map<int,GraphNode*> node_map; - - Variant get_drag_data_fw(const Point2& p_point,Control* p_from); - bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; - void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); -protected: - void _notification(int p_what); - static void _bind_methods(); -public: - - void add_node(int p_type, const Vector2 &location); - GraphEdit *get_graph_edit() { return graph_edit; } - void set_graph(Ref<ShaderGraph> p_graph); - - ShaderGraphView(ShaderGraph::ShaderType p_type=ShaderGraph::SHADER_TYPE_FRAGMENT); -}; - -class ShaderGraphEditor : public VBoxContainer { - - GDCLASS(ShaderGraphEditor,VBoxContainer); - - PopupMenu *popup; - TabContainer *tabs; - ShaderGraphView *graph_edits[ShaderGraph::SHADER_TYPE_MAX]; - static const char* node_names[ShaderGraph::NODE_TYPE_MAX]; - Vector2 next_location; - - bool _2d; - void _add_node(int p_type); - void _popup_requested(const Vector2 &p_position); -protected: - void _notification(int p_what); - static void _bind_methods(); -public: - - void edit(Ref<ShaderGraph> p_shader); - ShaderGraphEditor(bool p_2d); -}; - -class ShaderGraphEditorPlugin : public EditorPlugin { - - GDCLASS( ShaderGraphEditorPlugin, EditorPlugin ); - - bool _2d; - ShaderGraphEditor *shader_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "ShaderGraph"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - ShaderGraphEditorPlugin(EditorNode *p_node,bool p_2d); - ~ShaderGraphEditorPlugin(); - -}; -#endif -#endif diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp deleted file mode 100644 index ef971034cd..0000000000 --- a/tools/editor/plugins/spatial_editor_plugin.cpp +++ /dev/null @@ -1,4131 +0,0 @@ -/*************************************************************************/ -/* spatial_editor_plugin.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 "spatial_editor_plugin.h" - -#include "print_string.h" -#include "os/keyboard.h" -#include "scene/3d/visual_instance.h" -#include "scene/3d/camera.h" -#include "camera_matrix.h" -#include "sort.h" -#include "tools/editor/editor_node.h" -#include "tools/editor/editor_settings.h" -#include "scene/resources/surface_tool.h" -#include "tools/editor/spatial_editor_gizmos.h" -#include "global_config.h" -#include "tools/editor/plugins/animation_player_editor_plugin.h" -#include "tools/editor/animation_editor.h" - -#define DISTANCE_DEFAULT 4 - - -#define GIZMO_ARROW_SIZE 0.3 -#define GIZMO_RING_HALF_WIDTH 0.1 -//#define GIZMO_SCALE_DEFAULT 0.28 -#define GIZMO_SCALE_DEFAULT 0.15 - - -void SpatialEditorViewport::_update_camera() { - if (orthogonal) { - //camera->set_orthogonal(size.width*cursor.distance,get_znear(),get_zfar()); - camera->set_orthogonal(2 * cursor.distance, 0.1, 8192); - } - else - camera->set_perspective(get_fov(), get_znear(), get_zfar()); - - Transform camera_transform; - camera_transform.translate(cursor.pos); - camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot); - camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot); - - if (orthogonal) - camera_transform.translate(0, 0, 4096); - else - camera_transform.translate(0, 0, cursor.distance); - - if (camera->get_global_transform() != camera_transform) { - camera->set_global_transform(camera_transform); - update_transform_gizmo_view(); - } -} - -String SpatialEditorGizmo::get_handle_name(int p_idx) const { - - if (get_script_instance() && get_script_instance()->has_method("get_handle_name")) - return get_script_instance()->call("get_handle_name", p_idx); - - return ""; -} - -Variant SpatialEditorGizmo::get_handle_value(int p_idx) const{ - - if (get_script_instance() && get_script_instance()->has_method("get_handle_value")) - return get_script_instance()->call("get_handle_value", p_idx); - - return Variant(); -} - -void SpatialEditorGizmo::set_handle(int p_idx,Camera *p_camera, const Point2& p_point) { - - if (get_script_instance() && get_script_instance()->has_method("set_handle")) - get_script_instance()->call("set_handle", p_idx, p_camera, p_point); -} - -void SpatialEditorGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){ - - if (get_script_instance() && get_script_instance()->has_method("commit_handle")) - get_script_instance()->call("commit_handle", p_idx, p_restore, p_cancel); -} - -bool SpatialEditorGizmo::intersect_frustum(const Camera *p_camera,const Vector<Plane> &p_frustum) { - - return false; -} - -bool SpatialEditorGizmo::intersect_ray(const Camera *p_camera, const Point2 &p_point, Vector3& r_pos, Vector3& r_normal,int *r_gizmo_handle,bool p_sec_first) { - - return false; -} - -SpatialEditorGizmo::SpatialEditorGizmo(){ - - selected=false; -} - - - -int SpatialEditorViewport::get_selected_count() const { - - - Map<Node*,Object*> &selection = editor_selection->get_selection(); - - int count=0; - - for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { - - Spatial *sp = E->key()->cast_to<Spatial>(); - if (!sp) - continue; - - SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); - if (!se) - continue; - - count++; - } - - return count; -} - - - -float SpatialEditorViewport::get_znear() const { - - float val = spatial_editor->get_znear(); - if (val<0.001) - val=0.001; - return val; -} -float SpatialEditorViewport::get_zfar() const{ - - float val = spatial_editor->get_zfar(); - if (val<0.001) - val=0.001; - return val; - -} -float SpatialEditorViewport::get_fov() const{ - - float val = spatial_editor->get_fov(); - if (val<0.001) - val=0.001; - if (val>89) - val=89; - return val; - -} - - - -Transform SpatialEditorViewport::_get_camera_transform() const { - - return camera->get_global_transform(); -} - -Vector3 SpatialEditorViewport::_get_camera_pos() const { - - return _get_camera_transform().origin; -} - -Point2 SpatialEditorViewport::_point_to_screen(const Vector3& p_point) { - - return camera->unproject_position(p_point); - -} - -Vector3 SpatialEditorViewport::_get_ray_pos(const Vector2& p_pos) const { - - return camera->project_ray_origin(p_pos); -} - - -Vector3 SpatialEditorViewport::_get_camera_normal() const { - - return -_get_camera_transform().basis.get_axis(2); -} - -Vector3 SpatialEditorViewport::_get_ray(const Vector2& p_pos) { - - - return camera->project_ray_normal(p_pos); - - -} -/* -void SpatialEditorViewport::_clear_id(Spatial *p_node) { - - - editor_selection->remove_node(p_node); - - -} -*/ -void SpatialEditorViewport::_clear_selected() { - - editor_selection->clear(); -} - - - -void SpatialEditorViewport::_select_clicked(bool p_append,bool p_single) { - - if (!clicked) - return; - - Object *obj = ObjectDB::get_instance(clicked); - if (!obj) - return; - - - Spatial *sp = obj->cast_to<Spatial>(); - if (!sp) - return; - - _select(sp, clicked_wants_append,true); -} - - - -void SpatialEditorViewport::_select(Spatial *p_node, bool p_append,bool p_single) { - - - if (!p_append) { - - // should not modify the selection.. - - editor_selection->clear(); - editor_selection->add_node(p_node); - - } else { - - if (editor_selection->is_selected(p_node) && p_single) { - //erase - editor_selection->remove_node(p_node); - } else { - - editor_selection->add_node(p_node); - } - - } - -} - -ObjectID SpatialEditorViewport::_select_ray(const Point2& p_pos, bool p_append,bool &r_includes_current,int *r_gizmo_handle,bool p_alt_select) { - - if (r_gizmo_handle) - *r_gizmo_handle=-1; - - Vector3 ray=_get_ray(p_pos); - Vector3 pos=_get_ray_pos(p_pos); - - Vector<ObjectID> instances=VisualServer::get_singleton()->instances_cull_ray(pos,ray,get_tree()->get_root()->get_world()->get_scenario() ); - Set<Ref<SpatialEditorGizmo> > found_gizmos; - - ObjectID closest=0; - Spatial *item=NULL; - float closest_dist=1e20; - int selected_handle=-1; - - for (int i=0;i<instances.size();i++) { - - Object *obj=ObjectDB::get_instance(instances[i]); - if (!obj) - continue; - - Spatial *spat=obj->cast_to<Spatial>(); - - if (!spat) - continue; - - Ref<SpatialEditorGizmo> seg = spat->get_gizmo(); - - if (!seg.is_valid()) - continue; - - if (found_gizmos.has(seg)) - continue; - - found_gizmos.insert(seg); - Vector3 point; - Vector3 normal; - - int handle=-1; - bool inters = seg->intersect_ray(camera,p_pos,point,normal,NULL,p_alt_select); - - if (!inters) - continue; - - float dist = pos.distance_to(point); - - if (dist<0) - continue; - - if (dist < closest_dist) { - closest=instances[i]; - closest_dist=dist; - selected_handle=handle; - item=spat; - } - - // if (editor_selection->is_selected(spat)) - // r_includes_current=true; - - } - - - if (!item) - return 0; - - if (!editor_selection->is_selected(item) || (r_gizmo_handle && selected_handle>=0)) { - - if (r_gizmo_handle) - *r_gizmo_handle=selected_handle; - - } - - return closest; - -} - -void SpatialEditorViewport::_find_items_at_pos(const Point2& p_pos,bool &r_includes_current,Vector<_RayResult> &results,bool p_alt_select) { - - Vector3 ray=_get_ray(p_pos); - Vector3 pos=_get_ray_pos(p_pos); - - Vector<ObjectID> instances=VisualServer::get_singleton()->instances_cull_ray(pos,ray,get_tree()->get_root()->get_world()->get_scenario() ); - Set<Ref<SpatialEditorGizmo> > found_gizmos; - - r_includes_current=false; - - for (int i=0;i<instances.size();i++) { - - Object *obj=ObjectDB::get_instance(instances[i]); - - if (!obj) - continue; - - Spatial *spat=obj->cast_to<Spatial>(); - - if (!spat) - continue; - - Ref<SpatialEditorGizmo> seg = spat->get_gizmo(); - - if (!seg.is_valid()) - continue; - - if (found_gizmos.has(seg)) - continue; - - found_gizmos.insert(seg); - Vector3 point; - Vector3 normal; - - int handle=-1; - bool inters = seg->intersect_ray(camera,p_pos,point,normal,NULL,p_alt_select); - - if (!inters) - continue; - - float dist = pos.distance_to(point); - - if (dist<0) - continue; - - - - if (editor_selection->is_selected(spat)) - r_includes_current=true; - - _RayResult res; - res.item=spat; - res.depth=dist; - res.handle=handle; - results.push_back(res); - } - - - if (results.empty()) - return; - - results.sort(); -} - - -Vector3 SpatialEditorViewport::_get_screen_to_space(const Vector3& p_pos) { - - - CameraMatrix cm; - cm.set_perspective(get_fov(),get_size().aspect(),get_znear(),get_zfar()); - float screen_w,screen_h; - cm.get_viewport_size(screen_w,screen_h); - - Transform camera_transform; - camera_transform.translate( cursor.pos ); - camera_transform.basis.rotate(Vector3(1,0,0),-cursor.x_rot); - camera_transform.basis.rotate(Vector3(0,1,0),-cursor.y_rot); - camera_transform.translate(0,0,cursor.distance); - - return camera_transform.xform(Vector3( ((p_pos.x/get_size().width)*2.0-1.0)*screen_w, ((1.0-(p_pos.y/get_size().height))*2.0-1.0)*screen_h,-get_znear())); - -} - - -void SpatialEditorViewport::_select_region() { - - if (cursor.region_begin==cursor.region_end) - return; //nothing really - - Vector3 box[4]={ - Vector3( - MIN( cursor.region_begin.x, cursor.region_end.x), - MIN( cursor.region_begin.y, cursor.region_end.y), - 0 - ), - Vector3( - MAX( cursor.region_begin.x, cursor.region_end.x), - MIN( cursor.region_begin.y, cursor.region_end.y), - 0 - ), - Vector3( - MAX( cursor.region_begin.x, cursor.region_end.x), - MAX( cursor.region_begin.y, cursor.region_end.y), - 0 - ), - Vector3( - MIN( cursor.region_begin.x, cursor.region_end.x), - MAX( cursor.region_begin.y, cursor.region_end.y), - 0 - ) - }; - - Vector<Plane> frustum; - - Vector3 cam_pos=_get_camera_pos(); - Set<Ref<SpatialEditorGizmo> > found_gizmos; - - for(int i=0;i<4;i++) { - - Vector3 a=_get_screen_to_space(box[i]); - Vector3 b=_get_screen_to_space(box[(i+1)%4]); - frustum.push_back( Plane(a,b,cam_pos) ); - } - - Plane near( cam_pos, -_get_camera_normal() ); - near.d-=get_znear(); - - frustum.push_back( near ); - - Plane far=-near; - far.d+=500.0; - - frustum.push_back( far ); - - Vector<ObjectID> instances=VisualServer::get_singleton()->instances_cull_convex(frustum,get_tree()->get_root()->get_world()->get_scenario()); - - - for (int i=0;i<instances.size();i++) { - - Object *obj=ObjectDB::get_instance(instances[i]); - if (!obj) - continue; - Spatial *sp = obj->cast_to<Spatial>(); - if (!sp) - continue; - - Ref<SpatialEditorGizmo> seg = sp->get_gizmo(); - - if (!seg.is_valid()) - continue; - - if (found_gizmos.has(seg)) - continue; - - if (seg->intersect_frustum(camera,frustum)) - _select(sp,true,false); - } - -} - -void SpatialEditorViewport::_update_name() { - - String ortho = orthogonal?TTR("Orthogonal"):TTR("Perspective"); - - if (name!="") - view_menu->set_text("[ "+name+" "+ortho+" ]"); - else - view_menu->set_text("[ "+ortho+" ]"); -} - - -void SpatialEditorViewport::_compute_edit(const Point2& p_point) { - - _edit.click_ray=_get_ray( Vector2( p_point.x, p_point.y ) ); - _edit.click_ray_pos=_get_ray_pos( Vector2( p_point.x, p_point.y ) ); - _edit.plane=TRANSFORM_VIEW; - spatial_editor->update_transform_gizmo(); - _edit.center=spatial_editor->get_gizmo_transform().origin; - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - //Vector3 center; - //int nc=0; - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - Spatial *sp = E->get()->cast_to<Spatial>(); - if (!sp) - continue; - - SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); - if (!se) - continue; - - se->original=se->sp->get_global_transform(); - //center+=se->original.origin; - //nc++; - } - - /* - if (nc) - _edit.center=center/float(nc); - */ -} - -static int _get_key_modifier(const String& p_property) { - - switch(EditorSettings::get_singleton()->get(p_property).operator int()) { - - case 0: return 0; - case 1: return KEY_SHIFT; - case 2: return KEY_ALT; - case 3: return KEY_META; - case 4: return KEY_CONTROL; - } - return 0; -} - -bool SpatialEditorViewport::_gizmo_select(const Vector2& p_screenpos,bool p_hilite_only) { - - if (!spatial_editor->is_gizmo_visible()) - return false; - if (get_selected_count()==0) { - if (p_hilite_only) - spatial_editor->select_gizmo_hilight_axis(-1); - return false; - } - - - Vector3 ray_pos=_get_ray_pos( Vector2( p_screenpos.x, p_screenpos.y ) ); - Vector3 ray=_get_ray( Vector2( p_screenpos.x, p_screenpos.y ) ); - - Transform gt = spatial_editor->get_gizmo_transform(); - float gs=gizmo_scale; - - if (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_MOVE) { - - int col_axis=-1; - float col_d=1e20; - - for(int i=0;i<3;i++) { - - Vector3 grabber_pos = gt.origin+gt.basis.get_axis(i)*gs; - float grabber_radius = gs*GIZMO_ARROW_SIZE; - - Vector3 r; - if (Geometry::segment_intersects_sphere(ray_pos,ray_pos+ray*10000.0,grabber_pos,grabber_radius,&r)) { - float d = r.distance_to(ray_pos); - if (d<col_d) { - col_d=d; - col_axis=i; - } - } - } - - if (col_axis!=-1) { - - - if (p_hilite_only) { - - spatial_editor->select_gizmo_hilight_axis(col_axis); - - - } else { - //handle rotate - _edit.mode=TRANSFORM_TRANSLATE; - _compute_edit(Point2(p_screenpos.x,p_screenpos.y)); - _edit.plane=TransformPlane(TRANSFORM_X_AXIS+col_axis); - } - return true; - - - } - - } - - - if (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_ROTATE) { - - int col_axis=-1; - float col_d=1e20; - - for(int i=0;i<3;i++) { - - Plane plane(gt.origin,gt.basis.get_axis(i).normalized()); - Vector3 r; - if (!plane.intersects_ray(ray_pos,ray,&r)) - continue; - - float dist = r.distance_to(gt.origin); - - - - if (dist > gs*(1-GIZMO_RING_HALF_WIDTH) && dist < gs *(1+GIZMO_RING_HALF_WIDTH)) { - - float d = ray_pos.distance_to(r); - if (d<col_d) { - col_d=d; - col_axis=i; - } - } - } - - if (col_axis!=-1) { - - if (p_hilite_only) { - - spatial_editor->select_gizmo_hilight_axis(col_axis+3); - } else { - //handle rotate - _edit.mode=TRANSFORM_ROTATE; - _compute_edit(Point2(p_screenpos.x,p_screenpos.y)); - _edit.plane=TransformPlane(TRANSFORM_X_AXIS+col_axis); - } - return true; - } - } - - - if (p_hilite_only) - spatial_editor->select_gizmo_hilight_axis(-1); - - return false; - -} - - -void SpatialEditorViewport::_smouseenter() { - - if (!surface->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) - surface->grab_focus(); -} - -void SpatialEditorViewport::_list_select(InputEventMouseButton b) { - - _find_items_at_pos(Vector2( b.x, b.y ),clicked_includes_current,selection_results,b.mod.shift); - - Node *scene=editor->get_edited_scene(); - - for(int i=0;i<selection_results.size();i++) { - Spatial *item=selection_results[i].item; - if (item!=scene && item->get_owner()!=scene && !scene->is_editable_instance(item->get_owner())) { - //invalid result - selection_results.remove(i); - i--; - } - - } - - - clicked_wants_append=b.mod.shift; - - if (selection_results.size() == 1) { - - clicked=selection_results[0].item->get_instance_ID(); - selection_results.clear(); - - if (clicked) { - _select_clicked(clicked_wants_append,true); - clicked=0; - } - - } else if (!selection_results.empty()) { - - NodePath root_path = get_tree()->get_edited_scene_root()->get_path(); - StringName root_name = root_path.get_name(root_path.get_name_count()-1); - - for (int i = 0; i < selection_results.size(); i++) { - - Spatial *spat=selection_results[i].item; - - Ref<Texture> icon; - if (spat->has_meta("_editor_icon")) - icon=spat->get_meta("_editor_icon"); - else - icon=get_icon( has_icon(spat->get_class(),"EditorIcons")?spat->get_class():String("Object"),"EditorIcons"); - - String node_path="/"+root_name+"/"+root_path.rel_path_to(spat->get_path()); - - selection_menu->add_item(spat->get_name()); - selection_menu->set_item_icon(i, icon ); - selection_menu->set_item_metadata(i, node_path); - selection_menu->set_item_tooltip(i,String(spat->get_name())+ - "\nType: "+spat->get_class()+"\nPath: "+node_path); - } - - selection_menu->set_global_pos(Vector2( b.global_x, b.global_y )); - selection_menu->popup(); - selection_menu->call_deferred("grab_click_focus"); - selection_menu->set_invalidate_click_until_motion(); - - - - } -} -void SpatialEditorViewport::_sinput(const InputEvent &p_event) { - - if (previewing) - return; //do NONE - - - { - - EditorNode *en = editor; - EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); - - if (!over_plugin_list->empty()) { - bool discard = over_plugin_list->forward_spatial_gui_input(camera,p_event); - if (discard) - return; - } - } - - switch(p_event.type) { - case InputEvent::MOUSE_BUTTON: { - - const InputEventMouseButton &b=p_event.mouse_button; - - switch(b.button_index) { - - case BUTTON_WHEEL_UP: { - - - cursor.distance/=1.08; - if (cursor.distance<0.001) - cursor.distance=0.001; - - } break; - case BUTTON_WHEEL_DOWN: { - - if (cursor.distance<0.001) - cursor.distance=0.001; - cursor.distance*=1.08; - - } break; - case BUTTON_RIGHT: { - - NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int(); - - if (b.pressed && _edit.gizmo.is_valid()) { - //restore - _edit.gizmo->commit_handle(_edit.gizmo_handle,_edit.gizmo_initial_value,true); - _edit.gizmo=Ref<SpatialEditorGizmo>(); - } - - if (_edit.mode==TRANSFORM_NONE && b.pressed) { - - Plane cursor_plane(cursor.cursor_pos,_get_camera_normal()); - - Vector3 ray_origin = _get_ray_pos(Vector2(b.x,b.y)); - Vector3 ray_dir = _get_ray(Vector2(b.x,b.y)); - - - //gizmo modify - - if (b.mod.control) { - - Vector<ObjectID> instances=VisualServer::get_singleton()->instances_cull_ray(ray_origin,ray_dir,get_tree()->get_root()->get_world()->get_scenario() ); - - Plane p(ray_origin,_get_camera_normal()); - - float min_d=1e10; - bool found=false; - - for (int i=0;i<instances.size();i++) { - - - Object *obj=ObjectDB::get_instance(instances[i]); - - if (!obj) - continue; - - VisualInstance *vi=obj->cast_to<VisualInstance>(); - if (!vi) - continue; - - //optimize by checking AABB (although should pre sort by distance) - Rect3 aabb = vi->get_global_transform().xform(vi->get_aabb()); - if (p.distance_to(aabb.get_support(-ray_dir))>min_d) - continue; - - PoolVector<Face3> faces = vi->get_faces(VisualInstance::FACES_SOLID); - int c = faces.size(); - if (c>0) { - PoolVector<Face3>::Read r = faces.read(); - - for(int j=0;j<c;j++) { - - Vector3 inters; - if (r[j].intersects_ray(ray_origin,ray_dir,&inters)) { - - float d = p.distance_to(inters); - if (d<0) - continue; - - if (d<min_d) { - min_d=d; - found=true; - } - } - - } - } - - } - - if (found) { - - //cursor.cursor_pos=ray_origin+ray_dir*min_d; - //VisualServer::get_singleton()->instance_set_transform(cursor_instance,Transform(Matrix3(),cursor.cursor_pos)); - - } - - } else { - Vector3 new_pos; - if (cursor_plane.intersects_ray(ray_origin,ray_dir,&new_pos)) { - - //cursor.cursor_pos=new_pos; - //VisualServer::get_singleton()->instance_set_transform(cursor_instance,Transform(Matrix3(),cursor.cursor_pos)); - } - } - - if (b.mod.alt) { - - if (nav_scheme == NAVIGATION_MAYA) - break; - - _list_select(b); - return; - - } - } - - if (_edit.mode!=TRANSFORM_NONE && b.pressed) { - //cancel motion - _edit.mode=TRANSFORM_NONE; - //_validate_selection(); - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - Spatial *sp = E->get()->cast_to<Spatial>(); - if (!sp) - continue; - - SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); - if (!se) - continue; - - sp->set_global_transform( se->original ); - - } - surface->update(); - //VisualServer::get_singleton()->poly_clear(indicators); - set_message(TTR("Transform Aborted."),3); - } - } break; - case BUTTON_MIDDLE: { - - if (b.pressed && _edit.mode!=TRANSFORM_NONE) { - - switch(_edit.plane ) { - - case TRANSFORM_VIEW: { - - _edit.plane=TRANSFORM_X_AXIS; - set_message(TTR("X-Axis Transform."),2); - name=""; - _update_name(); - } break; - case TRANSFORM_X_AXIS: { - - _edit.plane=TRANSFORM_Y_AXIS; - set_message(TTR("Y-Axis Transform."),2); - - } break; - case TRANSFORM_Y_AXIS: { - - _edit.plane=TRANSFORM_Z_AXIS; - set_message(TTR("Z-Axis Transform."),2); - - } break; - case TRANSFORM_Z_AXIS: { - - _edit.plane=TRANSFORM_VIEW; - set_message(TTR("View Plane Transform."),2); - - } break; - } - - } - } break; - case BUTTON_LEFT: { - - if (b.pressed) { - - NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int(); - if ( (nav_scheme==NAVIGATION_MAYA || nav_scheme==NAVIGATION_MODO) && b.mod.alt) { - break; - } - - if (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_LIST_SELECT) { - _list_select(b); - break; - } - - _edit.mouse_pos=Point2(b.x,b.y); - _edit.snap=false; - _edit.mode=TRANSFORM_NONE; - - - //gizmo has priority over everything - - bool can_select_gizmos=true; - - { - int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS); - can_select_gizmos = view_menu->get_popup()->is_item_checked( idx ); - } - - - - if (can_select_gizmos && spatial_editor->get_selected()) { - - Ref<SpatialEditorGizmo> seg = spatial_editor->get_selected()->get_gizmo(); - if (seg.is_valid()) { - int handle=-1; - Vector3 point; - Vector3 normal; - bool inters = seg->intersect_ray(camera,_edit.mouse_pos,point,normal,&handle,b.mod.shift); - if (inters && handle!=-1) { - - _edit.gizmo=seg; - _edit.gizmo_handle=handle; - //_edit.gizmo_initial_pos=seg->get_handle_pos(gizmo_handle); - _edit.gizmo_initial_value=seg->get_handle_value(handle); - break; - - } - } - } - - - - if (_gizmo_select(_edit.mouse_pos)) - break; - - clicked=0; - clicked_includes_current=false; - - - if ((spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT && b.mod.control) || spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_ROTATE) { - - /* HANDLE ROTATION */ - if (get_selected_count()==0) - break; //bye - //handle rotate - _edit.mode=TRANSFORM_ROTATE; - _compute_edit(Point2(b.x,b.y)); - break; - - } - - if (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_MOVE) { - - if (get_selected_count()==0) - break; //bye - //handle rotate - _edit.mode=TRANSFORM_TRANSLATE; - _compute_edit(Point2(b.x,b.y)); - break; - - - } - - - if (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SCALE) { - - if (get_selected_count()==0) - break; //bye - //handle rotate - _edit.mode=TRANSFORM_SCALE; - _compute_edit(Point2(b.x,b.y)); - break; - - - } - - - - // todo scale - - int gizmo_handle=-1; - - clicked=_select_ray(Vector2( b.x, b.y ),b.mod.shift,clicked_includes_current,&gizmo_handle,b.mod.shift); - - //clicking is always deferred to either move or release - - clicked_wants_append=b.mod.shift; - - if (!clicked) { - - if (!clicked_wants_append) - _clear_selected(); - - //default to regionselect - cursor.region_select=true; - cursor.region_begin=Point2(b.x,b.y); - cursor.region_end=Point2(b.x,b.y); - } - - if (clicked && gizmo_handle>=0) { - - Object *obj=ObjectDB::get_instance(clicked); - if (obj) { - - Spatial *spa = obj->cast_to<Spatial>(); - if (spa) { - - Ref<SpatialEditorGizmo> seg=spa->get_gizmo(); - if (seg.is_valid()) { - - _edit.gizmo=seg; - _edit.gizmo_handle=gizmo_handle; - //_edit.gizmo_initial_pos=seg->get_handle_pos(gizmo_handle); - _edit.gizmo_initial_value=seg->get_handle_value(gizmo_handle); - //print_line("GIZMO: "+itos(gizmo_handle)+" FROMPOS: "+_edit.orig_gizmo_pos); - break; - - } - } - - } - //_compute_edit(Point2(b.x,b.y)); //in case a motion happens.. - } - - - - surface->update(); - } else { - - - if (_edit.gizmo.is_valid()) { - - _edit.gizmo->commit_handle(_edit.gizmo_handle,_edit.gizmo_initial_value,false); - _edit.gizmo=Ref<SpatialEditorGizmo>(); - break; - } - if (clicked) { - _select_clicked(clicked_wants_append,true); - //clickd processing was deferred - clicked=0; - - - } - - if (cursor.region_select) { - _select_region(); - cursor.region_select=false; - surface->update(); - } - - - if (_edit.mode!=TRANSFORM_NONE) { - - - static const char* _transform_name[4]={"None","Rotate","Translate","Scale"}; - undo_redo->create_action(_transform_name[_edit.mode]); - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - Spatial *sp = E->get()->cast_to<Spatial>(); - if (!sp) - continue; - - SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); - if (!se) - continue; - - undo_redo->add_do_method(sp,"set_global_transform",sp->get_global_transform()); - undo_redo->add_undo_method(sp,"set_global_transform",se->original); - } - undo_redo->commit_action(); - _edit.mode=TRANSFORM_NONE; - //VisualServer::get_singleton()->poly_clear(indicators); - set_message(""); - } - - - surface->update(); - } - } break; - } - } break; - case InputEvent::MOUSE_MOTION: { - const InputEventMouseMotion &m=p_event.mouse_motion; - _edit.mouse_pos=Point2(p_event.mouse_motion.x,p_event.mouse_motion.y); - - if (spatial_editor->get_selected()) { - - - Ref<SpatialEditorGizmo> seg = spatial_editor->get_selected()->get_gizmo(); - if (seg.is_valid()) { - - int selected_handle=-1; - - int handle=-1; - Vector3 point; - Vector3 normal; - bool inters = seg->intersect_ray(camera,_edit.mouse_pos,point,normal,&handle,false); - if (inters && handle!=-1) { - - selected_handle=handle; - - } - - if (selected_handle!=spatial_editor->get_over_gizmo_handle()) { - spatial_editor->set_over_gizmo_handle(selected_handle); - spatial_editor->get_selected()->update_gizmo(); - if (selected_handle!=-1) - spatial_editor->select_gizmo_hilight_axis(-1); - } - } - } - - if (spatial_editor->get_over_gizmo_handle()==-1 && !(m.button_mask&1) && !_edit.gizmo.is_valid()) { - - _gizmo_select(_edit.mouse_pos,true); - - } - - NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int(); - NavigationMode nav_mode = NAVIGATION_NONE; - - if (_edit.gizmo.is_valid()) { - - _edit.gizmo->set_handle(_edit.gizmo_handle,camera,Vector2(m.x,m.y)); - Variant v = _edit.gizmo->get_handle_value(_edit.gizmo_handle); - String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle); - set_message(n+": "+String(v)); - - } else if (m.button_mask&1) { - - if (nav_scheme == NAVIGATION_MAYA && m.mod.alt) { - nav_mode = NAVIGATION_ORBIT; - } else if (nav_scheme == NAVIGATION_MODO && m.mod.alt && m.mod.shift) { - nav_mode = NAVIGATION_PAN; - } else if (nav_scheme == NAVIGATION_MODO && m.mod.alt && m.mod.control) { - nav_mode = NAVIGATION_ZOOM; - } else if (nav_scheme == NAVIGATION_MODO && m.mod.alt) { - nav_mode = NAVIGATION_ORBIT; - } else { - if (clicked) { - - if (!clicked_includes_current) { - - _select_clicked(clicked_wants_append,true); - //clickd processing was deferred - } - - - _compute_edit(_edit.mouse_pos); - clicked=0; - - _edit.mode=TRANSFORM_TRANSLATE; - - } - - if (cursor.region_select && nav_mode == NAVIGATION_NONE) { - - cursor.region_end=Point2(m.x,m.y); - surface->update(); - return; - } - - if (_edit.mode==TRANSFORM_NONE && nav_mode == NAVIGATION_NONE) - break; - - - Vector3 ray_pos=_get_ray_pos( Vector2( m.x, m.y ) ); - Vector3 ray=_get_ray( Vector2( m.x, m.y ) ); - - - switch(_edit.mode) { - - case TRANSFORM_SCALE: { - - - Plane plane=Plane(_edit.center,_get_camera_normal()); - - - Vector3 intersection; - if (!plane.intersects_ray(ray_pos,ray,&intersection)) - break; - - Vector3 click; - if (!plane.intersects_ray(_edit.click_ray_pos,_edit.click_ray,&click)) - break; - - float center_click_dist = click.distance_to(_edit.center); - float center_inters_dist = intersection.distance_to(_edit.center); - if (center_click_dist==0) - break; - - float scale = (center_inters_dist / center_click_dist)*100.0; - - if (_edit.snap || spatial_editor->is_snap_enabled()) { - - scale = Math::stepify(scale,spatial_editor->get_scale_snap()); - } - - set_message(vformat(TTR("Scaling to %s%%."),String::num(scale,1))); - scale/=100.0; - - Transform r; - r.basis.scale(Vector3(scale,scale,scale)); - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - Spatial *sp = E->get()->cast_to<Spatial>(); - if (!sp) - continue; - - SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); - if (!se) - continue; - - - Transform original=se->original; - - Transform base=Transform( Basis(), _edit.center); - Transform t=base * (r * (base.inverse() * original)); - - sp->set_global_transform(t); - } - - surface->update(); - - } break; - - case TRANSFORM_TRANSLATE: { - - - Vector3 motion_mask; - Plane plane; - - switch( _edit.plane ) { - case TRANSFORM_VIEW: - motion_mask=Vector3(0,0,0); - plane=Plane(_edit.center,_get_camera_normal()); - break; - case TRANSFORM_X_AXIS: - motion_mask=spatial_editor->get_gizmo_transform().basis.get_axis(0); - plane=Plane(_edit.center,motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized()); - break; - case TRANSFORM_Y_AXIS: - motion_mask=spatial_editor->get_gizmo_transform().basis.get_axis(1); - plane=Plane(_edit.center,motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized()); - break; - case TRANSFORM_Z_AXIS: - motion_mask=spatial_editor->get_gizmo_transform().basis.get_axis(2); - plane=Plane(_edit.center,motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized()); - break; - } - - Vector3 intersection; - if (!plane.intersects_ray(ray_pos,ray,&intersection)) - break; - - Vector3 click; - if (!plane.intersects_ray(_edit.click_ray_pos,_edit.click_ray,&click)) - break; - - //_validate_selection(); - Vector3 motion = intersection-click; - if (motion_mask!=Vector3()) { - motion=motion_mask.dot(motion)*motion_mask; - } - - float snap=0; - - if (_edit.snap || spatial_editor->is_snap_enabled()) { - - snap = spatial_editor->get_translate_snap(); - motion.snap(snap); - } - - //set_message("Translating: "+motion); - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - Spatial *sp = E->get()->cast_to<Spatial>(); - if (!sp) { - continue; - } - - SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); - if (!se) { - continue; - } - - Transform t=se->original; - t.origin+=motion; - sp->set_global_transform(t); - } - } break; - - case TRANSFORM_ROTATE: { - - - Plane plane; - - switch( _edit.plane ) { - case TRANSFORM_VIEW: - plane=Plane(_edit.center,_get_camera_normal()); - break; - case TRANSFORM_X_AXIS: - plane=Plane(_edit.center,spatial_editor->get_gizmo_transform().basis.get_axis(0)); - break; - case TRANSFORM_Y_AXIS: - plane=Plane(_edit.center,spatial_editor->get_gizmo_transform().basis.get_axis(1)); - break; - case TRANSFORM_Z_AXIS: - plane=Plane(_edit.center,spatial_editor->get_gizmo_transform().basis.get_axis(2)); - break; - } - - Vector3 intersection; - if (!plane.intersects_ray(ray_pos,ray,&intersection)) - break; - - Vector3 click; - if (!plane.intersects_ray(_edit.click_ray_pos,_edit.click_ray,&click)) - break; - - - Vector3 y_axis=(click-_edit.center).normalized(); - Vector3 x_axis=plane.normal.cross(y_axis).normalized(); - - float angle=Math::atan2( x_axis.dot(intersection-_edit.center), y_axis.dot(intersection-_edit.center) ); - if (_edit.snap || spatial_editor->is_snap_enabled()) { - - float snap = spatial_editor->get_rotate_snap(); - - if (snap) { - angle=Math::rad2deg(angle)+snap*0.5; //else it wont reach +180 - angle-=Math::fmod(angle,snap); - set_message(vformat(TTR("Rotating %s degrees."),rtos(angle))); - angle=Math::deg2rad(angle); - } else - set_message(vformat(TTR("Rotating %s degrees."),rtos(Math::rad2deg(angle)))); - - } else { - set_message(vformat(TTR("Rotating %s degrees."),rtos(Math::rad2deg(angle)))); - } - - - - - Transform r; - r.basis.rotate(plane.normal,angle); - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - Spatial *sp = E->get()->cast_to<Spatial>(); - if (!sp) - continue; - - SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); - if (!se) - continue; - - - Transform original=se->original; - - Transform base=Transform( Basis(), _edit.center); - Transform t=base * r * base.inverse() * original; - - sp->set_global_transform(t); - } - - surface->update(); - /* - VisualServer::get_singleton()->poly_clear(indicators); - - Vector<Vector3> points; - Vector<Vector3> empty; - Vector<Color> colors; - points.push_back(intersection); - points.push_back(_edit.original.origin); - colors.push_back( Color(255,155,100) ); - colors.push_back( Color(255,155,100) ); - VisualServer::get_singleton()->poly_add_primitive(indicators,points,empty,colors,empty); - */ - } break; - default:{} - } - - } - - } else if (m.button_mask&2) { - - if (nav_scheme == NAVIGATION_MAYA && m.mod.alt) { - nav_mode = NAVIGATION_ZOOM; - } - - } else if (m.button_mask&4) { - - if (nav_scheme == NAVIGATION_GODOT) { - - int mod = 0; - if (m.mod.shift) - mod=KEY_SHIFT; - if (m.mod.alt) - mod=KEY_ALT; - if (m.mod.control) - mod=KEY_CONTROL; - if (m.mod.meta) - mod=KEY_META; - - if (mod == _get_key_modifier("editors/3d/pan_modifier")) - nav_mode = NAVIGATION_PAN; - else if (mod == _get_key_modifier("editors/3d/zoom_modifier")) - nav_mode = NAVIGATION_ZOOM; - else if (mod == _get_key_modifier("editors/3d/orbit_modifier")) - nav_mode = NAVIGATION_ORBIT; - - } else if (nav_scheme == NAVIGATION_MAYA) { - if (m.mod.alt) - nav_mode = NAVIGATION_PAN; - } - - } else if (EditorSettings::get_singleton()->get("editors/3d/emulate_3_button_mouse")) { - // Handle trackpad (no external mouse) use case - int mod = 0; - if (m.mod.shift) - mod=KEY_SHIFT; - if (m.mod.alt) - mod=KEY_ALT; - if (m.mod.control) - mod=KEY_CONTROL; - if (m.mod.meta) - mod=KEY_META; - - if(mod){ - if (mod == _get_key_modifier("editors/3d/pan_modifier")) - nav_mode = NAVIGATION_PAN; - else if (mod == _get_key_modifier("editors/3d/zoom_modifier")) - nav_mode = NAVIGATION_ZOOM; - else if (mod == _get_key_modifier("editors/3d/orbit_modifier")) - nav_mode = NAVIGATION_ORBIT; - } - } - - switch(nav_mode) { - case NAVIGATION_PAN:{ - - real_t pan_speed = 1/150.0; - int pan_speed_modifier = 10; - if (nav_scheme==NAVIGATION_MAYA && m.mod.shift) - pan_speed *= pan_speed_modifier; - - Transform camera_transform; - - camera_transform.translate(cursor.pos); - camera_transform.basis.rotate(Vector3(1,0,0),-cursor.x_rot); - camera_transform.basis.rotate(Vector3(0,1,0),-cursor.y_rot); - Vector3 translation(-m.relative_x*pan_speed,m.relative_y*pan_speed,0); - translation*=cursor.distance/DISTANCE_DEFAULT; - camera_transform.translate(translation); - cursor.pos=camera_transform.origin; - - } break; - - case NAVIGATION_ZOOM: { - real_t zoom_speed = 1/80.0; - int zoom_speed_modifier = 10; - if (nav_scheme==NAVIGATION_MAYA && m.mod.shift) - zoom_speed *= zoom_speed_modifier; - - NavigationZoomStyle zoom_style = (NavigationZoomStyle)EditorSettings::get_singleton()->get("editors/3d/zoom_style").operator int(); - if (zoom_style == NAVIGATION_ZOOM_HORIZONTAL) { - if ( m.relative_x > 0) - cursor.distance*=1-m.relative_x*zoom_speed; - else if (m.relative_x < 0) - cursor.distance/=1+m.relative_x*zoom_speed; - } - else { - if ( m.relative_y > 0) - cursor.distance*=1+m.relative_y*zoom_speed; - else if (m.relative_y < 0) - cursor.distance/=1-m.relative_y*zoom_speed; - } - - } break; - - case NAVIGATION_ORBIT: { - cursor.x_rot+=m.relative_y/80.0; - cursor.y_rot+=m.relative_x/80.0; - if (cursor.x_rot>Math_PI/2.0) - cursor.x_rot=Math_PI/2.0; - if (cursor.x_rot<-Math_PI/2.0) - cursor.x_rot=-Math_PI/2.0; - name=""; - _update_name(); - } break; - - default: {} - } - } break; - case InputEvent::KEY: { - const InputEventKey &k = p_event.key; - if (!k.pressed) - break; - - if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) { - if (_edit.mode != TRANSFORM_NONE) { - _edit.snap=true; - } - } - if (ED_IS_SHORTCUT("spatial_editor/bottom_view", p_event)) { - cursor.y_rot = 0; - cursor.x_rot = -Math_PI/2.0; - set_message(TTR("Bottom View."),2); - name = TTR("Bottom"); - _update_name(); - } - if (ED_IS_SHORTCUT("spatial_editor/top_view", p_event)) { - cursor.y_rot = 0; - cursor.x_rot = Math_PI/2.0; - set_message(TTR("Top View."),2); - name = TTR("Top"); - _update_name(); - } - if (ED_IS_SHORTCUT("spatial_editor/rear_view", p_event)) { - cursor.x_rot = 0; - cursor.y_rot = Math_PI; - set_message(TTR("Rear View."),2); - name = TTR("Rear"); - _update_name(); - } - if (ED_IS_SHORTCUT("spatial_editor/front_view", p_event)) { - cursor.x_rot = 0; - cursor.y_rot=0; - set_message(TTR("Front View."),2); - name=TTR("Front"); - _update_name(); - } - if (ED_IS_SHORTCUT("spatial_editor/left_view", p_event)) { - cursor.x_rot=0; - cursor.y_rot = Math_PI/2.0; - set_message(TTR("Left View."),2); - name = TTR("Left"); - _update_name(); - } - if (ED_IS_SHORTCUT("spatial_editor/right_view", p_event)) { - cursor.x_rot=0; - cursor.y_rot = -Math_PI/2.0; - set_message(TTR("Right View."),2); - name = TTR("Right"); - _update_name(); - } - if (ED_IS_SHORTCUT("spatial_editor/switch_perspective_orthogonal", p_event)) { - _menu_option(orthogonal?VIEW_PERSPECTIVE:VIEW_ORTHOGONAL); - _update_name(); - } - if (ED_IS_SHORTCUT("spatial_editor/insert_anim_key", p_event)) { - if (!get_selected_count() || _edit.mode!=TRANSFORM_NONE) - break; - - if (!AnimationPlayerEditor::singleton->get_key_editor()->has_keying()) { - set_message(TTR("Keying is disabled (no key inserted).")); - break; - } - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - Spatial *sp = E->get()->cast_to<Spatial>(); - if (!sp) - continue; - - emit_signal("transform_key_request",sp,"",sp->get_transform()); - } - - - set_message(TTR("Animation Key Inserted.")); - } - - if (k.scancode == KEY_SPACE) { - if (!k.pressed) emit_signal("toggle_maximize_view", this); - } - - } break; - - } - -} - -void SpatialEditorViewport::set_message(String p_message,float p_time) { - - message=p_message; - message_time=p_time; - -} - - - -void SpatialEditorViewport::_notification(int p_what) { - - - if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { - - bool visible=is_visible_in_tree(); - - set_process(visible); - - if (visible) - _update_camera(); - - call_deferred("update_transform_gizmo_view"); - } - - if (p_what==NOTIFICATION_RESIZED) { - - call_deferred("update_transform_gizmo_view"); - - } - - if (p_what==NOTIFICATION_PROCESS) { - - - //force editr camera - /* - current_camera=get_root_node()->get_current_camera(); - if (current_camera!=camera) { - - - } - */ - - _update_camera(); - - Map<Node*,Object*> &selection = editor_selection->get_selection(); - - bool changed=false; - bool exist=false; - - for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) { - - Spatial *sp = E->key()->cast_to<Spatial>(); - if (!sp) - continue; - - SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); - if (!se) - continue; - - - VisualInstance *vi=sp->cast_to<VisualInstance>(); - - - if (se->aabb.has_no_surface()) { - - se->aabb=vi?vi->get_aabb():Rect3( Vector3(-0.2,-0.2,-0.2),Vector3(0.4,0.4,0.4)); - } - - Transform t=sp->get_global_transform(); - t.translate(se->aabb.pos); - t.basis.scale( se->aabb.size ); - - exist=true; - if (se->last_xform==t) - continue; - changed=true; - se->last_xform=t; - VisualServer::get_singleton()->instance_set_transform(se->sbox_instance,t); - - } - - if (changed || (spatial_editor->is_gizmo_visible() && !exist)) { - spatial_editor->update_transform_gizmo(); - } - - if (message_time>0) { - - if (message!=last_message) { - surface->update(); - last_message=message; - } - - message_time-=get_fixed_process_delta_time(); - if (message_time<0) - surface->update(); - } - - //update shadow atlas if changed - - int shadowmap_size = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/size"); - int atlas_q0 = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/quadrant_0_subdiv"); - int atlas_q1 = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/quadrant_1_subdiv"); - int atlas_q2 = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/quadrant_2_subdiv"); - int atlas_q3 = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/quadrant_3_subdiv"); - - - viewport->set_shadow_atlas_size(shadowmap_size); - viewport->set_shadow_atlas_quadrant_subdiv(0,Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0)); - viewport->set_shadow_atlas_quadrant_subdiv(1,Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1)); - viewport->set_shadow_atlas_quadrant_subdiv(2,Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2)); - viewport->set_shadow_atlas_quadrant_subdiv(3,Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3)); - - //update msaa if changed - - int msaa_mode = GlobalConfig::get_singleton()->get("rendering/quality/msaa"); - viewport->set_msaa(Viewport::MSAA(msaa_mode)); - - bool hdr = GlobalConfig::get_singleton()->get("rendering/quality/hdr"); - viewport->set_hdr(hdr); - - - } - - if (p_what==NOTIFICATION_ENTER_TREE) { - - surface->connect("draw",this,"_draw"); - surface->connect("gui_input",this,"_sinput"); - surface->connect("mouse_entered",this,"_smouseenter"); - preview_camera->set_icon(get_icon("Camera","EditorIcons")); - _init_gizmo_instance(index); - } - if (p_what==NOTIFICATION_EXIT_TREE) { - - - _finish_gizmo_instances(); - - } - - if (p_what==NOTIFICATION_MOUSE_ENTER) { - - - } - - - if (p_what==NOTIFICATION_DRAW) { - - - - } - -} - -void SpatialEditorViewport::_draw() { - - if (surface->has_focus()) { - Size2 size = surface->get_size(); - Rect2 r =Rect2(Point2(),size); - get_stylebox("EditorFocus","EditorStyles")->draw(surface->get_canvas_item(),r); - } - - - RID ci=surface->get_canvas_item(); - - if (cursor.region_select) { - - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor.region_begin,cursor.region_end-cursor.region_begin),Color(0.7,0.7,1.0,0.3)); - } - - if (message_time>0) { - Ref<Font> font = get_font("font","Label"); - Point2 msgpos=Point2(5,get_size().y-20); - font->draw(ci,msgpos+Point2(1,1),message,Color(0,0,0,0.8)); - font->draw(ci,msgpos+Point2(-1,-1),message,Color(0,0,0,0.8)); - font->draw(ci,msgpos,message,Color(1,1,1,1)); - } - - - if (_edit.mode==TRANSFORM_ROTATE) { - - Point2 center = _point_to_screen(_edit.center); - VisualServer::get_singleton()->canvas_item_add_line(ci,_edit.mouse_pos, center, Color(0.4,0.7,1.0,0.8)); - - - } - - if (previewing) { - - - Size2 ss = Size2( GlobalConfig::get_singleton()->get("display/width"), GlobalConfig::get_singleton()->get("display/height") ); - float aspect = ss.aspect(); - Size2 s = get_size(); - - Rect2 draw_rect; - - - switch(previewing->get_keep_aspect_mode()) { - case Camera::KEEP_WIDTH: { - - draw_rect.size = Size2(s.width,s.width/aspect); - draw_rect.pos.x=0; - draw_rect.pos.y=(s.height-draw_rect.size.y)*0.5; - - } break; - case Camera::KEEP_HEIGHT: { - - draw_rect.size = Size2(s.height*aspect,s.height); - draw_rect.pos.y=0; - draw_rect.pos.x=(s.width-draw_rect.size.x)*0.5; - - } break; - } - - draw_rect = Rect2(Vector2(),s).clip(draw_rect); - - surface->draw_line(draw_rect.pos,draw_rect.pos+Vector2(draw_rect.size.x,0),Color(0.6,0.6,0.1,0.5),2.0); - surface->draw_line(draw_rect.pos+Vector2(draw_rect.size.x,0),draw_rect.pos+draw_rect.size,Color(0.6,0.6,0.1,0.5),2.0); - surface->draw_line(draw_rect.pos+draw_rect.size,draw_rect.pos+Vector2(0,draw_rect.size.y),Color(0.6,0.6,0.1,0.5),2.0); - surface->draw_line(draw_rect.pos,draw_rect.pos+Vector2(0,draw_rect.size.y),Color(0.6,0.6,0.1,0.5),2.0); - } - -} - - -void SpatialEditorViewport::_menu_option(int p_option) { - - switch(p_option) { - - case VIEW_TOP: { - - cursor.x_rot=Math_PI/2.0; - cursor.y_rot=0; - name=TTR("Top"); - _update_name(); - } break; - case VIEW_BOTTOM: { - - cursor.x_rot=-Math_PI/2.0; - cursor.y_rot=0; - name=TTR("Bottom"); - _update_name(); - - } break; - case VIEW_LEFT: { - - cursor.y_rot=Math_PI/2.0; - cursor.x_rot=0; - name=TTR("Left"); - _update_name(); - - } break; - case VIEW_RIGHT: { - - cursor.y_rot=-Math_PI/2.0; - cursor.x_rot=0; - name=TTR("Right"); - _update_name(); - - } break; - case VIEW_FRONT: { - - cursor.y_rot=0; - cursor.x_rot=0; - name=TTR("Front"); - _update_name(); - - } break; - case VIEW_REAR: { - - cursor.y_rot=Math_PI; - cursor.x_rot=0; - name=TTR("Rear"); - _update_name(); - - } break; - case VIEW_CENTER_TO_ORIGIN: { - - cursor.pos = Vector3(0,0,0); - - } break; - case VIEW_CENTER_TO_SELECTION: { - - focus_selection(); - - } break; - case VIEW_ALIGN_SELECTION_WITH_VIEW: { - - if (!get_selected_count()) - break; - - Transform camera_transform = camera->get_global_transform(); - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - undo_redo->create_action(TTR("Align with view")); - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - Spatial *sp = E->get()->cast_to<Spatial>(); - if (!sp) - continue; - - SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); - if (!se) - continue; - - Transform xform = camera_transform; - xform.scale_basis(sp->get_scale()); - - undo_redo->add_do_method(sp,"set_global_transform",xform); - undo_redo->add_undo_method(sp,"set_global_transform",sp->get_global_transform()); - } - undo_redo->commit_action(); - } break; - case VIEW_ENVIRONMENT: { - - int idx = view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT); - bool current = view_menu->get_popup()->is_item_checked( idx ); - current=!current; - if (current) { - - camera->set_environment(RES()); - } else { - - camera->set_environment(SpatialEditor::get_singleton()->get_viewport_environment()); - } - - view_menu->get_popup()->set_item_checked( idx, current ); - - - } break; - case VIEW_PERSPECTIVE: { - - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), true ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL), false ); - orthogonal=false; - call_deferred("update_transform_gizmo_view"); - _update_name(); - - } break; - case VIEW_ORTHOGONAL: { - - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL), true ); - orthogonal=true; - call_deferred("update_transform_gizmo_view"); - _update_name(); - - } break; - case VIEW_AUDIO_LISTENER: { - - int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER); - bool current = view_menu->get_popup()->is_item_checked( idx ); - current=!current; - viewport->set_as_audio_listener(current); - view_menu->get_popup()->set_item_checked( idx, current ); - - } break; - case VIEW_GIZMOS: { - - int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS); - bool current = view_menu->get_popup()->is_item_checked( idx ); - current=!current; - if (current) - camera->set_cull_mask( ((1<<20)-1)|(1<<(GIZMO_BASE_LAYER+index))|(1<<GIZMO_EDIT_LAYER)|(1<<GIZMO_GRID_LAYER) ); - else - camera->set_cull_mask( ((1<<20)-1)|(1<<(GIZMO_BASE_LAYER+index))|(1<<GIZMO_GRID_LAYER) ); - view_menu->get_popup()->set_item_checked( idx, current ); - - } break; - - } - -} - - -void SpatialEditorViewport::_preview_exited_scene() { - - preview_camera->set_pressed(false); - _toggle_camera_preview(false); - view_menu->show(); -} - - -void SpatialEditorViewport::_init_gizmo_instance(int p_idx) { - - uint32_t layer=1<<(GIZMO_BASE_LAYER+p_idx);//|(1<<GIZMO_GRID_LAYER); - - for(int i=0;i<3;i++) { - move_gizmo_instance[i]=VS::get_singleton()->instance_create(); - VS::get_singleton()->instance_set_base(move_gizmo_instance[i],spatial_editor->get_move_gizmo(i)->get_rid()); - VS::get_singleton()->instance_set_scenario(move_gizmo_instance[i],get_tree()->get_root()->get_world()->get_scenario()); - VS::get_singleton()->instance_set_visible(move_gizmo_instance[i],false); - //VS::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true); - VS::get_singleton()->instance_geometry_set_cast_shadows_setting(move_gizmo_instance[i], VS::SHADOW_CASTING_SETTING_OFF); - VS::get_singleton()->instance_set_layer_mask(move_gizmo_instance[i],layer); - - rotate_gizmo_instance[i]=VS::get_singleton()->instance_create(); - VS::get_singleton()->instance_set_base(rotate_gizmo_instance[i],spatial_editor->get_rotate_gizmo(i)->get_rid()); - VS::get_singleton()->instance_set_scenario(rotate_gizmo_instance[i],get_tree()->get_root()->get_world()->get_scenario()); - VS::get_singleton()->instance_set_visible(rotate_gizmo_instance[i],false); - //VS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true); - VS::get_singleton()->instance_geometry_set_cast_shadows_setting(rotate_gizmo_instance[i], VS::SHADOW_CASTING_SETTING_OFF); - VS::get_singleton()->instance_set_layer_mask(rotate_gizmo_instance[i],layer); - } - -} - - -void SpatialEditorViewport::_finish_gizmo_instances() { - - - for(int i=0;i<3;i++) { - VS::get_singleton()->free(move_gizmo_instance[i]); - VS::get_singleton()->free(rotate_gizmo_instance[i]); - } - -} -void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) { - - - ERR_FAIL_COND(p_activate && !preview); - ERR_FAIL_COND(!p_activate && !previewing); - - if (!p_activate) { - - previewing->disconnect("tree_exited",this,"_preview_exited_scene"); - previewing=NULL; - VS::get_singleton()->viewport_attach_camera( viewport->get_viewport_rid(), camera->get_camera() ); //restore - if (!preview) - preview_camera->hide(); - view_menu->show(); - surface->update(); - - } else { - - previewing=preview; - previewing->connect("tree_exited",this,"_preview_exited_scene"); - VS::get_singleton()->viewport_attach_camera( viewport->get_viewport_rid(), preview->get_camera() ); //replace - view_menu->hide(); - surface->update(); - - } -} - -void SpatialEditorViewport::_selection_result_pressed(int p_result) { - - if (selection_results.size() <= p_result) - return; - - clicked=selection_results[p_result].item->get_instance_ID(); - - if (clicked) { - _select_clicked(clicked_wants_append,true); - clicked=0; - } -} - -void SpatialEditorViewport::_selection_menu_hide() { - - selection_results.clear(); - selection_menu->clear(); - selection_menu->set_size(Vector2(0, 0)); -} - -void SpatialEditorViewport::set_can_preview(Camera* p_preview) { - - preview=p_preview; - - if (!preview_camera->is_pressed()) { - - if (p_preview) { - preview_camera->show(); - } else { - preview_camera->hide(); - } - } -} - -void SpatialEditorViewport::update_transform_gizmo_view() { - - if (!is_visible_in_tree()) - return; - - Transform xform = spatial_editor->get_gizmo_transform(); - - - Transform camera_xform = camera->get_transform(); - Vector3 camz = -camera_xform.get_basis().get_axis(2).normalized(); - Vector3 camy = -camera_xform.get_basis().get_axis(1).normalized(); - Plane p(camera_xform.origin,camz); - float gizmo_d = Math::abs( p.distance_to(xform.origin )); - float d0 = camera->unproject_position(camera_xform.origin+camz*gizmo_d).y; - float d1 = camera->unproject_position(camera_xform.origin+camz*gizmo_d+camy).y; - float dd = Math::abs(d0-d1); - if (dd==0) - dd=0.0001; - - float gsize = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size"); - gizmo_scale=(gsize/Math::abs(dd)); - Vector3 scale = Vector3(1,1,1) * gizmo_scale; - - xform.basis.scale(scale); - - //xform.basis.scale(GIZMO_SCALE_DEFAULT*Vector3(1,1,1)); - - - for(int i=0;i<3;i++) { - VisualServer::get_singleton()->instance_set_transform(move_gizmo_instance[i], xform ); - VisualServer::get_singleton()->instance_set_visible(move_gizmo_instance[i],spatial_editor->is_gizmo_visible()&& (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_MOVE) ); - VisualServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[i], xform ); - VisualServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[i],spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_ROTATE) ); - } - -} - -void SpatialEditorViewport::set_state(const Dictionary& p_state) { - - cursor.pos=p_state["pos"]; - cursor.x_rot=p_state["x_rot"]; - cursor.y_rot=p_state["y_rot"]; - cursor.distance=p_state["distance"]; - bool env = p_state["use_environment"]; - bool orth = p_state["use_orthogonal"]; - if (orth) - _menu_option(VIEW_ORTHOGONAL); - else - _menu_option(VIEW_PERSPECTIVE); - if (env != camera->get_environment().is_valid()) - _menu_option(VIEW_ENVIRONMENT); - if (p_state.has("listener")) { - bool listener = p_state["listener"]; - - int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER); - viewport->set_as_audio_listener(listener); - view_menu->get_popup()->set_item_checked( idx, listener ); - } - - if (p_state.has("previewing")) { - Node *pv = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["previewing"]); - if (pv && pv->cast_to<Camera>()) { - previewing=pv->cast_to<Camera>(); - previewing->connect("tree_exited",this,"_preview_exited_scene"); - VS::get_singleton()->viewport_attach_camera( viewport->get_viewport_rid(), previewing->get_camera() ); //replace - view_menu->hide(); - surface->update(); - preview_camera->set_pressed(true); - preview_camera->show(); - } - } -} - -Dictionary SpatialEditorViewport::get_state() const { - - Dictionary d; - d["pos"]=cursor.pos; - d["x_rot"]=cursor.x_rot; - d["y_rot"]=cursor.y_rot; - d["distance"]=cursor.distance; - d["use_environment"]=camera->get_environment().is_valid(); - d["use_orthogonal"]=camera->get_projection()==Camera::PROJECTION_ORTHOGONAL; - d["listener"]=viewport->is_audio_listener(); - if (previewing) { - d["previewing"]=EditorNode::get_singleton()->get_edited_scene()->get_path_to(previewing); - } - - return d; -} - - -void SpatialEditorViewport::_bind_methods(){ - - ClassDB::bind_method(D_METHOD("_draw"),&SpatialEditorViewport::_draw); - ClassDB::bind_method(D_METHOD("_smouseenter"),&SpatialEditorViewport::_smouseenter); - ClassDB::bind_method(D_METHOD("_sinput"),&SpatialEditorViewport::_sinput); - ClassDB::bind_method(D_METHOD("_menu_option"),&SpatialEditorViewport::_menu_option); - ClassDB::bind_method(D_METHOD("_toggle_camera_preview"),&SpatialEditorViewport::_toggle_camera_preview); - ClassDB::bind_method(D_METHOD("_preview_exited_scene"),&SpatialEditorViewport::_preview_exited_scene); - ClassDB::bind_method(D_METHOD("update_transform_gizmo_view"),&SpatialEditorViewport::update_transform_gizmo_view); - ClassDB::bind_method(D_METHOD("_selection_result_pressed"),&SpatialEditorViewport::_selection_result_pressed); - ClassDB::bind_method(D_METHOD("_selection_menu_hide"),&SpatialEditorViewport::_selection_menu_hide); - - ADD_SIGNAL( MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport")) ); -} - - -void SpatialEditorViewport::reset() { - - orthogonal=false; - message_time=0; - message=""; - last_message=""; - name=""; - - cursor.x_rot=0.5; - cursor.y_rot=0.5; - cursor.distance=4; - cursor.region_select=false; - _update_name(); -} - - -void SpatialEditorViewport::focus_selection() { - if (!get_selected_count()) - return; - - Vector3 center; - int count=0; - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - Spatial *sp = E->get()->cast_to<Spatial>(); - if (!sp) - continue; - - SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); - if (!se) - continue; - - center+=sp->get_global_transform().origin; - count++; - } - - if( count != 0 ) { - center/=float(count); - } - - cursor.pos=center; -} - - -SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index) { - - _edit.mode=TRANSFORM_NONE; - _edit.plane=TRANSFORM_VIEW; - _edit.edited_gizmo=0; - _edit.snap=1; - _edit.gizmo_handle=0; - - - - index=p_index; - editor=p_editor; - editor_selection=editor->get_editor_selection(); - undo_redo=editor->get_undo_redo(); - clicked=0; - clicked_includes_current=false; - orthogonal=false; - message_time=0; - - spatial_editor=p_spatial_editor; - ViewportContainer *c=memnew(ViewportContainer); - c->set_stretch(true); - add_child(c); - c->set_area_as_parent_rect(); - viewport = memnew( Viewport ); - viewport->set_disable_input(true); - - c->add_child(viewport); - surface = memnew( Control ); - add_child(surface); - surface->set_area_as_parent_rect(); - camera = memnew(Camera); - camera->set_disable_gizmo(true); - camera->set_cull_mask( ((1<<20)-1)|(1<<(GIZMO_BASE_LAYER+p_index))|(1<<GIZMO_EDIT_LAYER)|(1<<GIZMO_GRID_LAYER) ); - //camera->set_environment(SpatialEditor::get_singleton()->get_viewport_environment()); - viewport->add_child(camera); - camera->make_current(); - surface->set_focus_mode(FOCUS_ALL); - - view_menu = memnew( MenuButton ); - surface->add_child(view_menu); - view_menu->set_pos( Point2(4,4)); - view_menu->set_self_modulate(Color(1,1,1,0.5)); - view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/top_view"), VIEW_TOP); - view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/bottom_view"), VIEW_BOTTOM); - view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/left_view"), VIEW_LEFT); - view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/right_view"), VIEW_RIGHT); - view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/front_view"), VIEW_FRONT); - view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/rear_view"), VIEW_REAR); - view_menu->get_popup()->add_separator(); - view_menu->get_popup()->add_check_item(TTR("Perspective") + " (" + ED_GET_SHORTCUT("spatial_editor/switch_perspective_orthogonal")->get_as_text() + ")", VIEW_PERSPECTIVE); - view_menu->get_popup()->add_check_item(TTR("Orthogonal") + " (" + ED_GET_SHORTCUT("spatial_editor/switch_perspective_orthogonal")->get_as_text() + ")", VIEW_ORTHOGONAL); - view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE),true); - view_menu->get_popup()->add_separator(); - view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_environment", TTR("Environment")), VIEW_ENVIRONMENT); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT),true); - view_menu->get_popup()->add_separator(); - view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_listener", TTR("Audio Listener")), VIEW_AUDIO_LISTENER); - view_menu->get_popup()->add_separator(); - view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_gizmos", TTR("Gizmos")),VIEW_GIZMOS); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_GIZMOS),true); - - view_menu->get_popup()->add_separator(); - view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/focus_origin"), VIEW_CENTER_TO_ORIGIN); - view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/focus_selection"), VIEW_CENTER_TO_SELECTION); - view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/align_selection_with_view"), VIEW_ALIGN_SELECTION_WITH_VIEW); - view_menu->get_popup()->connect("id_pressed",this,"_menu_option"); - - preview_camera = memnew( Button ); - preview_camera->set_toggle_mode(true); - preview_camera->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,90); - preview_camera->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,10); - preview_camera->set_text("preview"); - surface->add_child(preview_camera); - preview_camera->hide(); - preview_camera->connect("toggled",this,"_toggle_camera_preview"); - previewing=NULL; - preview=NULL; - gizmo_scale=1.0; - - selection_menu = memnew( PopupMenu ); - add_child(selection_menu); - selection_menu->set_custom_minimum_size(Vector2(100, 0)); - selection_menu->connect("id_pressed", this, "_selection_result_pressed"); - selection_menu->connect("popup_hide", this, "_selection_menu_hide"); - - if (p_index==0) { - view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER),true); - viewport->set_as_audio_listener(true); - } - - - name=TTR("Top"); - _update_name(); - - EditorSettings::get_singleton()->connect("settings_changed",this,"update_transform_gizmo_view"); - -} - - - - - - - -SpatialEditor *SpatialEditor::singleton=NULL; - -SpatialEditorSelectedItem::~SpatialEditorSelectedItem() { - - if (sbox_instance.is_valid()) - VisualServer::get_singleton()->free(sbox_instance); -} - - - -void SpatialEditor::select_gizmo_hilight_axis(int p_axis) { - - - for(int i=0;i<3;i++) { - - move_gizmo[i]->surface_set_material(0,i==p_axis?gizmo_hl:gizmo_color[i]); - rotate_gizmo[i]->surface_set_material(0,(i+3)==p_axis?gizmo_hl:gizmo_color[i]); - } - -} - -void SpatialEditor::update_transform_gizmo() { - - List<Node*> &selection = editor_selection->get_selected_node_list(); - Rect3 center; - bool first=true; - - Basis gizmo_basis; - bool local_gizmo_coords = transform_menu->get_popup()->is_item_checked( transform_menu->get_popup()->get_item_index(MENU_TRANSFORM_LOCAL_COORDS) ); - - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - Spatial *sp = E->get()->cast_to<Spatial>(); - if (!sp) - continue; - - SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); - if (!se) - continue; - - Transform xf = se->sp->get_global_transform(); - if (first) { - center.pos=xf.origin; - first=false; - if (local_gizmo_coords) { - gizmo_basis=xf.basis; - gizmo_basis.orthonormalize(); - } - } else { - center.expand_to(xf.origin); - gizmo_basis=Basis(); - } - //count++; - } - - Vector3 pcenter = center.pos+center.size*0.5; - gizmo.visible=!first; - gizmo.transform.origin=pcenter; - gizmo.transform.basis=gizmo_basis; - - for(int i=0;i<4;i++) { - viewports[i]->update_transform_gizmo_view(); - } - -} - - -Object *SpatialEditor::_get_editor_data(Object *p_what) { - - Spatial *sp = p_what->cast_to<Spatial>(); - if (!sp) - return NULL; - - - SpatialEditorSelectedItem *si = memnew( SpatialEditorSelectedItem ); - - si->sp=sp; - si->sbox_instance=VisualServer::get_singleton()->instance_create2(selection_box->get_rid(),sp->get_world()->get_scenario()); - VS::get_singleton()->instance_geometry_set_cast_shadows_setting(si->sbox_instance, VS::SHADOW_CASTING_SETTING_OFF); - - if (get_tree()->is_editor_hint()) - editor->call("edit_node",sp); - - return si; -} - -void SpatialEditor::_generate_selection_box() { - - Rect3 aabb( Vector3(), Vector3(1,1,1) ); - aabb.grow_by( aabb.get_longest_axis_size()/20.0 ); - - Ref<SurfaceTool> st = memnew( SurfaceTool ); - - st->begin(Mesh::PRIMITIVE_LINES); - for (int i=0;i<12;i++) { - - Vector3 a,b; - aabb.get_edge(i,a,b); - - /*Vector<Vector3> points; - Vector<Color> colors; - points.push_back(a); - points.push_back(b);*/ - - st->add_color( Color(1.0,1.0,0.8,0.8) ); - st->add_vertex(a); - st->add_color( Color(1.0,1.0,0.8,0.4) ); - st->add_vertex(a.linear_interpolate(b,0.2)); - - st->add_color( Color(1.0,1.0,0.8,0.4) ); - st->add_vertex(a.linear_interpolate(b,0.8)); - st->add_color( Color(1.0,1.0,0.8,0.8) ); - st->add_vertex(b); - - } - - Ref<FixedSpatialMaterial> mat = memnew( FixedSpatialMaterial ); - mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED,true); - mat->set_albedo(Color(1,1,1)); - mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT,true); - mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR,true); - mat->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR,true); - st->set_material(mat); - selection_box = st->commit(); -} - - -Dictionary SpatialEditor::get_state() const { - - - Dictionary d; - - d["snap_enabled"]=snap_enabled; - d["translate_snap"]=get_translate_snap(); - d["rotate_snap"]=get_rotate_snap(); - d["scale_snap"]=get_scale_snap(); - - int local_coords_index=transform_menu->get_popup()->get_item_index(MENU_TRANSFORM_LOCAL_COORDS); - d["local_coords"]=transform_menu->get_popup()->is_item_checked( local_coords_index ); - - int vc=0; - if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT) )) - vc=1; - else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS) )) - vc=2; - else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS) )) - vc=3; - else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS) )) - vc=4; - else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT) )) - vc=5; - else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT) )) - vc=6; - - d["viewport_mode"]=vc; - Array vpdata; - for(int i=0;i<4;i++) { - vpdata.push_back( viewports[i]->get_state() ); - } - - d["viewports"]=vpdata; - - d["default_light"]=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_LIGHT) ); - d["ambient_light_color"]=settings_ambient_color->get_pick_color(); - - d["default_srgb"]=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_SRGB) ); - d["show_grid"]=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_GRID) ); - d["show_origin"]=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN) ); - d["fov"]=get_fov(); - d["znear"]=get_znear(); - d["zfar"]=get_zfar(); - d["deflight_rot_x"]=settings_default_light_rot_x; - d["deflight_rot_y"]=settings_default_light_rot_y; - - return d; -} -void SpatialEditor::set_state(const Dictionary& p_state) { - - Dictionary d = p_state; - - if (d.has("snap_enabled")) { - snap_enabled=d["snap_enabled"]; - int snap_enabled_idx=transform_menu->get_popup()->get_item_index(MENU_TRANSFORM_USE_SNAP); - transform_menu->get_popup()->set_item_checked( snap_enabled_idx, snap_enabled ); - } - - if (d.has("translate_snap")) - snap_translate->set_text(d["translate_snap"]); - - if (d.has("rotate_snap")) - snap_rotate->set_text(d["rotate_snap"]); - - if (d.has("scale_snap")) - snap_scale->set_text(d["scale_snap"]); - - if (d.has("local_coords")) { - int local_coords_idx=transform_menu->get_popup()->get_item_index(MENU_TRANSFORM_LOCAL_COORDS); - transform_menu->get_popup()->set_item_checked( local_coords_idx, d["local_coords"] ); - update_transform_gizmo(); - } - - if (d.has("viewport_mode")) { - int vc = d["viewport_mode"]; - - if (vc==1) - _menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT); - else if (vc==2) - _menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS); - else if (vc==3) - _menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS); - else if (vc==4) - _menu_item_pressed(MENU_VIEW_USE_4_VIEWPORTS); - else if (vc==5) - _menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS_ALT); - else if (vc==6) - _menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS_ALT); - } - - if (d.has("viewports")) { - Array vp = d["viewports"]; - ERR_FAIL_COND(vp.size()>4); - - for(int i=0;i<4;i++) { - viewports[i]->set_state(vp[i]); - } - } - - if (d.has("zfar")) - settings_zfar->set_value(float(d["zfar"])); - if (d.has("znear")) - settings_znear->set_value(float(d["znear"])); - if (d.has("fov")) - settings_fov->set_value(float(d["fov"])); - - if (d.has("default_light")) { - bool use = d["default_light"]; - - bool existing = light_instance.is_valid(); - if (use!=existing) { - if (existing) { - VisualServer::get_singleton()->free(light_instance); - light_instance=RID(); - } else { - light_instance=VisualServer::get_singleton()->instance_create2(light,get_tree()->get_root()->get_world()->get_scenario()); - VisualServer::get_singleton()->instance_set_transform(light_instance,light_transform); - - } - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_LIGHT), light_instance.is_valid() ); - } - - } - if (d.has("ambient_light_color")) { - settings_ambient_color->set_pick_color(d["ambient_light_color"]); - //viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,d["ambient_light_color"]); - } - - if (d.has("default_srgb")) { - bool use = d["default_srgb"]; - - //viewport_environment->set_enable_fx(Environment::FX_SRGB,use); - //view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_SRGB), use ); - } - if (d.has("show_grid")) { - bool use = d["show_grid"]; - - if (use!=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_GRID))) { - _menu_item_pressed(MENU_VIEW_GRID); - } - } - - if (d.has("show_origin")) { - bool use = d["show_origin"]; - - if (use!=view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN))) { - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN), use ); - VisualServer::get_singleton()->instance_set_visible(origin_instance,use); - } - } - - if (d.has("deflight_rot_x")) - settings_default_light_rot_x=d["deflight_rot_x"]; - if (d.has("deflight_rot_y")) - settings_default_light_rot_y=d["deflight_rot_y"]; - - _update_default_light_angle(); - - -} - - -void SpatialEditor::edit(Spatial *p_spatial) { - - if (p_spatial!=selected) { - if (selected) { - - Ref<SpatialEditorGizmo> seg = selected->get_gizmo(); - if (seg.is_valid()) { - seg->set_selected(false); - selected->update_gizmo(); - } - } - - selected=p_spatial; - over_gizmo_handle=-1; - - if (selected) { - - Ref<SpatialEditorGizmo> seg = selected->get_gizmo(); - if (seg.is_valid()) { - seg->set_selected(true); - selected->update_gizmo(); - } - } - } - - /* - if (p_spatial) { - _validate_selection(); - if (selected.has(p_spatial->get_instance_ID()) && selected.size()==1) - return; - _select(p_spatial->get_instance_ID(),false,true); - - // should become the selection - } - */ -} - -void SpatialEditor::_xform_dialog_action() { - - Transform t; - //translation - Vector3 scale; - Vector3 rotate; - Vector3 translate; - - for(int i=0;i<3;i++) { - translate[i]=xform_translate[i]->get_text().to_double(); - rotate[i]=Math::deg2rad(xform_rotate[i]->get_text().to_double()); - scale[i]=xform_scale[i]->get_text().to_double(); - } - - t.basis.scale(scale); - t.basis.rotate(rotate); - t.origin=translate; - - - undo_redo->create_action(TTR("XForm Dialog")); - - List<Node*> &selection = editor_selection->get_selected_node_list(); - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - - Spatial *sp = E->get()->cast_to<Spatial>(); - if (!sp) - continue; - - SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp); - if (!se) - continue; - - bool post = xform_type->get_selected()>0; - - Transform tr = sp->get_global_transform(); - if (post) - tr = tr * t; - else { - - tr.basis = t.basis * tr.basis; - tr.origin+=t.origin; - } - - undo_redo->add_do_method(sp,"set_global_transform",tr); - undo_redo->add_undo_method(sp,"set_global_transform",sp->get_global_transform()); - } - undo_redo->commit_action(); -} - -void SpatialEditor::_menu_item_pressed(int p_option) { - - switch(p_option) { - - case MENU_TOOL_SELECT: - case MENU_TOOL_MOVE: - case MENU_TOOL_ROTATE: - case MENU_TOOL_SCALE: - case MENU_TOOL_LIST_SELECT: { - - for(int i=0;i<TOOL_MAX;i++) - tool_button[i]->set_pressed(i==p_option); - tool_mode=(ToolMode)p_option; - - //static const char *_mode[]={"Selection Mode.","Translation Mode.","Rotation Mode.","Scale Mode.","List Selection Mode."}; - //set_message(_mode[p_option],3); - update_transform_gizmo(); - - } break; - case MENU_TRANSFORM_USE_SNAP: { - - bool is_checked = transform_menu->get_popup()->is_item_checked( transform_menu->get_popup()->get_item_index(p_option) ); - snap_enabled=!is_checked; - transform_menu->get_popup()->set_item_checked( transform_menu->get_popup()->get_item_index(p_option), snap_enabled ); - } break; - case MENU_TRANSFORM_CONFIGURE_SNAP: { - - snap_dialog->popup_centered(Size2(200,180)); - } break; - case MENU_TRANSFORM_LOCAL_COORDS: { - - bool is_checked = transform_menu->get_popup()->is_item_checked( transform_menu->get_popup()->get_item_index(p_option) ); - transform_menu->get_popup()->set_item_checked( transform_menu->get_popup()->get_item_index(p_option), !is_checked ); - update_transform_gizmo(); - - } break; - case MENU_TRANSFORM_DIALOG: { - - for(int i=0;i<3;i++) { - - - xform_translate[i]->set_text("0"); - xform_rotate[i]->set_text("0"); - xform_scale[i]->set_text("1"); - - } - - xform_dialog->popup_centered(Size2(200,200)); - - } break; - case MENU_VIEW_USE_DEFAULT_LIGHT: { - - bool is_checked = view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(p_option) ); - - if (is_checked) { - VisualServer::get_singleton()->free(light_instance); - light_instance=RID(); - } else { - light_instance=VisualServer::get_singleton()->instance_create2(light,get_tree()->get_root()->get_world()->get_scenario()); - VisualServer::get_singleton()->instance_set_transform(light_instance,light_transform); - - _update_default_light_angle(); - } - - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(p_option), light_instance.is_valid() ); - - } break; - case MENU_VIEW_USE_DEFAULT_SRGB: { - - bool is_checked = view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(p_option) ); - - if (is_checked) { - //viewport_environment->set_enable_fx(Environment::FX_SRGB,false); - } else { - //viewport_environment->set_enable_fx(Environment::FX_SRGB,true); - } - - is_checked = ! is_checked; - - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(p_option), is_checked ); - - - } break; - case MENU_VIEW_USE_1_VIEWPORT: { - - for(int i=1;i<4;i++) { - - viewports[i]->hide(); - } - - viewports[0]->set_area_as_parent_rect(); - - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), true ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); - - } break; - case MENU_VIEW_USE_2_VIEWPORTS: { - - for(int i=1;i<4;i++) { - - if (i==1 || i==3) - viewports[i]->hide(); - else - viewports[i]->show(); - - - } - viewports[0]->set_area_as_parent_rect(); - //viewports[0]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5); - viewports[2]->set_area_as_parent_rect(); - //viewports[2]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5); - - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), true ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); - - } break; - case MENU_VIEW_USE_2_VIEWPORTS_ALT: { - - for(int i=1;i<4;i++) { - - if (i==1 || i==3) - viewports[i]->hide(); - else - viewports[i]->show(); - - - } - viewports[0]->set_area_as_parent_rect(); - //viewports[0]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); - viewports[2]->set_area_as_parent_rect(); - //viewports[2]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5); - - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), true ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); - - } break; - case MENU_VIEW_USE_3_VIEWPORTS: { - - for(int i=1;i<4;i++) { - - if (i==1) - viewports[i]->hide(); - else - viewports[i]->show(); - } - viewports[0]->set_area_as_parent_rect(); - //viewports[0]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5); - viewports[2]->set_area_as_parent_rect(); - //viewports[2]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); - //viewports[2]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5); - viewports[3]->set_area_as_parent_rect(); - //viewports[3]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5); - //viewports[3]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5); - - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), true ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); - - } break; - case MENU_VIEW_USE_3_VIEWPORTS_ALT: { - - for(int i=1;i<4;i++) { - - if (i==1) - viewports[i]->hide(); - else - viewports[i]->show(); - } - viewports[0]->set_area_as_parent_rect(); - //viewports[0]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5); - //viewports[0]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); - viewports[2]->set_area_as_parent_rect(); - //viewports[2]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5); - //viewports[2]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); - viewports[3]->set_area_as_parent_rect(); - //viewports[3]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5); - - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), true ); - - } break; - case MENU_VIEW_USE_4_VIEWPORTS: { - - for(int i=1;i<4;i++) { - - viewports[i]->show(); - } - viewports[0]->set_area_as_parent_rect(); - //viewports[0]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); - //viewports[0]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5); - viewports[1]->set_area_as_parent_rect(); - //viewports[1]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5); - //viewports[1]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5); - viewports[2]->set_area_as_parent_rect(); - //viewports[2]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5); - //viewports[2]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5); - viewports[3]->set_area_as_parent_rect(); - //viewports[3]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5); - //viewports[3]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5); - - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS), true ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false ); - - } break; - case MENU_VIEW_DISPLAY_NORMAL: { - - - VisualServer::get_singleton()->scenario_set_debug( get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_DISABLED ); - - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), true ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), false ); - - } break; - case MENU_VIEW_DISPLAY_WIREFRAME: { - - VisualServer::get_singleton()->scenario_set_debug( get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_WIREFRAME ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), true ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), false ); - - } break; - case MENU_VIEW_DISPLAY_OVERDRAW: { - - VisualServer::get_singleton()->scenario_set_debug( get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_OVERDRAW ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), true ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), false ); - - } break; - case MENU_VIEW_DISPLAY_SHADELESS: { - - VisualServer::get_singleton()->scenario_set_debug( get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_SHADELESS ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), false ); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), true ); - - } break; - case MENU_VIEW_ORIGIN: { - - bool is_checked = view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(p_option) ); - - is_checked=!is_checked; - VisualServer::get_singleton()->instance_set_visible(origin_instance,is_checked); - - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(p_option), is_checked); - } break; - case MENU_VIEW_GRID: { - - bool is_checked = view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(p_option) ); - - grid_enabled=!is_checked; - - for(int i=0;i<3;++i) { - if (grid_enable[i]) { - VisualServer::get_singleton()->instance_set_visible(grid_instance[i],grid_enabled); - grid_visible[i]=grid_enabled; - } - } - - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(p_option), grid_enabled ); - - - } break; - case MENU_VIEW_CAMERA_SETTINGS: { - - settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size()+Size2(50,50)); - } break; - - } -} - - -void SpatialEditor::_init_indicators() { - - //make sure that the camera indicator is not selectable - light=VisualServer::get_singleton()->light_create( VisualServer::LIGHT_DIRECTIONAL ); - //VisualServer::get_singleton()->light_set_shadow( light, true ); - light_instance=VisualServer::get_singleton()->instance_create2(light,get_tree()->get_root()->get_world()->get_scenario()); - - - - light_transform.rotate(Vector3(1,0,0),-Math_PI/5.0); - VisualServer::get_singleton()->instance_set_transform(light_instance,light_transform); - - - //RID mat = VisualServer::get_singleton()->fixed_material_create(); - ///VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA,true); - //VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true); - - - { - - indicator_mat.instance(); - indicator_mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED,true); - //indicator_mat->set_flag(FixedSpatialMaterial::FLAG_ONTOP,true); - indicator_mat->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR,true); - indicator_mat->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR,true); - - indicator_mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT,true); - - PoolVector<Color> grid_colors[3]; - PoolVector<Vector3> grid_points[3]; - Vector<Color> origin_colors; - Vector<Vector3> origin_points; - - Color grid_color = EditorSettings::get_singleton()->get("editors/3d/grid_color"); - - for(int i=0;i<3;i++) { - Vector3 axis; - axis[i]=1; - Vector3 axis_n1; - axis_n1[(i+1)%3]=1; - Vector3 axis_n2; - axis_n2[(i+2)%3]=1; - - origin_colors.push_back(Color(axis.x,axis.y,axis.z)); - origin_colors.push_back(Color(axis.x,axis.y,axis.z)); - origin_points.push_back(axis*4096); - origin_points.push_back(axis*-4096); -#define ORIGIN_GRID_SIZE 25 - - for(int j=-ORIGIN_GRID_SIZE;j<=ORIGIN_GRID_SIZE;j++) { - - - grid_colors[i].push_back(grid_color); - grid_colors[i].push_back(grid_color); - grid_colors[i].push_back(grid_color); - grid_colors[i].push_back(grid_color); - grid_points[i].push_back(axis_n1*ORIGIN_GRID_SIZE+axis_n2*j); - grid_points[i].push_back(-axis_n1*ORIGIN_GRID_SIZE+axis_n2*j); - grid_points[i].push_back(axis_n2*ORIGIN_GRID_SIZE+axis_n1*j); - grid_points[i].push_back(-axis_n2*ORIGIN_GRID_SIZE+axis_n1*j); - - } - - grid[i] = VisualServer::get_singleton()->mesh_create(); - Array d; - d.resize(VS::ARRAY_MAX); - d[VisualServer::ARRAY_VERTEX]=grid_points[i]; - d[VisualServer::ARRAY_COLOR]=grid_colors[i]; - VisualServer::get_singleton()->mesh_add_surface_from_arrays(grid[i],VisualServer::PRIMITIVE_LINES,d); - VisualServer::get_singleton()->mesh_surface_set_material(grid[i],0,indicator_mat->get_rid()); - grid_instance[i] = VisualServer::get_singleton()->instance_create2(grid[i],get_tree()->get_root()->get_world()->get_scenario()); - - grid_visible[i]=false; - grid_enable[i]=false; - VisualServer::get_singleton()->instance_set_visible(grid_instance[i],false); - VisualServer::get_singleton()->instance_geometry_set_cast_shadows_setting(grid_instance[i], VS::SHADOW_CASTING_SETTING_OFF); - VS::get_singleton()->instance_set_layer_mask(grid_instance[i], 1 << SpatialEditorViewport::GIZMO_GRID_LAYER); - - - } - - origin = VisualServer::get_singleton()->mesh_create(); - Array d; - d.resize(VS::ARRAY_MAX); - d[VisualServer::ARRAY_VERTEX]=origin_points; - d[VisualServer::ARRAY_COLOR]=origin_colors; - - VisualServer::get_singleton()->mesh_add_surface_from_arrays(origin,VisualServer::PRIMITIVE_LINES,d); - VisualServer::get_singleton()->mesh_surface_set_material(origin,0,indicator_mat->get_rid()); - - - //origin = VisualServer::get_singleton()->poly_create(); - //VisualServer::get_singleton()->poly_add_primitive(origin,origin_points,Vector<Vector3>(),origin_colors,Vector<Vector3>()); - //VisualServer::get_singleton()->poly_set_material(origin,indicator_mat,true); - origin_instance = VisualServer::get_singleton()->instance_create2(origin,get_tree()->get_root()->get_world()->get_scenario()); - VS::get_singleton()->instance_set_layer_mask(origin_instance,1<<SpatialEditorViewport::GIZMO_GRID_LAYER); - - VisualServer::get_singleton()->instance_geometry_set_cast_shadows_setting(origin_instance, VS::SHADOW_CASTING_SETTING_OFF); - - - - VisualServer::get_singleton()->instance_set_visible(grid_instance[1],true); - grid_enable[1]=true; - grid_visible[1]=true; - grid_enabled=true; - last_grid_snap=1; - - } - - { - cursor_mesh = VisualServer::get_singleton()->mesh_create(); - PoolVector<Vector3> cursor_points; - float cs = 0.25; - cursor_points.push_back(Vector3(+cs,0,0)); - cursor_points.push_back(Vector3(-cs,0,0)); - cursor_points.push_back(Vector3(0,+cs,0)); - cursor_points.push_back(Vector3(0,-cs,0)); - cursor_points.push_back(Vector3(0,0,+cs)); - cursor_points.push_back(Vector3(0,0,-cs)); - cursor_material.instance(); - cursor_material->set_albedo(Color(0,1,1)); - cursor_material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED,true); - - Array d; - d.resize(VS::ARRAY_MAX); - d[VS::ARRAY_VERTEX]=cursor_points; - VisualServer::get_singleton()->mesh_add_surface_from_arrays(cursor_mesh,VS::PRIMITIVE_LINES,d); - VisualServer::get_singleton()->mesh_surface_set_material(cursor_mesh,0,cursor_material->get_rid()); - - cursor_instance = VisualServer::get_singleton()->instance_create2(cursor_mesh,get_tree()->get_root()->get_world()->get_scenario()); - VS::get_singleton()->instance_set_layer_mask(cursor_instance,1<<SpatialEditorViewport::GIZMO_GRID_LAYER); - - VisualServer::get_singleton()->instance_geometry_set_cast_shadows_setting(cursor_instance, VS::SHADOW_CASTING_SETTING_OFF); - - - } - - - { - - //move gizmo - - - float gizmo_alph = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_opacity"); - - gizmo_hl = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ) ); - gizmo_hl->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true); - gizmo_hl->set_flag(FixedSpatialMaterial::FLAG_ONTOP, true); - gizmo_hl->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true); - gizmo_hl->set_albedo(Color(1,1,1,gizmo_alph+0.2f)); - - for(int i=0;i<3;i++) { - - move_gizmo[i]=Ref<Mesh>( memnew( Mesh ) ); - rotate_gizmo[i]=Ref<Mesh>( memnew( Mesh ) ); - - - Ref<FixedSpatialMaterial> mat = memnew( FixedSpatialMaterial ); - mat->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true); - mat->set_flag(FixedSpatialMaterial::FLAG_ONTOP, true); - mat->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true); - Color col; - col[i]=1.0; - col.a= gizmo_alph; - mat->set_albedo(col); - gizmo_color[i]=mat; - - - - - Vector3 ivec; - ivec[i]=1; - Vector3 nivec; - nivec[(i+1)%3]=1; - nivec[(i+2)%3]=1; - Vector3 ivec2; - ivec2[(i+1)%3]=1; - Vector3 ivec3; - ivec3[(i+2)%3]=1; - - - { - - Ref<SurfaceTool> surftool = memnew( SurfaceTool ); - surftool->begin(Mesh::PRIMITIVE_TRIANGLES); - - //translate - - const int arrow_points=5; - Vector3 arrow[5]={ - nivec*0.0+ivec*0.0, - nivec*0.01+ivec*0.0, - nivec*0.01+ivec*1.0, - nivec*0.1+ivec*1.0, - nivec*0.0+ivec*(1+GIZMO_ARROW_SIZE), - }; - - int arrow_sides=6; - - - for(int k = 0; k < 7 ; k++) { - - - Basis ma(ivec,Math_PI*2*float(k)/arrow_sides); - Basis mb(ivec,Math_PI*2*float(k+1)/arrow_sides); - - - for(int j=0;j<arrow_points-1;j++) { - - Vector3 points[4]={ - ma.xform(arrow[j]), - mb.xform(arrow[j]), - mb.xform(arrow[j+1]), - ma.xform(arrow[j+1]), - }; - surftool->add_vertex(points[0]); - surftool->add_vertex(points[1]); - surftool->add_vertex(points[2]); - - surftool->add_vertex(points[0]); - surftool->add_vertex(points[2]); - surftool->add_vertex(points[3]); - } - - } - - surftool->set_material(mat); - surftool->commit(move_gizmo[i]); - } - - { - - - Ref<SurfaceTool> surftool = memnew( SurfaceTool ); - surftool->begin(Mesh::PRIMITIVE_TRIANGLES); - - Vector3 circle[5]={ - ivec*0.02+ivec2*0.02+ivec2*1.0, - ivec*-0.02+ivec2*0.02+ivec2*1.0, - ivec*-0.02+ivec2*-0.02+ivec2*1.0, - ivec*0.02+ivec2*-0.02+ivec2*1.0, - ivec*0.02+ivec2*0.02+ivec2*1.0, - }; - - - for(int k = 0; k < 33 ; k++) { - - - Basis ma(ivec,Math_PI*2*float(k)/32); - Basis mb(ivec,Math_PI*2*float(k+1)/32); - - - for(int j=0;j<4;j++) { - - Vector3 points[4]={ - ma.xform(circle[j]), - mb.xform(circle[j]), - mb.xform(circle[j+1]), - ma.xform(circle[j+1]), - }; - surftool->add_vertex(points[0]); - surftool->add_vertex(points[1]); - surftool->add_vertex(points[2]); - - surftool->add_vertex(points[0]); - surftool->add_vertex(points[2]); - surftool->add_vertex(points[3]); - } - - } - - surftool->set_material(mat); - surftool->commit(rotate_gizmo[i]); - - } - - - } - } - - /*for(int i=0;i<4;i++) { - - viewports[i]->init_gizmo_instance(i); - }*/ - - _generate_selection_box(); - - - //get_scene()->get_root_node()->cast_to<EditorNode>()->get_scene_root()->add_child(camera); - - //current_camera=camera; - -} - -void SpatialEditor::_finish_indicators() { - - VisualServer::get_singleton()->free(origin_instance); - VisualServer::get_singleton()->free(origin); - for(int i=0;i<3;i++) { - VisualServer::get_singleton()->free(grid_instance[i]); - VisualServer::get_singleton()->free(grid[i]); - } - VisualServer::get_singleton()->free(light_instance); - VisualServer::get_singleton()->free(light); - //VisualServer::get_singleton()->free(poly); - //VisualServer::get_singleton()->free(indicators_instance); - //VisualServer::get_singleton()->free(indicators); - - VisualServer::get_singleton()->free(cursor_instance); - VisualServer::get_singleton()->free(cursor_mesh); -} - -void SpatialEditor::_instance_scene() { -#if 0 - EditorNode *en = get_scene()->get_root_node()->cast_to<EditorNode>(); - ERR_FAIL_COND(!en); - String path = en->get_filesystem_dock()->get_selected_path(); - if (path=="") { - set_message(TTR("No scene selected to instance!")); - return; - } - - undo_redo->create_action(TTR("Instance at Cursor")); - - Node* scene = en->request_instance_scene(path); - - if (!scene) { - set_message(TTR("Could not instance scene!")); - undo_redo->commit_action(); //bleh - return; - } - - Spatial *s = scene->cast_to<Spatial>(); - if (s) { - - undo_redo->add_do_method(s,"set_global_transform",Transform(Matrix3(),cursor.cursor_pos)); - } - - undo_redo->commit_action(); -#endif -} - -void SpatialEditor::_unhandled_key_input(InputEvent p_event) { - - if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack()) - return; - -#if 0 -//i don't remember this being used, why was it here? - { - - EditorNode *en = editor; - EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); - - if (!over_plugin_list->empty() && over_plugin_list->forward_gui_input(p_event)) { - - return; //ate the over input event - } - - } -#endif - - switch(p_event.type) { - - case InputEvent::KEY: { - - - const InputEventKey &k=p_event.key; - - if (!k.pressed) - break; - - switch(k.scancode) { - - case KEY_Q: _menu_item_pressed(MENU_TOOL_SELECT); break; - case KEY_W: _menu_item_pressed(MENU_TOOL_MOVE); break; - case KEY_E: _menu_item_pressed(MENU_TOOL_ROTATE); break; - case KEY_R: _menu_item_pressed(MENU_TOOL_SCALE); break; - - case KEY_Z: { - if (k.mod.shift || k.mod.control || k.mod.command) - break; - - if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME))) { - _menu_item_pressed(MENU_VIEW_DISPLAY_NORMAL); - } else { - _menu_item_pressed(MENU_VIEW_DISPLAY_WIREFRAME); - } - } break; - -#if 0 -#endif - } - - } break; - } -} -void SpatialEditor::_notification(int p_what) { - - if (p_what==NOTIFICATION_READY) { - - tool_button[SpatialEditor::TOOL_MODE_SELECT]->set_icon( get_icon("ToolSelect","EditorIcons") ); - tool_button[SpatialEditor::TOOL_MODE_MOVE]->set_icon( get_icon("ToolMove","EditorIcons") ); - tool_button[SpatialEditor::TOOL_MODE_ROTATE]->set_icon( get_icon("ToolRotate","EditorIcons") ); - tool_button[SpatialEditor::TOOL_MODE_SCALE]->set_icon( get_icon("ToolScale","EditorIcons") ); - tool_button[SpatialEditor::TOOL_MODE_LIST_SELECT]->set_icon( get_icon("ListSelect","EditorIcons") ); - instance_button->set_icon( get_icon("SpatialAdd","EditorIcons") ); - instance_button->hide(); - - - view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT),get_icon("Panels1","EditorIcons")); - view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS),get_icon("Panels2","EditorIcons")); - view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT),get_icon("Panels2Alt","EditorIcons")); - view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS),get_icon("Panels3","EditorIcons")); - view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT),get_icon("Panels3Alt","EditorIcons")); - view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS),get_icon("Panels4","EditorIcons")); - - _menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT); - - get_tree()->connect("node_removed",this,"_node_removed"); - VS::get_singleton()->scenario_set_fallback_environment(get_viewport()->find_world()->get_scenario(),viewport_environment->get_rid()); - - } - - if (p_what==NOTIFICATION_ENTER_TREE) { - - gizmos = memnew( SpatialEditorGizmos ); - _init_indicators(); - _update_default_light_angle(); - } - - if (p_what==NOTIFICATION_EXIT_TREE) { - - _finish_indicators(); - memdelete( gizmos ); - - } -} - -void SpatialEditor::add_control_to_menu_panel(Control *p_control) { - - - hbc_menu->add_child(p_control); -} - -void SpatialEditor::set_can_preview(Camera* p_preview) { - - for(int i=0;i<4;i++) { - viewports[i]->set_can_preview(p_preview); - } -} - -VSplitContainer *SpatialEditor::get_shader_split() { - - return shader_split; -} - -HSplitContainer *SpatialEditor::get_palette_split() { - - return palette_split; -} - - -void SpatialEditor::_request_gizmo(Object* p_obj) { - - Spatial *sp=p_obj->cast_to<Spatial>(); - if (!sp) - return; - if (editor->get_edited_scene() && (sp==editor->get_edited_scene() || sp->get_owner()==editor->get_edited_scene() || editor->get_edited_scene()->is_editable_instance(sp->get_owner()))) { - - Ref<SpatialEditorGizmo> seg; - - for(int i=0;i<EditorNode::get_singleton()->get_editor_data().get_editor_plugin_count();i++) { - - seg = EditorNode::get_singleton()->get_editor_data().get_editor_plugin(i)->create_spatial_gizmo(sp); - if (seg.is_valid()) - break; - } - - if (!seg.is_valid()) { - seg = gizmos->get_gizmo(sp); - } - - if (seg.is_valid()) { - sp->set_gizmo(seg); - } - - - if (seg.is_valid() && sp==selected) { - seg->set_selected(true); - selected->update_gizmo(); - } - - } -} - -void SpatialEditor::_toggle_maximize_view(Object* p_viewport) { - if (!p_viewport) return; - SpatialEditorViewport *current_viewport = p_viewport->cast_to<SpatialEditorViewport>(); - if (!current_viewport) return; - - int index=-1; - bool maximized = false; - for(int i=0;i<4;i++) { - if (viewports[i]==current_viewport) { - index=i; - if ( current_viewport->get_global_rect() == viewport_base->get_global_rect() ) - maximized=true; - break; - } - } - if (index==-1) return; - - if (!maximized) { - - for(int i=0;i<4;i++) { - if (i==index) - viewports[i]->set_area_as_parent_rect(); - else - viewports[i]->hide(); - } - } else { - - for(int i=0;i<4;i++) - viewports[i]->show(); - - if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT) )) - _menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT); - else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS) )) - _menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS); - else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT) )) - _menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS_ALT); - else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS) )) - _menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS); - else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT) )) - _menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS_ALT); - else if (view_menu->get_popup()->is_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS) )) - _menu_item_pressed(MENU_VIEW_USE_4_VIEWPORTS); - } - -} - - -void SpatialEditor::_node_removed(Node* p_node) { - - if (p_node==selected) - selected=NULL; -} - -void SpatialEditor::_bind_methods() { - - //ClassDB::bind_method("_gui_input",&SpatialEditor::_gui_input); - ClassDB::bind_method("_unhandled_key_input",&SpatialEditor::_unhandled_key_input); - ClassDB::bind_method("_node_removed",&SpatialEditor::_node_removed); - ClassDB::bind_method("_menu_item_pressed",&SpatialEditor::_menu_item_pressed); - ClassDB::bind_method("_xform_dialog_action",&SpatialEditor::_xform_dialog_action); - ClassDB::bind_method("_instance_scene",&SpatialEditor::_instance_scene); - ClassDB::bind_method("_get_editor_data",&SpatialEditor::_get_editor_data); - ClassDB::bind_method("_request_gizmo",&SpatialEditor::_request_gizmo); - ClassDB::bind_method("_default_light_angle_input",&SpatialEditor::_default_light_angle_input); - ClassDB::bind_method("_update_ambient_light_color",&SpatialEditor::_update_ambient_light_color); - ClassDB::bind_method("_toggle_maximize_view",&SpatialEditor::_toggle_maximize_view); - - ADD_SIGNAL( MethodInfo("transform_key_request") ); - - -} - -void SpatialEditor::clear() { - - settings_fov->set_value(EDITOR_DEF("editors/3d/default_fov",60.0)); - settings_znear->set_value(EDITOR_DEF("editors/3d/default_z_near",0.1)); - settings_zfar->set_value(EDITOR_DEF("editors/3d/default_z_far",1500.0)); - - for(int i=0;i<4;i++) { - viewports[i]->reset(); - } - - _menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT); - _menu_item_pressed(MENU_VIEW_DISPLAY_NORMAL); - - - VisualServer::get_singleton()->instance_set_visible(origin_instance,true); - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN), true); - for(int i=0;i<3;++i) { - if (grid_enable[i]) { - VisualServer::get_singleton()->instance_set_visible(grid_instance[i],true); - grid_visible[i]=true; - } - } - - for(int i=0;i<4;i++) { - - viewports[i]->view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(SpatialEditorViewport::VIEW_AUDIO_LISTENER),i==0); - viewports[i]->viewport->set_as_audio_listener(i==0); - } - - view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_GRID), true ); - - settings_default_light_rot_x=Math_PI*0.3; - settings_default_light_rot_y=Math_PI*0.2; - - //viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,Color(0.15,0.15,0.15)); - settings_ambient_color->set_pick_color(Color(0.15,0.15,0.15)); - if (!light_instance.is_valid()) - _menu_item_pressed(MENU_VIEW_USE_DEFAULT_LIGHT); - - _update_default_light_angle(); - - -} - - -void SpatialEditor::_update_ambient_light_color(const Color& p_color) { - - //viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,settings_ambient_color->get_color()); - -} - -void SpatialEditor::_update_default_light_angle() { - - Transform t; - t.basis.rotate(Vector3(1,0,0),-settings_default_light_rot_x); - t.basis.rotate(Vector3(0,1,0),-settings_default_light_rot_y); - settings_dlight->set_transform(t); - if (light_instance.is_valid()) { - VS::get_singleton()->instance_set_transform(light_instance,t); - } - -} - -void SpatialEditor::_default_light_angle_input(const InputEvent& p_event) { - - - if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&(0x1|0x2|0x4)) { - - settings_default_light_rot_y = Math::fposmod(settings_default_light_rot_y - p_event.mouse_motion.relative_x*0.01,Math_PI*2.0); - settings_default_light_rot_x = Math::fposmod(settings_default_light_rot_x - p_event.mouse_motion.relative_y*0.01,Math_PI*2.0); - _update_default_light_angle(); - } - -} - - -SpatialEditor::SpatialEditor(EditorNode *p_editor) { - - gizmo.visible=true; - gizmo.scale=1.0; - - viewport_environment = Ref<Environment>( memnew( Environment ) ); - undo_redo=p_editor->get_undo_redo(); - VBoxContainer *vbc = this; - - custom_camera=NULL; - singleton=this; - editor=p_editor; - editor_selection=editor->get_editor_selection(); - editor_selection->add_editor_plugin(this); - - snap_enabled=false; - tool_mode = TOOL_MODE_SELECT; - - //set_focus_mode(FOCUS_ALL); - - hbc_menu = memnew( HBoxContainer ); - vbc->add_child(hbc_menu); - - - Vector<Variant> button_binds; - button_binds.resize(1); - - tool_button[TOOL_MODE_SELECT] = memnew( ToolButton ); - hbc_menu->add_child( tool_button[TOOL_MODE_SELECT] ); - tool_button[TOOL_MODE_SELECT]->set_toggle_mode(true); - tool_button[TOOL_MODE_SELECT]->set_flat(true); - tool_button[TOOL_MODE_SELECT]->set_pressed(true); - button_binds[0]=MENU_TOOL_SELECT; - tool_button[TOOL_MODE_SELECT]->connect("pressed", this,"_menu_item_pressed",button_binds); - tool_button[TOOL_MODE_SELECT]->set_tooltip("Select Mode (Q)\n"+keycode_get_string(KEY_MASK_CMD)+"Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"); - - - tool_button[TOOL_MODE_MOVE] = memnew( ToolButton ); - - hbc_menu->add_child( tool_button[TOOL_MODE_MOVE] ); - tool_button[TOOL_MODE_MOVE]->set_toggle_mode(true); - tool_button[TOOL_MODE_MOVE]->set_flat(true); - button_binds[0]=MENU_TOOL_MOVE; - tool_button[TOOL_MODE_MOVE]->connect("pressed", this,"_menu_item_pressed",button_binds); - tool_button[TOOL_MODE_MOVE]->set_tooltip(TTR("Move Mode (W)")); - - tool_button[TOOL_MODE_ROTATE] = memnew( ToolButton ); - hbc_menu->add_child( tool_button[TOOL_MODE_ROTATE] ); - tool_button[TOOL_MODE_ROTATE]->set_toggle_mode(true); - tool_button[TOOL_MODE_ROTATE]->set_flat(true); - button_binds[0]=MENU_TOOL_ROTATE; - tool_button[TOOL_MODE_ROTATE]->connect("pressed", this,"_menu_item_pressed",button_binds); - tool_button[TOOL_MODE_ROTATE]->set_tooltip(TTR("Rotate Mode (E)")); - - tool_button[TOOL_MODE_SCALE] = memnew( ToolButton ); - hbc_menu->add_child( tool_button[TOOL_MODE_SCALE] ); - tool_button[TOOL_MODE_SCALE]->set_toggle_mode(true); - tool_button[TOOL_MODE_SCALE]->set_flat(true); - button_binds[0]=MENU_TOOL_SCALE; - tool_button[TOOL_MODE_SCALE]->connect("pressed", this,"_menu_item_pressed",button_binds); - tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)")); - - instance_button = memnew( Button ); - hbc_menu->add_child( instance_button ); - instance_button->set_flat(true); - instance_button->connect("pressed",this,"_instance_scene"); - instance_button->hide(); - - VSeparator *vs = memnew( VSeparator ); - hbc_menu->add_child(vs); - - tool_button[TOOL_MODE_LIST_SELECT] = memnew( ToolButton ); - hbc_menu->add_child( tool_button[TOOL_MODE_LIST_SELECT] ); - tool_button[TOOL_MODE_LIST_SELECT]->set_toggle_mode(true); - tool_button[TOOL_MODE_LIST_SELECT]->set_flat(true); - button_binds[0]=MENU_TOOL_LIST_SELECT; - tool_button[TOOL_MODE_LIST_SELECT]->connect("pressed", this,"_menu_item_pressed",button_binds); - tool_button[TOOL_MODE_LIST_SELECT]->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode).")); - - vs = memnew( VSeparator ); - hbc_menu->add_child(vs); - - - ED_SHORTCUT("spatial_editor/bottom_view", TTR("Bottom View"), KEY_MASK_ALT+KEY_KP_7); - ED_SHORTCUT("spatial_editor/top_view", TTR("Top View"), KEY_KP_7); - ED_SHORTCUT("spatial_editor/rear_view", TTR("Rear View"), KEY_MASK_ALT+KEY_KP_1); - ED_SHORTCUT("spatial_editor/front_view", TTR("Front View"), KEY_KP_1); - ED_SHORTCUT("spatial_editor/left_view", TTR("Left View"), KEY_MASK_ALT+KEY_KP_3); - ED_SHORTCUT("spatial_editor/right_view", TTR("Right View"), KEY_KP_3); - ED_SHORTCUT("spatial_editor/switch_perspective_orthogonal", TTR("Switch Perspective/Orthogonal view"), KEY_KP_5); - ED_SHORTCUT("spatial_editor/snap", TTR("Snap"), KEY_S); - ED_SHORTCUT("spatial_editor/insert_anim_key", TTR("Insert Animation Key"), KEY_K); - ED_SHORTCUT("spatial_editor/focus_origin", TTR("Focus Origin"), KEY_O); - ED_SHORTCUT("spatial_editor/focus_selection", TTR("Focus Selection"), KEY_F); - ED_SHORTCUT("spatial_editor/align_selection_with_view", TTR("Align Selection With View"), KEY_MASK_ALT+KEY_MASK_CMD+KEY_F); - - - PopupMenu *p; - - transform_menu = memnew( MenuButton ); - transform_menu->set_text(TTR("Transform")); - hbc_menu->add_child( transform_menu ); - - p = transform_menu->get_popup(); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/use_snap", TTR("Use Snap")), MENU_TRANSFORM_USE_SNAP); - p->add_shortcut(ED_SHORTCUT("spatial_editor/configure_snap", TTR("Configure Snap..")), MENU_TRANSFORM_CONFIGURE_SNAP); - p->add_separator(); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/local_coords", TTR("Local Coords")), MENU_TRANSFORM_LOCAL_COORDS); - //p->set_item_checked(p->get_item_count()-1,true); - p->add_separator(); - p->add_shortcut(ED_SHORTCUT("spatial_editor/transform_dialog", TTR("Transform Dialog..")), MENU_TRANSFORM_DIALOG); - - p->connect("id_pressed", this,"_menu_item_pressed"); - - view_menu = memnew( MenuButton ); - view_menu->set_text(TTR("View")); - view_menu->set_pos( Point2( 212,0) ); - hbc_menu->add_child( view_menu ); - - p = view_menu->get_popup(); - - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/use_default_light", TTR("Use Default Light")), MENU_VIEW_USE_DEFAULT_LIGHT); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/use_default_srgb", TTR("Use Default sRGB")), MENU_VIEW_USE_DEFAULT_SRGB); - p->add_separator(); - - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/1_viewport", TTR("1 Viewport"), KEY_MASK_CMD+KEY_1), MENU_VIEW_USE_1_VIEWPORT); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports", TTR("2 Viewports"), KEY_MASK_CMD+KEY_2), MENU_VIEW_USE_2_VIEWPORTS); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports_alt", TTR("2 Viewports (Alt)"), KEY_MASK_ALT+KEY_MASK_CMD+KEY_2), MENU_VIEW_USE_2_VIEWPORTS_ALT); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/3_viewports", TTR("3 Viewports"),KEY_MASK_CMD+KEY_3), MENU_VIEW_USE_3_VIEWPORTS); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/3_viewports_alt", TTR("3 Viewports (Alt)"), KEY_MASK_ALT+KEY_MASK_CMD+KEY_3), MENU_VIEW_USE_3_VIEWPORTS_ALT); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/4_viewports", TTR("4 Viewports"), KEY_MASK_CMD+KEY_4), MENU_VIEW_USE_4_VIEWPORTS); - p->add_separator(); - - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_normal", TTR("Display Normal")), MENU_VIEW_DISPLAY_NORMAL); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_wireframe", TTR("Display Wireframe")), MENU_VIEW_DISPLAY_WIREFRAME); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_overdraw", TTR("Display Overdraw")), MENU_VIEW_DISPLAY_OVERDRAW); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_shadeless", TTR("Display Shadeless")), MENU_VIEW_DISPLAY_SHADELESS); - p->add_separator(); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_origin", TTR("View Origin")), MENU_VIEW_ORIGIN); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_grid", TTR("View Grid")), MENU_VIEW_GRID); - p->add_separator(); - p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings")), MENU_VIEW_CAMERA_SETTINGS); - - - p->set_item_checked( p->get_item_index(MENU_VIEW_USE_DEFAULT_LIGHT), true ); - p->set_item_checked( p->get_item_index(MENU_VIEW_DISPLAY_NORMAL), true ); - p->set_item_checked( p->get_item_index(MENU_VIEW_ORIGIN), true ); - p->set_item_checked( p->get_item_index(MENU_VIEW_GRID), true ); - - - p->connect("id_pressed", this,"_menu_item_pressed"); - - - /* REST OF MENU */ - - palette_split = memnew( HSplitContainer); - palette_split->set_v_size_flags(SIZE_EXPAND_FILL); - vbc->add_child(palette_split); - - shader_split = memnew( VSplitContainer ); - shader_split->set_h_size_flags(SIZE_EXPAND_FILL); - palette_split->add_child(shader_split); - viewport_base = memnew( Control ); - shader_split->add_child(viewport_base); - viewport_base->set_v_size_flags(SIZE_EXPAND_FILL); - for(int i=0;i<4;i++) { - - viewports[i] = memnew( SpatialEditorViewport(this,editor,i) ); - viewports[i]->connect("toggle_maximize_view",this,"_toggle_maximize_view"); - viewport_base->add_child(viewports[i]); - } - //vbc->add_child(viewport_base); - - - - - /* SNAP DIALOG */ - - snap_dialog = memnew( ConfirmationDialog ); - snap_dialog->set_title(TTR("Snap Settings")); - add_child(snap_dialog); - - VBoxContainer *snap_dialog_vbc = memnew( VBoxContainer ); - snap_dialog->add_child(snap_dialog_vbc); - //snap_dialog->set_child_rect(snap_dialog_vbc); - - snap_translate = memnew( LineEdit ); - snap_translate->set_text("1"); - snap_dialog_vbc->add_margin_child(TTR("Translate Snap:"),snap_translate); - - snap_rotate = memnew( LineEdit ); - snap_rotate->set_text("5"); - snap_dialog_vbc->add_margin_child(TTR("Rotate Snap (deg.):"),snap_rotate); - - snap_scale = memnew( LineEdit ); - snap_scale->set_text("5"); - snap_dialog_vbc->add_margin_child(TTR("Scale Snap (%):"),snap_scale); - - /* SETTINGS DIALOG */ - - settings_dialog = memnew( ConfirmationDialog ); - settings_dialog->set_title(TTR("Viewport Settings")); - add_child(settings_dialog); - settings_vbc = memnew( VBoxContainer ); - settings_vbc->set_custom_minimum_size(Size2(200,0)); - settings_dialog->add_child(settings_vbc); - //settings_dialog->set_child_rect(settings_vbc); - - - - settings_light_base = memnew( ViewportContainer ); - settings_light_base->set_custom_minimum_size(Size2(128,128)); - settings_light_base->connect("gui_input",this,"_default_light_angle_input"); - settings_vbc->add_margin_child(TTR("Default Light Normal:"),settings_light_base); - settings_light_vp = memnew( Viewport ); - settings_light_vp->set_disable_input(true); - settings_light_vp->set_use_own_world(true); - settings_light_base->add_child(settings_light_vp); - - settings_dlight = memnew( DirectionalLight ); - settings_light_vp->add_child(settings_dlight); - settings_sphere = memnew( ImmediateGeometry ); - settings_sphere->begin(Mesh::PRIMITIVE_TRIANGLES,Ref<Texture>()); - settings_sphere->set_color(Color(1,1,1)); - settings_sphere->add_sphere(32,16,1); - settings_sphere->end(); - settings_light_vp->add_child(settings_sphere); - settings_camera = memnew( Camera ); - settings_light_vp->add_child(settings_camera); - settings_camera->set_translation(Vector3(0,0,2)); - settings_camera->set_orthogonal(2.1,0.1,5); - - settings_default_light_rot_x=Math_PI*0.3; - settings_default_light_rot_y=Math_PI*0.2; - - - - settings_ambient_color = memnew( ColorPickerButton ); - settings_vbc->add_margin_child(TTR("Ambient Light Color:"),settings_ambient_color); - settings_ambient_color->connect("color_changed",this,"_update_ambient_light_color"); - settings_ambient_color->set_pick_color(Color(0.15,0.15,0.15)); - - - settings_fov = memnew( SpinBox ); - settings_fov->set_max(179); - settings_fov->set_min(1); - settings_fov->set_step(0.01); - settings_fov->set_value(EDITOR_DEF("editors/3d/default_fov",60.0)); - settings_vbc->add_margin_child(TTR("Perspective FOV (deg.):"),settings_fov); - - settings_znear = memnew( SpinBox ); - settings_znear->set_max(10000); - settings_znear->set_min(0.1); - settings_znear->set_step(0.01); - settings_znear->set_value(EDITOR_DEF("editors/3d/default_z_near",0.1)); - settings_vbc->add_margin_child(TTR("View Z-Near:"),settings_znear); - - settings_zfar = memnew( SpinBox ); - settings_zfar->set_max(10000); - settings_zfar->set_min(0.1); - settings_zfar->set_step(0.01); - settings_zfar->set_value(EDITOR_DEF("editors/3d/default_z_far",1500)); - settings_vbc->add_margin_child(TTR("View Z-Far:"),settings_zfar); - - //settings_dialog->get_cancel()->hide(); - /* XFORM DIALOG */ - - xform_dialog = memnew( ConfirmationDialog ); - xform_dialog->set_title(TTR("Transform Change")); - add_child(xform_dialog); - Label *l = memnew(Label); - l->set_text(TTR("Translate:")); - l->set_pos(Point2(5,5)); - xform_dialog->add_child(l); - - for(int i=0;i<3;i++) { - - xform_translate[i] = memnew( LineEdit ); - xform_translate[i]->set_pos( Point2(15+i*60,22) ); - xform_translate[i]->set_size( Size2(50,12 ) ); - xform_dialog->add_child( xform_translate[i] ); - } - - l = memnew(Label); - l->set_text(TTR("Rotate (deg.):")); - l->set_pos(Point2(5,45)); - xform_dialog->add_child(l); - - for(int i=0;i<3;i++) { - xform_rotate[i] = memnew( LineEdit ); - xform_rotate[i]->set_pos( Point2(15+i*60,62) ); - xform_rotate[i]->set_size( Size2(50,22 ) ); - xform_dialog->add_child(xform_rotate[i]); - } - - l = memnew(Label); - l->set_text(TTR("Scale (ratio):")); - l->set_pos(Point2(5,85)); - xform_dialog->add_child(l); - - for(int i=0;i<3;i++) { - xform_scale[i] = memnew( LineEdit ); - xform_scale[i]->set_pos( Point2(15+i*60,102) ); - xform_scale[i]->set_size( Size2(50,22 ) ); - xform_dialog->add_child(xform_scale[i]); - } - - l = memnew(Label); - l->set_text(TTR("Transform Type")); - l->set_pos(Point2(5,125)); - xform_dialog->add_child(l); - - xform_type = memnew( OptionButton ); - xform_type->set_anchor( MARGIN_RIGHT, ANCHOR_END ); - xform_type->set_begin( Point2(15,142) ); - xform_type->set_end( Point2(15,75) ); - xform_type->add_item(TTR("Pre")); - xform_type->add_item(TTR("Post")); - xform_dialog->add_child(xform_type); - - xform_dialog->connect("confirmed", this,"_xform_dialog_action"); - - scenario_debug=VisualServer::SCENARIO_DEBUG_DISABLED; - - selected=NULL; - - set_process_unhandled_key_input(true); - add_to_group("_spatial_editor_group"); - - EDITOR_DEF("editors/3d/manipulator_gizmo_size",80); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT,"editors/3d/manipulator_gizmo_size",PROPERTY_HINT_RANGE,"16,1024,1")); - EDITOR_DEF("editors/3d/manipulator_gizmo_opacity",0.2); - - over_gizmo_handle=-1; -} - -SpatialEditor::~SpatialEditor() { - - -} - - - - -void SpatialEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - - - spatial_editor->show(); - spatial_editor->set_process(true); - //VisualServer::get_singleton()->viewport_set_hide_scenario(editor->get_scene_root()->get_viewport(),false); - spatial_editor->grab_focus(); - - } else { - - spatial_editor->hide(); - spatial_editor->set_process(false); - //VisualServer::get_singleton()->viewport_set_hide_scenario(editor->get_scene_root()->get_viewport(),true); - - } - -} -void SpatialEditorPlugin::edit(Object *p_object) { - - spatial_editor->edit(p_object->cast_to<Spatial>()); -} - -bool SpatialEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("Spatial"); -} - -Dictionary SpatialEditorPlugin::get_state() const { - return spatial_editor->get_state(); -} - -void SpatialEditorPlugin::set_state(const Dictionary& p_state) { - - spatial_editor->set_state(p_state); -} - -void SpatialEditor::snap_cursor_to_plane(const Plane& p_plane) { - - //cursor.pos=p_plane.project(cursor.pos); -} - -void SpatialEditorPlugin::_bind_methods() { - - ClassDB::bind_method("snap_cursor_to_plane",&SpatialEditorPlugin::snap_cursor_to_plane); - -} - -void SpatialEditorPlugin::snap_cursor_to_plane(const Plane& p_plane) { - - - spatial_editor->snap_cursor_to_plane(p_plane); -} - - - - -SpatialEditorPlugin::SpatialEditorPlugin(EditorNode *p_node) { - - editor=p_node; - spatial_editor = memnew( SpatialEditor(p_node) ); - spatial_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); - editor->get_viewport()->add_child(spatial_editor); - - //spatial_editor->set_area_as_parent_rect(); - spatial_editor->hide(); - spatial_editor->connect("transform_key_request",editor,"_transform_keyed"); - - //spatial_editor->set_process(true); -} - - -SpatialEditorPlugin::~SpatialEditorPlugin() { - -} diff --git a/tools/editor/plugins/spatial_editor_plugin.h b/tools/editor/plugins/spatial_editor_plugin.h deleted file mode 100644 index 36f807c11f..0000000000 --- a/tools/editor/plugins/spatial_editor_plugin.h +++ /dev/null @@ -1,574 +0,0 @@ -/*************************************************************************/ -/* spatial_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef SPATIAL_EDITOR_PLUGIN_H -#define SPATIAL_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/3d/visual_instance.h" -#include "scene/3d/immediate_geometry.h" -#include "scene/3d/light.h" -#include "scene/gui/panel_container.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -class Camera; -class SpatialEditor; -class SpatialEditorGizmos; - -class SpatialEditorGizmo : public SpatialGizmo { - - GDCLASS(SpatialEditorGizmo,SpatialGizmo); - - bool selected; -public: - - void set_selected(bool p_selected) { selected=p_selected; } - bool is_selected() const { return selected; } - - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); - virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); - - virtual bool intersect_frustum(const Camera *p_camera,const Vector<Plane> &p_frustum); - virtual bool intersect_ray(const Camera *p_camera,const Point2& p_point, Vector3& r_pos, Vector3& r_normal,int *r_gizmo_handle=NULL,bool p_sec_first=false); - SpatialEditorGizmo(); -}; - - -class SpatialEditorViewport : public Control { - - GDCLASS( SpatialEditorViewport, Control ); -friend class SpatialEditor; - enum { - - VIEW_TOP, - VIEW_BOTTOM, - VIEW_LEFT, - VIEW_RIGHT, - VIEW_FRONT, - VIEW_REAR, - VIEW_CENTER_TO_ORIGIN, - VIEW_CENTER_TO_SELECTION, - VIEW_ALIGN_SELECTION_WITH_VIEW, - VIEW_PERSPECTIVE, - VIEW_ENVIRONMENT, - VIEW_ORTHOGONAL, - VIEW_AUDIO_LISTENER, - VIEW_GIZMOS, - }; -public: - enum { - GIZMO_BASE_LAYER=27, - GIZMO_EDIT_LAYER=26, - GIZMO_GRID_LAYER=25 - }; -private: - int index; - String name; - void _menu_option(int p_option); - Size2 prev_size; - - EditorNode *editor; - EditorSelection *editor_selection; - UndoRedo *undo_redo; - - Button *preview_camera; - - MenuButton *view_menu; - - Control *surface; - Viewport *viewport; - Camera *camera; - bool transforming; - bool orthogonal; - float gizmo_scale; - - struct _RayResult { - - Spatial* item; - float depth; - int handle; - _FORCE_INLINE_ bool operator<(const _RayResult& p_rr) const { return depth<p_rr.depth; } - }; - - void _update_name(); - void _compute_edit(const Point2& p_point); - void _clear_selected(); - void _select_clicked(bool p_append,bool p_single); - void _select(Spatial *p_node, bool p_append,bool p_single); - ObjectID _select_ray(const Point2& p_pos, bool p_append,bool &r_includes_current,int *r_gizmo_handle=NULL,bool p_alt_select=false); - void _find_items_at_pos(const Point2& p_pos,bool &r_includes_current,Vector<_RayResult> &results,bool p_alt_select=false); - Vector3 _get_ray_pos(const Vector2& p_pos) const; - Vector3 _get_ray(const Vector2& p_pos); - Point2 _point_to_screen(const Vector3& p_point); - Transform _get_camera_transform() const; - int get_selected_count() const; - - Vector3 _get_camera_pos() const; - Vector3 _get_camera_normal() const; - Vector3 _get_screen_to_space(const Vector3& p_vector3); - - void _select_region(); - bool _gizmo_select(const Vector2& p_screenpos,bool p_hilite_only=false); - - float get_znear() const; - float get_zfar() const; - float get_fov() const; - - ObjectID clicked; - Vector<_RayResult> selection_results; - bool clicked_includes_current; - bool clicked_wants_append; - - PopupMenu *selection_menu; - - enum NavigationScheme { - NAVIGATION_GODOT, - NAVIGATION_MAYA, - NAVIGATION_MODO, - }; - - enum NavigationZoomStyle { - NAVIGATION_ZOOM_VERTICAL, - NAVIGATION_ZOOM_HORIZONTAL - }; - - enum NavigationMode { - NAVIGATION_NONE, - NAVIGATION_PAN, - NAVIGATION_ZOOM, - NAVIGATION_ORBIT - }; - enum TransformMode { - TRANSFORM_NONE, - TRANSFORM_ROTATE, - TRANSFORM_TRANSLATE, - TRANSFORM_SCALE - - }; - enum TransformPlane { - TRANSFORM_VIEW, - TRANSFORM_X_AXIS, - TRANSFORM_Y_AXIS, - TRANSFORM_Z_AXIS, - }; - - struct EditData { - TransformMode mode; - TransformPlane plane; - Transform original; - Vector3 click_ray; - Vector3 click_ray_pos; - Vector3 center; - Vector3 orig_gizmo_pos; - int edited_gizmo; - Point2 mouse_pos; - bool snap; - Ref<SpatialEditorGizmo> gizmo; - int gizmo_handle; - Variant gizmo_initial_value; - Vector3 gizmo_initial_pos; - } _edit; - - struct Cursor { - - Vector3 cursor_pos; - - Vector3 pos; - float x_rot,y_rot,distance; - bool region_select; - Point2 region_begin,region_end; - - Cursor() { x_rot=y_rot=0.5; distance=4; region_select=false; } - } cursor; - - RID move_gizmo_instance[3], rotate_gizmo_instance[3]; - - - String last_message; - String message; - float message_time; - - void set_message(String p_message,float p_time=5); - - // - void _update_camera(); - void _draw(); - - void _smouseenter(); - void _sinput(const InputEvent& p_ie); - SpatialEditor *spatial_editor; - - Camera* previewing; - Camera* preview; - - void _preview_exited_scene(); - void _toggle_camera_preview(bool); - void _init_gizmo_instance(int p_idx); - void _finish_gizmo_instances(); - void _selection_result_pressed(int); - void _selection_menu_hide(); - void _list_select(InputEventMouseButton b); - - -protected: - - void _notification(int p_what); - static void _bind_methods(); -public: - - void update_transform_gizmo_view(); - - void set_can_preview(Camera* p_preview); - void set_state(const Dictionary& p_state); - Dictionary get_state() const; - void reset(); - - void focus_selection(); - - Viewport *get_viewport_node() { return viewport; } - - - SpatialEditorViewport(SpatialEditor *p_spatial_editor,EditorNode *p_editor,int p_index); -}; - - - -class SpatialEditorSelectedItem : public Object { - - GDCLASS(SpatialEditorSelectedItem,Object); - -public: - - Rect3 aabb; - Transform original; // original location when moving - Transform last_xform; // last transform - Spatial *sp; - RID sbox_instance; - - SpatialEditorSelectedItem() { sp=NULL; } - ~SpatialEditorSelectedItem(); -}; - -class SpatialEditor : public VBoxContainer { - - GDCLASS(SpatialEditor, VBoxContainer ); -public: - - enum ToolMode { - - TOOL_MODE_SELECT, - TOOL_MODE_MOVE, - TOOL_MODE_ROTATE, - TOOL_MODE_SCALE, - TOOL_MODE_LIST_SELECT, - TOOL_MAX - - }; - - -private: - EditorNode *editor; - EditorSelection *editor_selection; - - - - Control *viewport_base; - SpatialEditorViewport *viewports[4]; - VSplitContainer *shader_split; - HSplitContainer *palette_split; - - ///// - - ToolMode tool_mode; - bool orthogonal; - - - VisualServer::ScenarioDebugMode scenario_debug; - - RID light; - RID light_instance; - Transform light_transform; - - - RID origin; - RID origin_instance; - RID grid[3]; - RID grid_instance[3]; - bool grid_visible[3]; //currently visible - float last_grid_snap; - bool grid_enable[3]; //should be always visible if true - bool grid_enabled; - - Ref<Mesh> move_gizmo[3], rotate_gizmo[3]; - Ref<FixedSpatialMaterial> gizmo_color[3]; - Ref<FixedSpatialMaterial> gizmo_hl; - - - int over_gizmo_handle; - - - - Ref<Mesh> selection_box; - RID indicators; - RID indicators_instance; - RID cursor_mesh; - RID cursor_instance; - Ref<FixedSpatialMaterial> indicator_mat; - Ref<FixedSpatialMaterial> cursor_material; - -/* - struct Selected { - AABB aabb; - Transform original; // original location when moving - Transform last_xform; // last transform - Spatial *sp; - RID poly_instance; - }; - - Map<uint32_t,Selected> selected; -*/ - struct Gizmo { - - bool visible; - float scale; - Transform transform; - } gizmo; - - - - - enum MenuOption { - - MENU_TOOL_SELECT, - MENU_TOOL_MOVE, - MENU_TOOL_ROTATE, - MENU_TOOL_SCALE, - MENU_TOOL_LIST_SELECT, - MENU_TRANSFORM_USE_SNAP, - MENU_TRANSFORM_CONFIGURE_SNAP, - MENU_TRANSFORM_LOCAL_COORDS, - MENU_TRANSFORM_DIALOG, - MENU_VIEW_USE_1_VIEWPORT, - MENU_VIEW_USE_2_VIEWPORTS, - MENU_VIEW_USE_2_VIEWPORTS_ALT, - MENU_VIEW_USE_3_VIEWPORTS, - MENU_VIEW_USE_3_VIEWPORTS_ALT, - MENU_VIEW_USE_4_VIEWPORTS, - MENU_VIEW_USE_DEFAULT_LIGHT, - MENU_VIEW_USE_DEFAULT_SRGB, - MENU_VIEW_DISPLAY_NORMAL, - MENU_VIEW_DISPLAY_WIREFRAME, - MENU_VIEW_DISPLAY_OVERDRAW, - MENU_VIEW_DISPLAY_SHADELESS, - MENU_VIEW_ORIGIN, - MENU_VIEW_GRID, - MENU_VIEW_CAMERA_SETTINGS, - - }; - - - Button *tool_button[TOOL_MAX]; - Button *instance_button; - - - MenuButton* transform_menu; - MenuButton* view_menu; - - ConfirmationDialog *snap_dialog; - ConfirmationDialog *xform_dialog; - ConfirmationDialog *settings_dialog; - - bool snap_enabled; - LineEdit *snap_translate; - LineEdit *snap_rotate; - LineEdit *snap_scale; - PanelContainer* menu_panel; - - LineEdit *xform_translate[3]; - LineEdit *xform_rotate[3]; - LineEdit *xform_scale[3]; - OptionButton *xform_type; - - VBoxContainer *settings_vbc; - SpinBox *settings_fov; - SpinBox *settings_znear; - SpinBox *settings_zfar; - DirectionalLight *settings_dlight; - ImmediateGeometry *settings_sphere; - Camera *settings_camera; - float settings_default_light_rot_x; - float settings_default_light_rot_y; - - ViewportContainer *settings_light_base; - Viewport *settings_light_vp; - ColorPickerButton *settings_ambient_color; - Image settings_light_dir_image; - - - void _xform_dialog_action(); - void _menu_item_pressed(int p_option); - - HBoxContainer *hbc_menu; - - - -// -// - void _generate_selection_box(); - UndoRedo *undo_redo; - - void _instance_scene(); - void _init_indicators(); - void _finish_indicators(); - - void _toggle_maximize_view(Object* p_viewport); - - Node *custom_camera; - - Object *_get_editor_data(Object *p_what); - - Ref<Environment> viewport_environment; - - Spatial *selected; - - void _request_gizmo(Object* p_obj); - - static SpatialEditor *singleton; - - void _node_removed(Node* p_node); - SpatialEditorGizmos *gizmos; - SpatialEditor(); - - void _update_ambient_light_color(const Color& p_color); - void _update_default_light_angle(); - void _default_light_angle_input(const InputEvent& p_event); - -protected: - - - - - void _notification(int p_what); - //void _gui_input(InputEvent p_event); - void _unhandled_key_input(InputEvent p_event); - - static void _bind_methods(); -public: - - - static SpatialEditor *get_singleton() { return singleton; } - void snap_cursor_to_plane(const Plane& p_plane); - - float get_znear() const { return settings_znear->get_value(); } - float get_zfar() const { return settings_zfar->get_value(); } - float get_fov() const { return settings_fov->get_value(); } - - Transform get_gizmo_transform() const { return gizmo.transform; } - bool is_gizmo_visible() const { return gizmo.visible; } - - ToolMode get_tool_mode() const { return tool_mode; } - bool is_snap_enabled() const { return snap_enabled; } - float get_translate_snap() const { return snap_translate->get_text().to_double(); } - float get_rotate_snap() const { return snap_rotate->get_text().to_double(); } - float get_scale_snap() const { return snap_scale->get_text().to_double(); } - - Ref<Mesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; } - Ref<Mesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; } - - void update_transform_gizmo(); - - void select_gizmo_hilight_axis(int p_axis); - void set_custom_camera(Node *p_camera) { custom_camera=p_camera; } - - void set_undo_redo(UndoRedo *p_undo_redo) {undo_redo=p_undo_redo; } - Dictionary get_state() const; - void set_state(const Dictionary& p_state); - - Ref<Environment> get_viewport_environment() { return viewport_environment; } - - UndoRedo *get_undo_redo() { return undo_redo; } - - void add_control_to_menu_panel(Control *p_control); - - VSplitContainer *get_shader_split(); - HSplitContainer *get_palette_split(); - - Spatial *get_selected() { return selected; } - - int get_over_gizmo_handle() const { return over_gizmo_handle; } - void set_over_gizmo_handle(int idx) { over_gizmo_handle=idx; } - - void set_can_preview(Camera* p_preview); - - SpatialEditorViewport *get_editor_viewport(int p_idx) { - ERR_FAIL_INDEX_V(p_idx,4,NULL); - return viewports[p_idx]; - } - - Camera *get_camera() { return NULL; } - void edit(Spatial *p_spatial); - void clear(); - SpatialEditor(EditorNode *p_editor); - ~SpatialEditor(); -}; - -class SpatialEditorPlugin : public EditorPlugin { - - GDCLASS( SpatialEditorPlugin, EditorPlugin ); - - SpatialEditor *spatial_editor; - EditorNode *editor; -protected: - static void _bind_methods(); -public: - - void snap_cursor_to_plane(const Plane& p_plane); - - SpatialEditor *get_spatial_editor() { return spatial_editor; } - virtual String get_name() const { return "3D"; } - bool has_main_screen() const { return true; } - virtual void make_visible(bool p_visible); - virtual void edit(Object *p_object); - virtual bool handles(Object *p_object) const; - - virtual Dictionary get_state() const; - virtual void set_state(const Dictionary& p_state); - virtual void clear() { spatial_editor->clear(); } - - - SpatialEditorPlugin(EditorNode *p_node); - ~SpatialEditorPlugin(); - -}; - -#endif diff --git a/tools/editor/plugins/sprite_frames_editor_plugin.cpp b/tools/editor/plugins/sprite_frames_editor_plugin.cpp deleted file mode 100644 index c3c68e471e..0000000000 --- a/tools/editor/plugins/sprite_frames_editor_plugin.cpp +++ /dev/null @@ -1,969 +0,0 @@ -/*************************************************************************/ -/* sprite_frames_editor_plugin.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 "sprite_frames_editor_plugin.h" - -#include "io/resource_loader.h" -#include "global_config.h" -#include "tools/editor/editor_settings.h" -#include "scene/3d/sprite_3d.h" - - - -void SpriteFramesEditor::_gui_input(InputEvent p_event) { - - -} - -void SpriteFramesEditor::_notification(int p_what) { - - if (p_what==NOTIFICATION_FIXED_PROCESS) { - - } - - if (p_what==NOTIFICATION_ENTER_TREE) { - load->set_icon( get_icon("Folder","EditorIcons") ); - _delete->set_icon( get_icon("Del","EditorIcons") ); - new_anim->set_icon( get_icon("New","EditorIcons") ); - remove_anim->set_icon( get_icon("Del","EditorIcons") ); - - } - - if (p_what==NOTIFICATION_READY) { - - //NodePath("/root")->connect("node_removed", this,"_node_removed",Vector<Variant>(),true); - } - - if (p_what==NOTIFICATION_DRAW) { - - } -} - -void SpriteFramesEditor::_file_load_request(const PoolVector<String>& p_path,int p_at_pos) { - - ERR_FAIL_COND(!frames->has_animation(edited_anim)); - - List< Ref<Texture> > resources; - - for(int i=0;i<p_path.size();i++) { - - Ref<Texture> resource; - resource = ResourceLoader::load(p_path[i]); - - if (resource.is_null()) { - dialog->set_text(TTR("ERROR: Couldn't load frame resource!")); - dialog->set_title(TTR("Error!")); - //dialog->get_cancel()->set_text("Close"); - dialog->get_ok()->set_text(TTR("Close")); - dialog->popup_centered_minsize(); - return; ///beh should show an error i guess - } - - resources.push_back(resource); - } - - - if (resources.empty()) { - //print_line("added frames!"); - return; - } - - undo_redo->create_action(TTR("Add Frame")); - int fc=frames->get_frame_count(edited_anim); - - int count=0; - - for(List< Ref<Texture> >::Element *E=resources.front();E;E=E->next() ) { - - undo_redo->add_do_method(frames,"add_frame",edited_anim,E->get(),p_at_pos==-1?-1:p_at_pos+count); - undo_redo->add_undo_method(frames,"remove_frame",edited_anim,p_at_pos==-1?fc:p_at_pos); - count++; - - } - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - - undo_redo->commit_action(); - //print_line("added frames!"); -} - -void SpriteFramesEditor::_load_pressed() { - - ERR_FAIL_COND(!frames->has_animation(edited_anim)); - loading_scene=false; - - file->clear_filters(); - List<String> extensions; - ResourceLoader::get_recognized_extensions_for_type("Texture",&extensions); - for(int i=0;i<extensions.size();i++) - file->add_filter("*."+extensions[i]); - - file->set_mode(EditorFileDialog::MODE_OPEN_FILES); - - file->popup_centered_ratio(); - -} - - -void SpriteFramesEditor::_item_edited() { - -#if 0 - if (!tree->get_selected()) - return; - - TreeItem *s = tree->get_selected(); - - if (tree->get_selected_column()==0) { - // renamed - String old_name=s->get_metadata(0); - String new_name=s->get_text(0); - if (old_name==new_name) - return; - - if (new_name=="" || new_name.find("\\")!=-1 || new_name.find("/")!=-1 || frames->has_resource(new_name)) { - - s->set_text(0,old_name); - return; - } - - RES samp = frames->get_resource(old_name); - undo_redo->create_action("Rename Resource"); - undo_redo->add_do_method(frames,"remove_resource",old_name); - undo_redo->add_do_method(frames,"add_resource",new_name,samp); - undo_redo->add_undo_method(frames,"remove_resource",new_name); - undo_redo->add_undo_method(frames,"add_resource",old_name,samp); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - - } -#endif - -} - -void SpriteFramesEditor::_delete_confirm_pressed() { - - ERR_FAIL_COND(!frames->has_animation(edited_anim)); - - if (tree->get_current()<0) - return; - - sel-=1; - if (sel<0 && frames->get_frame_count(edited_anim)) - sel=0; - - int to_remove = tree->get_current(); - sel=to_remove; - Ref<Texture> r = frames->get_frame(edited_anim,to_remove); - undo_redo->create_action(TTR("Delete Resource")); - undo_redo->add_do_method(frames,"remove_frame",edited_anim,to_remove); - undo_redo->add_undo_method(frames,"add_frame",edited_anim,r,to_remove); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - -} - - -void SpriteFramesEditor::_paste_pressed() { - - ERR_FAIL_COND(!frames->has_animation(edited_anim)); - - Ref<Texture> r=EditorSettings::get_singleton()->get_resource_clipboard(); - if (!r.is_valid()) { - dialog->set_text(TTR("Resource clipboard is empty or not a texture!")); - dialog->set_title(TTR("Error!")); - //dialog->get_cancel()->set_text("Close"); - dialog->get_ok()->set_text(TTR("Close")); - dialog->popup_centered_minsize(); - return; ///beh should show an error i guess - } - - - undo_redo->create_action(TTR("Paste Frame")); - undo_redo->add_do_method(frames,"add_frame",edited_anim,r); - undo_redo->add_undo_method(frames,"remove_frame",edited_anim,frames->get_frame_count(edited_anim)); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - -} - -void SpriteFramesEditor::_empty_pressed() { - - ERR_FAIL_COND(!frames->has_animation(edited_anim)); - - int from=-1; - - if (tree->get_current()>=0) { - - from = tree->get_current(); - sel=from; - - } else { - from=frames->get_frame_count(edited_anim); - } - - - - Ref<Texture> r; - - undo_redo->create_action(TTR("Add Empty")); - undo_redo->add_do_method(frames,"add_frame",edited_anim,r,from); - undo_redo->add_undo_method(frames,"remove_frame",edited_anim,from); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - -} - -void SpriteFramesEditor::_empty2_pressed() { - - ERR_FAIL_COND(!frames->has_animation(edited_anim)); - - int from=-1; - - if (tree->get_current()>=0) { - - from = tree->get_current(); - sel=from; - - } else { - from=frames->get_frame_count(edited_anim); - } - - - - Ref<Texture> r; - - undo_redo->create_action(TTR("Add Empty")); - undo_redo->add_do_method(frames,"add_frame",edited_anim,r,from+1); - undo_redo->add_undo_method(frames,"remove_frame",edited_anim,from+1); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - -} - -void SpriteFramesEditor::_up_pressed() { - - ERR_FAIL_COND(!frames->has_animation(edited_anim)); - - if (tree->get_current()<0) - return; - - int to_move = tree->get_current(); - if (to_move<1) - return; - - sel=to_move; - sel-=1; - - Ref<Texture> r = frames->get_frame(edited_anim,to_move); - undo_redo->create_action(TTR("Delete Resource")); - undo_redo->add_do_method(frames,"set_frame",edited_anim,to_move,frames->get_frame(edited_anim,to_move-1)); - undo_redo->add_do_method(frames,"set_frame",edited_anim,to_move-1,frames->get_frame(edited_anim,to_move)); - undo_redo->add_undo_method(frames,"set_frame",edited_anim,to_move,frames->get_frame(edited_anim,to_move)); - undo_redo->add_undo_method(frames,"set_frame",edited_anim,to_move-1,frames->get_frame(edited_anim,to_move-1)); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - -} - -void SpriteFramesEditor::_down_pressed() { - - ERR_FAIL_COND(!frames->has_animation(edited_anim)); - - if (tree->get_current()<0) - return; - - int to_move = tree->get_current(); - if (to_move<0 || to_move>=frames->get_frame_count(edited_anim)-1) - return; - - sel=to_move; - sel+=1; - - Ref<Texture> r = frames->get_frame(edited_anim,to_move); - undo_redo->create_action(TTR("Delete Resource")); - undo_redo->add_do_method(frames,"set_frame",edited_anim,to_move,frames->get_frame(edited_anim,to_move+1)); - undo_redo->add_do_method(frames,"set_frame",edited_anim,to_move+1,frames->get_frame(edited_anim,to_move)); - undo_redo->add_undo_method(frames,"set_frame",edited_anim,to_move,frames->get_frame(edited_anim,to_move)); - undo_redo->add_undo_method(frames,"set_frame",edited_anim,to_move+1,frames->get_frame(edited_anim,to_move+1)); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - - - -} - - -void SpriteFramesEditor::_delete_pressed() { - - - if (tree->get_current()<0) - return; - - _delete_confirm_pressed(); //it has undo.. why bother with a dialog.. - /* - dialog->set_title("Confirm..."); - dialog->set_text("Remove Resource '"+tree->get_selected()->get_text(0)+"' ?"); - //dialog->get_cancel()->set_text("Cancel"); - //dialog->get_ok()->show(); - dialog->get_ok()->set_text("Remove"); - dialog->popup_centered(Size2(300,60));*/ - -} - - -void SpriteFramesEditor::_animation_select() { - - if (updating) - return; - - TreeItem *selected = animations->get_selected(); - ERR_FAIL_COND(!selected); - edited_anim=selected->get_text(0); - _update_library(true); - -} - - -static void _find_anim_sprites(Node* p_node,List<Node*> *r_nodes,Ref<SpriteFrames> p_sfames) { - - Node *edited = EditorNode::get_singleton()->get_edited_scene(); - if (!edited) - return; - if (p_node!=edited && p_node->get_owner()!=edited) - return; - - { - AnimatedSprite *as = p_node->cast_to<AnimatedSprite>(); - if (as && as->get_sprite_frames()==p_sfames) { - r_nodes->push_back(p_node); - } - } - - { - AnimatedSprite3D *as = p_node->cast_to<AnimatedSprite3D>(); - if (as && as->get_sprite_frames()==p_sfames) { - r_nodes->push_back(p_node); - } - } - - for(int i=0;i<p_node->get_child_count();i++) { - _find_anim_sprites(p_node->get_child(i),r_nodes,p_sfames); - } - -} - -void SpriteFramesEditor::_animation_name_edited(){ - - if (updating) - return; - - if (!frames->has_animation(edited_anim)) - return; - - TreeItem *edited = animations->get_edited(); - if (!edited) - return; - - String new_name = edited->get_text(0); - - if (new_name==String(edited_anim)) - return; - - new_name=new_name.replace("/","_").replace(","," "); - - String name=new_name; - int counter=0; - while(frames->has_animation(name)) { - counter++; - name=new_name+" "+itos(counter); - } - - List<Node*> nodes; - _find_anim_sprites(EditorNode::get_singleton()->get_edited_scene(),&nodes,Ref<SpriteFrames>(frames)); - - undo_redo->create_action(TTR("Rename Animation")); - undo_redo->add_do_method(frames,"rename_animation",edited_anim,name); - undo_redo->add_undo_method(frames,"rename_animation",name,edited_anim); - - for(List<Node*>::Element *E=nodes.front();E;E=E->next()) { - - String current = E->get()->call("get_animation"); - if (current!=edited_anim) - continue; - - undo_redo->add_do_method(E->get(),"set_animation",name); - undo_redo->add_undo_method(E->get(),"set_animation",edited_anim); - - } - - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - - edited_anim=new_name; - - undo_redo->commit_action(); - - - -} -void SpriteFramesEditor::_animation_add(){ - - - String new_name = "New Anim"; - - String name=new_name; - int counter=0; - while(frames->has_animation(name)) { - counter++; - name=new_name+" "+itos(counter); - } - - List<Node*> nodes; - _find_anim_sprites(EditorNode::get_singleton()->get_edited_scene(),&nodes,Ref<SpriteFrames>(frames)); - - - undo_redo->create_action(TTR("Add Animation")); - undo_redo->add_do_method(frames,"add_animation",name); - undo_redo->add_undo_method(frames,"remove_animation",name); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - - - for(List<Node*>::Element *E=nodes.front();E;E=E->next()) { - - String current = E->get()->call("get_animation"); - if (frames->has_animation(current)) - continue; - - undo_redo->add_do_method(E->get(),"set_animation",name); - undo_redo->add_undo_method(E->get(),"set_animation",current); - - } - - edited_anim=new_name; - - undo_redo->commit_action(); - -} -void SpriteFramesEditor::_animation_remove(){ - - //fuck everything - if (updating) - return; - - if (!frames->has_animation(edited_anim)) - return; - - - undo_redo->create_action(TTR("Remove Animation")); - undo_redo->add_do_method(frames,"remove_animation",edited_anim); - undo_redo->add_undo_method(frames,"add_animation",edited_anim); - undo_redo->add_undo_method(frames,"set_animation_speed",edited_anim,frames->get_animation_speed(edited_anim)); - undo_redo->add_undo_method(frames,"set_animation_loop",edited_anim,frames->get_animation_loop(edited_anim)); - int fc = frames->get_frame_count(edited_anim); - for(int i=0;i<fc;i++) { - Ref<Texture> frame = frames->get_frame(edited_anim,i); - undo_redo->add_undo_method(frames,"add_frame",edited_anim,frame); - } - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - - undo_redo->commit_action(); - -} - - -void SpriteFramesEditor::_animation_loop_changed() { - - if (updating) - return; - - undo_redo->create_action(TTR("Change Animation Loop")); - undo_redo->add_do_method(frames,"set_animation_loop",edited_anim,anim_loop->is_pressed()); - undo_redo->add_undo_method(frames,"set_animation_loop",edited_anim,frames->get_animation_loop(edited_anim)); - undo_redo->add_do_method(this,"_update_library",true); - undo_redo->add_undo_method(this,"_update_library",true); - undo_redo->commit_action(); - -} - -void SpriteFramesEditor::_animation_fps_changed(double p_value) { - - if (updating) - return; - - undo_redo->create_action(TTR("Change Animation FPS"),UndoRedo::MERGE_ENDS); - undo_redo->add_do_method(frames,"set_animation_speed",edited_anim,p_value); - undo_redo->add_undo_method(frames,"set_animation_speed",edited_anim,frames->get_animation_speed(edited_anim)); - undo_redo->add_do_method(this,"_update_library",true); - undo_redo->add_undo_method(this,"_update_library",true); - - undo_redo->commit_action(); - -} - -void SpriteFramesEditor::_update_library(bool p_skip_selector) { - - updating=true; - - if (!p_skip_selector) { - animations->clear(); - - TreeItem *anim_root=animations->create_item(); - - List<StringName> anim_names; - - anim_names.sort_custom<StringName::AlphCompare>(); - - frames->get_animation_list(&anim_names); - - anim_names.sort_custom<StringName::AlphCompare>(); - - for(List<StringName>::Element *E=anim_names.front();E;E=E->next()) { - - String name = E->get(); - - TreeItem *it = animations->create_item(anim_root); - - it->set_metadata(0,name); - - it->set_text(0,name); - it->set_editable(0,true); - - if (E->get()==edited_anim) { - it->select(0); - } - } - } - - - tree->clear(); - - if (!frames->has_animation(edited_anim)) { - updating=false; - return; - } - - - if (sel>=frames->get_frame_count(edited_anim)) - sel=frames->get_frame_count(edited_anim)-1; - else if (sel<0 && frames->get_frame_count(edited_anim)) - sel=0; - - for(int i=0;i<frames->get_frame_count(edited_anim);i++) { - - - String name; - Ref<Texture> icon; - - - if (frames->get_frame(edited_anim,i).is_null()) { - - name=itos(i)+": "+TTR("(empty)"); - - } else { - name=itos(i)+": "+frames->get_frame(edited_anim,i)->get_name(); - icon=frames->get_frame(edited_anim,i); - } - - tree->add_item(name,icon); - if (frames->get_frame(edited_anim,i).is_valid()) - tree->set_item_tooltip(tree->get_item_count()-1,frames->get_frame(edited_anim,i)->get_path()); - if (sel==i) - tree->select(tree->get_item_count()-1); - } - - anim_speed->set_value(frames->get_animation_speed(edited_anim)); - anim_loop->set_pressed(frames->get_animation_loop(edited_anim)); - - updating=false; - //player->add_resource("default",resource); -} - - - -void SpriteFramesEditor::edit(SpriteFrames* p_frames) { - - if (frames==p_frames) - return; - - frames=p_frames; - - - if (p_frames) { - - if (!p_frames->has_animation(edited_anim)) { - - List<StringName> anim_names; - frames->get_animation_list(&anim_names); - anim_names.sort_custom<StringName::AlphCompare>(); - if (anim_names.size()) { - edited_anim=anim_names.front()->get(); - } else { - edited_anim=StringName(); - } - - } - - _update_library(); - } else { - - hide(); - //set_fixed_process(false); - } - -} - - -Variant SpriteFramesEditor::get_drag_data_fw(const Point2& p_point,Control* p_from) { - - if (!frames->has_animation(edited_anim)) - return false; - - int idx = tree->get_item_at_pos(p_point,true); - - if (idx<0 || idx>=frames->get_frame_count(edited_anim)) - return Variant(); - - RES frame = frames->get_frame(edited_anim,idx); - - if (frame.is_null()) - return Variant(); - - return EditorNode::get_singleton()->drag_resource(frame,p_from); - - -} - -bool SpriteFramesEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const{ - - Dictionary d = p_data; - - if (!d.has("type")) - return false; - - if (d.has("from") && (Object*)(d["from"])==tree) - return false; - - if (String(d["type"])=="resource" && d.has("resource")) { - RES r=d["resource"]; - - Ref<Texture> texture = r; - - if (texture.is_valid()) { - - return true; - } - } - - - if (String(d["type"])=="files") { - - Vector<String> files = d["files"]; - - if (files.size()==0) - return false; - - for(int i=0;i<files.size();i++) { - String file = files[0]; - String ftype = EditorFileSystem::get_singleton()->get_file_type(file); - - if (!ClassDB::is_parent_class(ftype,"Texture")) { - return false; - } - - } - - return true; - - } - return false; -} - -void SpriteFramesEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from){ - - if (!can_drop_data_fw(p_point,p_data,p_from)) - return; - - Dictionary d = p_data; - - if (!d.has("type")) - return; - - int at_pos = tree->get_item_at_pos(p_point,true); - - if (String(d["type"])=="resource" && d.has("resource")) { - RES r=d["resource"]; - - Ref<Texture> texture = r; - - if (texture.is_valid()) { - - undo_redo->create_action(TTR("Add Frame")); - undo_redo->add_do_method(frames,"add_frame",edited_anim,texture,at_pos==-1?-1:at_pos); - undo_redo->add_undo_method(frames,"remove_frame",edited_anim,at_pos==-1?frames->get_frame_count(edited_anim):at_pos); - undo_redo->add_do_method(this,"_update_library"); - undo_redo->add_undo_method(this,"_update_library"); - undo_redo->commit_action(); - - } - } - - - if (String(d["type"])=="files") { - - PoolVector<String> files = d["files"]; - - _file_load_request(files,at_pos); - } - -} - - -void SpriteFramesEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_gui_input"),&SpriteFramesEditor::_gui_input); - ClassDB::bind_method(D_METHOD("_load_pressed"),&SpriteFramesEditor::_load_pressed); - ClassDB::bind_method(D_METHOD("_empty_pressed"),&SpriteFramesEditor::_empty_pressed); - ClassDB::bind_method(D_METHOD("_empty2_pressed"),&SpriteFramesEditor::_empty2_pressed); - ClassDB::bind_method(D_METHOD("_item_edited"),&SpriteFramesEditor::_item_edited); - ClassDB::bind_method(D_METHOD("_delete_pressed"),&SpriteFramesEditor::_delete_pressed); - ClassDB::bind_method(D_METHOD("_paste_pressed"),&SpriteFramesEditor::_paste_pressed); - ClassDB::bind_method(D_METHOD("_delete_confirm_pressed"),&SpriteFramesEditor::_delete_confirm_pressed); - ClassDB::bind_method(D_METHOD("_file_load_request","files","atpos"),&SpriteFramesEditor::_file_load_request,DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("_update_library","skipsel"),&SpriteFramesEditor::_update_library,DEFVAL(false)); - ClassDB::bind_method(D_METHOD("_up_pressed"),&SpriteFramesEditor::_up_pressed); - ClassDB::bind_method(D_METHOD("_down_pressed"),&SpriteFramesEditor::_down_pressed); - ClassDB::bind_method(D_METHOD("_animation_select"),&SpriteFramesEditor::_animation_select); - ClassDB::bind_method(D_METHOD("_animation_name_edited"),&SpriteFramesEditor::_animation_name_edited); - ClassDB::bind_method(D_METHOD("_animation_add"),&SpriteFramesEditor::_animation_add); - ClassDB::bind_method(D_METHOD("_animation_remove"),&SpriteFramesEditor::_animation_remove); - ClassDB::bind_method(D_METHOD("_animation_loop_changed"),&SpriteFramesEditor::_animation_loop_changed); - ClassDB::bind_method(D_METHOD("_animation_fps_changed"),&SpriteFramesEditor::_animation_fps_changed); - ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &SpriteFramesEditor::get_drag_data_fw); - ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SpriteFramesEditor::can_drop_data_fw); - ClassDB::bind_method(D_METHOD("drop_data_fw"), &SpriteFramesEditor::drop_data_fw); - - -} - - -SpriteFramesEditor::SpriteFramesEditor() { - - //add_style_override("panel", get_stylebox("panel","Panel")); - - split = memnew( HSplitContainer ); - add_child(split); - - VBoxContainer *vbc_animlist = memnew( VBoxContainer ); - split->add_child(vbc_animlist); - vbc_animlist->set_custom_minimum_size(Size2(150,0)); - //vbc_animlist->set_v_size_flags(SIZE_EXPAND_FILL); - - - VBoxContainer *sub_vb = memnew( VBoxContainer ); - vbc_animlist->add_margin_child(TTR("Animations"),sub_vb,true); - sub_vb->set_v_size_flags(SIZE_EXPAND_FILL); - - HBoxContainer *hbc_animlist = memnew( HBoxContainer ); - sub_vb->add_child(hbc_animlist); - - new_anim = memnew( Button ); - hbc_animlist->add_child(new_anim); - new_anim->connect("pressed",this,"_animation_add"); - - - hbc_animlist->add_spacer(); - - remove_anim = memnew( Button ); - hbc_animlist->add_child(remove_anim); - remove_anim->connect("pressed",this,"_animation_remove"); - - animations = memnew( Tree ); - sub_vb->add_child(animations); - animations->set_v_size_flags(SIZE_EXPAND_FILL); - animations->set_hide_root(true); - animations->connect("cell_selected",this,"_animation_select"); - animations->connect("item_edited",this,"_animation_name_edited"); - animations->set_single_select_cell_editing_only_when_already_selected(true); - - - anim_speed = memnew( SpinBox); - vbc_animlist->add_margin_child(TTR("Speed (FPS):"),anim_speed); - anim_speed->set_min(0); - anim_speed->set_max(100); - anim_speed->set_step(0.01); - anim_speed->connect("value_changed",this,"_animation_fps_changed"); - - anim_loop = memnew( CheckButton ); - anim_loop->set_text(TTR("Loop")); - vbc_animlist->add_child(anim_loop); - anim_loop->connect("pressed",this,"_animation_loop_changed"); - - VBoxContainer *vbc = memnew( VBoxContainer ); - split->add_child(vbc); - vbc->set_h_size_flags(SIZE_EXPAND_FILL); - - sub_vb = memnew( VBoxContainer ); - vbc->add_margin_child(TTR("Animation Frames"),sub_vb,true); - - - HBoxContainer *hbc = memnew( HBoxContainer ); - sub_vb->add_child(hbc); - - //animations = memnew( ItemList ); - - - load = memnew( Button ); - load->set_tooltip(TTR("Load Resource")); - hbc->add_child(load); - - paste = memnew( Button ); - paste->set_text(TTR("Paste")); - hbc->add_child(paste); - - empty = memnew( Button ); - empty->set_text(TTR("Insert Empty (Before)")); - hbc->add_child(empty); - - empty2 = memnew( Button ); - empty2->set_text(TTR("Insert Empty (After)")); - hbc->add_child(empty2); - - move_up = memnew( Button ); - move_up->set_text(TTR("Up")); - hbc->add_child(move_up); - - move_down = memnew( Button ); - move_down->set_text(TTR("Down")); - hbc->add_child(move_down); - - _delete = memnew( Button ); - hbc->add_child(_delete); - - file = memnew( EditorFileDialog ); - add_child(file); - - - tree = memnew( ItemList ); - tree->set_v_size_flags(SIZE_EXPAND_FILL); - tree->set_icon_mode(ItemList::ICON_MODE_TOP); - - int thumbnail_size = 96; - tree->set_max_columns(0); - tree->set_icon_mode(ItemList::ICON_MODE_TOP); - tree->set_fixed_column_width(thumbnail_size*3/2); - tree->set_max_text_lines(2); - tree->set_fixed_icon_size(Size2(thumbnail_size,thumbnail_size)); - //tree->set_min_icon_size(Size2(thumbnail_size,thumbnail_size)); - tree->set_drag_forwarding(this); - - - - sub_vb->add_child(tree); - - dialog = memnew( AcceptDialog ); - add_child( dialog ); - - load->connect("pressed", this,"_load_pressed"); - _delete->connect("pressed", this,"_delete_pressed"); - paste->connect("pressed", this,"_paste_pressed"); - empty->connect("pressed", this,"_empty_pressed"); - empty2->connect("pressed", this,"_empty2_pressed"); - move_up->connect("pressed", this,"_up_pressed"); - move_down->connect("pressed", this,"_down_pressed"); - file->connect("files_selected", this,"_file_load_request"); - //dialog->connect("confirmed", this,"_delete_confirm_pressed"); - //tree->connect("item_selected", this,"_item_edited"); - loading_scene=false; - sel=-1; - - updating=false; - - edited_anim="default"; - -} - - -void SpriteFramesEditorPlugin::edit(Object *p_object) { - - frames_editor->set_undo_redo(&get_undo_redo()); - SpriteFrames * s = p_object->cast_to<SpriteFrames>(); - if (!s) - return; - - frames_editor->edit(s); -} - -bool SpriteFramesEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("SpriteFrames"); -} - -void SpriteFramesEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - button->show(); - editor->make_bottom_panel_item_visible(frames_editor); - //frames_editor->set_process(true); - } else { - - button->hide(); - if (frames_editor->is_visible_in_tree()) - editor->hide_bottom_panel(); - - //frames_editor->set_process(false); - } - -} - -SpriteFramesEditorPlugin::SpriteFramesEditorPlugin(EditorNode *p_node) { - - editor=p_node; - frames_editor = memnew( SpriteFramesEditor ); - frames_editor->set_custom_minimum_size(Size2(0,300)); - button=editor->add_bottom_panel_item("SpriteFrames",frames_editor); - button->hide(); - - - -} - - -SpriteFramesEditorPlugin::~SpriteFramesEditorPlugin() -{ -} - - diff --git a/tools/editor/plugins/sprite_frames_editor_plugin.h b/tools/editor/plugins/sprite_frames_editor_plugin.h deleted file mode 100644 index 36a022b7e4..0000000000 --- a/tools/editor/plugins/sprite_frames_editor_plugin.h +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************/ -/* sprite_frames_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef SPRITE_FRAMES_EDITOR_PLUGIN_H -#define SPRITE_FRAMES_EDITOR_PLUGIN_H - - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/gui/tree.h" -#include "scene/2d/animated_sprite.h" -#include "scene/gui/file_dialog.h" -#include "scene/gui/dialogs.h" -#include "scene/gui/split_container.h" - - -class SpriteFramesEditor : public PanelContainer { - - GDCLASS(SpriteFramesEditor, PanelContainer ); - - Button *load; - Button *_delete; - Button *paste; - Button *empty; - Button *empty2; - Button *move_up; - Button *move_down; - ItemList *tree; - bool loading_scene; - int sel; - - HSplitContainer *split; - Button *new_anim; - Button *remove_anim; - - - Tree *animations; - SpinBox *anim_speed; - CheckButton *anim_loop; - - EditorFileDialog *file; - - AcceptDialog *dialog; - - SpriteFrames *frames; - - StringName edited_anim; - - void _load_pressed(); - void _load_scene_pressed(); - void _file_load_request(const PoolVector<String>& p_path, int p_at_pos=-1); - void _paste_pressed(); - void _empty_pressed(); - void _empty2_pressed(); - void _delete_pressed(); - void _delete_confirm_pressed(); - void _up_pressed(); - void _down_pressed(); - void _update_library(bool p_skip_selector=false); - void _item_edited(); - - - - void _animation_select(); - void _animation_name_edited(); - void _animation_add(); - void _animation_remove(); - void _animation_loop_changed(); - void _animation_fps_changed(double p_value); - - bool updating; - - UndoRedo *undo_redo; - - bool _is_drop_valid(const Dictionary& p_drag_data, const Dictionary& p_item_data) const; - Variant get_drag_data_fw(const Point2& p_point,Control* p_from); - bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; - void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); - -protected: - void _notification(int p_what); - void _gui_input(InputEvent p_event); - static void _bind_methods(); -public: - - void set_undo_redo(UndoRedo *p_undo_redo) {undo_redo=p_undo_redo; } - - void edit(SpriteFrames* p_frames); - SpriteFramesEditor(); -}; - -class SpriteFramesEditorPlugin : public EditorPlugin { - - GDCLASS( SpriteFramesEditorPlugin, EditorPlugin ); - - SpriteFramesEditor *frames_editor; - EditorNode *editor; - Button *button; - -public: - - virtual String get_name() const { return "SpriteFrames"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - SpriteFramesEditorPlugin(EditorNode *p_node); - ~SpriteFramesEditorPlugin(); - -}; - -#endif // SPRITE_FRAMES_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/stream_editor_plugin.h b/tools/editor/plugins/stream_editor_plugin.h deleted file mode 100644 index cc853d4661..0000000000 --- a/tools/editor/plugins/stream_editor_plugin.h +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************/ -/* stream_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef STREAM_EDITOR_PLUGIN_H -#define STREAM_EDITOR_PLUGIN_H - -#if 0 -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/audio/stream_player.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -class StreamEditor : public Control { - - GDCLASS(StreamEditor, Control ); - - Button * play; - Button * stop; - - Panel *panel; - Node *node; - - void _play(); - void _stop(); -protected: - void _notification(int p_what); - void _node_removed(Node *p_node); - static void _bind_methods(); -public: - - void edit(Node *p_stream); - StreamEditor(); -}; - -class StreamEditorPlugin : public EditorPlugin { - - GDCLASS( StreamEditorPlugin, EditorPlugin ); - - StreamEditor *stream_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "Stream"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - StreamEditorPlugin(EditorNode *p_node); - ~StreamEditorPlugin(); - -}; - -#endif // STREAM_EDITOR_PLUGIN_H -#endif diff --git a/tools/editor/plugins/style_box_editor_plugin.h b/tools/editor/plugins/style_box_editor_plugin.h deleted file mode 100644 index 29e98efd8b..0000000000 --- a/tools/editor/plugins/style_box_editor_plugin.h +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************/ -/* style_box_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef STYLE_BOX_EDITOR_PLUGIN_H -#define STYLE_BOX_EDITOR_PLUGIN_H - -#include "scene/resources/style_box.h" -#include "scene/gui/texture_rect.h" -#include "scene/gui/option_button.h" -#include "tools/editor/editor_node.h" - - -class StyleBoxEditor : public Control { - - GDCLASS( StyleBoxEditor, Control ); - - Panel *panel; - Panel *preview; - - Ref<StyleBox> stylebox; - - void _sb_changed(); - -protected: - - - static void _bind_methods(); -public: - - void edit(const Ref<StyleBox>& p_stylebox); - - StyleBoxEditor(); -}; - - - -class StyleBoxEditorPlugin : public EditorPlugin { - - GDCLASS( StyleBoxEditorPlugin, EditorPlugin ); - - StyleBoxEditor *stylebox_editor; - EditorNode *editor; - Button *button; - -public: - - virtual String get_name() const { return "StyleBox"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - StyleBoxEditorPlugin(EditorNode *p_node); - -}; - - -#endif // STYLE_BOX_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/texture_editor_plugin.cpp b/tools/editor/plugins/texture_editor_plugin.cpp deleted file mode 100644 index 90a798667f..0000000000 --- a/tools/editor/plugins/texture_editor_plugin.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/*************************************************************************/ -/* texture_editor_plugin.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 "texture_editor_plugin.h" - -#include "io/resource_loader.h" -#include "global_config.h" -#include "tools/editor/editor_settings.h" - -void TextureEditor::_gui_input(InputEvent p_event) { - - -} - -void TextureEditor::_notification(int p_what) { - - if (p_what==NOTIFICATION_FIXED_PROCESS) { - - } - - - if (p_what==NOTIFICATION_READY) { - - //get_scene()->connect("node_removed",this,"_node_removed"); - - } - - if (p_what==NOTIFICATION_DRAW) { - - - Ref<Texture> checkerboard = get_icon("Checkerboard","EditorIcons"); - Size2 size = get_size(); - - draw_texture_rect(checkerboard,Rect2(Point2(),size),true); - - int tex_width = texture->get_width() * size.height / texture ->get_height(); - int tex_height = size.height; - - if (tex_width>size.width) { - tex_width=size.width; - tex_height=texture->get_height() * tex_width / texture->get_width(); - } - - int ofs_x = (size.width - tex_width)/2; - int ofs_y = (size.height - tex_height)/2; - - draw_texture_rect(texture,Rect2(ofs_x,ofs_y,tex_width,tex_height)); - - Ref<Font> font = get_font("font","Label"); - - String format; - if (texture->cast_to<ImageTexture>()) { - format = Image::get_format_name(texture->cast_to<ImageTexture>()->get_format()); - } else { - format=texture->get_class(); - } - String text = itos(texture->get_width())+"x"+itos(texture->get_height())+" "+format; - - Size2 rect = font->get_string_size(text); - - Vector2 draw_from = size-rect+Size2(-2,font->get_ascent()-2); - if (draw_from.x<0) - draw_from.x=0; - - draw_string(font,draw_from+Vector2(2,2),text,Color(0,0,0,0.5),size.width); - draw_string(font,draw_from-Vector2(2,2),text,Color(0,0,0,0.5),size.width); - draw_string(font,draw_from,text,Color(1,1,1,1),size.width); - } -} - - - -void TextureEditor::edit(Ref<Texture> p_texture) { - - texture=p_texture; - - if (!texture.is_null()) - update(); - else { - - hide(); - } - -} - - - -void TextureEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_gui_input"),&TextureEditor::_gui_input); - -} - -TextureEditor::TextureEditor() { - - set_custom_minimum_size(Size2(1,150)); - -} - - -void TextureEditorPlugin::edit(Object *p_object) { - - Texture * s = p_object->cast_to<Texture>(); - if (!s) - return; - - texture_editor->edit(Ref<Texture>(s)); -} - -bool TextureEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("Texture"); -} - -void TextureEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - texture_editor->show(); - //texture_editor->set_process(true); - } else { - - texture_editor->hide(); - //texture_editor->set_process(false); - } - -} - -TextureEditorPlugin::TextureEditorPlugin(EditorNode *p_node) { - - editor=p_node; - texture_editor = memnew( TextureEditor ); - add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,texture_editor); - texture_editor->hide(); - - - -} - - -TextureEditorPlugin::~TextureEditorPlugin() -{ -} - - diff --git a/tools/editor/plugins/texture_editor_plugin.h b/tools/editor/plugins/texture_editor_plugin.h deleted file mode 100644 index 456a5249de..0000000000 --- a/tools/editor/plugins/texture_editor_plugin.h +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************/ -/* texture_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef TEXTURE_EDITOR_PLUGIN_H -#define TEXTURE_EDITOR_PLUGIN_H - - - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/resources/texture.h" - - -class TextureEditor : public Control { - - GDCLASS(TextureEditor, Control); - - - Ref<Texture> texture; - -protected: - void _notification(int p_what); - void _gui_input(InputEvent p_event); - static void _bind_methods(); -public: - - void edit(Ref<Texture> p_texture); - TextureEditor(); -}; - - -class TextureEditorPlugin : public EditorPlugin { - - GDCLASS( TextureEditorPlugin, EditorPlugin ); - - TextureEditor *texture_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "Texture"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - TextureEditorPlugin(EditorNode *p_node); - ~TextureEditorPlugin(); - -}; - -#endif // TEXTURE_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/texture_region_editor_plugin.h b/tools/editor/plugins/texture_region_editor_plugin.h deleted file mode 100644 index da713a53d3..0000000000 --- a/tools/editor/plugins/texture_region_editor_plugin.h +++ /dev/null @@ -1,153 +0,0 @@ -/*************************************************************************/ -/* texture_region_editor_plugin.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Author: Mariano Suligoy */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef TEXTURE_REGION_EDITOR_PLUGIN_H -#define TEXTURE_REGION_EDITOR_PLUGIN_H - -#include "canvas_item_editor_plugin.h" -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" -#include "scene/2d/sprite.h" -#include "scene/gui/patch_9_rect.h" -#include "scene/resources/style_box.h" -#include "scene/resources/texture.h" - -class TextureRegionEditor : public Control { - - GDCLASS(TextureRegionEditor, Control ); - - enum SnapMode { - SNAP_NONE, - SNAP_PIXEL, - SNAP_GRID, - SNAP_AUTOSLICE - }; - - friend class TextureRegionEditorPlugin; - MenuButton *snap_mode_button; - TextureRect *icon_zoom; - ToolButton *zoom_in; - ToolButton *zoom_reset; - ToolButton *zoom_out; - HBoxContainer * hb_grid; //For showing/hiding the grid controls when changing the SnapMode - SpinBox *sb_step_y; - SpinBox *sb_step_x; - SpinBox *sb_off_y; - SpinBox *sb_off_x; - SpinBox *sb_sep_y; - SpinBox *sb_sep_x; - Control *edit_draw; - - VScrollBar *vscroll; - HScrollBar *hscroll; - - EditorNode *editor; - UndoRedo* undo_redo; - - Vector2 draw_ofs; - float draw_zoom; - bool updating_scroll; - - int snap_mode; - Vector2 snap_offset; - Vector2 snap_step; - Vector2 snap_separation; - - NinePatchRect *node_patch9; - Sprite *node_sprite; - Ref<StyleBoxTexture> obj_styleBox; - Ref<AtlasTexture> atlas_tex; - - Rect2 rect; - Rect2 rect_prev; - float prev_margin; - int edited_margin; - List<Rect2> autoslice_cache; - - bool drag; - bool creating; - Vector2 drag_from; - int drag_index; - - void _set_snap_mode(int p_mode); - void _set_snap_off_x(float p_val); - void _set_snap_off_y(float p_val); - void _set_snap_step_x(float p_val); - void _set_snap_step_y(float p_val); - void _set_snap_sep_x(float p_val); - void _set_snap_sep_y(float p_val); - void _zoom_in(); - void _zoom_reset(); - void _zoom_out(); - void apply_rect(const Rect2& rect); -protected: - - void _notification(int p_what); - void _node_removed(Object *p_obj); - static void _bind_methods(); - - Vector2 snap_point(Vector2 p_target) const; - - virtual void _changed_callback(Object *p_changed, const char *p_prop); - -public: - - void _edit_region(); - void _region_draw(); - void _region_input(const InputEvent &p_input); - void _scroll_changed(float); - - void edit(Object *p_obj); - TextureRegionEditor(EditorNode* p_editor); - -}; - -class TextureRegionEditorPlugin : public EditorPlugin -{ - GDCLASS( TextureRegionEditorPlugin, EditorPlugin ); - - Button *region_button; - TextureRegionEditor *region_editor; - EditorNode *editor; -public: - - virtual String get_name() const { return "TextureRegion"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - void set_state(const Dictionary &p_state); - Dictionary get_state() const; - - TextureRegionEditorPlugin(EditorNode *p_node); -}; - -#endif // TEXTURE_REGION_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/theme_editor_plugin.h b/tools/editor/plugins/theme_editor_plugin.h deleted file mode 100644 index 9251da8e07..0000000000 --- a/tools/editor/plugins/theme_editor_plugin.h +++ /dev/null @@ -1,125 +0,0 @@ -/*************************************************************************/ -/* theme_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef THEME_EDITOR_PLUGIN_H -#define THEME_EDITOR_PLUGIN_H - -#include "scene/resources/theme.h" -#include "scene/gui/texture_rect.h" -#include "scene/gui/option_button.h" -#include "scene/gui/file_dialog.h" -#include "scene/gui/check_box.h" -#include "scene/gui/button_group.h" -#include "scene/gui/scroll_container.h" - -#include "tools/editor/editor_node.h" - - - - -class ThemeEditor : public Control { - - GDCLASS( ThemeEditor, Control ); - - - ScrollContainer *scroll; - VBoxContainer *main_vb; - Ref<Theme> theme; - - EditorFileDialog *file_dialog; - - double time_left; - - MenuButton *theme_menu; - ConfirmationDialog *add_del_dialog; - MenuButton *type_menu; - LineEdit *type_edit; - MenuButton *name_menu; - LineEdit *name_edit; - OptionButton *type_select; - Label * type_select_label; - Label * name_select_label; - Label * dtype_select_label; - - enum PopupMode { - POPUP_ADD, - POPUP_CLASS_ADD, - POPUP_REMOVE, - POPUP_CLASS_REMOVE, - POPUP_CREATE_EMPTY, - POPUP_CREATE_EDITOR_EMPTY - }; - - int popup_mode; - - Tree *test_tree; - - void _save_template_cbk(String fname); - void _dialog_cbk(); - void _type_menu_cbk(int p_option); - void _name_menu_about_to_show(); - void _name_menu_cbk(int p_option); - void _theme_menu_cbk(int p_option); - void _propagate_redraw(Control *p_at); - void _refresh_interval(); - - -protected: - void _notification(int p_what); - static void _bind_methods(); -public: - - void edit(const Ref<Theme>& p_theme); - - ThemeEditor(); -}; - - - -class ThemeEditorPlugin : public EditorPlugin { - - GDCLASS( ThemeEditorPlugin, EditorPlugin ); - - ThemeEditor *theme_editor; - EditorNode *editor; - Button *button; - -public: - - virtual String get_name() const { return "Theme"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - ThemeEditorPlugin(EditorNode *p_node); - -}; - - -#endif // THEME_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp deleted file mode 100644 index 16b354c8b1..0000000000 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ /dev/null @@ -1,1593 +0,0 @@ -/*************************************************************************/ -/* tile_map_editor_plugin.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 "tile_map_editor_plugin.h" - -#include "os/keyboard.h" -#include "os/input.h" -#include "canvas_item_editor_plugin.h" -#include "tools/editor/editor_settings.h" -#include "tools/editor/editor_scale.h" - -void TileMapEditor::_notification(int p_what) { - - switch(p_what) { - - case NOTIFICATION_ENTER_TREE: { - - transp->set_icon(get_icon("Transpose","EditorIcons")); - mirror_x->set_icon(get_icon("MirrorX","EditorIcons")); - mirror_y->set_icon(get_icon("MirrorY","EditorIcons")); - rotate_0->set_icon(get_icon("Rotate0","EditorIcons")); - rotate_90->set_icon(get_icon("Rotate90","EditorIcons")); - rotate_180->set_icon(get_icon("Rotate180","EditorIcons")); - rotate_270->set_icon(get_icon("Rotate270","EditorIcons")); - - } break; - case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - - if (is_visible_in_tree()) { - _update_palette(); - } - } break; - } -} - -void TileMapEditor::_menu_option(int p_option) { - - switch(p_option) { - - case OPTION_BUCKET: { - - tool=TOOL_BUCKET; - - canvas_item_editor->update(); - } break; - case OPTION_PICK_TILE: { - - tool=TOOL_PICKING; - - canvas_item_editor->update(); - } break; - case OPTION_SELECT: { - - tool=TOOL_SELECTING; - selection_active=false; - - canvas_item_editor->update(); - } break; - case OPTION_DUPLICATE: { - - _update_copydata(); - - if (selection_active) { - tool=TOOL_DUPLICATING; - - canvas_item_editor->update(); - } - } break; - case OPTION_ERASE_SELECTION: { - - if (!selection_active) - return; - - undo_redo->create_action("Erase Selection"); - for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) { - for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) { - - _set_cell(Point2i(j, i), TileMap::INVALID_CELL, false, false, false, true); - } - } - undo_redo->commit_action(); - - selection_active=false; - copydata.clear(); - - canvas_item_editor->update(); - } break; - } -} - -void TileMapEditor::_canvas_mouse_enter() { - - mouse_over=true; - canvas_item_editor->update(); -} - -void TileMapEditor::_canvas_mouse_exit() { - - mouse_over=false; - canvas_item_editor->update(); -} - -int TileMapEditor::get_selected_tile() const { - - int item = palette->get_current(); - - if (item==-1) - return TileMap::INVALID_CELL; - - return palette->get_item_metadata(item); -} - -void TileMapEditor::set_selected_tile(int p_tile) { - - int idx = palette->find_metadata(p_tile); - - if (idx >= 0) { - palette->select(idx, true); - palette->ensure_current_is_visible(); - } -} - -void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose,bool p_with_undo) { - - ERR_FAIL_COND(!node); - - int prev_val=node->get_cell(p_pos.x,p_pos.y); - - bool prev_flip_h=node->is_cell_x_flipped(p_pos.x,p_pos.y); - bool prev_flip_v=node->is_cell_y_flipped(p_pos.x,p_pos.y); - bool prev_transpose=node->is_cell_transposed(p_pos.x,p_pos.y); - - if (p_value==prev_val && p_flip_h==prev_flip_h && p_flip_v==prev_flip_v && p_transpose==prev_transpose) - return; //check that it's actually different - - if (p_with_undo) { - - undo_redo->add_do_method(node,"set_cellv",Point2(p_pos),p_value,p_flip_h,p_flip_v,p_transpose); - undo_redo->add_undo_method(node,"set_cellv",Point2(p_pos),prev_val,prev_flip_h,prev_flip_v,prev_transpose); - } else { - - node->set_cell(p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v,p_transpose); - } - -} - -void TileMapEditor::_text_entered(const String& p_text) { - - canvas_item_editor->grab_focus(); -} - -void TileMapEditor::_text_changed(const String& p_text) { - - _update_palette(); -} - -void TileMapEditor::_sbox_input(const InputEvent& p_ie) { - - if (p_ie.type==InputEvent::KEY && ( - p_ie.key.scancode == KEY_UP || - p_ie.key.scancode == KEY_DOWN || - p_ie.key.scancode == KEY_PAGEUP || - p_ie.key.scancode == KEY_PAGEDOWN ) ) { - - palette->call("_gui_input", p_ie); - search_box->accept_event(); - } -} - -void TileMapEditor::_update_palette() { - - if (!node) - return; - - int selected = get_selected_tile(); - palette->clear(); - - Ref<TileSet> tileset=node->get_tileset(); - if (tileset.is_null()) - return; - - List<int> tiles; - tileset->get_tile_list(&tiles); - - if (tiles.empty()) - return; - - float min_size = EDITOR_DEF("editors/tile_map/preview_size", 64); - min_size *= EDSCALE; - int hseparation = EDITOR_DEF("editors/tile_map/palette_item_hseparation",8); - bool show_tile_names = bool(EDITOR_DEF("editors/tile_map/show_tile_names", true)); - - palette->add_constant_override("hseparation", hseparation*EDSCALE); - palette->add_constant_override("vseparation", 8*EDSCALE); - - palette->set_fixed_icon_size(Size2(min_size, min_size)); - palette->set_fixed_column_width(min_size * MAX(size_slider->get_value(), 1)); - - String filter = search_box->get_text().strip_edges(); - - for (List<int>::Element *E=tiles.front();E;E=E->next()) { - - String name; - - if (tileset->tile_get_name(E->get())!="") { - name = itos(E->get())+" - "+tileset->tile_get_name(E->get()); - } else { - name = "#"+itos(E->get()); - } - - if (filter != "" && !filter.is_subsequence_ofi(name)) - continue; - - if (show_tile_names) { - palette->add_item(name); - } else { - palette->add_item(String()); - } - - Ref<Texture> tex = tileset->tile_get_texture(E->get()); - - if (tex.is_valid()) { - Rect2 region = tileset->tile_get_region(E->get()); - - if (!region.has_no_area()) - palette->set_item_icon_region(palette->get_item_count()-1, region); - - palette->set_item_icon(palette->get_item_count()-1, tex); - } - - palette->set_item_metadata(palette->get_item_count()-1, E->get()); - } - - palette->set_same_column_width(true); - - if (selected != -1) - set_selected_tile(selected); - else - palette->select(0); -} - -void TileMapEditor::_pick_tile(const Point2& p_pos) { - - int id = node->get_cell(p_pos.x, p_pos.y); - - if (id==TileMap::INVALID_CELL) - return; - - if (search_box->get_text().strip_edges() != "") { - - search_box->set_text(""); - _update_palette(); - } - - set_selected_tile(id); - - mirror_x->set_pressed(node->is_cell_x_flipped(p_pos.x, p_pos.y)); - mirror_y->set_pressed(node->is_cell_y_flipped(p_pos.x, p_pos.y)); - transp->set_pressed(node->is_cell_transposed(p_pos.x, p_pos.y)); - - _update_transform_buttons(); - canvas_item_editor->update(); -} - -PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i& p_start, bool erase, bool preview) { - - int prev_id = node->get_cell(p_start.x, p_start.y); - int id = TileMap::INVALID_CELL; - if (!erase) { - id = get_selected_tile(); - - if (id == TileMap::INVALID_CELL) - return PoolVector<Vector2>(); - } - - Rect2i r = node->get_item_rect(); - r.pos = r.pos/node->get_cell_size(); - r.size = r.size/node->get_cell_size(); - - int area = r.get_area(); - if(preview) { - // Test if we can re-use the result from preview bucket fill - bool invalidate_cache = false; - // Area changed - if(r != bucket_cache_rect) - _clear_bucket_cache(); - // Cache grid is not initialized - if(bucket_cache_visited == 0) { - bucket_cache_visited = new bool[area]; - invalidate_cache = true; - } - // Tile ID changed or position wasn't visited by the previous fill - int loc = (p_start.x - r.get_pos().x) + (p_start.y - r.get_pos().y) * r.get_size().x; - if(prev_id != bucket_cache_tile || !bucket_cache_visited[loc]) { - invalidate_cache = true; - } - if(invalidate_cache) { - for(int i = 0; i < area; ++i) - bucket_cache_visited[i] = false; - bucket_cache = PoolVector<Vector2>(); - bucket_cache_tile = prev_id; - bucket_cache_rect = r; - } - else { - return bucket_cache; - } - } - - PoolVector<Vector2> points; - - List<Point2i> queue; - queue.push_back(p_start); - - while (queue.size()) { - - Point2i n = queue.front()->get(); - queue.pop_front(); - - if (!r.has_point(n)) - continue; - - if (node->get_cell(n.x, n.y) == prev_id) { - - if(preview) { - int loc = (n.x - r.get_pos().x) + (n.y - r.get_pos().y) * r.get_size().x; - if(bucket_cache_visited[loc]) - continue; - bucket_cache_visited[loc] = true; - bucket_cache.push_back(n); - } - else { - node->set_cellv(n, id, flip_h, flip_v, transpose); - points.push_back(n); - } - - queue.push_back(n + Point2i(0, 1)); - queue.push_back(n + Point2i(0, -1)); - queue.push_back(n + Point2i(1, 0)); - queue.push_back(n + Point2i(-1, 0)); - } - } - - return preview ? bucket_cache : points; -} - -void TileMapEditor::_fill_points(const PoolVector<Vector2> p_points, const Dictionary& p_op) { - - int len = p_points.size(); - PoolVector<Vector2>::Read pr = p_points.read(); - - int id = p_op["id"]; - bool xf = p_op["flip_h"]; - bool yf = p_op["flip_v"]; - bool tr = p_op["transpose"]; - - for (int i=0;i<len;i++) { - - _set_cell(pr[i], id, xf, yf, tr); - } -} - -void TileMapEditor::_erase_points(const PoolVector<Vector2> p_points) { - - int len = p_points.size(); - PoolVector<Vector2>::Read pr = p_points.read(); - - for (int i=0;i<len;i++) { - - _set_cell(pr[i], TileMap::INVALID_CELL); - } -} - -void TileMapEditor::_select(const Point2i& p_from, const Point2i& p_to) { - - Point2i begin=p_from; - Point2i end=p_to; - - if (begin.x > end.x) { - - SWAP( begin.x, end.x); - } - if (begin.y > end.y) { - - SWAP( begin.y, end.y); - } - - rectangle.pos=begin; - rectangle.size=end-begin; - - canvas_item_editor->update(); -} - -void TileMapEditor::_draw_cell(int p_cell, const Point2i& p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D& p_xform) { - - Ref<Texture> t = node->get_tileset()->tile_get_texture(p_cell); - - if (t.is_null()) - return; - - Vector2 tile_ofs = node->get_tileset()->tile_get_texture_offset(p_cell); - - Rect2 r = node->get_tileset()->tile_get_region(p_cell); - Size2 sc = p_xform.get_scale(); - - Rect2 rect = Rect2(); - rect.pos = node->map_to_world(p_point) + node->get_cell_draw_offset(); - - if (r.has_no_area()) { - rect.size = t->get_size(); - } else { - rect.size = r.size; - } - - if (rect.size.y > rect.size.x) { - if ((p_flip_h && (p_flip_v || p_transpose)) || (p_flip_v && !p_transpose)) - tile_ofs.y += rect.size.y - rect.size.x; - } else if (rect.size.y < rect.size.x) { - if ((p_flip_v && (p_flip_h || p_transpose)) || (p_flip_h && !p_transpose)) - tile_ofs.x += rect.size.x - rect.size.y; - } - - if (p_transpose) { - SWAP(tile_ofs.x, tile_ofs.y); - } - if (p_flip_h) { - sc.x*=-1.0; - tile_ofs.x*=-1.0; - } - if (p_flip_v) { - sc.y*=-1.0; - tile_ofs.y*=-1.0; - } - - if (node->get_tile_origin()==TileMap::TILE_ORIGIN_TOP_LEFT) { - - rect.pos+=tile_ofs; - } else if (node->get_tile_origin()==TileMap::TILE_ORIGIN_BOTTOM_LEFT) { - Size2 cell_size = node->get_cell_size(); - - rect.pos+=tile_ofs; - - if(p_transpose) - { - if(p_flip_h) - rect.pos.x-=cell_size.x; - else - rect.pos.x+=cell_size.x; - } else { - if(p_flip_v) - rect.pos.y-=cell_size.y; - else - rect.pos.y+=cell_size.y; - } - - } else if (node->get_tile_origin()==TileMap::TILE_ORIGIN_CENTER) { - rect.pos+=node->get_cell_size()/2; - Vector2 s = r.size; - - Vector2 center = (s/2) - tile_ofs; - - if (p_flip_h) - rect.pos.x-=s.x-center.x; - else - rect.pos.x-=center.x; - - if (p_flip_v) - rect.pos.y-=s.y-center.y; - else - rect.pos.y-=center.y; - } - - rect.pos=p_xform.xform(rect.pos); - rect.size*=sc; - - if (r.has_no_area()) - canvas_item_editor->draw_texture_rect(t, rect, false, Color(1,1,1,0.5), p_transpose); - else - canvas_item_editor->draw_texture_rect_region(t, rect, r, Color(1,1,1,0.5), p_transpose); -} - -void TileMapEditor::_draw_fill_preview(int p_cell, const Point2i& p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D& p_xform) { - - PoolVector<Vector2> points = _bucket_fill(p_point, false, true); - PoolVector<Vector2>::Read pr = points.read(); - int len = points.size(); - int time_after = OS::get_singleton()->get_ticks_msec(); - - for(int i = 0; i < len; ++i) { - _draw_cell(p_cell, pr[i], p_flip_h, p_flip_v, p_transpose, p_xform); - } -} - -void TileMapEditor::_clear_bucket_cache() { - if(bucket_cache_visited) { - delete[] bucket_cache_visited; - bucket_cache_visited = 0; - } -} - -void TileMapEditor::_update_copydata() { - - copydata.clear(); - - if (!selection_active) - return; - - for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) { - - for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) { - - TileData tcd; - - tcd.cell=node->get_cell(j, i); - - if (tcd.cell!=TileMap::INVALID_CELL) { - tcd.pos=Point2i(j, i); - tcd.flip_h=node->is_cell_x_flipped(j,i); - tcd.flip_v=node->is_cell_y_flipped(j,i); - tcd.transpose=node->is_cell_transposed(j,i); - } - - copydata.push_back(tcd); - } - } -} - -static inline Vector<Point2i> line(int x0, int x1, int y0, int y1) { - - Vector<Point2i> points; - - float dx = ABS(x1 - x0); - float dy = ABS(y1 - y0); - - int x = x0; - int y = y0; - - int sx = x0 > x1 ? -1 : 1; - int sy = y0 > y1 ? -1 : 1; - - if (dx > dy) { - float err = dx/2; - - for (; x != x1; x += sx) { - points.push_back(Vector2(x, y)); - - err -= dy; - if (err < 0) { - y += sy; - err += dx; - } - } - } else { - float err = dy/2; - - for (; y != y1; y += sy) { - points.push_back(Vector2(x, y)); - - err -= dx; - if (err < 0) { - x += sx; - err += dy; - } - } - } - - points.push_back(Vector2(x, y)); - - return points; -} - -bool TileMapEditor::forward_gui_input(const InputEvent& p_event) { - - if (!node || !node->get_tileset().is_valid() || !node->is_visible_in_tree()) - return false; - - Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform(); - Transform2D xform_inv = xform.affine_inverse(); - - switch(p_event.type) { - - case InputEvent::MOUSE_BUTTON: { - - const InputEventMouseButton &mb=p_event.mouse_button; - - if (mb.button_index==BUTTON_LEFT) { - - if (mb.pressed) { - - if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) - return false; //drag - - if (tool==TOOL_NONE) { - - if (mb.mod.shift) { - - if (mb.mod.control) - tool=TOOL_RECTANGLE_PAINT; - else - tool=TOOL_LINE_PAINT; - - selection_active=false; - rectangle_begin=over_tile; - - return true; - } - - if (mb.mod.control) { - - tool=TOOL_PICKING; - _pick_tile(over_tile); - - return true; - } - - tool=TOOL_PAINTING; - } - - if (tool==TOOL_PAINTING) { - - int id = get_selected_tile(); - - if (id!=TileMap::INVALID_CELL) { - - tool=TOOL_PAINTING; - - paint_undo.clear(); - paint_undo[over_tile]=_get_op_from_cell(over_tile); - - _set_cell(over_tile, id, flip_h, flip_v, transpose); - } - } else if (tool==TOOL_PICKING) { - - _pick_tile(over_tile); - } else if (tool==TOOL_SELECTING) { - - selection_active=true; - rectangle_begin=over_tile; - } - - return true; - - } else { - - if (tool!=TOOL_NONE) { - - if (tool==TOOL_PAINTING) { - - int id=get_selected_tile(); - - if (id!=TileMap::INVALID_CELL && paint_undo.size()) { - - undo_redo->create_action(TTR("Paint TileMap")); - for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) { - - Point2 p=E->key(); - undo_redo->add_do_method(node,"set_cellv",p,id,flip_h,flip_v,transpose); - undo_redo->add_undo_method(node,"set_cellv",p,E->get().idx,E->get().xf,E->get().yf,E->get().tr); - } - undo_redo->commit_action(); - - paint_undo.clear(); - } - } else if (tool==TOOL_LINE_PAINT) { - - int id=get_selected_tile(); - - if (id!=TileMap::INVALID_CELL) { - - undo_redo->create_action("Line Draw"); - for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) { - - _set_cell(E->key(), id, flip_h, flip_v, transpose, true); - } - undo_redo->commit_action(); - - paint_undo.clear(); - - canvas_item_editor->update(); - } - } else if (tool==TOOL_RECTANGLE_PAINT) { - - int id=get_selected_tile(); - - if (id!=TileMap::INVALID_CELL) { - - undo_redo->create_action("Rectangle Paint"); - for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) { - for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) { - - _set_cell(Point2i(j, i), id, flip_h, flip_v, transpose, true); - } - } - undo_redo->commit_action(); - - canvas_item_editor->update(); - } - } else if (tool==TOOL_DUPLICATING) { - - Point2 ofs = over_tile-rectangle.pos; - - undo_redo->create_action(TTR("Duplicate")); - for (List<TileData>::Element *E=copydata.front();E;E=E->next()) { - - _set_cell(E->get().pos+ofs,E->get().cell,E->get().flip_h,E->get().flip_v,E->get().transpose,true); - } - undo_redo->commit_action(); - - copydata.clear(); - - canvas_item_editor->update(); - - } else if (tool==TOOL_SELECTING) { - - canvas_item_editor->update(); - - } else if (tool==TOOL_BUCKET) { - - Dictionary pop; - pop["id"] = node->get_cell(over_tile.x, over_tile.y); - pop["flip_h"] = node->is_cell_x_flipped(over_tile.x, over_tile.y); - pop["flip_v"] = node->is_cell_y_flipped(over_tile.x, over_tile.y); - pop["transpose"] = node->is_cell_transposed(over_tile.x, over_tile.y); - - PoolVector<Vector2> points = _bucket_fill(over_tile); - - if (points.size() == 0) - return false; - - Dictionary op; - op["id"] = get_selected_tile(); - op["flip_h"] = flip_h; - op["flip_v"] = flip_v; - op["transpose"] = transpose; - - undo_redo->create_action("Bucket Fill"); - - undo_redo->add_do_method(this, "_fill_points", points, op); - undo_redo->add_undo_method(this, "_fill_points", points, pop); - - undo_redo->commit_action(); - } - - tool=TOOL_NONE; - - return true; - } - } - } else if (mb.button_index==BUTTON_RIGHT) { - - if (mb.pressed) { - - if (tool==TOOL_SELECTING || selection_active) { - - tool=TOOL_NONE; - selection_active=false; - - canvas_item_editor->update(); - - return true; - } - - if (tool==TOOL_DUPLICATING) { - - tool=TOOL_NONE; - copydata.clear(); - - canvas_item_editor->update(); - - return true; - } - - if (tool==TOOL_NONE) { - - paint_undo.clear(); - - Point2 local = node->world_to_map(xform_inv.xform(Point2(mb.x, mb.y))); - - if (mb.mod.shift) { - - if (mb.mod.control) - tool=TOOL_RECTANGLE_ERASE; - else - tool=TOOL_LINE_ERASE; - - selection_active=false; - rectangle_begin=local; - } else { - - tool=TOOL_ERASING; - - paint_undo[local]=_get_op_from_cell(local); - _set_cell(local, TileMap::INVALID_CELL); - } - - return true; - } - - } else { - if (tool==TOOL_ERASING || tool==TOOL_RECTANGLE_ERASE || tool==TOOL_LINE_ERASE) { - - if (paint_undo.size()) { - undo_redo->create_action(TTR("Erase TileMap")); - for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) { - - Point2 p=E->key(); - undo_redo->add_do_method(node,"set_cellv",p,TileMap::INVALID_CELL,false,false,false); - undo_redo->add_undo_method(node,"set_cellv",p,E->get().idx,E->get().xf,E->get().yf,E->get().tr); - } - - undo_redo->commit_action(); - paint_undo.clear(); - } - - if (tool==TOOL_RECTANGLE_ERASE || tool==TOOL_LINE_ERASE) { - canvas_item_editor->update(); - } - - tool=TOOL_NONE; - - return true; - - } else if (tool==TOOL_BUCKET) { - - Dictionary pop; - pop["id"] = node->get_cell(over_tile.x, over_tile.y); - pop["flip_h"] = node->is_cell_x_flipped(over_tile.x, over_tile.y); - pop["flip_v"] = node->is_cell_y_flipped(over_tile.x, over_tile.y); - pop["transpose"] = node->is_cell_transposed(over_tile.x, over_tile.y); - - PoolVector<Vector2> points = _bucket_fill(over_tile, true); - - if (points.size() == 0) - return false; - - undo_redo->create_action("Bucket Fill"); - - undo_redo->add_do_method(this, "_erase_points", points); - undo_redo->add_undo_method(this, "_fill_points", points, pop); - - undo_redo->commit_action(); - } - } - } - } break; - case InputEvent::MOUSE_MOTION: { - - const InputEventMouseMotion &mm=p_event.mouse_motion; - - Point2i new_over_tile = node->world_to_map(xform_inv.xform(Point2(mm.x,mm.y))); - - if (new_over_tile!=over_tile) { - - over_tile=new_over_tile; - canvas_item_editor->update(); - } - - int tile_under = node->get_cell(over_tile.x, over_tile.y); - String tile_name = "none"; - - if (node->get_tileset()->has_tile(tile_under)) - tile_name = node->get_tileset()->tile_get_name(tile_under); - tile_info->set_text(String::num(over_tile.x)+", "+String::num(over_tile.y)+" ["+tile_name+"]"); - - if (tool==TOOL_PAINTING) { - - int id = get_selected_tile(); - if (id!=TileMap::INVALID_CELL) { - - if (!paint_undo.has(over_tile)) { - paint_undo[over_tile]=_get_op_from_cell(over_tile); - } - - _set_cell(over_tile, id, flip_h, flip_v, transpose); - - return true; - } - } - - if (tool==TOOL_SELECTING) { - - _select(rectangle_begin, over_tile); - - return true; - } - - if (tool==TOOL_LINE_PAINT || tool==TOOL_LINE_ERASE) { - - int id = get_selected_tile(); - bool erasing = (tool==TOOL_LINE_ERASE); - - if (erasing && paint_undo.size()) { - - for (Map<Point2i, CellOp>::Element *E=paint_undo.front();E;E=E->next()) { - - _set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr); - } - } - - paint_undo.clear(); - - if (id!=TileMap::INVALID_CELL) { - - Vector<Point2i> points = line(rectangle_begin.x, over_tile.x, rectangle_begin.y, over_tile.y); - - for (int i=0;i<points.size();i++) { - - paint_undo[points[i]]=_get_op_from_cell(points[i]); - - if (erasing) - _set_cell(points[i], TileMap::INVALID_CELL); - } - - canvas_item_editor->update(); - } - - return true; - } - if (tool==TOOL_RECTANGLE_PAINT || tool==TOOL_RECTANGLE_ERASE) { - - _select(rectangle_begin, over_tile); - - if (tool==TOOL_RECTANGLE_ERASE) { - - if (paint_undo.size()) { - - for (Map<Point2i, CellOp>::Element *E=paint_undo.front();E;E=E->next()) { - - _set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr); - } - } - - paint_undo.clear(); - - for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) { - for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) { - - Point2i tile = Point2i(j, i); - paint_undo[tile]=_get_op_from_cell(tile); - - _set_cell(tile, TileMap::INVALID_CELL); - } - } - } - - return true; - } - if (tool==TOOL_ERASING) { - - if (!paint_undo.has(over_tile)) { - paint_undo[over_tile]=_get_op_from_cell(over_tile); - } - - _set_cell(over_tile, TileMap::INVALID_CELL); - - return true; - } - if (tool==TOOL_PICKING && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) { - - _pick_tile(over_tile); - - return true; - } - } break; - case InputEvent::KEY: { - - const InputEventKey &k = p_event.key; - - if (!k.pressed) - break; - - if (k.scancode==KEY_ESCAPE) { - - if (tool==TOOL_DUPLICATING) - copydata.clear(); - else if (tool==TOOL_SELECTING || selection_active) - selection_active=false; - - tool=TOOL_NONE; - - canvas_item_editor->update(); - - return true; - } - - if (tool!=TOOL_NONE || !mouse_over) - return false; - - if (ED_IS_SHORTCUT("tile_map_editor/erase_selection", p_event)) { - _menu_option(OPTION_ERASE_SELECTION); - - return true; - } - if (ED_IS_SHORTCUT("tile_map_editor/select", p_event)) { - tool=TOOL_SELECTING; - selection_active=false; - - canvas_item_editor->update(); - - return true; - } - if (ED_IS_SHORTCUT("tile_map_editor/duplicate_selection", p_event)) { - _update_copydata(); - - if (selection_active) { - tool=TOOL_DUPLICATING; - - canvas_item_editor->update(); - - return true; - } - } - if (ED_IS_SHORTCUT("tile_map_editor/find_tile", p_event)) { - search_box->select_all(); - search_box->grab_focus(); - - return true; - } - if (ED_IS_SHORTCUT("tile_map_editor/mirror_x", p_event)) { - flip_h=!flip_h; - mirror_x->set_pressed(flip_h); - canvas_item_editor->update(); - return true; - } - if (ED_IS_SHORTCUT("tile_map_editor/mirror_y", p_event)) { - flip_v=!flip_v; - mirror_y->set_pressed(flip_v); - canvas_item_editor->update(); - return true; - } - if (ED_IS_SHORTCUT("tile_map_editor/transpose", p_event)) { - transpose = !transpose; - transp->set_pressed(transpose); - canvas_item_editor->update(); - return true; - } - } break; - } - - return false; -} - -void TileMapEditor::_canvas_draw() { - - if (!node) - return; - - Transform2D cell_xf = node->get_cell_transform(); - - Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform(); - Transform2D xform_inv = xform.affine_inverse(); - - - Size2 screen_size=canvas_item_editor->get_size(); - { - Rect2 aabb; - aabb.pos=node->world_to_map(xform_inv.xform(Vector2())); - aabb.expand_to(node->world_to_map(xform_inv.xform(Vector2(0,screen_size.height)))); - aabb.expand_to(node->world_to_map(xform_inv.xform(Vector2(screen_size.width,0)))); - aabb.expand_to(node->world_to_map(xform_inv.xform(screen_size))); - Rect2i si=aabb.grow(1.0); - - if (node->get_half_offset()!=TileMap::HALF_OFFSET_X) { - - int max_lines=2000; //avoid crash if size too smal - - for (int i=(si.pos.x)-1;i<=(si.pos.x+si.size.x);i++) { - - Vector2 from = xform.xform(node->map_to_world(Vector2(i,si.pos.y))); - Vector2 to = xform.xform(node->map_to_world(Vector2(i,si.pos.y+si.size.y+1))); - - Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); - canvas_item_editor->draw_line(from,to,col,1); - if (max_lines--==0) - break; - } - } else { - - int max_lines=10000; //avoid crash if size too smal - - for (int i=(si.pos.x)-1;i<=(si.pos.x+si.size.x);i++) { - - for (int j=(si.pos.y)-1;j<=(si.pos.y+si.size.y);j++) { - - Vector2 ofs; - if (ABS(j)&1) { - ofs=cell_xf[0]*0.5; - } - - Vector2 from = xform.xform(node->map_to_world(Vector2(i,j),true)+ofs); - Vector2 to = xform.xform(node->map_to_world(Vector2(i,j+1),true)+ofs); - Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); - canvas_item_editor->draw_line(from,to,col,1); - - if (max_lines--==0) - break; - - } - - } - } - - int max_lines=10000; //avoid crash if size too smal - - if (node->get_half_offset()!=TileMap::HALF_OFFSET_Y) { - - for (int i=(si.pos.y)-1;i<=(si.pos.y+si.size.y);i++) { - - Vector2 from = xform.xform(node->map_to_world(Vector2(si.pos.x,i))); - Vector2 to = xform.xform(node->map_to_world(Vector2(si.pos.x+si.size.x+1,i))); - - Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); - canvas_item_editor->draw_line(from,to,col,1); - - if (max_lines--==0) - break; - - } - } else { - - - for (int i=(si.pos.y)-1;i<=(si.pos.y+si.size.y);i++) { - - for (int j=(si.pos.x)-1;j<=(si.pos.x+si.size.x);j++) { - - Vector2 ofs; - if (ABS(j)&1) { - ofs=cell_xf[1]*0.5; - } - - Vector2 from = xform.xform(node->map_to_world(Vector2(j,i),true)+ofs); - Vector2 to = xform.xform(node->map_to_world(Vector2(j+1,i),true)+ofs); - Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); - canvas_item_editor->draw_line(from,to,col,1); - - if (max_lines--==0) - break; - - } - } - } - } - - if (selection_active) { - - Vector<Vector2> points; - points.push_back( xform.xform( node->map_to_world(( rectangle.pos ) ))); - points.push_back( xform.xform( node->map_to_world((rectangle.pos+Point2(rectangle.size.x+1,0)) ) )); - points.push_back( xform.xform( node->map_to_world((rectangle.pos+Point2(rectangle.size.x+1,rectangle.size.y+1)) ) )); - points.push_back( xform.xform( node->map_to_world((rectangle.pos+Point2(0,rectangle.size.y+1)) ) )); - - canvas_item_editor->draw_colored_polygon(points, Color(0.2,0.8,1,0.4)); - } - - if (mouse_over){ - - Vector2 endpoints[4]={ - node->map_to_world(over_tile, true), - node->map_to_world((over_tile+Point2(1,0)), true), - node->map_to_world((over_tile+Point2(1,1)), true), - node->map_to_world((over_tile+Point2(0,1)), true) - }; - - for (int i=0;i<4;i++) { - if (node->get_half_offset()==TileMap::HALF_OFFSET_X && ABS(over_tile.y)&1) - endpoints[i]+=cell_xf[0]*0.5; - if (node->get_half_offset()==TileMap::HALF_OFFSET_Y && ABS(over_tile.x)&1) - endpoints[i]+=cell_xf[1]*0.5; - endpoints[i]=xform.xform(endpoints[i]); - } - Color col; - if (node->get_cell(over_tile.x,over_tile.y)!=TileMap::INVALID_CELL) - col=Color(0.2,0.8,1.0,0.8); - else - col=Color(1.0,0.4,0.2,0.8); - - for (int i=0;i<4;i++) - canvas_item_editor->draw_line(endpoints[i],endpoints[(i+1)%4],col,2); - - - bool bucket_preview = EditorSettings::get_singleton()->get("editors/tile_map/bucket_fill_preview"); - if (tool==TOOL_SELECTING || tool==TOOL_PICKING || !bucket_preview) { - return; - } - - if (tool==TOOL_LINE_PAINT) { - - if (paint_undo.empty()) - return; - - int id = get_selected_tile(); - - if (id==TileMap::INVALID_CELL) - return; - - for (Map<Point2i, CellOp>::Element *E=paint_undo.front();E;E=E->next()) { - - _draw_cell(id, E->key(), flip_h, flip_v, transpose, xform); - } - - } else if (tool==TOOL_RECTANGLE_PAINT) { - - int id = get_selected_tile(); - - if (id==TileMap::INVALID_CELL) - return; - - for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) { - for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) { - - _draw_cell(id, Point2i(j, i), flip_h, flip_v, transpose, xform); - } - } - } else if (tool==TOOL_DUPLICATING) { - - if (copydata.empty()) - return; - - Ref<TileSet> ts = node->get_tileset(); - - if (ts.is_null()) - return; - - Point2 ofs = over_tile-rectangle.pos; - - for (List<TileData>::Element *E=copydata.front();E;E=E->next()) { - - if (!ts->has_tile(E->get().cell)) - continue; - - TileData tcd = E->get(); - - _draw_cell(tcd.cell, tcd.pos+ofs, tcd.flip_h, tcd.flip_v, tcd.transpose, xform); - } - - Rect2i duplicate=rectangle; - duplicate.pos=over_tile; - - Vector<Vector2> points; - points.push_back( xform.xform( node->map_to_world(duplicate.pos ) )); - points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(duplicate.size.x+1,0)) ) )); - points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(duplicate.size.x+1,duplicate.size.y+1))) )); - points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(0,duplicate.size.y+1))) )); - - canvas_item_editor->draw_colored_polygon(points, Color(0.2,1.0,0.8,0.2)); - - } else if(tool == TOOL_BUCKET) { - - int tile = get_selected_tile(); - _draw_fill_preview(tile, over_tile, flip_h, flip_v, transpose, xform); - - } else { - - int st = get_selected_tile(); - - if (st==TileMap::INVALID_CELL) - return; - - _draw_cell(st, over_tile, flip_h, flip_v, transpose, xform); - } - } -} - -void TileMapEditor::edit(Node *p_tile_map) { - - search_box->set_text(""); - - if (!canvas_item_editor) { - canvas_item_editor=CanvasItemEditor::get_singleton()->get_viewport_control(); - } - - if (node) - node->disconnect("settings_changed",this,"_tileset_settings_changed"); - if (p_tile_map) { - - node=p_tile_map->cast_to<TileMap>(); - if (!canvas_item_editor->is_connected("draw",this,"_canvas_draw")) - canvas_item_editor->connect("draw",this,"_canvas_draw"); - if (!canvas_item_editor->is_connected("mouse_entered",this,"_canvas_mouse_enter")) - canvas_item_editor->connect("mouse_entered",this,"_canvas_mouse_enter"); - if (!canvas_item_editor->is_connected("mouse_exited",this,"_canvas_mouse_exit")) - canvas_item_editor->connect("mouse_exited",this,"_canvas_mouse_exit"); - - _update_palette(); - - } else { - node=NULL; - - if (canvas_item_editor->is_connected("draw",this,"_canvas_draw")) - canvas_item_editor->disconnect("draw",this,"_canvas_draw"); - if (canvas_item_editor->is_connected("mouse_entered",this,"_canvas_mouse_enter")) - canvas_item_editor->disconnect("mouse_entered",this,"_canvas_mouse_enter"); - if (canvas_item_editor->is_connected("mouse_exited",this,"_canvas_mouse_exit")) - canvas_item_editor->disconnect("mouse_exited",this,"_canvas_mouse_exit"); - - _update_palette(); - } - - if (node) - node->connect("settings_changed",this,"_tileset_settings_changed"); - - _clear_bucket_cache(); - -} - -void TileMapEditor::_tileset_settings_changed() { - - _update_palette(); - - if (canvas_item_editor) - canvas_item_editor->update(); -} - -void TileMapEditor::_icon_size_changed(float p_value) { - if (node) { - palette->set_icon_scale(p_value); - _update_palette(); - } -} - -void TileMapEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_text_entered"),&TileMapEditor::_text_entered); - ClassDB::bind_method(D_METHOD("_text_changed"),&TileMapEditor::_text_changed); - ClassDB::bind_method(D_METHOD("_sbox_input"),&TileMapEditor::_sbox_input); - ClassDB::bind_method(D_METHOD("_menu_option"),&TileMapEditor::_menu_option); - ClassDB::bind_method(D_METHOD("_canvas_draw"),&TileMapEditor::_canvas_draw); - ClassDB::bind_method(D_METHOD("_canvas_mouse_enter"),&TileMapEditor::_canvas_mouse_enter); - ClassDB::bind_method(D_METHOD("_canvas_mouse_exit"),&TileMapEditor::_canvas_mouse_exit); - ClassDB::bind_method(D_METHOD("_tileset_settings_changed"),&TileMapEditor::_tileset_settings_changed); - ClassDB::bind_method(D_METHOD("_update_transform_buttons"),&TileMapEditor::_update_transform_buttons); - - ClassDB::bind_method(D_METHOD("_fill_points"),&TileMapEditor::_fill_points); - ClassDB::bind_method(D_METHOD("_erase_points"),&TileMapEditor::_erase_points); - - ClassDB::bind_method(D_METHOD("_icon_size_changed"), &TileMapEditor::_icon_size_changed); -} - -TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i& p_pos) -{ - CellOp op; - op.idx = node->get_cell(p_pos.x,p_pos.y); - if (op.idx!=TileMap::INVALID_CELL) { - if (node->is_cell_x_flipped(p_pos.x,p_pos.y)) - op.xf=true; - if (node->is_cell_y_flipped(p_pos.x,p_pos.y)) - op.yf=true; - if (node->is_cell_transposed(p_pos.x,p_pos.y)) - op.tr=true; - } - return op; -} - -void TileMapEditor::_update_transform_buttons(Object *p_button) { - //ERR_FAIL_NULL(p_button); - ToolButton *b=p_button->cast_to<ToolButton>(); - //ERR_FAIL_COND(!b); - - if (b == rotate_0) { - mirror_x->set_pressed(false); - mirror_y->set_pressed(false); - transp->set_pressed(false); - } - else if (b == rotate_90) { - mirror_x->set_pressed(true); - mirror_y->set_pressed(false); - transp->set_pressed(true); - } - else if (b == rotate_180) { - mirror_x->set_pressed(true); - mirror_y->set_pressed(true); - transp->set_pressed(false); - } - else if (b == rotate_270) { - mirror_x->set_pressed(false); - mirror_y->set_pressed(true); - transp->set_pressed(true); - } - - flip_h=mirror_x->is_pressed(); - flip_v=mirror_y->is_pressed(); - transpose=transp->is_pressed(); - - rotate_0->set_pressed(!flip_h && !flip_v && !transpose); - rotate_90->set_pressed(flip_h && !flip_v && transpose); - rotate_180->set_pressed(flip_h && flip_v && !transpose); - rotate_270->set_pressed(!flip_h && flip_v && transpose); -} - -TileMapEditor::TileMapEditor(EditorNode *p_editor) { - - node=NULL; - canvas_item_editor=NULL; - editor=p_editor; - undo_redo=editor->get_undo_redo(); - - tool=TOOL_NONE; - selection_active=false; - mouse_over=false; - - flip_h=false; - flip_v=false; - transpose=false; - - bucket_cache_tile = -1; - bucket_cache_visited = 0; - - ED_SHORTCUT("tile_map_editor/erase_selection", TTR("Erase selection"), KEY_DELETE); - ED_SHORTCUT("tile_map_editor/find_tile", TTR("Find tile"), KEY_MASK_CMD+KEY_F); - ED_SHORTCUT("tile_map_editor/transpose", TTR("Transpose")); - ED_SHORTCUT("tile_map_editor/mirror_x", TTR("Mirror X"), KEY_A); - ED_SHORTCUT("tile_map_editor/mirror_y", TTR("Mirror Y"), KEY_S); - - search_box = memnew( LineEdit ); - search_box->set_h_size_flags(SIZE_EXPAND_FILL); - search_box->connect("text_entered", this, "_text_entered"); - search_box->connect("text_changed", this, "_text_changed"); - search_box->connect("gui_input", this, "_sbox_input"); - add_child(search_box); - - size_slider = memnew( HSlider ); - size_slider->set_h_size_flags(SIZE_EXPAND_FILL); - size_slider->set_min(0.1f); - size_slider->set_max(4.0f); - size_slider->set_step(0.1f); - size_slider->set_value(1.0f); - size_slider->connect("value_changed", this, "_icon_size_changed"); - add_child(size_slider); - - int mw = EDITOR_DEF("editors/tile_map/palette_min_width", 80); - - // Add tile palette - palette = memnew( ItemList ); - palette->set_v_size_flags(SIZE_EXPAND_FILL); - palette->set_custom_minimum_size(Size2(mw,0)); - palette->set_max_columns(0); - palette->set_icon_mode(ItemList::ICON_MODE_TOP); - palette->set_max_text_lines(2); - add_child(palette); - - // Add menu items - toolbar = memnew( HBoxContainer ); - toolbar->set_h_size_flags(SIZE_EXPAND_FILL); - toolbar->set_alignment(BoxContainer::ALIGN_END); - CanvasItemEditor::get_singleton()->add_control_to_menu_panel(toolbar); - - // Tile position - tile_info = memnew( Label ); - toolbar->add_child(tile_info); - - options = memnew( MenuButton ); - options->set_text("Tile Map"); - options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("TileMap", "EditorIcons")); - options->set_process_unhandled_key_input(false); - - PopupMenu *p = options->get_popup(); - - p->add_item(TTR("Bucket"), OPTION_BUCKET); - p->add_separator(); - p->add_item(TTR("Pick Tile"), OPTION_PICK_TILE, KEY_CONTROL); - p->add_separator(); - p->add_shortcut(ED_SHORTCUT("tile_map_editor/select", TTR("Select"), KEY_MASK_CMD+KEY_B), OPTION_SELECT); - p->add_shortcut(ED_SHORTCUT("tile_map_editor/duplicate_selection", TTR("Duplicate Selection"), KEY_MASK_CMD+KEY_D), OPTION_DUPLICATE); - p->add_shortcut(ED_GET_SHORTCUT("tile_map_editor/erase_selection"), OPTION_ERASE_SELECTION); - - p->connect("id_pressed", this, "_menu_option"); - - toolbar->add_child(options); - - toolbar->add_child( memnew( VSeparator ) ); - - transp = memnew( ToolButton ); - transp->set_toggle_mode(true); - transp->set_tooltip(TTR("Transpose") + " ("+ED_GET_SHORTCUT("tile_map_editor/transpose")->get_as_text()+")"); - transp->set_focus_mode(FOCUS_NONE); - transp->connect("pressed", this, "_update_transform_buttons", make_binds(transp)); - toolbar->add_child(transp); - mirror_x = memnew( ToolButton ); - mirror_x->set_toggle_mode(true); - mirror_x->set_tooltip(TTR("Mirror X") + " ("+ED_GET_SHORTCUT("tile_map_editor/mirror_x")->get_as_text()+")"); - mirror_x->set_focus_mode(FOCUS_NONE); - mirror_x->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_x)); - toolbar->add_child(mirror_x); - mirror_y = memnew( ToolButton ); - mirror_y->set_toggle_mode(true); - mirror_y->set_tooltip(TTR("Mirror Y") + " ("+ED_GET_SHORTCUT("tile_map_editor/mirror_y")->get_as_text()+")"); - mirror_y->set_focus_mode(FOCUS_NONE); - mirror_y->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_y)); - toolbar->add_child(mirror_y); - - toolbar->add_child( memnew( VSeparator ) ); - - rotate_0 = memnew( ToolButton ); - rotate_0->set_toggle_mode(true); - rotate_0->set_tooltip(TTR("Rotate 0 degrees")); - rotate_0->set_focus_mode(FOCUS_NONE); - rotate_0->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_0)); - toolbar->add_child(rotate_0); - rotate_90 = memnew( ToolButton ); - rotate_90->set_toggle_mode(true); - rotate_90->set_tooltip(TTR("Rotate 90 degrees")); - rotate_90->set_focus_mode(FOCUS_NONE); - rotate_90->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_90)); - toolbar->add_child(rotate_90); - rotate_180 = memnew( ToolButton ); - rotate_180->set_toggle_mode(true); - rotate_180->set_tooltip(TTR("Rotate 180 degrees")); - rotate_180->set_focus_mode(FOCUS_NONE); - rotate_180->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_180)); - toolbar->add_child(rotate_180); - rotate_270 = memnew( ToolButton ); - rotate_270->set_toggle_mode(true); - rotate_270->set_tooltip(TTR("Rotate 270 degrees")); - rotate_270->set_focus_mode(FOCUS_NONE); - rotate_270->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_270)); - toolbar->add_child(rotate_270); - toolbar->hide(); - - rotate_0->set_pressed(true); -} - -TileMapEditor::~TileMapEditor() { - _clear_bucket_cache(); -} - -/////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////// - -void TileMapEditorPlugin::edit(Object *p_object) { - - tile_map_editor->edit(p_object->cast_to<Node>()); -} - -bool TileMapEditorPlugin::handles(Object *p_object) const { - - return p_object->is_class("TileMap"); -} - -void TileMapEditorPlugin::make_visible(bool p_visible) { - - if (p_visible) { - - tile_map_editor->show(); - tile_map_editor->get_toolbar()->show(); - } else { - - tile_map_editor->hide(); - tile_map_editor->get_toolbar()->hide(); - tile_map_editor->edit(NULL); - } -} - -TileMapEditorPlugin::TileMapEditorPlugin(EditorNode *p_node) { - - EDITOR_DEF("editors/tile_map/preview_size",64); - EDITOR_DEF("editors/tile_map/palette_item_hseparation",8); - EDITOR_DEF("editors/tile_map/show_tile_names", true); - EDITOR_DEF("editors/tile_map/bucket_fill_preview", true); - - tile_map_editor = memnew( TileMapEditor(p_node) ); - add_control_to_container(CONTAINER_CANVAS_EDITOR_SIDE, tile_map_editor); - tile_map_editor->hide(); -} - -TileMapEditorPlugin::~TileMapEditorPlugin() -{ -} - diff --git a/tools/editor/plugins/tile_map_editor_plugin.h b/tools/editor/plugins/tile_map_editor_plugin.h deleted file mode 100644 index 08032d9afd..0000000000 --- a/tools/editor/plugins/tile_map_editor_plugin.h +++ /dev/null @@ -1,207 +0,0 @@ -/*************************************************************************/ -/* tile_map_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef TILE_MAP_EDITOR_PLUGIN_H -#define TILE_MAP_EDITOR_PLUGIN_H - -#include "tools/editor/editor_plugin.h" -#include "tools/editor/editor_node.h" - -#include "scene/2d/tile_map.h" -#include "scene/gui/line_edit.h" -#include "scene/gui/tool_button.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/label.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -class TileMapEditor : public VBoxContainer { - - GDCLASS(TileMapEditor, VBoxContainer ); - - enum Tool { - - TOOL_NONE, - TOOL_PAINTING, - TOOL_ERASING, - TOOL_RECTANGLE_PAINT, - TOOL_RECTANGLE_ERASE, - TOOL_LINE_PAINT, - TOOL_LINE_ERASE, - TOOL_SELECTING, - TOOL_BUCKET, - TOOL_PICKING, - TOOL_DUPLICATING, - }; - - enum Options { - - OPTION_BUCKET, - OPTION_PICK_TILE, - OPTION_SELECT, - OPTION_DUPLICATE, - OPTION_ERASE_SELECTION - }; - - TileMap *node; - - EditorNode *editor; - UndoRedo *undo_redo; - Control *canvas_item_editor; - - LineEdit *search_box; - HSlider *size_slider; - ItemList *palette; - - HBoxContainer *toolbar; - - Label *tile_info; - MenuButton *options; - ToolButton *transp; - ToolButton *mirror_x; - ToolButton *mirror_y; - ToolButton *rotate_0; - ToolButton *rotate_90; - ToolButton *rotate_180; - ToolButton *rotate_270; - - Tool tool; - - bool selection_active; - bool mouse_over; - - bool flip_h; - bool flip_v; - bool transpose; - - Point2i rectangle_begin; - Rect2i rectangle; - - Point2i over_tile; - - bool * bucket_cache_visited; - Rect2i bucket_cache_rect; - int bucket_cache_tile; - PoolVector<Vector2> bucket_cache; - - struct CellOp { - int idx; - bool xf; - bool yf; - bool tr; - - CellOp() { idx=-1; xf=false; yf=false; tr=false; } - }; - - Map<Point2i, CellOp> paint_undo; - - struct TileData { - Point2i pos; - int cell; - bool flip_h; - bool flip_v; - bool transpose; - }; - - List<TileData> copydata; - - void _pick_tile(const Point2& p_pos); - - PoolVector<Vector2> _bucket_fill(const Point2i& p_start, bool erase=false, bool preview=false); - - void _fill_points(const PoolVector<Vector2> p_points, const Dictionary& p_op); - void _erase_points(const PoolVector<Vector2> p_points); - - void _select(const Point2i& p_from, const Point2i& p_to); - - void _draw_cell(int p_cell, const Point2i& p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D& p_xform); - void _draw_fill_preview(int p_cell, const Point2i& p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D& p_xform); - void _clear_bucket_cache(); - - void _update_copydata(); - - int get_selected_tile() const; - void set_selected_tile(int p_tile); - - void _text_entered(const String& p_text); - void _text_changed(const String& p_text); - void _sbox_input(const InputEvent& p_ie); - void _update_palette(); - void _canvas_draw(); - void _menu_option(int p_option); - - void _set_cell(const Point2i& p_pos, int p_value, bool p_flip_h=false, bool p_flip_v=false, bool p_transpose=false, bool p_with_undo=false); - - void _canvas_mouse_enter(); - void _canvas_mouse_exit(); - void _tileset_settings_changed(); - void _icon_size_changed(float p_value); - -protected: - - void _notification(int p_what); - static void _bind_methods(); - CellOp _get_op_from_cell(const Point2i& p_pos); - void _update_transform_buttons(Object *p_button=NULL); - -public: - - HBoxContainer *get_toolbar() const { return toolbar; } - - bool forward_gui_input(const InputEvent& p_event); - void edit(Node *p_tile_map); - - TileMapEditor(EditorNode *p_editor); - ~TileMapEditor(); -}; - -class TileMapEditorPlugin : public EditorPlugin { - - GDCLASS( TileMapEditorPlugin, EditorPlugin ); - - TileMapEditor *tile_map_editor; - -public: - - virtual bool forward_canvas_gui_input(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return tile_map_editor->forward_gui_input(p_event); } - - virtual String get_name() const { return "TileMap"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - TileMapEditorPlugin(EditorNode *p_node); - ~TileMapEditorPlugin(); - -}; - - -#endif // TILE_MAP_EDITOR_PLUGIN_H diff --git a/tools/editor/plugins/tile_set_editor_plugin.h b/tools/editor/plugins/tile_set_editor_plugin.h deleted file mode 100644 index 7fec7fa162..0000000000 --- a/tools/editor/plugins/tile_set_editor_plugin.h +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************/ -/* tile_set_editor_plugin.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef TILE_SET_EDITOR_PLUGIN_H -#define TILE_SET_EDITOR_PLUGIN_H - - - -#include "scene/resources/tile_set.h" -#include "tools/editor/editor_node.h" -#include "tools/editor/editor_name_dialog.h" - - -class TileSetEditor : public Control { - - GDCLASS( TileSetEditor, Control ); - - Ref<TileSet> tileset; - - EditorNode *editor; - MenuButton *menu; - ConfirmationDialog *cd; - EditorNameDialog *nd; - AcceptDialog *err_dialog; - - enum { - - MENU_OPTION_ADD_ITEM, - MENU_OPTION_REMOVE_ITEM, - MENU_OPTION_CREATE_FROM_SCENE, - MENU_OPTION_MERGE_FROM_SCENE - }; - - int option; - void _menu_cbk(int p_option); - void _menu_confirm(); - void _name_dialog_confirm(const String& name); - - static void _import_scene(Node *p_scene, Ref<TileSet> p_library, bool p_merge); - - -protected: - static void _bind_methods(); -public: - - void edit(const Ref<TileSet>& p_tileset); - static Error update_library_file(Node *p_base_scene, Ref<TileSet> ml,bool p_merge=true); - - TileSetEditor(EditorNode *p_editor); -}; - - - -class TileSetEditorPlugin : public EditorPlugin { - - GDCLASS( TileSetEditorPlugin, EditorPlugin ); - - TileSetEditor *tileset_editor; - EditorNode *editor; - -public: - - virtual String get_name() const { return "TileSet"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_node); - virtual bool handles(Object *p_node) const; - virtual void make_visible(bool p_visible); - - - - TileSetEditorPlugin(EditorNode *p_node); - -}; - - -#endif // TILE_SET_EDITOR_PLUGIN_H diff --git a/tools/editor/project_export.h b/tools/editor/project_export.h deleted file mode 100644 index c977e90e56..0000000000 --- a/tools/editor/project_export.h +++ /dev/null @@ -1,142 +0,0 @@ -/*************************************************************************/ -/* project_export.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef PROJECT_EXPORT_SETTINGS_H -#define PROJECT_EXPORT_SETTINGS_H - -#include "scene/main/timer.h" -#include "scene/gui/control.h" -#include "scene/gui/tree.h" -#include "scene/gui/label.h" -#include "tools/editor/editor_file_dialog.h" -#include "scene/gui/button.h" -#include "scene/gui/file_dialog.h" -#include "scene/gui/dialogs.h" -#include "scene/gui/tab_container.h" -#include "os/dir_access.h" -#include "os/thread.h" -#include "scene/gui/option_button.h" - -#include "scene/gui/slider.h" -#include "tools/editor/editor_file_system.h" -#include "property_editor.h" -#include "editor_export.h" - - -class EditorNode; - -class ProjectExportDialog : public ConfirmationDialog { - GDCLASS( ProjectExportDialog, ConfirmationDialog ); - -private: - - - TabContainer *sections; - - MenuButton *add_preset; - Button *delete_preset; - ItemList *presets; - - LineEdit *name; - PropertyEditor *parameters; - CheckButton *runnable; - - - EditorFileDialog *pck_export; - EditorFileDialog *file_export; - - Button *button_export; - bool updating; - - ConfirmationDialog *delete_confirm; - - OptionButton *export_filter; - LineEdit *include_filters; - LineEdit *exclude_filters; - Tree *include_files; - - Label* include_label; - MarginContainer *include_margin; - - StringName editor_icons; - - Tree *patches; - Button *patch_export; - int patch_index; - FileDialog *patch_dialog; - ConfirmationDialog *patch_erase; - - Button *export_button; - - void _patch_selected(const String& p_path); - void _patch_deleted(); - - void _runnable_pressed(); - void _name_changed(const String& p_string); - void _add_preset(int p_platform); - void _edit_preset(int p_index); - void _delete_preset(); - void _delete_preset_confirm(); - - void _update_presets(); - - void _export_type_changed(int p_which); - void _filter_changed(const String& p_filter); - void _fill_resource_tree(); - bool _fill_tree(EditorFileSystemDirectory *p_dir,TreeItem *p_item,Ref<EditorExportPreset> ¤t,bool p_only_scenes); - void _tree_changed(); - - void _patch_button_pressed(Object* p_item,int p_column,int p_id); - void _patch_edited(); - - - Variant get_drag_data_fw(const Point2& p_point,Control* p_from); - bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; - void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); - - FileDialog *export_pck_zip; - - void _export_pck_zip(); - void _export_pck_zip_selected(const String& p_path); - -protected: - void _notification(int p_what); - static void _bind_methods(); -public: - - void popup_export(); - - ProjectExportDialog(); - ~ProjectExportDialog(); -}; - - - - -#endif // PROJECT_EXPORT_SETTINGS_H - diff --git a/tools/editor/project_manager.h b/tools/editor/project_manager.h deleted file mode 100644 index 1fd8a301ea..0000000000 --- a/tools/editor/project_manager.h +++ /dev/null @@ -1,148 +0,0 @@ -/*************************************************************************/ -/* project_manager.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef PROJECT_MANAGER_H -#define PROJECT_MANAGER_H - -#include "scene/gui/dialogs.h" -#include "scene/gui/tree.h" -#include "scene/gui/scroll_container.h" -#include "scene/gui/file_dialog.h" -#include "scene/gui/tool_button.h" -#include "tools/editor/asset_library_editor_plugin.h" - -class NewProjectDialog; -class ProjectListFilter; - -class ProjectManager : public Control { - GDCLASS( ProjectManager, Control ); - - Button *erase_btn; - Button *open_btn; - Button *run_btn; - - FileDialog *scan_dir; - - EditorAssetLibrary *asset_library; - - ProjectListFilter *project_filter; - - ConfirmationDialog *erase_ask; - ConfirmationDialog *multi_open_ask; - ConfirmationDialog *multi_run_ask; - ConfirmationDialog *multi_scan_ask; - NewProjectDialog *npdialog; - ScrollContainer *scroll; - VBoxContainer *scroll_childs; - Map<String, String> selected_list; // name -> main_scene - String last_clicked; - bool importing; - - HBoxContainer *projects_hb; - - TabContainer *tabs; - - Control *gui_base; - - - - void _scan_projects(); - void _run_project(); - void _run_project_confirm(); - void _open_project(); - void _open_project_confirm(); - void _import_project(); - void _new_project(); - void _erase_project(); - void _erase_project_confirm(); - void _update_project_buttons(); - void _exit_dialog(); - void _scan_begin(const String& p_base); - - void _load_recent_projects(); - void _on_project_created(const String& dir); - void _update_scroll_pos(const String& dir); - void _scan_dir(DirAccess *da,float pos, float total,List<String> *r_projects); - - void _install_project(const String& p_zip_path,const String& p_title); - - void _panel_draw(Node *p_hb); - void _panel_input(const InputEvent& p_ev,Node *p_hb); - void _unhandled_input(const InputEvent& p_ev); - void _favorite_pressed(Node *p_hb); - void _files_dropped(PoolStringArray p_files, int p_screen); - void _scan_multiple_folders(PoolStringArray p_files); - -protected: - - void _notification(int p_what); - static void _bind_methods(); -public: - ProjectManager(); - ~ProjectManager(); -}; - -class ProjectListFilter : public HBoxContainer { - - GDCLASS( ProjectListFilter, HBoxContainer ); - -private: - - friend class ProjectManager; - - enum Command { - CMD_CLEAR_FILTER, - }; - - OptionButton *filter_option; - LineEdit *search_box; - ToolButton *clear_search_button; - - enum FilterOption { - FILTER_NAME, - FILTER_PATH, - }; - FilterOption _current_filter; - - void _command(int p_command); - void _search_text_changed(const String& p_newtext); - void _setup_filters(); - void _filter_option_selected(int p_idx); - -protected: - void _notification(int p_what); - static void _bind_methods(); - -public: - - String get_search_term(); - FilterOption get_filter_option(); - ProjectListFilter(); -}; - -#endif // PROJECT_MANAGER_H diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h deleted file mode 100644 index e31a3313c1..0000000000 --- a/tools/editor/property_editor.h +++ /dev/null @@ -1,352 +0,0 @@ -/*************************************************************************/ -/* property_editor.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef PROPERTY_EDITOR_H -#define PROPERTY_EDITOR_H - -#include "scene/gui/tree.h" -#include "scene/gui/button.h" -#include "scene/gui/check_box.h" -#include "scene/gui/label.h" -#include "tools/editor/editor_file_dialog.h" -#include "scene/gui/dialogs.h" -#include "scene/gui/color_picker.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/texture_rect.h" -#include "scene/gui/text_edit.h" -#include "scene/gui/check_button.h" -#include "scene/gui/split_container.h" -#include "scene/gui/grid_container.h" -#include "scene_tree_editor.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - -class PropertyValueEvaluator; -class CreateDialog; -class PropertySelector; - -class CustomPropertyEditor : public Popup { - - GDCLASS( CustomPropertyEditor, Popup ); - - enum { - MAX_VALUE_EDITORS=12, - MAX_ACTION_BUTTONS=5, - OBJ_MENU_LOAD=0, - OBJ_MENU_EDIT=1, - OBJ_MENU_CLEAR=2, - OBJ_MENU_MAKE_UNIQUE=3, - OBJ_MENU_COPY=4, - OBJ_MENU_PASTE=5, - OBJ_MENU_REIMPORT=6, - OBJ_MENU_NEW_SCRIPT=7, - OBJ_MENU_SHOW_IN_FILE_SYSTEM=8, - TYPE_BASE_ID=100 - }; - - enum { - EASING_LINEAR, - EASING_EASE_IN, - EASING_EASE_OUT, - EASING_ZERO, - EASING_IN_OUT, - EASING_OUT_IN - }; - - - PopupMenu *menu; - SceneTreeDialog *scene_tree; - EditorFileDialog *file; - ConfirmationDialog *error; - String name; - Variant::Type type; - Variant v; - List<String> field_names; - int hint; - String hint_text; - LineEdit *value_editor[MAX_VALUE_EDITORS]; - int focused_value_editor; - Label *value_label[MAX_VALUE_EDITORS]; - HScrollBar *scroll[4]; - Button *action_buttons[MAX_ACTION_BUTTONS]; - MenuButton *type_button; - Vector<String> inheritors_array; - TextureRect *texture_preview; - ColorPicker *color_picker; - TextEdit *text_edit; - bool read_only; - bool picking_viewport; - GridContainer *checks20gc; - CheckBox *checks20[20]; - SpinBox *spinbox; - HSlider *slider; - - - Control *easing_draw; - CreateDialog *create_dialog; - PropertySelector *property_select; - - Object* owner; - - bool updating; - - PropertyValueEvaluator *evaluator; - - void _text_edit_changed(); - void _file_selected(String p_file); - void _scroll_modified(double p_value); - void _modified(String p_string); - void _range_modified(double p_value); - void _focus_enter(); - void _focus_exit(); - void _action_pressed(int p_which); - void _type_create_selected(int p_idx); - void _create_dialog_callback(); - void _create_selected_property(const String &p_prop); - - - void _color_changed(const Color& p_color); - void _draw_easing(); - void _menu_option(int p_which); - - void _drag_easing(const InputEvent& p_ev); - - void _node_path_selected(NodePath p_path); - void show_value_editors(int p_amount); - void config_value_editors(int p_amount, int p_columns,int p_label_w,const List<String>& p_strings); - void config_action_buttons(const List<String>& p_strings); - - void _emit_changed_whole_or_field(); - - -protected: - - void _notification(int p_what); - static void _bind_methods(); - -public: - - - void hide_menu(); - - Variant get_variant() const; - String get_name() const; - - 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(); -}; - -class PropertyEditor : public Control { - - GDCLASS( PropertyEditor, Control ); - - Tree *tree; - Label *top_label; - //Object *object; - LineEdit *search_box; - - PropertyValueEvaluator *evaluator; - - Object* obj; - - - StringName _prop_edited; - - bool capitalize_paths; - bool changing; - bool update_tree_pending; - bool autoclear; - bool keying; - bool read_only; - bool show_categories; - bool show_type_icons; - float refresh_countdown; - bool use_doc_hints; - bool use_filter; - bool subsection_selectable; - bool hide_script; - - HashMap<String,String> pending; - String selected_property; - - Map<StringName,Map<StringName,String> > descr_cache; - Map<StringName,String > class_descr_cache; - - CustomPropertyEditor *custom_editor; - - void _resource_edit_request(); - void _custom_editor_edited(); - void _custom_editor_edited_field(const String& p_field_name); - void _custom_editor_request(bool p_arrow); - - void _item_selected(); - void _item_edited(); - TreeItem *get_parent_node(String p_path,HashMap<String,TreeItem*>& item_paths,TreeItem *root); - - void set_item_text(TreeItem *p_item, int p_type, const String& p_name, int p_hint=PROPERTY_HINT_NONE, const String& p_hint_text=""); - - TreeItem *find_item(TreeItem *p_item,const String& p_name); - - - virtual void _changed_callback(Object *p_changed,const char * p_what); - virtual void _changed_callbacks(Object *p_changed,const String& p_callback); - - void _check_reload_status(const String&p_name,TreeItem* item); - - void _edit_button(Object *p_item, int p_column, int p_button); - - void _node_removed(Node *p_node); - -friend class ProjectExportDialog; - void _edit_set(const String& p_name, const Variant& p_value,bool p_refresh_all=false, const String& p_changed_field=""); - void _draw_flags(Object *ti,const Rect2& p_rect); - - bool _might_be_in_instance(); - bool _get_instanced_node_original_property(const StringName& p_prop,Variant& value); - bool _is_property_different(const Variant& p_current, const Variant& p_orig,int p_usage=0); - - void _refresh_item(TreeItem *p_item); - void _set_range_def(Object *p_item, String prop, float p_frame); - - void _filter_changed(const String& p_text); - - void _mark_drop_fields(TreeItem* p_at); - void _clear_drop_fields(TreeItem* p_at); - - bool _is_drop_valid(const Dictionary& p_drag_data, const Dictionary& p_item_data) const; - Variant get_drag_data_fw(const Point2& p_point,Control* p_from); - bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; - void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); - - void _resource_preview_done(const String& p_path,const Ref<Texture>& p_preview,Variant p_ud); - void _draw_transparency(Object *t, const Rect2& p_rect); - - UndoRedo *undo_redo; -protected: - - void _notification(int p_what); - static void _bind_methods(); -public: - - void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo=p_undo_redo; } - - String get_selected_path() const; - - Tree *get_scene_tree(); - Label* get_top_label(); - void hide_top_label(); - void update_tree(); - void update_property(const String& p_prop); - - void refresh(); - - void edit(Object* p_object); - - void set_keying(bool p_active); - void set_read_only(bool p_read_only) { read_only=p_read_only; custom_editor->set_read_only(p_read_only);} - - void set_capitalize_paths(bool p_capitalize); - void set_autoclear(bool p_enable); - - void set_show_categories(bool p_show); - void set_use_doc_hints(bool p_enable) { use_doc_hints=p_enable; } - void set_hide_script(bool p_hide) { hide_script=p_hide; } - - void set_use_filter(bool p_use); - void register_text_enter(Node *p_line_edit); - - void set_subsection_selectable(bool p_selectable); - - PropertyEditor(); - ~PropertyEditor(); - -}; - - -class SectionedPropertyEditorFilter; - -class SectionedPropertyEditor : public HBoxContainer { - - - GDCLASS(SectionedPropertyEditor,HBoxContainer); - - ObjectID obj; - - Tree *sections; - SectionedPropertyEditorFilter *filter; - - Map<String,TreeItem*> section_map; - PropertyEditor *editor; - - - static void _bind_methods(); - void _section_selected(); - -public: - - PropertyEditor *get_property_editor(); - void edit(Object* p_object); - String get_full_item_path(const String& p_item); - - void set_current_section(const String& p_section); - String get_current_section() const; - - void update_category_list(); - - SectionedPropertyEditor(); - ~SectionedPropertyEditor(); -}; - -class PropertyValueEvaluator : public ValueEvaluator { - GDCLASS( 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 diff --git a/tools/editor/property_selector.h b/tools/editor/property_selector.h deleted file mode 100644 index d29183f85e..0000000000 --- a/tools/editor/property_selector.h +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************/ -/* property_selector.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef PROPERTYSELECTOR_H -#define PROPERTYSELECTOR_H - -#include "tools/editor/property_editor.h" -#include "scene/gui/rich_text_label.h" -#include "editor_help.h" - -class PropertySelector : public ConfirmationDialog { - GDCLASS(PropertySelector,ConfirmationDialog ) - - - LineEdit *search_box; - Tree *search_options; - - void _update_search(); - - void _sbox_input(const InputEvent& p_ie); - - void _confirmed(); - void _text_changed(const String& p_newtext); - - EditorHelpBit *help_bit; - - bool properties; - String selected; - Variant::Type type; - InputEvent::Type event_type; - String base_type; - ObjectID script; - Object *instance; - - void _item_selected(); -protected: - void _notification(int p_what); - static void _bind_methods(); - - - -public: - - - void select_method_from_base_type(const String& p_base,const String& p_current=""); - void select_method_from_script(const Ref<Script>& p_script,const String& p_current=""); - void select_method_from_basic_type(Variant::Type p_type,const String& p_current=""); - void select_method_from_instance(Object* p_instance, const String &p_current=""); - - void select_property_from_base_type(const String& p_base,const String& p_current=""); - void select_property_from_script(const Ref<Script>& p_script,const String& p_current=""); - void select_property_from_basic_type(Variant::Type p_type,InputEvent::Type p_event_type,const String& p_current=""); - void select_property_from_instance(Object* p_instance, const String &p_current=""); - - PropertySelector(); -}; - -#endif // PROPERTYSELECTOR_H diff --git a/tools/editor/reparent_dialog.h b/tools/editor/reparent_dialog.h deleted file mode 100644 index 5e21f84581..0000000000 --- a/tools/editor/reparent_dialog.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************/ -/* reparent_dialog.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef REPARENT_DIALOG_H -#define REPARENT_DIALOG_H - -#include "scene/gui/dialogs.h" -#include "scene/gui/button.h" -#include "scene/gui/check_button.h" -#include "scene/gui/check_box.h" -#include "tools/editor/scene_tree_editor.h" -#include "scene/gui/line_edit.h" -/** -@author Juan Linietsky <reduzio@gmail.com> -*/ -class ReparentDialog : public ConfirmationDialog { - - GDCLASS( ReparentDialog, ConfirmationDialog ); - - SceneTreeEditor *tree; - CheckBox *keep_transform; - - - void update_tree(); - void _reparent(); - void _cancel(); - - -protected: - - void _notification(int p_what); - static void _bind_methods(); -public: - - void set_current(const Set<Node*>& p_selection); - String get_selected_type(); - - ReparentDialog(); - ~ReparentDialog(); - -}; - -#endif diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp deleted file mode 100644 index 4f3700adb5..0000000000 --- a/tools/editor/scene_tree_dock.cpp +++ /dev/null @@ -1,2061 +0,0 @@ -/*************************************************************************/ -/* scene_tree_dock.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 "scene_tree_dock.h" - -#include "editor_node.h" -#include "global_config.h" -#include "os/keyboard.h" -#include "scene/resources/packed_scene.h" -#include "editor_settings.h" -#include "tools/editor/plugins/canvas_item_editor_plugin.h" -#include "tools/editor/plugins/spatial_editor_plugin.h" -#include "script_editor_debugger.h" -#include "tools/editor/plugins/script_editor_plugin.h" -#include "core/io/resource_saver.h" -#include "multi_node_edit.h" -#include "tools/editor/plugins/animation_player_editor_plugin.h" -#include "animation_editor.h" -#include "scene/main/viewport.h" - - -void SceneTreeDock::_nodes_drag_begin() { - - - if (restore_script_editor_on_drag) { - EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT); - restore_script_editor_on_drag=false; - } - -} - -void SceneTreeDock::_input(InputEvent p_event) { - - if (p_event.type==InputEvent::MOUSE_BUTTON && !p_event.mouse_button.pressed && p_event.mouse_button.button_index==BUTTON_LEFT) { - restore_script_editor_on_drag=false; //lost chance - } -} - -void SceneTreeDock::_unhandled_key_input(InputEvent p_event) { - - if (get_viewport()->get_modal_stack_top()) - return; //ignore because of modal window - - if (!p_event.key.pressed || p_event.key.echo) - return; - - if (ED_IS_SHORTCUT("scene_tree/add_child_node", p_event)) { - _tool_selected(TOOL_NEW); - } - else if (ED_IS_SHORTCUT("scene_tree/instance_scene", p_event)) { - _tool_selected(TOOL_INSTANCE); - } - else if (ED_IS_SHORTCUT("scene_tree/change_node_type", p_event)) { - _tool_selected(TOOL_REPLACE); - } - else if (ED_IS_SHORTCUT("scene_tree/duplicate", p_event)) { - _tool_selected(TOOL_DUPLICATE); - } - else if (ED_IS_SHORTCUT("scene_tree/attach_script", p_event)) { - _tool_selected(TOOL_ATTACH_SCRIPT); - } - else if(ED_IS_SHORTCUT("scene_tree/clear_script", p_event)) { - _tool_selected(TOOL_CLEAR_SCRIPT); - } - else if (ED_IS_SHORTCUT("scene_tree/move_up", p_event)) { - _tool_selected(TOOL_MOVE_UP); - } - else if (ED_IS_SHORTCUT("scene_tree/move_down", p_event)) { - _tool_selected(TOOL_MOVE_DOWN); - } - else if (ED_IS_SHORTCUT("scene_tree/reparent", p_event)) { - _tool_selected(TOOL_REPARENT); - } - else if (ED_IS_SHORTCUT("scene_tree/merge_from_scene", p_event)) { - _tool_selected(TOOL_MERGE_FROM_SCENE); - } - else if (ED_IS_SHORTCUT("scene_tree/save_branch_as_scene", p_event)) { - _tool_selected(TOOL_NEW_SCENE_FROM); - } - else if (ED_IS_SHORTCUT("scene_tree/delete_no_confirm", p_event)) { - _tool_selected(TOOL_ERASE, true); - } - else if(ED_IS_SHORTCUT("scene_tree/copy_node_path", p_event)) { - _tool_selected(TOOL_COPY_NODE_PATH); - } - else if (ED_IS_SHORTCUT("scene_tree/delete", p_event)) { - _tool_selected(TOOL_ERASE); - } -} - -void SceneTreeDock::instance(const String& p_file) { - - Node *parent = scene_tree->get_selected(); - if (!parent || !edited_scene) { - - current_option=-1; - //accept->get_cancel()->hide(); - accept->get_ok()->set_text(TTR("OK :(")); - accept->set_text(TTR("No parent to instance a child at.")); - accept->popup_centered_minsize(); - return; - }; - - ERR_FAIL_COND(!parent); - - Vector<String> scenes; - scenes.push_back(p_file); - _perform_instance_scenes(scenes,parent,-1); - -} - -void SceneTreeDock::instance_scenes(const Vector<String>& p_files, Node *p_parent) { - - Node *parent = p_parent; - - if (!parent) { - parent = scene_tree->get_selected(); - } - - if (!parent || !edited_scene) { - - accept->get_ok()->set_text(TTR("OK")); - accept->set_text(TTR("No parent to instance the scenes at.")); - accept->popup_centered_minsize(); - return; - }; - - _perform_instance_scenes(p_files, parent, -1); -} - -void SceneTreeDock::_perform_instance_scenes(const Vector<String>& p_files,Node* parent,int p_pos) { - - - - ERR_FAIL_COND(!parent); - - - Vector<Node*> instances; - - bool error=false; - - for(int i=0;i<p_files.size();i++) { - - Ref<PackedScene> sdata = ResourceLoader::load(p_files[i]); - if (!sdata.is_valid()) { - current_option=-1; - //accept->get_cancel()->hide(); - accept->get_ok()->set_text(TTR("Ugh")); - accept->set_text(vformat(TTR("Error loading scene from %s"),p_files[i])); - accept->popup_centered_minsize(); - error=true; - break; - - } - - Node*instanced_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); - if (!instanced_scene) { - current_option=-1; - //accept->get_cancel()->hide(); - accept->get_ok()->set_text(TTR("Ugh")); - accept->set_text(vformat(TTR("Error instancing scene from %s"),p_files[i])); - accept->popup_centered_minsize(); - error=true; - break; - - } - - if (edited_scene->get_filename()!="") { - - if (_cyclical_dependency_exists(edited_scene->get_filename(), instanced_scene)) { - - accept->get_ok()->set_text(TTR("Ok")); - accept->set_text(vformat(TTR("Cannot instance the scene '%s' because the current scene exists within one of its nodes."),p_files[i])); - accept->popup_centered_minsize(); - error=true; - break; - } - } - - instanced_scene->set_filename( GlobalConfig::get_singleton()->localize_path(p_files[i]) ); - - instances.push_back(instanced_scene); - } - - if (error) { - for(int i=0;i<instances.size();i++) { - memdelete(instances[i]); - } - return; - } - - - - //instanced_scene->generate_instance_state(); - - editor_data->get_undo_redo().create_action(TTR("Instance Scene(s)")); - - for(int i=0;i<instances.size();i++) { - - Node* instanced_scene=instances[i]; - - editor_data->get_undo_redo().add_do_method(parent,"add_child",instanced_scene); - if (p_pos>=0) { - editor_data->get_undo_redo().add_do_method(parent,"move_child",instanced_scene,p_pos+i); - } - editor_data->get_undo_redo().add_do_method(instanced_scene,"set_owner",edited_scene); - editor_data->get_undo_redo().add_do_method(editor_selection,"clear"); - editor_data->get_undo_redo().add_do_method(editor_selection,"add_node",instanced_scene); - editor_data->get_undo_redo().add_do_reference(instanced_scene); - editor_data->get_undo_redo().add_undo_method(parent,"remove_child",instanced_scene); - - String new_name = parent->validate_child_name(instanced_scene); - ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); - editor_data->get_undo_redo().add_do_method(sed,"live_debug_instance_node",edited_scene->get_path_to(parent),p_files[i],new_name); - editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+new_name)); - } - - editor_data->get_undo_redo().commit_action(); - - -} - -void SceneTreeDock::_replace_with_branch_scene(const String& p_file,Node* base) { - Ref<PackedScene> sdata = ResourceLoader::load(p_file); - if (!sdata.is_valid()) { - accept->get_ok()->set_text(TTR("Ugh")); - accept->set_text(vformat(TTR("Error loading scene from %s"),p_file)); - accept->popup_centered_minsize(); - return; - } - - Node *instanced_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); - if (!instanced_scene) { - accept->get_ok()->set_text(TTR("Ugh")); - accept->set_text(vformat(TTR("Error instancing scene from %s"),p_file)); - accept->popup_centered_minsize(); - return; - } - - Node *parent = base->get_parent(); - int pos = base->get_index(); - memdelete(base); - parent->add_child(instanced_scene); - parent->move_child(instanced_scene, pos); - instanced_scene->set_owner(edited_scene); - editor_selection->clear(); - editor_selection->add_node(instanced_scene); - scene_tree->set_selected(instanced_scene); -} - -bool SceneTreeDock::_cyclical_dependency_exists(const String& p_target_scene_path, Node* p_desired_node) { - int childCount = p_desired_node->get_child_count(); - - if (p_desired_node->get_filename()==p_target_scene_path) { - return true; - } - - for (int i=0;i<childCount;i++) { - Node* child=p_desired_node->get_child(i); - - if(_cyclical_dependency_exists(p_target_scene_path,child)) { - return true; - } - } - - return false; -} - - -void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { - - current_option=p_tool; - - switch(p_tool) { - - case TOOL_NEW: { - /* - if (!_validate_no_foreign()) - break; - */ - create_dialog->popup(true); - } break; - case TOOL_INSTANCE: { - - Node *scene = edited_scene; - - if (!scene) { - - EditorNode::get_singleton()->new_inherited_scene(); - - /* should be legal now - current_option=-1; - //confirmation->get_cancel()->hide(); - accept->get_ok()->set_text("I see.."); - accept->set_text("This operation can't be done without a tree root."); - accept->popup_centered_minsize(); - */ - break; - } - - /* - if (!_validate_no_foreign()) - break; - */ - - file->set_mode(EditorFileDialog::MODE_OPEN_FILE); - List<String> extensions; - ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions); - file->clear_filters(); - for(int i=0;i<extensions.size();i++) { - - file->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); - } - - //file->set_current_path(current_path); - file->popup_centered_ratio(); - - } break; - case TOOL_REPLACE: { - - create_dialog->popup(false); - } break; - case TOOL_CONNECT: { - - Node *current = scene_tree->get_selected(); - if (!current) - break; - - /* - if (!_validate_no_foreign()) - break; - connect_dialog->popup_centered_ratio(); - connect_dialog->set_node(current); - */ - - } break; - case TOOL_GROUP: { - - Node *current = scene_tree->get_selected(); - if (!current) - break; - /* - if (!_validate_no_foreign()) - break; - groups_editor->set_current(current); - groups_editor->popup_centered_ratio(); - */ - } break; - case TOOL_ATTACH_SCRIPT: { - - Node *selected = scene_tree->get_selected(); - if (!selected) - break; - - /* - if (!_validate_no_foreign()) - break; - */ - - Ref<Script> existing = selected->get_script(); - if (existing.is_valid()) - editor->push_item(existing.ptr()); - else { - String path = selected->get_filename(); - script_create_dialog->config(selected->get_class(),path); - script_create_dialog->popup_centered(Size2(300,290)); - //script_create_dialog->popup_centered_minsize(); - - } - - } break; - case TOOL_CLEAR_SCRIPT: { - Node *selected = scene_tree->get_selected(); - if(!selected) - break; - - Ref<Script> existing = selected->get_script(); - if(existing.is_valid()) { - const RefPtr empty; - selected->set_script(empty); - button_create_script->show(); - button_clear_script->hide(); - } - - } break; - case TOOL_MOVE_UP: - case TOOL_MOVE_DOWN: { - - if (!scene_tree->get_selected()) - break; - - - if (scene_tree->get_selected()==edited_scene) { - - - current_option=-1; - //accept->get_cancel()->hide(); - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text(TTR("This operation can't be done on the tree root.")); - accept->popup_centered_minsize(); - break; - } - - - if (!_validate_no_foreign()) - break; - - bool MOVING_DOWN = (p_tool == TOOL_MOVE_DOWN); - bool MOVING_UP = !MOVING_DOWN; - - Node *common_parent = scene_tree->get_selected()->get_parent(); - List<Node*> selection = editor_selection->get_selected_node_list(); - selection.sort_custom<Node::Comparator>(); // sort by index - if (MOVING_DOWN) - selection.invert(); - - int lowest_id = common_parent->get_child_count() - 1; - int highest_id = 0; - for (List<Node*>::Element *E = selection.front(); E; E = E->next()) { - int index = E->get()->get_index(); - - if (index > highest_id) highest_id = index; - if (index < lowest_id) lowest_id = index; - - if (E->get()->get_parent() != common_parent) - common_parent = NULL; - } - - if (!common_parent || (MOVING_DOWN && highest_id >= common_parent->get_child_count() - MOVING_DOWN) || (MOVING_UP && lowest_id == 0)) - break; // one or more nodes can not be moved - - if (selection.size() == 1) editor_data->get_undo_redo().create_action(TTR("Move Node In Parent")); - if (selection.size() > 1) editor_data->get_undo_redo().create_action(TTR("Move Nodes In Parent")); - - for (int i = 0; i < selection.size(); i++) { - Node *top_node = selection[i]; - Node *bottom_node = selection[selection.size() - 1 - i]; - - ERR_FAIL_COND(!top_node->get_parent()); - ERR_FAIL_COND(!bottom_node->get_parent()); - - int bottom_node_pos = bottom_node->get_index(); - int top_node_pos_next = top_node->get_index() + (MOVING_DOWN ? 1 : -1); - - editor_data->get_undo_redo().add_do_method(top_node->get_parent(), "move_child", top_node, top_node_pos_next); - editor_data->get_undo_redo().add_undo_method(bottom_node->get_parent(), "move_child", bottom_node, bottom_node_pos); - } - - editor_data->get_undo_redo().commit_action(); - - } break; - case TOOL_DUPLICATE: { - - if (!edited_scene) - break; - - - if (editor_selection->is_selected(edited_scene)) { - - - current_option=-1; - //accept->get_cancel()->hide(); - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text(TTR("This operation can't be done on the tree root.")); - accept->popup_centered_minsize(); - break; - } - - if (!_validate_no_foreign()) - break; - - List<Node*> selection = editor_selection->get_selected_node_list(); - if (selection.size()==0) - break; - - List<Node*> reselect; - - editor_data->get_undo_redo().create_action(TTR("Duplicate Node(s)")); - editor_data->get_undo_redo().add_do_method(editor_selection,"clear"); - - Node *dupsingle=NULL; - - - for (List<Node*>::Element *E=selection.front();E;E=E->next()) { - - Node *node = E->get(); - Node *parent = node->get_parent(); - - List<Node*> owned; - node->get_owned_by(node->get_owner(),&owned); - - Map<Node*,Node*> duplimap; - Node * dup = _duplicate(node,duplimap); - - ERR_CONTINUE(!dup); - - if (selection.size()==1) - dupsingle=dup; - - dup->set_name(parent->validate_child_name(dup)); - - editor_data->get_undo_redo().add_do_method(parent,"_add_child_below_node",node, dup); - for (List<Node*>::Element *F=owned.front();F;F=F->next()) { - - if (!duplimap.has(F->get())) { - - continue; - } - Node *d=duplimap[F->get()]; - editor_data->get_undo_redo().add_do_method(d,"set_owner",node->get_owner()); - } - editor_data->get_undo_redo().add_do_method(editor_selection,"add_node",dup); - editor_data->get_undo_redo().add_undo_method(parent,"remove_child",dup); - editor_data->get_undo_redo().add_do_reference(dup); - - ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); - - editor_data->get_undo_redo().add_do_method(sed,"live_debug_duplicate_node",edited_scene->get_path_to(node),dup->get_name()); - editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+dup->get_name())); - - //parent->add_child(dup); - //reselect.push_back(dup); - } - - editor_data->get_undo_redo().commit_action(); - - if (dupsingle) - editor->push_item(dupsingle); - - - - - - } break; - case TOOL_REPARENT: { - - - if (!scene_tree->get_selected()) - break; - - - if (editor_selection->is_selected(edited_scene)) { - - - current_option=-1; - //confirmation->get_cancel()->hide(); - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text(TTR("This operation can't be done on the tree root.")); - accept->popup_centered_minsize(); - break; - } - - if (!_validate_no_foreign()) - break; - - List<Node*> nodes = editor_selection->get_selected_node_list(); - Set<Node*> nodeset; - for(List<Node*>::Element *E=nodes.front();E;E=E->next()) { - - nodeset.insert(E->get()); - } - reparent_dialog->popup_centered_ratio(); - reparent_dialog->set_current( nodeset ); - - } break; - case TOOL_MULTI_EDIT: { - - Node*root=EditorNode::get_singleton()->get_edited_scene(); - if (!root) - break; - Ref<MultiNodeEdit> mne = memnew( MultiNodeEdit ); - for (const Map<Node*,Object*>::Element *E=EditorNode::get_singleton()->get_editor_selection()->get_selection().front();E;E=E->next()) { - mne->add_node(root->get_path_to(E->key())); - } - - EditorNode::get_singleton()->push_item(mne.ptr()); - - } break; - - case TOOL_ERASE: { - - List<Node*> remove_list = editor_selection->get_selected_node_list(); - - if (remove_list.empty()) - return; - - if (!_validate_no_foreign()) - break; - - if (p_confirm_override) { - _delete_confirm(); - - // hack, force 2d editor viewport to refresh after deletion - if (CanvasItemEditor *editor = CanvasItemEditor::get_singleton()) - editor->get_viewport_control()->update(); - - } else { - delete_dialog->set_text(TTR("Delete Node(s)?")); - delete_dialog->popup_centered_minsize(); - } - - } break; - case TOOL_MERGE_FROM_SCENE: { - - EditorNode::get_singleton()->merge_from_scene(); - } break; - case TOOL_NEW_SCENE_FROM: { - - Node *scene = editor_data->get_edited_scene_root(); - - if (!scene) { - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text(TTR("This operation can't be done without a scene.")); - accept->popup_centered_minsize(); - break; - } - - List<Node*> selection = editor_selection->get_selected_node_list(); - - if (selection.size()!=1) { - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text(TTR("This operation requires a single selected node.")); - accept->popup_centered_minsize(); - break; - } - - Node *tocopy = selection.front()->get(); - - if (tocopy==scene){ - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text(TTR("Can not perform with the root node.")); - accept->popup_centered_minsize(); - break; - } - - if (tocopy!=editor_data->get_edited_scene_root() && tocopy->get_filename()!="") { - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text(TTR("This operation can't be done on instanced scenes.")); - accept->popup_centered_minsize(); - break; - } - - new_scene_from_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE); - - List<String> extensions; - Ref<PackedScene> sd = memnew( PackedScene ); - ResourceSaver::get_recognized_extensions(sd,&extensions); - new_scene_from_dialog->clear_filters(); - for(int i=0;i<extensions.size();i++) { - new_scene_from_dialog->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper()); - } - - String existing; - if (extensions.size()) { - String root_name(tocopy->get_name()); - existing=root_name+"."+extensions.front()->get().to_lower(); - } - new_scene_from_dialog->set_current_path(existing); - - new_scene_from_dialog->popup_centered_ratio(); - new_scene_from_dialog->set_title(TTR("Save New Scene As..")); - - } break; - case TOOL_COPY_NODE_PATH: { - List<Node*> selection = editor_selection->get_selected_node_list(); - - if(List<Node*>::Element *e = selection.front()) { - if(Node *node = e->get()) { - Node *root = EditorNode::get_singleton()->get_edited_scene(); - NodePath path = root->get_path().rel_path_to(node->get_path()); - OS::get_singleton()->set_clipboard(path); - } - } - } break; - } - -} - -void SceneTreeDock::_notification(int p_what) { - - switch(p_what) { - - case NOTIFICATION_READY: { - - if (!first_enter) - break; - first_enter=false; - - CanvasItemEditorPlugin *canvas_item_plugin = editor_data->get_editor("2D")->cast_to<CanvasItemEditorPlugin>(); - if (canvas_item_plugin) { - canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree"); - canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", scene_tree, "_update_tree"); - scene_tree->connect("node_changed", canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), "update"); - } - button_add->set_icon(get_icon("Add","EditorIcons")); - button_instance->set_icon(get_icon("Instance","EditorIcons")); - button_create_script->set_icon(get_icon("ScriptCreate","EditorIcons")); - button_clear_script->set_icon(get_icon("ScriptRemove", "EditorIcons")); - - - filter_icon->set_texture(get_icon("Zoom","EditorIcons")); - - EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed",this,"_selection_changed"); - - } break; - } -} - - -void SceneTreeDock::_load_request(const String& p_path) { - - editor->open_request(p_path); -} - -void SceneTreeDock::_script_open_request(const Ref<Script>& p_script) { - - editor->edit_resource(p_script); -} - -void SceneTreeDock::_node_selected() { - - - Node *node=scene_tree->get_selected(); - - if (!node) { - - editor->push_item(NULL); - return; - } - - if (ScriptEditor::get_singleton()->is_visible_in_tree()) { - restore_script_editor_on_drag=true; - } - - editor->push_item(node); - - -} - -void SceneTreeDock::_node_renamed() { - - _node_selected(); -} - -Node *SceneTreeDock::_duplicate(Node *p_node, Map<Node*,Node*> &duplimap) { - - Node *node=NULL; - - if (p_node->get_filename()!="") { //an instance - - Ref<PackedScene> sd = ResourceLoader::load( p_node->get_filename() ); - ERR_FAIL_COND_V(!sd.is_valid(),NULL); - node = sd->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); - ERR_FAIL_COND_V(!node,NULL); - node->set_scene_instance_load_placeholder(p_node->get_scene_instance_load_placeholder()); - //node->generate_instance_state(); - } else { - Object *obj = ClassDB::instance(p_node->get_class()); - ERR_FAIL_COND_V(!obj,NULL); - node = obj->cast_to<Node>(); - if (!node) - memdelete(obj); - ERR_FAIL_COND_V(!node,NULL); - - } - - List<PropertyInfo> plist; - - p_node->get_property_list(&plist); - - for(List<PropertyInfo>::Element *E=plist.front();E;E=E->next()) { - - if (!(E->get().usage&PROPERTY_USAGE_STORAGE)) - continue; - String name = E->get().name; - node->set( name, p_node->get(name) ); - - } - - - List<Node::GroupInfo> group_info; - p_node->get_groups(&group_info); - for (List<Node::GroupInfo>::Element *E=group_info.front();E;E=E->next()) { - - if (E->get().persistent) - node->add_to_group(E->get().name,true); - } - - - node->set_name(p_node->get_name()); - duplimap[p_node]=node; - - for(int i=0;i<p_node->get_child_count();i++) { - - Node *child = p_node->get_child(i); - if (p_node->get_owner()!=child->get_owner()) - continue; //don't bother with not in-scene nodes. - - Node *dup = _duplicate(child,duplimap); - if (!dup) { - memdelete(node); - return NULL; - } - - node->add_child(dup); - } - - return node; - -} - - -void SceneTreeDock::_set_owners(Node *p_owner, const Array& p_nodes) { - - for(int i=0;i<p_nodes.size();i++) { - - Object *obj=p_nodes[i]; - if (!obj) - continue; - - Node *n=obj->cast_to<Node>(); - if (!n) - continue; - n->set_owner(p_owner); - } -} - - -void SceneTreeDock::_fill_path_renames(Vector<StringName> base_path,Vector<StringName> new_base_path,Node * p_node, List<Pair<NodePath,NodePath> > *p_renames) { - - base_path.push_back(p_node->get_name()); - if (new_base_path.size()) - new_base_path.push_back(p_node->get_name()); - - NodePath from( base_path,true ); - NodePath to; - if (new_base_path.size()) - to=NodePath( new_base_path,true ); - - Pair<NodePath,NodePath> npp; - npp.first=from; - npp.second=to; - - p_renames->push_back(npp); - - for(int i=0;i<p_node->get_child_count();i++) { - - _fill_path_renames(base_path,new_base_path,p_node->get_child(i),p_renames); - } - - -} - -void SceneTreeDock::fill_path_renames(Node* p_node, Node *p_new_parent, List<Pair<NodePath,NodePath> > *p_renames) { - - if (!bool(EDITOR_DEF("editors/animation/autorename_animation_tracks",true))) - return; - - - Vector<StringName> base_path; - Node *n = p_node->get_parent(); - while(n) { - base_path.push_back(n->get_name()); - n=n->get_parent(); - } - base_path.invert(); - - Vector<StringName> new_base_path; - if (p_new_parent) { - n = p_new_parent; - while(n) { - new_base_path.push_back(n->get_name()); - n=n->get_parent(); - } - - new_base_path.invert(); - } - - _fill_path_renames(base_path,new_base_path,p_node,p_renames); -} - -void SceneTreeDock::perform_node_renames(Node* p_base,List<Pair<NodePath,NodePath> > *p_renames, Map<Ref<Animation>, Set<int> > *r_rem_anims) { - - Map<Ref<Animation>, Set<int> > rem_anims; - - if (!r_rem_anims) - r_rem_anims=&rem_anims; - - if (!bool(EDITOR_DEF("editors/animation/autorename_animation_tracks",true))) - return; - - if (!p_base) { - - p_base=edited_scene; - } - - if (!p_base) - return; - - - if (p_base->cast_to<AnimationPlayer>()) { - - AnimationPlayer *ap=p_base->cast_to<AnimationPlayer>(); - List<StringName> anims; - ap->get_animation_list(&anims); - Node *root = ap->get_node(ap->get_root()); - - - if (root) { - - - NodePath root_path=root->get_path(); - NodePath new_root_path=root_path; - - - for(List<Pair<NodePath,NodePath> >::Element* E=p_renames->front();E;E=E->next()) { - - if (E->get().first==root_path) { - new_root_path=E->get().second; - break; - } - } - - if (new_root_path!=NodePath()) { - //will not be erased - - for(List<StringName>::Element *E=anims.front();E;E=E->next()) { - - Ref<Animation> anim=ap->get_animation(E->get()); - if (!r_rem_anims->has(anim)) { - r_rem_anims->insert(anim,Set<int>()); - Set<int> &ran = r_rem_anims->find(anim)->get(); - for(int i=0;i<anim->get_track_count();i++) - ran.insert(i); - } - - Set<int> &ran = r_rem_anims->find(anim)->get(); - - if (anim.is_null()) - continue; - - for(int i=0;i<anim->get_track_count();i++) { - - NodePath track_np=anim->track_get_path(i); - Node *n = root->get_node(track_np); - if (!n) { - continue; - } - - NodePath old_np = n->get_path(); - - if (!ran.has(i)) - continue; //channel was removed - - for(List<Pair<NodePath,NodePath> >::Element* E=p_renames->front();E;E=E->next()) { - - if (E->get().first==old_np) { - - - if (E->get().second==NodePath()) { - //will be erased - - int idx=0; - Set<int>::Element *EI=ran.front(); - ERR_FAIL_COND(!EI); //bug - while(EI->get()!=i) { - idx++; - EI=EI->next(); - ERR_FAIL_COND(!EI); //another bug - - } - - editor_data->get_undo_redo().add_do_method(anim.ptr(),"remove_track",idx); - editor_data->get_undo_redo().add_undo_method(anim.ptr(),"add_track",anim->track_get_type(i),idx); - editor_data->get_undo_redo().add_undo_method(anim.ptr(),"track_set_path",idx,track_np); - editor_data->get_undo_redo().add_undo_method(anim.ptr(),"track_set_interpolation_type",idx,anim->track_get_interpolation_type(i)); - for(int j=0;j<anim->track_get_key_count(i);j++) { - - editor_data->get_undo_redo().add_undo_method(anim.ptr(),"track_insert_key",idx,anim->track_get_key_time(i,j),anim->track_get_key_value(i,j),anim->track_get_key_transition(i,j)); - } - - ran.erase(i); //byebye channel - - } else { - //will be renamed - NodePath rel_path = new_root_path.rel_path_to(E->get().second); - - NodePath new_path = NodePath( rel_path.get_names(), track_np.get_subnames(), false, track_np.get_property() ); - if (new_path==track_np) - continue; //bleh - editor_data->get_undo_redo().add_do_method(anim.ptr(),"track_set_path",i,new_path); - editor_data->get_undo_redo().add_undo_method(anim.ptr(),"track_set_path",i,track_np); - } - } - } - } - } - } - } - } - - - for(int i=0;i<p_base->get_child_count();i++) - perform_node_renames(p_base->get_child(i),p_renames,r_rem_anims); - -} - - -void SceneTreeDock::_node_prerenamed(Node* p_node, const String& p_new_name) { - - - List<Pair<NodePath,NodePath> > path_renames; - - Vector<StringName> base_path; - Node *n = p_node->get_parent(); - while(n) { - base_path.push_back(n->get_name()); - n=n->get_parent(); - } - base_path.invert(); - - - Vector<StringName> new_base_path=base_path; - base_path.push_back(p_node->get_name()); - - new_base_path.push_back(p_new_name); - - Pair<NodePath,NodePath> npp; - npp.first = NodePath(base_path,true); - npp.second = NodePath(new_base_path,true); - path_renames.push_back(npp); - - - for(int i=0;i<p_node->get_child_count();i++) - _fill_path_renames(base_path,new_base_path,p_node->get_child(i),&path_renames); - - perform_node_renames(NULL,&path_renames); - -} - -bool SceneTreeDock::_validate_no_foreign() { - - List<Node*> selection = editor_selection->get_selected_node_list(); - - for (List<Node*>::Element *E=selection.front();E;E=E->next()) { - - if (E->get()!=edited_scene && E->get()->get_owner()!=edited_scene) { - - accept->get_ok()->set_text(TTR("Makes Sense!")); - accept->set_text(TTR("Can't operate on nodes from a foreign scene!")); - accept->popup_centered_minsize(); - return false; - - } - - if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E->get()))>=0) { - - accept->get_ok()->set_text(TTR("Makes Sense!")); - accept->set_text(TTR("Can't operate on nodes the current scene inherits from!")); - accept->popup_centered_minsize(); - return false; - - } - - } - - return true; -} - -void SceneTreeDock::_node_reparent(NodePath p_path,bool p_keep_global_xform) { - - - Node *new_parent = scene_root->get_node(p_path); - ERR_FAIL_COND(!new_parent); - - //ok all valid - - List<Node*> selection = editor_selection->get_selected_node_list(); - - if (selection.empty()) - return; //nothing to reparent - - Vector<Node*> nodes; - - for(List<Node*>::Element *E=selection.front();E;E=E->next()) { - nodes.push_back(E->get()); - } - - _do_reparent(new_parent,-1,nodes,p_keep_global_xform); - -} - - -void SceneTreeDock::_do_reparent(Node* p_new_parent,int p_position_in_parent,Vector<Node*> p_nodes,bool p_keep_global_xform) { - - - Node *new_parent = p_new_parent; - ERR_FAIL_COND(!new_parent); - - Node *validate=new_parent; - while(validate) { - - if (p_nodes.find(validate)!=-1) { - ERR_EXPLAIN("Selection changed at some point.. can't reparent"); - ERR_FAIL(); - return; - } - validate=validate->get_parent(); - } - - //ok all valid - - List<Node*> selection = editor_selection->get_selected_node_list(); - - if (p_nodes.size()==0) - return; //nothing to reparent - - //sort by tree order, so re-adding is easy - p_nodes.sort_custom<Node::Comparator>(); - - editor_data->get_undo_redo().create_action(TTR("Reparent Node")); - - List<Pair<NodePath,NodePath> > path_renames; - Vector<StringName> former_names; - - int inc=0; - - for(int ni=0;ni<p_nodes.size();ni++) { - - //no undo for now, sorry - Node *node = p_nodes[ni]; - - fill_path_renames(node,new_parent,&path_renames); - former_names.push_back(node->get_name()); - - List<Node*> owned; - node->get_owned_by(node->get_owner(),&owned); - Array owners; - for(List<Node*>::Element *E=owned.front();E;E=E->next()) { - - owners.push_back(E->get()); - } - - - if (new_parent==node->get_parent() && node->get_index() < p_position_in_parent+ni) { - //if child will generate a gap when moved, adjust - inc--; - } - - editor_data->get_undo_redo().add_do_method(node->get_parent(),"remove_child",node); - editor_data->get_undo_redo().add_do_method(new_parent,"add_child",node); - - if (p_position_in_parent>=0) - editor_data->get_undo_redo().add_do_method(new_parent,"move_child",node,p_position_in_parent+inc); - - ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); - String new_name = new_parent->validate_child_name(node); - editor_data->get_undo_redo().add_do_method(sed,"live_debug_reparent_node",edited_scene->get_path_to(node),edited_scene->get_path_to(new_parent),new_name,-1); - editor_data->get_undo_redo().add_undo_method(sed,"live_debug_reparent_node",NodePath(String(edited_scene->get_path_to(new_parent))+"/"+new_name),edited_scene->get_path_to(node->get_parent()),node->get_name(),node->get_index()); - - if (p_keep_global_xform) { - if (node->cast_to<Node2D>()) - editor_data->get_undo_redo().add_do_method(node,"set_global_transform",node->cast_to<Node2D>()->get_global_transform()); - if (node->cast_to<Spatial>()) - editor_data->get_undo_redo().add_do_method(node,"set_global_transform",node->cast_to<Spatial>()->get_global_transform()); - if (node->cast_to<Control>()) - editor_data->get_undo_redo().add_do_method(node,"set_global_pos",node->cast_to<Control>()->get_global_pos()); - } - - editor_data->get_undo_redo().add_do_method(this,"_set_owners",edited_scene,owners); - - if (AnimationPlayerEditor::singleton->get_key_editor()->get_root()==node) - editor_data->get_undo_redo().add_do_method(AnimationPlayerEditor::singleton->get_key_editor(),"set_root",node); - - editor_data->get_undo_redo().add_undo_method(new_parent,"remove_child",node); - editor_data->get_undo_redo().add_undo_method(node,"set_name",former_names[ni]); - - inc++; - - } - - //add and move in a second step.. (so old order is preserved) - - - - for(int ni=0;ni<p_nodes.size();ni++) { - - Node *node = p_nodes[ni]; - - List<Node*> owned; - node->get_owned_by(node->get_owner(),&owned); - Array owners; - for(List<Node*>::Element *E=owned.front();E;E=E->next()) { - - owners.push_back(E->get()); - } - - int child_pos = node->get_position_in_parent(); - - editor_data->get_undo_redo().add_undo_method(node->get_parent(),"add_child",node); - editor_data->get_undo_redo().add_undo_method(node->get_parent(),"move_child",node,child_pos); - editor_data->get_undo_redo().add_undo_method(this,"_set_owners",edited_scene,owners); - if (AnimationPlayerEditor::singleton->get_key_editor()->get_root()==node) - editor_data->get_undo_redo().add_undo_method(AnimationPlayerEditor::singleton->get_key_editor(),"set_root",node); - - if (p_keep_global_xform) { - if (node->cast_to<Node2D>()) - editor_data->get_undo_redo().add_undo_method(node,"set_transform",node->cast_to<Node2D>()->get_transform()); - if (node->cast_to<Spatial>()) - editor_data->get_undo_redo().add_undo_method(node,"set_transform",node->cast_to<Spatial>()->get_transform()); - if (node->cast_to<Control>()) - editor_data->get_undo_redo().add_undo_method(node,"set_pos",node->cast_to<Control>()->get_pos()); - } - - - - } - - perform_node_renames(NULL,&path_renames); - - editor_data->get_undo_redo().commit_action(); - //node->set_owner(owner); -} - -void SceneTreeDock::_script_created(Ref<Script> p_script) { - - Node *selected = scene_tree->get_selected(); - if (!selected) - return; - selected->set_script(p_script.get_ref_ptr()); - editor->push_item(p_script.operator->()); - button_create_script->hide(); - button_clear_script->show(); - -} - - -void SceneTreeDock::_delete_confirm() { - - List<Node*> remove_list = editor_selection->get_selected_node_list(); - - if (remove_list.empty()) - return; - - - editor->get_editor_plugins_over()->make_visible(false); - - editor_data->get_undo_redo().create_action(TTR("Remove Node(s)")); - - bool entire_scene=false; - - for(List<Node*>::Element *E=remove_list.front();E;E=E->next()) { - - if (E->get()==edited_scene) { - entire_scene=true; - } - } - - if (entire_scene) { - - editor_data->get_undo_redo().add_do_method(editor,"set_edited_scene",(Object*)NULL); - editor_data->get_undo_redo().add_undo_method(editor,"set_edited_scene",edited_scene); - editor_data->get_undo_redo().add_undo_method(edited_scene,"set_owner",edited_scene->get_owner()); - editor_data->get_undo_redo().add_undo_reference(edited_scene); - - } else { - - remove_list.sort_custom<Node::Comparator>(); //sort nodes to keep positions - List<Pair<NodePath,NodePath> > path_renames; - - - //delete from animation - for(List<Node*>::Element *E=remove_list.front();E;E=E->next()) { - Node *n = E->get(); - if (!n->is_inside_tree() || !n->get_parent()) - continue; - - fill_path_renames(n,NULL,&path_renames); - - } - - perform_node_renames(NULL,&path_renames); - //delete for read - for(List<Node*>::Element *E=remove_list.front();E;E=E->next()) { - Node *n = E->get(); - if (!n->is_inside_tree() || !n->get_parent()) - continue; - - List<Node*> owned; - n->get_owned_by(n->get_owner(),&owned); - Array owners; - for(List<Node*>::Element *E=owned.front();E;E=E->next()) { - - owners.push_back(E->get()); - } - - - editor_data->get_undo_redo().add_do_method(n->get_parent(),"remove_child",n); - editor_data->get_undo_redo().add_undo_method(n->get_parent(),"add_child",n); - editor_data->get_undo_redo().add_undo_method(n->get_parent(),"move_child",n,n->get_index()); - if (AnimationPlayerEditor::singleton->get_key_editor()->get_root()==n) - editor_data->get_undo_redo().add_undo_method(AnimationPlayerEditor::singleton->get_key_editor(),"set_root",n); - editor_data->get_undo_redo().add_undo_method(this,"_set_owners",edited_scene,owners); - //editor_data->get_undo_redo().add_undo_method(n,"set_owner",n->get_owner()); - editor_data->get_undo_redo().add_undo_reference(n); - - ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); - editor_data->get_undo_redo().add_do_method(sed,"live_debug_remove_and_keep_node",edited_scene->get_path_to(n),n->get_instance_ID()); - editor_data->get_undo_redo().add_undo_method(sed,"live_debug_restore_node",n->get_instance_ID(),edited_scene->get_path_to(n->get_parent()),n->get_index()); - - } - - - } - editor_data->get_undo_redo().commit_action(); - - -} - - - - -void SceneTreeDock::_selection_changed() { - - int selection_size = EditorNode::get_singleton()->get_editor_selection()->get_selection().size(); - if (selection_size>1) { - //automatically turn on multi-edit - _tool_selected(TOOL_MULTI_EDIT); - } - - if (selection_size==1) { - if(EditorNode::get_singleton()->get_editor_selection()->get_selection().front()->key()->get_script().is_null()) { - button_create_script->show(); - button_clear_script->hide(); - } - else { - button_create_script->hide(); - button_clear_script->show(); - } - } else { - button_create_script->hide(); - button_clear_script->hide(); - } - - //tool_buttons[TOOL_MULTI_EDIT]->set_disabled(EditorNode::get_singleton()->get_editor_selection()->get_selection().size()<2); - -} - - -void SceneTreeDock::_create() { - - - if (current_option==TOOL_NEW) { - - Node *parent=NULL; - - - if (edited_scene) { - // If root exists in edited scene - parent = scene_tree->get_selected(); - if( !parent ) - parent = edited_scene; - - } else { - // If no root exist in edited scene - parent = scene_root; - ERR_FAIL_COND(!parent); - } - - Object *c = create_dialog->instance_selected(); - - ERR_FAIL_COND(!c); - Node *child=c->cast_to<Node>(); - ERR_FAIL_COND(!child); - - editor_data->get_undo_redo().create_action(TTR("Create Node")); - - if (edited_scene) { - - editor_data->get_undo_redo().add_do_method(parent,"add_child",child); - editor_data->get_undo_redo().add_do_method(child,"set_owner",edited_scene); - editor_data->get_undo_redo().add_do_method(editor_selection,"clear"); - editor_data->get_undo_redo().add_do_method(editor_selection,"add_node",child); - editor_data->get_undo_redo().add_do_reference(child); - editor_data->get_undo_redo().add_undo_method(parent,"remove_child",child); - - - String new_name = parent->validate_child_name(child); - ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); - editor_data->get_undo_redo().add_do_method(sed,"live_debug_create_node",edited_scene->get_path_to(parent),child->get_class(),new_name); - editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+new_name)); - - } else { - - editor_data->get_undo_redo().add_do_method(editor,"set_edited_scene",child); - editor_data->get_undo_redo().add_do_reference(child); - editor_data->get_undo_redo().add_undo_method(editor,"set_edited_scene",(Object*)NULL); - - } - - editor_data->get_undo_redo().commit_action(); - editor->push_item(c); - - if (c->cast_to<Control>()) { - //make editor more comfortable, so some controls don't appear super shrunk - Control *ct = c->cast_to<Control>(); - - Size2 ms = ct->get_minimum_size(); - if (ms.width<4) - ms.width=40; - if (ms.height<4) - ms.height=40; - ct->set_size(ms); - } - - - } else if (current_option==TOOL_REPLACE) { - Node * n = scene_tree->get_selected(); - ERR_FAIL_COND(!n); - - Object *c = create_dialog->instance_selected(); - - ERR_FAIL_COND(!c); - Node *newnode=c->cast_to<Node>(); - ERR_FAIL_COND(!newnode); - - List<PropertyInfo> pinfo; - n->get_property_list(&pinfo); - - for(List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) { - if (!(E->get().usage&PROPERTY_USAGE_STORAGE)) - continue; - newnode->set(E->get().name,n->get(E->get().name)); - } - - editor->push_item(NULL); - - //reconnect signals - List<MethodInfo> sl; - - n->get_signal_list(&sl); - for (List<MethodInfo>::Element *E=sl.front();E;E=E->next()) { - - List<Object::Connection> cl; - n->get_signal_connection_list(E->get().name,&cl); - - for(List<Object::Connection>::Element *F=cl.front();F;F=F->next()) { - - Object::Connection &c=F->get(); - if (!(c.flags&Object::CONNECT_PERSIST)) - continue; - newnode->connect(c.signal,c.target,c.method,varray(),Object::CONNECT_PERSIST); - } - - } - - String newname=n->get_name(); - - List<Node*> to_erase; - for(int i=0;i<n->get_child_count();i++) { - if (n->get_child(i)->get_owner()==NULL && n->is_owned_by_parent()) { - to_erase.push_back(n->get_child(i)); - } - } - n->replace_by(newnode,true); - - if (n==edited_scene) { - edited_scene=newnode; - editor->set_edited_scene(newnode); - newnode->set_editable_instances(n->get_editable_instances()); - } - - //small hack to make collisionshapes and other kind of nodes to work - for(int i=0;i<newnode->get_child_count();i++) { - Node *c=newnode->get_child(i); - c->call("set_transform", c->call("get_transform") ); - } - editor_data->get_undo_redo().clear_history(); - newnode->set_name(newname); - - editor->push_item(newnode); - - memdelete(n); - - while(to_erase.front()) { - memdelete(to_erase.front()->get()); - to_erase.pop_front(); - } - - - - } - -} - - -void SceneTreeDock::set_edited_scene(Node* p_scene) { - - edited_scene=p_scene; -} - -void SceneTreeDock::set_selected(Node *p_node, bool p_emit_selected ) { - - scene_tree->set_selected(p_node,p_emit_selected); - -} - -void SceneTreeDock::import_subscene() { - - import_subscene_dialog->popup_centered_ratio(); -} - -void SceneTreeDock::_import_subscene() { - - Node* parent = scene_tree->get_selected(); - if (!parent) { - parent = editor_data->get_edited_scene_root(); - ERR_FAIL_COND(!parent); - } - - import_subscene_dialog->move(parent,edited_scene); - editor_data->get_undo_redo().clear_history(); //no undo for now.. - - -/* - editor_data->get_undo_redo().create_action("Import Subscene"); - editor_data->get_undo_redo().add_do_method(parent,"add_child",ss); - //editor_data->get_undo_redo().add_do_method(editor_selection,"clear"); - //editor_data->get_undo_redo().add_do_method(editor_selection,"add_node",child); - editor_data->get_undo_redo().add_do_reference(ss); - editor_data->get_undo_redo().add_undo_method(parent,"remove_child",ss); - editor_data->get_undo_redo().commit_action(); -*/ -} - -void SceneTreeDock::_new_scene_from(String p_file) { - - List<Node*> selection = editor_selection->get_selected_node_list(); - - if (selection.size()!=1) { - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text(TTR("This operation requires a single selected node.")); - accept->popup_centered_minsize(); - return; - } - - Node *base = selection.front()->get(); - - Map<Node*,Node*> reown; - reown[editor_data->get_edited_scene_root()]=base; - Node *copy = base->duplicate_and_reown(reown); - if (copy) { - - Ref<PackedScene> sdata = memnew( PackedScene ); - Error err = sdata->pack(copy); - memdelete(copy); - - if (err!=OK) { - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text(TTR("Couldn't save new scene. Likely dependencies (instances) couldn't be satisfied.")); - accept->popup_centered_minsize(); - return; - } - - int flg=0; - if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) - flg|=ResourceSaver::FLAG_COMPRESS; - /* - if (EditorSettings::get_singleton()->get("filesystem/on_save/save_paths_as_relative")) - flg|=ResourceSaver::FLAG_RELATIVE_PATHS; - */ - - - err = ResourceSaver::save(p_file,sdata,flg); - if (err!=OK) { - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text(TTR("Error saving scene.")); - accept->popup_centered_minsize(); - return; - } - _replace_with_branch_scene(p_file, base); - } else { - accept->get_ok()->set_text(TTR("I see..")); - accept->set_text(TTR("Error duplicating scene to save it.")); - accept->popup_centered_minsize(); - return; - } - -} - -static bool _is_node_visible(Node* p_node) { - - if (!p_node->get_owner()) - return false; - if (p_node->get_owner()!=EditorNode::get_singleton()->get_edited_scene() && !EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node->get_owner())) - return false; - - return true; - -} - -static bool _has_visible_children(Node* p_node) { - - bool collapsed = p_node->is_displayed_folded(); - if (collapsed) - return false; - - for(int i=0;i<p_node->get_child_count();i++) { - - Node* child = p_node->get_child(i); - if (!_is_node_visible(child)) - continue; - - return true; - } - - return false; - -} - - - -static Node* _find_last_visible(Node* p_node) { - - Node* last=NULL; - - bool collapsed = p_node->is_displayed_folded(); - - if (!collapsed) { - for(int i=0;i<p_node->get_child_count();i++) { - if (_is_node_visible(p_node->get_child(i))) { - last=p_node->get_child(i); - } - } - } - - if (last) { - Node* lastc=_find_last_visible(last); - if (lastc) - last=lastc; - - - } else { - last=p_node; - } - - return last; -} - - -void SceneTreeDock::_normalize_drop(Node*& to_node, int &to_pos, int p_type) { - - to_pos=-1; - - if (p_type==-1) { - //drop at above selected node - if (to_node==EditorNode::get_singleton()->get_edited_scene()) { - to_node=NULL; - ERR_EXPLAIN("Cannot perform drop above the root node!"); - ERR_FAIL(); - } - - to_pos=to_node->get_index(); - to_node=to_node->get_parent(); - - } else if (p_type==1) { - //drop at below selected node - if (to_node==EditorNode::get_singleton()->get_edited_scene()) { - //if at lower sibling of root node - to_pos=0; //just insert at begining of root node - return; - } - - - Node* lower_sibling=NULL; - - - - if (_has_visible_children(to_node) ) { - to_pos=0; - } else { - - - for(int i=to_node->get_index()+1;i<to_node->get_parent()->get_child_count();i++) { - Node *c =to_node->get_parent()->get_child(i); - if (_is_node_visible(c)) { - lower_sibling=c; - break; - } - } - if (lower_sibling) { - to_pos=lower_sibling->get_index(); - } - - to_node=to_node->get_parent(); - - - } -#if 0 - //quite complicated, look for next visible in tree - upper_sibling=_find_last_visible(upper_sibling); - - if (upper_sibling->get_parent()==to_node->get_parent()) { - //just insert over this node because nothing is above at an upper level - to_pos=to_node->get_index(); - to_node=to_node->get_parent(); - } else { - to_pos=-1; //insert last in whathever is up - to_node=upper_sibling->get_parent(); //insert at a parent of whathever is up - } - - - } else { - //just insert over this node because nothing is above at the same level - to_pos=to_node->get_index(); - to_node=to_node->get_parent(); - } -#endif - - } - -} - -void SceneTreeDock::_files_dropped(Vector<String> p_files,NodePath p_to,int p_type) { - - Node *node = get_node(p_to); - ERR_FAIL_COND(!node); - - int to_pos=-1; - _normalize_drop(node,to_pos,p_type); - _perform_instance_scenes(p_files,node,to_pos); -} - -void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) { - Ref<Script> scr = ResourceLoader::load(p_file); - ERR_FAIL_COND(!scr.is_valid()); - Node *n = get_node(p_to); - if (n) { - n->set_script(scr.get_ref_ptr()); - } -} - -void SceneTreeDock::_nodes_dragged(Array p_nodes,NodePath p_to,int p_type) { - - Vector<Node*> nodes; - Node *to_node; - - for(int i=0;i<p_nodes.size();i++) { - Node *n=get_node((p_nodes[i])); - if (n) { - nodes.push_back(n); - } - } - - if (nodes.size()==0) - return; - - to_node=get_node(p_to); - if (!to_node) - return; - - int to_pos=-1; - - _normalize_drop(to_node,to_pos,p_type); - _do_reparent(to_node,to_pos,nodes,true); - -} - -void SceneTreeDock::_tree_rmb(const Vector2& p_menu_pos) { - if (!EditorNode::get_singleton()->get_edited_scene()) { - - menu->clear(); - menu->add_icon_shortcut(get_icon("Add","EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW); - menu->add_icon_shortcut(get_icon("Instance","EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE); - - menu->set_size(Size2(1,1)); - menu->set_pos(p_menu_pos); - menu->popup(); - return; - } - - List<Node*> selection = editor_selection->get_selected_node_list(); - - if (selection.size()==0) - return; - - menu->clear(); - - - if (selection.size()==1) { - menu->add_icon_shortcut(get_icon("Add","EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW); - menu->add_icon_shortcut(get_icon("Instance","EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE); - menu->add_separator(); - menu->add_icon_shortcut(get_icon("Reload","EditorIcons"),ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE); - //menu->add_separator(); moved to their own dock - //menu->add_icon_item(get_icon("Groups","EditorIcons"),TTR("Edit Groups"),TOOL_GROUP); - //menu->add_icon_item(get_icon("Connect","EditorIcons"),TTR("Edit Connections"),TOOL_CONNECT); - menu->add_separator(); - menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT); - menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT); - menu->add_separator(); - } - - menu->add_icon_shortcut(get_icon("Up","EditorIcons"),ED_GET_SHORTCUT("scene_tree/move_up"), TOOL_MOVE_UP); - menu->add_icon_shortcut(get_icon("Down","EditorIcons"),ED_GET_SHORTCUT("scene_tree/move_down"), TOOL_MOVE_DOWN); - menu->add_icon_shortcut(get_icon("Duplicate","EditorIcons"),ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE); - menu->add_icon_shortcut(get_icon("Reparent","EditorIcons"),ED_GET_SHORTCUT("scene_tree/reparent"), TOOL_REPARENT); - - if (selection.size()==1) { - menu->add_separator(); - menu->add_icon_shortcut(get_icon("Blend","EditorIcons"),ED_GET_SHORTCUT("scene_tree/merge_from_scene"), TOOL_MERGE_FROM_SCENE); - menu->add_icon_shortcut(get_icon("CreateNewSceneFrom","EditorIcons"),ED_GET_SHORTCUT("scene_tree/save_branch_as_scene"), TOOL_NEW_SCENE_FROM); - menu->add_separator(); - menu->add_icon_shortcut(get_icon("CopyNodePath","EditorIcons"), ED_GET_SHORTCUT("scene_tree/copy_node_path"), TOOL_COPY_NODE_PATH); - } - menu->add_separator(); - menu->add_icon_shortcut(get_icon("Remove","EditorIcons"), ED_SHORTCUT("scene_tree/delete", TTR("Delete Node(s)"), KEY_DELETE), TOOL_ERASE); - menu->set_size(Size2(1,1)); - menu->set_pos(p_menu_pos); - menu->popup(); - -} - - -void SceneTreeDock::_filter_changed(const String& p_filter) { - - scene_tree->set_filter(p_filter); -} - -String SceneTreeDock::get_filter() { - - return filter->get_text(); -} - -void SceneTreeDock::set_filter(const String& p_filter){ - - filter->set_text(p_filter); - scene_tree->set_filter(p_filter); -} - - -void SceneTreeDock::_focus_node() { - - Node *node = scene_tree->get_selected(); - ERR_FAIL_COND(!node); - - if (node->is_class("CanvasItem")) { - CanvasItemEditorPlugin *editor = editor_data->get_editor("2D")->cast_to<CanvasItemEditorPlugin>(); - editor->get_canvas_item_editor()->focus_selection(); - } else { - SpatialEditorPlugin *editor = editor_data->get_editor("3D")->cast_to<SpatialEditorPlugin>(); - editor->get_spatial_editor()->get_editor_viewport(0)->focus_selection(); - } -} - -void SceneTreeDock::open_script_dialog(Node* p_for_node) { - - scene_tree->set_selected(p_for_node,false); - _tool_selected(TOOL_ATTACH_SCRIPT); -} - -void SceneTreeDock::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_tool_selected"),&SceneTreeDock::_tool_selected,DEFVAL(false)); - ClassDB::bind_method(D_METHOD("_create"),&SceneTreeDock::_create); - //ClassDB::bind_method(D_METHOD("_script_created"),&SceneTreeDock::_script_created); - ClassDB::bind_method(D_METHOD("_node_reparent"),&SceneTreeDock::_node_reparent); - ClassDB::bind_method(D_METHOD("_set_owners"),&SceneTreeDock::_set_owners); - ClassDB::bind_method(D_METHOD("_node_selected"),&SceneTreeDock::_node_selected); - ClassDB::bind_method(D_METHOD("_node_renamed"),&SceneTreeDock::_node_renamed); - ClassDB::bind_method(D_METHOD("_script_created"),&SceneTreeDock::_script_created); - ClassDB::bind_method(D_METHOD("_load_request"),&SceneTreeDock::_load_request); - ClassDB::bind_method(D_METHOD("_script_open_request"),&SceneTreeDock::_script_open_request); - ClassDB::bind_method(D_METHOD("_unhandled_key_input"),&SceneTreeDock::_unhandled_key_input); - ClassDB::bind_method(D_METHOD("_input"),&SceneTreeDock::_input); - ClassDB::bind_method(D_METHOD("_nodes_drag_begin"),&SceneTreeDock::_nodes_drag_begin); - ClassDB::bind_method(D_METHOD("_delete_confirm"),&SceneTreeDock::_delete_confirm); - ClassDB::bind_method(D_METHOD("_node_prerenamed"),&SceneTreeDock::_node_prerenamed); - ClassDB::bind_method(D_METHOD("_import_subscene"),&SceneTreeDock::_import_subscene); - ClassDB::bind_method(D_METHOD("_selection_changed"),&SceneTreeDock::_selection_changed); - ClassDB::bind_method(D_METHOD("_new_scene_from"),&SceneTreeDock::_new_scene_from); - ClassDB::bind_method(D_METHOD("_nodes_dragged"),&SceneTreeDock::_nodes_dragged); - ClassDB::bind_method(D_METHOD("_files_dropped"),&SceneTreeDock::_files_dropped); - ClassDB::bind_method(D_METHOD("_script_dropped"),&SceneTreeDock::_script_dropped); - ClassDB::bind_method(D_METHOD("_tree_rmb"),&SceneTreeDock::_tree_rmb); - ClassDB::bind_method(D_METHOD("_filter_changed"),&SceneTreeDock::_filter_changed); - ClassDB::bind_method(D_METHOD("_focus_node"),&SceneTreeDock::_focus_node); - - - ClassDB::bind_method(D_METHOD("instance"),&SceneTreeDock::instance); -} - - - -SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelection *p_editor_selection,EditorData &p_editor_data) { - - editor=p_editor; - edited_scene=NULL; - editor_data=&p_editor_data; - editor_selection=p_editor_selection; - scene_root=p_scene_root; - - VBoxContainer *vbc = this; - - HBoxContainer *filter_hbc = memnew( HBoxContainer ); - ToolButton *tb; - - ED_SHORTCUT("scene_tree/add_child_node",TTR("Add Child Node"), KEY_MASK_CMD|KEY_A); - ED_SHORTCUT("scene_tree/instance_scene",TTR("Instance Child Scene")); - ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type")); - ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script")); - ED_SHORTCUT("scene_tree/clear_script", TTR("Clear Script")); - ED_SHORTCUT("scene_tree/move_up", TTR("Move Up"), KEY_MASK_CMD | KEY_UP); - ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KEY_MASK_CMD | KEY_DOWN); - ED_SHORTCUT("scene_tree/duplicate", TTR("Duplicate"),KEY_MASK_CMD | KEY_D); - ED_SHORTCUT("scene_tree/reparent", TTR("Reparent")); - ED_SHORTCUT("scene_tree/merge_from_scene", TTR("Merge From Scene")); - ED_SHORTCUT("scene_tree/save_branch_as_scene", TTR("Save Branch as Scene")); - ED_SHORTCUT("scene_tree/copy_node_path", TTR("Copy Node Path"), KEY_MASK_CMD|KEY_C); - ED_SHORTCUT("scene_tree/delete_no_confirm", TTR("Delete (No Confirm)"), KEY_MASK_SHIFT|KEY_DELETE); - ED_SHORTCUT("scene_tree/delete", TTR("Delete"), KEY_DELETE); - - tb = memnew( ToolButton ); - tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_NEW, false)); - tb->set_tooltip(TTR("Add/Create a New Node")); - tb->set_shortcut(ED_GET_SHORTCUT("scene_tree/add_child_node")); - filter_hbc->add_child(tb); - button_add=tb; - - tb = memnew( ToolButton ); - tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_INSTANCE, false)); - tb->set_tooltip(TTR("Instance a scene file as a Node. Creates an inherited scene if no root node exists.")); - tb->set_shortcut(ED_GET_SHORTCUT("scene_tree/instance_scene")); - filter_hbc->add_child(tb); - button_instance=tb; - - - - vbc->add_child(filter_hbc); - filter = memnew( LineEdit ); - filter->set_h_size_flags(SIZE_EXPAND_FILL); - filter_hbc->add_child(filter); - filter_icon = memnew( TextureRect ); - filter_hbc->add_child(filter_icon); - filter_icon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); - filter->connect("text_changed",this,"_filter_changed"); - - - tb = memnew( ToolButton ); - tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_ATTACH_SCRIPT, false)); - tb->set_tooltip(TTR("Attach a new or existing script for the selected node.")); - tb->set_shortcut(ED_GET_SHORTCUT("scene_tree/attach_script")); - filter_hbc->add_child(tb); - button_create_script=tb; - - tb = memnew(ToolButton); - tb->connect("pressed", this, "_tool_selected", make_binds(TOOL_CLEAR_SCRIPT, false)); - tb->set_tooltip(TTR("Clear a script for the selected node.")); - tb->set_shortcut(ED_GET_SHORTCUT("scene_tree/clear_script")); - filter_hbc->add_child(tb); - button_clear_script = tb; - - - scene_tree = memnew( SceneTreeEditor(false,true,true )); - vbc->add_child(scene_tree); - scene_tree->set_v_size_flags(SIZE_EXPAND|SIZE_FILL); - scene_tree->connect("rmb_pressed",this,"_tree_rmb"); - - scene_tree->connect("node_selected", this,"_node_selected",varray(),CONNECT_DEFERRED); - scene_tree->connect("node_renamed", this,"_node_renamed",varray(),CONNECT_DEFERRED); - scene_tree->connect("node_prerename", this,"_node_prerenamed"); - scene_tree->connect("open",this,"_load_request"); - scene_tree->connect("open_script",this,"_script_open_request"); - scene_tree->connect("nodes_rearranged",this,"_nodes_dragged"); - scene_tree->connect("files_dropped",this,"_files_dropped"); - scene_tree->connect("script_dropped",this,"_script_dropped"); - scene_tree->connect("nodes_dragged",this,"_nodes_drag_begin"); - - scene_tree->get_scene_tree()->connect("item_double_clicked", this, "_focus_node"); - - scene_tree->set_undo_redo(&editor_data->get_undo_redo()); - scene_tree->set_editor_selection(editor_selection); - - - create_dialog = memnew( CreateDialog ); - create_dialog->set_base_type("Node"); - add_child(create_dialog); - create_dialog->connect("create",this,"_create"); - - //groups_editor = memnew( GroupsEditor ); - //add_child(groups_editor); - //groups_editor->set_undo_redo(&editor_data->get_undo_redo()); - - //connect_dialog = memnew( ConnectionsDialog(p_editor) ); - //add_child(connect_dialog); - //connect_dialog->set_undoredo(&editor_data->get_undo_redo()); - - script_create_dialog = memnew( ScriptCreateDialog ); - add_child(script_create_dialog); - script_create_dialog->connect("script_created",this,"_script_created"); - - reparent_dialog = memnew( ReparentDialog ); - add_child(reparent_dialog); - reparent_dialog->connect("reparent",this,"_node_reparent"); - - accept = memnew( AcceptDialog ); - add_child(accept); - - file = memnew( EditorFileDialog ); - add_child(file); - file->connect("file_selected",this,"instance"); - set_process_unhandled_key_input(true); - - delete_dialog = memnew( ConfirmationDialog ); - add_child(delete_dialog); - delete_dialog->connect("confirmed",this,"_delete_confirm"); - - import_subscene_dialog = memnew( EditorSubScene ); - add_child(import_subscene_dialog); - import_subscene_dialog->connect("subscene_selected",this,"_import_subscene"); - - new_scene_from_dialog = memnew( EditorFileDialog ); - new_scene_from_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE); - add_child(new_scene_from_dialog); - new_scene_from_dialog->connect("file_selected",this,"_new_scene_from"); - - - menu = memnew( PopupMenu ); - add_child(menu); - menu->connect("id_pressed",this,"_tool_selected"); - first_enter=true; - restore_script_editor_on_drag=false; - - vbc->add_constant_override("separation",4); - set_process_input(true); -} diff --git a/tools/editor/scene_tree_editor.cpp b/tools/editor/scene_tree_editor.cpp deleted file mode 100644 index 0e15040a35..0000000000 --- a/tools/editor/scene_tree_editor.cpp +++ /dev/null @@ -1,1316 +0,0 @@ -/*************************************************************************/ -/* scene_tree_editor.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 "scene_tree_editor.h" - -#include "scene/gui/label.h" -#include "editor_node.h" -#include "print_string.h" -#include "message_queue.h" -#include "scene/main/viewport.h" -#include "tools/editor/plugins/canvas_item_editor_plugin.h" -#include "scene/resources/packed_scene.h" - -Node *SceneTreeEditor::get_scene_node() { - - ERR_FAIL_COND_V(!is_inside_tree(),NULL); - - return get_tree()->get_edited_scene_root(); -} - - -void SceneTreeEditor::_subscene_option(int p_idx) { - - Object *obj = ObjectDB::get_instance(instance_node); - if (!obj) - return; - Node *node = obj->cast_to<Node>(); - if (!node) - return; - - switch(p_idx) { - - case SCENE_MENU_EDITABLE_CHILDREN: { - - bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node); - editable = !editable; - - //node->set_instance_children_editable(editable); - EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node,editable); - instance_menu->set_item_checked(0,editable); - if (editable) { - node->set_scene_instance_load_placeholder(false); - instance_menu->set_item_checked(1,false); - } - - _update_tree(); - - } break; - case SCENE_MENU_USE_PLACEHOLDER: { - - bool placeholder = node->get_scene_instance_load_placeholder(); - placeholder = !placeholder; - - //node->set_instance_children_editable(editable); - if (placeholder) { - EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node,false); - } - node->set_scene_instance_load_placeholder(placeholder); - instance_menu->set_item_checked(0,false); - instance_menu->set_item_checked(1,placeholder); - - _update_tree(); - - } break; - case SCENE_MENU_OPEN: { - - emit_signal("open",node->get_filename()); - } break; - case SCENE_MENU_CLEAR_INHERITANCE: { - clear_inherit_confirm->popup_centered_minsize(); - } break; - case SCENE_MENU_CLEAR_INSTANCING: { - - Node*root=EditorNode::get_singleton()->get_edited_scene(); - if (!root) - break; - - - ERR_FAIL_COND(node->get_filename()==String()); - - undo_redo->create_action("Discard Instancing"); - - undo_redo->add_do_method(node,"set_filename",""); - undo_redo->add_undo_method(node,"set_filename",node->get_filename()); - - _node_replace_owner(node,node,root); - - undo_redo->add_do_method(this,"update_tree"); - undo_redo->add_undo_method(this,"update_tree"); - - undo_redo->commit_action(); - - - } break; - case SCENE_MENU_OPEN_INHERITED: { - if (node && node->get_scene_inherited_state().is_valid()) { - emit_signal("open",node->get_scene_inherited_state()->get_path()); - } - } break; - case SCENE_MENU_CLEAR_INHERITANCE_CONFIRM: { - if (node && node->get_scene_inherited_state().is_valid()) { - node->set_scene_inherited_state(Ref<SceneState>()); - update_tree(); - EditorNode::get_singleton()->get_property_editor()->update_tree(); - } - - } break; - - - } - -} - - -void SceneTreeEditor::_node_replace_owner(Node* p_base,Node* p_node,Node* p_root) { - - if (p_base!=p_node) { - - if (p_node->get_owner()==p_base) { - - undo_redo->add_do_method(p_node,"set_owner",p_root); - undo_redo->add_undo_method(p_node,"set_owner",p_base); - } - } - - for(int i=0;i<p_node->get_child_count();i++) { - - _node_replace_owner(p_base,p_node->get_child(i),p_root); - } -} - - -void SceneTreeEditor::_cell_button_pressed(Object *p_item,int p_column,int p_id) { - - TreeItem *item=p_item->cast_to<TreeItem>(); - ERR_FAIL_COND(!item); - - NodePath np = item->get_metadata(0); - - Node *n=get_node(np); - ERR_FAIL_COND(!n); - - if (p_id==BUTTON_SUBSCENE) { - //open scene request - Rect2 item_rect = tree->get_item_rect(item,0); - item_rect.pos.y-=tree->get_scroll().y; - item_rect.pos+=tree->get_global_pos(); - - if (n==get_scene_node()) { - inheritance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y)); - inheritance_menu->set_size(Vector2(item_rect.size.x,0)); - inheritance_menu->popup(); - instance_node=n->get_instance_ID(); - - } else { - instance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y)); - instance_menu->set_size(Vector2(item_rect.size.x,0)); - if (EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(n)) - instance_menu->set_item_checked(0,true); - else - instance_menu->set_item_checked(0,false); - - if (n->get_owner()==get_scene_node()) { - instance_menu->set_item_checked(1,n->get_scene_instance_load_placeholder()); - instance_menu->set_item_disabled(1,false); - } else { - - instance_menu->set_item_checked(1,false); - instance_menu->set_item_disabled(1,true); - } - - instance_menu->popup(); - instance_node=n->get_instance_ID(); - } - //emit_signal("open",n->get_filename()); - } else if (p_id==BUTTON_SCRIPT) { - RefPtr script=n->get_script(); - if (!script.is_null()) - emit_signal("open_script",script); - - } else if (p_id==BUTTON_VISIBILITY) { - - - if (n->is_class("Spatial")) { - - bool v = bool(n->call("is_visible")); - undo_redo->create_action(TTR("Toggle Spatial Visible")); - undo_redo->add_do_method(n,"set_visible",!v); - undo_redo->add_undo_method(n,"set_visible",v); - undo_redo->commit_action(); - - } else if (n->is_class("CanvasItem")) { - - bool v = bool(n->call("is_visible")); - undo_redo->create_action(TTR("Toggle CanvasItem Visible")); - undo_redo->add_do_method(n,v?"hide":"show"); - undo_redo->add_undo_method(n,v?"show":"hide"); - undo_redo->commit_action(); - } - - } else if (p_id==BUTTON_LOCK) { - - if (n->is_class("CanvasItem")) { - n->set_meta("_edit_lock_", Variant()); - _update_tree(); - emit_signal("node_changed"); - } - - } else if (p_id==BUTTON_GROUP) { - if (n->is_class("CanvasItem")) { - n->set_meta("_edit_group_", Variant()); - _update_tree(); - emit_signal("node_changed"); - } - } else if (p_id==BUTTON_WARNING) { - - String config_err = n->get_configuration_warning(); - if (config_err==String()) - return; - config_err=config_err.word_wrap(80); - warning->set_text(config_err); - warning->popup_centered_minsize(); - - } else if (p_id==BUTTON_SIGNALS) { - - editor_selection->clear(); - editor_selection->add_node(n); - - set_selected(n); - - NodeDock::singleton->get_parent()->call("set_current_tab",NodeDock::singleton->get_index()); - NodeDock::singleton->show_connections(); - - } else if (p_id==BUTTON_GROUPS) { - - editor_selection->clear(); - editor_selection->add_node(n); - - set_selected(n); - - NodeDock::singleton->get_parent()->call("set_current_tab",NodeDock::singleton->get_index()); - NodeDock::singleton->show_groups(); - } -} - -bool SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) { - - if (!p_node) - return false; - - // only owned nodes are editable, since nodes can create their own (manually owned) child nodes, - // which the editor needs not to know about. - - bool part_of_subscene=false; - - if (!display_foreign && p_node->get_owner()!=get_scene_node() && p_node!=get_scene_node()) { - - if ((show_enabled_subscene || can_open_instance) && p_node->get_owner() && (get_scene_node()->is_editable_instance(p_node->get_owner()))) { - - part_of_subscene=true; - //allow - } else { - return false; - } - } else { - part_of_subscene = p_node!=get_scene_node() && get_scene_node()->get_scene_inherited_state().is_valid() && get_scene_node()->get_scene_inherited_state()->find_node_by_path(get_scene_node()->get_path_to(p_node))>=0; - } - - TreeItem *item = tree->create_item(p_parent); - item->set_text(0, p_node->get_name() ); - if (can_rename && !part_of_subscene /*(p_node->get_owner() == get_scene_node() || p_node==get_scene_node())*/) - item->set_editable(0, true); - - item->set_selectable(0,true); - if (can_rename) { -#ifdef ENABLE_DEPRECATED - if (p_node->has_meta("_editor_collapsed")) { - //remove previous way of storing folding, which did not get along with scene inheritance and instancing - if ((bool)p_node->get_meta("_editor_collapsed")) - p_node->set_display_folded(true); - p_node->set_meta("_editor_collapsed",Variant()); - } -#endif - bool collapsed = p_node->is_displayed_folded(); - if (collapsed) - item->set_collapsed(true); - } - - Ref<Texture> icon; - if (p_node->has_meta("_editor_icon")) - icon=p_node->get_meta("_editor_icon"); - else - icon=get_icon( (has_icon(p_node->get_class(),"EditorIcons")?p_node->get_class():String("Object")),"EditorIcons"); - item->set_icon(0, icon ); - item->set_metadata( 0,p_node->get_path() ); - - if (part_of_subscene) { - - //item->set_selectable(0,marked_selectable); - item->set_custom_color(0,Color(0.8,0.4,0.20)); - - } else if (marked.has(p_node)) { - - item->set_selectable(0,marked_selectable); - item->set_custom_color(0,Color(0.8,0.1,0.10)); - } else if (!marked_selectable && !marked_children_selectable) { - - Node *node=p_node; - while(node) { - if (marked.has(node)) { - item->set_selectable(0,false); - item->set_custom_color(0,Color(0.8,0.1,0.10)); - break; - } - node=node->get_parent(); - } - } - - - - if (can_rename) { //should be can edit.. - - String warning = p_node->get_configuration_warning(); - if (warning!=String()) { - item->add_button(0,get_icon("NodeWarning","EditorIcons"),BUTTON_WARNING); - } - - bool has_connections = p_node->has_persistent_signal_connections(); - bool has_groups = p_node->has_persistent_groups(); - - if (has_connections && has_groups) { - item->add_button(0,get_icon("ConnectionAndGroups","EditorIcons"),BUTTON_SIGNALS); - } else if (has_connections) { - item->add_button(0,get_icon("Connect","EditorIcons"),BUTTON_SIGNALS); - } else if (has_groups) { - item->add_button(0,get_icon("Groups","EditorIcons"),BUTTON_GROUPS); - } - } - - if (p_node==get_scene_node() && p_node->get_scene_inherited_state().is_valid()) { - item->add_button(0,get_icon("InstanceOptions","EditorIcons"),BUTTON_SUBSCENE); - item->set_tooltip(0,TTR("Inherits:")+" "+p_node->get_scene_inherited_state()->get_path()+"\n"+TTR("Type:")+" "+p_node->get_class()); - } else if (p_node!=get_scene_node() && p_node->get_filename()!="" && can_open_instance) { - - item->add_button(0,get_icon("InstanceOptions","EditorIcons"),BUTTON_SUBSCENE); - item->set_tooltip(0,TTR("Instance:")+" "+p_node->get_filename()+"\n"+TTR("Type:")+" "+p_node->get_class()); - } else { - item->set_tooltip(0,String(p_node->get_name())+"\n"+TTR("Type:")+" "+p_node->get_class()); - } - - if (can_open_instance) { - - if (!p_node->is_connected("script_changed",this,"_node_script_changed")) - p_node->connect("script_changed",this,"_node_script_changed",varray(p_node)); - - - if (!p_node->get_script().is_null()) { - - item->add_button(0,get_icon("Script","EditorIcons"),BUTTON_SCRIPT); - } - - if (p_node->is_class("CanvasItem")) { - - bool is_locked = p_node->has_meta("_edit_lock_");//_edit_group_ - if (is_locked) - item->add_button(0,get_icon("Lock", "EditorIcons"), BUTTON_LOCK); - - bool is_grouped = p_node->has_meta("_edit_group_"); - if (is_grouped) - item->add_button(0,get_icon("Group", "EditorIcons"), BUTTON_GROUP); - - bool v = p_node->call("is_visible"); - if (v) - item->add_button(0,get_icon("Visible","EditorIcons"),BUTTON_VISIBILITY); - else - item->add_button(0,get_icon("Hidden","EditorIcons"),BUTTON_VISIBILITY); - - if (!p_node->is_connected("visibility_changed",this,"_node_visibility_changed")) - p_node->connect("visibility_changed",this,"_node_visibility_changed",varray(p_node)); - - _update_visibility_color(p_node, item); - } else if (p_node->is_class("Spatial")) { - - bool v = p_node->call("is_visible"); - if (v) - item->add_button(0,get_icon("Visible","EditorIcons"),BUTTON_VISIBILITY); - else - item->add_button(0,get_icon("Hidden","EditorIcons"),BUTTON_VISIBILITY); - - if (!p_node->is_connected("visibility_changed",this,"_node_visibility_changed")) - p_node->connect("visibility_changed",this,"_node_visibility_changed",varray(p_node)); - - _update_visibility_color(p_node, item); - } - - } - - if (editor_selection) { - if (editor_selection->is_selected(p_node)) { - - item->select(0); - } - } - - if (selected==p_node) { - if (!editor_selection) - item->select(0); - item->set_as_cursor(0); - } - - bool keep= (filter.is_subsequence_ofi(String(p_node->get_name()))); - - for (int i=0;i<p_node->get_child_count();i++) { - - bool child_keep = _add_nodes(p_node->get_child(i),item); - - keep = keep || child_keep; - - } - - if (!keep) { - memdelete(item); - return false; - } else { - return true; - } - -} - - -void SceneTreeEditor::_node_visibility_changed(Node *p_node) { - - - if (p_node!=get_scene_node() && !p_node->get_owner()) { - - return; - } - TreeItem* item=p_node?_find(tree->get_root(),p_node->get_path()):NULL; - if (!item) { - - return; - } - int idx=item->get_button_by_id(0,BUTTON_VISIBILITY); - ERR_FAIL_COND(idx==-1); - - bool visible=false; - - if (p_node->is_class("CanvasItem")) { - visible = p_node->call("is_visible"); - CanvasItemEditor::get_singleton()->get_viewport_control()->update(); - } else if (p_node->is_class("Spatial")) { - visible = p_node->call("is_visible"); - } - - if (visible) - item->set_button(0,idx,get_icon("Visible","EditorIcons")); - else - item->set_button(0,idx,get_icon("Hidden","EditorIcons")); - - _update_visibility_color(p_node, item); -} - -void SceneTreeEditor::_update_visibility_color(Node *p_node, TreeItem *p_item) { - if (p_node->is_class("CanvasItem") || p_node->is_class("Spatial")) { - Color color(1,1,1,1); - bool visible_on_screen = p_node->call("is_visible"); - if (!visible_on_screen) { - color = Color(0.6,0.6,0.6,1); - } - int idx=p_item->get_button_by_id(0,BUTTON_VISIBILITY); - p_item->set_button_color(0,idx,color); - } -} - -void SceneTreeEditor::_node_script_changed(Node *p_node) { - - _update_tree(); - /* - changes the order :| - TreeItem* item=p_node?_find(tree->get_root(),p_node->get_path()):NULL; - if (p_node->get_script().is_null()) { - - int idx=item->get_button_by_id(0,2); - if (idx>=0) - item->erase_button(0,idx); - } else { - - int idx=item->get_button_by_id(0,2); - if (idx<0) - item->add_button(0,get_icon("Script","EditorIcons"),2); - - }*/ - -} - -void SceneTreeEditor::_node_removed(Node *p_node) { - - if (EditorNode::get_singleton()->is_exiting()) - return; //speed up exit - - if (p_node->is_connected("script_changed",this,"_node_script_changed")) - p_node->disconnect("script_changed",this,"_node_script_changed"); - - if (p_node->is_class("Spatial") || p_node->is_class("CanvasItem")) { - if (p_node->is_connected("visibility_changed",this,"_node_visibility_changed")) - p_node->disconnect("visibility_changed",this,"_node_visibility_changed"); - } - - if (p_node==selected) { - selected=NULL; - emit_signal("node_selected"); - } - - -} -void SceneTreeEditor::_update_tree() { - - - if (!is_inside_tree()) { - tree_dirty=false; - return; - } - - updating_tree=true; - tree->clear(); - if (get_scene_node()) { - _add_nodes( get_scene_node(), NULL ); - last_hash = hash_djb2_one_64(0); - _compute_hash(get_scene_node(),last_hash); - - } - updating_tree=false; - - tree_dirty=false; - -} - -void SceneTreeEditor::_compute_hash(Node *p_node,uint64_t &hash) { - - hash=hash_djb2_one_64(p_node->get_instance_ID(),hash); - if (p_node->get_parent()) - hash=hash_djb2_one_64(p_node->get_parent()->get_instance_ID(),hash); //so a reparent still produces a different hash - - - for(int i=0;i<p_node->get_child_count();i++) { - - _compute_hash(p_node->get_child(i),hash); - } -} - -void SceneTreeEditor::_test_update_tree() { - - pending_test_update=false; - - if (!is_inside_tree()) - return; - - if(tree_dirty) - return; // don't even bother - - uint64_t hash = hash_djb2_one_64(0); - if (get_scene_node()) - _compute_hash(get_scene_node(),hash); - //test hash - if (hash==last_hash) - return; // did not change - - MessageQueue::get_singleton()->push_call(this,"_update_tree"); - tree_dirty=true; -} - -void SceneTreeEditor::_tree_changed() { - - if (EditorNode::get_singleton()->is_exiting()) - return; //speed up exit - if (pending_test_update) - return; - if (tree_dirty) - return; - - MessageQueue::get_singleton()->push_call(this,"_test_update_tree"); - pending_test_update=true; - -} - -void SceneTreeEditor::_selected_changed() { - - - TreeItem *s = tree->get_selected(); - ERR_FAIL_COND(!s); - NodePath np = s->get_metadata(0); - - Node *n=get_node(np); - - - if (n==selected) - return; - - - selected = get_node(np); - - blocked++; - emit_signal("node_selected"); - blocked--; - - -} - - -void SceneTreeEditor::_cell_multi_selected(Object *p_object,int p_cell,bool p_selected) { - - TreeItem *item = p_object->cast_to<TreeItem>(); - ERR_FAIL_COND(!item); - - NodePath np = item->get_metadata(0); - - Node *n=get_node(np); - - if (!n) - return; - - if (!editor_selection) - return; - - if (p_selected) { - editor_selection->add_node(n); - - } else { - editor_selection->remove_node(n); - - } - -} - -void SceneTreeEditor::_notification(int p_what) { - - if (p_what==NOTIFICATION_ENTER_TREE) { - - get_tree()->connect("tree_changed",this,"_tree_changed"); - get_tree()->connect("node_removed",this,"_node_removed"); - get_tree()->connect("node_configuration_warning_changed",this,"_warning_changed"); - - instance_menu->set_item_icon(5,get_icon("Load","EditorIcons")); - tree->connect("item_collapsed",this,"_cell_collapsed"); - inheritance_menu->set_item_icon(2,get_icon("Load","EditorIcons")); - clear_inherit_confirm->connect("confirmed",this,"_subscene_option",varray(SCENE_MENU_CLEAR_INHERITANCE_CONFIRM)); - - EditorSettings::get_singleton()->connect("settings_changed",this,"_editor_settings_changed"); - - - //get_scene()->connect("tree_changed",this,"_tree_changed",Vector<Variant>(),CONNECT_DEFERRED); - //get_scene()->connect("node_removed",this,"_node_removed",Vector<Variant>(),CONNECT_DEFERRED); - _update_tree(); - } - if (p_what==NOTIFICATION_EXIT_TREE) { - - get_tree()->disconnect("tree_changed",this,"_tree_changed"); - get_tree()->disconnect("node_removed",this,"_node_removed"); - tree->disconnect("item_collapsed",this,"_cell_collapsed"); - clear_inherit_confirm->disconnect("confirmed",this,"_subscene_option"); - get_tree()->disconnect("node_configuration_warning_changed",this,"_warning_changed"); - EditorSettings::get_singleton()->disconnect("settings_changed",this,"_editor_settings_changed"); - } - -} - - -TreeItem* SceneTreeEditor::_find(TreeItem *p_node,const NodePath& p_path) { - - if (!p_node) - return NULL; - - NodePath np=p_node->get_metadata(0); - if (np==p_path) - return p_node; - - TreeItem *children=p_node->get_children(); - while(children) { - - TreeItem *n=_find(children,p_path); - if (n) - return n; - children=children->get_next(); - } - - return NULL; -} - -void SceneTreeEditor::set_selected(Node *p_node,bool p_emit_selected) { - - ERR_FAIL_COND(blocked>0); - - if (pending_test_update) - _test_update_tree(); - if (tree_dirty) - _update_tree(); - - if (selected==p_node) - return; - - - TreeItem* item=p_node?_find(tree->get_root(),p_node->get_path()):NULL; - - if (item) { - // make visible when it's collapsed - TreeItem* node=item->get_parent(); - while (node && node!=tree->get_root()) { - node->set_collapsed(false); - node=node->get_parent(); - } - item->select(0); - item->set_as_cursor(0); - selected=p_node; - tree->ensure_cursor_is_visible(); - } else { - if (!p_node) - selected=NULL; - _update_tree(); - selected=p_node; - if (p_emit_selected) - emit_signal("node_selected"); - } - -} - -void SceneTreeEditor::_rename_node(ObjectID p_node,const String& p_name) { - - Object *o = ObjectDB::get_instance(p_node); - ERR_FAIL_COND(!o); - Node *n = o->cast_to<Node>(); - ERR_FAIL_COND(!n); - TreeItem* item=_find(tree->get_root(),n->get_path()); - ERR_FAIL_COND(!item); - - n->set_name( p_name ); - item->set_metadata(0,n->get_path()); - item->set_text(0,p_name); - emit_signal("node_renamed"); - - if (!tree_dirty) { - MessageQueue::get_singleton()->push_call(this,"_update_tree"); - tree_dirty=true; - } - - -} - - -void SceneTreeEditor::_renamed() { - - TreeItem *which=tree->get_edited(); - - ERR_FAIL_COND(!which); - NodePath np = which->get_metadata(0); - Node *n=get_node(np); - ERR_FAIL_COND(!n); - - String new_name=which->get_text(0); - if (new_name.find(".") != -1 || new_name.find("/") != -1) { - - error->set_text(TTR("Invalid node name, the following characters are not allowed:")+"\n \".\", \"/\""); - error->popup_centered_minsize(); - new_name=n->get_name(); - } - - if (new_name==n->get_name()) - return; - - if (!undo_redo) { - n->set_name( new_name ); - which->set_metadata(0,n->get_path()); - emit_signal("node_renamed"); - } else { - undo_redo->create_action(TTR("Rename Node")); - emit_signal("node_prerename",n,new_name); - undo_redo->add_do_method(this,"_rename_node",n->get_instance_ID(),new_name); - undo_redo->add_undo_method(this,"_rename_node",n->get_instance_ID(),n->get_name()); - undo_redo->commit_action(); - } -} - - -Node *SceneTreeEditor::get_selected() { - - return selected; -} - -void SceneTreeEditor::set_marked(const Set<Node*>& p_marked,bool p_selectable,bool p_children_selectable) { - - if (tree_dirty) - _update_tree(); - marked=p_marked; - marked_selectable=p_selectable; - marked_children_selectable=p_children_selectable; - _update_tree(); -} - -void SceneTreeEditor::set_marked(Node *p_marked,bool p_selectable,bool p_children_selectable) { - - Set<Node*> s; - if (p_marked) - s.insert(p_marked); - set_marked(s,p_selectable,p_children_selectable); - - -} - -void SceneTreeEditor::set_filter(const String& p_filter) { - - filter=p_filter; - _update_tree(); -} - -String SceneTreeEditor::get_filter() const { - - return filter; -} - - -void SceneTreeEditor::set_display_foreign_nodes(bool p_display) { - - display_foreign=p_display; - _update_tree(); -} -bool SceneTreeEditor::get_display_foreign_nodes() const { - - return display_foreign; -} - -void SceneTreeEditor::set_editor_selection(EditorSelection *p_selection) { - - editor_selection=p_selection; - tree->set_select_mode(Tree::SELECT_MULTI); - tree->set_cursor_can_exit_tree(false); - editor_selection->connect("selection_changed",this,"_selection_changed"); -} - -void SceneTreeEditor::_update_selection(TreeItem *item) { - - ERR_FAIL_COND(!item); - - NodePath np = item->get_metadata(0); - - if (!has_node(np)) - return; - - Node *n=get_node(np); - - if (!n) - return; - - if (editor_selection->is_selected(n)) - item->select(0); - else - item->deselect(0); - - TreeItem *c=item->get_children(); - - - while(c) { - - _update_selection(c); - c=c->get_next(); - } -} - -void SceneTreeEditor::_selection_changed() { - - if (!editor_selection) - return; - - TreeItem *root=tree->get_root(); - - if (!root) - return; - _update_selection(root); -} - -void SceneTreeEditor::_cell_collapsed(Object *p_obj) { - - if (updating_tree) - return; - if (!can_rename) - return; - - TreeItem *ti=p_obj->cast_to<TreeItem>(); - if (!ti) - return; - - bool collapsed=ti->is_collapsed(); - - NodePath np = ti->get_metadata(0); - - Node *n=get_node(np); - ERR_FAIL_COND(!n); - - n->set_display_folded(collapsed); - -} - -Variant SceneTreeEditor::get_drag_data_fw(const Point2& p_point,Control* p_from) { - if (!can_rename) - return Variant(); //not editable tree - - Vector<Node*> selected; - Vector<Ref<Texture> > icons; - TreeItem *next=tree->get_next_selected(NULL); - while (next) { - - NodePath np = next->get_metadata(0); - - Node *n=get_node(np); - if (n) { - - selected.push_back(n); - icons.push_back(next->get_icon(0)); - } - next=tree->get_next_selected(next); - } - - if (selected.empty()) - return Variant(); - - VBoxContainer *vb = memnew( VBoxContainer ); - Array objs; - int list_max = 10; - float opacity_step = 1.0f / list_max; - float opacity_item = 1.0f; - for(int i=0;i<selected.size();i++) { - - if (i<list_max){ - HBoxContainer *hb = memnew( HBoxContainer ); - TextureRect *tf = memnew(TextureRect); - tf->set_texture(icons[i]); - hb->add_child(tf); - Label *label = memnew( Label( selected[i]->get_name() ) ); - hb->add_child(label); - vb->add_child(hb); - hb->set_modulate(Color(1,1,1,opacity_item)); - opacity_item -= opacity_step; - } - NodePath p = selected[i]->get_path(); - objs.push_back(p); - } - - set_drag_preview(vb); - Dictionary drag_data; - drag_data["type"]="nodes"; - drag_data["nodes"]=objs; - - tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN|Tree::DROP_MODE_ON_ITEM); - emit_signal("nodes_dragged"); - - return drag_data; -} - -bool SceneTreeEditor::_is_script_type(const StringName &p_type) const { - return (script_types->find(p_type)); -} - -bool SceneTreeEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const { - - if (!can_rename) - return false; //not editable tree - if (filter!=String()) - return false; //can't rearrange tree with filter turned on - - - Dictionary d=p_data; - if (!d.has("type")) - return false; - - TreeItem *item = tree->get_item_at_pos(p_point); - if (!item) - return false; - - int section = tree->get_drop_section_at_pos(p_point); - if (section<-1 || (section==-1 && !item->get_parent())) - return false; - - if (String(d["type"])=="files") { - - Vector<String> files = d["files"]; - - if (files.size()==0) - return false; //weird - - if (_is_script_type(EditorFileSystem::get_singleton()->get_file_type(files[0]))) { - tree->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM); - return true; - } - - for(int i=0;i<files.size();i++) { - String file = files[i]; - String ftype = EditorFileSystem::get_singleton()->get_file_type(file); - if (ftype!="PackedScene") - return false; - } - - tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN|Tree::DROP_MODE_ON_ITEM); //so it works.. - - return true; - } - - - if (String(d["type"])=="nodes") { - return true; - } - - return false; -} -void SceneTreeEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) { - - if (!can_drop_data_fw(p_point,p_data,p_from)) - return; - - TreeItem *item = tree->get_item_at_pos(p_point); - if (!item) - return; - int section = tree->get_drop_section_at_pos(p_point); - if (section<-1) - return; - - NodePath np = item->get_metadata(0); - Node *n=get_node(np); - if (!n) - return; - - Dictionary d=p_data; - - if (String(d["type"])=="nodes") { - Array nodes=d["nodes"]; - emit_signal("nodes_rearranged",nodes,np,section); - } - - if (String(d["type"])=="files") { - - Vector<String> files = d["files"]; - - - String ftype = EditorFileSystem::get_singleton()->get_file_type(files[0]); - if (_is_script_type(ftype)) { - emit_signal("script_dropped", files[0],np); - } else { - emit_signal("files_dropped",files,np,section); - } - } - -} - -void SceneTreeEditor::_rmb_select(const Vector2& p_pos) { - - emit_signal("rmb_pressed",tree->get_global_transform().xform(p_pos)); -} - - -void SceneTreeEditor::_warning_changed(Node* p_for_node) { - - //should use a timer - update_timer->start(); - //print_line("WARNING CHANGED "+String(p_for_node->get_name())); - -} - - -void SceneTreeEditor::_editor_settings_changed() { - bool enable_rl = EditorSettings::get_singleton()->get("docks/scene_tree/draw_relationship_lines"); - Color rl_color = EditorSettings::get_singleton()->get("docks/scene_tree/relationship_line_color"); - - if (enable_rl) { - tree->add_constant_override("draw_relationship_lines",1); - tree->add_color_override("relationship_line_color", rl_color); - } - else - tree->add_constant_override("draw_relationship_lines",0); - -} - - -void SceneTreeEditor::_bind_methods() { - - ClassDB::bind_method("_tree_changed",&SceneTreeEditor::_tree_changed); - ClassDB::bind_method("_update_tree",&SceneTreeEditor::_update_tree); - ClassDB::bind_method("_node_removed",&SceneTreeEditor::_node_removed); - ClassDB::bind_method("_selected_changed",&SceneTreeEditor::_selected_changed); - ClassDB::bind_method("_renamed",&SceneTreeEditor::_renamed); - ClassDB::bind_method("_rename_node",&SceneTreeEditor::_rename_node); - ClassDB::bind_method("_test_update_tree",&SceneTreeEditor::_test_update_tree); - ClassDB::bind_method("_cell_multi_selected",&SceneTreeEditor::_cell_multi_selected); - ClassDB::bind_method("_selection_changed",&SceneTreeEditor::_selection_changed); - ClassDB::bind_method("_cell_button_pressed",&SceneTreeEditor::_cell_button_pressed); - ClassDB::bind_method("_cell_collapsed",&SceneTreeEditor::_cell_collapsed); - ClassDB::bind_method("_subscene_option",&SceneTreeEditor::_subscene_option); - ClassDB::bind_method("_rmb_select",&SceneTreeEditor::_rmb_select); - ClassDB::bind_method("_warning_changed",&SceneTreeEditor::_warning_changed); - - ClassDB::bind_method("_node_script_changed",&SceneTreeEditor::_node_script_changed); - ClassDB::bind_method("_node_visibility_changed",&SceneTreeEditor::_node_visibility_changed); - - ClassDB::bind_method("_editor_settings_changed", &SceneTreeEditor::_editor_settings_changed); - - ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &SceneTreeEditor::get_drag_data_fw); - ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SceneTreeEditor::can_drop_data_fw); - ClassDB::bind_method(D_METHOD("drop_data_fw"), &SceneTreeEditor::drop_data_fw); - - ClassDB::bind_method(D_METHOD("update_tree"), &SceneTreeEditor::update_tree); - - ADD_SIGNAL( MethodInfo("node_selected") ); - ADD_SIGNAL( MethodInfo("node_renamed") ); - ADD_SIGNAL( MethodInfo("node_prerename") ); - ADD_SIGNAL( MethodInfo("node_changed") ); - ADD_SIGNAL( MethodInfo("nodes_dragged") ); - ADD_SIGNAL( MethodInfo("nodes_rearranged",PropertyInfo(Variant::ARRAY,"paths"),PropertyInfo(Variant::NODE_PATH,"to_path"),PropertyInfo(Variant::INT,"type") ) ); - ADD_SIGNAL( MethodInfo("files_dropped",PropertyInfo(Variant::POOL_STRING_ARRAY,"files"),PropertyInfo(Variant::NODE_PATH,"to_path"),PropertyInfo(Variant::INT,"type") ) ); - ADD_SIGNAL( MethodInfo("script_dropped",PropertyInfo(Variant::STRING,"file"),PropertyInfo(Variant::NODE_PATH,"to_path"))); - ADD_SIGNAL( MethodInfo("rmb_pressed",PropertyInfo(Variant::VECTOR2,"pos")) ) ; - - ADD_SIGNAL( MethodInfo("open") ); - ADD_SIGNAL( MethodInfo("open_script") ); - - -} - - -SceneTreeEditor::SceneTreeEditor(bool p_label,bool p_can_rename, bool p_can_open_instance) { - - - undo_redo=NULL; - tree_dirty=true; - selected=NULL; - - marked_selectable=false; - marked_children_selectable=false; - can_rename=p_can_rename; - can_open_instance=p_can_open_instance; - display_foreign=false; - editor_selection=NULL; - - if (p_label) { - Label *label = memnew( Label ); - label->set_pos( Point2(10, 0)); - label->set_text(TTR("Scene Tree (Nodes):")); - - add_child(label); - } - - tree = memnew( Tree ); - tree->set_anchor( MARGIN_RIGHT, ANCHOR_END ); - tree->set_anchor( MARGIN_BOTTOM, ANCHOR_END ); - tree->set_begin( Point2(0,p_label?18:0 )); - tree->set_end( Point2(0,0 )); - - add_child( tree ); - - tree->set_drag_forwarding(this); - if (p_can_rename) { - tree->set_allow_rmb_select(true); - tree->connect("item_rmb_selected",this,"_rmb_select"); - tree->connect("empty_tree_rmb_selected",this,"_rmb_select"); - } - - tree->connect("cell_selected", this,"_selected_changed"); - tree->connect("item_edited", this,"_renamed",varray(),CONNECT_DEFERRED); - tree->connect("multi_selected",this,"_cell_multi_selected"); - tree->connect("button_pressed",this,"_cell_button_pressed"); - //tree->connect("item_edited", this,"_renamed",Vector<Variant>(),true); - - error = memnew( AcceptDialog ); - add_child(error); - - warning = memnew( AcceptDialog ); - add_child(warning); - warning->set_title("Node Configuration Warning!"); - - - show_enabled_subscene=false; - - last_hash=0; - pending_test_update=false; - updating_tree=false; - blocked=0; - - instance_menu = memnew( PopupMenu ); - instance_menu->add_check_item(TTR("Editable Children"),SCENE_MENU_EDITABLE_CHILDREN); - instance_menu->add_check_item(TTR("Load As Placeholder"),SCENE_MENU_USE_PLACEHOLDER); - instance_menu->add_separator(); - instance_menu->add_item(TTR("Discard Instancing"),SCENE_MENU_CLEAR_INSTANCING); - instance_menu->add_separator(); - instance_menu->add_item(TTR("Open in Editor"),SCENE_MENU_OPEN); - instance_menu->connect("id_pressed",this,"_subscene_option"); - add_child(instance_menu); - - inheritance_menu = memnew( PopupMenu ); - inheritance_menu->add_item(TTR("Clear Inheritance"),SCENE_MENU_CLEAR_INHERITANCE); - inheritance_menu->add_separator(); - inheritance_menu->add_item(TTR("Open in Editor"),SCENE_MENU_OPEN_INHERITED); - inheritance_menu->connect("id_pressed",this,"_subscene_option"); - - add_child(inheritance_menu); - - clear_inherit_confirm = memnew( ConfirmationDialog ); - clear_inherit_confirm->set_text(TTR("Clear Inheritance? (No Undo!)")); - clear_inherit_confirm->get_ok()->set_text(TTR("Clear!")); - add_child(clear_inherit_confirm); - - update_timer = memnew(Timer); - update_timer->connect("timeout",this,"_update_tree"); - update_timer->set_one_shot(true); - update_timer->set_wait_time(0.5); - add_child(update_timer); - - script_types = memnew(List<StringName>); - ClassDB::get_inheriters_from_class("Script", script_types); - -} - - - -SceneTreeEditor::~SceneTreeEditor() { - - memdelete(script_types); -} - - -/******** DIALOG *********/ - -void SceneTreeDialog::_notification(int p_what) { - - if (p_what==NOTIFICATION_ENTER_TREE) { - connect("confirmed", this,"_select"); - - } - - if (p_what==NOTIFICATION_EXIT_TREE) { - disconnect("confirmed", this,"_select"); - - } - if (p_what==NOTIFICATION_DRAW) { - - RID ci = get_canvas_item(); - get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size())); - } - - if (p_what==NOTIFICATION_VISIBILITY_CHANGED && is_visible_in_tree()) { - - tree->update_tree(); - } - - -} - -void SceneTreeDialog::_cancel() { - - hide(); - - - -} -void SceneTreeDialog::_select() { - - if (tree->get_selected()) { - emit_signal("selected",tree->get_selected()->get_path()); - hide(); - } -} - -void SceneTreeDialog::_bind_methods() { - - ClassDB::bind_method("_select",&SceneTreeDialog::_select); - ClassDB::bind_method("_cancel",&SceneTreeDialog::_cancel); - ADD_SIGNAL( MethodInfo("selected",PropertyInfo(Variant::NODE_PATH,"path"))); - -} - - -SceneTreeDialog::SceneTreeDialog() { - - set_title(TTR("Select a Node")); - - tree = memnew( SceneTreeEditor(false,false) ); - add_child(tree); - //set_child_rect(tree); - - tree->get_scene_tree()->connect("item_activated",this,"_select"); - -} - - -SceneTreeDialog::~SceneTreeDialog() -{ -} diff --git a/tools/editor/script_create_dialog.h b/tools/editor/script_create_dialog.h deleted file mode 100644 index df16efc73c..0000000000 --- a/tools/editor/script_create_dialog.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************/ -/* script_create_dialog.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef SCRIPT_CREATE_DIALOG_H -#define SCRIPT_CREATE_DIALOG_H - -#include "scene/gui/dialogs.h" -#include "scene/gui/line_edit.h" -#include "scene/gui/option_button.h" -#include "tools/editor/editor_file_dialog.h" -#include "tools/editor/editor_settings.h" -#include "scene/gui/check_button.h" - -class ScriptCreateDialog : public ConfirmationDialog { - GDCLASS(ScriptCreateDialog,ConfirmationDialog); - - LineEdit *class_name; - Label *error_label; - Label *path_error_label; - LineEdit *parent_name; - OptionButton *language_menu; - LineEdit *file_path; - EditorFileDialog *file_browse; - CheckButton *internal; - VBoxContainer *path_vb; - AcceptDialog *alert; - bool path_valid; - bool create_new; - String initial_bp; - EditorSettings *editor_settings; - - - void _path_changed(const String& p_path=String()); - void _lang_changed(int l=0); - void _built_in_pressed(); - bool _validate(const String& p_strin); - void _class_name_changed(const String& p_name); - void _browse_path(); - void _file_selected(const String& p_file); - virtual void ok_pressed(); - void _create_new(); - void _load_exist(); - void _update_controls(); -protected: - - static void _bind_methods(); -public: - - void config(const String& p_base_name,const String&p_base_path); - - ScriptCreateDialog(); -}; - -#endif // SCRIPT_CREATE_DIALOG_H diff --git a/tools/editor/spatial_editor_gizmos.h b/tools/editor/spatial_editor_gizmos.h deleted file mode 100644 index 8a63d4f81e..0000000000 --- a/tools/editor/spatial_editor_gizmos.h +++ /dev/null @@ -1,521 +0,0 @@ -/*************************************************************************/ -/* spatial_editor_gizmos.h */ -/*************************************************************************/ -/* 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. */ -/*************************************************************************/ -#ifndef SPATIAL_EDITOR_GIZMOS_H -#define SPATIAL_EDITOR_GIZMOS_H - - -#include "tools/editor/plugins/spatial_editor_plugin.h" -#include "scene/3d/light.h" -#include "scene/3d/listener.h" -#include "scene/3d/camera.h" -#include "scene/3d/position_3d.h" -#include "scene/3d/test_cube.h" -#include "scene/3d/mesh_instance.h" -#include "scene/3d/body_shape.h" -#include "scene/3d/room_instance.h" -#include "scene/3d/visibility_notifier.h" -#include "scene/3d/portal.h" -#include "scene/3d/ray_cast.h" -#include "scene/3d/navigation_mesh.h" -#include "scene/3d/reflection_probe.h" -#include "scene/3d/gi_probe.h" - -#include "scene/3d/vehicle_body.h" -#include "scene/3d/collision_polygon.h" -#include "scene/3d/physics_joint.h" - - -class Camera; - -class EditorSpatialGizmo : public SpatialEditorGizmo { - - GDCLASS(EditorSpatialGizmo,SpatialGizmo); - - struct Instance{ - - RID instance; - Ref<Mesh> mesh; - RID skeleton; - bool billboard; - bool unscaled; - bool can_intersect; - bool extra_margin; - Instance() { - - billboard=false; - unscaled=false; - can_intersect=false; - extra_margin=false; - } - - void create_instance(Spatial *p_base); - - }; - - Vector<Vector3> collision_segments; - Ref<TriangleMesh> collision_mesh; - - struct Handle { - Vector3 pos; - bool billboard; - }; - - Vector<Vector3> handles; - Vector<Vector3> secondary_handles; - bool billboard_handle; - - bool valid; - Spatial *base; - Vector<Instance> instances; - Spatial *spatial_node; - - void _set_spatial_node(Node *p_node) { set_spatial_node(p_node->cast_to<Spatial>()); } -protected: - void add_lines(const Vector<Vector3> &p_lines,const Ref<Material>& p_material,bool p_billboard=false); - void add_mesh(const Ref<Mesh>& p_mesh,bool p_billboard=false,const RID& p_skeleton=RID()); - void add_collision_segments(const Vector<Vector3> &p_lines); - void add_collision_triangles(const Ref<TriangleMesh>& p_tmesh); - void add_unscaled_billboard(const Ref<Material>& p_material,float p_scale=1); - void add_handles(const Vector<Vector3> &p_handles,bool p_billboard=false,bool p_secondary=false); - - void set_spatial_node(Spatial *p_node); - - static void _bind_methods(); -public: - - virtual Vector3 get_handle_pos(int p_idx) const; - virtual bool intersect_frustum(const Camera *p_camera,const Vector<Plane> &p_frustum); - virtual bool intersect_ray(const Camera *p_camera,const Point2& p_point, Vector3& r_pos, Vector3& r_normal,int *r_gizmo_handle=NULL,bool p_sec_first=false); - - void clear(); - void create(); - void transform(); - virtual void redraw(); - void free(); - - EditorSpatialGizmo(); - ~EditorSpatialGizmo(); -}; - - - -class LightSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(LightSpatialGizmo,EditorSpatialGizmo); - - Light* light; - -public: - - - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); - virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); - - void redraw(); - LightSpatialGizmo(Light* p_light=NULL); - -}; - -class CameraSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(CameraSpatialGizmo,EditorSpatialGizmo); - - Camera* camera; - -public: - - - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); - virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); - - void redraw(); - CameraSpatialGizmo(Camera* p_camera=NULL); - -}; - - - -class MeshInstanceSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(MeshInstanceSpatialGizmo,EditorSpatialGizmo); - - MeshInstance* mesh; - -public: - - void redraw(); - MeshInstanceSpatialGizmo(MeshInstance* p_mesh=NULL); - -}; - -class Position3DSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(Position3DSpatialGizmo,EditorSpatialGizmo); - - Position3D* p3d; - -public: - - void redraw(); - Position3DSpatialGizmo(Position3D* p_p3d=NULL); - -}; - -class SkeletonSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(SkeletonSpatialGizmo,EditorSpatialGizmo); - - Skeleton* skel; - -public: - - void redraw(); - SkeletonSpatialGizmo(Skeleton* p_skel=NULL); - -}; - - -class TestCubeSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(TestCubeSpatialGizmo,EditorSpatialGizmo); - - TestCube* tc; - -public: - void redraw(); - TestCubeSpatialGizmo(TestCube* p_tc=NULL); - -}; - - -class RoomSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(RoomSpatialGizmo,EditorSpatialGizmo); - - - struct _EdgeKey { - - Vector3 from; - Vector3 to; - - bool operator<(const _EdgeKey& p_with) const { return from==p_with.from ? to < p_with.to : from < p_with.from; } - }; - - - - Room* room; - -public: - - void redraw(); - RoomSpatialGizmo(Room* p_room=NULL); - -}; - - -class PortalSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(PortalSpatialGizmo,EditorSpatialGizmo); - - Portal* portal; - -public: - - void redraw(); - PortalSpatialGizmo(Portal* p_portal=NULL); - -}; - - -class VisibilityNotifierGizmo : public EditorSpatialGizmo { - - GDCLASS(VisibilityNotifierGizmo ,EditorSpatialGizmo); - - - VisibilityNotifier* notifier; - -public: - - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); - virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); - - void redraw(); - VisibilityNotifierGizmo(VisibilityNotifier* p_notifier=NULL); - -}; - - -class ReflectionProbeGizmo : public EditorSpatialGizmo { - - GDCLASS(ReflectionProbeGizmo ,EditorSpatialGizmo); - - - ReflectionProbe* probe; - -public: - - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); - virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); - - void redraw(); - ReflectionProbeGizmo(ReflectionProbe* p_notifier=NULL); - -}; - -class GIProbeGizmo : public EditorSpatialGizmo { - - GDCLASS(GIProbeGizmo ,EditorSpatialGizmo); - - - GIProbe* probe; - -public: - - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); - virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); - - void redraw(); - GIProbeGizmo(GIProbe* p_notifier=NULL); - -}; - - -class CollisionShapeSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(CollisionShapeSpatialGizmo,EditorSpatialGizmo); - - CollisionShape* cs; - -public: - virtual String get_handle_name(int p_idx) const; - virtual Variant get_handle_value(int p_idx) const; - virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point); - virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false); - void redraw(); - CollisionShapeSpatialGizmo(CollisionShape* p_cs=NULL); - -}; - - -class CollisionPolygonSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(CollisionPolygonSpatialGizmo,EditorSpatialGizmo); - - CollisionPolygon* polygon; - -public: - - void redraw(); - CollisionPolygonSpatialGizmo(CollisionPolygon* p_polygon=NULL); - -}; - - - -class RayCastSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(RayCastSpatialGizmo,EditorSpatialGizmo); - - RayCast* raycast; - -public: - - void redraw(); - RayCastSpatialGizmo(RayCast* p_raycast=NULL); - -}; - - - -class VehicleWheelSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(VehicleWheelSpatialGizmo,EditorSpatialGizmo); - - VehicleWheel* car_wheel; - -public: - - void redraw(); - VehicleWheelSpatialGizmo(VehicleWheel* p_car_wheel=NULL); - -}; - - -class NavigationMeshSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(NavigationMeshSpatialGizmo,EditorSpatialGizmo); - - - struct _EdgeKey { - - Vector3 from; - Vector3 to; - - bool operator<(const _EdgeKey& p_with) const { return from==p_with.from ? to < p_with.to : from < p_with.from; } - }; - - - - NavigationMeshInstance* navmesh; - -public: - - void redraw(); - NavigationMeshSpatialGizmo(NavigationMeshInstance* p_navmesh=NULL); - -}; - - -class PinJointSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(PinJointSpatialGizmo,EditorSpatialGizmo); - - PinJoint* p3d; - -public: - - void redraw(); - PinJointSpatialGizmo(PinJoint* p_p3d=NULL); - -}; - - -class HingeJointSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(HingeJointSpatialGizmo,EditorSpatialGizmo); - - HingeJoint* p3d; - -public: - - void redraw(); - HingeJointSpatialGizmo(HingeJoint* p_p3d=NULL); - -}; - -class SliderJointSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(SliderJointSpatialGizmo,EditorSpatialGizmo); - - SliderJoint* p3d; - -public: - - void redraw(); - SliderJointSpatialGizmo(SliderJoint* p_p3d=NULL); - -}; - -class ConeTwistJointSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(ConeTwistJointSpatialGizmo,EditorSpatialGizmo); - - ConeTwistJoint* p3d; - -public: - - void redraw(); - ConeTwistJointSpatialGizmo(ConeTwistJoint* p_p3d=NULL); - -}; - - -class Generic6DOFJointSpatialGizmo : public EditorSpatialGizmo { - - GDCLASS(Generic6DOFJointSpatialGizmo,EditorSpatialGizmo); - - Generic6DOFJoint* p3d; - -public: - - void redraw(); - Generic6DOFJointSpatialGizmo(Generic6DOFJoint* p_p3d=NULL); - -}; - - -class SpatialEditorGizmos { -public: - - Ref<FixedSpatialMaterial> create_line_material(const Color& p_base_color); - Ref<FixedSpatialMaterial> create_solid_material(const Color& p_base_color); - Ref<FixedSpatialMaterial> handle2_material; - Ref<FixedSpatialMaterial> handle_material; - Ref<FixedSpatialMaterial> light_material; - Ref<FixedSpatialMaterial> light_material_omni_icon; - Ref<FixedSpatialMaterial> light_material_directional_icon; - Ref<FixedSpatialMaterial> camera_material; - Ref<FixedSpatialMaterial> skeleton_material; - Ref<FixedSpatialMaterial> reflection_probe_material; - Ref<FixedSpatialMaterial> reflection_probe_material_internal; - Ref<FixedSpatialMaterial> gi_probe_material; - Ref<FixedSpatialMaterial> gi_probe_material_internal; - Ref<FixedSpatialMaterial> room_material; - Ref<FixedSpatialMaterial> portal_material; - Ref<FixedSpatialMaterial> raycast_material; - Ref<FixedSpatialMaterial> visibility_notifier_material; - Ref<FixedSpatialMaterial> car_wheel_material; - Ref<FixedSpatialMaterial> joint_material; - - Ref<FixedSpatialMaterial> navmesh_edge_material; - Ref<FixedSpatialMaterial> navmesh_solid_material; - Ref<FixedSpatialMaterial> navmesh_edge_material_disabled; - Ref<FixedSpatialMaterial> navmesh_solid_material_disabled; - - Ref<FixedSpatialMaterial> listener_icon; - - Ref<FixedSpatialMaterial> sample_player_icon; - Ref<FixedSpatialMaterial> stream_player_icon; - Ref<FixedSpatialMaterial> visibility_notifier_icon; - - Ref<FixedSpatialMaterial> shape_material; - Ref<Texture> handle_t; - - Ref<Mesh> pos3d_mesh; - Ref<Mesh> listener_line_mesh; - static SpatialEditorGizmos *singleton; - - Ref<TriangleMesh> test_cube_tm; - - - Ref<SpatialEditorGizmo> get_gizmo(Spatial *p_spatial); - - SpatialEditorGizmos(); -}; -#endif // SPATIAL_EDITOR_GIZMOS_H diff --git a/tools/editor/translations/Makefile b/tools/editor/translations/Makefile deleted file mode 100644 index bea20e877d..0000000000 --- a/tools/editor/translations/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Makefile providing various facilities to manage translations - -TEMPLATE = tools.pot -POFILES = $(wildcard *.po) -LANGS = $(POFILES:%.po=%) - -all: update merge - -update: - @cd ../..; python2 tools/translations/extract.py - -merge: - @for po in $(POFILES); do \ - echo -e "\nMerging $$po..."; \ - msgmerge -w 79 -C $$po $$po $(TEMPLATE) > "$$po".new; \ - mv -f "$$po".new $$po; \ - done - -check: - @for po in $(POFILES); do msgfmt -c $$po -o /dev/null; done diff --git a/tools/editor/translations/extract.py b/tools/editor/translations/extract.py deleted file mode 100755 index 1192c19011..0000000000 --- a/tools/editor/translations/extract.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/bin/python - -import fnmatch -import os -import shutil -import subprocess -import sys - - -line_nb = False - -for arg in sys.argv[1:]: - if (arg == "--with-line-nb"): - print("Enabling line numbers in the context locations.") - line_nb = True - else: - os.sys.exit("Non supported argument '" + arg + "'. Aborting.") - - -if (not os.path.exists("tools")): - os.sys.exit("ERROR: This script should be started from the root of the git repo.") - - -matches = [] -for root, dirnames, filenames in os.walk('.'): - for filename in fnmatch.filter(filenames, '*.cpp'): - if (filename.find("collada") != -1): - continue - matches.append(os.path.join(root, filename)) - for filename in fnmatch.filter(filenames, '*.h'): - if (filename.find("collada") != -1): - continue - matches.append(os.path.join(root, filename)) -matches.sort() - - -unique_str = [] -unique_loc = {} -main_po = """ -# LANGUAGE translation of the Godot Engine editor -# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community -# This file is distributed under the same license as the Godot source code. -# -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: Godot Engine editor\\n" -"Content-Type: text/plain; charset=UTF-8\\n" -"Content-Transfer-Encoding: 8-bit\\n" -""" - -print("Updating the tools.pot template...") - -for fname in matches: - - f = open(fname, "rb") - - l = f.readline() - lc = 1 - while (l): - - patterns = ['RTR(\"', 'TTR(\"'] - idx = 0 - pos = 0 - while (pos >= 0): - pos = l.find(patterns[idx], pos) - if (pos == -1): - if (idx < len(patterns) - 1): - idx += 1 - pos = 0 - continue - pos += 5 - - msg = "" - while (pos < len(l) and (l[pos] != '"' or l[pos - 1] == '\\')): - msg += l[pos] - pos += 1 - - location = os.path.relpath(fname).replace('\\', '/') - if (line_nb): - location += ":" + str(lc) - - if (not msg in unique_str): - main_po += "\n#: " + location + "\n" - main_po += 'msgid "' + msg + '"\n' - main_po += 'msgstr ""\n' - unique_str.append(msg) - unique_loc[msg] = [location] - elif (not location in unique_loc[msg]): - # Add additional location to previous occurence too - msg_pos = main_po.find('\nmsgid "' + msg + '"') - if (msg_pos == -1): - print("Someone apparently thought writing Python was as easy as GDScript. Ping Akien.") - main_po = main_po[:msg_pos] + ' ' + location + main_po[msg_pos:] - unique_loc[msg].append(location) - - l = f.readline() - lc += 1 - - f.close() - - -f = open("tools.pot", "wb") -f.write(main_po) -f.close() - -if (os.name == "posix"): - print("Wrapping template at 79 characters for compatibility with Weblate.") - os.system("msgmerge -w79 tools.pot tools.pot > tools.pot.wrap") - shutil.move("tools.pot.wrap", "tools.pot") - -shutil.move("tools.pot", "tools/translations/tools.pot") - -# TODO: Make that in a portable way, if we care; if not, kudos to Unix users -if (os.name == "posix"): - added = subprocess.check_output("git diff tools/translations/tools.pot | grep \+msgid | wc -l", shell=True) - removed = subprocess.check_output("git diff tools/translations/tools.pot | grep \\\-msgid | wc -l", shell=True) - print("\n# Template changes compared to the staged status:") - print("# Additions: %s msgids.\n# Deletions: %s msgids." % (int(added), int(removed))) |