summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/color.cpp2
-rw-r--r--core/command_queue_mt.h4
-rw-r--r--core/globals.cpp7
-rw-r--r--core/image.cpp87
-rw-r--r--core/image.h6
-rw-r--r--core/io/file_access_memory.cpp8
-rw-r--r--core/io/file_access_memory.h1
-rw-r--r--core/io/packet_peer.cpp21
-rw-r--r--core/io/packet_peer.h8
-rw-r--r--core/io/resource_loader.cpp1
-rw-r--r--core/math/math_2d.h23
-rw-r--r--core/message_queue.cpp19
-rw-r--r--core/object.cpp2
-rw-r--r--core/vector.h4
-rw-r--r--demos/2d/motion/engine.cfg3
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp6
-rw-r--r--drivers/gles2/rasterizer_gles2.h1
-rw-r--r--drivers/png/image_loader_png.cpp22
-rw-r--r--drivers/png/image_loader_png.h3
-rw-r--r--godot.creator.user.RG2068193
-rw-r--r--main/main.cpp8
-rwxr-xr-xplatform/iphone/gl_view.mm5
-rw-r--r--scene/2d/area_2d.cpp55
-rw-r--r--scene/2d/area_2d.h10
-rw-r--r--scene/2d/navigation2d.cpp29
-rw-r--r--scene/2d/navigation2d.h12
-rw-r--r--scene/2d/particles_2d.cpp152
-rw-r--r--scene/2d/particles_2d.h15
-rw-r--r--scene/2d/physics_body_2d.cpp39
-rw-r--r--scene/2d/physics_body_2d.h7
-rw-r--r--scene/3d/area.cpp16
-rw-r--r--scene/3d/area.h4
-rw-r--r--scene/3d/navigation.cpp30
-rw-r--r--scene/3d/navigation.h13
-rw-r--r--scene/3d/spatial.cpp3
-rw-r--r--scene/animation/animation_player.cpp2
-rw-r--r--scene/gui/color_ramp_edit.cpp368
-rw-r--r--scene/gui/color_ramp_edit.h52
-rw-r--r--scene/gui/item_list.cpp1048
-rw-r--r--scene/gui/item_list.h132
-rw-r--r--scene/gui/rich_text_label.cpp58
-rw-r--r--scene/gui/rich_text_label.h13
-rw-r--r--scene/gui/text_edit.cpp4
-rw-r--r--scene/register_scene_types.cpp6
-rw-r--r--scene/resources/audio_stream_resampled.cpp55
-rw-r--r--scene/resources/color_ramp.cpp117
-rw-r--r--scene/resources/color_ramp.h98
-rw-r--r--scene/resources/default_theme/checker_bg.pngbin0 -> 180 bytes
-rw-r--r--scene/resources/default_theme/default_theme.cpp24
-rw-r--r--scene/resources/default_theme/theme_data.h5
-rw-r--r--scene/resources/shader.cpp3
-rw-r--r--scene/resources/shader.h19
-rw-r--r--servers/physics/area_sw.cpp3
-rw-r--r--servers/physics/area_sw.h4
-rw-r--r--servers/physics/body_sw.cpp9
-rw-r--r--servers/physics_2d/area_2d_sw.cpp3
-rw-r--r--servers/physics_2d/area_2d_sw.h4
-rw-r--r--servers/physics_2d/body_2d_sw.cpp9
-rw-r--r--servers/physics_2d_server.cpp1
-rw-r--r--servers/physics_2d_server.h1
-rw-r--r--servers/physics_server.cpp1
-rw-r--r--servers/physics_server.h1
-rw-r--r--servers/visual/visual_server_raster.cpp2
-rw-r--r--servers/visual/visual_server_raster.h2
-rw-r--r--servers/visual/visual_server_wrap_mt.cpp12
-rw-r--r--servers/visual/visual_server_wrap_mt.h2
-rw-r--r--servers/visual_server.cpp2
-rw-r--r--servers/visual_server.h2
-rw-r--r--tools/editor/editor_dir_dialog.cpp17
-rw-r--r--tools/editor/editor_file_dialog.cpp1366
-rw-r--r--tools/editor/editor_file_dialog.h245
-rw-r--r--tools/editor/editor_file_system.cpp10
-rw-r--r--tools/editor/editor_node.cpp159
-rw-r--r--tools/editor/editor_node.h12
-rw-r--r--tools/editor/editor_resource_preview.cpp261
-rw-r--r--tools/editor/editor_resource_preview.h95
-rw-r--r--tools/editor/editor_settings.cpp92
-rw-r--r--tools/editor/editor_settings.h14
-rw-r--r--tools/editor/editor_sub_scene.cpp4
-rw-r--r--tools/editor/editor_sub_scene.h4
-rw-r--r--tools/editor/icons/icon_arrow_left.pngbin0 -> 243 bytes
-rw-r--r--tools/editor/icons/icon_arrow_left_disabled.pngbin0 -> 244 bytes
-rw-r--r--tools/editor/icons/icon_arrow_right.pngbin0 -> 263 bytes
-rw-r--r--tools/editor/icons/icon_arrow_right_disabled.pngbin0 -> 252 bytes
-rw-r--r--tools/editor/icons/icon_arrow_up.pngbin0 -> 259 bytes
-rw-r--r--tools/editor/icons/icon_arrow_up_disabled.pngbin0 -> 275 bytes
-rw-r--r--tools/editor/icons/icon_color_ramp.pngbin0 -> 290 bytes
-rw-r--r--tools/editor/icons/icon_favorites.pngbin375 -> 412 bytes
-rw-r--r--tools/editor/icons/icon_file_big.pngbin0 -> 986 bytes
-rw-r--r--tools/editor/icons/icon_file_list.pngbin0 -> 260 bytes
-rw-r--r--tools/editor/icons/icon_file_thumbnail.pngbin0 -> 296 bytes
-rw-r--r--tools/editor/icons/icon_folder_big.pngbin0 -> 1215 bytes
-rw-r--r--tools/editor/icons/icon_item_list.pngbin0 -> 341 bytes
-rw-r--r--tools/editor/icons/icon_remove.pngbin398 -> 519 bytes
-rw-r--r--tools/editor/icons/icon_remove_small.pngbin0 -> 297 bytes
-rw-r--r--tools/editor/icons/icon_wait_no_preview.pngbin0 -> 1041 bytes
-rw-r--r--tools/editor/icons/icon_wait_preview_1.pngbin0 -> 1208 bytes
-rw-r--r--tools/editor/icons/icon_wait_preview_2.pngbin0 -> 1270 bytes
-rw-r--r--tools/editor/icons/icon_wait_preview_3.pngbin0 -> 1190 bytes
-rw-r--r--tools/editor/icons/icon_wait_preview_4.pngbin0 -> 1269 bytes
-rw-r--r--tools/editor/icons/icon_wait_preview_5.pngbin0 -> 1191 bytes
-rw-r--r--tools/editor/icons/icon_wait_preview_6.pngbin0 -> 1278 bytes
-rw-r--r--tools/editor/icons/icon_wait_preview_7.pngbin0 -> 1192 bytes
-rw-r--r--tools/editor/icons/icon_wait_preview_8.pngbin0 -> 1341 bytes
-rw-r--r--tools/editor/io_plugins/editor_font_import_plugin.cpp14
-rw-r--r--tools/editor/io_plugins/editor_mesh_import_plugin.cpp12
-rw-r--r--tools/editor/io_plugins/editor_sample_import_plugin.cpp12
-rw-r--r--tools/editor/io_plugins/editor_scene_import_plugin.cpp16
-rw-r--r--tools/editor/io_plugins/editor_texture_import_plugin.cpp383
-rw-r--r--tools/editor/io_plugins/editor_texture_import_plugin.h8
-rw-r--r--tools/editor/io_plugins/editor_translation_import_plugin.cpp10
-rw-r--r--tools/editor/plugins/animation_player_editor_plugin.cpp6
-rw-r--r--tools/editor/plugins/animation_player_editor_plugin.h2
-rw-r--r--tools/editor/plugins/animation_tree_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/animation_tree_editor_plugin.h2
-rw-r--r--tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp1
-rw-r--r--tools/editor/plugins/collision_polygon_editor_plugin.cpp1
-rw-r--r--tools/editor/plugins/color_ramp_editor_plugin.cpp83
-rw-r--r--tools/editor/plugins/color_ramp_editor_plugin.h37
-rw-r--r--tools/editor/plugins/cube_grid_theme_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/cube_grid_theme_editor_plugin.h2
-rw-r--r--tools/editor/plugins/editor_preview_plugins.cpp777
-rw-r--r--tools/editor/plugins/editor_preview_plugins.h88
-rw-r--r--tools/editor/plugins/light_occluder_2d_editor_plugin.cpp1
-rw-r--r--tools/editor/plugins/navigation_polygon_editor_plugin.cpp2
-rw-r--r--tools/editor/plugins/particles_2d_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/particles_2d_editor_plugin.h2
-rw-r--r--tools/editor/plugins/particles_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/particles_editor_plugin.h2
-rw-r--r--tools/editor/plugins/resource_preloader_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/resource_preloader_editor_plugin.h2
-rw-r--r--tools/editor/plugins/rich_text_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/rich_text_editor_plugin.h2
-rw-r--r--tools/editor/plugins/sample_editor_plugin.cpp119
-rw-r--r--tools/editor/plugins/sample_library_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/sample_library_editor_plugin.h2
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.cpp10
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.h8
-rw-r--r--tools/editor/plugins/sprite_frames_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/sprite_frames_editor_plugin.h2
-rw-r--r--tools/editor/plugins/theme_editor_plugin.cpp6
-rw-r--r--tools/editor/plugins/theme_editor_plugin.h2
-rw-r--r--tools/editor/project_export.cpp10
-rw-r--r--tools/editor/project_export.h6
-rw-r--r--tools/editor/project_settings.cpp20
-rw-r--r--tools/editor/project_settings.h8
-rw-r--r--tools/editor/property_editor.cpp24
-rw-r--r--tools/editor/property_editor.h4
-rw-r--r--tools/editor/resources_dock.cpp4
-rw-r--r--tools/editor/resources_dock.h3
-rw-r--r--tools/editor/scene_tree_dock.cpp6
-rw-r--r--tools/editor/scene_tree_dock.h2
-rw-r--r--tools/editor/script_create_dialog.cpp4
-rw-r--r--tools/editor/script_create_dialog.h4
154 files changed, 6571 insertions, 330 deletions
diff --git a/core/color.cpp b/core/color.cpp
index ba4751dc2f..32f3df6d4b 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -161,7 +161,7 @@ void Color::invert() {
r=1.0-r;
g=1.0-g;
- g=1.0-b;
+ b=1.0-b;
}
void Color::contrast() {
diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h
index 0985f3cfe7..113199869b 100644
--- a/core/command_queue_mt.h
+++ b/core/command_queue_mt.h
@@ -34,6 +34,7 @@
#include "os/mutex.h"
#include "os/memory.h"
#include "simple_type.h"
+#include "print_string.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -174,7 +175,7 @@ class CommandQueueMT {
R* ret;
SyncSemaphore *sync;
- virtual void call() { *ret = (instance->*method)(p1); sync->sem->post(); sync->in_use=false; ; }
+ virtual void call() { *ret = (instance->*method)(p1); sync->sem->post(); print_line("post"); sync->in_use=false; ; }
};
template<class T,class M,class P1,class P2,class R>
@@ -675,6 +676,7 @@ public:
if (sync) sync->post();
ss->sem->wait();
+ print_line("wait");
}
template<class T, class M, class P1, class P2,class R>
diff --git a/core/globals.cpp b/core/globals.cpp
index 0315ff0c24..8a7d66b68a 100644
--- a/core/globals.cpp
+++ b/core/globals.cpp
@@ -1397,6 +1397,13 @@ Globals::Globals() {
set("input/ui_accept",va);
va=Array();
+ key.key.scancode=KEY_SPACE;
+ va.push_back(key);
+ joyb.joy_button.button_index=JOY_BUTTON_3;
+ va.push_back(joyb);
+ set("input/ui_select",va);
+
+ va=Array();
key.key.scancode=KEY_ESCAPE;
va.push_back(key);
joyb.joy_button.button_index=JOY_BUTTON_1;
diff --git a/core/image.cpp b/core/image.cpp
index 04b3905489..037018519e 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -1124,6 +1124,7 @@ void Image::create( const char ** p_xpm ) {
}
#define DETECT_ALPHA_MAX_TRESHOLD 254
#define DETECT_ALPHA_MIN_TRESHOLD 2
+
#define DETECT_ALPHA( m_value )\
{ \
uint8_t value=m_value;\
@@ -1136,6 +1137,82 @@ void Image::create( const char ** p_xpm ) {
}\
}
+#define DETECT_NON_ALPHA( m_value )\
+{ \
+ uint8_t value=m_value;\
+ if (value>0) {\
+ \
+ detected=true;\
+ break;\
+ }\
+}
+
+
+bool Image::is_invisible() const {
+
+ if (format==FORMAT_GRAYSCALE ||
+ format==FORMAT_RGB ||
+ format==FORMAT_INDEXED)
+ return false;
+
+ int len = data.size();
+
+ if (len==0)
+ return true;
+
+ if (format >= FORMAT_YUV_422 && format <= FORMAT_YUV_444)
+ return false;
+
+ int w,h;
+ _get_mipmap_offset_and_size(1,len,w,h);
+
+ DVector<uint8_t>::Read r = data.read();
+ const unsigned char *data_ptr=r.ptr();
+
+ bool detected=false;
+
+ switch(format) {
+ case FORMAT_INTENSITY: {
+
+ for(int i=0;i<len;i++) {
+ DETECT_NON_ALPHA(data_ptr[i]);
+ }
+ } break;
+ case FORMAT_GRAYSCALE_ALPHA: {
+
+
+ for(int i=0;i<(len>>1);i++) {
+ DETECT_NON_ALPHA(data_ptr[(i<<1)+1]);
+ }
+
+ } break;
+ case FORMAT_RGBA: {
+
+ for(int i=0;i<(len>>2);i++) {
+ DETECT_NON_ALPHA(data_ptr[(i<<2)+3])
+ }
+
+ } break;
+ case FORMAT_INDEXED: {
+
+ return false;
+ } break;
+ case FORMAT_INDEXED_ALPHA: {
+
+ return false;
+ } break;
+ case FORMAT_PVRTC2_ALPHA:
+ case FORMAT_PVRTC4_ALPHA:
+ case FORMAT_BC2:
+ case FORMAT_BC3: {
+ detected=true;
+ } break;
+ default: {}
+ }
+
+ return !detected;
+}
+
Image::AlphaMode Image::detect_alpha() const {
if (format==FORMAT_GRAYSCALE ||
@@ -1746,6 +1823,10 @@ Error Image::_decompress_bc() {
return OK;
}
+bool Image::is_compressed() const {
+ return format>=FORMAT_BC1;
+}
+
Image Image::decompressed() const {
@@ -1998,7 +2079,7 @@ void Image::blit_rect(const Image& p_src, const Rect2& p_src_rect,const Point2&
}
-Image (*Image::_png_mem_loader_func)(const uint8_t*)=NULL;
+Image (*Image::_png_mem_loader_func)(const uint8_t*,int)=NULL;
void (*Image::_image_compress_bc_func)(Image *)=NULL;
void (*Image::_image_compress_pvrtc2_func)(Image *)=NULL;
void (*Image::_image_compress_pvrtc4_func)(Image *)=NULL;
@@ -2167,7 +2248,7 @@ void Image::fix_alpha_edges() {
}
-Image::Image(const uint8_t* p_png) {
+Image::Image(const uint8_t* p_png,int p_len) {
width=0;
height=0;
@@ -2175,7 +2256,7 @@ Image::Image(const uint8_t* p_png) {
format=FORMAT_GRAYSCALE;
if (_png_mem_loader_func) {
- *this = _png_mem_loader_func(p_png);
+ *this = _png_mem_loader_func(p_png,p_len);
}
}
diff --git a/core/image.h b/core/image.h
index ddb5e88ebf..8ce4f22dc1 100644
--- a/core/image.h
+++ b/core/image.h
@@ -94,7 +94,7 @@ public:
/* INTERPOLATE GAUSS */
};
- static Image (*_png_mem_loader_func)(const uint8_t* p_png);
+ static Image (*_png_mem_loader_func)(const uint8_t* p_png,int p_size);
static void (*_image_compress_bc_func)(Image *);
static void (*_image_compress_pvrtc2_func)(Image *);
static void (*_image_compress_pvrtc4_func)(Image *);
@@ -305,6 +305,7 @@ public:
};
AlphaMode detect_alpha() const;
+ bool is_invisible() const;
void put_indexed_pixel(int p_x, int p_y, uint8_t p_idx,int p_mipmap=0);
uint8_t get_indexed_pixel(int p_x, int p_y,int p_mipmap=0) const;
@@ -335,6 +336,7 @@ public:
Image compressed(int p_mode); /* from the Image::CompressMode enum */
Error decompress();
Image decompressed() const;
+ bool is_compressed() const;
void fix_alpha_edges();
void premultiply_alpha();
@@ -349,7 +351,7 @@ public:
Image get_rect(const Rect2& p_area) const;
static void set_compress_bc_func(void (*p_compress_func)(Image *));
- Image(const uint8_t* p_mem_png);
+ Image(const uint8_t* p_mem_png, int p_len=-1);
Image(const char **p_xpm);
~Image();
diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp
index 2880c4ebda..83da55fc61 100644
--- a/core/io/file_access_memory.cpp
+++ b/core/io/file_access_memory.cpp
@@ -74,6 +74,14 @@ bool FileAccessMemory::file_exists(const String& p_name) {
}
+Error FileAccessMemory::open_custom(const uint8_t* p_data, int p_len) {
+
+ data=(uint8_t*)p_data;
+ length=p_len;
+ pos=0;
+ return OK;
+}
+
Error FileAccessMemory::_open(const String& p_path, int p_mode_flags) {
ERR_FAIL_COND_V(!files, ERR_FILE_NOT_FOUND);
diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h
index 5a9ec2b3c6..8c58a8a8ce 100644
--- a/core/io/file_access_memory.h
+++ b/core/io/file_access_memory.h
@@ -44,6 +44,7 @@ public:
static void register_file(String p_name, Vector<uint8_t> p_data);
static void cleanup();
+ virtual Error open_custom(const uint8_t* p_data, int p_len); ///< open a file
virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index 7b5ea65a4b..be566471a8 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -36,7 +36,7 @@
PacketPeer::PacketPeer() {
-
+ last_get_error=OK;
}
Error PacketPeer::get_packet_buffer(DVector<uint8_t> &r_buffer) const {
@@ -108,10 +108,29 @@ Variant PacketPeer::_bnd_get_var() const {
return var;
};
+Error PacketPeer::_put_packet(const DVector<uint8_t> &p_buffer) {
+ return put_packet_buffer(p_buffer);
+}
+DVector<uint8_t> PacketPeer::_get_packet() const {
+
+ DVector<uint8_t> raw;
+ last_get_error=get_packet_buffer(raw);
+ return raw;
+}
+
+Error PacketPeer::_get_packet_error() const {
+
+ return last_get_error;
+}
+
+
void PacketPeer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_var"),&PacketPeer::_bnd_get_var);
ObjectTypeDB::bind_method(_MD("put_var", "var:var"),&PacketPeer::put_var);
+ ObjectTypeDB::bind_method(_MD("get_packet:Error"),&PacketPeer::_get_packet);
+ ObjectTypeDB::bind_method(_MD("put_packet", "buffer"),&PacketPeer::_get_packet);
+ ObjectTypeDB::bind_method(_MD("get_packet_error:Error"),&PacketPeer::_get_packet_error);
ObjectTypeDB::bind_method(_MD("get_available_packet_count"),&PacketPeer::get_available_packet_count);
};
diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h
index 3448ebde1b..76d1eb22b5 100644
--- a/core/io/packet_peer.h
+++ b/core/io/packet_peer.h
@@ -41,6 +41,14 @@ class PacketPeer : public Reference {
static void _bind_methods();
+
+ Error _put_packet(const DVector<uint8_t> &p_buffer);
+ DVector<uint8_t> _get_packet() const;
+ Error _get_packet_error() const;
+
+
+ mutable Error last_get_error;
+
public:
virtual int get_available_packet_count() const=0;
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 03b6c9759b..22d89840ae 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -214,6 +214,7 @@ RES ResourceLoader::load(const String &p_path,const String& p_type_hint,bool p_n
Ref<ResourceImportMetadata> ResourceLoader::load_import_metadata(const String &p_path) {
+
String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
diff --git a/core/math/math_2d.h b/core/math/math_2d.h
index ac315fddb7..5e6cefd114 100644
--- a/core/math/math_2d.h
+++ b/core/math/math_2d.h
@@ -226,6 +226,29 @@ struct Rect2 {
return true;
}
+ inline float distance_to(const Vector2& p_point) const {
+
+ float dist = 1e20;
+
+ if (p_point.x < pos.x) {
+ dist=MIN(dist,pos.x-p_point.x);
+ }
+ if (p_point.y < pos.y) {
+ dist=MIN(dist,pos.y-p_point.y);
+ }
+ if (p_point.x >= (pos.x+size.x) ) {
+ dist=MIN(p_point.x-(pos.x+size.x),dist);
+ }
+ if (p_point.y >= (pos.y+size.y) ) {
+ dist=MIN(p_point.y-(pos.y+size.y),dist);
+ }
+
+ if (dist==1e20)
+ return 0;
+ else
+ return dist;
+ }
+
_FORCE_INLINE_ bool intersects_transformed(const Matrix32& p_xform, const Rect2& p_rect) const;
bool intersects_segment(const Point2& p_from, const Point2& p_to, Point2* r_pos=NULL, Point2* r_normal=NULL) const;
diff --git a/core/message_queue.cpp b/core/message_queue.cpp
index cfbdb37b88..489939ee65 100644
--- a/core/message_queue.cpp
+++ b/core/message_queue.cpp
@@ -324,6 +324,7 @@ int MessageQueue::get_max_buffer_usage() const {
void MessageQueue::flush() {
+
if (buffer_max_used<buffer_end); {
buffer_max_used=buffer_end;
//statistics();
@@ -331,9 +332,14 @@ void MessageQueue::flush() {
uint32_t read_pos=0;
- while (read_pos < buffer_end ) {
+ //using reverse locking strategy
+ _THREAD_SAFE_LOCK_
+
+ while (read_pos<buffer_end) {
+
+ _THREAD_SAFE_UNLOCK_
+
//lock on each interation, so a call can re-add itself to the message queue
- _THREAD_SAFE_LOCK_
Message *message = (Message*)&buffer[ read_pos ];
@@ -379,16 +385,17 @@ void MessageQueue::flush() {
}
- read_pos+=sizeof(Message);
+ uint32_t advance = sizeof(Message);
if (message->type!=TYPE_NOTIFICATION)
- read_pos+=sizeof(Variant)*message->args;
+ advance+=sizeof(Variant)*message->args;
message->~Message();
- _THREAD_SAFE_UNLOCK_
+ _THREAD_SAFE_LOCK_
+ read_pos+=advance;
}
- _THREAD_SAFE_LOCK_
+
buffer_end=0; // reset buffer
_THREAD_SAFE_UNLOCK_
diff --git a/core/object.cpp b/core/object.cpp
index 84786df8d4..83a6dada80 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -1351,7 +1351,7 @@ Error Object::connect(const StringName& p_signal, Object *p_to_object, const Str
if (!s) {
bool signal_is_valid = ObjectTypeDB::has_signal(get_type_name(),p_signal);
if (!signal_is_valid) {
- ERR_EXPLAIN("Attempt to connect to nonexistent signal: "+p_signal);
+ ERR_EXPLAIN("Attempt to connect nonexistent signal '"+p_signal+"' to method '"+p_to_method+"'");
ERR_FAIL_COND_V(!signal_is_valid,ERR_INVALID_PARAMETER);
}
signal_map[p_signal]=Signal();
diff --git a/core/vector.h b/core/vector.h
index 04018b9f78..b93d9a0dea 100644
--- a/core/vector.h
+++ b/core/vector.h
@@ -104,7 +104,7 @@ public:
template <class T_val>
- int find(T_val& p_val) const;
+ int find(const T_val& p_val) const;
void set(int p_index,T p_elem);
T get(int p_index) const;
@@ -221,7 +221,7 @@ void Vector<T>::_copy_on_write() {
}
template<class T> template<class T_val>
-int Vector<T>::find(T_val& p_val) const {
+int Vector<T>::find(const T_val &p_val) const {
int ret = -1;
if (size() == 0)
diff --git a/demos/2d/motion/engine.cfg b/demos/2d/motion/engine.cfg
index 261111904c..29c4d0da20 100644
--- a/demos/2d/motion/engine.cfg
+++ b/demos/2d/motion/engine.cfg
@@ -3,9 +3,12 @@
name="Motion Test"
main_scene="res://motion.scn"
+<<<<<<< HEAD
+=======
[display]
width=800
height=600
stretch_mode="2d"
stretch_aspect="keep"
+>>>>>>> ab99671bb835a5fe24a092ec34afe1ad862ac254
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 4acac957c8..a588643fd9 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -5214,7 +5214,7 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material
DEBUG_TEST_ERROR("Material arameters");
if (p_material->shader_cache->uses_time) {
- material_shader.set_uniform(MaterialShaderGLES2::TIME,Math::fmod(last_time,300.0));
+ material_shader.set_uniform(MaterialShaderGLES2::TIME,Math::fmod(last_time,shader_time_rollback));
draw_next_frame=true;
}
//if uses TIME - draw_next_frame=true
@@ -9219,7 +9219,7 @@ void RasterizerGLES2::_canvas_item_setup_shader_uniforms(CanvasItemMaterial *mat
}
if (shader->uses_time) {
- canvas_shader.set_uniform(CanvasShaderGLES2::TIME,Math::fmod(last_time,300.0));
+ canvas_shader.set_uniform(CanvasShaderGLES2::TIME,Math::fmod(last_time,shader_time_rollback));
draw_next_frame=true;
}
//if uses TIME - draw_next_frame=true
@@ -10814,6 +10814,8 @@ void RasterizerGLES2::init() {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);// unbind
#endif
+ shader_time_rollback = GLOBAL_DEF("rasterizer/shader_time_rollback",300);
+
using_canvas_bg=false;
_update_framebuffer();
DEBUG_TEST_ERROR("Initializing");
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index 1821b1a750..e83bd39caa 100644
--- a/drivers/gles2/rasterizer_gles2.h
+++ b/drivers/gles2/rasterizer_gles2.h
@@ -1273,6 +1273,7 @@ class RasterizerGLES2 : public Rasterizer {
Environment *current_env;
VS::ScenarioDebugMode current_debug;
RID overdraw_material;
+ float shader_time_rollback;
mutable MaterialShaderGLES2 material_shader;
diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp
index 2e1488ff9d..2a4720b07b 100644
--- a/drivers/png/image_loader_png.cpp
+++ b/drivers/png/image_loader_png.cpp
@@ -31,6 +31,8 @@
#include "print_string.h"
#include "os/os.h"
+
+
void ImageLoaderPNG::_read_png_data(png_structp png_ptr,png_bytep data, png_size_t p_length) {
FileAccess *f = (FileAccess*)png_get_io_ptr(png_ptr);
@@ -253,6 +255,7 @@ void ImageLoaderPNG::get_recognized_extensions(List<String> *p_extensions) const
struct PNGReadStatus {
int offset;
+ int size;
const unsigned char *image;
};
@@ -261,17 +264,26 @@ static void user_read_data(png_structp png_ptr,png_bytep data, png_size_t p_leng
PNGReadStatus *rstatus;
rstatus=(PNGReadStatus*)png_get_io_ptr(png_ptr);
- memcpy(data,&rstatus->image[rstatus->offset],p_length);
- rstatus->offset+=p_length;
+ int to_read=p_length;
+ if (rstatus->size>=0) {
+ to_read = MIN( p_length, rstatus->size - rstatus->offset);
+ }
+ memcpy(data,&rstatus->image[rstatus->offset],to_read);
+ rstatus->offset+=to_read;
+
+ if (to_read<p_length) {
+ memset(&data[to_read],0,p_length-to_read);
+ }
}
-static Image _load_mem_png(const uint8_t* p_png) {
+static Image _load_mem_png(const uint8_t* p_png,int p_size) {
PNGReadStatus prs;
prs.image=p_png;
prs.offset=0;
+ prs.size=p_size;
Image img;
Error err = ImageLoaderPNG::_load_image(&prs,user_read_data,&img);
@@ -283,9 +295,10 @@ static Image _load_mem_png(const uint8_t* p_png) {
static Image _lossless_unpack_png(const DVector<uint8_t>& p_data) {
+ int len = p_data.size();
DVector<uint8_t>::Read r = p_data.read();
ERR_FAIL_COND_V(r[0]!='P' || r[1]!='N' || r[2]!='G' || r[3]!=' ',Image());
- return _load_mem_png(&r[4]);
+ return _load_mem_png(&r[4],len-4);
}
@@ -424,6 +437,7 @@ static DVector<uint8_t> _lossless_pack_png(const Image& p_image) {
ImageLoaderPNG::ImageLoaderPNG() {
+
Image::_png_mem_loader_func=_load_mem_png;
Image::lossless_unpacker=_lossless_unpack_png;
Image::lossless_packer=_lossless_pack_png;
diff --git a/drivers/png/image_loader_png.h b/drivers/png/image_loader_png.h
index 7acfd041ee..8413a7eae1 100644
--- a/drivers/png/image_loader_png.h
+++ b/drivers/png/image_loader_png.h
@@ -40,7 +40,10 @@ class ImageLoaderPNG : public ImageFormatLoader {
static void _read_png_data(png_structp png_ptr,png_bytep data, png_size_t p_length);
+
public:
+
+
static Error _load_image(void *rf_up,png_rw_ptr p_func,Image *p_image);
virtual Error load_image(Image *p_image,FileAccess *f);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
diff --git a/godot.creator.user.RG2068 b/godot.creator.user.RG2068
new file mode 100644
index 0000000000..8787ab7489
--- /dev/null
+++ b/godot.creator.user.RG2068
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by QtCreator 3.3.0, 2015-06-01T19:30:41. -->
+<qtcreator>
+ <data>
+ <variable>EnvironmentId</variable>
+ <value type="QByteArray">{6e68b27c-e98a-4fc6-8922-8c1a204b4713}</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.ActiveTarget</variable>
+ <value type="int">0</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.EditorSettings</variable>
+ <valuemap type="QVariantMap">
+ <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+ <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
+ <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+ <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+ <value type="QString" key="language">Cpp</value>
+ <valuemap type="QVariantMap" key="value">
+ <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
+ </valuemap>
+ </valuemap>
+ <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+ <value type="QString" key="language">QmlJS</value>
+ <valuemap type="QVariantMap" key="value">
+ <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
+ </valuemap>
+ </valuemap>
+ <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
+ <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
+ <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
+ <value type="int" key="EditorConfiguration.IndentSize">4</value>
+ <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+ <value type="int" key="EditorConfiguration.MarginColumn">80</value>
+ <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
+ <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+ <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+ <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+ <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
+ <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
+ <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+ <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+ <value type="int" key="EditorConfiguration.TabSize">8</value>
+ <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+ <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
+ <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+ <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+ <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+ <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.PluginSettings</variable>
+ <valuemap type="QVariantMap"/>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Target.0</variable>
+ <valuemap type="QVariantMap">
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{c3e3ea66-641c-4cd9-9de4-d23a3cd559d2}</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">C:/Users/reduz/coding/godot</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
+ <value type="QString">all</value>
+ </valuelist>
+ <value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
+ <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
+ <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand">c:\users\reduz\coding\godot\make.bat</value>
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
+ <value type="QString">clean</value>
+ </valuelist>
+ <value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">true</value>
+ <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
+ <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Default</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Default</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy locally</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+ <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+ <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+ <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+ <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+ <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+ <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+ <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+ <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+ <value type="int">0</value>
+ <value type="int">1</value>
+ <value type="int">2</value>
+ <value type="int">3</value>
+ <value type="int">4</value>
+ <value type="int">5</value>
+ <value type="int">6</value>
+ <value type="int">7</value>
+ <value type="int">8</value>
+ <value type="int">9</value>
+ <value type="int">10</value>
+ <value type="int">11</value>
+ <value type="int">12</value>
+ <value type="int">13</value>
+ <value type="int">14</value>
+ </valuelist>
+ <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+ <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+ <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Arguments"></value>
+ <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable"></value>
+ <value type="bool" key="ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal">false</value>
+ <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">%{buildDir}</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Executable</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
+ <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+ <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+ <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.TargetCount</variable>
+ <value type="int">1</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+ <value type="int">18</value>
+ </data>
+ <data>
+ <variable>Version</variable>
+ <value type="int">18</value>
+ </data>
+</qtcreator>
diff --git a/main/main.cpp b/main/main.cpp
index 531d7cfbdc..a00538a6ae 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1320,8 +1320,8 @@ bool Main::iteration() {
double step=(double)ticks_elapsed / 1000000.0;
float frame_slice=1.0/OS::get_singleton()->get_iterations_per_second();
- //if (time_accum+step < frame_slice)
- // return false;
+// if (time_accum+step < frame_slice)
+// return false;
frame+=ticks_elapsed;
@@ -1380,6 +1380,8 @@ bool Main::iteration() {
SpatialSound2DServer::get_singleton()->update( step*time_scale );
+ VisualServer::get_singleton()->sync(); //sync if still drawing from previous frames.
+
if (OS::get_singleton()->can_draw()) {
if ((!force_redraw_requested) && OS::get_singleton()->is_in_low_processor_usage_mode()) {
@@ -1392,8 +1394,6 @@ bool Main::iteration() {
OS::get_singleton()->frames_drawn++;
force_redraw_requested = false;
}
- } else {
- VisualServer::get_singleton()->flush(); // flush visual commands
}
if (AudioServer::get_singleton())
diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm
index 55185aa49d..3309fd0820 100755
--- a/platform/iphone/gl_view.mm
+++ b/platform/iphone/gl_view.mm
@@ -352,8 +352,9 @@ static void clear_touches() {
// Generate IDs for a framebuffer object and a color renderbuffer
UIScreen* mainscr = [UIScreen mainScreen];
printf("******** screen size %i, %i\n", (int)mainscr.currentMode.size.width, (int)mainscr.currentMode.size.height);
- if (mainscr.currentMode.size.width == 640 || mainscr.currentMode.size.width == 960) // modern iphone, can go to 640x960
- self.contentScaleFactor = 2.0;
+ float minPointSize = MIN(mainscr.bounds.size.width, mainscr.bounds.size.height);
+ float minScreenSize = MIN(mainscr.currentMode.size.width, mainscr.currentMode.size.height);
+ self.contentScaleFactor = minScreenSize / minPointSize;
glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index 827256c2fa..f9e79e25bc 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -52,6 +52,17 @@ bool Area2D::is_gravity_a_point() const{
return gravity_is_point;
}
+void Area2D::set_gravity_distance_scale(real_t p_scale){
+
+ gravity_distance_scale=p_scale;
+ Physics2DServer::get_singleton()->area_set_param(get_rid(),Physics2DServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE,p_scale);
+
+}
+
+real_t Area2D::get_gravity_distance_scale() const{
+ return gravity_distance_scale;
+}
+
void Area2D::set_gravity_vector(const Vector2& p_vec){
gravity_vec=p_vec;
@@ -535,6 +546,39 @@ uint32_t Area2D::get_layer_mask() const {
return layer_mask;
}
+void Area2D::set_collision_mask_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_collision_mask();
+ if (p_value)
+ mask|=1<<p_bit;
+ else
+ mask&=~(1<<p_bit);
+ set_collision_mask(mask);
+
+}
+
+bool Area2D::get_collision_mask_bit(int p_bit) const{
+
+ return get_collision_mask()&(1<<p_bit);
+}
+
+
+void Area2D::set_layer_mask_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_layer_mask();
+ if (p_value)
+ mask|=1<<p_bit;
+ else
+ mask&=~(1<<p_bit);
+ set_layer_mask(mask);
+
+}
+
+bool Area2D::get_layer_mask_bit(int p_bit) const{
+
+ return get_layer_mask()&(1<<p_bit);
+}
+
void Area2D::_bind_methods() {
@@ -550,6 +594,9 @@ void Area2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_gravity_is_point","enable"),&Area2D::set_gravity_is_point);
ObjectTypeDB::bind_method(_MD("is_gravity_a_point"),&Area2D::is_gravity_a_point);
+ ObjectTypeDB::bind_method(_MD("set_gravity_distance_scale","distance_scale"),&Area2D::set_gravity_distance_scale);
+ ObjectTypeDB::bind_method(_MD("get_gravity_distance_scale"),&Area2D::get_gravity_distance_scale);
+
ObjectTypeDB::bind_method(_MD("set_gravity_vector","vector"),&Area2D::set_gravity_vector);
ObjectTypeDB::bind_method(_MD("get_gravity_vector"),&Area2D::get_gravity_vector);
@@ -571,6 +618,12 @@ void Area2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_layer_mask","layer_mask"),&Area2D::set_layer_mask);
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&Area2D::get_layer_mask);
+ ObjectTypeDB::bind_method(_MD("set_collision_mask_bit","bit","value"),&Area2D::set_collision_mask_bit);
+ ObjectTypeDB::bind_method(_MD("get_collision_mask_bit","bit"),&Area2D::get_collision_mask_bit);
+
+ ObjectTypeDB::bind_method(_MD("set_layer_mask_bit","bit","value"),&Area2D::set_layer_mask_bit);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask_bit","bit"),&Area2D::get_layer_mask_bit);
+
ObjectTypeDB::bind_method(_MD("set_enable_monitoring","enable"),&Area2D::set_enable_monitoring);
ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"),&Area2D::is_monitoring_enabled);
@@ -600,6 +653,7 @@ void Area2D::_bind_methods() {
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"space_override",PROPERTY_HINT_ENUM,"Disabled,Combine,Replace"),_SCS("set_space_override_mode"),_SCS("get_space_override_mode"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"gravity_point"),_SCS("set_gravity_is_point"),_SCS("is_gravity_a_point"));
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity_distance_scale", PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_gravity_distance_scale"),_SCS("get_gravity_distance_scale"));
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"gravity_vec"),_SCS("set_gravity_vector"),_SCS("get_gravity_vector"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity",PROPERTY_HINT_RANGE,"-1024,1024,0.01"),_SCS("set_gravity"),_SCS("get_gravity"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"linear_damp",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_linear_damp"),_SCS("get_linear_damp"));
@@ -618,6 +672,7 @@ Area2D::Area2D() : CollisionObject2D(Physics2DServer::get_singleton()->area_crea
set_gravity(98);;
set_gravity_vector(Vector2(0,1));
gravity_is_point=false;
+ gravity_distance_scale=0;
linear_damp=0.1;
angular_damp=1;
locked=false;
diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h
index 0c064f54cd..f5a88390e7 100644
--- a/scene/2d/area_2d.h
+++ b/scene/2d/area_2d.h
@@ -49,6 +49,7 @@ private:
Vector2 gravity_vec;
real_t gravity;
bool gravity_is_point;
+ real_t gravity_distance_scale;
real_t linear_damp;
real_t angular_damp;
uint32_t collision_mask;
@@ -132,6 +133,9 @@ public:
void set_gravity_is_point(bool p_enabled);
bool is_gravity_a_point() const;
+ void set_gravity_distance_scale(real_t p_scale);
+ real_t get_gravity_distance_scale() const;
+
void set_gravity_vector(const Vector2& p_vec);
Vector2 get_gravity_vector() const;
@@ -159,6 +163,12 @@ public:
void set_layer_mask(uint32_t p_mask);
uint32_t get_layer_mask() const;
+ void set_collision_mask_bit(int p_bit, bool p_value);
+ bool get_collision_mask_bit(int p_bit) const;
+
+ void set_layer_mask_bit(int p_bit, bool p_value);
+ bool get_layer_mask_bit(int p_bit) const;
+
Array get_overlapping_bodies() const; //function for script
Array get_overlapping_areas() const; //function for script
diff --git a/scene/2d/navigation2d.cpp b/scene/2d/navigation2d.cpp
index 5a02501816..5db0e0a9fc 100644
--- a/scene/2d/navigation2d.cpp
+++ b/scene/2d/navigation2d.cpp
@@ -91,9 +91,13 @@ void Navigation2D::_navpoly_link(int p_id) {
} else {
if (C->get().B!=NULL) {
- print_line(String()+_get_vertex(ek.a)+" -> "+_get_vertex(ek.b));
+ ConnectionPending pending;
+ pending.polygon=&p;
+ pending.edge=j;
+ p.edges[j].P=C->get().pending.push_back(pending);
+ continue;
+ //print_line(String()+_get_vertex(ek.a)+" -> "+_get_vertex(ek.b));
}
- ERR_CONTINUE(C->get().B!=NULL); //wut
C->get().B=&p;
C->get().B_edge=j;
@@ -133,7 +137,12 @@ void Navigation2D::_navpoly_unlink(int p_id) {
EdgeKey ek(edges[i].point,edges[next].point);
Map<EdgeKey,Connection>::Element *C=connections.find(ek);
ERR_CONTINUE(!C);
- if (C->get().B) {
+
+ if (edges[i].P) {
+ C->get().pending.erase(edges[i].P);
+ edges[i].P=NULL;
+
+ } else if (C->get().B) {
//disconnect
C->get().B->edges[C->get().B_edge].C=NULL;
@@ -149,6 +158,20 @@ void Navigation2D::_navpoly_unlink(int p_id) {
C->get().B=NULL;
C->get().B_edge=-1;
+ if (C->get().pending.size()) {
+ //reconnect if something is pending
+ ConnectionPending cp = C->get().pending.front()->get();
+ C->get().pending.pop_front();
+
+ C->get().B=cp.polygon;
+ C->get().B_edge=cp.edge;
+ C->get().A->edges[C->get().A_edge].C=cp.polygon;
+ C->get().A->edges[C->get().A_edge].C_edge=cp.edge;
+ cp.polygon->edges[cp.edge].C=C->get().A;
+ cp.polygon->edges[cp.edge].C_edge=C->get().A_edge;
+ cp.polygon->edges[cp.edge].P=NULL;
+ }
+
} else {
connections.erase(C);
//erase
diff --git a/scene/2d/navigation2d.h b/scene/2d/navigation2d.h
index 829b0f544b..231f1e8c63 100644
--- a/scene/2d/navigation2d.h
+++ b/scene/2d/navigation2d.h
@@ -41,7 +41,13 @@ class Navigation2D : public Node2D {
struct NavMesh;
+ struct Polygon;
+ struct ConnectionPending {
+
+ Polygon *polygon;
+ int edge;
+ };
struct Polygon {
@@ -49,7 +55,8 @@ class Navigation2D : public Node2D {
Point point;
Polygon *C; //connection
int C_edge;
- Edge() { C=NULL; C_edge=-1; }
+ List<ConnectionPending>::Element *P;
+ Edge() { C=NULL; C_edge=-1; P=NULL; }
};
Vector<Edge> edges;
@@ -72,6 +79,9 @@ class Navigation2D : public Node2D {
int A_edge;
Polygon *B;
int B_edge;
+
+ List<ConnectionPending> pending;
+
Connection() { A=NULL; B=NULL; A_edge=-1; B_edge=-1;}
};
diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp
index 39d747c436..f0b7c2be60 100644
--- a/scene/2d/particles_2d.cpp
+++ b/scene/2d/particles_2d.cpp
@@ -503,19 +503,6 @@ void Particles2D::_notification(int p_what) {
if (!local_space)
invxform=get_global_transform().affine_inverse();
- int col_count=0;
- float last=-1;
- ColorPhase cphase[MAX_COLOR_PHASES];
-
- for(int i=0;i<color_phase_count;i++) {
-
- if (color_phases[i].pos<=last)
- break;
- cphase[i]=color_phases[i];
- col_count++;
- }
-
-
int start_particle = (int)(time * (float)particle_count / lifetime);
for (int id=0;id<particle_count;++id) {
@@ -537,32 +524,14 @@ void Particles2D::_notification(int p_what) {
uint32_t rand_seed=p.seed*(i+1);
-
- int cpos=0;
-
- while(cpos<col_count) {
-
- if (cphase[cpos].pos > ptime)
- break;
- cpos++;
- }
-
- cpos--;
-
Color color;
- //could be faster..
- if (cpos==-1)
- color=Color(1,1,1,1);
- else {
- if (cpos==col_count-1)
- color=cphase[cpos].color;
- else {
- float diff = (cphase[cpos+1].pos-cphase[cpos].pos);
- if (diff>0)
- color=cphase[cpos].color.linear_interpolate(cphase[cpos+1].color, (ptime - cphase[cpos].pos) / diff );
- else
- color=cphase[cpos+1].color;
- }
+
+ if(color_ramp.is_valid())
+ {
+ color = color_ramp->get_color_at_offset(ptime);
+ } else
+ {
+ color = default_color;
}
@@ -813,6 +782,27 @@ Ref<Texture> Particles2D::get_texture() const {
return texture;
}
+void Particles2D::set_color(const Color& p_color) {
+
+ default_color = p_color;
+}
+
+Color Particles2D::get_color() const {
+
+ return default_color;
+}
+
+
+void Particles2D::set_color_ramp(const Ref<ColorRamp>& p_color_ramp) {
+
+ color_ramp=p_color_ramp;
+}
+
+Ref<ColorRamp> Particles2D::get_color_ramp() const {
+
+ return color_ramp;
+}
+
void Particles2D::set_emissor_offset(const Point2& p_offset) {
emissor_offset=p_offset;
@@ -834,40 +824,76 @@ bool Particles2D::is_using_local_space() const {
return local_space;
}
-
+//Deprecated. Converts color phases to color ramp
void Particles2D::set_color_phases(int p_phases) {
- ERR_FAIL_INDEX(p_phases,MAX_COLOR_PHASES+1);
- color_phase_count=p_phases;
+ //Create color ramp if we have 2 or more phases.
+ //Otherwise first phase phase will be assigned to default color.
+ if(p_phases > 1 && color_ramp.is_null())
+ {
+ color_ramp = Ref<ColorRamp>(memnew (ColorRamp()));
+ }
+ if(color_ramp.is_valid())
+ {
+ color_ramp->get_points().resize(p_phases);
+ }
}
+//Deprecated.
int Particles2D::get_color_phases() const {
- return color_phase_count;
+ if(color_ramp.is_valid())
+ {
+ return color_ramp->get_points_count();
+ }
+ return 0;
}
+//Deprecated. Converts color phases to color ramp
void Particles2D::set_color_phase_color(int p_phase,const Color& p_color) {
ERR_FAIL_INDEX(p_phase,MAX_COLOR_PHASES);
- color_phases[p_phase].color=p_color;
-
+ if(color_ramp.is_valid())
+ {
+ if(color_ramp->get_points_count() > p_phase)
+ color_ramp->set_color(p_phase, p_color);
+ } else
+ {
+ if(p_phase == 0)
+ default_color = p_color;
+ }
}
+
+//Deprecated.
Color Particles2D::get_color_phase_color(int p_phase) const {
ERR_FAIL_INDEX_V(p_phase,MAX_COLOR_PHASES,Color());
- return color_phases[p_phase].color;
+ if(color_ramp.is_valid())
+ {
+ return color_ramp->get_color(p_phase);
+ }
+ return Color(0,0,0,1);
}
+//Deprecated. Converts color phases to color ramp
void Particles2D::set_color_phase_pos(int p_phase,float p_pos) {
ERR_FAIL_INDEX(p_phase,MAX_COLOR_PHASES);
ERR_FAIL_COND(p_pos<0.0 || p_pos>1.0);
- color_phases[p_phase].pos=p_pos;
-
+ if(color_ramp.is_valid() && color_ramp->get_points_count() > p_phase)
+ {
+ return color_ramp->set_offset(p_phase, p_pos);
+ }
}
+
+//Deprecated.
float Particles2D::get_color_phase_pos(int p_phase) const {
ERR_FAIL_INDEX_V(p_phase,MAX_COLOR_PHASES,0);
- return color_phases[p_phase].pos;
+ if(color_ramp.is_valid())
+ {
+ return color_ramp->get_offset(p_phase);
+ }
+ return 0;
}
void Particles2D::set_emission_half_extents(const Vector2& p_extents) {
@@ -997,6 +1023,12 @@ void Particles2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_texture:Texture","texture"),&Particles2D::set_texture);
ObjectTypeDB::bind_method(_MD("get_texture:Texture"),&Particles2D::get_texture);
+ ObjectTypeDB::bind_method(_MD("set_color","color"),&Particles2D::set_color);
+ ObjectTypeDB::bind_method(_MD("get_color"),&Particles2D::get_color);
+
+ ObjectTypeDB::bind_method(_MD("set_color_ramp:ColorRamp","color_ramp"),&Particles2D::set_color_ramp);
+ ObjectTypeDB::bind_method(_MD("get_color_ramp:ColorRamp"),&Particles2D::get_color_ramp);
+
ObjectTypeDB::bind_method(_MD("set_emissor_offset","offset"),&Particles2D::set_emissor_offset);
ObjectTypeDB::bind_method(_MD("get_emissor_offset"),&Particles2D::get_emissor_offset);
@@ -1055,7 +1087,6 @@ void Particles2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT,"config/v_frames",PROPERTY_HINT_RANGE,"1,512,1"),_SCS("set_v_frames"),_SCS("get_v_frames"));
-
for(int i=0;i<PARAM_MAX;i++) {
ADD_PROPERTYI(PropertyInfo(Variant::REAL,_particlesframe_property_names[i],PROPERTY_HINT_RANGE,_particlesframe_property_ranges[i]),_SCS("set_param"),_SCS("get_param"),i);
}
@@ -1064,14 +1095,17 @@ void Particles2D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::REAL,_particlesframe_property_rnames[i],PROPERTY_HINT_RANGE,"-1,1,0.01"),_SCS("set_randomness"),_SCS("get_randomness"),i);
}
- ADD_PROPERTY( PropertyInfo( Variant::INT, "color_phases/count",PROPERTY_HINT_RANGE,"0,4,1"), _SCS("set_color_phases"), _SCS("get_color_phases"));
+ ADD_PROPERTY( PropertyInfo( Variant::INT, "color_phases/count",PROPERTY_HINT_RANGE,"0,4,1", 0), _SCS("set_color_phases"), _SCS("get_color_phases"));
+ //Backward compatibility. They will be converted to color ramp
for(int i=0;i<MAX_COLOR_PHASES;i++) {
String phase="phase_"+itos(i)+"/";
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, phase+"pos", PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_color_phase_pos"),_SCS("get_color_phase_pos"),i );
- ADD_PROPERTYI( PropertyInfo( Variant::COLOR, phase+"color"),_SCS("set_color_phase_color"),_SCS("get_color_phase_color"),i );
+ ADD_PROPERTYI( PropertyInfo( Variant::REAL, phase+"pos", PROPERTY_HINT_RANGE,"0,1,0.01", 0),_SCS("set_color_phase_pos"),_SCS("get_color_phase_pos"),i );
+ ADD_PROPERTYI( PropertyInfo( Variant::COLOR, phase+"color", PROPERTY_HINT_NONE, "", 0),_SCS("set_color_phase_color"),_SCS("get_color_phase_color"),i );
}
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color/color"),_SCS("set_color"),_SCS("get_color"));
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"color/color_ramp",PROPERTY_HINT_RESOURCE_TYPE,"ColorRamp"),_SCS("set_color_ramp"),_SCS("get_color_ramp"));
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2_ARRAY,"emission_points",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_emission_points"),_SCS("get_emission_points"));
@@ -1097,8 +1131,6 @@ void Particles2D::_bind_methods() {
}
-
-
Particles2D::Particles2D() {
for(int i=0;i<PARAM_MAX;i++) {
@@ -1118,6 +1150,7 @@ Particles2D::Particles2D() {
set_param(PARAM_FINAL_SIZE,1.0);
set_param(PARAM_ANIM_SPEED_SCALE,1.0);
+ set_color(Color(1,1,1,1));
time=0;
lifetime=2;
@@ -1129,17 +1162,6 @@ Particles2D::Particles2D() {
preprocess=0;
time_scale=1.0;
- color_phase_count=1;
-
- set_color_phase_pos(0,0.0);
- set_color_phase_pos(1,1.0);
- set_color_phase_pos(2,1.0);
- set_color_phase_pos(3,1.0);
-
- set_color_phase_color(0,Color(1,1,1));
- set_color_phase_color(1,Color(0,0,0));
- set_color_phase_color(2,Color(0,0,0));
- set_color_phase_color(3,Color(0,0,0));
flip_h=false;
flip_v=false;
diff --git a/scene/2d/particles_2d.h b/scene/2d/particles_2d.h
index 90b5a188a6..4ee0fcf8da 100644
--- a/scene/2d/particles_2d.h
+++ b/scene/2d/particles_2d.h
@@ -31,6 +31,7 @@
#include "scene/2d/node_2d.h"
#include "scene/resources/texture.h"
+#include "scene/resources/color_ramp.h"
class Particles2D;
class ParticleAttractor2D : public Node2D {
@@ -125,11 +126,6 @@ private:
};
Vector<Particle> particles;
- int color_phase_count;
- struct ColorPhase {
- Color color;
- float pos;
- } color_phases[MAX_COLOR_PHASES];
struct AttractorCache {
@@ -161,6 +157,9 @@ private:
Ref<Texture> texture;
+ //If no color ramp is set then default color is used. Created as simple alternative to color_ramp.
+ Color default_color;
+ Ref<ColorRamp> color_ramp;
void testee(int a, int b, int c, int d, int e);
void _process_particles(float p_delta);
@@ -230,6 +229,12 @@ public:
void set_texture(const Ref<Texture>& p_texture);
Ref<Texture> get_texture() const;
+ void set_color(const Color& p_color);
+ Color get_color() const;
+
+ void set_color_ramp(const Ref<ColorRamp>& p_texture);
+ Ref<ColorRamp> get_color_ramp() const;
+
void set_emissor_offset(const Point2& p_offset);
Point2 get_emissor_offset() const;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 3d2917d843..c30921eb69 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -85,6 +85,14 @@ void PhysicsBody2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask);
ObjectTypeDB::bind_method(_MD("set_collision_mask","mask"),&PhysicsBody2D::set_collision_mask);
ObjectTypeDB::bind_method(_MD("get_collision_mask"),&PhysicsBody2D::get_collision_mask);
+
+
+ ObjectTypeDB::bind_method(_MD("set_collision_mask_bit","bit","value"),&PhysicsBody2D::set_collision_mask_bit);
+ ObjectTypeDB::bind_method(_MD("get_collision_mask_bit","bit"),&PhysicsBody2D::get_collision_mask_bit);
+
+ ObjectTypeDB::bind_method(_MD("set_layer_mask_bit","bit","value"),&PhysicsBody2D::set_layer_mask_bit);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask_bit","bit"),&PhysicsBody2D::get_layer_mask_bit);
+
ObjectTypeDB::bind_method(_MD("_set_layers","mask"),&PhysicsBody2D::_set_layers);
ObjectTypeDB::bind_method(_MD("_get_layers"),&PhysicsBody2D::_get_layers);
ObjectTypeDB::bind_method(_MD("set_one_way_collision_direction","dir"),&PhysicsBody2D::set_one_way_collision_direction);
@@ -122,6 +130,37 @@ uint32_t PhysicsBody2D::get_collision_mask() const {
return collision_mask;
}
+void PhysicsBody2D::set_collision_mask_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_collision_mask();
+ if (p_value)
+ mask|=1<<p_bit;
+ else
+ mask&=~(1<<p_bit);
+ set_collision_mask(mask);
+
+}
+bool PhysicsBody2D::get_collision_mask_bit(int p_bit) const{
+
+ return get_collision_mask()&(1<<p_bit);
+}
+
+
+void PhysicsBody2D::set_layer_mask_bit(int p_bit, bool p_value) {
+
+ uint32_t mask = get_layer_mask();
+ if (p_value)
+ mask|=1<<p_bit;
+ else
+ mask&=~(1<<p_bit);
+ set_layer_mask(mask);
+
+}
+
+bool PhysicsBody2D::get_layer_mask_bit(int p_bit) const{
+
+ return get_layer_mask()&(1<<p_bit);
+}
PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) {
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 03f95959b6..b70fdd59cf 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -61,6 +61,13 @@ public:
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
+
+ void set_collision_mask_bit(int p_bit, bool p_value);
+ bool get_collision_mask_bit(int p_bit) const;
+
+ void set_layer_mask_bit(int p_bit, bool p_value);
+ bool get_layer_mask_bit(int p_bit) const;
+
void add_collision_exception_with(Node* p_node); //must be physicsbody
void remove_collision_exception_with(Node* p_node);
diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp
index d49ffff729..76527c72e6 100644
--- a/scene/3d/area.cpp
+++ b/scene/3d/area.cpp
@@ -52,6 +52,17 @@ bool Area::is_gravity_a_point() const{
return gravity_is_point;
}
+void Area::set_gravity_distance_scale(real_t p_scale){
+
+ gravity_distance_scale=p_scale;
+ PhysicsServer::get_singleton()->area_set_param(get_rid(),PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE,p_scale);
+
+}
+
+real_t Area::get_gravity_distance_scale() const{
+ return gravity_distance_scale;
+}
+
void Area::set_gravity_vector(const Vector3& p_vec){
gravity_vec=p_vec;
@@ -302,6 +313,9 @@ void Area::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_gravity_is_point","enable"),&Area::set_gravity_is_point);
ObjectTypeDB::bind_method(_MD("is_gravity_a_point"),&Area::is_gravity_a_point);
+ ObjectTypeDB::bind_method(_MD("set_gravity_distance_scale","distance_scale"),&Area::set_gravity_distance_scale);
+ ObjectTypeDB::bind_method(_MD("get_gravity_distance_scale"),&Area::get_gravity_distance_scale);
+
ObjectTypeDB::bind_method(_MD("set_gravity_vector","vector"),&Area::set_gravity_vector);
ObjectTypeDB::bind_method(_MD("get_gravity_vector"),&Area::get_gravity_vector);
@@ -330,6 +344,7 @@ void Area::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::INT,"space_override",PROPERTY_HINT_ENUM,"Disabled,Combine,Replace"),_SCS("set_space_override_mode"),_SCS("get_space_override_mode"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"gravity_point"),_SCS("set_gravity_is_point"),_SCS("is_gravity_a_point"));
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity_distance_scale", PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_gravity_distance_scale"),_SCS("get_gravity_distance_scale"));
ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"gravity_vec"),_SCS("set_gravity_vector"),_SCS("get_gravity_vector"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity",PROPERTY_HINT_RANGE,"-1024,1024,0.01"),_SCS("set_gravity"),_SCS("get_gravity"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"density",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_density"),_SCS("get_density"));
@@ -345,6 +360,7 @@ Area::Area() : CollisionObject(PhysicsServer::get_singleton()->area_create(),tru
locked=false;
set_gravity_vector(Vector3(0,-1,0));
gravity_is_point=false;
+ gravity_distance_scale=0;
density=0.1;
priority=0;
monitoring=false;
diff --git a/scene/3d/area.h b/scene/3d/area.h
index 493c71c595..fb853092f3 100644
--- a/scene/3d/area.h
+++ b/scene/3d/area.h
@@ -49,6 +49,7 @@ private:
Vector3 gravity_vec;
real_t gravity;
bool gravity_is_point;
+ real_t gravity_distance_scale;
real_t density;
int priority;
bool monitoring;
@@ -98,6 +99,9 @@ public:
void set_gravity_is_point(bool p_enabled);
bool is_gravity_a_point() const;
+ void set_gravity_distance_scale(real_t p_scale);
+ real_t get_gravity_distance_scale() const;
+
void set_gravity_vector(const Vector3& p_vec);
Vector3 get_gravity_vector() const;
diff --git a/scene/3d/navigation.cpp b/scene/3d/navigation.cpp
index 48820706dd..bfa8add09c 100644
--- a/scene/3d/navigation.cpp
+++ b/scene/3d/navigation.cpp
@@ -85,9 +85,14 @@ void Navigation::_navmesh_link(int p_id) {
} else {
if (C->get().B!=NULL) {
- print_line(String()+_get_vertex(ek.a)+" -> "+_get_vertex(ek.b));
+ ConnectionPending pending;
+ pending.polygon=&p;
+ pending.edge=j;
+ p.edges[j].P=C->get().pending.push_back(pending);
+ continue;
+ //print_line(String()+_get_vertex(ek.a)+" -> "+_get_vertex(ek.b));
}
- ERR_CONTINUE(C->get().B!=NULL); //wut
+ //ERR_CONTINUE(C->get().B!=NULL); //wut
C->get().B=&p;
C->get().B_edge=j;
@@ -126,8 +131,13 @@ void Navigation::_navmesh_unlink(int p_id) {
EdgeKey ek(edges[i].point,edges[next].point);
Map<EdgeKey,Connection>::Element *C=connections.find(ek);
+
ERR_CONTINUE(!C);
- if (C->get().B) {
+
+ if (edges[i].P) {
+ C->get().pending.erase(edges[i].P);
+ edges[i].P=NULL;
+ } else if (C->get().B) {
//disconnect
C->get().B->edges[C->get().B_edge].C=NULL;
@@ -143,6 +153,20 @@ void Navigation::_navmesh_unlink(int p_id) {
C->get().B=NULL;
C->get().B_edge=-1;
+ if (C->get().pending.size()) {
+ //reconnect if something is pending
+ ConnectionPending cp = C->get().pending.front()->get();
+ C->get().pending.pop_front();
+
+ C->get().B=cp.polygon;
+ C->get().B_edge=cp.edge;
+ C->get().A->edges[C->get().A_edge].C=cp.polygon;
+ C->get().A->edges[C->get().A_edge].C_edge=cp.edge;
+ cp.polygon->edges[cp.edge].C=C->get().A;
+ cp.polygon->edges[cp.edge].C_edge=C->get().A_edge;
+ cp.polygon->edges[cp.edge].P=NULL;
+ }
+
} else {
connections.erase(C);
//erase
diff --git a/scene/3d/navigation.h b/scene/3d/navigation.h
index 0f7f67571f..f8434aaf72 100644
--- a/scene/3d/navigation.h
+++ b/scene/3d/navigation.h
@@ -42,6 +42,13 @@ class Navigation : public Spatial {
struct NavMesh;
+ struct Polygon;
+
+ struct ConnectionPending {
+
+ Polygon *polygon;
+ int edge;
+ };
struct Polygon {
@@ -50,7 +57,8 @@ class Navigation : public Spatial {
Point point;
Polygon *C; //connection
int C_edge;
- Edge() { C=NULL; C_edge=-1; }
+ List<ConnectionPending>::Element *P;
+ Edge() { C=NULL; C_edge=-1; P=NULL; }
};
Vector<Edge> edges;
@@ -72,6 +80,9 @@ class Navigation : public Spatial {
int A_edge;
Polygon *B;
int B_edge;
+
+ List<ConnectionPending> pending;
+
Connection() { A=NULL; B=NULL; A_edge=-1; B_edge=-1;}
};
diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp
index 9c69520a85..c672d0e94f 100644
--- a/scene/3d/spatial.cpp
+++ b/scene/3d/spatial.cpp
@@ -626,10 +626,11 @@ void Spatial::rotate_z(float p_radians){
void Spatial::translate(const Vector3& p_offset){
Transform t =get_transform();
- t.origin+=p_offset;
+ t.translate(p_offset);
set_transform(t);
}
+
void Spatial::scale(const Vector3& p_ratio){
Transform t =get_transform();
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 6676f70981..74ae2c0d55 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -223,7 +223,7 @@ void AnimationPlayer::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
- stop_all();
+ //stop_all();
clear_caches();
} break;
}
diff --git a/scene/gui/color_ramp_edit.cpp b/scene/gui/color_ramp_edit.cpp
new file mode 100644
index 0000000000..382c0dc103
--- /dev/null
+++ b/scene/gui/color_ramp_edit.cpp
@@ -0,0 +1,368 @@
+#include "color_ramp_edit.h"
+#include "os/keyboard.h"
+
+ColorRampEdit::ColorRampEdit(){
+ grabbed=-1;
+ grabbing=false;
+ set_focus_mode(FOCUS_ALL);
+
+ popup = memnew( PopupPanel );
+ picker = memnew( ColorPicker );
+ popup->add_child(picker);
+ popup->set_child_rect(picker);
+ add_child(popup);
+
+ checker = Ref<ImageTexture>(memnew( ImageTexture ));
+ checker->create_from_image( Image(checker_bg_png),ImageTexture::FLAG_REPEAT );
+}
+
+int ColorRampEdit::_get_point_from_pos(int x) {
+ int result = -1;
+ int total_w = get_size().width-get_size().height-3;
+ for(int i=0;i<points.size();i++) {
+ //Check if we clicked at point
+ if (ABS(x-points[i].offset*total_w+1)<(POINT_WIDTH/2+1)) {
+ result=i;
+ }
+ }
+ return result;
+}
+
+void ColorRampEdit::_show_color_picker() {
+ if (grabbed==-1)
+ return;
+ Size2 ms = Size2(350, picker->get_combined_minimum_size().height+10);
+ picker->set_color(points[grabbed].color);
+ popup->set_pos(get_global_pos()-Vector2(ms.width-get_size().width,ms.height));
+ popup->set_size(ms);
+ popup->popup();
+}
+
+ColorRampEdit::~ColorRampEdit() {
+
+}
+
+void ColorRampEdit::_input_event(const InputEvent& p_event) {
+
+ if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) {
+
+ points.remove(grabbed);
+ grabbed=-1;
+ update();
+ emit_signal("ramp_changed");
+ accept_event();
+ }
+
+ //Show color picker on double click.
+ if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.doubleclick && p_event.mouse_button.pressed) {
+ grabbed=_get_point_from_pos(p_event.mouse_button.x);
+ _show_color_picker();
+ accept_event();
+ }
+
+ //Delete point on right click
+ if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==2 && p_event.mouse_button.pressed) {
+ grabbed=_get_point_from_pos(p_event.mouse_button.x);
+ if(grabbed != -1)
+ {
+ points.remove(grabbed);
+ grabbed=-1;
+ update();
+ emit_signal("ramp_changed");
+ accept_event();
+ }
+ }
+
+ if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) {
+
+ update();
+ int x = p_event.mouse_button.x;
+ int total_w = get_size().width-get_size().height-3;
+
+ //Check if color selector was clicked.
+ if (x>total_w+3) {
+ _show_color_picker();
+ return;
+ }
+
+ grabbing=true;
+
+ grabbed=_get_point_from_pos(x);
+ //grab or select
+ if (grabbed!=-1) {
+ return;
+ }
+
+ //insert
+ ColorRamp::Point newPoint;
+ newPoint.offset=CLAMP(x/float(total_w),0,1);
+
+ ColorRamp::Point prev;
+ ColorRamp::Point next;
+
+ int pos=-1;
+ for(int i=0;i<points.size();i++) {
+ if (points[i].offset<newPoint.offset)
+ pos=i;
+ }
+
+ if (pos==-1) {
+
+ prev.color=Color(0,0,0);
+ prev.offset=0;
+ if (points.size()) {
+ next=points[0];
+ } else {
+ next.color=Color(1,1,1);
+ next.offset=1.0;
+ }
+ } else {
+
+ if (pos==points.size()-1) {
+ next.color=Color(1,1,1);
+ next.offset=1.0;
+ } else {
+ next=points[pos+1];
+ }
+ prev=points[pos];
+
+ }
+
+ newPoint.color=prev.color.linear_interpolate(next.color,(newPoint.offset-prev.offset)/(next.offset-prev.offset));
+
+ points.push_back(newPoint);
+ points.sort();
+ for(int i=0;i<points.size();i++) {
+ if (points[i].offset==newPoint.offset) {
+ grabbed=i;
+ break;
+ }
+ }
+
+ emit_signal("ramp_changed");
+
+ }
+
+ if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && !p_event.mouse_button.pressed) {
+
+ if (grabbing) {
+ grabbing=false;
+ emit_signal("ramp_changed");
+ }
+ update();
+ }
+
+ if (p_event.type==InputEvent::MOUSE_MOTION && grabbing) {
+
+ int total_w = get_size().width-get_size().height-3;
+
+ int x = p_event.mouse_motion.x;
+ float newofs = CLAMP(x/float(total_w),0,1);
+
+ bool valid=true;
+ for(int i=0;i<points.size();i++) {
+
+ if (points[i].offset==newofs && i!=grabbed) {
+ valid=false;
+ }
+ }
+
+ if (!valid)
+ return;
+
+ points[grabbed].offset=newofs;
+
+ points.sort();
+ for(int i=0;i<points.size();i++) {
+ if (points[i].offset==newofs) {
+ grabbed=i;
+ break;
+ }
+ }
+
+ emit_signal("ramp_changed");
+
+ update();
+ }
+}
+
+void ColorRampEdit::_notification(int p_what) {
+
+ if (p_what==NOTIFICATION_ENTER_TREE) {
+ picker->connect("color_changed",this,"_color_changed");
+ }
+ if (p_what==NOTIFICATION_DRAW) {
+
+ int w = get_size().x;
+ int h = get_size().y;
+
+ if (w == 0 || h == 0)
+ return; //Safety check. We have division by 'h'. And in any case there is nothing to draw with such size
+
+ int total_w = get_size().width-get_size().height-3;
+
+ //Draw checker pattern for ramp
+ _draw_checker(0,0, total_w, h);
+
+ //Draw color ramp
+ ColorRamp::Point prev;
+ prev.offset=0;
+ if(points.size() == 0)
+ prev.color=Color(0,0,0); //Draw black rectangle if we have no points
+ else
+ prev.color = points[0].color; //Extend color of first point to the beginning.
+
+ for(int i=-1;i<points.size();i++) {
+
+ ColorRamp::Point next;
+ //If there is no next point
+ if (i+1 == points.size()) {
+ if(points.size() == 0)
+ next.color=Color(0,0,0); //Draw black rectangle if we have no points
+ else
+ next.color=points[i].color; //Extend color of last point to the end.
+ next.offset=1;
+ } else {
+ next=points[i+1];
+ }
+
+ if (prev.offset==next.offset) {
+ prev=next;
+ continue;
+ }
+
+ Vector<Vector2> points;
+ Vector<Color> colors;
+ points.push_back(Vector2(prev.offset*total_w,h));
+ points.push_back(Vector2(prev.offset*total_w,0));
+ points.push_back(Vector2(next.offset*total_w,0));
+ points.push_back(Vector2(next.offset*total_w,h));
+ colors.push_back(prev.color);
+ colors.push_back(prev.color);
+ colors.push_back(next.color);
+ colors.push_back(next.color);
+ draw_primitive(points,colors,Vector<Point2>());
+ prev=next;
+ }
+
+ //Draw point markers
+ for(int i=0;i<points.size();i++) {
+
+ Color col = i==grabbed?Color(1,0.0,0.0,0.9):points[i].color.contrasted();
+ col.a = 0.9;
+
+ draw_line(Vector2(points[i].offset*total_w,0),Vector2(points[i].offset*total_w,h/2),col);
+ draw_rect(Rect2(points[i].offset*total_w-POINT_WIDTH/2, h/2, POINT_WIDTH, h/2), Color(0.6, 0.6, 0.6, i==grabbed?0.9:0.4));
+ draw_line(Vector2(points[i].offset*total_w-POINT_WIDTH/2,h/2),Vector2(points[i].offset*total_w-POINT_WIDTH/2,h-1),col);
+ draw_line(Vector2(points[i].offset*total_w+POINT_WIDTH/2,h/2),Vector2(points[i].offset*total_w+POINT_WIDTH/2,h-1),col);
+ draw_line(Vector2(points[i].offset*total_w-POINT_WIDTH/2,h/2),Vector2(points[i].offset*total_w+POINT_WIDTH/2,h/2),col);
+ draw_line(Vector2(points[i].offset*total_w-POINT_WIDTH/2,h-1),Vector2(points[i].offset*total_w+POINT_WIDTH/2,h-1),col);
+
+ }
+
+
+ //Draw "button" for color selector
+ _draw_checker(total_w+3,0, h, h);
+ if (grabbed!=-1) {
+ //Draw with selection color
+ draw_rect(Rect2(total_w+3,0,h,h),points[grabbed].color);
+ } else {
+ //if no color selected draw grey color with 'X' on top.
+ draw_rect(Rect2(total_w+3,0,h,h), Color(0.5, 0.5, 0.5, 1));
+ draw_line(Vector2(total_w+3,0),Vector2(total_w+3+h,h),Color(1,1,1,0.6));
+ draw_line(Vector2(total_w+3,h),Vector2(total_w+3+h,0),Color(1,1,1,0.6));
+ }
+
+ //Draw borders around color ramp if in focus
+ if (has_focus()) {
+
+ draw_line(Vector2(-1,-1),Vector2(total_w+1,-1),Color(1,1,1,0.6));
+ draw_line(Vector2(total_w+1,-1),Vector2(total_w+1,h+1),Color(1,1,1,0.6));
+ draw_line(Vector2(total_w+1,h+1),Vector2(-1,h+1),Color(1,1,1,0.6));
+ draw_line(Vector2(-1,-1),Vector2(-1,h+1),Color(1,1,1,0.6));
+ }
+
+ }
+}
+
+void ColorRampEdit::_draw_checker(int x, int y, int w, int h) {
+ //Draw it with polygon to insert UVs for scale
+ Vector<Vector2> backPoints;
+ backPoints.push_back(Vector2(x, y));
+ backPoints.push_back(Vector2(x, y+h));
+ backPoints.push_back(Vector2(x+w, y+h));
+ backPoints.push_back(Vector2(x+w, y));
+ Vector<Color> colorPoints;
+ colorPoints.push_back(Color(1, 1, 1, 1));
+ colorPoints.push_back(Color(1, 1, 1, 1));
+ colorPoints.push_back(Color(1, 1, 1, 1));
+ colorPoints.push_back(Color(1, 1, 1, 1));
+ Vector<Vector2> uvPoints;
+ //Draw checker pattern pixel-perfect and scale it by 2.
+ uvPoints.push_back(Vector2(x, y));
+ uvPoints.push_back(Vector2(x, y+h*.5f/checker->get_height()));
+ uvPoints.push_back(Vector2(x+w*.5f/checker->get_width(), y+h*.5f/checker->get_height()));
+ uvPoints.push_back(Vector2(x+w*.5f/checker->get_width(), y));
+ draw_polygon(backPoints, colorPoints, uvPoints, checker);
+}
+
+Size2 ColorRampEdit::get_minimum_size() const {
+
+ return Vector2(0,16);
+}
+
+void ColorRampEdit::_color_changed(const Color& p_color) {
+
+ if (grabbed==-1)
+ return;
+ points[grabbed].color=p_color;
+ update();
+ emit_signal("ramp_changed");
+
+}
+
+void ColorRampEdit::set_ramp(const Vector<float>& p_offsets,const Vector<Color>& p_colors) {
+
+ ERR_FAIL_COND(p_offsets.size()!=p_colors.size());
+ points.clear();
+ for(int i=0;i<p_offsets.size();i++) {
+ ColorRamp::Point p;
+ p.offset=p_offsets[i];
+ p.color=p_colors[i];
+ points.push_back(p);
+ }
+
+ points.sort();
+ update();
+}
+
+Vector<float> ColorRampEdit::get_offsets() const {
+ Vector<float> ret;
+ for(int i=0;i<points.size();i++)
+ ret.push_back(points[i].offset);
+ return ret;
+}
+
+Vector<Color> ColorRampEdit::get_colors() const {
+ Vector<Color> ret;
+ for(int i=0;i<points.size();i++)
+ ret.push_back(points[i].color);
+ return ret;
+}
+
+void ColorRampEdit::set_points(Vector<ColorRamp::Point>& p_points) {
+ if(points.size() != p_points.size())
+ grabbed = -1;
+ points.clear();
+ points = p_points;
+}
+
+Vector<ColorRamp::Point>& ColorRampEdit::get_points() {
+ return points;
+}
+
+void ColorRampEdit::_bind_methods() {
+ ObjectTypeDB::bind_method(_MD("_input_event"),&ColorRampEdit::_input_event);
+ ObjectTypeDB::bind_method(_MD("_color_changed"),&ColorRampEdit::_color_changed);
+ ADD_SIGNAL(MethodInfo("ramp_changed"));
+}
diff --git a/scene/gui/color_ramp_edit.h b/scene/gui/color_ramp_edit.h
new file mode 100644
index 0000000000..91292eed0d
--- /dev/null
+++ b/scene/gui/color_ramp_edit.h
@@ -0,0 +1,52 @@
+#ifndef SCENE_GUI_COLOR_RAMP_EDIT_H_
+#define SCENE_GUI_COLOR_RAMP_EDIT_H_
+
+#include "scene/gui/popup.h"
+#include "scene/gui/color_picker.h"
+#include "scene/resources/color_ramp.h"
+#include "scene/resources/default_theme/theme_data.h"
+
+#define POINT_WIDTH 8
+
+class ColorRampEdit : public Control {
+
+ OBJ_TYPE(ColorRampEdit,Control);
+
+ PopupPanel *popup;
+ ColorPicker *picker;
+
+ Ref<ImageTexture> checker;
+
+ bool grabbing;
+ int grabbed;
+ Vector<ColorRamp::Point> points;
+
+ void _draw_checker(int x, int y, int w, int h);
+ void _color_changed(const Color& p_color);
+ int _get_point_from_pos(int x);
+ void _show_color_picker();
+
+protected:
+ void _input_event(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;
+ void set_points(Vector<ColorRamp::Point>& p_points);
+ Vector<ColorRamp::Point>& get_points();
+ virtual Size2 get_minimum_size() const;
+
+ ColorRampEdit();
+ virtual ~ColorRampEdit();
+};
+
+/*class ColorRampEditPanel : public Panel
+{
+ OBJ_TYPE(ColorRampEditPanel, Panel );
+};*/
+
+
+#endif /* SCENE_GUI_COLOR_RAMP_EDIT_H_ */
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
new file mode 100644
index 0000000000..2fd4d810de
--- /dev/null
+++ b/scene/gui/item_list.cpp
@@ -0,0 +1,1048 @@
+#include "item_list.h"
+#include "os/os.h"
+#include "globals.h"
+
+
+void ItemList::add_item(const String& p_item,const Ref<Texture>& p_texture,bool p_selectable) {
+
+ Item item;
+ item.icon=p_texture;
+ item.text=p_item;
+ item.selectable=p_selectable;
+ item.selected=false;
+ item.disabled=false;
+ items.push_back(item);
+
+ update();
+ shape_changed=true;
+
+}
+
+void ItemList::add_icon_item(const Ref<Texture>& p_item,bool p_selectable){
+
+ Item item;
+ item.icon=p_item;
+ //item.text=p_item;
+ item.selectable=p_selectable;
+ item.selected=false;
+ item.disabled=false;
+ items.push_back(item);
+
+ update();
+ shape_changed=true;
+
+}
+
+void ItemList::set_item_text(int p_idx,const String& p_text){
+
+ ERR_FAIL_INDEX(p_idx,items.size());
+
+ items[p_idx].text=p_text;
+ update();
+ shape_changed=true;
+
+}
+
+String ItemList::get_item_text(int p_idx) const{
+
+ ERR_FAIL_INDEX_V(p_idx,items.size(),String());
+ return items[p_idx].text;
+
+}
+
+void ItemList::set_item_tooltip(int p_idx,const String& p_tooltip){
+
+ ERR_FAIL_INDEX(p_idx,items.size());
+
+ items[p_idx].tooltip=p_tooltip;
+ update();
+ shape_changed=true;
+
+}
+
+String ItemList::get_item_tooltip(int p_idx) const{
+
+ ERR_FAIL_INDEX_V(p_idx,items.size(),String());
+ return items[p_idx].tooltip;
+
+}
+
+void ItemList::set_item_icon(int p_idx,const Ref<Texture>& p_icon){
+
+ ERR_FAIL_INDEX(p_idx,items.size());
+
+ items[p_idx].icon=p_icon;
+ update();
+ shape_changed=true;
+
+
+}
+Ref<Texture> ItemList::get_item_icon(int p_idx) const{
+
+ ERR_FAIL_INDEX_V(p_idx,items.size(),Ref<Texture>());
+
+ return items[p_idx].icon;
+
+}
+
+
+void ItemList::set_item_tag_icon(int p_idx,const Ref<Texture>& p_tag_icon){
+
+ ERR_FAIL_INDEX(p_idx,items.size());
+
+ items[p_idx].tag_icon=p_tag_icon;
+ update();
+ shape_changed=true;
+
+
+}
+Ref<Texture> ItemList::get_item_tag_icon(int p_idx) const{
+
+ ERR_FAIL_INDEX_V(p_idx,items.size(),Ref<Texture>());
+
+ return items[p_idx].tag_icon;
+
+}
+
+void ItemList::set_item_selectable(int p_idx,bool p_selectable){
+
+ ERR_FAIL_INDEX(p_idx,items.size());
+
+ items[p_idx].selectable=p_selectable;
+
+
+}
+
+
+bool ItemList::is_item_selectable(int p_idx) const{
+
+ ERR_FAIL_INDEX_V(p_idx,items.size(),false);
+ return items[p_idx].selectable;
+}
+
+void ItemList::set_item_disabled(int p_idx,bool p_disabled){
+
+ ERR_FAIL_INDEX(p_idx,items.size());
+
+ items[p_idx].disabled=p_disabled;
+
+
+}
+
+
+bool ItemList::is_item_disabled(int p_idx) const{
+
+ ERR_FAIL_INDEX_V(p_idx,items.size(),false);
+ return items[p_idx].disabled;
+}
+
+
+void ItemList::set_item_metadata(int p_idx,const Variant& p_metadata){
+
+ ERR_FAIL_INDEX(p_idx,items.size());
+
+ items[p_idx].metadata=p_metadata;
+ update();
+ shape_changed=true;
+
+}
+
+Variant ItemList::get_item_metadata(int p_idx) const{
+
+ ERR_FAIL_INDEX_V(p_idx,items.size(),Variant());
+ return items[p_idx].metadata;
+
+}
+void ItemList::select(int p_idx,bool p_single){
+
+ ERR_FAIL_INDEX(p_idx,items.size());
+
+ if (p_single || select_mode==SELECT_SINGLE) {
+
+ if (!items[p_idx].selectable) {
+ return;
+ }
+
+ for(int i=0;i<items.size();i++) {
+ items[i].selected=p_idx==i;
+ }
+
+ current=p_idx;
+ } else {
+
+ if (items[p_idx].selectable) {
+ items[p_idx].selected=true;
+ }
+ }
+ update();
+
+}
+void ItemList::unselect(int p_idx){
+
+ ERR_FAIL_INDEX(p_idx,items.size());
+
+ if (select_mode!=SELECT_MULTI) {
+ items[p_idx].selected=false;
+ current=-1;
+ } else {
+ items[p_idx].selected=false;
+ }
+ update();
+
+}
+bool ItemList::is_selected(int p_idx) const{
+
+ ERR_FAIL_INDEX_V(p_idx,items.size(),false);
+
+ return items[p_idx].selected;
+
+}
+
+void ItemList::set_current(int p_current) {
+ ERR_FAIL_INDEX(p_current,items.size());
+
+ if (select_mode==SELECT_SINGLE)
+ select(p_current,true);
+ else {
+ current=p_current;
+ update();
+ }
+}
+
+int ItemList::get_current() const {
+
+ return current;
+}
+
+
+int ItemList::get_item_count() const{
+
+ return items.size();
+}
+void ItemList::remove_item(int p_idx){
+
+ ERR_FAIL_INDEX(p_idx,items.size());
+
+ items.remove(p_idx);
+ update();
+ shape_changed=true;
+
+}
+
+void ItemList::clear(){
+
+ items.clear();
+ current=-1;
+ update();
+
+}
+
+void ItemList::set_fixed_column_width(int p_size){
+
+ ERR_FAIL_COND(p_size<0);
+ fixed_column_width=p_size;
+ update();
+ shape_changed=true;
+
+}
+int ItemList::get_fixed_column_width() const{
+
+ return fixed_column_width;
+}
+
+void ItemList::set_max_text_lines(int p_lines){
+
+ ERR_FAIL_COND(p_lines<1);
+ max_text_lines=p_lines;
+ update();
+ shape_changed=true;
+
+}
+int ItemList::get_max_text_lines() const{
+
+ return max_text_lines;
+}
+
+void ItemList::set_max_columns(int p_amount){
+
+ ERR_FAIL_COND(p_amount<0);
+ max_columns=p_amount;
+ update();
+}
+int ItemList::get_max_columns() const{
+
+ return max_columns;
+}
+
+void ItemList::set_select_mode(SelectMode p_mode) {
+
+ select_mode=p_mode;
+ update();
+}
+
+ItemList::SelectMode ItemList::get_select_mode() const {
+
+ return select_mode;
+}
+
+void ItemList::set_icon_mode(IconMode p_mode){
+
+ icon_mode=p_mode;
+ update();
+ shape_changed=true;
+
+}
+ItemList::IconMode ItemList::get_icon_mode() const{
+
+ return icon_mode;
+}
+
+void ItemList::set_min_icon_size(const Size2& p_size) {
+
+ min_icon_size=p_size;
+ update();
+}
+
+Size2 ItemList::get_min_icon_size() const {
+
+ return min_icon_size;
+}
+
+
+
+void ItemList::_input_event(const InputEvent& p_event) {
+ if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_LEFT && p_event.mouse_button.pressed) {
+
+ const InputEventMouseButton &mb = p_event.mouse_button;
+
+ search_string=""; //any mousepress cancels
+ Vector2 pos(mb.x,mb.y);
+ Ref<StyleBox> bg = get_stylebox("bg");
+ pos-=bg->get_offset();
+ pos.y+=scroll_bar->get_val();
+
+ int closest = -1;
+ int closest_dist=0x7FFFFFFF;
+
+ for(int i=0;i<items.size();i++) {
+
+ Rect2 rc = items[i].rect_cache;
+ if (i%current_columns==current_columns-1) {
+ rc.size.width=get_size().width; //not right but works
+ }
+
+ if (rc.has_point(pos)) {
+ closest=i;
+ break;
+ }
+
+ float dist = rc.distance_to(pos);
+ if (dist<closest_dist) {
+ closest=i;
+ closest_dist=dist;
+ }
+ }
+
+ if (closest!=-1) {
+
+ int i = closest;
+
+ if (select_mode==SELECT_MULTI && items[i].selected && mb.mod.command) {
+ unselect(i);
+ emit_signal("multi_selected",i,false);
+ } else if (select_mode==SELECT_MULTI && mb.mod.shift && current>=0 && current<items.size() && current!=i) {
+
+ int from = current;
+ int to = i;
+ if (i<current) {
+ SWAP(from,to);
+ }
+ for(int j=from;j<=to;j++) {
+ bool selected = !items[j].selected;
+ select(j,false);
+ if (selected)
+ emit_signal("multi_selected",i,true);
+ }
+ } else {
+ bool selected = !items[i].selected;
+ select(i,select_mode==SELECT_SINGLE || !mb.mod.command);
+ if (selected) {
+ if (select_mode==SELECT_SINGLE) {
+ emit_signal("item_selected",i);
+ } else
+ emit_signal("multi_selected",i,true);
+ }
+
+ if (/*select_mode==SELECT_SINGLE &&*/ mb.doubleclick) {
+
+ emit_signal("item_activated",i);
+
+ }
+
+
+ }
+
+
+ return;
+ }
+ }
+ if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_WHEEL_UP && p_event.mouse_button.pressed) {
+
+ scroll_bar->set_val( scroll_bar->get_val()-scroll_bar->get_page()/8 );
+
+ }
+ if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_WHEEL_DOWN && p_event.mouse_button.pressed) {
+
+ scroll_bar->set_val( scroll_bar->get_val()+scroll_bar->get_page()/8 );
+
+ }
+
+ if (p_event.is_pressed() && items.size()>0) {
+ if (p_event.is_action("ui_up")) {
+
+ if (search_string!="") {
+
+ uint64_t now = OS::get_singleton()->get_ticks_msec();
+ uint64_t diff = now-search_time_msec;
+
+ if (diff<int(Globals::get_singleton()->get("gui/incr_search_max_interval_msec"))*2) {
+
+ for(int i=current-1;i>=0;i--) {
+
+ if (items[i].text.begins_with(search_string)) {
+
+ set_current(i);
+ ensure_current_is_visible();
+ if (select_mode==SELECT_SINGLE) {
+ emit_signal("item_selected",current);
+ }
+
+
+ break;
+ }
+ }
+ accept_event();
+ return;
+ }
+ }
+
+ if (current>=current_columns) {
+ set_current(current-current_columns);
+ ensure_current_is_visible();
+ if (select_mode==SELECT_SINGLE) {
+ emit_signal("item_selected",current);
+ }
+ accept_event();
+ }
+ } else if (p_event.is_action("ui_down")) {
+
+ if (search_string!="") {
+
+ uint64_t now = OS::get_singleton()->get_ticks_msec();
+ uint64_t diff = now-search_time_msec;
+
+ if (diff<int(Globals::get_singleton()->get("gui/incr_search_max_interval_msec"))*2) {
+
+ for(int i=current+1;i<items.size();i++) {
+
+ if (items[i].text.begins_with(search_string)) {
+
+ set_current(i);
+ ensure_current_is_visible();
+ if (select_mode==SELECT_SINGLE) {
+ emit_signal("item_selected",current);
+ }
+ break;
+ }
+ }
+ accept_event();
+ return;
+ }
+ }
+
+ if (current<items.size()-current_columns) {
+ set_current(current+current_columns);
+ ensure_current_is_visible();
+ if (select_mode==SELECT_SINGLE) {
+ emit_signal("item_selected",current);
+ }
+ accept_event();
+
+ }
+ } else if (p_event.is_action("ui_page_up")) {
+
+ search_string=""; //any mousepress cancels
+
+ for(int i=4;i>0;i--) {
+ if (current-current_columns*i >=0 ) {
+ set_current( current- current_columns*i);
+ ensure_current_is_visible();
+ if (select_mode==SELECT_SINGLE) {
+ emit_signal("item_selected",current);
+ }
+ accept_event();
+ break;
+ }
+ }
+ } else if (p_event.is_action("ui_page_down")) {
+
+ search_string=""; //any mousepress cancels
+
+ for(int i=4;i>0;i--) {
+ if (current+current_columns*i < items.size() ) {
+ set_current( current+ current_columns*i);
+ ensure_current_is_visible();
+ if (select_mode==SELECT_SINGLE) {
+ emit_signal("item_selected",current);
+ }
+ accept_event();
+
+ break;
+ }
+ }
+ } else if (p_event.is_action("ui_left")) {
+
+ search_string=""; //any mousepress cancels
+
+ if (current%current_columns!=0) {
+ set_current(current-1);
+ ensure_current_is_visible();
+ if (select_mode==SELECT_SINGLE) {
+ emit_signal("item_selected",current);
+ }
+ accept_event();
+
+ }
+ } else if (p_event.is_action("ui_right")) {
+
+ search_string=""; //any mousepress cancels
+
+ if (current%current_columns!=(current_columns-1)) {
+ set_current(current+1);
+ ensure_current_is_visible();
+ if (select_mode==SELECT_SINGLE) {
+ emit_signal("item_selected",current);
+ }
+ accept_event();
+
+ }
+ } else if (p_event.is_action("ui_cancel")) {
+ search_string="";
+ } else if (p_event.is_action("ui_select")) {
+
+
+ if (select_mode==SELECT_MULTI && current>=0 && current<items.size()) {
+ if (items[current].selectable && !items[current].selected) {
+ select(current,false);
+ emit_signal("multi_selected",current,true);
+ } else if (items[current].selected) {
+ unselect(current);
+ emit_signal("multi_selected",current,false);
+ }
+ }
+ } else if (p_event.is_action("ui_accept")) {
+ search_string=""; //any mousepress cance
+
+ if (current>=0 && current<items.size()) {
+ emit_signal("item_activated",current);
+ }
+ } else if (p_event.type==InputEvent::KEY) {
+
+ if (p_event.key.unicode) {
+
+ uint64_t now = OS::get_singleton()->get_ticks_msec();
+ uint64_t diff = now-search_time_msec;
+ uint64_t max_interval = uint64_t(GLOBAL_DEF("gui/incr_search_max_interval_msec",2000));
+ search_time_msec = now;
+
+ if (diff>max_interval) {
+ search_string="";
+ }
+
+ search_string+=String::chr(p_event.key.unicode);
+ for(int i=0;i<items.size();i++) {
+ if (items[i].text.begins_with(search_string)) {
+ set_current(i);
+ ensure_current_is_visible();
+ if (select_mode==SELECT_SINGLE) {
+ emit_signal("item_selected",current);
+ }
+ break;
+ }
+ }
+
+ }
+
+ }
+ }
+
+
+
+
+}
+
+void ItemList::ensure_current_is_visible() {
+
+ if (current>=0 && current <=items.size()) {
+
+ Rect2 r = items[current].rect_cache;
+ int from = scroll_bar->get_val();
+ int to = from + scroll_bar->get_page();
+
+ if (r.pos.y < from) {
+ scroll_bar->set_val(r.pos.y);
+ } else if (r.pos.y+r.size.y > to) {
+ scroll_bar->set_val(r.pos.y+r.size.y - (to-from));
+ }
+ }
+}
+
+void ItemList::_notification(int p_what) {
+
+ if (p_what==NOTIFICATION_RESIZED) {
+ shape_changed=true;
+ update();
+ }
+
+ if (p_what==NOTIFICATION_DRAW) {
+
+ VS::get_singleton()->canvas_item_set_clip(get_canvas_item(),true);
+ Ref<StyleBox> bg = get_stylebox("bg");
+
+ int mw = scroll_bar->get_minimum_size().x;
+ scroll_bar->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,mw+bg->get_margin(MARGIN_RIGHT));
+ scroll_bar->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,bg->get_margin(MARGIN_RIGHT));
+ scroll_bar->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,bg->get_margin(MARGIN_TOP));
+ scroll_bar->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,bg->get_margin(MARGIN_BOTTOM));
+
+
+ Size2 size = get_size();
+
+ float page = size.height-bg->get_minimum_size().height;
+ int width = size.width - mw - bg->get_minimum_size().width;
+ scroll_bar->set_page(page);
+
+ draw_style_box(bg,Rect2(Point2(),size));
+
+ int hseparation = get_constant("hseparation");
+ int vseparation = get_constant("vseparation");
+ int icon_margin = get_constant("icon_margin");
+ int line_separation = get_constant("line_separation");
+
+ Ref<StyleBox> sbsel = has_focus()?get_stylebox("selected_focus"):get_stylebox("selected");
+ Ref<StyleBox> cursor = has_focus()?get_stylebox("cursor"):get_stylebox("cursor_unfocused");
+
+ Ref<Font> font = get_font("font");
+ Color guide_color = get_color("guide_color");
+ Color font_color = get_color("font_color");
+ int font_height = font->get_height();
+ Vector<int> line_size_cache;
+ Vector<int> line_limit_cache;
+
+ if (max_text_lines) {
+ line_size_cache.resize(max_text_lines);
+ line_limit_cache.resize(max_text_lines);
+ }
+
+ if (has_focus()) {
+ VisualServer::get_singleton()->canvas_item_add_clip_ignore(get_canvas_item(),true);
+ draw_style_box(get_stylebox("bg_focus"),Rect2(Point2(),size));
+ VisualServer::get_singleton()->canvas_item_add_clip_ignore(get_canvas_item(),false);
+ }
+
+ if (shape_changed) {
+
+ //1- compute item minimum sizes
+ for(int i=0;i<items.size();i++) {
+
+ Size2 minsize;
+ if (items[i].icon.is_valid()) {
+ minsize=items[i].icon->get_size();
+ if (min_icon_size.x!=0)
+ minsize.x = MAX(minsize.x,min_icon_size.x);
+ if (min_icon_size.y!=0)
+ minsize.y = MAX(minsize.y,min_icon_size.y);
+
+ if (items[i].text!="") {
+ if (icon_mode==ICON_MODE_TOP) {
+ minsize.y+=icon_margin;
+ } else {
+ minsize.x+=icon_margin;
+ }
+ }
+ }
+
+ if (items[i].text!="") {
+
+ Size2 s = font->get_string_size(items[i].text);
+ //s.width=MIN(s.width,fixed_column_width);
+
+
+
+ if (icon_mode==ICON_MODE_TOP) {
+ minsize.x=MAX(minsize.x,s.width);
+ if (max_text_lines>0) {
+ minsize.y+=(font_height+line_separation)*max_text_lines;
+ } else {
+ minsize.y+=s.height;
+ }
+
+ } else {
+ minsize.y=MAX(minsize.y,s.height);
+ minsize.x+=s.width;
+ }
+ }
+
+
+
+ items[i].rect_cache.size=minsize;
+ if (fixed_column_width>0)
+ items[i].rect_cache.size.x=fixed_column_width;
+
+ }
+
+ int fit_size = size.x - bg->get_minimum_size().width - mw;
+
+ //2-attempt best fit
+ current_columns = 0x7FFFFFFF;
+ if (max_columns>0)
+ current_columns=max_columns;
+
+
+ while(true) {
+ //repeat util all fits
+ //print_line("try with "+itos(current_columns));
+ bool all_fit=true;
+ Vector2 ofs;
+ int col=0;
+ int max_h=0;
+ separators.clear();;
+ for(int i=0;i<items.size();i++) {
+
+ if (current_columns>1 && items[i].rect_cache.size.width+ofs.x > fit_size) {
+ //went past
+ current_columns=MAX(col,1);
+ all_fit=false;
+ break;
+ }
+
+ items[i].rect_cache.pos=ofs;
+ max_h=MAX(max_h,items[i].rect_cache.size.y);
+ ofs.x+=items[i].rect_cache.size.x;
+ //print_line("item "+itos(i)+" ofs "+rtos(items[i].rect_cache.size.x));
+ if (col>0)
+ ofs.x+=hseparation;
+ col++;
+ if (col==current_columns) {
+
+ if (i<items.size()-1)
+ separators.push_back(ofs.y+max_h+vseparation/2);
+ ofs.x=0;
+ ofs.y+=max_h+vseparation;
+ col=0;
+ max_h=0;
+ }
+ }
+
+ if (all_fit) {
+ float max = MAX(page,ofs.y+max_h);
+ scroll_bar->set_max(max);
+ //print_line("max: "+rtos(max)+" page "+rtos(page));
+ if (max<=page) {
+ scroll_bar->set_val(0);
+ scroll_bar->hide();
+ } else {
+ scroll_bar->show();
+ }
+ break;
+ }
+ }
+
+
+ shape_changed=false;
+ }
+
+
+
+ Vector2 base_ofs = bg->get_offset();
+ base_ofs.y-=int(scroll_bar->get_val());
+
+ Rect2 clip(Point2(),size-bg->get_minimum_size()+Vector2(0,scroll_bar->get_val()));
+
+ for(int i=0;i<items.size();i++) {
+
+
+ Rect2 rcache = items[i].rect_cache;
+
+ if (!clip.intersects(rcache))
+ continue;
+
+
+ if (current_columns==1) {
+ rcache.size.width = width-rcache.pos.x;
+ }
+ if (items[i].selected) {
+ Rect2 r=rcache;
+ r.pos+=base_ofs;
+
+ r.pos.x-=sbsel->get_margin(MARGIN_LEFT);
+ r.size.x+=sbsel->get_margin(MARGIN_LEFT)+sbsel->get_margin(MARGIN_RIGHT);
+ r.pos.y-=sbsel->get_margin(MARGIN_TOP);
+ r.size.y+=sbsel->get_margin(MARGIN_TOP)+sbsel->get_margin(MARGIN_BOTTOM);
+
+ draw_style_box(sbsel,r);
+
+ }
+
+
+ Vector2 text_ofs;
+ if (items[i].icon.is_valid()) {
+
+ Vector2 icon_ofs;
+ if (min_icon_size!=Vector2()) {
+ icon_ofs = (min_icon_size - items[i].icon->get_size())/2;
+ }
+
+ if (icon_mode==ICON_MODE_TOP) {
+ draw_texture(items[i].icon,icon_ofs+items[i].rect_cache.pos+Vector2(items[i].rect_cache.size.width/2-items[i].icon->get_width()/2,0).floor()+base_ofs);
+ text_ofs.y = MAX(items[i].icon->get_height(),min_icon_size.y)+icon_margin;
+ } else {
+ draw_texture(items[i].icon,icon_ofs+items[i].rect_cache.pos+Vector2(0,items[i].rect_cache.size.height/2-items[i].icon->get_height()/2).floor()+base_ofs);
+ text_ofs.x = MAX(items[i].icon->get_width(),min_icon_size.x)+icon_margin;
+ }
+ }
+
+ if (items[i].tag_icon.is_valid()) {
+
+ draw_texture(items[i].tag_icon,items[i].rect_cache.pos+base_ofs);
+ }
+
+ if (items[i].text!="") {
+
+ int max_len=-1;
+
+ Vector2 size = font->get_string_size(items[i].text);
+ if (fixed_column_width)
+ max_len=fixed_column_width;
+ else
+ max_len=size.x;
+
+ if (icon_mode==ICON_MODE_TOP && max_text_lines>0) {
+
+ int ss = items[i].text.length();
+ float ofs=0;
+ int line=0;
+ for(int j=0;j<=ss;j++) {
+
+ int cs = j<ss?font->get_char_size(items[i].text[j],items[i].text[j+1]).x:0;
+ if (ofs+cs>max_len || j==ss) {
+ line_limit_cache[line]=j;
+ line_size_cache[line]=ofs;
+ line++;
+ ofs=0;
+ if (line>=max_text_lines)
+ break;
+ } else {
+ ofs+=cs;
+ }
+
+ }
+
+ line=0;
+ ofs=0;
+
+ text_ofs.y+=font->get_ascent();
+ text_ofs=text_ofs.floor();
+ text_ofs+=base_ofs;
+ text_ofs+=items[i].rect_cache.pos;
+
+ for(int j=0;j<ss;j++) {
+
+ if (j==line_limit_cache[line]) {
+ line++;
+ ofs=0;
+ if (line>=max_text_lines)
+ break;
+ }
+ ofs+=font->draw_char(get_canvas_item(),text_ofs+Vector2(ofs+(max_len-line_size_cache[line])/2,line*(font_height+line_separation)).floor(),items[i].text[j],items[i].text[j+1],font_color);
+ }
+
+ //special multiline mode
+ } else {
+
+ if (fixed_column_width>0)
+ size.x=MIN(size.x,fixed_column_width);
+
+ if (icon_mode==ICON_MODE_TOP) {
+ text_ofs.x+=(items[i].rect_cache.size.width-size.x)/2;
+ } else {
+ text_ofs.y+=(items[i].rect_cache.size.height-size.y)/2;
+ }
+
+ text_ofs.y+=font->get_ascent();
+ text_ofs=text_ofs.floor();
+ text_ofs+=base_ofs;
+ text_ofs+=items[i].rect_cache.pos;
+
+ draw_string(font,text_ofs,items[i].text,font_color,max_len+1);
+ }
+
+
+ }
+
+ if (select_mode==SELECT_MULTI && i==current) {
+
+ Rect2 r=rcache;
+ r.pos+=base_ofs;
+ draw_style_box(cursor,r);
+
+ }
+ }
+
+ for(int i=0;i<separators.size();i++) {
+ draw_line(Vector2(bg->get_margin(MARGIN_LEFT),base_ofs.y+separators[i]),Vector2(size.width-bg->get_margin(MARGIN_LEFT),base_ofs.y+separators[i]),guide_color);
+ }
+
+ }
+}
+
+void ItemList::_scroll_changed(double) {
+ update();
+}
+
+
+String ItemList::get_tooltip(const Point2& p_pos) const {
+
+ Vector2 pos=p_pos;
+ Ref<StyleBox> bg = get_stylebox("bg");
+ pos-=bg->get_offset();
+ pos.y+=scroll_bar->get_val();
+
+ int closest = -1;
+ int closest_dist=0x7FFFFFFF;
+
+ for(int i=0;i<items.size();i++) {
+
+ Rect2 rc = items[i].rect_cache;
+ if (i%current_columns==current_columns-1) {
+ rc.size.width=get_size().width; //not right but works
+ }
+
+ if (rc.has_point(pos)) {
+ closest=i;
+ break;
+ }
+
+ float dist = rc.distance_to(pos);
+ if (dist<closest_dist) {
+ closest=i;
+ closest_dist=dist;
+ }
+ }
+
+ if (closest!=-1) {
+ if (items[closest].tooltip!="") {
+ return items[closest].tooltip;
+ }
+ if (items[closest].text!="") {
+ return items[closest].text;
+ }
+ }
+
+ return Control::get_tooltip(p_pos);
+
+
+}
+
+
+void ItemList::_bind_methods(){
+
+ ObjectTypeDB::bind_method(_MD("add_item","text","icon:Texture","selectable"),&ItemList::add_item,DEFVAL(Ref<Texture>()),DEFVAL(true));
+ ObjectTypeDB::bind_method(_MD("add_icon_item","icon:Texture","selectable"),&ItemList::add_icon_item,DEFVAL(true));
+
+ ObjectTypeDB::bind_method(_MD("set_item_text","idx","text"),&ItemList::set_item_text);
+ ObjectTypeDB::bind_method(_MD("get_item_text","idx"),&ItemList::get_item_text);
+
+ ObjectTypeDB::bind_method(_MD("set_item_icon","idx","icon:Texture"),&ItemList::set_item_icon);
+ ObjectTypeDB::bind_method(_MD("get_item_icon:Tedture","idx"),&ItemList::get_item_icon);
+
+ ObjectTypeDB::bind_method(_MD("set_item_selectable","idx","selectable"),&ItemList::set_item_selectable);
+ ObjectTypeDB::bind_method(_MD("is_item_selectable","idx"),&ItemList::is_item_selectable);
+
+ ObjectTypeDB::bind_method(_MD("set_item_disabled","idx","disabled"),&ItemList::set_item_disabled);
+ ObjectTypeDB::bind_method(_MD("is_item_disabled","idx"),&ItemList::is_item_disabled);
+
+ ObjectTypeDB::bind_method(_MD("set_item_tooltip","idx","tooltip"),&ItemList::set_item_tooltip);
+ ObjectTypeDB::bind_method(_MD("get_item_tooltip","idx"),&ItemList::get_item_tooltip);
+
+ ObjectTypeDB::bind_method(_MD("select","idx","single"),&ItemList::select,DEFVAL(true));
+ ObjectTypeDB::bind_method(_MD("unselect","idx"),&ItemList::unselect);
+ ObjectTypeDB::bind_method(_MD("is_selected","idx"),&ItemList::is_selected);
+
+ ObjectTypeDB::bind_method(_MD("get_item_count"),&ItemList::get_item_count);
+ ObjectTypeDB::bind_method(_MD("remove_item","idx"),&ItemList::remove_item);
+
+ ObjectTypeDB::bind_method(_MD("clear"),&ItemList::clear);
+
+ ObjectTypeDB::bind_method(_MD("set_fixed_column_width","width"),&ItemList::set_fixed_column_width);
+ ObjectTypeDB::bind_method(_MD("get_fixed_column_width"),&ItemList::get_fixed_column_width);
+
+ ObjectTypeDB::bind_method(_MD("set_max_text_lines","lines"),&ItemList::set_max_text_lines);
+ ObjectTypeDB::bind_method(_MD("get_max_text_lines"),&ItemList::get_max_text_lines);
+
+ ObjectTypeDB::bind_method(_MD("set_max_columns","amount"),&ItemList::set_max_columns);
+ ObjectTypeDB::bind_method(_MD("get_max_columns"),&ItemList::get_max_columns);
+
+ ObjectTypeDB::bind_method(_MD("set_select_mode","mode"),&ItemList::set_select_mode);
+ ObjectTypeDB::bind_method(_MD("get_select_mode"),&ItemList::get_select_mode);
+
+ ObjectTypeDB::bind_method(_MD("set_icon_mode","mode"),&ItemList::set_icon_mode);
+ ObjectTypeDB::bind_method(_MD("get_icon_mode"),&ItemList::get_icon_mode);
+
+ ObjectTypeDB::bind_method(_MD("set_min_icon_size","size"),&ItemList::set_min_icon_size);
+ ObjectTypeDB::bind_method(_MD("get_min_icon_size"),&ItemList::get_min_icon_size);
+
+ ObjectTypeDB::bind_method(_MD("ensure_current_is_visible"),&ItemList::ensure_current_is_visible);
+
+ ObjectTypeDB::bind_method(_MD("_scroll_changed"),&ItemList::_scroll_changed);
+ ObjectTypeDB::bind_method(_MD("_input_event"),&ItemList::_input_event);
+
+ BIND_CONSTANT( ICON_MODE_TOP );
+ BIND_CONSTANT( ICON_MODE_LEFT );
+ BIND_CONSTANT( SELECT_SINGLE );
+ BIND_CONSTANT( SELECT_MULTI );
+
+ ADD_SIGNAL( MethodInfo("item_selected",PropertyInfo(Variant::INT,"index")));
+ ADD_SIGNAL( MethodInfo("multi_selected",PropertyInfo(Variant::INT,"index"),PropertyInfo(Variant::BOOL,"selected")));
+ ADD_SIGNAL( MethodInfo("item_activated",PropertyInfo(Variant::INT,"index")));
+}
+
+
+
+ItemList::ItemList() {
+
+ current=-1;
+
+ select_mode=SELECT_SINGLE;
+ icon_mode=ICON_MODE_LEFT;
+
+ fixed_column_width=0;
+ max_text_lines=1;
+ max_columns=1;
+
+ scroll_bar = memnew( VScrollBar );
+ add_child(scroll_bar);
+
+ shape_changed=true;
+ scroll_bar->connect("value_changed",this,"_scroll_changed");
+
+ set_focus_mode(FOCUS_ALL);
+ current_columns=1;
+ search_time_msec=0;
+
+}
+
+ItemList::~ItemList() {
+
+}
+
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
new file mode 100644
index 0000000000..6bbb416970
--- /dev/null
+++ b/scene/gui/item_list.h
@@ -0,0 +1,132 @@
+#ifndef ITEMLIST_H
+#define ITEMLIST_H
+
+#include "scene/gui/control.h"
+#include "scene/gui/scroll_bar.h"
+
+class ItemList : public Control {
+
+ OBJ_TYPE( ItemList, Control );
+public:
+
+ enum IconMode {
+ ICON_MODE_TOP,
+ ICON_MODE_LEFT
+ };
+
+ enum SelectMode {
+ SELECT_SINGLE,
+ SELECT_MULTI
+ };
+private:
+ struct Item {
+
+ Ref<Texture> icon;
+ Ref<Texture> tag_icon;
+ String text;
+ bool selectable;
+ bool selected;
+ bool disabled;
+ Variant metadata;
+ String tooltip;
+
+ Rect2 rect_cache;
+ };
+
+ int current;
+
+ bool shape_changed;
+
+ Vector<Item> items;
+ Vector<int> separators;
+
+ SelectMode select_mode;
+ IconMode icon_mode;
+ VScrollBar *scroll_bar;
+
+ uint64_t search_time_msec;
+ String search_string;
+
+ int current_columns;
+ int fixed_column_width;
+ int max_text_lines;
+ int max_columns;
+ Size2 min_icon_size;
+
+ void _scroll_changed(double);
+ void _input_event(const InputEvent& p_event);
+protected:
+
+ void _notification(int p_what);
+ static void _bind_methods();
+public:
+
+ void add_item(const String& p_item,const Ref<Texture>& p_texture=Ref<Texture>(),bool p_selectable=true);
+ void add_icon_item(const Ref<Texture>& p_item,bool p_selectable=true);
+
+ void set_item_text(int p_idx,const String& p_text);
+ String get_item_text(int p_idx) const;
+
+ void set_item_icon(int p_idx,const Ref<Texture>& p_icon);
+ Ref<Texture> get_item_icon(int p_idx) const;
+
+ void set_item_selectable(int p_idx,bool p_selectable);
+ bool is_item_selectable(int p_idx) const;
+
+ void set_item_disabled(int p_idx,bool p_disabled);
+ bool is_item_disabled(int p_idx) const;
+
+ void set_item_metadata(int p_idx,const Variant& p_metadata);
+ Variant get_item_metadata(int p_idx) const;
+
+ void set_item_tag_icon(int p_idx,const Ref<Texture>& p_tag_icon);
+ Ref<Texture> get_item_tag_icon(int p_idx) const;
+
+ void set_item_tooltip(int p_idx,const String& p_tooltip);
+ String get_item_tooltip(int p_idx) const;
+
+ void select(int p_idx,bool p_single=true);
+ void unselect(int p_idx);
+ bool is_selected(int p_idx) const;
+
+ void set_current(int p_current);
+ int get_current() const;
+
+
+ int get_item_count() const;
+ void remove_item(int p_idx);
+
+ void clear();
+
+ void set_fixed_column_width(int p_size);
+ int get_fixed_column_width() const;
+
+ void set_max_text_lines(int p_amount);
+ int get_max_text_lines() const;
+
+ void set_max_columns(int p_amount);
+ int get_max_columns() const;
+
+ void set_select_mode(SelectMode p_mode);
+ SelectMode get_select_mode() const;
+
+ void set_icon_mode(IconMode p_mode);
+ IconMode get_icon_mode() const;
+
+ void set_min_icon_size(const Size2& p_size);
+ Size2 get_min_icon_size() const;
+
+ void ensure_current_is_visible();
+
+
+ virtual String get_tooltip(const Point2& p_pos) const;
+
+ ItemList();
+ ~ItemList();
+};
+
+VARIANT_ENUM_CAST(ItemList::SelectMode);
+VARIANT_ENUM_CAST(ItemList::IconMode);
+
+
+#endif // ITEMLIST_H
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 987a2ed800..7a607786ee 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -58,7 +58,7 @@ RichTextLabel::Item *RichTextLabel::_get_next_item(Item* p_item) {
}
-void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p_mode,const Ref<Font> &p_base_font,const Color &p_base_color,const Point2i& p_click_pos,Item **r_click_item,int *r_click_char,bool *r_outside) {
+void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p_mode,const Ref<Font> &p_base_font,const Color &p_base_color,const Point2i& p_click_pos,Item **r_click_item,int *r_click_char,bool *r_outside,int p_char_count) {
RID ci;
if (r_outside)
@@ -80,6 +80,7 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p
int line=0;
int spaces=0;
+
if (p_mode!=PROCESS_CACHE) {
ERR_FAIL_INDEX(line,l.offset_caches.size());
@@ -89,6 +90,7 @@ void RichTextLabel::_process_line(int &y, int p_width, int p_line, ProcessMode p
if (p_mode==PROCESS_CACHE) {
l.offset_caches.clear();
l.height_caches.clear();
+ l.char_count=0;
}
int wofs=margin;
@@ -216,6 +218,8 @@ if (m_height > line_height) {\
underline=true;
}
+ } else if (p_mode==PROCESS_CACHE) {
+ l.char_count+=text->text.length();
}
rchar=0;
@@ -326,18 +330,23 @@ if (m_height > line_height) {\
}
}
- int cw;
+ int cw=0;
+
+ bool visible = visible_characters<0 || p_char_count<visible_characters;
if (selected) {
cw = font->get_char_size(c[i],c[i+1]).x;
draw_rect(Rect2(pofs,y,cw,lh),selection_bg);
- font->draw_char(ci,Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],selection_fg);
+ if (visible)
+ font->draw_char(ci,Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],selection_fg);
} else {
- cw=font->draw_char(ci,Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],color);
+ if (visible)
+ cw=font->draw_char(ci,Point2(pofs,y+lh-(fh-ascent)),c[i],c[i+1],color);
}
+ p_char_count++;
if (c[i]=='\t') {
cw=tab_size*font->get_char_size(' ').width;
}
@@ -371,6 +380,8 @@ if (m_height > line_height) {\
lh=0;
if (p_mode!=PROCESS_CACHE)
lh = line<l.height_caches.size()?l.height_caches[line]:1;
+ else
+ l.char_count+=1; //images count as chars too
ItemImage *img = static_cast<ItemImage*>(it);
@@ -383,9 +394,12 @@ if (m_height > line_height) {\
ENSURE_WIDTH( img->image->get_width() );
- if (p_mode==PROCESS_DRAW) {
+ bool visible = visible_characters<0 || p_char_count<visible_characters;
+
+ if (p_mode==PROCESS_DRAW && visible) {
img->image->draw(ci,Point2(wofs,y+lh-font->get_descent()-img->image->get_height()));
}
+ p_char_count++;
ADVANCE( img->image->get_width() );
CHECK_HEIGHT( (img->image->get_height()+font->get_descent()) );
@@ -556,11 +570,13 @@ void RichTextLabel::_notification(int p_what) {
//todo, change to binary search
int from_line = 0;
+ int total_chars = 0;
while (from_line<lines.size()) {
if (lines[from_line].height_accum_cache>=ofs)
break;
from_line++;
+ total_chars+=lines[from_line].char_count;
}
if (from_line>=lines.size())
@@ -572,7 +588,8 @@ void RichTextLabel::_notification(int p_what) {
while (y<size.height && from_line<lines.size()) {
- _process_line(y,size.width-scroll_w,from_line,PROCESS_DRAW,base_font,base_color);
+ _process_line(y,size.width-scroll_w,from_line,PROCESS_DRAW,base_font,base_color,Point2i(),NULL,NULL,NULL,total_chars);
+ total_chars+=lines[from_line].char_count;
from_line++;
}
}
@@ -1688,11 +1705,17 @@ void RichTextLabel::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_bbcode","text"),&RichTextLabel::set_bbcode);
ObjectTypeDB::bind_method(_MD("get_bbcode"),&RichTextLabel::get_bbcode);
+ ObjectTypeDB::bind_method(_MD("set_visible_characters","amount"),&RichTextLabel::set_visible_characters);
+ ObjectTypeDB::bind_method(_MD("get_visible_characters"),&RichTextLabel::get_visible_characters);
+
+ ObjectTypeDB::bind_method(_MD("get_total_character_count"),&RichTextLabel::get_total_character_count);
+
ObjectTypeDB::bind_method(_MD("set_use_bbcode","enable"),&RichTextLabel::set_use_bbcode);
ObjectTypeDB::bind_method(_MD("is_using_bbcode"),&RichTextLabel::is_using_bbcode);
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"bbcode/enabled"),_SCS("set_use_bbcode"),_SCS("is_using_bbcode"));
ADD_PROPERTY(PropertyInfo(Variant::STRING,"bbcode/bbcode",PROPERTY_HINT_MULTILINE_TEXT),_SCS("set_bbcode"),_SCS("get_bbcode"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"visible_characters",PROPERTY_HINT_RANGE,"-1,128000,1"),_SCS("set_visible_characters"),_SCS("get_visible_characters"));
ADD_SIGNAL( MethodInfo("meta_clicked",PropertyInfo(Variant::NIL,"meta")));
@@ -1719,6 +1742,27 @@ void RichTextLabel::_bind_methods() {
}
+
+void RichTextLabel::set_visible_characters(int p_visible) {
+
+ visible_characters=p_visible;
+ update();
+}
+
+int RichTextLabel::get_visible_characters() const {
+
+ return visible_characters;
+}
+int RichTextLabel::get_total_character_count() const {
+
+ int tc=0;
+ for(int i=0;i<lines.size();i++)
+ tc+=lines[i].char_count;
+
+ return tc;
+}
+
+
RichTextLabel::RichTextLabel() {
@@ -1756,6 +1800,8 @@ RichTextLabel::RichTextLabel() {
selection.active=false;
selection.enabled=false;
+ visible_characters=-1;
+
}
RichTextLabel::~RichTextLabel() {
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 7172e8e500..eaa8d5d60a 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -171,8 +171,9 @@ private:
Vector<int> space_caches;
int height_cache;
int height_accum_cache;
+ int char_count;
- Line() { from=NULL; }
+ Line() { from=NULL; char_count=0; }
};
@@ -223,10 +224,10 @@ private:
Selection selection;
+ int visible_characters;
-
- void _process_line(int &y, int p_width, int p_line, ProcessMode p_mode,const Ref<Font> &p_base_font,const Color &p_base_color,const Point2i& p_click_pos=Point2i(),Item **r_click_item=NULL,int *r_click_char=NULL,bool *r_outside=NULL);
+ void _process_line(int &y, int p_width, int p_line, ProcessMode p_mode,const Ref<Font> &p_base_font,const Color &p_base_color,const Point2i& p_click_pos=Point2i(),Item **r_click_item=NULL,int *r_click_char=NULL,bool *r_outside=NULL,int p_char_count=0);
void _find_click(const Point2i& p_click,Item **r_click_item=NULL,int *r_click_char=NULL,bool *r_outside=NULL);
@@ -246,6 +247,8 @@ private:
bool use_bbcode;
String bbcode;
+
+
protected:
void _notification(int p_what);
@@ -304,6 +307,10 @@ public:
void set_bbcode(const String& p_bbcode);
String get_bbcode() const;
+ void set_visible_characters(int p_visible);
+ int get_visible_characters() const;
+ int get_total_character_count() const;
+
RichTextLabel();
~RichTextLabel();
};
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 0c15f99509..c497bc5363 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -3601,6 +3601,10 @@ TextEdit::TextEdit() {
set_focus_mode(FOCUS_ALL);
_update_caches();
cache.size=Size2(1,1);
+ cache.row_height=1;
+ cache.line_spacing=1;
+ cache.line_number_w=1;
+
tab_size=4;
text.set_tab_size(tab_size);
text.clear();
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 687410d192..717ed93b16 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -66,6 +66,7 @@
#include "scene/gui/file_dialog.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/tree.h"
+#include "scene/gui/item_list.h"
#include "scene/gui/text_edit.h"
#include "scene/gui/texture_button.h"
#include "scene/gui/separator.h"
@@ -170,6 +171,7 @@
#include "scene/resources/audio_stream.h"
#include "scene/resources/gibberish_stream.h"
#include "scene/resources/bit_mask.h"
+#include "scene/resources/color_ramp.h"
#include "scene/scene_string_names.h"
@@ -327,7 +329,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<HButtonArray>();
ObjectTypeDB::register_type<VButtonArray>();
ObjectTypeDB::register_type<TextureProgress>();
-
+ ObjectTypeDB::register_type<ItemList>();
#ifndef ADVANCED_GUI_DISABLED
@@ -335,6 +337,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<LineEdit>();
ObjectTypeDB::register_type<PopupMenu>();
ObjectTypeDB::register_type<Tree>();
+
ObjectTypeDB::register_type<TextEdit>();
ObjectTypeDB::register_virtual_type<TreeItem>();
@@ -565,6 +568,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<PolygonPathFinder>();
ObjectTypeDB::register_type<BitMap>();
+ ObjectTypeDB::register_type<ColorRamp>();
OS::get_singleton()->yield(); //may take time to init
diff --git a/scene/resources/audio_stream_resampled.cpp b/scene/resources/audio_stream_resampled.cpp
index 506b34fbf6..6317780bd3 100644
--- a/scene/resources/audio_stream_resampled.cpp
+++ b/scene/resources/audio_stream_resampled.cpp
@@ -230,6 +230,51 @@ bool AudioStreamResampled::mix(int32_t *p_dest, int p_frames) {
case 4: read=_resample<4>(p_dest,todo,increment); break;
case 6: read=_resample<6>(p_dest,todo,increment); break;
}
+#if 1
+ //end of stream, fadeout
+ int remaining = p_frames-todo;
+ if (remaining && todo>0) {
+
+ //print_line("fadeout");
+ for(int c=0;c<channels;c++) {
+
+ for(int i=0;i<todo;i++) {
+
+ int32_t samp = p_dest[i*channels+c]>>8;
+ uint32_t mul = (todo-i) * 256 /todo;
+ //print_line("mul: "+itos(i)+" "+itos(mul));
+ p_dest[i*channels+c]=samp*mul;
+ }
+
+ }
+
+ }
+
+#else
+ int remaining = p_frames-todo;
+ if (remaining && todo>0) {
+
+
+ for(int c=0;c<channels;c++) {
+
+ int32_t from = p_dest[(todo-1)*channels+c]>>8;
+
+ for(int i=0;i<remaining;i++) {
+
+ uint32_t mul = (remaining-i) * 256 /remaining;
+ p_dest[(todo+i)*channels+c]=from*mul;
+ }
+
+ }
+
+ }
+#endif
+
+ //zero out what remains there to avoid glitches
+ for(int i=todo*channels;i<int(p_frames)*channels;i++) {
+
+ p_dest[i]=0;
+ }
if (read>rb_todo)
read=rb_todo;
@@ -316,6 +361,16 @@ AudioStreamResampled::AudioStreamResampled() {
rb=NULL;
offset=0;
read_buf=NULL;
+ rb_read_pos=0;
+ rb_write_pos=0;
+
+ rb_bits=0;
+ rb_len=0;
+ rb_mask=0;
+ read_buff_len=0;
+ channels=0;
+ mix_rate=0;
+
}
AudioStreamResampled::~AudioStreamResampled() {
diff --git a/scene/resources/color_ramp.cpp b/scene/resources/color_ramp.cpp
new file mode 100644
index 0000000000..97d3fafd58
--- /dev/null
+++ b/scene/resources/color_ramp.cpp
@@ -0,0 +1,117 @@
+/*
+ * color_ramp.h
+ */
+
+#include "color_ramp.h"
+
+//setter and getter names for property serialization
+#define COLOR_RAMP_GET_OFFSETS "get_offsets"
+#define COLOR_RAMP_GET_COLORS "get_colors"
+#define COLOR_RAMP_SET_OFFSETS "set_offsets"
+#define COLOR_RAMP_SET_COLORS "set_colors"
+
+ColorRamp::ColorRamp() {
+ //Set initial color ramp transition from black to white
+ points.resize(2);
+ points[0].color = Color(0,0,0,1);
+ points[0].offset = 0;
+ points[1].color = Color(1,1,1,1);
+ points[1].offset = 1;
+ is_sorted = true;
+}
+
+ColorRamp::~ColorRamp() {
+
+}
+
+void ColorRamp::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD(COLOR_RAMP_SET_OFFSETS,"offsets"),&ColorRamp::set_offsets);
+ ObjectTypeDB::bind_method(_MD(COLOR_RAMP_GET_OFFSETS),&ColorRamp::get_offsets);
+
+ ObjectTypeDB::bind_method(_MD(COLOR_RAMP_SET_COLORS,"colors"),&ColorRamp::set_colors);
+ ObjectTypeDB::bind_method(_MD(COLOR_RAMP_GET_COLORS),&ColorRamp::get_colors);
+
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"offsets"),_SCS(COLOR_RAMP_SET_OFFSETS),_SCS(COLOR_RAMP_GET_OFFSETS) );
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"colors"),_SCS(COLOR_RAMP_SET_COLORS),_SCS(COLOR_RAMP_GET_COLORS) );
+}
+
+Vector<float> ColorRamp::get_offsets() const {
+ Vector<float> offsets;
+ offsets.resize(points.size());
+ for(int i = 0; i < points.size(); i++)
+ {
+ offsets[i] = points[i].offset;
+ }
+ return offsets;
+}
+
+Vector<Color> ColorRamp::get_colors() const {
+ Vector<Color> colors;
+ colors.resize(points.size());
+ for(int i = 0; i < points.size(); i++)
+ {
+ colors[i] = points[i].color;
+ }
+ return colors;
+}
+
+void ColorRamp::set_offsets(const Vector<float>& p_offsets) {
+ points.resize(p_offsets.size());
+ for(int i = 0; i < points.size(); i++)
+ {
+ points[i].offset = p_offsets[i];
+ }
+ is_sorted = false;
+}
+
+void ColorRamp::set_colors(const Vector<Color>& p_colors) {
+ if(points.size()<p_colors.size())
+ is_sorted = false;
+ points.resize(p_colors.size());
+ for(int i = 0; i < points.size(); i++)
+ {
+ points[i].color = p_colors[i];
+ }
+}
+
+Vector<ColorRamp::Point>& ColorRamp::get_points() {
+ return points;
+}
+
+void ColorRamp::set_points(Vector<ColorRamp::Point>& p_points) {
+ points = p_points;
+ is_sorted = false;
+}
+
+void ColorRamp::set_offset(int pos, const float offset) {
+ if(points.size() <= pos)
+ points.resize(pos + 1);
+ points[pos].offset = offset;
+ is_sorted = false;
+}
+
+float ColorRamp::get_offset(int pos) const {
+ if(points.size() > pos)
+ return points[pos].offset;
+ return 0; //TODO: Maybe throw some error instead?
+}
+
+void ColorRamp::set_color(int pos, const Color& color) {
+ if(points.size() <= pos)
+ {
+ points.resize(pos + 1);
+ is_sorted = false;
+ }
+ points[pos].color = color;
+}
+
+Color ColorRamp::get_color(int pos) const {
+ if(points.size() > pos)
+ return points[pos].color;
+ return Color(0,0,0,1); //TODO: Maybe throw some error instead?
+}
+
+int ColorRamp::get_points_count() const {
+ return points.size();
+}
diff --git a/scene/resources/color_ramp.h b/scene/resources/color_ramp.h
new file mode 100644
index 0000000000..8f6ba2c3e5
--- /dev/null
+++ b/scene/resources/color_ramp.h
@@ -0,0 +1,98 @@
+/*
+ * color_ramp.h
+ */
+
+#ifndef SCENE_RESOURCES_COLOR_RAMP_H_
+#define SCENE_RESOURCES_COLOR_RAMP_H_
+
+#include "resource.h"
+
+class ColorRamp: public Resource {
+ OBJ_TYPE( ColorRamp, Resource );
+ OBJ_SAVE_TYPE( ColorRamp );
+
+public:
+ struct Point {
+
+ float offset;
+ Color color;
+ bool operator<(const Point& p_ponit) const {
+ return offset<p_ponit.offset;
+ }
+ };
+
+private:
+ Vector<Point> points;
+ bool is_sorted;
+
+protected:
+ static void _bind_methods();
+
+public:
+ ColorRamp();
+ virtual ~ColorRamp();
+
+ void set_points(Vector<Point>& points);
+ Vector<Point>& get_points();
+
+ void set_offset(int pos, const float offset);
+ float get_offset(int pos) const;
+
+ void set_color(int pos, const Color& color);
+ Color get_color(int pos) const;
+
+ void set_offsets(const Vector<float>& offsets);
+ Vector<float> get_offsets() const;
+
+ void set_colors(const Vector<Color>& colors);
+ Vector<Color> get_colors() const;
+
+ _FORCE_INLINE_ Color get_color_at_offset(float p_offset) {
+
+ if (points.empty())
+ return Color(0,0,0,1);
+
+ if(!is_sorted)
+ {
+ points.sort();
+ is_sorted = true;
+ }
+
+ //binary search
+ int low = 0;
+ int high = points.size() -1;
+ int middle;
+
+ while( low <= high )
+ {
+ middle = ( low + high ) / 2;
+ Point& point = points[middle];
+ if( point.offset > p_offset ) {
+ high = middle - 1; //search low end of array
+ } else if ( point.offset < p_offset) {
+ low = middle + 1; //search high end of array
+ } else {
+ return point.color;
+ }
+ }
+
+ //return interpolated value
+ if (points[middle].offset>p_offset)
+ {
+ middle--;
+ }
+ int first=middle;
+ int second=middle+1;
+ if(second>=points.size())
+ return points[points.size()-1].color;
+ if(first<0)
+ return points[0].color;
+ Point& pointFirst = points[first];
+ Point& pointSecond = points[second];
+ return pointFirst.color.linear_interpolate(pointSecond.color, (p_offset-pointFirst.offset)/(pointSecond.offset - pointFirst.offset));
+ }
+
+ int get_points_count() const;
+};
+
+#endif /* SCENE_RESOURCES_COLOR_RAMP_H_ */
diff --git a/scene/resources/default_theme/checker_bg.png b/scene/resources/default_theme/checker_bg.png
new file mode 100644
index 0000000000..0674f9da26
--- /dev/null
+++ b/scene/resources/default_theme/checker_bg.png
Binary files differ
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 2fddafc07b..62fa01f587 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -574,7 +574,7 @@ void make_default_theme() {
// Tree
Ref<StyleBoxTexture> tree_selected = make_stylebox( selection_png,4,4,4,4,8,0,8,0);
- Ref<StyleBoxTexture> tree_selected_oof = make_stylebox( selection_oof_png,4,4,4,4,8,0,8,0);
+ Ref<StyleBoxTexture> tree_selected_oof = make_stylebox( selection_oof_png,4,4,4,4,8,0,8,0);
t->set_stylebox("bg","Tree", make_stylebox( tree_bg_png,4,4,4,5) );
t->set_stylebox("bg_focus","Tree", focus );
@@ -605,12 +605,31 @@ void make_default_theme() {
t->set_color("guide_color","Tree", Color(0,0,0,0.1) );
t->set_constant("hseparation","Tree",4);
- t->set_constant("vseparation","Tree",2);
+ t->set_constant("vseparation","Tree",4);
t->set_constant("guide_width","Tree",2);
t->set_constant("item_margin","Tree",12);
t->set_constant("button_margin","Tree",4);
+ // ItemList
+ Ref<StyleBoxTexture> item_selected = make_stylebox( selection_png,4,4,4,4,8,2,8,2);
+ Ref<StyleBoxTexture> item_selected_oof = make_stylebox( selection_oof_png,4,4,4,4,8,2,8,2);
+
+ t->set_stylebox("bg","ItemList", make_stylebox( tree_bg_png,4,4,4,5) );
+ t->set_stylebox("bg_focus","ItemList", focus );
+ t->set_constant("hseparation","ItemList",4);
+ t->set_constant("vseparation","ItemList",2);
+ t->set_constant("icon_margin","ItemList",4);
+ t->set_constant("line_separation","ItemList",2);
+ t->set_font("font","ItemList", default_font );
+ t->set_color("font_color","ItemList", control_font_color_low );
+ t->set_color("font_color_selected","ItemList", control_font_color_pressed );
+ t->set_color("guide_color","ItemList", Color(0,0,0,0.1) );
+ t->set_stylebox("selected","ItemList", item_selected_oof );
+ t->set_stylebox("selected_focus","ItemList", item_selected );
+ t->set_stylebox("cursor","ItemList", focus );
+ t->set_stylebox("cursor_unfocused","ItemList", focus );
+
// TextEdit
@@ -692,7 +711,6 @@ void make_default_theme() {
// FileDialog
t->set_icon("folder","FileDialog",make_icon(icon_folder_png));
-
t->set_color("files_disabled","FileDialog",Color(0,0,0,0.7));
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index 78e210239d..8bd0a66271 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -49,6 +49,11 @@ static const unsigned char checked_png[]={
};
+static const unsigned char checker_bg_png[]={
+0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x8,0x8,0x6,0x0,0x0,0x0,0xc4,0xf,0xbe,0x8b,0x0,0x0,0x0,0x1,0x73,0x52,0x47,0x42,0x0,0xae,0xce,0x1c,0xe9,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1,0x8f,0xb,0xfc,0x61,0x5,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xe,0xc4,0x0,0x0,0xe,0xc4,0x1,0x95,0x2b,0xe,0x1b,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0x9,0x14,0xd,0x1c,0x1b,0x52,0x41,0x72,0xa4,0x0,0x0,0x0,0x24,0x49,0x44,0x41,0x54,0x28,0x53,0x63,0xfc,0xf,0x4,0xc,0x48,0xa0,0xa1,0xa1,0x1,0xca,0x82,0x0,0x26,0x28,0x8d,0x13,0x50,0xae,0x80,0xb1,0xbe,0xbe,0x7e,0x60,0xdd,0xc0,0xc0,0x0,0x0,0x78,0x11,0x9,0x87,0x2b,0xa,0xe1,0x69,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
+};
+
+
static const unsigned char close_png[]={
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x73,0x0,0x29,0x0,0x7c,0x29,0x1e,0x61,0x18,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdd,0x9,0x19,0x1,0x14,0x3,0xf4,0x10,0x33,0xed,0x0,0x0,0x1,0x53,0x49,0x44,0x41,0x54,0x38,0xcb,0xcd,0x92,0xbd,0x4e,0x5b,0x41,0x10,0x85,0xbf,0xd9,0x9d,0xfd,0xb9,0xd7,0xb2,0xb9,0x81,0x8e,0x26,0xf4,0x69,0x53,0x50,0x44,0xa2,0x74,0x3,0xd,0xd,0x48,0x48,0xf4,0x3c,0x16,0x8f,0xc1,0x23,0xf0,0x0,0xf4,0x8e,0x90,0x11,0x96,0x25,0xa2,0x10,0x45,0x4a,0x9c,0x6b,0x4f,0xa,0xf6,0x4a,0xe6,0xc6,0x4e,0xb,0x47,0x5a,0xed,0xee,0x9c,0xd9,0xd1,0x99,0xb3,0x3,0x6f,0xd,0xd9,0x70,0xd7,0x72,0xfe,0xd3,0xe3,0x42,0xd9,0x5b,0xc0,0xba,0xa0,0xef,0x3d,0xfe,0xe0,0x9c,0x3b,0x35,0xb3,0x21,0xf0,0x1d,0xf8,0x5d,0xe2,0xd,0xf0,0xd9,0x39,0xf7,0xc5,0xcc,0xee,0x81,0x5f,0x9b,0xd4,0x4,0xe7,0xdc,0x65,0xd3,0x34,0x3f,0x53,0x4a,0x73,0xe0,0x18,0xd8,0x2b,0xeb,0x78,0x38,0x1c,0x3e,0xe5,0x9c,0x7f,0x38,0xe7,0x2e,0xd7,0xd4,0xfc,0x23,0xf1,0x30,0xc6,0x38,0x4b,0x29,0x59,0x8,0xe1,0x1e,0xb8,0x0,0x2e,0xea,0xba,0x7e,0xa8,0xaa,0xca,0x42,0x8,0x33,0xe0,0x70,0x5b,0x1,0x80,0x1d,0x60,0xac,0xaa,0x93,0x9c,0xb3,0xa9,0xea,0x63,0x8c,0x71,0x36,0x18,0xc,0x4c,0x55,0x27,0xc0,0xb8,0xe4,0xfc,0xd7,0xd4,0x5d,0xe0,0x5c,0x55,0xa7,0x39,0x67,0xcb,0x39,0x9b,0xf7,0x7e,0xa,0x9c,0x17,0xee,0x95,0xf1,0xba,0xa5,0x90,0x17,0x11,0x6f,0xf6,0x62,0xb6,0x88,0xb8,0x9e,0xe1,0x5b,0xd1,0x0,0x27,0x75,0x5d,0x3f,0x14,0xd9,0xd3,0x4e,0x49,0xf1,0xe4,0xa4,0xe4,0x6c,0x44,0x10,0x91,0xa3,0xd1,0x68,0xf4,0x54,0x55,0x55,0xd7,0xf3,0x19,0x70,0xa6,0xaa,0x93,0x94,0x92,0xc5,0x18,0xe7,0x22,0x72,0xb4,0x6e,0xe2,0xab,0x16,0xbc,0xf7,0x7,0x8b,0xc5,0x42,0x97,0xcb,0xe5,0xbc,0x6d,0xdb,0x2b,0xe0,0x16,0xa0,0x6d,0xdb,0x67,0xe7,0xdc,0xb5,0x88,0x24,0x11,0xd9,0xef,0x5a,0xeb,0x4f,0x62,0x37,0x48,0xe3,0xd5,0x6a,0xf5,0x15,0xb8,0x3,0x9e,0xb,0x37,0x2,0x3e,0x89,0xc8,0x47,0x33,0xbb,0x1,0xbe,0xad,0x4f,0x63,0xff,0x17,0xc2,0x16,0x73,0xb5,0x70,0xc2,0xbb,0xc2,0x5f,0x47,0xa5,0x56,0x8a,0x30,0xdd,0x7d,0xae,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
};
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index 862669ecd8..90598ee789 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -36,7 +36,7 @@
Shader::Mode Shader::get_mode() const {
- return (Mode)VisualServer::get_singleton()->shader_get_mode(shader);
+ return mode;
}
void Shader::set_code( const String& p_vertex, const String& p_fragment, const String& p_light,int p_fragment_ofs,int p_light_ofs) {
@@ -203,6 +203,7 @@ void Shader::_bind_methods() {
Shader::Shader(Mode p_mode) {
+ mode=p_mode;
shader = VisualServer::get_singleton()->shader_create(VS::ShaderMode(p_mode));
params_cache_dirty=true;
}
diff --git a/scene/resources/shader.h b/scene/resources/shader.h
index c5ef3777f7..b805cbec96 100644
--- a/scene/resources/shader.h
+++ b/scene/resources/shader.h
@@ -37,8 +37,18 @@ class Shader : public Resource {
OBJ_TYPE(Shader,Resource);
OBJ_SAVE_TYPE( Shader );
RES_BASE_EXTENSION("shd");
- RID shader;
+public:
+ enum Mode {
+
+ MODE_MATERIAL,
+ MODE_CANVAS_ITEM,
+ MODE_POST_PROCESS,
+ MODE_MAX
+ };
+private:
+ RID shader;
+ Mode mode;
Dictionary _get_code();
void _set_code(const Dictionary& p_string);
@@ -55,15 +65,10 @@ class Shader : public Resource {
protected:
+
static void _bind_methods();
public:
- enum Mode {
- MODE_MATERIAL,
- MODE_CANVAS_ITEM,
- MODE_POST_PROCESS,
- MODE_MAX
- };
//void set_mode(Mode p_mode);
Mode get_mode() const;
diff --git a/servers/physics/area_sw.cpp b/servers/physics/area_sw.cpp
index de241c948b..aa1c530221 100644
--- a/servers/physics/area_sw.cpp
+++ b/servers/physics/area_sw.cpp
@@ -98,6 +98,7 @@ void AreaSW::set_param(PhysicsServer::AreaParameter p_param, const Variant& p_va
case PhysicsServer::AREA_PARAM_GRAVITY: gravity=p_value; ; break;
case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR: gravity_vector=p_value; ; break;
case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT: gravity_is_point=p_value; ; break;
+ case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE: gravity_distance_scale=p_value; ; break;
case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: point_attenuation=p_value; ; break;
case PhysicsServer::AREA_PARAM_DENSITY: density=p_value; ; break;
case PhysicsServer::AREA_PARAM_PRIORITY: priority=p_value; ; break;
@@ -113,6 +114,7 @@ Variant AreaSW::get_param(PhysicsServer::AreaParameter p_param) const {
case PhysicsServer::AREA_PARAM_GRAVITY: return gravity;
case PhysicsServer::AREA_PARAM_GRAVITY_VECTOR: return gravity_vector;
case PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT: return gravity_is_point;
+ case PhysicsServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE: return gravity_distance_scale;
case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: return point_attenuation;
case PhysicsServer::AREA_PARAM_DENSITY: return density;
case PhysicsServer::AREA_PARAM_PRIORITY: return priority;
@@ -177,6 +179,7 @@ AreaSW::AreaSW() : CollisionObjectSW(TYPE_AREA), monitor_query_list(this), move
gravity=9.80665;
gravity_vector=Vector3(0,-1,0);
gravity_is_point=false;
+ gravity_distance_scale=0;
point_attenuation=1;
density=0.1;
priority=0;
diff --git a/servers/physics/area_sw.h b/servers/physics/area_sw.h
index 87843b93c9..a875472f6b 100644
--- a/servers/physics/area_sw.h
+++ b/servers/physics/area_sw.h
@@ -45,6 +45,7 @@ class AreaSW : public CollisionObjectSW{
float gravity;
Vector3 gravity_vector;
bool gravity_is_point;
+ float gravity_distance_scale;
float point_attenuation;
float density;
int priority;
@@ -125,6 +126,9 @@ public:
_FORCE_INLINE_ void set_gravity_as_point(bool p_enable) { gravity_is_point=p_enable; }
_FORCE_INLINE_ bool is_gravity_point() const { return gravity_is_point; }
+ _FORCE_INLINE_ void set_gravity_distance_scale(float scale) { gravity_distance_scale=scale; }
+ _FORCE_INLINE_ float get_gravity_distance_scale() const { return gravity_distance_scale; }
+
_FORCE_INLINE_ void set_point_attenuation(float p_point_attenuation) { point_attenuation=p_point_attenuation; }
_FORCE_INLINE_ float get_point_attenuation() const { return point_attenuation; }
diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp
index 1cc0b763a4..5a528ecf94 100644
--- a/servers/physics/body_sw.cpp
+++ b/servers/physics/body_sw.cpp
@@ -362,9 +362,12 @@ void BodySW::set_space(SpaceSW *p_space){
void BodySW::_compute_area_gravity(const AreaSW *p_area) {
if (p_area->is_gravity_point()) {
-
- gravity += (p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin()).normalized() * p_area->get_gravity();
-
+ if(p_area->get_gravity_distance_scale() > 0) {
+ Vector3 v = p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin();
+ gravity += v.normalized() * (p_area->get_gravity() / Math::pow(v.length() * p_area->get_gravity_distance_scale()+1, 2) );
+ } else {
+ gravity += (p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin()).normalized() * p_area->get_gravity();
+ }
} else {
gravity += p_area->get_gravity_vector() * p_area->get_gravity();
}
diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp
index dad1891b77..1a41cda482 100644
--- a/servers/physics_2d/area_2d_sw.cpp
+++ b/servers/physics_2d/area_2d_sw.cpp
@@ -120,6 +120,7 @@ void Area2DSW::set_param(Physics2DServer::AreaParameter p_param, const Variant&
case Physics2DServer::AREA_PARAM_GRAVITY: gravity=p_value; ; break;
case Physics2DServer::AREA_PARAM_GRAVITY_VECTOR: gravity_vector=p_value; ; break;
case Physics2DServer::AREA_PARAM_GRAVITY_IS_POINT: gravity_is_point=p_value; ; break;
+ case Physics2DServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE: gravity_distance_scale=p_value; ; break;
case Physics2DServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: point_attenuation=p_value; ; break;
case Physics2DServer::AREA_PARAM_LINEAR_DAMP: linear_damp=p_value; ; break;
case Physics2DServer::AREA_PARAM_ANGULAR_DAMP: angular_damp=p_value; ; break;
@@ -136,6 +137,7 @@ Variant Area2DSW::get_param(Physics2DServer::AreaParameter p_param) const {
case Physics2DServer::AREA_PARAM_GRAVITY: return gravity;
case Physics2DServer::AREA_PARAM_GRAVITY_VECTOR: return gravity_vector;
case Physics2DServer::AREA_PARAM_GRAVITY_IS_POINT: return gravity_is_point;
+ case Physics2DServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE: return gravity_distance_scale;
case Physics2DServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: return point_attenuation;
case Physics2DServer::AREA_PARAM_LINEAR_DAMP: return linear_damp;
case Physics2DServer::AREA_PARAM_ANGULAR_DAMP: return angular_damp;
@@ -248,6 +250,7 @@ Area2DSW::Area2DSW() : CollisionObject2DSW(TYPE_AREA), monitor_query_list(this),
gravity=9.80665;
gravity_vector=Vector2(0,-1);
gravity_is_point=false;
+ gravity_distance_scale=0;
point_attenuation=1;
angular_damp=1.0;
diff --git a/servers/physics_2d/area_2d_sw.h b/servers/physics_2d/area_2d_sw.h
index 4a54a337ed..6d99764c68 100644
--- a/servers/physics_2d/area_2d_sw.h
+++ b/servers/physics_2d/area_2d_sw.h
@@ -46,6 +46,7 @@ class Area2DSW : public CollisionObject2DSW{
float gravity;
Vector2 gravity_vector;
bool gravity_is_point;
+ float gravity_distance_scale;
float point_attenuation;
float linear_damp;
float angular_damp;
@@ -139,6 +140,9 @@ public:
_FORCE_INLINE_ void set_gravity_as_point(bool p_enable) { gravity_is_point=p_enable; }
_FORCE_INLINE_ bool is_gravity_point() const { return gravity_is_point; }
+ _FORCE_INLINE_ void set_gravity_distance_scale(float scale) { gravity_distance_scale=scale; }
+ _FORCE_INLINE_ float get_gravity_distance_scale() const { return gravity_distance_scale; }
+
_FORCE_INLINE_ void set_point_attenuation(float p_point_attenuation) { point_attenuation=p_point_attenuation; }
_FORCE_INLINE_ float get_point_attenuation() const { return point_attenuation; }
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index ccce058f13..38835c9a82 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -383,9 +383,12 @@ void Body2DSW::set_space(Space2DSW *p_space){
void Body2DSW::_compute_area_gravity(const Area2DSW *p_area) {
if (p_area->is_gravity_point()) {
-
- gravity += (p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin()).normalized() * p_area->get_gravity();
-
+ if(p_area->get_gravity_distance_scale() > 0) {
+ Vector2 v = p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin();
+ gravity += v.normalized() * (p_area->get_gravity() / Math::pow(v.length() * p_area->get_gravity_distance_scale()+1, 2) );
+ } else {
+ gravity += (p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin()).normalized() * p_area->get_gravity();
+ }
} else {
gravity += p_area->get_gravity_vector() * p_area->get_gravity();
}
diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp
index c2ad7b2165..b9d15d6e35 100644
--- a/servers/physics_2d_server.cpp
+++ b/servers/physics_2d_server.cpp
@@ -657,6 +657,7 @@ void Physics2DServer::_bind_methods() {
BIND_CONSTANT( AREA_PARAM_GRAVITY );
BIND_CONSTANT( AREA_PARAM_GRAVITY_VECTOR );
BIND_CONSTANT( AREA_PARAM_GRAVITY_IS_POINT );
+ BIND_CONSTANT( AREA_PARAM_GRAVITY_DISTANCE_SCALE );
BIND_CONSTANT( AREA_PARAM_GRAVITY_POINT_ATTENUATION );
BIND_CONSTANT( AREA_PARAM_LINEAR_DAMP);
BIND_CONSTANT( AREA_PARAM_ANGULAR_DAMP);
diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h
index 9922d2e345..b24496880e 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -306,6 +306,7 @@ public:
AREA_PARAM_GRAVITY,
AREA_PARAM_GRAVITY_VECTOR,
AREA_PARAM_GRAVITY_IS_POINT,
+ AREA_PARAM_GRAVITY_DISTANCE_SCALE,
AREA_PARAM_GRAVITY_POINT_ATTENUATION,
AREA_PARAM_LINEAR_DAMP,
AREA_PARAM_ANGULAR_DAMP,
diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp
index 4feb1b5269..e02601af41 100644
--- a/servers/physics_server.cpp
+++ b/servers/physics_server.cpp
@@ -681,6 +681,7 @@ void PhysicsServer::_bind_methods() {
BIND_CONSTANT( AREA_PARAM_GRAVITY );
BIND_CONSTANT( AREA_PARAM_GRAVITY_VECTOR );
BIND_CONSTANT( AREA_PARAM_GRAVITY_IS_POINT );
+ BIND_CONSTANT( AREA_PARAM_GRAVITY_DISTANCE_SCALE );
BIND_CONSTANT( AREA_PARAM_GRAVITY_POINT_ATTENUATION );
BIND_CONSTANT( AREA_PARAM_DENSITY );
BIND_CONSTANT( AREA_PARAM_PRIORITY );
diff --git a/servers/physics_server.h b/servers/physics_server.h
index ffb462af22..05b64da804 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -298,6 +298,7 @@ public:
AREA_PARAM_GRAVITY,
AREA_PARAM_GRAVITY_VECTOR,
AREA_PARAM_GRAVITY_IS_POINT,
+ AREA_PARAM_GRAVITY_DISTANCE_SCALE,
AREA_PARAM_GRAVITY_POINT_ATTENUATION,
AREA_PARAM_DENSITY,
AREA_PARAM_PRIORITY
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index a547da9b61..52e5c21272 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -7358,7 +7358,7 @@ void VisualServerRaster::_draw_cursors_and_margins() {
rasterizer->canvas_end_rect();
};
-void VisualServerRaster::flush() {
+void VisualServerRaster::sync() {
//do none
}
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index f3b94b73df..e2940c216b 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -1237,7 +1237,7 @@ public:
/* EVENT QUEUING */
virtual void draw();
- virtual void flush();
+ virtual void sync();
virtual void init();
virtual void finish();
diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp
index 44a41a93da..19dff3d36c 100644
--- a/servers/visual/visual_server_wrap_mt.cpp
+++ b/servers/visual/visual_server_wrap_mt.cpp
@@ -96,16 +96,19 @@ void VisualServerWrapMT::thread_loop() {
/* EVENT QUEUING */
-void VisualServerWrapMT::flush() {
+void VisualServerWrapMT::sync() {
if (create_thread) {
+ /* TODO: sync with the thread */
+
+ /*
ERR_FAIL_COND(!draw_mutex);
draw_mutex->lock();
draw_pending++; //cambiar por un saferefcount
draw_mutex->unlock();
-
- command_queue.push( this, &VisualServerWrapMT::thread_flush);
+ */
+ //command_queue.push( this, &VisualServerWrapMT::thread_flush);
} else {
command_queue.flush_all(); //flush all pending from other threads
@@ -118,15 +121,16 @@ void VisualServerWrapMT::draw() {
if (create_thread) {
+ /* TODO: Make it draw
ERR_FAIL_COND(!draw_mutex);
draw_mutex->lock();
draw_pending++; //cambiar por un saferefcount
draw_mutex->unlock();
command_queue.push( this, &VisualServerWrapMT::thread_draw);
+ */
} else {
- command_queue.flush_all(); //flush all pending from other threads
visual_server->draw();
}
}
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index d07e1940d7..6719342a6a 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -681,7 +681,7 @@ public:
virtual void init();
virtual void finish();
virtual void draw();
- virtual void flush();
+ virtual void sync();
FUNC0RC(bool,has_changed);
/* RENDER INFO */
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 78320f277e..25e6a68469 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -554,7 +554,7 @@ void VisualServer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("mesh_add_surface_from_planes"),&VisualServer::mesh_add_surface_from_planes);
ObjectTypeDB::bind_method(_MD("draw"),&VisualServer::draw);
- ObjectTypeDB::bind_method(_MD("flush"),&VisualServer::flush);
+ ObjectTypeDB::bind_method(_MD("sync"),&VisualServer::sync);
ObjectTypeDB::bind_method(_MD("free"),&VisualServer::free);
ObjectTypeDB::bind_method(_MD("set_default_clear_color"),&VisualServer::set_default_clear_color);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index c1c2ef4fd3..ef63907e34 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -1097,7 +1097,7 @@ public:
/* EVENT QUEUING */
virtual void draw()=0;
- virtual void flush()=0;
+ virtual void sync()=0;
virtual bool has_changed() const=0;
virtual void init()=0;
virtual void finish()=0;
diff --git a/tools/editor/editor_dir_dialog.cpp b/tools/editor/editor_dir_dialog.cpp
index 5e6bad41aa..a8421acff8 100644
--- a/tools/editor/editor_dir_dialog.cpp
+++ b/tools/editor/editor_dir_dialog.cpp
@@ -43,6 +43,7 @@ void EditorDirDialog::_update_dir(TreeItem* p_item) {
da->list_dir_begin();
String p=da->get_next();
+ List<String> dirs;
bool ishidden;
bool show_hidden = EditorSettings::get_singleton()->get("file_dialog/show_hidden_files");
@@ -52,16 +53,22 @@ void EditorDirDialog::_update_dir(TreeItem* p_item) {
if (show_hidden || !ishidden) {
if (da->current_is_dir() && !p.begins_with(".")) {
- TreeItem *ti = tree->create_item(p_item);
- ti->set_text(0,p);
- ti->set_icon(0,get_icon("Folder","EditorIcons"));
- ti->set_collapsed(true);
+ 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;
diff --git a/tools/editor/editor_file_dialog.cpp b/tools/editor/editor_file_dialog.cpp
new file mode 100644
index 0000000000..b1bbd71f7b
--- /dev/null
+++ b/tools/editor/editor_file_dialog.cpp
@@ -0,0 +1,1366 @@
+#include "editor_file_dialog.h"
+#include "scene/gui/label.h"
+#include "scene/gui/center_container.h"
+#include "print_string.h"
+#include "os/keyboard.h"
+#include "editor_resource_preview.h"
+#include "editor_settings.h"
+#include "scene/gui/margin_container.h"
+EditorFileDialog::GetIconFunc EditorFileDialog::get_icon_func=NULL;
+EditorFileDialog::GetIconFunc EditorFileDialog::get_large_icon_func=NULL;
+
+EditorFileDialog::RegisterFunc EditorFileDialog::register_func=NULL;
+EditorFileDialog::RegisterFunc EditorFileDialog::unregister_func=NULL;
+
+
+VBoxContainer *EditorFileDialog::get_vbox() {
+ return vbox;
+
+}
+
+void EditorFileDialog::_notification(int p_what) {
+
+ if (p_what==NOTIFICATION_ENTER_TREE) {
+
+ mode_thumbnails->set_icon(get_icon("FileThumbnail","EditorIcons"));
+ mode_list->set_icon(get_icon("FileList","EditorIcons"));
+ dir_prev->set_icon(get_icon("ArrowLeft","EditorIcons"));
+ dir_next->set_icon(get_icon("ArrowRight","EditorIcons"));
+ dir_up->set_icon(get_icon("ArrowUp","EditorIcons"));
+ favorite->set_icon(get_icon("Favorites","EditorIcons"));
+
+ fav_up->set_icon(get_icon("MoveUp","EditorIcons"));
+ fav_down->set_icon(get_icon("MoveDown","EditorIcons"));
+ fav_rm->set_icon(get_icon("RemoveSmall","EditorIcons"));
+
+ }
+ if (p_what==NOTIFICATION_PROCESS) {
+
+ if (preview_waiting) {
+ preview_wheel_timeout-=get_process_delta_time();
+ if (preview_wheel_timeout<=0) {
+ preview_wheel_index++;
+ if (preview_wheel_index>=8)
+ preview_wheel_index=0;
+ Ref<Texture> frame = get_icon("WaitPreview"+itos(preview_wheel_index+1),"EditorIcons");
+ preview->set_texture(frame);
+ preview_wheel_timeout=0.1;
+ }
+ }
+ }
+
+ if (p_what==NOTIFICATION_DRAW) {
+
+ //RID ci = get_canvas_item();
+ //get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
+ }
+}
+
+void EditorFileDialog::set_enable_multiple_selection(bool p_enable) {
+
+ item_list->set_select_mode(p_enable?ItemList::SELECT_MULTI:ItemList::SELECT_SINGLE);
+
+};
+
+Vector<String> EditorFileDialog::get_selected_files() const {
+
+ Vector<String> list;
+ for(int i=0;i<item_list->get_item_count();i++) {
+ if (item_list->is_selected(i))
+ list.push_back(item_list->get_item_text(i));
+ }
+ return list;
+
+};
+
+void EditorFileDialog::update_dir() {
+
+ dir->set_text(dir_access->get_current_dir());
+}
+
+void EditorFileDialog::_dir_entered(String p_dir) {
+
+
+ dir_access->change_dir(p_dir);
+ file->set_text("");
+ invalidate();
+ update_dir();
+ _push_history();
+
+
+}
+
+void EditorFileDialog::_file_entered(const String& p_file) {
+
+ _action_pressed();
+}
+
+void EditorFileDialog::_save_confirm_pressed() {
+ String f=dir_access->get_current_dir().plus_file(file->get_text());
+ _save_to_recent();
+ emit_signal("file_selected",f);
+ hide();
+}
+
+void EditorFileDialog::_post_popup() {
+
+ ConfirmationDialog::_post_popup();
+ if (invalidated) {
+ update_file_list();
+ invalidated=false;
+ }
+ if (mode==MODE_SAVE_FILE)
+ file->grab_focus();
+ else
+ item_list->grab_focus();
+
+ if (is_visible() && get_current_file()!="")
+ _request_single_thumbnail(get_current_dir().plus_file(get_current_file()));
+
+ if (is_visible()) {
+ Ref<Texture> folder = get_icon("folder","FileDialog");
+ recent->clear();
+
+
+ bool res = access==ACCESS_RESOURCES;
+ Vector<String> recentd = EditorSettings::get_singleton()->get_recent_dirs();
+ for(int i=0;i<recentd.size();i++) {
+ bool cres = recentd[i].begins_with("res://");
+ if (cres!=res)
+ continue;
+ String name = recentd[i];
+ if (res && name=="res://") {
+ name="/";
+ } else {
+ name=name.get_file()+"/";
+ }
+
+ //print_line("file: "+name);
+ recent->add_item(name,folder);
+ recent->set_item_metadata( recent->get_item_count()-1,recentd[i]);
+ }
+
+ local_history.clear();
+ local_history_pos=-1;
+ _push_history();
+
+ _update_favorites();
+ }
+
+}
+
+void EditorFileDialog::_thumbnail_result(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata) {
+
+ if (display_mode==DISPLAY_LIST || p_preview.is_null())
+ return;
+
+ for(int i=0;i<item_list->get_item_count();i++) {
+ Dictionary d = item_list->get_item_metadata(i);
+ String pname = d["path"];
+ if (pname==p_path) {
+ item_list->set_item_icon(i,p_preview);
+ item_list->set_item_tag_icon(i,Ref<Texture>());
+ }
+ }
+}
+
+void EditorFileDialog::_thumbnail_done(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata) {
+
+ set_process(false);
+ preview_waiting=false;
+
+ if (p_preview.is_valid() && get_current_path()==p_path) {
+
+
+ preview->set_texture(p_preview);
+ if (display_mode==DISPLAY_THUMBNAILS) {
+ preview_vb->hide();
+ } else {
+ preview_vb->show();
+ }
+
+ } else {
+ preview_vb->hide();
+ preview->set_texture(Ref<Texture>());
+
+ }
+
+}
+
+void EditorFileDialog::_request_single_thumbnail(const String& p_path) {
+
+ EditorResourcePreview::get_singleton()->queue_resource_preview(p_path,this,"_thumbnail_done",p_path);
+ print_line("want file "+p_path);
+ set_process(true);
+ preview_waiting=true;
+ preview_wheel_timeout=0;
+
+}
+
+void EditorFileDialog::_action_pressed() {
+
+ if (mode==MODE_OPEN_FILES) {
+
+
+ String fbase=dir_access->get_current_dir();
+
+ DVector<String> files;
+ for(int i=0;i<item_list->get_item_count();i++) {
+ if (item_list->is_selected(i))
+ files.push_back( fbase.plus_file(item_list->get_item_text(i) ));
+ }
+
+ if (files.size()) {
+ _save_to_recent();
+ emit_signal("files_selected",files);
+ hide();
+ }
+
+ return;
+ }
+
+ String f=dir_access->get_current_dir().plus_file(file->get_text());
+
+ if (mode==MODE_OPEN_FILE && dir_access->file_exists(f)) {
+ _save_to_recent();
+ emit_signal("file_selected",f);
+ hide();
+ }
+
+ if (mode==MODE_OPEN_DIR) {
+
+
+ String path=dir_access->get_current_dir();
+ /*if (tree->get_selected()) {
+ Dictionary d = tree->get_selected()->get_metadata(0);
+ if (d["dir"]) {
+ path=path+"/"+String(d["name"]);
+ }
+ }*/
+ path=path.replace("\\","/");
+ _save_to_recent();
+ emit_signal("dir_selected",path);
+ hide();
+ }
+
+ if (mode==MODE_SAVE_FILE) {
+
+ bool valid=false;
+
+ if (filter->get_selected()==filter->get_item_count()-1) {
+ valid=true; //match none
+ } else if (filters.size()>1 && filter->get_selected()==0) {
+ // match all filters
+ for (int i=0;i<filters.size();i++) {
+
+ String flt=filters[i].get_slice(";",0);
+ for (int j=0;j<flt.get_slice_count(",");j++) {
+
+ String str = flt.get_slice(",",j).strip_edges();
+ if (f.match(str)) {
+ valid=true;
+ break;
+ }
+ }
+ if (valid)
+ break;
+ }
+ } else {
+ int idx=filter->get_selected();
+ if (filters.size()>1)
+ idx--;
+ if (idx>=0 && idx<filters.size()) {
+
+ String flt=filters[idx].get_slice(";",0);
+ int filterSliceCount=flt.get_slice_count(",");
+ for (int j=0;j<filterSliceCount;j++) {
+
+ String str = (flt.get_slice(",",j).strip_edges());
+ if (f.match(str)) {
+ valid=true;
+ break;
+ }
+ }
+
+ if (!valid && filterSliceCount>0) {
+ String str = (flt.get_slice(",",0).strip_edges());
+ f+=str.substr(1, str.length()-1);
+ _request_single_thumbnail(get_current_dir().plus_file(f.get_file()));
+ file->set_text(f.get_file());
+ valid=true;
+ }
+ } else {
+ valid=true;
+ }
+ }
+
+
+ if (!valid) {
+
+ exterr->popup_centered_minsize(Size2(250,80));
+ return;
+
+ }
+
+ if (dir_access->file_exists(f)) {
+ confirm_save->set_text("File Exists, Overwrite?");
+ confirm_save->popup_centered(Size2(200,80));
+ } else {
+
+ _save_to_recent();
+ emit_signal("file_selected",f);
+ hide();
+ }
+ }
+}
+
+void EditorFileDialog::_cancel_pressed() {
+
+ file->set_text("");
+ invalidate();
+ hide();
+}
+
+void EditorFileDialog::_item_selected(int p_item) {
+
+ int current = p_item;
+ if (current<0 || current>=item_list->get_item_count())
+ return;
+
+ Dictionary d=item_list->get_item_metadata(current);
+
+ if (!d["dir"]) {
+
+ file->set_text(d["name"]);
+ _request_single_thumbnail(get_current_dir().plus_file(get_current_file()));
+ }
+}
+
+void EditorFileDialog::_push_history() {
+
+ local_history.resize(local_history_pos+1);
+ String new_path = dir_access->get_current_dir();
+ if (local_history.size()==0 || new_path!=local_history[local_history_pos]) {
+ local_history.push_back(new_path);
+ local_history_pos++;
+ dir_prev->set_disabled(local_history_pos==0);
+ dir_next->set_disabled(true);
+ }
+
+}
+void EditorFileDialog::_item_dc_selected(int p_item) {
+
+
+ int current = p_item;
+ if (current<0 || current>=item_list->get_item_count())
+ return;
+
+ Dictionary d=item_list->get_item_metadata(current);
+
+ if (d["dir"]) {
+
+ print_line("change dir: "+String(d["name"]));
+ dir_access->change_dir(d["name"]);
+ if (mode==MODE_OPEN_FILE || mode==MODE_OPEN_FILES || mode==MODE_OPEN_DIR)
+ file->set_text("");
+ call_deferred("_update_file_list");
+ call_deferred("_update_dir");
+
+ _push_history();
+
+
+ } else {
+
+ _action_pressed();
+ }
+}
+
+
+
+void EditorFileDialog::update_file_list() {
+
+
+ int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");
+ Ref<Texture> folder_thumbnail;
+ Ref<Texture> file_thumbnail;
+
+ item_list->clear();
+
+ if (display_mode==DISPLAY_THUMBNAILS) {
+
+ item_list->set_max_columns(0);
+ item_list->set_icon_mode(ItemList::ICON_MODE_TOP);
+ item_list->set_fixed_column_width(thumbnail_size*3/2);
+ item_list->set_max_text_lines(2);
+ item_list->set_min_icon_size(Size2(thumbnail_size,thumbnail_size));
+
+ if (!has_icon("ResizedFolder","EditorIcons")) {
+ Ref<ImageTexture> folder = get_icon("FolderBig","EditorIcons");
+ Image img = folder->get_data();
+ img.resize(thumbnail_size,thumbnail_size);
+ Ref<ImageTexture> resized_folder = Ref<ImageTexture>( memnew( ImageTexture));
+ resized_folder->create_from_image(img,0);
+ Theme::get_default()->set_icon("ResizedFolder","EditorIcons",resized_folder);
+ }
+
+ folder_thumbnail = get_icon("ResizedFolder","EditorIcons");
+
+ if (!has_icon("ResizedFile","EditorIcons")) {
+ Ref<ImageTexture> file = get_icon("FileBig","EditorIcons");
+ Image img = file->get_data();
+ img.resize(thumbnail_size,thumbnail_size);
+ Ref<ImageTexture> resized_file = Ref<ImageTexture>( memnew( ImageTexture));
+ resized_file->create_from_image(img,0);
+ Theme::get_default()->set_icon("ResizedFile","EditorIcons",resized_file);
+ }
+
+ file_thumbnail = get_icon("ResizedFile","EditorIcons");
+
+ preview_vb->hide();
+
+ } else {
+
+ item_list->set_icon_mode(ItemList::ICON_MODE_LEFT);
+ item_list->set_max_columns(1);
+ item_list->set_max_text_lines(1);
+ item_list->set_fixed_column_width(0);
+ item_list->set_min_icon_size(Size2());
+ if (preview->get_texture().is_valid())
+ preview_vb->show();
+
+ }
+
+
+ dir_access->list_dir_begin();
+
+
+ Ref<Texture> folder = get_icon("folder","FileDialog");
+ List<String> files;
+ List<String> dirs;
+
+ bool isdir;
+ bool ishidden;
+ bool show_hidden = show_hidden_files;
+ String item;
+
+ while ((item=dir_access->get_next(&isdir))!="") {
+
+ ishidden = dir_access->current_is_hidden();
+
+ if (show_hidden || !ishidden) {
+ if (!isdir)
+ files.push_back(item);
+ else
+ dirs.push_back(item);
+ }
+ }
+
+ dirs.sort_custom<NoCaseComparator>();
+ files.sort_custom<NoCaseComparator>();
+
+ while(!dirs.empty()) {
+
+ if (dirs.front()->get()!=".") {
+ item_list->add_item(dirs.front()->get()+"/");
+ if (display_mode==DISPLAY_THUMBNAILS) {
+
+ item_list->set_item_icon(item_list->get_item_count()-1,folder_thumbnail);
+ } else {
+
+ item_list->set_item_icon(item_list->get_item_count()-1,folder);
+ }
+
+ Dictionary d;
+ d["name"]=dirs.front()->get();
+ d["path"]=String();
+ d["dir"]=true;
+ item_list->set_item_metadata( item_list->get_item_count() -1, d);
+ }
+ dirs.pop_front();
+
+ }
+
+ dirs.clear();
+
+ List<String> patterns;
+ // build filter
+ if (filter->get_selected()==filter->get_item_count()-1) {
+
+ // match all
+ } else if (filters.size()>1 && filter->get_selected()==0) {
+ // match all filters
+ for (int i=0;i<filters.size();i++) {
+
+ String f=filters[i].get_slice(";",0);
+ for (int j=0;j<f.get_slice_count(",");j++) {
+
+ patterns.push_back(f.get_slice(",",j).strip_edges());
+ }
+ }
+ } else {
+ int idx=filter->get_selected();
+ if (filters.size()>1)
+ idx--;
+
+ if (idx>=0 && idx<filters.size()) {
+
+ String f=filters[idx].get_slice(";",0);
+ for (int j=0;j<f.get_slice_count(",");j++) {
+
+ patterns.push_back(f.get_slice(",",j).strip_edges());
+ }
+ }
+ }
+
+
+ String base_dir = dir_access->get_current_dir();
+
+
+ while(!files.empty()) {
+
+ bool match=patterns.empty();
+
+ for(List<String>::Element *E=patterns.front();E;E=E->next()) {
+
+ if (files.front()->get().matchn(E->get())) {
+
+ match=true;
+ break;
+ }
+ }
+
+ if (match) {
+ //TreeItem *ti=tree->create_item(root);
+ //ti->set_text(0,files.front()->get());
+ item_list->add_item(files.front()->get());
+
+ if (get_icon_func) {
+
+ Ref<Texture> icon = get_icon_func(base_dir.plus_file(files.front()->get()));
+ //ti->set_icon(0,icon);
+ if (display_mode==DISPLAY_THUMBNAILS) {
+
+ item_list->set_item_icon(item_list->get_item_count()-1,file_thumbnail);
+ item_list->set_item_tag_icon(item_list->get_item_count()-1,icon);
+ } else {
+ item_list->set_item_icon(item_list->get_item_count()-1,icon);
+ }
+ }
+
+ if (mode==MODE_OPEN_DIR) {
+ //disabled mode?
+ //ti->set_custom_color(0,get_color("files_disabled"));
+ //ti->set_selectable(0,false);
+ }
+ Dictionary d;
+ d["name"]=files.front()->get();
+ d["dir"]=false;
+ String fullpath = base_dir.plus_file(files.front()->get());
+
+ if (display_mode==DISPLAY_THUMBNAILS) {
+ EditorResourcePreview::get_singleton()->queue_resource_preview(fullpath,this,"_thumbnail_result",fullpath);
+ }
+ d["path"]=base_dir.plus_file(files.front()->get());
+ //ti->set_metadata(0,d);
+ item_list->set_item_metadata(item_list->get_item_count()-1,d);
+
+ if (file->get_text()==files.front()->get())
+ item_list->set_current(item_list->get_item_count()-1);
+ }
+
+ files.pop_front();
+ }
+
+ if (favorites->get_current()>=0) {
+ favorites->unselect(favorites->get_current());
+ }
+
+ favorite->set_pressed(false);
+ fav_up->set_disabled(true);
+ fav_down->set_disabled(true);
+ for(int i=0;i<favorites->get_item_count();i++) {
+ if (favorites->get_item_metadata(i)==base_dir) {
+ favorites->select(i);
+ favorite->set_pressed(true);
+ if (i>0) {
+ fav_up->set_disabled(false);
+ }
+ if (i<favorites->get_item_count()-1) {
+ fav_down->set_disabled(false);
+ }
+ break;
+ }
+
+ }
+ // ??
+ //if (tree->get_root() && tree->get_root()->get_children())
+ // tree->get_root()->get_children()->select(0);
+
+ files.clear();
+
+}
+
+void EditorFileDialog::_filter_selected(int) {
+
+ update_file_list();
+}
+
+void EditorFileDialog::update_filters() {
+
+ filter->clear();
+
+ if (filters.size()>1) {
+ String all_filters;
+
+ const int max_filters=5;
+
+ for(int i=0;i<MIN( max_filters, filters.size()) ;i++) {
+ String flt=filters[i].get_slice(";",0);
+ if (i>0)
+ all_filters+=",";
+ all_filters+=flt;
+ }
+
+ if (max_filters<filters.size())
+ all_filters+=", ...";
+
+ filter->add_item("All Recognized ( "+all_filters+" )");
+ }
+ for(int i=0;i<filters.size();i++) {
+
+ String flt=filters[i].get_slice(";",0).strip_edges();
+ String desc=filters[i].get_slice(";",1).strip_edges();
+ if (desc.length())
+ filter->add_item(desc+" ( "+flt+" )");
+ else
+ filter->add_item("( "+flt+" )");
+ }
+
+ filter->add_item("All Files (*)");
+
+}
+
+void EditorFileDialog::clear_filters() {
+
+ filters.clear();
+ update_filters();
+ invalidate();
+}
+void EditorFileDialog::add_filter(const String& p_filter) {
+
+ filters.push_back(p_filter);
+ update_filters();
+ invalidate();
+
+}
+
+String EditorFileDialog::get_current_dir() const {
+
+ return dir->get_text();
+}
+String EditorFileDialog::get_current_file() const {
+
+ return file->get_text();
+}
+String EditorFileDialog::get_current_path() const {
+
+ return dir->get_text().plus_file(file->get_text());
+}
+void EditorFileDialog::set_current_dir(const String& p_dir) {
+
+ dir_access->change_dir(p_dir);
+ update_dir();
+ invalidate();
+ //_push_history();
+
+
+}
+void EditorFileDialog::set_current_file(const String& p_file) {
+
+ file->set_text(p_file);
+ update_dir();
+ invalidate();
+ int lp = p_file.find_last(".");
+ if (lp!=-1) {
+ file->select(0,lp);
+ file->grab_focus();
+ }
+
+ if (is_visible())
+ _request_single_thumbnail(get_current_dir().plus_file(get_current_file()));
+
+
+}
+void EditorFileDialog::set_current_path(const String& p_path) {
+
+ if (!p_path.size())
+ return;
+ int pos=MAX( p_path.find_last("/"), p_path.find_last("\\") );
+ if (pos==-1) {
+
+ set_current_file(p_path);
+ } else {
+
+ String dir=p_path.substr(0,pos);
+ String file=p_path.substr(pos+1,p_path.length());
+ set_current_dir(dir);
+ set_current_file(file);
+ }
+}
+
+
+void EditorFileDialog::set_mode(Mode p_mode) {
+
+ mode=p_mode;
+ switch(mode) {
+
+ case MODE_OPEN_FILE: get_ok()->set_text("Open"); set_title("Open a File"); makedir->hide(); break;
+ case MODE_OPEN_FILES: get_ok()->set_text("Open"); set_title("Open File(s)"); makedir->hide(); break;
+ case MODE_SAVE_FILE: get_ok()->set_text("Save"); set_title("Save a File"); makedir->show(); break;
+ case MODE_OPEN_DIR: get_ok()->set_text("Open"); set_title("Open a Directory"); makedir->show(); break;
+ }
+
+ if (mode==MODE_OPEN_FILES) {
+ item_list->set_select_mode(ItemList::SELECT_MULTI);
+ } else {
+ item_list->set_select_mode(ItemList::SELECT_SINGLE);
+ }
+}
+
+EditorFileDialog::Mode EditorFileDialog::get_mode() const {
+
+ return mode;
+}
+
+void EditorFileDialog::set_access(Access p_access) {
+
+ ERR_FAIL_INDEX(p_access,3);
+ if (access==p_access)
+ return;
+ memdelete( dir_access );
+ switch(p_access) {
+ case ACCESS_FILESYSTEM: {
+
+ dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ } break;
+ case ACCESS_RESOURCES: {
+
+ dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ } break;
+ case ACCESS_USERDATA: {
+
+ dir_access = DirAccess::create(DirAccess::ACCESS_USERDATA);
+ } break;
+ }
+ access=p_access;
+ _update_drives();
+ invalidate();
+ update_filters();
+ update_dir();
+}
+
+void EditorFileDialog::invalidate() {
+
+ if (is_visible()) {
+ update_file_list();
+ invalidated=false;
+ } else {
+ invalidated=true;
+ }
+
+}
+
+EditorFileDialog::Access EditorFileDialog::get_access() const{
+
+ return access;
+}
+
+void EditorFileDialog::_make_dir_confirm() {
+
+
+ Error err = dir_access->make_dir( makedirname->get_text() );
+ if (err==OK) {
+ dir_access->change_dir(makedirname->get_text());
+ invalidate();
+ update_filters();
+ update_dir();
+ _push_history();
+
+ } else {
+ mkdirerr->popup_centered_minsize(Size2(250,50));
+ }
+}
+
+
+void EditorFileDialog::_make_dir() {
+
+ makedialog->popup_centered_minsize(Size2(250,80));
+ makedirname->grab_focus();
+
+}
+
+void EditorFileDialog::_select_drive(int p_idx) {
+
+ String d = drives->get_item_text(p_idx);
+ dir_access->change_dir(d);
+ file->set_text("");
+ invalidate();
+ update_dir();
+ _push_history();
+
+
+}
+
+void EditorFileDialog::_update_drives() {
+
+
+ int dc = dir_access->get_drive_count();
+ if (dc==0 || access!=ACCESS_FILESYSTEM) {
+ drives->hide();
+ } else {
+ drives->clear();
+ drives->show();
+
+ for(int i=0;i<dir_access->get_drive_count();i++) {
+ String d = dir_access->get_drive(i);
+ drives->add_item(dir_access->get_drive(i));
+ }
+
+ drives->select(dir_access->get_current_drive());
+
+ }
+}
+
+
+void EditorFileDialog::_favorite_selected(int p_idx) {
+
+ Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs();
+ ERR_FAIL_INDEX(p_idx,favorited.size());
+
+ dir_access->change_dir(favorited[p_idx]);
+ file->set_text("");
+ invalidate();
+ update_dir();
+ _push_history();
+}
+
+void EditorFileDialog::_favorite_move_up(){
+
+ int current = favorites->get_current();
+
+ if (current>0 && current<favorites->get_item_count()) {
+ Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs();
+
+ int a_idx=favorited.find(String(favorites->get_item_metadata(current-1)));
+ int b_idx=favorited.find(String(favorites->get_item_metadata(current)));
+
+ if (a_idx==-1 || b_idx==-1)
+ return;
+ SWAP(favorited[a_idx],favorited[b_idx]);
+
+ EditorSettings::get_singleton()->set_favorite_dirs(favorited);
+
+ _update_favorites();
+ update_file_list();
+
+ }
+}
+void EditorFileDialog::_favorite_move_down(){
+
+ int current = favorites->get_current();
+
+ if (current>=0 && current<favorites->get_item_count()-1) {
+ Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs();
+
+ int a_idx=favorited.find(String(favorites->get_item_metadata(current+1)));
+ int b_idx=favorited.find(String(favorites->get_item_metadata(current)));
+
+ if (a_idx==-1 || b_idx==-1)
+ return;
+ SWAP(favorited[a_idx],favorited[b_idx]);
+
+ EditorSettings::get_singleton()->set_favorite_dirs(favorited);
+
+ _update_favorites();
+ update_file_list();
+
+ }
+}
+
+
+void EditorFileDialog::_update_favorites() {
+
+ bool res = access==ACCESS_RESOURCES;
+
+ String current = get_current_dir();
+ Ref<Texture> star = get_icon("Favorites","EditorIcons");
+ favorites->clear();
+
+ favorite->set_pressed(false);
+
+
+ Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs();
+ for(int i=0;i<favorited.size();i++) {
+ bool cres = favorited[i].begins_with("res://");
+ if (cres!=res)
+ continue;
+ String name = favorited[i];
+
+ bool setthis = name==current;
+
+ if (res && name=="res://") {
+ name="/";
+ } else {
+ name=name.get_file()+"/";
+ }
+
+
+ //print_line("file: "+name);
+ favorites->add_item(name,star);
+ favorites->set_item_metadata( favorites->get_item_count()-1,favorited[i]);
+
+ if (setthis) {
+ favorite->set_pressed(true);
+ favorites->set_current(favorites->get_item_count()-1);
+ }
+ }
+
+
+}
+
+void EditorFileDialog::_favorite_toggled(bool p_toggle) {
+ bool res = access==ACCESS_RESOURCES;
+
+ String cd = get_current_dir();
+
+ Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs();
+
+ bool found = false;
+ for(int i=0;i<favorited.size();i++) {
+ bool cres = favorited[i].begins_with("res://");
+ if (cres!=res)
+ continue;
+
+ if (favorited[i]==cd) {
+ found=true;
+ break;
+ }
+ }
+
+ if (found) {
+ favorited.erase(cd);
+ favorite->set_pressed(false);
+ } else {
+ favorited.push_back(cd);
+ favorite->set_pressed(true);
+ }
+
+ EditorSettings::get_singleton()->set_favorite_dirs(favorited);
+
+ _update_favorites();
+
+}
+
+void EditorFileDialog::_recent_selected(int p_idx) {
+
+ Vector<String> recentd = EditorSettings::get_singleton()->get_recent_dirs();
+ ERR_FAIL_INDEX(p_idx,recentd.size());
+
+ dir_access->change_dir(recent->get_item_metadata(p_idx));
+ update_file_list();
+ update_dir();
+ _push_history();
+}
+
+void EditorFileDialog::_go_up() {
+
+ dir_access->change_dir("..");
+ update_file_list();
+ update_dir();
+ _push_history();
+
+}
+
+void EditorFileDialog::_go_back(){
+
+ if (local_history_pos<=0) {
+ return;
+ }
+
+ local_history_pos--;
+ dir_access->change_dir(local_history[local_history_pos]);
+ update_file_list();
+ update_dir();
+
+ dir_prev->set_disabled(local_history_pos==0);
+ dir_next->set_disabled(local_history_pos==local_history.size()-1);
+}
+void EditorFileDialog::_go_forward(){
+
+ if (local_history_pos==local_history.size()-1) {
+ return;
+ }
+
+ local_history_pos++;
+ dir_access->change_dir(local_history[local_history_pos]);
+ update_file_list();
+ update_dir();
+
+ dir_prev->set_disabled(local_history_pos==0);
+ dir_next->set_disabled(local_history_pos==local_history.size()-1);
+
+}
+
+bool EditorFileDialog::default_show_hidden_files=true;
+
+void EditorFileDialog::set_display_mode(DisplayMode p_mode) {
+
+ if (display_mode==p_mode)
+ return;
+ if (p_mode==DISPLAY_THUMBNAILS) {
+ mode_list->set_pressed(false);
+ mode_thumbnails->set_pressed(true);
+ } else {
+ mode_thumbnails->set_pressed(false);
+ mode_list->set_pressed(true);
+ }
+ display_mode=p_mode;
+ invalidate();;
+}
+
+EditorFileDialog::DisplayMode EditorFileDialog::get_display_mode() const{
+
+ return display_mode;
+}
+
+
+
+void EditorFileDialog::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("_item_selected"),&EditorFileDialog::_item_selected);
+ ObjectTypeDB::bind_method(_MD("_item_db_selected"),&EditorFileDialog::_item_dc_selected);
+ ObjectTypeDB::bind_method(_MD("_dir_entered"),&EditorFileDialog::_dir_entered);
+ ObjectTypeDB::bind_method(_MD("_file_entered"),&EditorFileDialog::_file_entered);
+ ObjectTypeDB::bind_method(_MD("_action_pressed"),&EditorFileDialog::_action_pressed);
+ ObjectTypeDB::bind_method(_MD("_cancel_pressed"),&EditorFileDialog::_cancel_pressed);
+ ObjectTypeDB::bind_method(_MD("_filter_selected"),&EditorFileDialog::_filter_selected);
+ ObjectTypeDB::bind_method(_MD("_save_confirm_pressed"),&EditorFileDialog::_save_confirm_pressed);
+
+ ObjectTypeDB::bind_method(_MD("clear_filters"),&EditorFileDialog::clear_filters);
+ ObjectTypeDB::bind_method(_MD("add_filter","filter"),&EditorFileDialog::add_filter);
+ ObjectTypeDB::bind_method(_MD("get_current_dir"),&EditorFileDialog::get_current_dir);
+ ObjectTypeDB::bind_method(_MD("get_current_file"),&EditorFileDialog::get_current_file);
+ ObjectTypeDB::bind_method(_MD("get_current_path"),&EditorFileDialog::get_current_path);
+ ObjectTypeDB::bind_method(_MD("set_current_dir","dir"),&EditorFileDialog::set_current_dir);
+ ObjectTypeDB::bind_method(_MD("set_current_file","file"),&EditorFileDialog::set_current_file);
+ ObjectTypeDB::bind_method(_MD("set_current_path","path"),&EditorFileDialog::set_current_path);
+ ObjectTypeDB::bind_method(_MD("set_mode","mode"),&EditorFileDialog::set_mode);
+ ObjectTypeDB::bind_method(_MD("get_mode"),&EditorFileDialog::get_mode);
+ ObjectTypeDB::bind_method(_MD("get_vbox:VBoxContainer"),&EditorFileDialog::get_vbox);
+ ObjectTypeDB::bind_method(_MD("set_access","access"),&EditorFileDialog::set_access);
+ ObjectTypeDB::bind_method(_MD("get_access"),&EditorFileDialog::get_access);
+ ObjectTypeDB::bind_method(_MD("set_show_hidden_files"),&EditorFileDialog::set_show_hidden_files);
+ ObjectTypeDB::bind_method(_MD("is_showing_hidden_files"),&EditorFileDialog::is_showing_hidden_files);
+ ObjectTypeDB::bind_method(_MD("_select_drive"),&EditorFileDialog::_select_drive);
+ ObjectTypeDB::bind_method(_MD("_make_dir"),&EditorFileDialog::_make_dir);
+ ObjectTypeDB::bind_method(_MD("_make_dir_confirm"),&EditorFileDialog::_make_dir_confirm);
+ ObjectTypeDB::bind_method(_MD("_update_file_list"),&EditorFileDialog::update_file_list);
+ ObjectTypeDB::bind_method(_MD("_update_dir"),&EditorFileDialog::update_dir);
+ ObjectTypeDB::bind_method(_MD("_thumbnail_done"),&EditorFileDialog::_thumbnail_done);
+ ObjectTypeDB::bind_method(_MD("set_display_mode","mode"),&EditorFileDialog::set_display_mode);
+ ObjectTypeDB::bind_method(_MD("get_display_mode"),&EditorFileDialog::get_display_mode);
+ ObjectTypeDB::bind_method(_MD("_thumbnail_result"),&EditorFileDialog::_thumbnail_result);
+
+ ObjectTypeDB::bind_method(_MD("_recent_selected"),&EditorFileDialog::_recent_selected);
+ ObjectTypeDB::bind_method(_MD("_go_back"),&EditorFileDialog::_go_back);
+ ObjectTypeDB::bind_method(_MD("_go_forward"),&EditorFileDialog::_go_forward);
+ ObjectTypeDB::bind_method(_MD("_go_up"),&EditorFileDialog::_go_up);
+
+ ObjectTypeDB::bind_method(_MD("_favorite_toggled"),&EditorFileDialog::_favorite_toggled);
+ ObjectTypeDB::bind_method(_MD("_favorite_selected"),&EditorFileDialog::_favorite_selected);
+ ObjectTypeDB::bind_method(_MD("_favorite_move_up"),&EditorFileDialog::_favorite_move_up);
+ ObjectTypeDB::bind_method(_MD("_favorite_move_down"),&EditorFileDialog::_favorite_move_down);
+
+ ObjectTypeDB::bind_method(_MD("invalidate"),&EditorFileDialog::invalidate);
+
+ ADD_SIGNAL(MethodInfo("file_selected",PropertyInfo( Variant::STRING,"path")));
+ ADD_SIGNAL(MethodInfo("files_selected",PropertyInfo( Variant::STRING_ARRAY,"paths")));
+ ADD_SIGNAL(MethodInfo("dir_selected",PropertyInfo( Variant::STRING,"dir")));
+
+ BIND_CONSTANT( MODE_OPEN_FILE );
+ BIND_CONSTANT( MODE_OPEN_FILES );
+ BIND_CONSTANT( MODE_OPEN_DIR );
+ BIND_CONSTANT( MODE_SAVE_FILE );
+
+ BIND_CONSTANT( ACCESS_RESOURCES );
+ BIND_CONSTANT( ACCESS_USERDATA );
+ BIND_CONSTANT( ACCESS_FILESYSTEM );
+
+}
+
+
+void EditorFileDialog::set_show_hidden_files(bool p_show) {
+ show_hidden_files=p_show;
+ invalidate();
+}
+
+bool EditorFileDialog::is_showing_hidden_files() const {
+ return show_hidden_files;
+}
+
+void EditorFileDialog::set_default_show_hidden_files(bool p_show) {
+ default_show_hidden_files=p_show;
+}
+
+void EditorFileDialog::_save_to_recent() {
+
+ String dir = get_current_dir();
+ Vector<String> recent = EditorSettings::get_singleton()->get_recent_dirs();
+
+ const int max=20;
+ int count=0;
+ bool res=dir.begins_with("res://");
+
+ for(int i=0;i<recent.size();i++) {
+ bool cres=recent[i].begins_with("res://");
+ if (recent[i]==dir || (res==cres && count>max)) {
+ recent.remove(i);
+ i--;
+ } else {
+ count++;
+ }
+ }
+
+ recent.insert(0,dir);
+
+ EditorSettings::get_singleton()->set_recent_dirs(recent);
+
+
+}
+
+EditorFileDialog::EditorFileDialog() {
+
+ show_hidden_files=true;
+ display_mode=DISPLAY_THUMBNAILS;
+ local_history_pos=0;
+
+ VBoxContainer *vbc = memnew( VBoxContainer );
+ add_child(vbc);
+ set_child_rect(vbc);
+
+ mode=MODE_SAVE_FILE;
+ set_title("Save a File");
+
+ HBoxContainer *pathhb = memnew( HBoxContainer );
+
+ dir_prev = memnew( ToolButton );
+ dir_next = memnew( ToolButton );
+ dir_up = memnew( ToolButton );
+
+ pathhb->add_child(dir_prev);
+ pathhb->add_child(dir_next);
+ pathhb->add_child(dir_up);
+
+ dir_prev->connect("pressed",this,"_go_back");
+ dir_next->connect("pressed",this,"_go_forward");
+ dir_up->connect("pressed",this,"_go_up");
+
+ dir = memnew(LineEdit);
+ pathhb->add_child(dir);
+ dir->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ favorite = memnew( ToolButton );
+ favorite->set_toggle_mode(true);
+ favorite->connect("toggled",this,"_favorite_toggled");
+ pathhb->add_child(favorite);
+
+ mode_thumbnails = memnew( ToolButton );
+ mode_thumbnails->connect("pressed",this,"set_display_mode",varray(DISPLAY_THUMBNAILS));
+ mode_thumbnails->set_toggle_mode(true);
+ mode_thumbnails->set_pressed(true);
+ pathhb->add_child(mode_thumbnails);
+ mode_list = memnew( ToolButton );
+ mode_list->connect("pressed",this,"set_display_mode",varray(DISPLAY_LIST));
+ mode_list->set_toggle_mode(true);
+ pathhb->add_child(mode_list);
+
+ drives = memnew( OptionButton );
+ pathhb->add_child(drives);
+ drives->connect("item_selected",this,"_select_drive");
+
+ makedir = memnew( Button );
+ makedir->set_text("Create Folder");
+ makedir->connect("pressed",this,"_make_dir");
+ pathhb->add_child(makedir);
+
+ list_hb = memnew( HBoxContainer );
+
+ vbc->add_margin_child("Path:",pathhb);
+ vbc->add_child(list_hb);
+ list_hb->set_v_size_flags(SIZE_EXPAND_FILL);
+
+ VBoxContainer *fav_vb = memnew( VBoxContainer );
+ list_hb->add_child(fav_vb);
+ HBoxContainer *fav_hb = memnew( HBoxContainer );
+ fav_vb->add_child(fav_hb);
+ fav_hb->add_child(memnew(Label("Favorites:")));
+ fav_hb->add_spacer();
+ fav_up = memnew( ToolButton );
+ fav_hb->add_child(fav_up);
+ fav_up->connect("pressed",this,"_favorite_move_up");
+ fav_down = memnew( ToolButton );
+ fav_hb->add_child(fav_down);
+ fav_down->connect("pressed",this,"_favorite_move_down");
+ fav_rm = memnew( ToolButton );
+ fav_hb->add_child(fav_rm);
+ fav_rm->hide(); // redundant
+
+ MarginContainer *fav_mv = memnew( MarginContainer );
+ fav_vb->add_child(fav_mv);
+ fav_mv->set_v_size_flags(SIZE_EXPAND_FILL);
+ favorites = memnew( ItemList );
+ fav_mv->add_child(favorites);
+ favorites->connect("item_selected",this,"_favorite_selected");
+
+ recent = memnew( ItemList );
+ fav_vb->add_margin_child("Recent:",recent,true);
+ recent->connect("item_selected",this,"_recent_selected");
+
+ VBoxContainer *item_vb = memnew( VBoxContainer );
+ list_hb->add_child(item_vb);
+ item_vb->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ item_list = memnew( ItemList );
+ item_list->set_v_size_flags(SIZE_EXPAND_FILL);
+ item_vb->add_margin_child("Directories & Files:",item_list,true);
+
+ HBoxContainer* filter_hb = memnew( HBoxContainer );
+ item_vb->add_child(filter_hb);
+
+ VBoxContainer *filter_vb = memnew( VBoxContainer );
+ filter_hb->add_child(filter_vb);
+ filter_vb->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ preview_vb = memnew( VBoxContainer );
+ filter_hb->add_child(preview_vb);
+ CenterContainer *prev_cc = memnew( CenterContainer );
+ preview_vb->add_margin_child("Preview:",prev_cc);
+ preview = memnew( TextureFrame );
+ prev_cc->add_child(preview);
+ preview_vb->hide();
+
+
+ file = memnew(LineEdit);
+ //add_child(file);
+ filter_vb->add_margin_child("File:",file);
+
+
+ filter = memnew( OptionButton );
+ //add_child(filter);
+ filter_vb->add_margin_child("Filter:",filter);
+ filter->set_clip_text(true);//too many extensions overflow it
+
+ dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ access=ACCESS_RESOURCES;
+ _update_drives();
+
+
+ connect("confirmed", this,"_action_pressed");
+ //cancel->connect("pressed", this,"_cancel_pressed");
+ item_list->connect("item_selected", this,"_item_selected",varray(),CONNECT_DEFERRED);
+ item_list->connect("item_activated", this,"_item_db_selected",varray());
+ dir->connect("text_entered", this,"_dir_entered");
+ file->connect("text_entered", this,"_file_entered");
+ filter->connect("item_selected", this,"_filter_selected");
+
+
+ confirm_save = memnew( ConfirmationDialog );
+ confirm_save->set_as_toplevel(true);
+ add_child(confirm_save);
+
+
+ confirm_save->connect("confirmed", this,"_save_confirm_pressed");
+
+ makedialog = memnew( ConfirmationDialog );
+ makedialog->set_title("Create Folder");
+ VBoxContainer *makevb= memnew( VBoxContainer );
+ makedialog->add_child(makevb);
+ makedialog->set_child_rect(makevb);
+ makedirname = memnew( LineEdit );
+ makevb->add_margin_child("Name:",makedirname);
+ add_child(makedialog);
+ makedialog->register_text_enter(makedirname);
+ makedialog->connect("confirmed",this,"_make_dir_confirm");
+ mkdirerr = memnew( AcceptDialog );
+ mkdirerr->set_text("Could not create folder.");
+ add_child(mkdirerr);
+
+ exterr = memnew( AcceptDialog );
+ exterr->set_text("Must use a valid extension.");
+ add_child(exterr);
+
+
+ //update_file_list();
+ update_filters();
+ update_dir();
+
+ set_hide_on_ok(false);
+ vbox=vbc;
+
+
+ invalidated=true;
+ if (register_func)
+ register_func(this);
+
+ preview_wheel_timeout=0;
+ preview_wheel_index=0;
+ preview_waiting=false;
+
+}
+
+
+EditorFileDialog::~EditorFileDialog() {
+
+ if (unregister_func)
+ unregister_func(this);
+ memdelete(dir_access);
+}
+
+
+void EditorLineEditFileChooser::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("_browse"),&EditorLineEditFileChooser::_browse);
+ ObjectTypeDB::bind_method(_MD("_chosen"),&EditorLineEditFileChooser::_chosen);
+ ObjectTypeDB::bind_method(_MD("get_button:Button"),&EditorLineEditFileChooser::get_button);
+ ObjectTypeDB::bind_method(_MD("get_line_edit:LineEdit"),&EditorLineEditFileChooser::get_line_edit);
+ ObjectTypeDB::bind_method(_MD("get_file_dialog:EditorFileDialog"),&EditorLineEditFileChooser::get_file_dialog);
+
+}
+
+void EditorLineEditFileChooser::_chosen(const String& p_text){
+
+ line_edit->set_text(p_text);
+ line_edit->emit_signal("text_entered",p_text);
+}
+
+void EditorLineEditFileChooser::_browse() {
+
+ dialog->popup_centered_ratio();
+}
+
+EditorLineEditFileChooser::EditorLineEditFileChooser() {
+
+ line_edit = memnew( LineEdit );
+ add_child(line_edit);
+ line_edit->set_h_size_flags(SIZE_EXPAND_FILL);
+ button = memnew( Button );
+ button->set_text(" .. ");
+ add_child(button);
+ button->connect("pressed",this,"_browse");
+ dialog = memnew( EditorFileDialog);
+ add_child(dialog);
+ dialog->connect("file_selected",this,"_chosen");
+ dialog->connect("dir_selected",this,"_chosen");
+ dialog->connect("files_selected",this,"_chosen");
+
+}
diff --git a/tools/editor/editor_file_dialog.h b/tools/editor/editor_file_dialog.h
new file mode 100644
index 0000000000..6cfd970516
--- /dev/null
+++ b/tools/editor/editor_file_dialog.h
@@ -0,0 +1,245 @@
+/*************************************************************************/
+/* file_dialog.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2015 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 EDITORFILEDIALOG_H
+#define EDITORFILEDIALOG_H
+
+#include "scene/gui/dialogs.h"
+#include "scene/gui/item_list.h"
+#include "scene/gui/line_edit.h"
+#include "scene/gui/option_button.h"
+#include "scene/gui/dialogs.h"
+#include "os/dir_access.h"
+#include "scene/gui/box_container.h"
+#include "scene/gui/texture_frame.h"
+#include "scene/gui/tool_button.h"
+/**
+ @author Juan Linietsky <reduzio@gmail.com>
+*/
+class EditorFileDialog : public ConfirmationDialog {
+
+ OBJ_TYPE( EditorFileDialog, ConfirmationDialog );
+
+public:
+
+ enum DisplayMode {
+ DISPLAY_THUMBNAILS,
+ DISPLAY_LIST
+ };
+
+
+ enum Access {
+ ACCESS_RESOURCES,
+ ACCESS_USERDATA,
+ ACCESS_FILESYSTEM
+ };
+
+
+ enum Mode {
+ MODE_OPEN_FILE,
+ MODE_OPEN_FILES,
+ MODE_OPEN_DIR,
+ MODE_SAVE_FILE,
+ };
+
+ typedef Ref<Texture> (*GetIconFunc)(const String&);
+ typedef void (*RegisterFunc)(EditorFileDialog*);
+
+ static GetIconFunc get_icon_func;
+ static GetIconFunc get_large_icon_func;
+ static RegisterFunc register_func;
+ static RegisterFunc unregister_func;
+
+private:
+
+ ConfirmationDialog *makedialog;
+ LineEdit *makedirname;
+
+ Button *makedir;
+ Access access;
+ //Button *action;
+ VBoxContainer *vbox;
+ Mode mode;
+ LineEdit *dir;
+
+ ToolButton *dir_prev;
+ ToolButton *dir_next;
+ ToolButton *dir_up;
+
+ OptionButton *drives;
+ ItemList *item_list;
+ TextureFrame *preview;
+ VBoxContainer *preview_vb;
+ HBoxContainer *list_hb;
+ LineEdit *file;
+ AcceptDialog *mkdirerr;
+ AcceptDialog *exterr;
+ OptionButton *filter;
+ DirAccess *dir_access;
+ ConfirmationDialog *confirm_save;
+ ToolButton *mode_thumbnails;
+ ToolButton *mode_list;
+
+
+ ToolButton *favorite;
+
+ ToolButton *fav_up;
+ ToolButton *fav_down;
+ ToolButton *fav_rm;
+
+ ItemList *favorites;
+ ItemList *recent;
+
+ Vector<String> local_history;
+ int local_history_pos;
+ void _push_history();
+
+ Vector<String> filters;
+
+ bool preview_waiting;
+ int preview_wheel_index;
+ float preview_wheel_timeout;
+ static bool default_show_hidden_files;
+ bool show_hidden_files;
+ DisplayMode display_mode;
+
+ bool invalidated;
+
+ void update_dir();
+ void update_file_list();
+ void update_filters();
+
+ void _update_favorites();
+ void _favorite_toggled(bool p_toggle);
+ void _favorite_selected(int p_idx);
+ void _favorite_move_up();
+ void _favorite_move_down();
+
+
+
+ void _recent_selected(int p_idx);
+
+ void _item_selected(int p_item);
+ void _item_dc_selected(int p_item);
+
+ void _select_drive(int p_idx);
+ void _dir_entered(String p_dir);
+ void _file_entered(const String& p_file);
+ void _action_pressed();
+ void _save_confirm_pressed();
+ void _cancel_pressed();
+ void _filter_selected(int);
+ void _make_dir();
+ void _make_dir_confirm();
+
+ void _update_drives();
+
+ void _go_up();
+ void _go_back();
+ void _go_forward();
+
+ virtual void _post_popup();
+
+ void _save_to_recent();
+ //callback funtion is callback(String p_path,Ref<Texture> preview,Variant udata) preview null if could not load
+
+ void _thumbnail_result(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata);
+ void _thumbnail_done(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata);
+ void _request_single_thumbnail(const String& p_path);
+
+protected:
+
+ void _notification(int p_what);
+ static void _bind_methods();
+ //bind helpers
+public:
+
+ void clear_filters();
+ void add_filter(const String& p_filter);
+
+ void set_enable_multiple_selection(bool p_enable);
+ Vector<String> get_selected_files() const;
+
+ String get_current_dir() const;
+ String get_current_file() const;
+ String get_current_path() const;
+ void set_current_dir(const String& p_dir);
+ void set_current_file(const String& p_file);
+ void set_current_path(const String& p_path);
+
+ void set_display_mode(DisplayMode p_mode);
+ DisplayMode get_display_mode() const;
+
+ void set_mode(Mode p_mode);
+ Mode get_mode() const;
+
+ VBoxContainer *get_vbox();
+ LineEdit *get_line_edit() { return file; }
+
+ void set_access(Access p_access);
+ Access get_access() const;
+
+ void set_show_hidden_files(bool p_show);
+ bool is_showing_hidden_files() const;
+
+ static void set_default_show_hidden_files(bool p_show);
+
+ void invalidate();
+
+ EditorFileDialog();
+ ~EditorFileDialog();
+
+};
+
+class EditorLineEditFileChooser : public HBoxContainer {
+
+ OBJ_TYPE( EditorLineEditFileChooser, HBoxContainer );
+ Button *button;
+ LineEdit *line_edit;
+ EditorFileDialog *dialog;
+
+ void _chosen(const String& p_text);
+ void _browse();
+protected:
+ static void _bind_methods();
+public:
+
+ Button *get_button() { return button; }
+ LineEdit *get_line_edit() { return line_edit; }
+ EditorFileDialog *get_file_dialog() { return dialog; }
+
+ EditorLineEditFileChooser();
+};
+
+VARIANT_ENUM_CAST( EditorFileDialog::Mode );
+VARIANT_ENUM_CAST( EditorFileDialog::Access );
+VARIANT_ENUM_CAST( EditorFileDialog::DisplayMode );
+
+#endif // EDITORFILEDIALOG_H
diff --git a/tools/editor/editor_file_system.cpp b/tools/editor/editor_file_system.cpp
index ae083db0ff..d741087a9f 100644
--- a/tools/editor/editor_file_system.cpp
+++ b/tools/editor/editor_file_system.cpp
@@ -33,7 +33,7 @@
#include "os/file_access.h"
#include "editor_node.h"
#include "io/resource_saver.h"
-
+#include "editor_settings.h"
EditorFileSystem *EditorFileSystem::singleton=NULL;
@@ -357,7 +357,9 @@ void EditorFileSystem::_scan_scenes() {
String project=Globals::get_singleton()->get_resource_path();
- FileAccess *f =FileAccess::open(project+"/.fscache",FileAccess::READ);
+
+ String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("file_cache");
+ FileAccess *f =FileAccess::open(fscache,FileAccess::READ);
if (f) {
//read the disk cache
@@ -470,7 +472,9 @@ void EditorFileSystem::_scan_scenes() {
//save back the findings
- f=FileAccess::open(project+"/.fscache",FileAccess::WRITE);
+// String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("file_cache");
+
+ f=FileAccess::open(fscache,FileAccess::WRITE);
_save_type_cache_fs(scandir,f);
f->close();
memdelete(f);
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index 7157dbda96..688604ecfd 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -91,6 +91,7 @@
#include "plugins/polygon_2d_editor_plugin.h"
#include "plugins/navigation_polygon_editor_plugin.h"
#include "plugins/light_occluder_2d_editor_plugin.h"
+#include "plugins/color_ramp_editor_plugin.h"
// end
#include "tools/editor/io_plugins/editor_texture_import_plugin.h"
#include "tools/editor/io_plugins/editor_scene_import_plugin.h"
@@ -99,6 +100,7 @@
#include "tools/editor/io_plugins/editor_translation_import_plugin.h"
#include "tools/editor/io_plugins/editor_mesh_import_plugin.h"
+#include "plugins/editor_preview_plugins.h"
EditorNode *EditorNode::singleton=NULL;
@@ -320,6 +322,11 @@ void EditorNode::_fs_changed() {
E->get()->invalidate();
}
+
+ for(Set<EditorFileDialog*>::Element *E=editor_file_dialogs.front();E;E=E->next()) {
+
+ E->get()->invalidate();
+ }
}
void EditorNode::_sources_changed(bool p_exist) {
@@ -386,7 +393,7 @@ void EditorNode::edit_node(Node *p_node) {
void EditorNode::open_resource(const String& p_type) {
- file->set_mode(FileDialog::MODE_OPEN_FILE);
+ file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type(p_type,&extensions);
@@ -718,6 +725,96 @@ void EditorNode::_save_edited_subresources(Node* scene,Map<RES,bool>& processed,
}
+void EditorNode::_find_node_types(Node* p_node, int&count_2d, int&count_3d) {
+
+ if (p_node->is_type("Viewport") || (p_node!=get_edited_scene() && p_node->get_owner()!=get_edited_scene()))
+ return;
+
+ if (p_node->is_type("CanvasItem"))
+ count_2d++;
+ else if (p_node->is_type("Spatial"))
+ count_3d++;
+
+ for(int i=0;i<p_node->get_child_count();i++)
+ _find_node_types(p_node->get_child(i),count_2d,count_3d);
+
+}
+
+
+void EditorNode::_save_scene_with_preview(String p_file) {
+
+ int c2d=0;
+ int c3d=0;
+
+ EditorProgress save("save","Saving Scene",4);
+ save.step("Analyzing",0);
+ _find_node_types(get_edited_scene(),c2d,c3d);
+
+ RID viewport;
+ bool is2d;
+ if (c3d<c2d) {
+ viewport=scene_root->get_viewport();
+ is2d=true;
+ } else {
+ viewport=SpatialEditor::get_singleton()->get_editor_viewport(0)->get_viewport_node()->get_viewport();
+ is2d=false;
+
+ }
+ save.step("Creating Thumbnail",1);
+ //current view?
+ int screen =-1;
+ for(int i=0;i<editor_table.size();i++) {
+ if (editor_plugin_screen==editor_table[i]) {
+ screen=i;
+ break;
+ }
+ }
+
+ _editor_select(is2d?0:1);
+
+ VS::get_singleton()->viewport_queue_screen_capture(viewport);
+ save.step("Creating Thumbnail",2);
+ save.step("Creating Thumbnail",3);
+ Image img = VS::get_singleton()->viewport_get_screen_capture(viewport);
+ int preview_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");;
+ int width,height;
+ if (img.get_width() > preview_size && img.get_width() >= img.get_height()) {
+
+ width=preview_size;
+ height = img.get_height() * preview_size / img.get_width();
+ } else if (img.get_height() > preview_size && img.get_height() >= img.get_width()) {
+
+ height=preview_size;
+ width = img.get_width() * preview_size / img.get_height();
+ } else {
+
+ width=img.get_width();
+ height=img.get_height();
+ }
+
+ img.convert(Image::FORMAT_RGB);
+ img.resize(width,height);
+
+ String pfile = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/last_scene_preview.png");
+ img.save_png(pfile);
+ Vector<uint8_t> imgdata = FileAccess::get_file_as_array(pfile);
+
+ print_line("img data is "+itos(imgdata.size()));
+
+ if (scene_import_metadata.is_null())
+ scene_import_metadata = Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) );
+ scene_import_metadata->set_option("thumbnail",imgdata);
+
+ //tamanio tel thumbnail
+ if (screen!=-1) {
+ _editor_select(screen);
+ }
+ save.step("Saving Scene",4);
+ _save_scene(p_file);
+
+}
+
+
void EditorNode::_save_scene(String p_file) {
Node *scene = edited_scene;
@@ -1016,7 +1113,9 @@ void EditorNode::_dialog_action(String p_file) {
if (file->get_mode()==FileDialog::MODE_SAVE_FILE) {
- _save_scene(p_file);
+ //_save_scene(p_file);
+ _save_scene_with_preview(p_file);
+
}
} break;
@@ -1024,7 +1123,8 @@ void EditorNode::_dialog_action(String p_file) {
case FILE_SAVE_AND_RUN: {
if (file->get_mode()==FileDialog::MODE_SAVE_FILE) {
- _save_scene(p_file);
+ //_save_scene(p_file);
+ _save_scene_with_preview(p_file);
_run(false);
}
} break;
@@ -1177,7 +1277,8 @@ void EditorNode::_dialog_action(String p_file) {
if (file->get_mode()==FileDialog::MODE_SAVE_FILE) {
- _save_scene(p_file);
+ //_save_scene(p_file);
+ _save_scene_with_preview(p_file);
}
} break;
@@ -1505,7 +1606,8 @@ void EditorNode::_run(bool p_current,const String& p_custom) {
return;
}
- _save_scene(scene->get_filename());
+ //_save_scene(scene->get_filename());
+ _save_scene_with_preview(scene->get_filename());
}
}
@@ -1608,7 +1710,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
//print_tree();
- file->set_mode(FileDialog::MODE_OPEN_FILE);
+ file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
//not for now?
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions);
@@ -1659,7 +1761,8 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
Node *scene = edited_scene;
if (scene && scene->get_filename()!="") {
- _save_scene(scene->get_filename());
+ //_save_scene(scene->get_filename());
+ _save_scene_with_preview(scene->get_filename());
return;
};
// fallthrough to save_as
@@ -1678,7 +1781,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
break;
}
- file->set_mode(FileDialog::MODE_SAVE_FILE);
+ file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
bool relpaths = (scene->has_meta("__editor_relpaths__") && scene->get_meta("__editor_relpaths__").operator bool());
@@ -1761,7 +1864,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
bool relpaths = (scene->has_meta("__editor_relpaths__") && scene->get_meta("__editor_relpaths__").operator bool());
- file->set_mode(FileDialog::MODE_SAVE_FILE);
+ file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
file->set_current_path(cpath);
file->set_title("Save Translatable Strings");
@@ -1810,7 +1913,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
break;
}
- file->set_mode(FileDialog::MODE_SAVE_FILE);
+ file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
List<String> extensions;
Ref<PackedScene> sd = memnew( PackedScene );
@@ -3132,6 +3235,7 @@ void EditorNode::register_editor_types() {
ObjectTypeDB::register_type<EditorImportPlugin>();
ObjectTypeDB::register_type<EditorScenePostImport>();
ObjectTypeDB::register_type<EditorScript>();
+ ObjectTypeDB::register_type<EditorFileDialog>();
//ObjectTypeDB::register_type<EditorImporter>();
@@ -3282,6 +3386,16 @@ void EditorNode::_file_dialog_unregister(FileDialog *p_dialog){
singleton->file_dialogs.erase(p_dialog);
}
+void EditorNode::_editor_file_dialog_register(EditorFileDialog *p_dialog) {
+
+ singleton->editor_file_dialogs.insert(p_dialog);
+}
+
+void EditorNode::_editor_file_dialog_unregister(EditorFileDialog *p_dialog){
+
+ singleton->editor_file_dialogs.erase(p_dialog);
+}
+
Vector<EditorNodeInitCallback> EditorNode::_init_callbacks;
Error EditorNode::export_platform(const String& p_platform, const String& p_path, bool p_debug,const String& p_password,bool p_quit_after) {
@@ -3334,6 +3448,11 @@ EditorNode::EditorNode() {
FileDialog::register_func=_file_dialog_register;
FileDialog::unregister_func=_file_dialog_unregister;
+ EditorFileDialog::get_icon_func=_file_dialog_get_icon;
+ EditorFileDialog::register_func=_editor_file_dialog_register;
+ EditorFileDialog::unregister_func=_editor_file_dialog_unregister;
+
+
editor_import_export = memnew( EditorImportExport );
add_child(editor_import_export);
@@ -3358,6 +3477,9 @@ EditorNode::EditorNode() {
editor_register_icons(theme);
editor_register_fonts(theme);
+ //theme->set_icon("folder","EditorFileDialog",Theme::get_default()->get_icon("folder","EditorFileDialog"));
+ //theme->set_color("files_disabled","EditorFileDialog",Color(0,0,0,0.7));
+
String global_font = EditorSettings::get_singleton()->get("global/font");
if (global_font!="") {
Ref<Font> fnt = ResourceLoader::load(global_font);
@@ -3376,6 +3498,8 @@ EditorNode::EditorNode() {
theme->set_stylebox("EditorFocus","EditorStyles",focus_sbt);
+ resource_preview = memnew( EditorResourcePreview );
+ add_child(resource_preview);
progress_dialog = memnew( ProgressDialog );
gui_base->add_child(progress_dialog);
@@ -3473,6 +3597,7 @@ EditorNode::EditorNode() {
animation_panel=pc;
animation_panel->hide();
+
HBoxContainer *animation_hb = memnew( HBoxContainer);
animation_vb->add_child(animation_hb);
@@ -4031,7 +4156,7 @@ EditorNode::EditorNode() {
file_templates->add_filter("*.tpz ; Template Package");
- file = memnew( FileDialog );
+ file = memnew( EditorFileDialog );
gui_base->add_child(file);
file->set_current_dir("res://");
@@ -4105,8 +4230,9 @@ EditorNode::EditorNode() {
editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_TEXTURE_2D) )));
- editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_TEXTURE_3D) )));
editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_ATLAS) )));
+ editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_LARGE) )));
+ editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_TEXTURE_3D) )));
Ref<EditorSceneImportPlugin> _scene_import = memnew(EditorSceneImportPlugin(this) );
Ref<EditorSceneImporterCollada> _collada_import = memnew( EditorSceneImporterCollada);
_scene_import->add_importer(_collada_import);
@@ -4157,10 +4283,19 @@ EditorNode::EditorNode() {
add_editor_plugin( memnew( Polygon2DEditorPlugin(this) ) );
add_editor_plugin( memnew( LightOccluder2DEditorPlugin(this) ) );
add_editor_plugin( memnew( NavigationPolygonEditorPlugin(this) ) );
+ add_editor_plugin( memnew( ColorRampEditorPlugin(this) ) );
for(int i=0;i<EditorPlugins::get_plugin_count();i++)
add_editor_plugin( EditorPlugins::create(i,this) );
+
+ resource_preview->add_preview_generator( Ref<EditorTexturePreviewPlugin>( memnew(EditorTexturePreviewPlugin )));
+ resource_preview->add_preview_generator( Ref<EditorPackedScenePreviewPlugin>( memnew(EditorPackedScenePreviewPlugin )));
+ resource_preview->add_preview_generator( Ref<EditorMaterialPreviewPlugin>( memnew(EditorMaterialPreviewPlugin )));
+ resource_preview->add_preview_generator( Ref<EditorScriptPreviewPlugin>( memnew(EditorScriptPreviewPlugin )));
+ resource_preview->add_preview_generator( Ref<EditorSamplePreviewPlugin>( memnew(EditorSamplePreviewPlugin )));
+ resource_preview->add_preview_generator( Ref<EditorMeshPreviewPlugin>( memnew(EditorMeshPreviewPlugin )));
+
circle_step_msec=OS::get_singleton()->get_ticks_msec();
circle_step_frame=OS::get_singleton()->get_frames_drawn();;
circle_step=0;
diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h
index 614cec5bcc..365dff84ee 100644
--- a/tools/editor/editor_node.h
+++ b/tools/editor/editor_node.h
@@ -78,7 +78,7 @@
#include "tools/editor/editor_plugin.h"
#include "fileserver/editor_file_server.h"
-
+#include "editor_resource_preview.h"
@@ -238,7 +238,7 @@ class EditorNode : public Node {
EditorSettingsDialog *settings_config_dialog;
RunSettingsDialog *run_settings_dialog;
ProjectSettings *project_settings;
- FileDialog *file;
+ EditorFileDialog *file;
FileDialog *file_templates;
FileDialog *file_export;
FileDialog *file_export_lib;
@@ -304,6 +304,7 @@ class EditorNode : public Node {
EditorSelection *editor_selection;
ProjectExport *project_export;
ProjectExportDialog *project_export_settings;
+ EditorResourcePreview *resource_preview;
EditorFileServer *file_server;
@@ -381,11 +382,15 @@ class EditorNode : public Node {
String import_reload_fn;
Set<FileDialog*> file_dialogs;
+ Set<EditorFileDialog*> editor_file_dialogs;
+
Map<String,Ref<Texture> > icon_type_cache;
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();
@@ -394,6 +399,9 @@ class EditorNode : public Node {
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);
+
struct ExportDefer {
String platform;
diff --git a/tools/editor/editor_resource_preview.cpp b/tools/editor/editor_resource_preview.cpp
new file mode 100644
index 0000000000..f684b49a2c
--- /dev/null
+++ b/tools/editor/editor_resource_preview.cpp
@@ -0,0 +1,261 @@
+#include "editor_resource_preview.h"
+#include "editor_settings.h"
+#include "os/file_access.h"
+#include "io/resource_loader.h"
+#include "io/resource_saver.h"
+#include "globals.h"
+
+
+Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String& p_path) {
+
+ RES res = ResourceLoader::load(p_path);
+ if (!res.is_valid())
+ return res;
+ return generate(res);
+}
+
+EditorResourcePreviewGenerator::EditorResourcePreviewGenerator() {
+
+
+}
+
+
+EditorResourcePreview* EditorResourcePreview::singleton=NULL;
+
+
+void EditorResourcePreview::_thread_func(void *ud) {
+
+ EditorResourcePreview *erp=(EditorResourcePreview*)ud;
+ erp->_thread();
+
+}
+
+
+void EditorResourcePreview::_preview_ready(const String& p_str,const Ref<Texture>& p_texture,ObjectID id,const StringName& p_func,const Variant& p_ud) {
+
+ //print_line("preview is ready");
+ preview_mutex->lock();
+
+ Item item;
+ item.order=order++;
+ item.preview=p_texture;
+ cache[p_str]=item;
+
+ Object *recv = ObjectDB::get_instance(id);
+ if (recv) {
+ recv->call_deferred(p_func,p_str,p_texture,p_ud);
+ }
+
+ preview_mutex->unlock();
+}
+
+Ref<Texture> EditorResourcePreview::_generate_preview(const QueueItem& p_item,const String& cache_base) {
+
+ String type = ResourceLoader::get_resource_type(p_item.path);
+ //print_line("resource type is: "+type);
+
+ if (type=="")
+ return Ref<Texture>(); //could not guess type
+
+ Ref<Texture> generated;
+
+ for(int i=0;i<preview_generators.size();i++) {
+ if (!preview_generators[i]->handles(type))
+ continue;
+ generated = preview_generators[i]->generate_from_path(p_item.path);
+
+ break;
+ }
+
+ if (generated.is_valid()) {
+ //print_line("was generated");
+ int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");
+ //wow it generated a preview... save cache
+ ResourceSaver::save(cache_base+".png",generated);
+ FileAccess *f=FileAccess::open(cache_base+".txt",FileAccess::WRITE);
+ f->store_line(itos(thumbnail_size));
+ f->store_line(itos(FileAccess::get_modified_time(p_item.path)));
+ f->store_line(FileAccess::get_md5(p_item.path));
+ memdelete(f);
+ } else {
+ //print_line("was not generated");
+
+ }
+
+ return generated;
+}
+
+void EditorResourcePreview::_thread() {
+
+ //print_line("begin thread");
+ while(!exit) {
+
+ //print_line("wait for semaphore");
+ preview_sem->wait();
+ preview_mutex->lock();
+
+ //print_line("blue team go");
+
+ if (queue.size()) {
+
+
+
+ QueueItem item = queue.front()->get();
+ queue.pop_front();
+ preview_mutex->unlock();
+
+ Ref<Texture> texture;
+
+ //print_line("pop from queue "+item.path);
+
+ uint64_t modtime = FileAccess::get_modified_time(item.path);
+ int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");
+
+ if (cache.has(item.path)) {
+ //already has it because someone loaded it, just let it know it's ready
+ call_deferred("_preview_ready",item.path,cache[item.path].preview,item.id,item.function,item.userdata);
+
+ } else {
+
+
+ String temp_path=EditorSettings::get_singleton()->get_settings_path().plus_file("tmp");
+ String cache_base = Globals::get_singleton()->globalize_path(item.path).md5_text();
+ cache_base = temp_path.plus_file("resthumb-"+cache_base);
+
+ //does not have it, try to load a cached thumbnail
+
+ String file = cache_base+".txt";
+ //print_line("cachetxt at "+file);
+ FileAccess *f=FileAccess::open(file,FileAccess::READ);
+ if (!f) {
+
+ //print_line("generate because not cached");
+
+ //generate
+ texture=_generate_preview(item,cache_base);
+ } else {
+
+ int tsize = f->get_line().to_int64();
+ uint64_t last_modtime = f->get_line().to_int64();
+
+ bool cache_valid = true;
+
+ if (tsize!=thumbnail_size) {
+ cache_valid=false;
+ memdelete(f);
+ } else if (last_modtime!=modtime) {
+
+ String last_md5 = f->get_line();
+ String md5 = FileAccess::get_md5(item.path);
+ memdelete(f);
+
+ if (last_md5!=md5) {
+
+ cache_valid=false;
+ } else {
+ //update modified time
+
+ f=FileAccess::open(file,FileAccess::WRITE);
+ f->store_line(itos(modtime));
+ f->store_line(md5);
+ memdelete(f);
+ }
+ } else {
+ memdelete(f);
+ }
+
+ if (cache_valid) {
+
+ texture = ResourceLoader::load(cache_base+".png","ImageTexture",true);
+ if (!texture.is_valid()) {
+ //well fuck
+ cache_valid=false;
+ }
+ }
+
+ if (!cache_valid) {
+
+ texture=_generate_preview(item,cache_base);
+ }
+
+ }
+
+ //print_line("notify of preview ready");
+ call_deferred("_preview_ready",item.path,texture,item.id,item.function,item.userdata);
+
+ }
+
+ } else {
+ preview_mutex->unlock();
+ }
+
+ }
+}
+
+
+
+
+void EditorResourcePreview::queue_resource_preview(const String& p_path, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata) {
+
+ ERR_FAIL_NULL(p_receiver);
+ preview_mutex->lock();
+ if (cache.has(p_path)) {
+ cache[p_path].order=order++;
+ p_receiver->call_deferred(p_receiver_func,p_path,cache[p_path].preview,p_userdata);
+ preview_mutex->unlock();
+ return;
+
+ }
+
+ //print_line("send to thread "+p_path);
+ QueueItem item;
+ item.function=p_receiver_func;
+ item.id=p_receiver->get_instance_ID();
+ item.path=p_path;
+ item.userdata=p_userdata;
+
+ queue.push_back(item);
+ preview_mutex->unlock();
+ preview_sem->post();
+
+}
+
+void EditorResourcePreview::add_preview_generator(const Ref<EditorResourcePreviewGenerator>& p_generator) {
+
+ preview_generators.push_back(p_generator);
+}
+
+EditorResourcePreview* EditorResourcePreview::get_singleton() {
+
+ return singleton;
+}
+
+void EditorResourcePreview::_bind_methods() {
+
+ ObjectTypeDB::bind_method("_preview_ready",&EditorResourcePreview::_preview_ready);
+}
+
+EditorResourcePreview::EditorResourcePreview() {
+ singleton=this;
+ preview_mutex = Mutex::create();
+ preview_sem = Semaphore::create();
+ order=0;
+ exit=false;
+
+ thread = Thread::create(_thread_func,this);
+}
+
+
+EditorResourcePreview::~EditorResourcePreview()
+{
+
+ exit=true;
+ preview_sem->post();
+ Thread::wait_to_finish(thread);
+ memdelete(thread);
+ memdelete(preview_mutex);
+ memdelete(preview_sem);
+
+
+}
+
diff --git a/tools/editor/editor_resource_preview.h b/tools/editor/editor_resource_preview.h
new file mode 100644
index 0000000000..aadae75597
--- /dev/null
+++ b/tools/editor/editor_resource_preview.h
@@ -0,0 +1,95 @@
+#ifndef EDITORRESOURCEPREVIEW_H
+#define EDITORRESOURCEPREVIEW_H
+
+#include "scene/main/node.h"
+#include "os/semaphore.h"
+#include "os/thread.h"
+#include "scene/resources/texture.h"
+
+/* make previews for:
+*packdscene
+*wav
+*image
+*mesh
+-font
+*script
+*material
+-shader
+-shader graph?
+-navigation mesh
+-collision?
+-occluder polygon
+-navigation polygon
+-tileset
+-curve and curve2D
+*/
+
+
+class EditorResourcePreviewGenerator : public Reference {
+
+ OBJ_TYPE(EditorResourcePreviewGenerator,Reference );
+
+public:
+
+ virtual bool handles(const String& p_type) const=0;
+ virtual Ref<Texture> generate(const RES& p_from)=0;
+ virtual Ref<Texture> generate_from_path(const String& p_path);
+
+ EditorResourcePreviewGenerator();
+};
+
+
+class EditorResourcePreview : public Node {
+
+ OBJ_TYPE(EditorResourcePreview,Node);
+
+
+ static EditorResourcePreview* singleton;
+
+ struct QueueItem {
+ String path;
+ ObjectID id;
+ StringName function;
+ Variant userdata;
+ };
+
+ List<QueueItem> queue;
+
+ Mutex *preview_mutex;
+ Semaphore *preview_sem;
+ Thread *thread;
+ bool exit;
+
+ struct Item {
+ Ref<Texture> preview;
+ int order;
+ };
+
+ int order;
+
+ Map<String,Item> cache;
+
+ void _preview_ready(const String& p_str,const Ref<Texture>& p_texture, ObjectID id, const StringName &p_func, const Variant &p_ud);
+ Ref<Texture> _generate_preview(const QueueItem& p_item, const String &cache_base);
+
+ static void _thread_func(void *ud);
+ void _thread();
+
+ Vector<Ref<EditorResourcePreviewGenerator> > preview_generators;
+protected:
+
+ static void _bind_methods();
+public:
+
+ static EditorResourcePreview* get_singleton();
+
+ //callback funtion is callback(String p_path,Ref<Texture> preview,Variant udata) preview null if could not load
+ void queue_resource_preview(const String& p_path, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata);
+
+ void add_preview_generator(const Ref<EditorResourcePreviewGenerator>& p_generator);
+
+ EditorResourcePreview();
+ ~EditorResourcePreview();
+};
+
+#endif // EDITORRESOURCEPREVIEW_H
diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp
index f49d3b496d..361a86b88e 100644
--- a/tools/editor/editor_settings.cpp
+++ b/tools/editor/editor_settings.cpp
@@ -224,6 +224,28 @@ void EditorSettings::create() {
dir->change_dir("..");
}
+ if (dir->change_dir("config")!=OK) {
+ dir->make_dir("config");
+ } else {
+
+ dir->change_dir("..");
+ }
+
+ dir->change_dir("config");
+
+ String pcp=Globals::get_singleton()->get_resource_path();
+ if (pcp.ends_with("/"))
+ pcp=config_path.substr(0,pcp.size()-1);
+ pcp=pcp.get_file()+"-"+pcp.md5_text();
+
+ if (dir->change_dir(pcp)) {
+ dir->make_dir(pcp);
+ } else {
+ dir->change_dir("..");
+ }
+
+ dir->change_dir("..");
+
// path at least is validated, so validate config file
@@ -244,6 +266,7 @@ void EditorSettings::create() {
}
singleton->config_file_path=config_file_path;
+ singleton->project_config_path=pcp;
singleton->settings_path=config_path+"/"+config_dir;
if (OS::get_singleton()->is_stdout_verbose()) {
@@ -251,7 +274,7 @@ void EditorSettings::create() {
print_line("EditorSettings: Load OK!");
}
-
+ singleton->load_favorites();
singleton->scan_plugins();
return;
@@ -448,6 +471,8 @@ void EditorSettings::_load_defaults() {
set("text_editor/create_signal_callbacks",true);
set("file_dialog/show_hidden_files", false);
+ set("file_dialog/thumbnail_size", 64);
+ hints["file_dialog/thumbnail_size"]=PropertyInfo(Variant::INT,"file_dialog/thumbnail_size",PROPERTY_HINT_RANGE,"32,128,16");
set("animation/autorename_animation_tracks",true);
set("animation/confirm_insert_track",true);
@@ -646,6 +671,71 @@ void EditorSettings::set_plugin_enabled(const String& p_plugin, bool p_enabled)
}
+void EditorSettings::set_favorite_dirs(const Vector<String>& p_favorites) {
+
+ favorite_dirs=p_favorites;
+ FileAccess *f = FileAccess::open(get_project_settings_path().plus_file("favorite_dirs"),FileAccess::WRITE);
+ if (f) {
+ for(int i=0;i<favorite_dirs.size();i++)
+ f->store_line(favorite_dirs[i]);
+ memdelete(f);
+ }
+
+}
+
+Vector<String> EditorSettings::get_favorite_dirs() const {
+
+ return favorite_dirs;
+}
+
+
+void EditorSettings::set_recent_dirs(const Vector<String>& p_recent) {
+
+ recent_dirs=p_recent;
+ FileAccess *f = FileAccess::open(get_project_settings_path().plus_file("recent_dirs"),FileAccess::WRITE);
+ if (f) {
+ for(int i=0;i<recent_dirs.size();i++)
+ f->store_line(recent_dirs[i]);
+ memdelete(f);
+ }
+}
+
+Vector<String> EditorSettings::get_recent_dirs() const {
+
+ return recent_dirs;
+}
+
+String EditorSettings::get_project_settings_path() const {
+
+
+ return get_settings_path().plus_file("config").plus_file(project_config_path);
+}
+
+
+void EditorSettings::load_favorites() {
+
+ FileAccess *f = FileAccess::open(get_project_settings_path().plus_file("favorite_dirs"),FileAccess::READ);
+ if (f) {
+ String line = f->get_line().strip_edges();
+ while(line!="") {
+ favorite_dirs.push_back(line);
+ line = f->get_line().strip_edges();
+ }
+ memdelete(f);
+ }
+
+ f = FileAccess::open(get_project_settings_path().plus_file("recent_dirs"),FileAccess::READ);
+ if (f) {
+ String line = f->get_line().strip_edges();
+ while(line!="") {
+ recent_dirs.push_back(line);
+ line = f->get_line().strip_edges();
+ }
+ memdelete(f);
+ }
+
+}
+
void EditorSettings::_bind_methods() {
diff --git a/tools/editor/editor_settings.h b/tools/editor/editor_settings.h
index 1594719a92..6b7e6eb989 100644
--- a/tools/editor/editor_settings.h
+++ b/tools/editor/editor_settings.h
@@ -88,6 +88,11 @@ private:
void _load_defaults();
+ String project_config_path;
+
+ Vector<String> favorite_dirs;
+ Vector<String> recent_dirs;
+
protected:
static void _bind_methods();
@@ -102,6 +107,7 @@ public:
static EditorSettings *get_singleton();
void erase(String p_var);
String get_settings_path() const;
+ String get_project_settings_path() const;
const Map<String,Plugin>& get_plugins() const { return plugins; }
@@ -125,6 +131,14 @@ public:
void add_property_hint(const PropertyInfo& p_hint);
+ void set_favorite_dirs(const Vector<String>& p_favorite_dirs);
+ Vector<String> get_favorite_dirs() const;
+
+ void set_recent_dirs(const Vector<String>& p_recent_dirs);
+ Vector<String> get_recent_dirs() const;
+
+ void load_favorites();
+
EditorSettings();
~EditorSettings();
diff --git a/tools/editor/editor_sub_scene.cpp b/tools/editor/editor_sub_scene.cpp
index 49385daeaa..2a6eba2554 100644
--- a/tools/editor/editor_sub_scene.cpp
+++ b/tools/editor/editor_sub_scene.cpp
@@ -215,7 +215,7 @@ EditorSubScene::EditorSubScene() {
tree->set_v_size_flags(SIZE_EXPAND_FILL);
vb->add_margin_child("Import From Node:",tree)->set_v_size_flags(SIZE_EXPAND_FILL);
- file_dialog = memnew( FileDialog );
+ file_dialog = memnew( EditorFileDialog );
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions);
@@ -224,7 +224,7 @@ EditorSubScene::EditorSubScene() {
file_dialog->add_filter("*."+E->get());
}
- file_dialog->set_mode(FileDialog::MODE_OPEN_FILE);
+ file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE);
add_child(file_dialog);
file_dialog->connect("file_selected",this,"_path_selected");
diff --git a/tools/editor/editor_sub_scene.h b/tools/editor/editor_sub_scene.h
index 9d78dab2a2..dfd6c531e2 100644
--- a/tools/editor/editor_sub_scene.h
+++ b/tools/editor/editor_sub_scene.h
@@ -31,7 +31,7 @@
#include "scene/gui/dialogs.h"
#include "scene/gui/tree.h"
-#include "scene/gui/file_dialog.h"
+#include "tools/editor/editor_file_dialog.h"
class EditorSubScene : public ConfirmationDialog {
@@ -42,7 +42,7 @@ class EditorSubScene : public ConfirmationDialog {
Tree *tree;
Node *scene;
- FileDialog *file_dialog;
+ EditorFileDialog *file_dialog;
void _fill_tree(Node* p_node,TreeItem *p_parent);
void _reown(Node* p_node,List<Node*> *p_to_reown);
diff --git a/tools/editor/icons/icon_arrow_left.png b/tools/editor/icons/icon_arrow_left.png
new file mode 100644
index 0000000000..b72ac2a10d
--- /dev/null
+++ b/tools/editor/icons/icon_arrow_left.png
Binary files differ
diff --git a/tools/editor/icons/icon_arrow_left_disabled.png b/tools/editor/icons/icon_arrow_left_disabled.png
new file mode 100644
index 0000000000..f1f9d0f988
--- /dev/null
+++ b/tools/editor/icons/icon_arrow_left_disabled.png
Binary files differ
diff --git a/tools/editor/icons/icon_arrow_right.png b/tools/editor/icons/icon_arrow_right.png
new file mode 100644
index 0000000000..d0a48b01ac
--- /dev/null
+++ b/tools/editor/icons/icon_arrow_right.png
Binary files differ
diff --git a/tools/editor/icons/icon_arrow_right_disabled.png b/tools/editor/icons/icon_arrow_right_disabled.png
new file mode 100644
index 0000000000..840cd0da0a
--- /dev/null
+++ b/tools/editor/icons/icon_arrow_right_disabled.png
Binary files differ
diff --git a/tools/editor/icons/icon_arrow_up.png b/tools/editor/icons/icon_arrow_up.png
new file mode 100644
index 0000000000..10aac0e0f6
--- /dev/null
+++ b/tools/editor/icons/icon_arrow_up.png
Binary files differ
diff --git a/tools/editor/icons/icon_arrow_up_disabled.png b/tools/editor/icons/icon_arrow_up_disabled.png
new file mode 100644
index 0000000000..fb46aa1373
--- /dev/null
+++ b/tools/editor/icons/icon_arrow_up_disabled.png
Binary files differ
diff --git a/tools/editor/icons/icon_color_ramp.png b/tools/editor/icons/icon_color_ramp.png
new file mode 100644
index 0000000000..9031b5ec53
--- /dev/null
+++ b/tools/editor/icons/icon_color_ramp.png
Binary files differ
diff --git a/tools/editor/icons/icon_favorites.png b/tools/editor/icons/icon_favorites.png
index da4713d032..4a3b575f95 100644
--- a/tools/editor/icons/icon_favorites.png
+++ b/tools/editor/icons/icon_favorites.png
Binary files differ
diff --git a/tools/editor/icons/icon_file_big.png b/tools/editor/icons/icon_file_big.png
new file mode 100644
index 0000000000..887a4ee05c
--- /dev/null
+++ b/tools/editor/icons/icon_file_big.png
Binary files differ
diff --git a/tools/editor/icons/icon_file_list.png b/tools/editor/icons/icon_file_list.png
new file mode 100644
index 0000000000..e5e9213e61
--- /dev/null
+++ b/tools/editor/icons/icon_file_list.png
Binary files differ
diff --git a/tools/editor/icons/icon_file_thumbnail.png b/tools/editor/icons/icon_file_thumbnail.png
new file mode 100644
index 0000000000..c32be5e8f8
--- /dev/null
+++ b/tools/editor/icons/icon_file_thumbnail.png
Binary files differ
diff --git a/tools/editor/icons/icon_folder_big.png b/tools/editor/icons/icon_folder_big.png
new file mode 100644
index 0000000000..988e070f98
--- /dev/null
+++ b/tools/editor/icons/icon_folder_big.png
Binary files differ
diff --git a/tools/editor/icons/icon_item_list.png b/tools/editor/icons/icon_item_list.png
new file mode 100644
index 0000000000..f930e7ecaa
--- /dev/null
+++ b/tools/editor/icons/icon_item_list.png
Binary files differ
diff --git a/tools/editor/icons/icon_remove.png b/tools/editor/icons/icon_remove.png
index 10e56d5bb8..f0f814e304 100644
--- a/tools/editor/icons/icon_remove.png
+++ b/tools/editor/icons/icon_remove.png
Binary files differ
diff --git a/tools/editor/icons/icon_remove_small.png b/tools/editor/icons/icon_remove_small.png
new file mode 100644
index 0000000000..e0903689cf
--- /dev/null
+++ b/tools/editor/icons/icon_remove_small.png
Binary files differ
diff --git a/tools/editor/icons/icon_wait_no_preview.png b/tools/editor/icons/icon_wait_no_preview.png
new file mode 100644
index 0000000000..5d20cd99ec
--- /dev/null
+++ b/tools/editor/icons/icon_wait_no_preview.png
Binary files differ
diff --git a/tools/editor/icons/icon_wait_preview_1.png b/tools/editor/icons/icon_wait_preview_1.png
new file mode 100644
index 0000000000..0aab42e04a
--- /dev/null
+++ b/tools/editor/icons/icon_wait_preview_1.png
Binary files differ
diff --git a/tools/editor/icons/icon_wait_preview_2.png b/tools/editor/icons/icon_wait_preview_2.png
new file mode 100644
index 0000000000..f476b9ce1f
--- /dev/null
+++ b/tools/editor/icons/icon_wait_preview_2.png
Binary files differ
diff --git a/tools/editor/icons/icon_wait_preview_3.png b/tools/editor/icons/icon_wait_preview_3.png
new file mode 100644
index 0000000000..2775d1ef43
--- /dev/null
+++ b/tools/editor/icons/icon_wait_preview_3.png
Binary files differ
diff --git a/tools/editor/icons/icon_wait_preview_4.png b/tools/editor/icons/icon_wait_preview_4.png
new file mode 100644
index 0000000000..2eaa86fec9
--- /dev/null
+++ b/tools/editor/icons/icon_wait_preview_4.png
Binary files differ
diff --git a/tools/editor/icons/icon_wait_preview_5.png b/tools/editor/icons/icon_wait_preview_5.png
new file mode 100644
index 0000000000..6590644bc1
--- /dev/null
+++ b/tools/editor/icons/icon_wait_preview_5.png
Binary files differ
diff --git a/tools/editor/icons/icon_wait_preview_6.png b/tools/editor/icons/icon_wait_preview_6.png
new file mode 100644
index 0000000000..307e412310
--- /dev/null
+++ b/tools/editor/icons/icon_wait_preview_6.png
Binary files differ
diff --git a/tools/editor/icons/icon_wait_preview_7.png b/tools/editor/icons/icon_wait_preview_7.png
new file mode 100644
index 0000000000..b0edc94d93
--- /dev/null
+++ b/tools/editor/icons/icon_wait_preview_7.png
Binary files differ
diff --git a/tools/editor/icons/icon_wait_preview_8.png b/tools/editor/icons/icon_wait_preview_8.png
new file mode 100644
index 0000000000..67a2f48ec3
--- /dev/null
+++ b/tools/editor/icons/icon_wait_preview_8.png
Binary files differ
diff --git a/tools/editor/io_plugins/editor_font_import_plugin.cpp b/tools/editor/io_plugins/editor_font_import_plugin.cpp
index 375333ddf6..10a3877529 100644
--- a/tools/editor/io_plugins/editor_font_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_font_import_plugin.cpp
@@ -28,7 +28,7 @@
/*************************************************************************/
#include "editor_font_import_plugin.h"
#include "scene/gui/dialogs.h"
-#include "scene/gui/file_dialog.h"
+#include "tools/editor/editor_file_dialog.h"
#include "tools/editor/editor_node.h"
#include "os/file_access.h"
#include "editor_atlas.h"
@@ -379,8 +379,8 @@ class EditorFontImportDialog : public ConfirmationDialog {
OBJ_TYPE(EditorFontImportDialog, ConfirmationDialog);
- LineEditFileChooser *source;
- LineEditFileChooser *dest;
+ EditorLineEditFileChooser *source;
+ EditorLineEditFileChooser *dest;
SpinBox *font_size;
LineEdit *test_string;
ColorPickerButton *test_color;
@@ -612,9 +612,9 @@ public:
hbc->add_child(vbr);
vbr->set_h_size_flags(SIZE_EXPAND_FILL);
- source = memnew( LineEditFileChooser );
- source->get_file_dialog()->set_access(FileDialog::ACCESS_FILESYSTEM);
- source->get_file_dialog()->set_mode(FileDialog::MODE_OPEN_FILE);
+ 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_line_edit()->connect("text_entered",this,"_src_changed");
@@ -626,7 +626,7 @@ public:
font_size->set_max(256);
font_size->set_val(16);
font_size->connect("value_changed",this,"_font_size_changed");
- dest = memnew( LineEditFileChooser );
+ dest = memnew( EditorLineEditFileChooser );
//
List<String> fl;
Ref<Font> font= memnew(Font);
diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp
index 7d6f400ccc..2e5a6f8a81 100644
--- a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp
@@ -1,6 +1,6 @@
#include "editor_mesh_import_plugin.h"
-#include "scene/gui/file_dialog.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"
@@ -126,7 +126,7 @@ class EditorMeshImportDialog : public ConfirmationDialog {
LineEdit *import_path;
LineEdit *save_path;
- FileDialog *file_select;
+ EditorFileDialog *file_select;
EditorDirDialog *save_select;
ConfirmationDialog *error_dialog;
PropertyEditor *option_editor;
@@ -300,16 +300,16 @@ public:
save_choose->connect("pressed", this,"_browse_target");
- file_select = memnew(FileDialog);
- file_select->set_access(FileDialog::ACCESS_FILESYSTEM);
+ file_select = memnew(EditorFileDialog);
+ file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
add_child(file_select);
- file_select->set_mode(FileDialog::MODE_OPEN_FILES);
+ file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES);
file_select->connect("files_selected", this,"_choose_files");
file_select->add_filter("*.obj ; Wavefront OBJ");
save_select = memnew( EditorDirDialog );
add_child(save_select);
- // save_select->set_mode(FileDialog::MODE_OPEN_DIR);
+ // save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR);
save_select->connect("dir_selected", this,"_choose_save_dir");
get_ok()->connect("pressed", this,"_import");
diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.cpp b/tools/editor/io_plugins/editor_sample_import_plugin.cpp
index fa472ed033..9491f957c3 100644
--- a/tools/editor/io_plugins/editor_sample_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_sample_import_plugin.cpp
@@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "editor_sample_import_plugin.h"
-#include "scene/gui/file_dialog.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"
@@ -171,7 +171,7 @@ class EditorSampleImportDialog : public ConfirmationDialog {
LineEdit *import_path;
LineEdit *save_path;
- FileDialog *file_select;
+ EditorFileDialog *file_select;
EditorDirDialog *save_select;
ConfirmationDialog *error_dialog;
PropertyEditor *option_editor;
@@ -363,16 +363,16 @@ public:
save_choose->connect("pressed", this,"_browse_target");
- file_select = memnew(FileDialog);
- file_select->set_access(FileDialog::ACCESS_FILESYSTEM);
+ file_select = memnew(EditorFileDialog);
+ file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
add_child(file_select);
- file_select->set_mode(FileDialog::MODE_OPEN_FILES);
+ 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(FileDialog::MODE_OPEN_DIR);
+ // save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR);
save_select->connect("dir_selected", this,"_choose_save_dir");
get_ok()->connect("pressed", this,"_import");
diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
index 2ce5f3a5a7..99dcf4ed28 100644
--- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
@@ -162,8 +162,8 @@ class EditorSceneImportDialog : public ConfirmationDialog {
LineEdit *save_path;
LineEdit *script_path;
Tree *import_options;
- FileDialog *file_select;
- FileDialog *script_select;
+ EditorFileDialog *file_select;
+ EditorFileDialog *script_select;
EditorDirDialog *save_select;
OptionButton *texture_action;
@@ -1079,19 +1079,19 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce
vbc->set_v_size_flags(SIZE_EXPAND_FILL);
vbc->add_margin_child("Options:",import_options,true);
- file_select = memnew(FileDialog);
- file_select->set_access(FileDialog::ACCESS_FILESYSTEM);
+ file_select = memnew(EditorFileDialog);
+ file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
add_child(file_select);
- file_select->set_mode(FileDialog::MODE_OPEN_FILE);
+ 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(FileDialog::MODE_SAVE_FILE);
+ //save_select->set_mode(EditorFileDialog::MODE_SAVE_FILE);
save_select->connect("dir_selected", this,"_choose_save_file");
get_ok()->connect("pressed", this,"_import");
@@ -1140,7 +1140,7 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce
script_choose->connect("pressed", this,"_browse_script");
- script_select = memnew(FileDialog);
+ script_select = memnew(EditorFileDialog);
add_child(script_select);
for(int i=0;i<ScriptServer::get_language_count();i++) {
@@ -1152,7 +1152,7 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce
}
- script_select->set_mode(FileDialog::MODE_OPEN_FILE);
+ script_select->set_mode(EditorFileDialog::MODE_OPEN_FILE);
script_select->connect("file_selected", this,"_choose_script");
diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp
index 3add30d81e..4f7ec1839a 100644
--- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp
@@ -144,6 +144,8 @@ void EditorImportTextureOptions::_changed() {
void EditorImportTextureOptions::_bind_methods() {
+ print_line("bind toptions");
+
ObjectTypeDB::bind_method("_changed",&EditorImportTextureOptions::_changed);
ObjectTypeDB::bind_method("_changedp",&EditorImportTextureOptions::_changedp);
@@ -219,7 +221,6 @@ EditorImportTextureOptions::EditorImportTextureOptions() {
fname++;
}
-
add_margin_child("Texture Options",flags,true);
notice_for_2d = memnew( Label );
@@ -247,17 +248,20 @@ class EditorTextureImportDialog : public ConfirmationDialog {
LineEdit *import_path;
LineEdit *save_path;
- FileDialog *file_select;
- FileDialog *save_file_select;
+ EditorFileDialog *file_select;
+ EditorFileDialog *save_file_select;
EditorDirDialog *save_select;
OptionButton *texture_action;
ConfirmationDialog *error_dialog;
CheckButton *crop_source;
+ SpinBox *size;
bool atlas;
+ bool large;
EditorTextureImportPlugin *plugin;
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();
@@ -272,7 +276,7 @@ public:
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,bool p_2d=false,bool p_atlas=false);
+ EditorTextureImportDialog(EditorTextureImportPlugin *p_plugin=NULL,bool p_2d=false,bool p_atlas=false,bool p_large=false);
};
@@ -301,6 +305,15 @@ void EditorTextureImportDialog::_choose_files(const Vector<String>& p_path) {
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);
@@ -336,7 +349,7 @@ void EditorTextureImportDialog::_import() {
}
- if (!atlas && !DirAccess::exists(save_path->get_text())) {
+ if (!atlas && !large && !DirAccess::exists(save_path->get_text())) {
error_dialog->set_text("Target path must exist.");
error_dialog->popup_centered_minsize();
return;
@@ -362,6 +375,8 @@ void EditorTextureImportDialog::_import() {
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_val()));
+ imd->set_option("large",false);
imd->set_option("crop",crop_source->is_pressed());
Error err = plugin->import(dst_file,imd);
@@ -372,7 +387,38 @@ void EditorTextureImportDialog::_import() {
return;
}
+ } else if (large) { //atlas
+
+ if (files.size()!=1) {
+
+ error_dialog->set_text("Only one file is required for large texture");
+ error_dialog->popup_centered(Size2(200,100));
+ 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_val()));
+ imd->set_option("crop",crop_source->is_pressed());
+ Error err = plugin->import(dst_file,imd);
+ if (err) {
+
+ error_dialog->set_text("Error importing: "+dst_file.get_file());
+ error_dialog->popup_centered(Size2(200,100));
+ return;
+
+ }
} else {
@@ -387,6 +433,8 @@ void EditorTextureImportDialog::_import() {
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);
+
Error err = plugin->import(dst_file,imd);
if (err) {
@@ -408,7 +456,7 @@ void EditorTextureImportDialog::_browse() {
void EditorTextureImportDialog::_browse_target() {
- if (atlas) {
+ if (atlas || large) {
save_file_select->popup_centered_ratio();
} else {
save_select->popup_centered_ratio();
@@ -424,7 +472,7 @@ void EditorTextureImportDialog::popup_import(const String& p_from) {
Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from);
ERR_FAIL_COND(!rimd.is_valid());
- if (plugin->get_mode()==EditorTextureImportPlugin::MODE_ATLAS)
+ if (plugin->get_mode()==EditorTextureImportPlugin::MODE_ATLAS || plugin->get_mode()==EditorTextureImportPlugin::MODE_LARGE)
save_path->set_text(p_from);
else
save_path->set_text(p_from.get_base_dir());
@@ -474,6 +522,7 @@ void EditorTextureImportDialog::_bind_methods() {
ObjectTypeDB::bind_method("_choose_files",&EditorTextureImportDialog::_choose_files);
+ ObjectTypeDB::bind_method("_choose_file",&EditorTextureImportDialog::_choose_file);
ObjectTypeDB::bind_method("_choose_save_dir",&EditorTextureImportDialog::_choose_save_dir);
ObjectTypeDB::bind_method("_import",&EditorTextureImportDialog::_import);
ObjectTypeDB::bind_method("_browse",&EditorTextureImportDialog::_browse);
@@ -481,21 +530,25 @@ void EditorTextureImportDialog::_bind_methods() {
// ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) );
}
-EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* p_plugin, bool p_2d, bool p_atlas) {
+EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* p_plugin, bool p_2d, bool p_atlas,bool p_large) {
atlas=p_atlas;
+ large=p_large;
plugin=p_plugin;
set_title("Import Textures");
- texture_options = memnew( EditorImportTextureOptions );;
- VBoxContainer *vbc = texture_options;
+
+ VBoxContainer *vbc = memnew(VBoxContainer);
add_child(vbc);
set_child_rect(vbc);
VBoxContainer *source_vb=memnew(VBoxContainer);
- vbc->add_margin_child("Source Texture(s):",source_vb);
+ if (large)
+ vbc->add_margin_child("Source Texture:",source_vb);
+ else
+ vbc->add_margin_child("Source Texture(s):",source_vb);
HBoxContainer *hbc = memnew( HBoxContainer );
source_vb->add_child(hbc);
@@ -510,6 +563,7 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin*
if (!p_atlas)
crop_source->hide();
+
Button * import_choose = memnew( Button );
import_choose->set_text(" .. ");
hbc->add_child(import_choose);
@@ -519,6 +573,19 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin*
hbc = memnew( HBoxContainer );
vbc->add_margin_child("Target Path:",hbc);
+ size = memnew( SpinBox );
+ size->set_min(128);
+ size->set_max(16384);
+
+ if (p_atlas) {
+ size->set_val(2048);
+ vbc->add_margin_child("Max Texture size:",size);
+ } else {
+ size->set_val(256);
+ vbc->add_margin_child("Cell Size:",size);
+ }
+
+
save_path = memnew( LineEdit );
save_path->set_h_size_flags(SIZE_EXPAND_FILL);
hbc->add_child(save_path);
@@ -529,32 +596,39 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin*
save_choose->connect("pressed", this,"_browse_target");
- file_select = memnew(FileDialog);
- file_select->set_access(FileDialog::ACCESS_FILESYSTEM);
+ file_select = memnew(EditorFileDialog);
+ file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
add_child(file_select);
- file_select->set_mode(FileDialog::MODE_OPEN_FILES);
+ if (!large)
+ file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES);
+ else
+ file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE);
file_select->connect("files_selected", this,"_choose_files");
+ file_select->connect("file_selected", this,"_choose_file");
- save_file_select = memnew(FileDialog);
- save_file_select->set_access(FileDialog::ACCESS_RESOURCES);
+ save_file_select = memnew(EditorFileDialog);
+ save_file_select->set_access(EditorFileDialog::ACCESS_RESOURCES);
add_child(save_file_select);
- save_file_select->set_mode(FileDialog::MODE_SAVE_FILE);
+ save_file_select->set_mode(EditorFileDialog::MODE_SAVE_FILE);
save_file_select->clear_filters();
- save_file_select->add_filter("*.tex;Base Atlas Texture");
+ if (large)
+ save_file_select->add_filter("*.ltex;Large Texture");
+ else
+ save_file_select->add_filter("*.tex;Base Atlas Texture");
save_file_select->connect("file_selected", this,"_choose_save_dir");
save_select = memnew( EditorDirDialog );
add_child(save_select);
-// save_select->set_mode(FileDialog::MODE_OPEN_DIR);
+// 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("Import");
//move stuff up
- for(int i=0;i<4;i++)
- vbc->move_child( vbc->get_child( vbc->get_child_count() -1), 0);
+ //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);
@@ -563,13 +637,24 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin*
set_hide_on_ok(false);
+ texture_options = memnew( EditorImportTextureOptions );;
+ vbc->add_child(texture_options);
+ texture_options->set_v_size_flags(SIZE_EXPAND_FILL);
+
if (atlas) {
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);
- texture_options->show_2d_notice();
+ //texture_options->show_2d_notice();
set_title("Import Textures for Atlas (2D)");
+ } else if (large) {
+
+ 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);
+ texture_options->show_2d_notice();
+ set_title("Import Large Textures (2D)");
} else if (p_2d) {
@@ -615,12 +700,17 @@ String EditorTextureImportPlugin::get_name() const {
return "texture_atlas";
} break;
+ case MODE_LARGE: {
+
+ return "texture_large";
+ } break;
}
return "";
}
+
String EditorTextureImportPlugin::get_visible_name() const {
switch(mode) {
@@ -635,7 +725,11 @@ String EditorTextureImportPlugin::get_visible_name() const {
} break;
case MODE_ATLAS: {
- return "Atlas Texture";
+ return "2D Atlas Texture";
+ } break;
+ case MODE_LARGE: {
+
+ return "2D Large Texture";
} break;
}
@@ -733,6 +827,135 @@ Error EditorTextureImportPlugin::import(const String& p_path, const Ref<Resource
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,int 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_RGBA) {
+
+ image.convert(Image::FORMAT_RGB);
+
+ }
+
+ if (image.get_format()==Image::FORMAT_RGBA && flags&IMAGE_FLAG_FIX_BORDER_ALPHA) {
+
+ image.fix_alpha_edges();
+ }
+
+ if (image.get_format()==Image::FORMAT_RGBA && 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_RGB || image.get_format()==Image::FORMAT_RGBA) && 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_RGBA) {
+
+ image.convert(Image::FORMAT_RGB);
+
+ }
+
+ if (image.get_format()==Image::FORMAT_RGBA && flags&IMAGE_FLAG_FIX_BORDER_ALPHA) {
+
+ image.fix_alpha_edges();
+ }
+
+ if (image.get_format()==Image::FORMAT_RGBA && 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_RGB || image.get_format()==Image::FORMAT_RGBA) && 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));
+ }
+
+ //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){
@@ -744,8 +967,11 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
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;
@@ -765,7 +991,80 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
if (from->has_option("shrink"))
shrink=from->get_option("shrink");
- if (atlas) {
+ 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","Import Large Texture",3);
+
+ pg.step("Load Source Image",0);
+ Image img;
+ Error err = ImageLoader::load_image(src_path,&img);
+ if (err) {
+ return err;
+ }
+
+ pg.step("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("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());
+ existing->set_path(p_path);
+ existing->set_import_metadata(from);
+ }
+ pg.step("Saving",3);
+
+ err = ResourceSaver::save(p_path,existing);
+ if (err!=OK) {
+ EditorNode::add_io_error("Couldn't save large texture: "+p_path);
+ return err;
+ }
+
+ return OK;
+
+
+ } else if (atlas) {
//prepare atlas!
Vector< Image > sources;
@@ -897,8 +1196,6 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
}
- int format=from->get_option("format");
- float quality=from->get_option("quality");
if (!p_external) {
from->set_editor(get_name());
@@ -932,7 +1229,11 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
}
}
+ 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();
@@ -989,13 +1290,6 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
texture->set_lossy_storage_quality(quality);
- Error err = ResourceSaver::save(p_path,texture);
-
- if (err!=OK) {
- EditorNode::add_io_error("Couldn't save converted texture: "+p_path);
- return err;
- }
-
} else {
@@ -1058,15 +1352,20 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
texture->set_size_override(Size2(orig_w,orig_h));
}
- uint32_t save_flags=ResourceSaver::FLAG_COMPRESS;
+ compress=true;
- Error err = ResourceSaver::save(p_path,texture,save_flags);
- if (err!=OK) {
- EditorNode::add_io_error("Couldn't save converted texture: "+p_path);
- return err;
- }
}
+#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("Couldn't save converted texture: "+p_path);
+ return err;
+ }
return OK;
}
@@ -1255,14 +1554,14 @@ Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, c
}
-EditorTextureImportPlugin *EditorTextureImportPlugin::singleton[3]={NULL,NULL,NULL};
+EditorTextureImportPlugin *EditorTextureImportPlugin::singleton[EditorTextureImportPlugin::MODE_MAX]={NULL,NULL,NULL,NULL};
EditorTextureImportPlugin::EditorTextureImportPlugin(EditorNode *p_editor, Mode p_mode) {
singleton[p_mode]=this;
editor=p_editor;
- mode=p_mode;
- dialog = memnew( EditorTextureImportDialog(this,p_mode==MODE_TEXTURE_2D || p_mode==MODE_ATLAS,p_mode==MODE_ATLAS) );
+ mode=p_mode;
+ dialog = memnew( EditorTextureImportDialog(this,p_mode==MODE_TEXTURE_2D || p_mode==MODE_ATLAS || p_mode==MODE_LARGE,p_mode==MODE_ATLAS,p_mode==MODE_LARGE) );
editor->get_gui_base()->add_child(dialog);
}
diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.h b/tools/editor/io_plugins/editor_texture_import_plugin.h
index 5cd36e838e..02d09d9e17 100644
--- a/tools/editor/io_plugins/editor_texture_import_plugin.h
+++ b/tools/editor/io_plugins/editor_texture_import_plugin.h
@@ -56,7 +56,9 @@ public:
enum Mode {
MODE_TEXTURE_2D,
MODE_TEXTURE_3D,
- MODE_ATLAS
+ MODE_ATLAS,
+ MODE_LARGE,
+ MODE_MAX
};
@@ -65,10 +67,10 @@ private:
Mode mode;
EditorNode *editor;
EditorTextureImportDialog *dialog;
- static EditorTextureImportPlugin *singleton[3];
+ static EditorTextureImportPlugin *singleton[MODE_MAX];
//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,int shrink);
void compress_image(EditorExportPlatform::ImageCompression p_mode,Image& image,bool p_smaller);
public:
diff --git a/tools/editor/io_plugins/editor_translation_import_plugin.cpp b/tools/editor/io_plugins/editor_translation_import_plugin.cpp
index 6d59b52fb5..d152d71af4 100644
--- a/tools/editor/io_plugins/editor_translation_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_translation_import_plugin.cpp
@@ -47,7 +47,7 @@ class EditorTranslationImportDialog : public ConfirmationDialog {
LineEdit *import_path;
LineEdit *save_path;
- FileDialog *file_select;
+ EditorFileDialog *file_select;
CheckButton *ignore_first;
CheckButton *compress;
CheckButton *add_to_project;
@@ -347,16 +347,16 @@ public:
add_to_project->set_text("Add to Project (engine.cfg)");
tcomp->add_child(add_to_project);
- file_select = memnew(FileDialog);
- file_select->set_access(FileDialog::ACCESS_FILESYSTEM);
+ file_select = memnew(EditorFileDialog);
+ file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
add_child(file_select);
- file_select->set_mode(FileDialog::MODE_OPEN_FILE);
+ 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(FileDialog::MODE_OPEN_DIR);
+ // save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR);
save_select->connect("dir_selected", this,"_choose_save_dir");
get_ok()->connect("pressed", this,"_import");
diff --git a/tools/editor/plugins/animation_player_editor_plugin.cpp b/tools/editor/plugins/animation_player_editor_plugin.cpp
index 9a93eed969..05b12543d2 100644
--- a/tools/editor/plugins/animation_player_editor_plugin.cpp
+++ b/tools/editor/plugins/animation_player_editor_plugin.cpp
@@ -98,7 +98,7 @@ void AnimationPlayerEditor::_notification(int p_what) {
duplicate_anim->set_icon( get_icon("Duplicate","EditorIcons") );
autoplay->set_icon( get_icon("AutoPlay","EditorIcons") );
load_anim->set_icon( get_icon("Folder","EditorIcons") );
- remove_anim->set_icon( get_icon("Del","EditorIcons") );
+ remove_anim->set_icon( get_icon("Remove","EditorIcons") );
edit_anim->set_icon( get_icon("Edit","EditorIcons") );
blend_anim->set_icon( get_icon("Blend","EditorIcons") );
play->set_icon( get_icon("PlayStart","EditorIcons") );
@@ -355,7 +355,7 @@ void AnimationPlayerEditor::_animation_rename() {
}
void AnimationPlayerEditor::_animation_load() {
ERR_FAIL_COND(!player);
- file->set_mode( FileDialog::MODE_OPEN_FILE );
+ file->set_mode( EditorFileDialog::MODE_OPEN_FILE );
file->clear_filters();
List<String> extensions;
@@ -1232,7 +1232,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) {
resource_edit_anim->hide();
- file = memnew(FileDialog);
+ file = memnew(EditorFileDialog);
add_child(file);
name_dialog = memnew( ConfirmationDialog );
diff --git a/tools/editor/plugins/animation_player_editor_plugin.h b/tools/editor/plugins/animation_player_editor_plugin.h
index 5c9dc6cab8..9f0413088d 100644
--- a/tools/editor/plugins/animation_player_editor_plugin.h
+++ b/tools/editor/plugins/animation_player_editor_plugin.h
@@ -84,7 +84,7 @@ class AnimationPlayerEditor : public VBoxContainer {
Ref<Texture> autoplay_icon;
bool last_active;
- FileDialog *file;
+ EditorFileDialog *file;
struct BlendEditor {
diff --git a/tools/editor/plugins/animation_tree_editor_plugin.cpp b/tools/editor/plugins/animation_tree_editor_plugin.cpp
index 2df9377daf..382bc44726 100644
--- a/tools/editor/plugins/animation_tree_editor_plugin.cpp
+++ b/tools/editor/plugins/animation_tree_editor_plugin.cpp
@@ -1193,7 +1193,7 @@ void AnimationTreeEditor::_add_menu_item(int p_item) {
} else if (p_item == MENU_IMPORT_ANIMATIONS) {
file_op = MENU_IMPORT_ANIMATIONS;
- file_dialog->set_mode(FileDialog::MODE_OPEN_FILE);
+ file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE);
file_dialog->popup_centered_ratio();
} else {
@@ -1458,7 +1458,7 @@ AnimationTreeEditor::AnimationTreeEditor() {
edit_check->hide();;
edit_check->connect("pressed", this,"_edit_dialog_changed");
- file_dialog = memnew( FileDialog );
+ file_dialog = memnew( EditorFileDialog );
file_dialog->set_enable_multiple_selection(true);
file_dialog->set_current_dir(Globals::get_singleton()->get_resource_path());
add_child(file_dialog);
diff --git a/tools/editor/plugins/animation_tree_editor_plugin.h b/tools/editor/plugins/animation_tree_editor_plugin.h
index beb67c7196..bd29530c7a 100644
--- a/tools/editor/plugins/animation_tree_editor_plugin.h
+++ b/tools/editor/plugins/animation_tree_editor_plugin.h
@@ -79,7 +79,7 @@ class AnimationTreeEditor : public Control {
Button *edit_button;
Button *filter_button;
CheckButton *edit_check;
- FileDialog* file_dialog;
+ EditorFileDialog* file_dialog;
int file_op;
void _popup_edit_dialog();
diff --git a/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp
index a533c6aa1e..8eea723126 100644
--- a/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp
+++ b/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp
@@ -380,6 +380,7 @@ void CollisionPolygon2DEditor::_bind_methods() {
CollisionPolygon2DEditor::CollisionPolygon2DEditor(EditorNode *p_editor) {
+ node=NULL;
canvas_item_editor=NULL;
editor=p_editor;
undo_redo = editor->get_undo_redo();
diff --git a/tools/editor/plugins/collision_polygon_editor_plugin.cpp b/tools/editor/plugins/collision_polygon_editor_plugin.cpp
index de40727f1b..381cfd74ab 100644
--- a/tools/editor/plugins/collision_polygon_editor_plugin.cpp
+++ b/tools/editor/plugins/collision_polygon_editor_plugin.cpp
@@ -533,6 +533,7 @@ void CollisionPolygonEditor::_bind_methods() {
CollisionPolygonEditor::CollisionPolygonEditor(EditorNode *p_editor) {
+ node=NULL;
editor=p_editor;
undo_redo = editor->get_undo_redo();
diff --git a/tools/editor/plugins/color_ramp_editor_plugin.cpp b/tools/editor/plugins/color_ramp_editor_plugin.cpp
new file mode 100644
index 0000000000..df50535402
--- /dev/null
+++ b/tools/editor/plugins/color_ramp_editor_plugin.cpp
@@ -0,0 +1,83 @@
+/*
+ * color_ramp_editor_plugin.cpp
+ */
+
+#include "color_ramp_editor_plugin.h"
+
+ColorRampEditorPlugin::ColorRampEditorPlugin(EditorNode *p_node) {
+
+ editor=p_node;
+ ramp_editor = memnew( ColorRampEdit );
+
+ add_custom_control(CONTAINER_CANVAS_EDITOR_BOTTOM,ramp_editor);
+ //add_custom_control(CONTAINER_SPATIAL_EDITOR_BOTTOM,ramp_editor);
+ ramp_editor->set_custom_minimum_size(Size2(100, 48));
+ ramp_editor->hide();
+ ramp_editor->connect("ramp_changed", this, "ramp_changed");
+}
+
+void ColorRampEditorPlugin::edit(Object *p_object) {
+
+ ColorRamp* color_ramp = p_object->cast_to<ColorRamp>();
+ if (!color_ramp)
+ return;
+ color_ramp_ref = Ref<ColorRamp>(color_ramp);
+ ramp_editor->set_points(color_ramp_ref->get_points());
+}
+
+bool ColorRampEditorPlugin::handles(Object *p_object) const {
+
+ return p_object->is_type("ColorRamp");
+}
+
+void ColorRampEditorPlugin::make_visible(bool p_visible) {
+
+ if (p_visible) {
+ ramp_editor->show();
+ } else {
+ ramp_editor->hide();
+ }
+
+}
+
+void ColorRampEditorPlugin::_ramp_changed() {
+
+ if(color_ramp_ref.is_valid())
+ {
+
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+
+ //Not sure if I should convert this data to DVector
+ Vector<float> new_offsets=ramp_editor->get_offsets();
+ Vector<Color> new_colors=ramp_editor->get_colors();
+ Vector<float> old_offsets=color_ramp_ref->get_offsets();
+ Vector<Color> old_colors=color_ramp_ref->get_colors();
+
+ if (old_offsets.size()!=new_offsets.size())
+ ur->create_action("Add/Remove Color Ramp Point");
+ else
+ ur->create_action("Modify Color Ramp",true);
+ ur->add_do_method(this,"undo_redo_color_ramp",new_offsets,new_colors);
+ ur->add_undo_method(this,"undo_redo_color_ramp",old_offsets,old_colors);
+ ur->commit_action();
+
+ //color_ramp_ref->set_points(ramp_editor->get_points());
+ }
+}
+
+void ColorRampEditorPlugin::_undo_redo_color_ramp(const Vector<float>& offsets,
+ const Vector<Color>& colors) {
+
+ color_ramp_ref->set_offsets(offsets);
+ color_ramp_ref->set_colors(colors);
+ ramp_editor->set_points(color_ramp_ref->get_points());
+ ramp_editor->update();
+}
+
+ColorRampEditorPlugin::~ColorRampEditorPlugin(){
+}
+
+void ColorRampEditorPlugin::_bind_methods() {
+ ObjectTypeDB::bind_method(_MD("ramp_changed"),&ColorRampEditorPlugin::_ramp_changed);
+ ObjectTypeDB::bind_method(_MD("undo_redo_color_ramp","offsets","colors"),&ColorRampEditorPlugin::_undo_redo_color_ramp);
+}
diff --git a/tools/editor/plugins/color_ramp_editor_plugin.h b/tools/editor/plugins/color_ramp_editor_plugin.h
new file mode 100644
index 0000000000..e39a5d65fe
--- /dev/null
+++ b/tools/editor/plugins/color_ramp_editor_plugin.h
@@ -0,0 +1,37 @@
+/*
+ * color_ramp_editor_plugin.h
+ */
+
+#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 {
+
+ OBJ_TYPE( ColorRampEditorPlugin, EditorPlugin );
+
+ 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
index 7d243b8a65..c118485083 100644
--- a/tools/editor/plugins/cube_grid_theme_editor_plugin.cpp
+++ b/tools/editor/plugins/cube_grid_theme_editor_plugin.cpp
@@ -269,8 +269,8 @@ void MeshLibraryEditor::_bind_methods() {
MeshLibraryEditor::MeshLibraryEditor(EditorNode *p_editor) {
- file = memnew( FileDialog );
- file->set_mode(FileDialog::MODE_OPEN_FILE);
+ file = memnew( EditorFileDialog );
+ file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
//not for now?
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions);
diff --git a/tools/editor/plugins/cube_grid_theme_editor_plugin.h b/tools/editor/plugins/cube_grid_theme_editor_plugin.h
index 70ccef2add..583ddf6e14 100644
--- a/tools/editor/plugins/cube_grid_theme_editor_plugin.h
+++ b/tools/editor/plugins/cube_grid_theme_editor_plugin.h
@@ -42,7 +42,7 @@ class MeshLibraryEditor : public Control {
EditorNode *editor;
MenuButton *menu;
ConfirmationDialog *cd;
- FileDialog *file;
+ EditorFileDialog *file;
int to_erase;
enum {
diff --git a/tools/editor/plugins/editor_preview_plugins.cpp b/tools/editor/plugins/editor_preview_plugins.cpp
new file mode 100644
index 0000000000..a77ba9a605
--- /dev/null
+++ b/tools/editor/plugins/editor_preview_plugins.cpp
@@ -0,0 +1,777 @@
+#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"
+
+bool EditorTexturePreviewPlugin::handles(const String& p_type) const {
+
+ return ObjectTypeDB::is_type(p_type,"ImageTexture");
+}
+
+Ref<Texture> EditorTexturePreviewPlugin::generate(const RES& p_from) {
+
+ Ref<ImageTexture> tex =p_from;
+ Image img = tex->get_data();
+ if (img.empty())
+ return Ref<Texture>();
+
+ img.clear_mipmaps();
+
+ int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");
+ if (img.is_compressed()) {
+ if (img.decompress()!=OK)
+ return Ref<Texture>();
+ } else if (img.get_format()!=Image::FORMAT_RGB && img.get_format()!=Image::FORMAT_RGB) {
+ img.convert(Image::FORMAT_RGBA);
+ }
+
+ 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() {
+
+
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+
+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()));
+ DVector<uint8_t> thumbnail = tn;
+
+ int len = thumbnail.size();
+ if (len==0)
+ return Ref<Texture>();
+
+
+ DVector<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 ObjectTypeDB::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 ObjectTypeDB::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("file_dialog/thumbnail_size");
+ 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;
+
+ DVector<Vector3> vertices;
+ DVector<Vector3> normals;
+ DVector<Vector2> uvs;
+ DVector<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 ObjectTypeDB::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("file_dialog/thumbnail_size");
+ Image img(thumbnail_size,thumbnail_size,0,Image::FORMAT_RGBA);
+
+
+
+ Color bg_color = EditorSettings::get_singleton()->get("text_editor/background_color");
+ bg_color.a=1.0;
+ Color keyword_color = EditorSettings::get_singleton()->get("text_editor/keyword_color");
+ Color text_color = EditorSettings::get_singleton()->get("text_editor/text_color");
+ Color symbol_color = EditorSettings::get_singleton()->get("text_editor/symbol_color");
+ Color comment_color = EditorSettings::get_singleton()->get("text_editor/comment_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() {
+
+
+}
+///////////////////////////////////////////////////////////////////
+
+bool EditorSamplePreviewPlugin::handles(const String& p_type) const {
+
+ return ObjectTypeDB::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("file_dialog/thumbnail_size");
+
+ DVector<uint8_t> img;
+ int w = thumbnail_size;
+ int h = thumbnail_size;
+ img.resize(w*h*3);
+
+ DVector<uint8_t>::Write imgdata = img.write();
+ uint8_t * imgw = imgdata.ptr();
+ DVector<uint8_t> data = smp->get_data();
+ DVector<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,signed_nibble,diff,step;
+
+ ima_adpcm.last_nibble++;
+ const uint8_t *src_ptr=sdata;
+
+ nibble = (ima_adpcm.last_nibble&1)?
+ (src_ptr[ima_adpcm.last_nibble>>1]>>4):(src_ptr[ima_adpcm.last_nibble>>1]&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;
+
+ /*
+ signed_nibble = (nibble&7) * ((nibble&8)?-1:1);
+ diff = (2 * signed_nibble + 1) * step / 4; */
+
+ 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[(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 = i*len/w;
+ int to = (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[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[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,ofs;
+ float v;
+ if (j<(h/2)) {
+ half=0;
+ ofs=0;
+ v = (j/(float)(h/2)) * 2.0 - 1.0;
+ } else {
+ half=1;
+ ofs=h/2;
+ v = ((j-(h/2))/(float)(h/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 = DVector<uint8_t>::Write();
+
+ Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture));
+ ptex->create_from_image(Image(w,h,0,Image::FORMAT_RGB,img),0);
+ return ptex;
+
+}
+
+EditorSamplePreviewPlugin::EditorSamplePreviewPlugin() {
+
+
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+bool EditorMeshPreviewPlugin::handles(const String& p_type) const {
+
+ return ObjectTypeDB::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("file_dialog/thumbnail_size");
+ 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);
+
+}
diff --git a/tools/editor/plugins/editor_preview_plugins.h b/tools/editor/plugins/editor_preview_plugins.h
new file mode 100644
index 0000000000..98071e2a0e
--- /dev/null
+++ b/tools/editor/plugins/editor_preview_plugins.h
@@ -0,0 +1,88 @@
+#ifndef EDITORPREVIEWPLUGINS_H
+#define EDITORPREVIEWPLUGINS_H
+
+#include "tools/editor/editor_resource_preview.h"
+
+class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator {
+public:
+
+ virtual bool handles(const String& p_type) const;
+ virtual Ref<Texture> generate(const RES& p_from);
+
+ EditorTexturePreviewPlugin();
+};
+
+
+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();
+};
+
+
+class EditorSamplePreviewPlugin : public EditorResourcePreviewGenerator {
+public:
+
+ virtual bool handles(const String& p_type) const;
+ virtual Ref<Texture> generate(const RES& p_from);
+
+ EditorSamplePreviewPlugin();
+};
+
+
+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 // EDITORPREVIEWPLUGINS_H
diff --git a/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp b/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp
index bf882857d9..757b5327dd 100644
--- a/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp
+++ b/tools/editor/plugins/light_occluder_2d_editor_plugin.cpp
@@ -411,6 +411,7 @@ void LightOccluder2DEditor::_bind_methods() {
LightOccluder2DEditor::LightOccluder2DEditor(EditorNode *p_editor) {
+ node=NULL;
canvas_item_editor=NULL;
editor=p_editor;
undo_redo = editor->get_undo_redo();
diff --git a/tools/editor/plugins/navigation_polygon_editor_plugin.cpp b/tools/editor/plugins/navigation_polygon_editor_plugin.cpp
index bc15741d0f..fa1f614413 100644
--- a/tools/editor/plugins/navigation_polygon_editor_plugin.cpp
+++ b/tools/editor/plugins/navigation_polygon_editor_plugin.cpp
@@ -459,7 +459,7 @@ void NavigationPolygonEditor::_bind_methods() {
}
NavigationPolygonEditor::NavigationPolygonEditor(EditorNode *p_editor) {
-
+ node=NULL;
canvas_item_editor=NULL;
editor=p_editor;
undo_redo = editor->get_undo_redo();
diff --git a/tools/editor/plugins/particles_2d_editor_plugin.cpp b/tools/editor/plugins/particles_2d_editor_plugin.cpp
index 629b4fdc64..fdf534a3a8 100644
--- a/tools/editor/plugins/particles_2d_editor_plugin.cpp
+++ b/tools/editor/plugins/particles_2d_editor_plugin.cpp
@@ -172,14 +172,14 @@ Particles2DEditorPlugin::Particles2DEditorPlugin(EditorNode *p_node) {
menu->get_popup()->add_item("Clear Emission Mask",MENU_CLEAR_EMISSION_MASK);
menu->set_text("Particles");
- file = memnew(FileDialog);
+ file = memnew(EditorFileDialog);
add_child(file);
List<String> ext;
ImageLoader::get_recognized_extensions(&ext);
for(List<String>::Element *E=ext.front();E;E=E->next()) {
file->add_filter("*."+E->get()+"; "+E->get().to_upper());
}
- file->set_mode(FileDialog::MODE_OPEN_FILE);
+ file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(menu);
epoints = memnew( SpinBox );
epoints->set_min(1);
diff --git a/tools/editor/plugins/particles_2d_editor_plugin.h b/tools/editor/plugins/particles_2d_editor_plugin.h
index 0c355a8c8c..dba0bb4dae 100644
--- a/tools/editor/plugins/particles_2d_editor_plugin.h
+++ b/tools/editor/plugins/particles_2d_editor_plugin.h
@@ -48,7 +48,7 @@ class Particles2DEditorPlugin : public EditorPlugin {
};
- FileDialog *file;
+ EditorFileDialog *file;
EditorNode *editor;
MenuButton *menu;
diff --git a/tools/editor/plugins/particles_editor_plugin.cpp b/tools/editor/plugins/particles_editor_plugin.cpp
index 3431220526..f6f01d82ca 100644
--- a/tools/editor/plugins/particles_editor_plugin.cpp
+++ b/tools/editor/plugins/particles_editor_plugin.cpp
@@ -394,7 +394,7 @@ ParticlesEditor::ParticlesEditor() {
add_child(err_dialog);
- emission_file_dialog = memnew( FileDialog );
+ emission_file_dialog = memnew( EditorFileDialog );
add_child(emission_file_dialog);
emission_file_dialog->connect("file_selected",this,"_resource_seleted");
emission_tree_dialog = memnew( SceneTreeDialog );
@@ -410,7 +410,7 @@ ParticlesEditor::ParticlesEditor() {
emission_file_dialog->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper());
}
- emission_file_dialog->set_mode(FileDialog::MODE_OPEN_FILE);
+ 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);
diff --git a/tools/editor/plugins/particles_editor_plugin.h b/tools/editor/plugins/particles_editor_plugin.h
index cc13b4f2a9..92756af1f6 100644
--- a/tools/editor/plugins/particles_editor_plugin.h
+++ b/tools/editor/plugins/particles_editor_plugin.h
@@ -48,7 +48,7 @@ class ParticlesEditor : public Control {
Particles *node;
- FileDialog *emission_file_dialog;
+ EditorFileDialog *emission_file_dialog;
SceneTreeDialog *emission_tree_dialog;
ConfirmationDialog *err_dialog;
diff --git a/tools/editor/plugins/resource_preloader_editor_plugin.cpp b/tools/editor/plugins/resource_preloader_editor_plugin.cpp
index 39251be468..9cd20ac53a 100644
--- a/tools/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/tools/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -102,7 +102,7 @@ void ResourcePreloaderEditor::_load_pressed() {
for(int i=0;i<extensions.size();i++)
file->add_filter("*."+extensions[i]);
- file->set_mode(FileDialog::MODE_OPEN_FILE);
+ file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
file->popup_centered_ratio();
@@ -310,7 +310,7 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() {
paste->set_text("Paste");
hbc->add_child(paste);
- file = memnew( FileDialog );
+ file = memnew( EditorFileDialog );
add_child(file);
diff --git a/tools/editor/plugins/resource_preloader_editor_plugin.h b/tools/editor/plugins/resource_preloader_editor_plugin.h
index b3261bd182..88272bc603 100644
--- a/tools/editor/plugins/resource_preloader_editor_plugin.h
+++ b/tools/editor/plugins/resource_preloader_editor_plugin.h
@@ -49,7 +49,7 @@ class ResourcePreloaderEditor : public PanelContainer {
bool loading_scene;
- FileDialog *file;
+ EditorFileDialog *file;
AcceptDialog *dialog;
diff --git a/tools/editor/plugins/rich_text_editor_plugin.cpp b/tools/editor/plugins/rich_text_editor_plugin.cpp
index 91eb0a7880..a0daad854f 100644
--- a/tools/editor/plugins/rich_text_editor_plugin.cpp
+++ b/tools/editor/plugins/rich_text_editor_plugin.cpp
@@ -111,10 +111,10 @@ RichTextEditor::RichTextEditor() {
options->get_popup()->add_item("Clear",CLEAR);
options->get_popup()->connect("item_pressed", this,"_menu_option");
- file_dialog = memnew( FileDialog );
+ file_dialog = memnew( EditorFileDialog );
add_child(file_dialog);
file_dialog->add_filter("*.txt");
- file_dialog->set_mode(FileDialog::MODE_OPEN_FILE);
+ file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE);
file_dialog->connect("file_selected",this,"_file_selected");
}
diff --git a/tools/editor/plugins/rich_text_editor_plugin.h b/tools/editor/plugins/rich_text_editor_plugin.h
index 653d756d8f..478dc0d308 100644
--- a/tools/editor/plugins/rich_text_editor_plugin.h
+++ b/tools/editor/plugins/rich_text_editor_plugin.h
@@ -53,7 +53,7 @@ class RichTextEditor : public Control {
Panel *panel;
MenuButton *options;
RichTextLabel *node;
- FileDialog *file_dialog;
+ EditorFileDialog *file_dialog;
void _file_selected(const String& p_path);
void _menu_option(int p_option);
diff --git a/tools/editor/plugins/sample_editor_plugin.cpp b/tools/editor/plugins/sample_editor_plugin.cpp
index 3219935688..31fa7246ae 100644
--- a/tools/editor/plugins/sample_editor_plugin.cpp
+++ b/tools/editor/plugins/sample_editor_plugin.cpp
@@ -98,6 +98,125 @@ void SampleEditor::generate_preview_texture(const Ref<Sample>& p_sample,Ref<Imag
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,signed_nibble,diff,step;
+
+ ima_adpcm.last_nibble++;
+ const uint8_t *src_ptr=sdata;
+
+ nibble = (ima_adpcm.last_nibble&1)?
+ (src_ptr[ima_adpcm.last_nibble>>1]>>4):(src_ptr[ima_adpcm.last_nibble>>1]&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;
+
+ /*
+ signed_nibble = (nibble&7) * ((nibble&8)?-1:1);
+ diff = (2 * signed_nibble + 1) * step / 4; */
+
+ 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[(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
diff --git a/tools/editor/plugins/sample_library_editor_plugin.cpp b/tools/editor/plugins/sample_library_editor_plugin.cpp
index bb9d1f9dd0..cf9a6c41a4 100644
--- a/tools/editor/plugins/sample_library_editor_plugin.cpp
+++ b/tools/editor/plugins/sample_library_editor_plugin.cpp
@@ -350,13 +350,13 @@ SampleLibraryEditor::SampleLibraryEditor() {
_delete = memnew( Button );
- file = memnew( FileDialog );
+ 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(FileDialog::MODE_OPEN_FILES);
+ file->set_mode(EditorFileDialog::MODE_OPEN_FILES);
_delete->set_pos(Point2( 65, 5 ));
_delete->set_size( Size2(1,1 ) );
diff --git a/tools/editor/plugins/sample_library_editor_plugin.h b/tools/editor/plugins/sample_library_editor_plugin.h
index 70c7fed068..2770ca2d9a 100644
--- a/tools/editor/plugins/sample_library_editor_plugin.h
+++ b/tools/editor/plugins/sample_library_editor_plugin.h
@@ -54,7 +54,7 @@ class SampleLibraryEditor : public Panel {
Button *_delete;
Tree *tree;
- FileDialog *file;
+ EditorFileDialog *file;
ConfirmationDialog *dialog;
diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp
index 0b3f3e0626..77663f39c0 100644
--- a/tools/editor/plugins/spatial_editor_plugin.cpp
+++ b/tools/editor/plugins/spatial_editor_plugin.cpp
@@ -2216,6 +2216,14 @@ void SpatialEditorViewport::reset() {
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();;
@@ -3615,6 +3623,8 @@ void SpatialEditor::_default_light_angle_input(const InputEvent& p_event) {
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();
diff --git a/tools/editor/plugins/spatial_editor_plugin.h b/tools/editor/plugins/spatial_editor_plugin.h
index b890f285ee..ff8912fca8 100644
--- a/tools/editor/plugins/spatial_editor_plugin.h
+++ b/tools/editor/plugins/spatial_editor_plugin.h
@@ -239,7 +239,7 @@ public:
void set_state(const Dictionary& p_state);
Dictionary get_state() const;
void reset();
-
+ Viewport *get_viewport_node() { return viewport; }
SpatialEditorViewport(SpatialEditor *p_spatial_editor,EditorNode *p_editor,int p_index);
@@ -422,6 +422,7 @@ private:
HBoxContainer *hbc_menu;
+
//
//
void _generate_selection_box();
@@ -514,6 +515,11 @@ public:
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();
diff --git a/tools/editor/plugins/sprite_frames_editor_plugin.cpp b/tools/editor/plugins/sprite_frames_editor_plugin.cpp
index 7fdfac2578..e90087efda 100644
--- a/tools/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/tools/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -115,7 +115,7 @@ void SpriteFramesEditor::_load_pressed() {
for(int i=0;i<extensions.size();i++)
file->add_filter("*."+extensions[i]);
- file->set_mode(FileDialog::MODE_OPEN_FILES);
+ file->set_mode(EditorFileDialog::MODE_OPEN_FILES);
file->popup_centered_ratio();
@@ -435,7 +435,7 @@ SpriteFramesEditor::SpriteFramesEditor() {
_delete = memnew( Button );
hbc->add_child(_delete);
- file = memnew( FileDialog );
+ file = memnew( EditorFileDialog );
add_child(file);
diff --git a/tools/editor/plugins/sprite_frames_editor_plugin.h b/tools/editor/plugins/sprite_frames_editor_plugin.h
index ffd35f3755..969d7b1ce3 100644
--- a/tools/editor/plugins/sprite_frames_editor_plugin.h
+++ b/tools/editor/plugins/sprite_frames_editor_plugin.h
@@ -54,7 +54,7 @@ class SpriteFramesEditor : public PanelContainer {
int sel;
- FileDialog *file;
+ EditorFileDialog *file;
AcceptDialog *dialog;
diff --git a/tools/editor/plugins/theme_editor_plugin.cpp b/tools/editor/plugins/theme_editor_plugin.cpp
index 128ff949e1..55e8f164d6 100644
--- a/tools/editor/plugins/theme_editor_plugin.cpp
+++ b/tools/editor/plugins/theme_editor_plugin.cpp
@@ -408,7 +408,7 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
if (p_option==POPUP_CREATE_TEMPLATE) {
- file_dialog->set_mode(FileDialog::MODE_SAVE_FILE);
+ file_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
file_dialog->set_current_path("custom.theme");
file_dialog->popup_centered_ratio();
return;
@@ -734,7 +734,7 @@ ThemeEditor::ThemeEditor() {
fd_button->set_text("Open File Dialog");
panel->add_child(fd_button);
- test_file_dialog = memnew( FileDialog );
+ test_file_dialog = memnew( EditorFileDialog );
panel->add_child(test_file_dialog);
fd_button->connect("pressed", this,"_open_file_dialog");
@@ -804,7 +804,7 @@ ThemeEditor::ThemeEditor() {
add_del_dialog->get_ok()->connect("pressed", this,"_dialog_cbk");
- file_dialog = memnew( FileDialog );
+ file_dialog = memnew( EditorFileDialog );
file_dialog->add_filter("*.theme ; Theme File");
add_child(file_dialog);
file_dialog->connect("file_selected",this,"_save_template_cbk");
diff --git a/tools/editor/plugins/theme_editor_plugin.h b/tools/editor/plugins/theme_editor_plugin.h
index 37f5ad6129..40c7ad8186 100644
--- a/tools/editor/plugins/theme_editor_plugin.h
+++ b/tools/editor/plugins/theme_editor_plugin.h
@@ -48,7 +48,7 @@ class ThemeEditor : public Control {
VBoxContainer *main_vb;
Ref<Theme> theme;
- FileDialog *file_dialog;
+ EditorFileDialog *file_dialog;
double time_left;
diff --git a/tools/editor/project_export.cpp b/tools/editor/project_export.cpp
index ab27ac7fa9..e38c672a3e 100644
--- a/tools/editor/project_export.cpp
+++ b/tools/editor/project_export.cpp
@@ -563,7 +563,7 @@ void ProjectExportDialog::_update_group_list() {
TreeItem *ti = groups->create_item(r);
ti->set_text(0,E->get());
- ti->add_button(0,get_icon("Del","EditorIcons"));
+ ti->add_button(0,get_icon("Remove","EditorIcons"));
if (E->get()==current) {
ti->select(0);
}
@@ -1342,9 +1342,9 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
expopt="--,Export,Bundle";
- file_export = memnew( FileDialog );
+ file_export = memnew( EditorFileDialog );
add_child(file_export);
- file_export->set_access(FileDialog::ACCESS_FILESYSTEM);
+ file_export->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
file_export->set_current_dir( EditorSettings::get_singleton()->get("global/default_project_export_path") );
file_export->set_title("Export Project");
@@ -1361,8 +1361,8 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
file_export_password->set_editable(false);
file_export->get_vbox()->add_margin_child("Password:",file_export_password);
- pck_export = memnew( FileDialog );
- pck_export->set_access(FileDialog::ACCESS_FILESYSTEM);
+ pck_export = memnew( EditorFileDialog );
+ pck_export->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
pck_export->set_current_dir( EditorSettings::get_singleton()->get("global/default_project_export_path") );
pck_export->set_title("Export Project PCK");
pck_export->connect("file_selected", this,"_export_action_pck");
diff --git a/tools/editor/project_export.h b/tools/editor/project_export.h
index 08d19e1751..c88233ae01 100644
--- a/tools/editor/project_export.h
+++ b/tools/editor/project_export.h
@@ -33,7 +33,7 @@
#include "scene/gui/control.h"
#include "scene/gui/tree.h"
#include "scene/gui/label.h"
-#include "scene/gui/file_dialog.h"
+#include "tools/editor/editor_file_dialog.h"
#include "scene/gui/button.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/tab_container.h"
@@ -80,8 +80,8 @@ private:
Tree * tree;
- FileDialog *pck_export;
- FileDialog *file_export;
+ EditorFileDialog *pck_export;
+ EditorFileDialog *file_export;
CheckButton *file_export_check;
LineEdit *file_export_password;
diff --git a/tools/editor/project_settings.cpp b/tools/editor/project_settings.cpp
index 08a1191f41..fea9c705ef 100644
--- a/tools/editor/project_settings.cpp
+++ b/tools/editor/project_settings.cpp
@@ -415,7 +415,7 @@ void ProjectSettings::_update_actions() {
item->set_cell_mode(0,TreeItem::CELL_MODE_CHECK);
item->set_text(0,name);
item->add_button(0,get_icon("Add","EditorIcons"),1);
- item->add_button(0,get_icon("Del","EditorIcons"),2);
+ item->add_button(0,get_icon("Remove","EditorIcons"),2);
item->set_custom_bg_color(0,get_color("prop_subsection","Editor"));
item->set_editable(0,true);
item->set_checked(0,pi.usage&PROPERTY_USAGE_CHECKED);
@@ -483,7 +483,7 @@ void ProjectSettings::_update_actions() {
action->set_icon(0,get_icon("JoyAxis","EditorIcons"));
} break;
}
- action->add_button(0,get_icon("Del","EditorIcons"),2);
+ action->add_button(0,get_icon("Remove","EditorIcons"),2);
action->set_metadata(0,i);
}
}
@@ -1450,9 +1450,9 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
translation_list->set_v_size_flags(SIZE_EXPAND_FILL);
tmc->add_child(translation_list);
- translation_file_open=memnew( FileDialog );
+ translation_file_open=memnew( EditorFileDialog );
add_child(translation_file_open);
- translation_file_open->set_mode(FileDialog::MODE_OPEN_FILE);
+ translation_file_open->set_mode(EditorFileDialog::MODE_OPEN_FILE);
translation_file_open->connect("file_selected",this,"_translation_add");
}
@@ -1477,9 +1477,9 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
tmc->add_child(translation_remap);
translation_remap->connect("button_pressed",this,"_translation_res_delete");
- translation_res_file_open=memnew( FileDialog );
+ translation_res_file_open=memnew( EditorFileDialog );
add_child(translation_res_file_open);
- translation_res_file_open->set_mode(FileDialog::MODE_OPEN_FILE);
+ translation_res_file_open->set_mode(EditorFileDialog::MODE_OPEN_FILE);
translation_res_file_open->connect("file_selected",this,"_translation_res_add");
thb = memnew( HBoxContainer);
@@ -1507,9 +1507,9 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
translation_remap_options->connect("item_edited",this,"_translation_res_option_changed");
translation_remap_options->connect("button_pressed",this,"_translation_res_option_delete");
- translation_res_option_file_open=memnew( FileDialog );
+ translation_res_option_file_open=memnew( EditorFileDialog );
add_child(translation_res_option_file_open);
- translation_res_option_file_open->set_mode(FileDialog::MODE_OPEN_FILE);
+ translation_res_option_file_open->set_mode(EditorFileDialog::MODE_OPEN_FILE);
translation_res_option_file_open->connect("file_selected",this,"_translation_res_option_add");
}
@@ -1548,9 +1548,9 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
autoload_list->set_v_size_flags(SIZE_EXPAND_FILL);
avb->add_margin_child("List:",autoload_list,true);
- autoload_file_open=memnew( FileDialog );
+ autoload_file_open=memnew( EditorFileDialog );
add_child(autoload_file_open);
- autoload_file_open->set_mode(FileDialog::MODE_OPEN_FILE);
+ autoload_file_open->set_mode(EditorFileDialog::MODE_OPEN_FILE);
autoload_file_open->connect("file_selected",this,"_autoload_file_callback");
autoload_list->set_columns(2);
diff --git a/tools/editor/project_settings.h b/tools/editor/project_settings.h
index 8e40407d3e..7c91254764 100644
--- a/tools/editor/project_settings.h
+++ b/tools/editor/project_settings.h
@@ -67,19 +67,19 @@ class ProjectSettings : public AcceptDialog {
InputEvent last_wait_for_key;
- FileDialog *translation_file_open;
+ EditorFileDialog *translation_file_open;
Tree *translation_list;
Button *translation_res_option_add_button;
- FileDialog *translation_res_file_open;
- FileDialog *translation_res_option_file_open;
+ EditorFileDialog *translation_res_file_open;
+ EditorFileDialog *translation_res_option_file_open;
Tree *translation_remap;
Tree *translation_remap_options;
Tree *autoload_list;
- FileDialog *autoload_file_open;
+ EditorFileDialog *autoload_file_open;
LineEdit *autoload_add_name;
LineEdit *autoload_add_path;
diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp
index 559267dc07..98e0df77f7 100644
--- a/tools/editor/property_editor.cpp
+++ b/tools/editor/property_editor.cpp
@@ -83,7 +83,7 @@ void CustomPropertyEditor::_menu_option(int p_which) {
switch(p_which) {
case OBJ_MENU_LOAD: {
- file->set_mode(FileDialog::MODE_OPEN_FILE);
+ file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
List<String> extensions;
String type=(hint==PROPERTY_HINT_RESOURCE_TYPE)?hint_text:String();
@@ -908,11 +908,11 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
if (p_which==0) {
if (hint==PROPERTY_HINT_FILE)
- file->set_access(FileDialog::ACCESS_RESOURCES);
+ file->set_access(EditorFileDialog::ACCESS_RESOURCES);
else
- file->set_access(FileDialog::ACCESS_FILESYSTEM);
+ file->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
- file->set_mode(FileDialog::MODE_OPEN_FILE);
+ file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
file->clear_filters();
file->clear_filters();
@@ -946,10 +946,10 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
if (p_which==0) {
if (hint==PROPERTY_HINT_DIR)
- file->set_access(FileDialog::ACCESS_RESOURCES);
+ file->set_access(EditorFileDialog::ACCESS_RESOURCES);
else
- file->set_access(FileDialog::ACCESS_FILESYSTEM);
- file->set_mode(FileDialog::MODE_OPEN_DIR);
+ file->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+ file->set_mode(EditorFileDialog::MODE_OPEN_DIR);
file->clear_filters();
file->popup_centered_ratio();
} else {
@@ -1001,8 +1001,8 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
}
} else if (p_which==1) {
- file->set_access(FileDialog::ACCESS_RESOURCES);
- file->set_mode(FileDialog::MODE_OPEN_FILE);
+ file->set_access(EditorFileDialog::ACCESS_RESOURCES);
+ file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
List<String> extensions;
String type=(hint==PROPERTY_HINT_RESOURCE_TYPE)?hint_text:String();
@@ -1081,8 +1081,8 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
} else if (p_which==1) {
- file->set_access(FileDialog::ACCESS_RESOURCES);
- file->set_mode(FileDialog::MODE_OPEN_FILE);
+ file->set_access(EditorFileDialog::ACCESS_RESOURCES);
+ file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
List<String> extensions;
ImageLoader::get_recognized_extensions(&extensions);
@@ -1612,7 +1612,7 @@ CustomPropertyEditor::CustomPropertyEditor() {
color_picker->connect("color_changed",this,"_color_changed");
set_as_toplevel(true);
- file = memnew ( FileDialog );
+ file = memnew ( EditorFileDialog );
add_child(file);
file->hide();
diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h
index 164643afaa..de5cac8711 100644
--- a/tools/editor/property_editor.h
+++ b/tools/editor/property_editor.h
@@ -32,7 +32,7 @@
#include "scene/gui/tree.h"
#include "scene/gui/button.h"
#include "scene/gui/label.h"
-#include "scene/gui/file_dialog.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"
@@ -75,7 +75,7 @@ class CustomPropertyEditor : public Popup {
PopupMenu *menu;
SceneTreeDialog *scene_tree;
- FileDialog *file;
+ EditorFileDialog *file;
ConfirmationDialog *error;
String name;
Variant::Type type;
diff --git a/tools/editor/resources_dock.cpp b/tools/editor/resources_dock.cpp
index 33ec1f2054..b69eec4a51 100644
--- a/tools/editor/resources_dock.cpp
+++ b/tools/editor/resources_dock.cpp
@@ -152,7 +152,7 @@ void ResourcesDock::save_resource_as(const Ref<Resource>& p_resource) {
List<String> extensions;
ResourceSaver::get_recognized_extensions(res,&extensions);
- file->set_mode(FileDialog::MODE_SAVE_FILE);
+ file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
if (p_resource->get_path()!="" && p_resource->get_path().find("::")==-1) {
@@ -396,7 +396,7 @@ ResourcesDock::ResourcesDock(EditorNode *p_editor) {
accept = memnew (AcceptDialog);
add_child(accept);
- file = memnew( FileDialog );
+ file = memnew( EditorFileDialog );
add_child(file);
file->connect("file_selected",this,"_file_action");
diff --git a/tools/editor/resources_dock.h b/tools/editor/resources_dock.h
index a94579240e..933b457b29 100644
--- a/tools/editor/resources_dock.h
+++ b/tools/editor/resources_dock.h
@@ -38,6 +38,7 @@
#include "scene/gui/menu_button.h"
#include "scene/gui/file_dialog.h"
#include "create_dialog.h"
+#include "editor_file_dialog.h"
class EditorNode;
@@ -68,7 +69,7 @@ class ResourcesDock : public VBoxContainer {
CreateDialog *create_dialog;
AcceptDialog *accept;
- FileDialog *file;
+ EditorFileDialog *file;
Tree *resources;
bool block_add;
int current_action;
diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp
index 87a13ee9ce..432f60fa53 100644
--- a/tools/editor/scene_tree_dock.cpp
+++ b/tools/editor/scene_tree_dock.cpp
@@ -171,7 +171,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (!_validate_no_foreign())
break;
- file->set_mode(FileDialog::MODE_OPEN_FILE);
+ file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions);
file->clear_filters();
@@ -484,7 +484,7 @@ void SceneTreeDock::_notification(int p_what) {
"MoveDown",
"Duplicate",
"Reparent",
- "Del",
+ "Remove",
};
for(int i=0;i<TOOL_BUTTON_MAX;i++)
@@ -1355,7 +1355,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec
accept = memnew( AcceptDialog );
add_child(accept);
- file = memnew( FileDialog );
+ file = memnew( EditorFileDialog );
add_child(file);
file->connect("file_selected",this,"instance");
set_process_unhandled_key_input(true);
diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h
index e1a4a10e58..34e8a00739 100644
--- a/tools/editor/scene_tree_dock.h
+++ b/tools/editor/scene_tree_dock.h
@@ -87,7 +87,7 @@ class SceneTreeDock : public VBoxContainer {
ConfirmationDialog *delete_dialog;
ReparentDialog *reparent_dialog;
- FileDialog *file;
+ EditorFileDialog *file;
EditorSubScene *import_subscene_dialog;
diff --git a/tools/editor/script_create_dialog.cpp b/tools/editor/script_create_dialog.cpp
index 35f7798ed5..bdfb66f0f2 100644
--- a/tools/editor/script_create_dialog.cpp
+++ b/tools/editor/script_create_dialog.cpp
@@ -184,7 +184,7 @@ void ScriptCreateDialog::_built_in_pressed() {
void ScriptCreateDialog::_browse_path() {
- file_browse->set_mode(FileDialog::MODE_SAVE_FILE);
+ file_browse->set_mode(EditorFileDialog::MODE_SAVE_FILE);
file_browse->clear_filters();
List<String> extensions;
@@ -365,7 +365,7 @@ ScriptCreateDialog::ScriptCreateDialog() {
set_hide_on_ok(false);
set_title("Create Script for Node..");;
- file_browse = memnew( FileDialog );
+ file_browse = memnew( EditorFileDialog );
file_browse->connect("file_selected",this,"_file_selected");
add_child(file_browse);
get_ok()->set_text("Create");
diff --git a/tools/editor/script_create_dialog.h b/tools/editor/script_create_dialog.h
index 61f5df4341..59fde8fbd5 100644
--- a/tools/editor/script_create_dialog.h
+++ b/tools/editor/script_create_dialog.h
@@ -32,7 +32,7 @@
#include "scene/gui/dialogs.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/option_button.h"
-#include "scene/gui/file_dialog.h"
+#include "tools/editor/editor_file_dialog.h"
#include "scene/gui/check_button.h"
class ScriptCreateDialog : public ConfirmationDialog {
@@ -44,7 +44,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
LineEdit *parent_name;
OptionButton *language_menu;
LineEdit *file_path;
- FileDialog *file_browse;
+ EditorFileDialog *file_browse;
CheckButton *internal;
VBoxContainer *path_vb;
AcceptDialog *alert;