Merge branch 'master' of github.com:okamstudio/godot into development

This commit is contained in:
James McLean 2015-06-23 18:22:14 -04:00
commit d23ee8eb01
24 changed files with 1021 additions and 114 deletions

10
.editorconfig Normal file
View file

@ -0,0 +1,10 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = tab
[.travis.yml]
indent_style = space
indent_size = 2

2
.gitignore vendored
View file

@ -281,3 +281,5 @@ cscope.out
cscope.in.out
cscope.po.out
godot.creator.*
projects/

View file

@ -360,6 +360,11 @@ if selected_platform in platform_list:
AddToVSProject(env.scene_sources)
AddToVSProject(env.servers_sources)
AddToVSProject(env.tool_sources)
#env['MSVS_VERSION']='9.0'
env['MSVSBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
env['MSVSREBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
env['MSVSCLEANCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
debug_variants = ['Debug|Win32']+['Debug|x64']
release_variants = ['Release|Win32']+['Release|x64']

View file

@ -340,3 +340,126 @@ UndoRedo::~UndoRedo() {
clear_history();
}
Variant UndoRedo::_add_do_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error) {
if (p_argcount<2) {
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument=0;
return Variant();
}
if (p_args[0]->get_type()!=Variant::OBJECT) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0;
r_error.expected=Variant::OBJECT;
return Variant();
}
if (p_args[1]->get_type()!=Variant::STRING) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=1;
r_error.expected=Variant::STRING;
return Variant();
}
r_error.error=Variant::CallError::CALL_OK;
Object* object = *p_args[0];
String method = *p_args[1];
Variant v[VARIANT_ARG_MAX];
for(int i=0;i<MIN(VARIANT_ARG_MAX,p_argcount-2);++i) {
v[i]=*p_args[i+2];
}
add_do_method(object,method,v[0],v[1],v[2],v[3],v[4]);
return Variant();
}
Variant UndoRedo::_add_undo_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error) {
if (p_argcount<2) {
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument=0;
return Variant();
}
if (p_args[0]->get_type()!=Variant::OBJECT) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0;
r_error.expected=Variant::OBJECT;
return Variant();
}
if (p_args[1]->get_type()!=Variant::STRING) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=1;
r_error.expected=Variant::STRING;
return Variant();
}
r_error.error=Variant::CallError::CALL_OK;
Object* object = *p_args[0];
String method = *p_args[1];
Variant v[VARIANT_ARG_MAX];
for(int i=0;i<MIN(VARIANT_ARG_MAX,p_argcount-2);++i) {
v[i]=*p_args[i+2];
}
add_undo_method(object,method,v[0],v[1],v[2],v[3],v[4]);
return Variant();
}
void UndoRedo::_bind_methods() {
ObjectTypeDB::bind_method(_MD("create_action","name","mergeable"),&UndoRedo::create_action, DEFVAL(false) );
ObjectTypeDB::bind_method(_MD("commit_action"),&UndoRedo::commit_action);
//ObjectTypeDB::bind_method(_MD("add_do_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_do_method);
//ObjectTypeDB::bind_method(_MD("add_undo_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_undo_method);
{
MethodInfo mi;
mi.name="add_do_method";
mi.arguments.push_back( PropertyInfo( Variant::OBJECT, "object"));
mi.arguments.push_back( PropertyInfo( Variant::STRING, "method"));
Vector<Variant> defargs;
for(int i=0;i<VARIANT_ARG_MAX;++i) {
mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i)));
defargs.push_back(Variant());
}
ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"add_do_method",&UndoRedo::_add_do_method,mi,defargs);
}
{
MethodInfo mi;
mi.name="add_undo_method";
mi.arguments.push_back( PropertyInfo( Variant::OBJECT, "object"));
mi.arguments.push_back( PropertyInfo( Variant::STRING, "method"));
Vector<Variant> defargs;
for(int i=0;i<VARIANT_ARG_MAX;++i) {
mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i)));
defargs.push_back(Variant());
}
ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"add_undo_method",&UndoRedo::_add_undo_method,mi,defargs);
}
ObjectTypeDB::bind_method(_MD("add_do_property","object", "property", "value:var"),&UndoRedo::add_do_property);
ObjectTypeDB::bind_method(_MD("add_undo_property","object", "property", "value:var"),&UndoRedo::add_undo_property);
ObjectTypeDB::bind_method(_MD("add_do_reference","object"),&UndoRedo::add_do_reference);
ObjectTypeDB::bind_method(_MD("add_undo_reference","object"),&UndoRedo::add_undo_reference);
ObjectTypeDB::bind_method(_MD("clear_history"),&UndoRedo::clear_history);
ObjectTypeDB::bind_method(_MD("get_current_action_name"),&UndoRedo::get_current_action_name);
ObjectTypeDB::bind_method(_MD("get_version"),&UndoRedo::get_version);
}

View file

@ -38,9 +38,12 @@
class UndoRedo : public Object {
OBJ_TYPE(UndoRedo,Object);
OBJ_SAVE_TYPE( UndoRedo );
public:
typedef void (*CommitNotifyCallback)(void *p_ud,const String& p_name);
Variant _add_do_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
Variant _add_undo_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
private:
struct Operation {
@ -81,6 +84,10 @@ private:
CommitNotifyCallback callback;
void* callback_ud;
protected:
static void _bind_methods();
public:
void create_action(const String& p_name="",bool p_mergeable=false);

View file

@ -1,11 +0,0 @@
::res://::1422910453
floor.png::ImageTexture::1422910453::
fog.gd::GDScript::1422910025::
fog.png::ImageTexture::1422908128::
fog.scn::PackedScene::1422909435::
fog.xml::TileSet::1422909324::
icon.png::ImageTexture::1422811193::
tile_edit.scn::PackedScene::1422909313::
troll.gd::GDScript::1422909940::
troll.png::ImageTexture::1418669358::
troll.scn::PackedScene::1418669358::

View file

@ -3,12 +3,9 @@
name="Motion Test"
main_scene="res://motion.scn"
<<<<<<< HEAD
=======
[display]
width=800
height=600
stretch_mode="2d"
stretch_aspect="keep"
>>>>>>> ab99671bb835a5fe24a092ec34afe1ad862ac254

View file

@ -8783,7 +8783,7 @@
</description>
</method>
<method name="get_undo_redo" >
<return type="Object">
<return type="UndoRedo">
</return>
<description>
</description>

View file

@ -2131,7 +2131,6 @@ bool GDInstance::set(const StringName& p_name, const Variant& p_value) {
{
const Map<StringName,GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name);
if (E) {
members[E->get().index]=p_value;
if (E->get().setter) {
const Variant *val=&p_value;
Variant::CallError err;
@ -2140,6 +2139,8 @@ bool GDInstance::set(const StringName& p_name, const Variant& p_value) {
return true; //function exists, call was successful
}
}
else
members[E->get().index] = p_value;
return true;
}
}

View file

@ -61,7 +61,7 @@ void GridMapEditor::_menu_option(int p_option) {
case MENU_OPTION_CONFIGURE: {
} break;
case MENU_OPTION_LOCK_VIEW: {
@ -522,7 +522,9 @@ void GridMapEditor::_duplicate_paste() {
}
bool GridMapEditor::forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event) {
if (!node) {
return false;
}
if (edit_mode->get_selected()==0) { // regular click
switch (p_event.type) {
@ -706,9 +708,40 @@ struct _CGMEItemSort {
};
void GridMapEditor::_set_display_mode(int p_mode) {
if (display_mode==p_mode) {
return;
}
if (p_mode == DISPLAY_LIST) {
mode_list->set_pressed(true);
mode_thumbnail->set_pressed(false);
} else if (p_mode == DISPLAY_THUMBNAIL) {
mode_list->set_pressed(false);
mode_thumbnail->set_pressed(true);
}
display_mode=p_mode;
update_pallete();
}
void GridMapEditor::update_pallete() {
int selected = theme_pallete->get_current();
theme_pallete->clear();
if (display_mode == DISPLAY_THUMBNAIL) {
theme_pallete->set_max_columns(0);
theme_pallete->set_icon_mode(ItemList::ICON_MODE_TOP);
} else if (display_mode == DISPLAY_LIST){
theme_pallete->set_max_columns(1);
theme_pallete->set_icon_mode(ItemList::ICON_MODE_LEFT);
}
float min_size = EDITOR_DEF("grid_map/preview_size",64);
theme_pallete->set_min_icon_size(Size2(min_size, min_size));
theme_pallete->set_fixed_column_width(min_size*3/2);
theme_pallete->set_max_text_lines(2);
Ref<MeshLibrary> theme = node->get_theme();
@ -720,10 +753,6 @@ void GridMapEditor::update_pallete() {
Vector<int> ids;
ids = theme->get_item_list();
TreeItem *root = theme_pallete->create_item(NULL);
theme_pallete->set_hide_root(true);
TreeItem *selected=NULL;
List<_CGMEItemSort> il;
for(int i=0;i<ids.size();i++) {
@ -734,45 +763,31 @@ void GridMapEditor::update_pallete() {
}
il.sort();
int col=0;
TreeItem *ti=NULL;
int selected_col=0;
int item = 0;
for(List<_CGMEItemSort>::Element *E=il.front();E;E=E->next()) {
int id = E->get().id;
if (col==0) {
ti = theme_pallete->create_item(root);
}
theme_pallete->add_item("");
String name=theme->get_item_name(id);
Ref<Texture> preview = theme->get_item_preview(id);
if (!preview.is_null()) {
ti->set_cell_mode(col,TreeItem::CELL_MODE_ICON);
ti->set_icon(col,preview);
ti->set_tooltip(col,name);
} else {
ti->set_text(col,name);
theme_pallete->set_item_icon(item, preview);
theme_pallete->set_item_tooltip(item, name);
}
ti->set_metadata(col,id);
if (selected_pallete==id) {
selected=ti;
selected_col=col;
if (name!="") {
theme_pallete->set_item_text(item,name);
}
theme_pallete->set_item_metadata(item, id);
col++;
if (col==theme_pallete->get_columns())
col=0;
item++;
}
if (selected)
selected->select(selected_col);
if (selected!=-1) {
theme_pallete->select(selected);
}
last_theme=theme.operator->();
}
@ -842,6 +857,9 @@ void GridMapEditor::edit(GridMap *p_gridmap) {
VisualServer::get_singleton()->instance_geometry_set_flag(grid_instance[i],VS::INSTANCE_FLAG_VISIBLE,false);
}
VisualServer::get_singleton()->instance_geometry_set_flag(cursor_instance, VS::INSTANCE_FLAG_VISIBLE,false);
_clear_areas();
return;
@ -951,7 +969,7 @@ void GridMapEditor::update_grid() {
grid_xform.origin.x-=1; //force update in hackish way.. what do i care
VS *vs = VS::get_singleton();
//VS *vs = VS::get_singleton();
grid_ofs[edit_axis]=edit_floor[edit_axis]*node->get_cell_size();
@ -976,7 +994,7 @@ void GridMapEditor::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_TREE) {
theme_pallete->connect("cell_selected", this,"_item_selected_cbk");
theme_pallete->connect("item_selected", this,"_item_selected_cbk");
edit_mode->connect("item_selected", this,"_edit_mode_changed");
area_list->connect("item_edited", this,"_area_renamed");
area_list->connect("item_selected", this,"_area_selected");
@ -1014,7 +1032,7 @@ void GridMapEditor::_notification(int p_what) {
if (xf!=grid_xform) {
for(int i=0;i<3;i++) {
VS::get_singleton()->instance_set_transform(grid_instance[i],xf * edit_grid_xform);
}
grid_xform=xf;
@ -1043,7 +1061,9 @@ void GridMapEditor::_notification(int p_what) {
}
void GridMapEditor::_update_cursor_instance() {
if (!node) {
return;
}
if (cursor_instance.is_valid())
VisualServer::get_singleton()->free(cursor_instance);
@ -1063,18 +1083,8 @@ void GridMapEditor::_update_cursor_instance() {
}
void GridMapEditor::_item_selected_cbk() {
TreeItem *it = theme_pallete->get_selected();
if (it) {
selected_pallete=it->get_metadata(theme_pallete->get_selected_column());
} else {
selected_pallete=-1;
}
void GridMapEditor::_item_selected_cbk(int idx) {
selected_pallete=theme_pallete->get_item_metadata(idx);
_update_cursor_instance();
@ -1092,7 +1102,9 @@ void GridMapEditor::_clear_areas() {
}
void GridMapEditor::_update_areas_display() {
if (!node) {
return;
}
_clear_areas();
List<int> areas;
@ -1179,7 +1191,7 @@ void GridMapEditor::_bind_methods() {
ObjectTypeDB::bind_method("_area_selected",&GridMapEditor::_area_selected);
ObjectTypeDB::bind_method("_floor_changed",&GridMapEditor::_floor_changed);
ObjectTypeDB::bind_method(_MD("_set_display_mode","mode"), &GridMapEditor::_set_display_mode);
}
@ -1240,6 +1252,9 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
clip_mode=CLIP_DISABLED;
options->get_popup()->connect("item_pressed", this,"_menu_option");
HBoxContainer *hb = memnew( HBoxContainer );
add_child(hb);
hb->set_h_size_flags(SIZE_EXPAND_FILL);
edit_mode = memnew(OptionButton);
edit_mode->set_area_as_parent_rect();
@ -1247,13 +1262,27 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
edit_mode->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,14);;
edit_mode->add_item("Tiles");
edit_mode->add_item("Areas");
add_child(edit_mode);
hb->add_child(edit_mode);
edit_mode->set_h_size_flags(SIZE_EXPAND_FILL);
mode_thumbnail = memnew( ToolButton );
mode_thumbnail->set_toggle_mode(true);
mode_thumbnail->set_pressed(true);
mode_thumbnail->set_icon(p_editor->get_gui_base()->get_icon("FileThumbnail","EditorIcons"));
hb->add_child(mode_thumbnail);
mode_thumbnail->connect("pressed", this, "_set_display_mode", varray(DISPLAY_THUMBNAIL));
mode_list = memnew( ToolButton );
mode_list->set_toggle_mode(true);
mode_list->set_pressed(false);
mode_list->set_icon(p_editor->get_gui_base()->get_icon("FileList", "EditorIcons"));
hb->add_child(mode_list);
mode_list->connect("pressed", this, "_set_display_mode", varray(DISPLAY_LIST));
display_mode = DISPLAY_THUMBNAIL;
selected_area=-1;
theme_pallete = memnew( Tree );
theme_pallete->set_columns(3);
theme_pallete = memnew( ItemList );
add_child(theme_pallete);
theme_pallete->set_v_size_flags(SIZE_EXPAND_FILL);

View file

@ -40,10 +40,8 @@
class SpatialEditorPlugin;
class GridMapEditor : public VBoxContainer {
OBJ_TYPE(GridMapEditor, VBoxContainer );
enum {
GRID_CURSOR_SIZE=50
@ -66,6 +64,10 @@ class GridMapEditor : public VBoxContainer {
CLIP_BELOW
};
enum DisplayMode {
DISPLAY_THUMBNAIL,
DISPLAY_LIST
};
UndoRedo *undo_redo;
InputAction input_action;
@ -73,6 +75,8 @@ class GridMapEditor : public VBoxContainer {
MenuButton * options;
SpinBox *floor;
OptionButton *edit_mode;
ToolButton *mode_thumbnail;
ToolButton *mode_list;
HBoxContainer *spatial_editor_hb;
struct SetItem {
@ -132,6 +136,7 @@ class GridMapEditor : public VBoxContainer {
Vector3 cursor_origin;
Vector3 last_mouseover;
int display_mode;
int selected_pallete;
int selected_area;
int cursor_rot;
@ -183,9 +188,10 @@ class GridMapEditor : public VBoxContainer {
void _configure();
void _menu_option(int);
void update_pallete();
Tree *theme_pallete;
void _set_display_mode(int p_mode);
ItemList *theme_pallete;
Tree *area_list;
void _item_selected_cbk();
void _item_selected_cbk(int idx);
void _update_cursor_transform();
void _update_cursor_instance();
void _update_clip();

View file

@ -48,6 +48,7 @@ void ColorRampEdit::_input_event(const InputEvent& p_event) {
points.remove(grabbed);
grabbed=-1;
grabbing=false;
update();
emit_signal("ramp_changed");
accept_event();
@ -67,12 +68,38 @@ void ColorRampEdit::_input_event(const InputEvent& p_event) {
{
points.remove(grabbed);
grabbed=-1;
grabbing=false;
update();
emit_signal("ramp_changed");
accept_event();
}
}
//Hold alt key to duplicate selected color
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed && p_event.key.mod.alt ) {
int x = p_event.mouse_button.x;
grabbed=_get_point_from_pos(x);
if( grabbed != -1 ) {
int total_w = get_size().width-get_size().height-3;
ColorRamp::Point newPoint = points[grabbed];
newPoint.offset=CLAMP(x/float(total_w),0,1);
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");
update();
}
}
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) {
update();
@ -158,6 +185,33 @@ void ColorRampEdit::_input_event(const InputEvent& p_event) {
int x = p_event.mouse_motion.x;
float newofs = CLAMP(x/float(total_w),0,1);
//Snap to nearest point if holding shift
if (p_event.key.mod.shift) {
float snap_treshhold = 0.03;
float smallest_ofs = snap_treshhold;
bool founded = false;
int nearest_point;
for(int i=0;i<points.size();++i) {
if (i != grabbed) {
float temp_ofs = ABS(points[i].offset - newofs);
if (temp_ofs < smallest_ofs) {
smallest_ofs = temp_ofs;
nearest_point = i;
if (founded)
break;
founded = true;
}
}
}
if (founded) {
if (points[nearest_point].offset < newofs)
newofs = points[nearest_point].offset+0.00001;
else
newofs = points[nearest_point].offset-0.00001;
newofs = CLAMP(newofs,0,1);
}
}
bool valid=true;
for(int i=0;i<points.size();i++) {

View file

@ -686,7 +686,7 @@ void FileDialog::set_default_show_hidden_files(bool p_show) {
FileDialog::FileDialog() {
show_hidden_files=true;
show_hidden_files=default_show_hidden_files;
VBoxContainer *vbc = memnew( VBoxContainer );
add_child(vbc);

View file

@ -510,6 +510,7 @@ float Font::draw_char(RID p_canvas_item, const Point2& p_pos, const CharType& p_
void Font::_bind_methods() {
ObjectTypeDB::bind_method(_MD("create_from_fnt","path"),&Font::create_from_fnt);
ObjectTypeDB::bind_method(_MD("set_height","px"),&Font::set_height);
ObjectTypeDB::bind_method(_MD("get_height"),&Font::get_height);

View file

@ -55,7 +55,7 @@ void register_server_types() {
ObjectTypeDB::register_virtual_type<Physics2DDirectBodyState>();
ObjectTypeDB::register_virtual_type<Physics2DDirectSpaceState>();
ObjectTypeDB::register_virtual_type<Physics2DShapeQueryResult>();
ObjectTypeDB::register_virtual_type<Physics2DTestMotionResult>();
ObjectTypeDB::register_type<Physics2DTestMotionResult>();
ObjectTypeDB::register_type<Physics2DShapeQueryParameters>();
ObjectTypeDB::register_type<PhysicsShapeQueryParameters>();

View file

@ -3319,7 +3319,8 @@ void AnimationKeyEditor::_insert_delay() {
void AnimationKeyEditor::_step_changed(float p_len) {
updating=true;
animation->set_step(p_len);
if (!animation.is_null())
animation->set_step(p_len);
updating=false;
}

View file

@ -92,6 +92,7 @@
#include "plugins/navigation_polygon_editor_plugin.h"
#include "plugins/light_occluder_2d_editor_plugin.h"
#include "plugins/color_ramp_editor_plugin.h"
#include "plugins/collision_shape_2d_editor_plugin.h"
// end
#include "tools/editor/io_plugins/editor_texture_import_plugin.h"
#include "tools/editor/io_plugins/editor_scene_import_plugin.h"
@ -3455,6 +3456,7 @@ void EditorNode::register_editor_types() {
ObjectTypeDB::register_type<EditorScenePostImport>();
ObjectTypeDB::register_type<EditorScript>();
ObjectTypeDB::register_type<EditorFileDialog>();
ObjectTypeDB::register_type<UndoRedo>();
//ObjectTypeDB::register_type<EditorImporter>();
@ -5050,6 +5052,7 @@ EditorNode::EditorNode() {
add_editor_plugin( memnew( LightOccluder2DEditorPlugin(this) ) );
add_editor_plugin( memnew( NavigationPolygonEditorPlugin(this) ) );
add_editor_plugin( memnew( ColorRampEditorPlugin(this) ) );
add_editor_plugin( memnew( CollisionShape2DEditorPlugin(this) ) );
for(int i=0;i<EditorPlugins::get_plugin_count();i++)
add_editor_plugin( EditorPlugins::create(i,this) );

View file

@ -0,0 +1,533 @@
#include "collision_shape_2d_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
#include "scene/resources/segment_shape_2d.h"
#include "scene/resources/shape_line_2d.h"
#include "scene/resources/circle_shape_2d.h"
#include "scene/resources/rectangle_shape_2d.h"
#include "scene/resources/capsule_shape_2d.h"
#include "scene/resources/convex_polygon_shape_2d.h"
#include "scene/resources/concave_polygon_shape_2d.h"
Variant CollisionShape2DEditor::get_handle_value(int idx) const {
switch ( shape_type ) {
case CAPSULE_SHAPE: {
Ref<CapsuleShape2D> capsule = node->get_shape();
if (idx==0) {
return capsule->get_radius();
} else if (idx==1) {
return capsule->get_height();
}
} break;
case CIRCLE_SHAPE: {
Ref<CircleShape2D> circle = node->get_shape();
if (idx==0) {
return circle->get_radius();
}
} break;
case CONCAVE_POLYGON_SHAPE: {
} break;
case CONVEX_POLYGON_SHAPE: {
} break;
case LINE_SHAPE: {
} break;
case RAY_SHAPE: {
Ref<RayShape2D> ray = node->get_shape();
if (idx==0) {
return ray->get_length();
}
} break;
case RECTANGLE_SHAPE: {
Ref<RectangleShape2D> rect = node->get_shape();
if (idx<2) {
return rect->get_extents().abs();
}
} break;
case SEGMENT_SHAPE: {
Ref<SegmentShape2D> seg = node->get_shape();
if (idx==0) {
return seg->get_a();
} else if (idx==1) {
return seg->get_b();
}
} break;
}
return Variant();
}
void CollisionShape2DEditor::set_handle(int idx, Point2& p_point) {
switch ( shape_type ) {
case CAPSULE_SHAPE: {
if (idx < 2) {
Ref<CapsuleShape2D> capsule = node->get_shape();
real_t parameter = Math::abs(p_point[idx]);
if (idx==0) {
capsule->set_radius(parameter);
} else if (idx==1){
capsule->set_height(parameter*2 - capsule->get_radius()*2);
}
canvas_item_editor->get_viewport_control()->update();
}
} break;
case CIRCLE_SHAPE: {
Ref<CircleShape2D> circle = node->get_shape();
circle->set_radius(p_point.length());
canvas_item_editor->get_viewport_control()->update();
} break;
case CONCAVE_POLYGON_SHAPE: {
} break;
case CONVEX_POLYGON_SHAPE: {
} break;
case LINE_SHAPE: {
} break;
case RAY_SHAPE: {
Ref<RayShape2D> ray = node->get_shape();
ray->set_length(Math::abs(p_point.y));
canvas_item_editor->get_viewport_control()->update();
} break;
case RECTANGLE_SHAPE: {
if (idx<2) {
Ref<RectangleShape2D> rect = node->get_shape();
Vector2 extents = rect->get_extents();
extents[idx] = p_point[idx];
rect->set_extents(extents.abs());
canvas_item_editor->get_viewport_control()->update();
}
} break;
case SEGMENT_SHAPE: {
if (edit_handle < 2) {
Ref<SegmentShape2D> seg = node->get_shape();
if (idx==0) {
seg->set_a(p_point);
} else if (idx==1) {
seg->set_b(p_point);
}
canvas_item_editor->get_viewport_control()->update();
}
} break;
}
}
void CollisionShape2DEditor::commit_handle(int idx, Variant& p_org) {
Control* c = canvas_item_editor->get_viewport_control();
undo_redo->create_action("Set Handle");
switch ( shape_type ) {
case CAPSULE_SHAPE: {
Ref<CapsuleShape2D> capsule = node->get_shape();
if (idx==0) {
undo_redo->add_do_method(capsule.ptr(),"set_radius",capsule->get_radius());
undo_redo->add_do_method(c,"update");
undo_redo->add_undo_method(capsule.ptr(),"set_radius",p_org);
undo_redo->add_do_method(c,"update");
} else if (idx==1) {
undo_redo->add_do_method(capsule.ptr(),"set_height",capsule->get_height());
undo_redo->add_do_method(c,"update");
undo_redo->add_undo_method(capsule.ptr(),"set_height",p_org);
undo_redo->add_undo_method(c,"update");
}
} break;
case CIRCLE_SHAPE: {
Ref<CircleShape2D> circle = node->get_shape();
undo_redo->add_do_method(circle.ptr(),"set_radius",circle->get_radius());
undo_redo->add_do_method(c,"update");
undo_redo->add_undo_method(circle.ptr(),"set_radius",p_org);
undo_redo->add_undo_method(c,"update");
} break;
case CONCAVE_POLYGON_SHAPE: {
} break;
case CONVEX_POLYGON_SHAPE: {
} break;
case LINE_SHAPE: {
} break;
case RAY_SHAPE: {
Ref<RayShape2D> ray = node->get_shape();
undo_redo->add_do_method(ray.ptr(),"set_length",ray->get_length());
undo_redo->add_do_method(c,"update");
undo_redo->add_undo_method(ray.ptr(),"set_length",p_org);
undo_redo->add_undo_method(c,"update");
} break;
case RECTANGLE_SHAPE: {
Ref<RectangleShape2D> rect = node->get_shape();
undo_redo->add_do_method(rect.ptr(),"set_extents",rect->get_extents());
undo_redo->add_do_method(c,"update");
undo_redo->add_undo_method(rect.ptr(),"set_extents",p_org);
undo_redo->add_undo_method(c,"update");
} break;
case SEGMENT_SHAPE: {
Ref<SegmentShape2D> seg = node->get_shape();
if (idx==0) {
undo_redo->add_do_method(seg.ptr(),"set_a",seg->get_a());
undo_redo->add_do_method(c,"update");
undo_redo->add_undo_method(seg.ptr(),"set_a",p_org);
undo_redo->add_undo_method(c,"update");
} else if (idx==1) {
undo_redo->add_do_method(seg.ptr(),"set_b",seg->get_b());
undo_redo->add_do_method(c,"update");
undo_redo->add_undo_method(seg.ptr(),"set_b",p_org);
undo_redo->add_undo_method(c,"update");
}
} break;
}
undo_redo->commit_action();
}
bool CollisionShape2DEditor::forward_input_event(const InputEvent& p_event) {
if (!node) {
return false;
}
if (!node->get_shape().is_valid()) {
return false;
}
if (shape_type == -1) {
return false;
}
switch( p_event.type ) {
case InputEvent::MOUSE_BUTTON: {
const InputEventMouseButton& mb = p_event.mouse_button;
Matrix32 gt = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
Point2 gpoint(mb.x,mb.y);
if (mb.button_index == BUTTON_LEFT) {
if (mb.pressed) {
for (int i = 0; i < handles.size(); i++) {
if (gt.xform(handles[i]).distance_to(gpoint) < 8) {
edit_handle = i;
break;
}
}
if (edit_handle==-1) {
pressed = false;
return false;
}
original = get_handle_value(edit_handle);
pressed = true;
return true;
} else {
if (pressed) {
commit_handle(edit_handle, original);
edit_handle = -1;
pressed = false;
return true;
}
}
}
return false;
} break;
case InputEvent::MOUSE_MOTION: {
const InputEventMouseMotion& mm = p_event.mouse_motion;
if (edit_handle == -1 || !pressed) {
return false;
}
Point2 gpoint = Point2(mm.x,mm.y);
Point2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
cpoint = canvas_item_editor->snap_point(cpoint);
cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
set_handle(edit_handle, cpoint);
return true;
} break;
}
return false;
}
void CollisionShape2DEditor::_get_current_shape_type() {
if (!node) {
return;
}
Ref<Shape2D> s = node->get_shape();
if (!s.is_valid()) {
return;
}
if (s->cast_to<CapsuleShape2D>()) {
shape_type = CAPSULE_SHAPE;
} else if (s->cast_to<CircleShape2D>()) {
shape_type = CIRCLE_SHAPE;
} else if (s->cast_to<ConcavePolygonShape2D>()) {
shape_type = CONCAVE_POLYGON_SHAPE;
} else if (s->cast_to<ConvexPolygonShape2D>()) {
shape_type = CONVEX_POLYGON_SHAPE;
} else if (s->cast_to<LineShape2D>()) {
shape_type = LINE_SHAPE;
} else if (s->cast_to<RayShape2D>()) {
shape_type = RAY_SHAPE;
} else if (s->cast_to<RectangleShape2D>()) {
shape_type = RECTANGLE_SHAPE;
} else if (s->cast_to<SegmentShape2D>()) {
shape_type = SEGMENT_SHAPE;
} else {
shape_type = -1;
}
canvas_item_editor->get_viewport_control()->update();
}
void CollisionShape2DEditor::_canvas_draw() {
if (!node) {
return;
}
if (!node->get_shape().is_valid()) {
return;
}
_get_current_shape_type();
if (shape_type == -1) {
return;
}
Control *c = canvas_item_editor->get_viewport_control();
Matrix32 gt = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
Ref<Texture> h = get_icon("EditorHandle","EditorIcons");
Vector2 size = h->get_size()*0.5;
handles.clear();
switch (shape_type) {
case CAPSULE_SHAPE: {
Ref<CapsuleShape2D> shape = node->get_shape();
handles.resize(2);
float radius = shape->get_radius();
float height = shape->get_height()/2;
handles[0] = Point2(radius, -height);
handles[1] = Point2(0,-(height + radius));
c->draw_texture(h, gt.xform(handles[0])-size);
c->draw_texture(h, gt.xform(handles[1])-size);
} break;
case CIRCLE_SHAPE: {
Ref<CircleShape2D> shape = node->get_shape();
handles.resize(1);
handles[0] = Point2(shape->get_radius(),0);
c->draw_texture(h, gt.xform(handles[0])-size);
} break;
case CONCAVE_POLYGON_SHAPE: {
} break;
case CONVEX_POLYGON_SHAPE: {
} break;
case LINE_SHAPE: {
} break;
case RAY_SHAPE: {
Ref<RayShape2D> shape = node->get_shape();
handles.resize(1);
handles[0] = Point2(0,shape->get_length());
c->draw_texture(h,gt.xform(handles[0])-size);
} break;
case RECTANGLE_SHAPE: {
Ref<RectangleShape2D> shape = node->get_shape();
handles.resize(2);
Vector2 ext = shape->get_extents();
handles[0] = Point2(ext.x,0);
handles[1] = Point2(0,-ext.y);
c->draw_texture(h,gt.xform(handles[0])-size);
c->draw_texture(h,gt.xform(handles[1])-size);
} break;
case SEGMENT_SHAPE: {
Ref<SegmentShape2D> shape = node->get_shape();
handles.resize(2);
handles[0] = shape->get_a();
handles[1] = shape->get_b();
c->draw_texture(h, gt.xform(handles[0])-size);
c->draw_texture(h, gt.xform(handles[1])-size);
} break;
}
}
void CollisionShape2DEditor::edit(Node* p_node) {
if (!canvas_item_editor) {
canvas_item_editor=CanvasItemEditor::get_singleton();
}
if (p_node) {
node=p_node->cast_to<CollisionShape2D>();
if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw"))
canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw");
_get_current_shape_type();
} else {
edit_handle = -1;
shape_type = -1;
if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw"))
canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw");
node=NULL;
}
canvas_item_editor->get_viewport_control()->update();
}
void CollisionShape2DEditor::_bind_methods() {
ObjectTypeDB::bind_method("_canvas_draw",&CollisionShape2DEditor::_canvas_draw);
ObjectTypeDB::bind_method("_get_current_shape_type",&CollisionShape2DEditor::_get_current_shape_type);
}
CollisionShape2DEditor::CollisionShape2DEditor(EditorNode* p_editor) {
node = NULL;
canvas_item_editor = NULL;
editor = p_editor;
undo_redo = p_editor->get_undo_redo();
edit_handle = -1;
pressed = false;
}
void CollisionShape2DEditorPlugin::edit(Object* p_obj) {
collision_shape_2d_editor->edit(p_obj->cast_to<Node>());
}
bool CollisionShape2DEditorPlugin::handles(Object* p_obj) const {
return p_obj->is_type("CollisionShape2D");
}
void CollisionShape2DEditorPlugin::make_visible(bool visible) {
if (!visible) {
edit(NULL);
}
}
CollisionShape2DEditorPlugin::CollisionShape2DEditorPlugin(EditorNode* p_node) {
editor=p_node;
collision_shape_2d_editor = memnew( CollisionShape2DEditor(p_node) );
p_node->get_gui_base()->add_child(collision_shape_2d_editor);
}
CollisionShape2DEditorPlugin::~CollisionShape2DEditorPlugin() {
}

View file

@ -0,0 +1,73 @@
#ifndef COLLISION_SHAPE_2D_EDITOR_PLUGIN_H
#define COLLISION_SHAPE_2D_EDITOR_PLUGIN_H
#include "tools/editor/editor_plugin.h"
#include "tools/editor/editor_node.h"
#include "scene/2d/collision_shape_2d.h"
class CanvasItemEditor;
class CollisionShape2DEditor : public Control {
OBJ_TYPE(CollisionShape2DEditor, Control);
enum ShapeType {
CAPSULE_SHAPE,
CIRCLE_SHAPE,
CONCAVE_POLYGON_SHAPE,
CONVEX_POLYGON_SHAPE,
LINE_SHAPE,
RAY_SHAPE,
RECTANGLE_SHAPE,
SEGMENT_SHAPE
};
EditorNode* editor;
UndoRedo* undo_redo;
CanvasItemEditor* canvas_item_editor;
CollisionShape2D* node;
Vector<Point2> handles;
int shape_type;
int edit_handle;
bool pressed;
Variant original;
Variant get_handle_value(int idx) const;
void set_handle(int idx, Point2& p_point);
void commit_handle(int idx, Variant& p_org);
void _get_current_shape_type();
void _canvas_draw();
protected:
static void _bind_methods();
public:
bool forward_input_event(const InputEvent& p_event);
void edit(Node* p_node);
CollisionShape2DEditor(EditorNode* p_editor);
};
class CollisionShape2DEditorPlugin : public EditorPlugin {
OBJ_TYPE(CollisionShape2DEditorPlugin, EditorPlugin);
CollisionShape2DEditor* collision_shape_2d_editor;
EditorNode* editor;
public:
virtual bool forward_input_event(const InputEvent& p_event) { return collision_shape_2d_editor->forward_input_event(p_event); }
virtual String get_name() const { return "CollisionShape2D"; }
bool has_main_screen() const { return false; }
virtual void edit(Object* p_obj);
virtual bool handles(Object* p_obj) const;
virtual void make_visible(bool visible);
CollisionShape2DEditorPlugin(EditorNode* p_editor);
~CollisionShape2DEditorPlugin();
};
#endif //COLLISION_SHAPE_2D_EDITOR_PLUGIN_H

View file

@ -290,8 +290,19 @@ void ScriptTextEditor::reload_text() {
ERR_FAIL_COND(script.is_null()) ;
get_text_edit()->set_text(script->get_source_code());
get_text_edit()->clear_undo_history();
TextEdit *te = get_text_edit();
int column = te->cursor_get_column();
int row = te->cursor_get_line();
int h = te->get_h_scroll();
int v = te->get_v_scroll();
te->set_text(script->get_source_code());
te->clear_undo_history();
te->cursor_set_line(row);
te->cursor_set_column(column);
te->set_h_scroll(h);
te->set_v_scroll(v);
_line_col_changed();
}

View file

@ -71,22 +71,19 @@ void TileMapEditor::_canvas_mouse_exit() {
}
int TileMapEditor::get_selected_tile() const {
TreeItem *item = palette->get_selected();
if (!item)
int item = palette->get_current();
if (item==-1)
return TileMap::INVALID_CELL;
return item->get_metadata(0);
return palette->get_item_metadata(item);
}
void TileMapEditor::set_selected_tile(int p_tile) {
TreeItem *item = palette->get_root()->get_children();
while (item) {
if ((int)item->get_metadata(0) == p_tile) {
item->select(0);
palette->ensure_cursor_is_visible();
for (int i = 0; i < palette->get_item_count(); i++) {
if (palette->get_item_metadata(i).operator int() == p_tile) {
palette->select(i,true);
palette->ensure_current_is_visible();
break;
}
item = item->get_next();
}
}
@ -95,7 +92,7 @@ void TileMapEditor::_set_cell_shortened(const Point2& p_pos,int p_value,bool p_f
ERR_FAIL_COND(!node);
node->set_cell(floor(p_pos.x), floor(p_pos.y), p_value, p_flip_h, p_flip_v, p_transpose);
}
void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose,bool p_with_undo) {
ERR_FAIL_COND(!node);
@ -120,42 +117,78 @@ void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bo
}
void TileMapEditor::_set_display_mode(int p_mode) {
if (display_mode == p_mode) {
return;
}
switch (p_mode) {
case DISPLAY_THUMBNAIL: {
button_thumbnail->set_pressed(true);
button_list->set_pressed(false);
} break;
case DISPLAY_LIST: {
button_thumbnail->set_pressed(false);
button_list->set_pressed(true);
} break;
}
display_mode = p_mode;
_update_palette();
}
void TileMapEditor::_update_palette() {
if (!node)
return;
palette->clear();;
palette->clear();
Ref<TileSet> tileset=node->get_tileset();
if (!tileset.is_valid())
return;
TreeItem *root = palette->create_item();
palette->set_hide_root(true);
List<int> tiles;
tileset->get_tile_list(&tiles);
if (display_mode == DISPLAY_THUMBNAIL) {
palette->set_max_columns(0);
palette->set_icon_mode(ItemList::ICON_MODE_TOP);
} else if (display_mode == DISPLAY_LIST) {
palette->set_max_columns(1);
palette->set_icon_mode(ItemList::ICON_MODE_LEFT);
}
palette->set_max_text_lines(2);
for(List<int>::Element *E=tiles.front();E;E=E->next()) {
palette->add_item("");
TreeItem *tile = palette->create_item(root);
tile->set_icon_max_width(0,64);
Ref<Texture> tex = tileset->tile_get_texture(E->get());
if (tex.is_valid()) {
tile->set_icon(0,tex);
Rect2 region = tileset->tile_get_region(E->get());
if (region!=Rect2())
tile->set_icon_region(0,region);
} else if (tileset->tile_get_name(E->get())!="")
tile->set_text(0,tileset->tile_get_name(E->get()));
else
tile->set_text(0,"#"+itos(E->get()));
if (!region.has_no_area()) {
Image data = VS::get_singleton()->texture_get_data(tex->get_rid());
tile->set_metadata(0,E->get());
Ref<ImageTexture> img = memnew( ImageTexture );
img->create_from_image(data.get_rect(region));
palette->set_item_icon(palette->get_item_count()-1, img);
} else {
palette->set_item_icon(palette->get_item_count()-1,tex);
}
}
if (tileset->tile_get_name(E->get())!="") {
palette->set_item_text(palette->get_item_count()-1, tileset->tile_get_name(E->get()));
} else {
palette->set_item_text(palette->get_item_count()-1, "#"+itos(E->get()));
}
palette->set_item_metadata(palette->get_item_count()-1, E->get());
}
}
@ -387,7 +420,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
}
if (tool==TOOL_ERASING) {
Point2i local =over_tile;
Point2i local =over_tile;
if (!paint_undo.has(over_tile)) {
paint_undo[over_tile]=_get_op_from_cell(over_tile);
}
@ -641,7 +674,7 @@ void TileMapEditor::_canvas_draw() {
Ref<Texture> t = ts->tile_get_texture(st);
if (t.is_valid()) {
Vector2 from = node->map_to_world(over_tile)+node->get_cell_draw_offset();
Rect2 r = ts->tile_get_region(st);
Rect2 r = ts->tile_get_region(st);
Size2 sc = xform.get_scale();
if (mirror_x->is_pressed())
sc.x*=-1.0;
@ -755,7 +788,7 @@ void TileMapEditor::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_tileset_settings_changed"),&TileMapEditor::_tileset_settings_changed);
ObjectTypeDB::bind_method(_MD("_update_transform_buttons"),&TileMapEditor::_update_transform_buttons);
ObjectTypeDB::bind_method(_MD("_set_cell_shortened","pos","tile","flip_x","flip_y","transpose"),&TileMapEditor::_set_cell_shortened,DEFVAL(false),DEFVAL(false),DEFVAL(false));
ObjectTypeDB::bind_method(_MD("_set_display_mode","mode"),&TileMapEditor::_set_display_mode);
}
TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i& p_pos)
@ -777,7 +810,7 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) {
//ERR_FAIL_NULL(p_button);
ToolButton *b=p_button->cast_to<ToolButton>();
//ERR_FAIL_COND(!b);
mirror_x->set_block_signals(true);
mirror_y->set_block_signals(true);
transpose->set_block_signals(true);
@ -785,7 +818,7 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) {
rotate_90->set_block_signals(true);
rotate_180->set_block_signals(true);
rotate_270->set_block_signals(true);
if (b == rotate_0) {
mirror_x->set_pressed(false);
mirror_y->set_pressed(false);
@ -806,7 +839,7 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) {
mirror_y->set_pressed(true);
transpose->set_pressed(true);
}
rotate_0->set_pressed(!mirror_x->is_pressed() && !mirror_y->is_pressed() && !transpose->is_pressed());
rotate_90->set_pressed(mirror_x->is_pressed() && !mirror_y->is_pressed() && transpose->is_pressed());
rotate_180->set_pressed(mirror_x->is_pressed() && mirror_y->is_pressed() && !transpose->is_pressed());
@ -833,8 +866,27 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
ec->set_custom_minimum_size(Size2(mw,0));
add_child(ec);
HBoxContainer *hb = memnew( HBoxContainer );
add_child(hb);
hb->set_h_size_flags(SIZE_EXPAND_FILL);
hb->add_spacer(true);
button_thumbnail = memnew( ToolButton );
button_thumbnail->set_toggle_mode(true);
button_thumbnail->set_pressed(true);
button_thumbnail->set_icon(p_editor->get_gui_base()->get_icon("FileThumbnail","EditorIcons"));
hb->add_child(button_thumbnail);
button_thumbnail->connect("pressed", this, "_set_display_mode", varray(DISPLAY_THUMBNAIL));
button_list = memnew( ToolButton );
button_list->set_toggle_mode(true);
button_list->set_pressed(false);
button_list->set_icon(p_editor->get_gui_base()->get_icon("FileList","EditorIcons"));
hb->add_child(button_list);
button_list->connect("pressed", this, "_set_display_mode", varray(DISPLAY_LIST));
// Add tile palette
palette = memnew( Tree );
palette = memnew( ItemList );
palette->set_v_size_flags(SIZE_EXPAND_FILL);
add_child(palette);
@ -886,7 +938,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
rotate_270->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_270));
canvas_item_editor_hb->add_child(rotate_270);
canvas_item_editor_hb->hide();
rotate_0->set_pressed(true);
tool=TOOL_NONE;
selection_active=false;

View file

@ -55,10 +55,18 @@ class TileMapEditor : public VBoxContainer {
TOOL_PICKING
};
enum DisplayMode {
DISPLAY_THUMBNAIL,
DISPLAY_LIST
};
Tool tool;
Control *canvas_item_editor;
Tree *palette;
int display_mode;
ItemList *palette;
ToolButton *button_thumbnail;
ToolButton *button_list;
EditorNode *editor;
Panel *panel;
TileMap *node;
@ -95,6 +103,7 @@ class TileMapEditor : public VBoxContainer {
int get_selected_tile() const;
void set_selected_tile(int p_tile);
void _set_display_mode(int p_mode);
void _update_palette();
void _canvas_draw();
void _menu_option(int p_option);

View file

@ -819,6 +819,7 @@ ProjectManager::ProjectManager() {
if (!EditorSettings::get_singleton())
EditorSettings::create();
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("file_dialog/show_hidden_files"));
set_area_as_parent_rect();
Panel *panel = memnew( Panel );

View file

@ -228,7 +228,7 @@ class DaeExporter:
# imgpath="images/"+image.name+".png"
self.writel(S_IMGS,1,'<image id="'+imgid+'" name="'+image.name+'">')
self.writel(S_IMGS,2,'<init_from>'+imgpath+'</init_from>"/>')
self.writel(S_IMGS,2,'<init_from>'+imgpath+'</init_from>')
self.writel(S_IMGS,1,'</image>')
self.image_cache[image]=imgid
return imgid