Merge branch 'master' of github.com:okamstudio/godot into development
This commit is contained in:
commit
d23ee8eb01
24 changed files with 1021 additions and 114 deletions
10
.editorconfig
Normal file
10
.editorconfig
Normal 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
2
.gitignore
vendored
|
@ -281,3 +281,5 @@ cscope.out
|
|||
cscope.in.out
|
||||
cscope.po.out
|
||||
godot.creator.*
|
||||
|
||||
projects/
|
|
@ -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']
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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::
|
|
@ -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
|
||||
|
|
|
@ -8783,7 +8783,7 @@
|
|||
</description>
|
||||
</method>
|
||||
<method name="get_undo_redo" >
|
||||
<return type="Object">
|
||||
<return type="UndoRedo">
|
||||
</return>
|
||||
<description>
|
||||
</description>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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>();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) );
|
||||
|
|
533
tools/editor/plugins/collision_shape_2d_editor_plugin.cpp
Normal file
533
tools/editor/plugins/collision_shape_2d_editor_plugin.cpp
Normal 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() {
|
||||
|
||||
}
|
73
tools/editor/plugins/collision_shape_2d_editor_plugin.h
Normal file
73
tools/editor/plugins/collision_shape_2d_editor_plugin.h
Normal 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
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue