Added selection menu to spatial and canvas editors
This commit is contained in:
parent
d123c89c58
commit
f84dc8e59d
@ -435,6 +435,47 @@ CanvasItem* CanvasItemEditor::_select_canvas_item_at_pos(const Point2& p_pos,Nod
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos,Node* p_node,const Matrix32& p_parent_xform,const Matrix32& p_canvas_xform, Vector<_SelectResult> &r_items) {
|
||||||
|
if (!p_node)
|
||||||
|
return;
|
||||||
|
if (p_node->cast_to<Viewport>())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CanvasItem *c=p_node->cast_to<CanvasItem>();
|
||||||
|
|
||||||
|
for (int i=p_node->get_child_count()-1;i>=0;i--) {
|
||||||
|
|
||||||
|
if (c && !c->is_set_as_toplevel())
|
||||||
|
_find_canvas_items_at_pos(p_pos,p_node->get_child(i),p_parent_xform * c->get_transform(),p_canvas_xform, r_items);
|
||||||
|
else {
|
||||||
|
CanvasLayer *cl = p_node->cast_to<CanvasLayer>();
|
||||||
|
if (cl)
|
||||||
|
return;
|
||||||
|
_find_canvas_items_at_pos(p_pos,p_node->get_child(i),transform ,cl ? cl->get_transform() : p_canvas_xform, r_items); //use base transform
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (c && c->is_visible() && !c->has_meta("_edit_lock_")) {
|
||||||
|
|
||||||
|
Rect2 rect = c->get_item_rect();
|
||||||
|
Point2 local_pos = (p_parent_xform * p_canvas_xform * c->get_transform()).affine_inverse().xform(p_pos);
|
||||||
|
|
||||||
|
|
||||||
|
if (rect.has_point(local_pos)) {
|
||||||
|
Node2D *node=c->cast_to<Node2D>();
|
||||||
|
|
||||||
|
_SelectResult res;
|
||||||
|
res.item=c;
|
||||||
|
res.z=node?node->get_z():0;
|
||||||
|
res.has_z=node;
|
||||||
|
r_items.push_back(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void CanvasItemEditor::_find_canvas_items_at_rect(const Rect2& p_rect,Node* p_node,const Matrix32& p_parent_xform,const Matrix32& p_canvas_xform,List<CanvasItem*> *r_items) {
|
void CanvasItemEditor::_find_canvas_items_at_rect(const Rect2& p_rect,Node* p_node,const Matrix32& p_parent_xform,const Matrix32& p_canvas_xform,List<CanvasItem*> *r_items) {
|
||||||
|
|
||||||
@ -477,6 +518,96 @@ void CanvasItemEditor::_find_canvas_items_at_rect(const Rect2& p_rect,Node* p_no
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CanvasItemEditor::_select(CanvasItem *item, Point2 p_click_pos, bool p_append, bool p_drag) {
|
||||||
|
|
||||||
|
if (p_append) {
|
||||||
|
//additive selection
|
||||||
|
|
||||||
|
if (!item) {
|
||||||
|
|
||||||
|
if (p_drag) {
|
||||||
|
drag_from=transform.affine_inverse().xform(p_click_pos);
|
||||||
|
|
||||||
|
box_selecting=true;
|
||||||
|
box_selecting_to=drag_from;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; //nothing to add
|
||||||
|
}
|
||||||
|
|
||||||
|
if (editor_selection->is_selected(item)) {
|
||||||
|
//already in here, erase it
|
||||||
|
editor_selection->remove_node(item);
|
||||||
|
//_remove_canvas_item(c);
|
||||||
|
|
||||||
|
viewport->update();
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
_append_canvas_item(item);
|
||||||
|
viewport->update();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//regular selection
|
||||||
|
|
||||||
|
if (!item) {
|
||||||
|
//clear because nothing clicked
|
||||||
|
editor_selection->clear();;
|
||||||
|
|
||||||
|
if (p_drag) {
|
||||||
|
drag_from=transform.affine_inverse().xform(p_click_pos);
|
||||||
|
|
||||||
|
box_selecting=true;
|
||||||
|
box_selecting_to=drag_from;
|
||||||
|
}
|
||||||
|
|
||||||
|
viewport->update();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!editor_selection->is_selected(item)) {
|
||||||
|
//select a new one and clear previous selection
|
||||||
|
editor_selection->clear();
|
||||||
|
editor_selection->add_node(item);
|
||||||
|
//reselect
|
||||||
|
if (get_tree()->is_editor_hint()) {
|
||||||
|
editor->call("edit_node",item);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_drag) {
|
||||||
|
//prepare to move!
|
||||||
|
|
||||||
|
List<Node*> &selection = editor_selection->get_selected_node_list();
|
||||||
|
|
||||||
|
for(List<Node*>::Element *E=selection.front();E;E=E->next()) {
|
||||||
|
|
||||||
|
CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>();
|
||||||
|
if (!canvas_item || !canvas_item->is_visible())
|
||||||
|
continue;
|
||||||
|
CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
|
||||||
|
if (!se)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
se->undo_state=canvas_item->edit_get_state();
|
||||||
|
if (canvas_item->cast_to<Node2D>())
|
||||||
|
se->undo_pivot=canvas_item->cast_to<Node2D>()->edit_get_pivot();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
drag=DRAG_ALL;
|
||||||
|
drag_from=transform.affine_inverse().xform(p_click_pos);
|
||||||
|
drag_point_from=_find_topleftmost_point();
|
||||||
|
}
|
||||||
|
|
||||||
|
viewport->update();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CanvasItemEditor::_key_move(const Vector2& p_dir, bool p_snap, KeyMoveMODE p_move_mode) {
|
void CanvasItemEditor::_key_move(const Vector2& p_dir, bool p_snap, KeyMoveMODE p_move_mode) {
|
||||||
|
|
||||||
|
|
||||||
@ -776,6 +907,24 @@ void CanvasItemEditor::_dialog_value_changed(double) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CanvasItemEditor::_selection_result_pressed(int p_result) {
|
||||||
|
|
||||||
|
if (selection_results.size() <= p_result)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CanvasItem *item=selection_results[p_result].item;
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
_select(item, Point2(), additive_selection, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasItemEditor::_selection_menu_hide() {
|
||||||
|
|
||||||
|
selection_results.clear();
|
||||||
|
selection_menu->clear();
|
||||||
|
selection_menu->set_size(Vector2(0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
bool CanvasItemEditor::get_remove_list(List<Node*> *p_list) {
|
bool CanvasItemEditor::get_remove_list(List<Node*> *p_list) {
|
||||||
|
|
||||||
|
|
||||||
@ -838,7 +987,60 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) {
|
|||||||
|
|
||||||
if (b.button_index==BUTTON_RIGHT) {
|
if (b.button_index==BUTTON_RIGHT) {
|
||||||
|
|
||||||
|
if (!b.pressed && tool==TOOL_SELECT && b.mod.alt) {
|
||||||
|
|
||||||
|
Point2 click=Point2(b.x,b.y);
|
||||||
|
|
||||||
|
Node* scene = editor->get_edited_scene();
|
||||||
|
if (!scene)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_find_canvas_items_at_pos(click, scene,transform,Matrix32(), selection_results);
|
||||||
|
|
||||||
|
if (selection_results.size() == 1) {
|
||||||
|
|
||||||
|
CanvasItem *item = selection_results[0].item;
|
||||||
|
selection_results.clear();
|
||||||
|
|
||||||
|
additive_selection=b.mod.shift;
|
||||||
|
if (!_select(item, click, additive_selection, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else if (!selection_results.empty()) {
|
||||||
|
|
||||||
|
selection_results.sort();
|
||||||
|
|
||||||
|
NodePath root_path = get_tree()->get_edited_scene_root()->get_path();
|
||||||
|
StringName root_name = root_path.get_name(root_path.get_name_count()-1);
|
||||||
|
|
||||||
|
for (int i = 0; i < selection_results.size(); i++) {
|
||||||
|
|
||||||
|
CanvasItem *item=selection_results[i].item;
|
||||||
|
|
||||||
|
Ref<Texture> icon;
|
||||||
|
if (item->has_meta("_editor_icon"))
|
||||||
|
icon=item->get_meta("_editor_icon");
|
||||||
|
else
|
||||||
|
icon=get_icon( has_icon(item->get_type(),"EditorIcons")?item->get_type():String("Object"),"EditorIcons");
|
||||||
|
|
||||||
|
String node_path="/"+root_name+"/"+root_path.rel_path_to(item->get_path());
|
||||||
|
|
||||||
|
selection_menu->add_item(item->get_name());
|
||||||
|
selection_menu->set_item_icon(i, icon );
|
||||||
|
selection_menu->set_item_metadata(i, node_path);
|
||||||
|
selection_menu->set_item_tooltip(i,String(item->get_name())+
|
||||||
|
"\nType: "+item->get_type()+"\nPath: "+node_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
additive_selection=b.mod.shift;
|
||||||
|
|
||||||
|
selection_menu->set_global_pos(Vector2( b.global_x, b.global_y ));
|
||||||
|
selection_menu->popup();
|
||||||
|
selection_menu->call_deferred("grab_click_focus");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (get_item_count() > 0 && drag!=DRAG_NONE) {
|
if (get_item_count() > 0 && drag!=DRAG_NONE) {
|
||||||
//cancel drag
|
//cancel drag
|
||||||
@ -1203,82 +1405,10 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) {
|
|||||||
#if 0
|
#if 0
|
||||||
if ( b.pressed ) box_selection_start( click );
|
if ( b.pressed ) box_selection_start( click );
|
||||||
#endif
|
#endif
|
||||||
if (b.mod.shift) { //additive selection
|
|
||||||
|
|
||||||
if (!c) {
|
additive_selection=b.mod.shift;
|
||||||
|
if (!_select(c, click, additive_selection))
|
||||||
drag_from=transform.affine_inverse().xform(click);
|
return;
|
||||||
|
|
||||||
box_selecting=true;
|
|
||||||
box_selecting_to=drag_from;
|
|
||||||
|
|
||||||
return; //nothing to add
|
|
||||||
}
|
|
||||||
|
|
||||||
if (editor_selection->is_selected(c)) {
|
|
||||||
//already in here, erase it
|
|
||||||
editor_selection->remove_node(c);
|
|
||||||
//_remove_canvas_item(c);
|
|
||||||
|
|
||||||
viewport->update();
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
_append_canvas_item(c);
|
|
||||||
viewport->update();
|
|
||||||
} else {
|
|
||||||
//regular selection
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!c) {
|
|
||||||
//clear because nothing clicked
|
|
||||||
editor_selection->clear();;
|
|
||||||
|
|
||||||
drag_from=transform.affine_inverse().xform(click);
|
|
||||||
|
|
||||||
box_selecting=true;
|
|
||||||
box_selecting_to=drag_from;
|
|
||||||
viewport->update();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!editor_selection->is_selected(c)) {
|
|
||||||
//select a new one and clear previous selection
|
|
||||||
editor_selection->clear();
|
|
||||||
editor_selection->add_node(c);
|
|
||||||
//reselect
|
|
||||||
if (get_tree()->is_editor_hint()) {
|
|
||||||
editor->call("edit_node",c);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//prepare to move!
|
|
||||||
|
|
||||||
List<Node*> &selection = editor_selection->get_selected_node_list();
|
|
||||||
|
|
||||||
for(List<Node*>::Element *E=selection.front();E;E=E->next()) {
|
|
||||||
|
|
||||||
CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>();
|
|
||||||
if (!canvas_item || !canvas_item->is_visible())
|
|
||||||
continue;
|
|
||||||
CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
|
|
||||||
if (!se)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
se->undo_state=canvas_item->edit_get_state();
|
|
||||||
if (canvas_item->cast_to<Node2D>())
|
|
||||||
se->undo_pivot=canvas_item->cast_to<Node2D>()->edit_get_pivot();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
drag=DRAG_ALL;
|
|
||||||
drag_from=transform.affine_inverse().xform(click);
|
|
||||||
drag_point_from=_find_topleftmost_point();
|
|
||||||
viewport->update();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2867,6 +2997,8 @@ void CanvasItemEditor::_bind_methods() {
|
|||||||
ObjectTypeDB::bind_method("_viewport_draw",&CanvasItemEditor::_viewport_draw);
|
ObjectTypeDB::bind_method("_viewport_draw",&CanvasItemEditor::_viewport_draw);
|
||||||
ObjectTypeDB::bind_method("_viewport_input_event",&CanvasItemEditor::_viewport_input_event);
|
ObjectTypeDB::bind_method("_viewport_input_event",&CanvasItemEditor::_viewport_input_event);
|
||||||
ObjectTypeDB::bind_method("_snap_changed",&CanvasItemEditor::_snap_changed);
|
ObjectTypeDB::bind_method("_snap_changed",&CanvasItemEditor::_snap_changed);
|
||||||
|
ObjectTypeDB::bind_method(_MD("_selection_result_pressed"),&CanvasItemEditor::_selection_result_pressed);
|
||||||
|
ObjectTypeDB::bind_method(_MD("_selection_menu_hide"),&CanvasItemEditor::_selection_menu_hide);
|
||||||
|
|
||||||
ADD_SIGNAL( MethodInfo("item_lock_status_changed") );
|
ADD_SIGNAL( MethodInfo("item_lock_status_changed") );
|
||||||
ADD_SIGNAL( MethodInfo("item_group_status_changed") );
|
ADD_SIGNAL( MethodInfo("item_group_status_changed") );
|
||||||
@ -3196,6 +3328,12 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
|
|||||||
dialog_val->connect("value_changed",this,"_dialog_value_changed");
|
dialog_val->connect("value_changed",this,"_dialog_value_changed");
|
||||||
select_sb = Ref<StyleBoxTexture>( memnew( StyleBoxTexture) );
|
select_sb = Ref<StyleBoxTexture>( memnew( StyleBoxTexture) );
|
||||||
|
|
||||||
|
selection_menu = memnew( PopupMenu );
|
||||||
|
add_child(selection_menu);
|
||||||
|
selection_menu->set_custom_minimum_size(Vector2(100, 0));
|
||||||
|
selection_menu->connect("item_pressed", this, "_selection_result_pressed");
|
||||||
|
selection_menu->connect("popup_hide", this, "_selection_menu_hide");
|
||||||
|
|
||||||
key_pos=true;
|
key_pos=true;
|
||||||
key_rot=true;
|
key_rot=true;
|
||||||
key_scale=false;
|
key_scale=false;
|
||||||
@ -3218,6 +3356,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
|
|||||||
can_move_pivot=false;
|
can_move_pivot=false;
|
||||||
drag=DRAG_NONE;
|
drag=DRAG_NONE;
|
||||||
bone_last_frame=0;
|
bone_last_frame=0;
|
||||||
|
additive_selection=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CanvasItemEditor *CanvasItemEditor::singleton=NULL;
|
CanvasItemEditor *CanvasItemEditor::singleton=NULL;
|
||||||
|
@ -150,6 +150,7 @@ class CanvasItemEditor : public VBoxContainer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
EditorSelection *editor_selection;
|
EditorSelection *editor_selection;
|
||||||
|
bool additive_selection;
|
||||||
|
|
||||||
Tool tool;
|
Tool tool;
|
||||||
bool first_update;
|
bool first_update;
|
||||||
@ -183,6 +184,18 @@ class CanvasItemEditor : public VBoxContainer {
|
|||||||
|
|
||||||
MenuOption last_option;
|
MenuOption last_option;
|
||||||
|
|
||||||
|
struct _SelectResult {
|
||||||
|
|
||||||
|
CanvasItem* item;
|
||||||
|
float z;
|
||||||
|
bool has_z;
|
||||||
|
_FORCE_INLINE_ bool operator<(const _SelectResult& p_rr) const {
|
||||||
|
return has_z && p_rr.has_z ? p_rr.z < z : p_rr.has_z;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector<_SelectResult> selection_results;
|
||||||
|
|
||||||
struct LockList {
|
struct LockList {
|
||||||
Point2 pos;
|
Point2 pos;
|
||||||
bool lock;
|
bool lock;
|
||||||
@ -249,6 +262,8 @@ class CanvasItemEditor : public VBoxContainer {
|
|||||||
Button *key_scale_button;
|
Button *key_scale_button;
|
||||||
Button *key_insert_button;
|
Button *key_insert_button;
|
||||||
|
|
||||||
|
PopupMenu *selection_menu;
|
||||||
|
|
||||||
//PopupMenu *popup;
|
//PopupMenu *popup;
|
||||||
DragType drag;
|
DragType drag;
|
||||||
Point2 drag_from;
|
Point2 drag_from;
|
||||||
@ -276,8 +291,11 @@ class CanvasItemEditor : public VBoxContainer {
|
|||||||
|
|
||||||
int handle_len;
|
int handle_len;
|
||||||
CanvasItem* _select_canvas_item_at_pos(const Point2 &p_pos,Node* p_node,const Matrix32& p_parent_xform,const Matrix32& p_canvas_xform);
|
CanvasItem* _select_canvas_item_at_pos(const Point2 &p_pos,Node* p_node,const Matrix32& p_parent_xform,const Matrix32& p_canvas_xform);
|
||||||
|
void _find_canvas_items_at_pos(const Point2 &p_pos,Node* p_node,const Matrix32& p_parent_xform,const Matrix32& p_canvas_xform, Vector<_SelectResult> &r_items);
|
||||||
void _find_canvas_items_at_rect(const Rect2& p_rect,Node* p_node,const Matrix32& p_parent_xform,const Matrix32& p_canvas_xform,List<CanvasItem*> *r_items);
|
void _find_canvas_items_at_rect(const Rect2& p_rect,Node* p_node,const Matrix32& p_parent_xform,const Matrix32& p_canvas_xform,List<CanvasItem*> *r_items);
|
||||||
|
|
||||||
|
bool _select(CanvasItem *item, Point2 p_click_pos, bool p_append, bool p_drag=true);
|
||||||
|
|
||||||
ConfirmationDialog *snap_dialog;
|
ConfirmationDialog *snap_dialog;
|
||||||
|
|
||||||
AcceptDialog *value_dialog;
|
AcceptDialog *value_dialog;
|
||||||
@ -304,6 +322,9 @@ class CanvasItemEditor : public VBoxContainer {
|
|||||||
void _append_canvas_item(CanvasItem *p_item);
|
void _append_canvas_item(CanvasItem *p_item);
|
||||||
void _dialog_value_changed(double);
|
void _dialog_value_changed(double);
|
||||||
void _snap_changed();
|
void _snap_changed();
|
||||||
|
void _selection_result_pressed(int);
|
||||||
|
void _selection_menu_hide();
|
||||||
|
|
||||||
UndoRedo *undo_redo;
|
UndoRedo *undo_redo;
|
||||||
|
|
||||||
Point2 _find_topleftmost_point();
|
Point2 _find_topleftmost_point();
|
||||||
|
@ -232,15 +232,6 @@ void SpatialEditorViewport::_select(Spatial *p_node, bool p_append,bool p_single
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct _RayResult {
|
|
||||||
|
|
||||||
Spatial* item;
|
|
||||||
float depth;
|
|
||||||
int handle;
|
|
||||||
_FORCE_INLINE_ bool operator<(const _RayResult& p_rr) const { return depth<p_rr.depth; }
|
|
||||||
};
|
|
||||||
|
|
||||||
ObjectID SpatialEditorViewport::_select_ray(const Point2& p_pos, bool p_append,bool &r_includes_current,int *r_gizmo_handle,bool p_alt_select) {
|
ObjectID SpatialEditorViewport::_select_ray(const Point2& p_pos, bool p_append,bool &r_includes_current,int *r_gizmo_handle,bool p_alt_select) {
|
||||||
|
|
||||||
if (r_gizmo_handle)
|
if (r_gizmo_handle)
|
||||||
@ -379,6 +370,70 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2& p_pos, bool p_append,b
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpatialEditorViewport::_find_items_at_pos(const Point2& p_pos,bool &r_includes_current,Vector<_RayResult> &results,bool p_alt_select) {
|
||||||
|
|
||||||
|
Vector3 ray=_get_ray(p_pos);
|
||||||
|
Vector3 pos=_get_ray_pos(p_pos);
|
||||||
|
|
||||||
|
Vector<RID> instances=VisualServer::get_singleton()->instances_cull_ray(pos,ray,get_tree()->get_root()->get_world()->get_scenario() );
|
||||||
|
Set<Ref<SpatialEditorGizmo> > found_gizmos;
|
||||||
|
|
||||||
|
r_includes_current=false;
|
||||||
|
|
||||||
|
for (int i=0;i<instances.size();i++) {
|
||||||
|
|
||||||
|
uint32_t id=VisualServer::get_singleton()->instance_get_object_instance_ID(instances[i]);
|
||||||
|
Object *obj=ObjectDB::get_instance(id);
|
||||||
|
if (!obj)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Spatial *spat=obj->cast_to<Spatial>();
|
||||||
|
|
||||||
|
if (!spat)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Ref<SpatialEditorGizmo> seg = spat->get_gizmo();
|
||||||
|
|
||||||
|
if (!seg.is_valid())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (found_gizmos.has(seg))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
found_gizmos.insert(seg);
|
||||||
|
Vector3 point;
|
||||||
|
Vector3 normal;
|
||||||
|
|
||||||
|
int handle=-1;
|
||||||
|
bool inters = seg->intersect_ray(camera,p_pos,point,normal,NULL,p_alt_select);
|
||||||
|
|
||||||
|
if (!inters)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
float dist = pos.distance_to(point);
|
||||||
|
|
||||||
|
if (dist<0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (editor_selection->is_selected(spat))
|
||||||
|
r_includes_current=true;
|
||||||
|
|
||||||
|
_RayResult res;
|
||||||
|
res.item=spat;
|
||||||
|
res.depth=dist;
|
||||||
|
res.handle=handle;
|
||||||
|
results.push_back(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (results.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
results.sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Vector3 SpatialEditorViewport::_get_screen_to_space(const Vector3& p_pos) {
|
Vector3 SpatialEditorViewport::_get_screen_to_space(const Vector3& p_pos) {
|
||||||
|
|
||||||
@ -724,6 +779,7 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
|
|||||||
} break;
|
} break;
|
||||||
case BUTTON_RIGHT: {
|
case BUTTON_RIGHT: {
|
||||||
|
|
||||||
|
NavigationScheme nav_scheme = _get_navigation_schema("3d_editor/navigation_scheme");
|
||||||
|
|
||||||
if (b.pressed && _edit.gizmo.is_valid()) {
|
if (b.pressed && _edit.gizmo.is_valid()) {
|
||||||
//restore
|
//restore
|
||||||
@ -832,6 +888,57 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
|
|||||||
//VisualServer::get_singleton()->poly_clear(indicators);
|
//VisualServer::get_singleton()->poly_clear(indicators);
|
||||||
set_message("Transform Aborted.",3);
|
set_message("Transform Aborted.",3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!b.pressed && (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT && b.mod.alt)) {
|
||||||
|
|
||||||
|
if (nav_scheme == NAVIGATION_MAYA)
|
||||||
|
break;
|
||||||
|
|
||||||
|
_find_items_at_pos(Vector2( b.x, b.y ),clicked_includes_current,selection_results,b.mod.shift);
|
||||||
|
|
||||||
|
clicked_wants_append=b.mod.shift;
|
||||||
|
|
||||||
|
if (selection_results.size() == 1) {
|
||||||
|
|
||||||
|
clicked=selection_results[0].item->get_instance_ID();
|
||||||
|
selection_results.clear();
|
||||||
|
|
||||||
|
if (clicked) {
|
||||||
|
_select_clicked(clicked_wants_append,true);
|
||||||
|
clicked=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (!selection_results.empty()) {
|
||||||
|
|
||||||
|
NodePath root_path = get_tree()->get_edited_scene_root()->get_path();
|
||||||
|
StringName root_name = root_path.get_name(root_path.get_name_count()-1);
|
||||||
|
|
||||||
|
for (int i = 0; i < selection_results.size(); i++) {
|
||||||
|
|
||||||
|
Spatial *spat=selection_results[i].item;
|
||||||
|
|
||||||
|
Ref<Texture> icon;
|
||||||
|
if (spat->has_meta("_editor_icon"))
|
||||||
|
icon=spat->get_meta("_editor_icon");
|
||||||
|
else
|
||||||
|
icon=get_icon( has_icon(spat->get_type(),"EditorIcons")?spat->get_type():String("Object"),"EditorIcons");
|
||||||
|
|
||||||
|
String node_path="/"+root_name+"/"+root_path.rel_path_to(spat->get_path());
|
||||||
|
|
||||||
|
selection_menu->add_item(spat->get_name());
|
||||||
|
selection_menu->set_item_icon(i, icon );
|
||||||
|
selection_menu->set_item_metadata(i, node_path);
|
||||||
|
selection_menu->set_item_tooltip(i,String(spat->get_name())+
|
||||||
|
"\nType: "+spat->get_type()+"\nPath: "+node_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
selection_menu->set_global_pos(Vector2( b.global_x, b.global_y ));
|
||||||
|
selection_menu->popup();
|
||||||
|
selection_menu->call_deferred("grab_click_focus");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case BUTTON_MIDDLE: {
|
case BUTTON_MIDDLE: {
|
||||||
|
|
||||||
@ -2096,6 +2203,26 @@ void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpatialEditorViewport::_selection_result_pressed(int p_result) {
|
||||||
|
|
||||||
|
if (selection_results.size() <= p_result)
|
||||||
|
return;
|
||||||
|
|
||||||
|
clicked=selection_results[p_result].item->get_instance_ID();
|
||||||
|
|
||||||
|
if (clicked) {
|
||||||
|
_select_clicked(clicked_wants_append,true);
|
||||||
|
clicked=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpatialEditorViewport::_selection_menu_hide() {
|
||||||
|
|
||||||
|
selection_results.clear();
|
||||||
|
selection_menu->clear();
|
||||||
|
selection_menu->set_size(Vector2(0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
void SpatialEditorViewport::set_can_preview(Camera* p_preview) {
|
void SpatialEditorViewport::set_can_preview(Camera* p_preview) {
|
||||||
|
|
||||||
preview=p_preview;
|
preview=p_preview;
|
||||||
@ -2210,6 +2337,8 @@ void SpatialEditorViewport::_bind_methods(){
|
|||||||
ObjectTypeDB::bind_method(_MD("_toggle_camera_preview"),&SpatialEditorViewport::_toggle_camera_preview);
|
ObjectTypeDB::bind_method(_MD("_toggle_camera_preview"),&SpatialEditorViewport::_toggle_camera_preview);
|
||||||
ObjectTypeDB::bind_method(_MD("_preview_exited_scene"),&SpatialEditorViewport::_preview_exited_scene);
|
ObjectTypeDB::bind_method(_MD("_preview_exited_scene"),&SpatialEditorViewport::_preview_exited_scene);
|
||||||
ObjectTypeDB::bind_method(_MD("update_transform_gizmo_view"),&SpatialEditorViewport::update_transform_gizmo_view);
|
ObjectTypeDB::bind_method(_MD("update_transform_gizmo_view"),&SpatialEditorViewport::update_transform_gizmo_view);
|
||||||
|
ObjectTypeDB::bind_method(_MD("_selection_result_pressed"),&SpatialEditorViewport::_selection_result_pressed);
|
||||||
|
ObjectTypeDB::bind_method(_MD("_selection_menu_hide"),&SpatialEditorViewport::_selection_menu_hide);
|
||||||
|
|
||||||
ADD_SIGNAL( MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport")) );
|
ADD_SIGNAL( MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport")) );
|
||||||
}
|
}
|
||||||
@ -2307,6 +2436,12 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
|
|||||||
preview=NULL;
|
preview=NULL;
|
||||||
gizmo_scale=1.0;
|
gizmo_scale=1.0;
|
||||||
|
|
||||||
|
selection_menu = memnew( PopupMenu );
|
||||||
|
add_child(selection_menu);
|
||||||
|
selection_menu->set_custom_minimum_size(Vector2(100, 0));
|
||||||
|
selection_menu->connect("item_pressed", this, "_selection_result_pressed");
|
||||||
|
selection_menu->connect("popup_hide", this, "_selection_menu_hide");
|
||||||
|
|
||||||
if (p_index==0) {
|
if (p_index==0) {
|
||||||
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER),true);
|
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER),true);
|
||||||
viewport->set_as_audio_listener(true);
|
viewport->set_as_audio_listener(true);
|
||||||
|
@ -111,12 +111,21 @@ private:
|
|||||||
bool orthogonal;
|
bool orthogonal;
|
||||||
float gizmo_scale;
|
float gizmo_scale;
|
||||||
|
|
||||||
|
struct _RayResult {
|
||||||
|
|
||||||
|
Spatial* item;
|
||||||
|
float depth;
|
||||||
|
int handle;
|
||||||
|
_FORCE_INLINE_ bool operator<(const _RayResult& p_rr) const { return depth<p_rr.depth; }
|
||||||
|
};
|
||||||
|
|
||||||
void _update_name();
|
void _update_name();
|
||||||
void _compute_edit(const Point2& p_point);
|
void _compute_edit(const Point2& p_point);
|
||||||
void _clear_selected();
|
void _clear_selected();
|
||||||
void _select_clicked(bool p_append,bool p_single);
|
void _select_clicked(bool p_append,bool p_single);
|
||||||
void _select(Spatial *p_node, bool p_append,bool p_single);
|
void _select(Spatial *p_node, bool p_append,bool p_single);
|
||||||
ObjectID _select_ray(const Point2& p_pos, bool p_append,bool &r_includes_current,int *r_gizmo_handle=NULL,bool p_alt_select=false);
|
ObjectID _select_ray(const Point2& p_pos, bool p_append,bool &r_includes_current,int *r_gizmo_handle=NULL,bool p_alt_select=false);
|
||||||
|
void _find_items_at_pos(const Point2& p_pos,bool &r_includes_current,Vector<_RayResult> &results,bool p_alt_select=false);
|
||||||
Vector3 _get_ray_pos(const Vector2& p_pos) const;
|
Vector3 _get_ray_pos(const Vector2& p_pos) const;
|
||||||
Vector3 _get_ray(const Vector2& p_pos);
|
Vector3 _get_ray(const Vector2& p_pos);
|
||||||
Point2 _point_to_screen(const Vector3& p_point);
|
Point2 _point_to_screen(const Vector3& p_point);
|
||||||
@ -136,9 +145,12 @@ private:
|
|||||||
float get_fov() const;
|
float get_fov() const;
|
||||||
|
|
||||||
ObjectID clicked;
|
ObjectID clicked;
|
||||||
|
Vector<_RayResult> selection_results;
|
||||||
bool clicked_includes_current;
|
bool clicked_includes_current;
|
||||||
bool clicked_wants_append;
|
bool clicked_wants_append;
|
||||||
|
|
||||||
|
PopupMenu *selection_menu;
|
||||||
|
|
||||||
enum NavigationScheme {
|
enum NavigationScheme {
|
||||||
NAVIGATION_GODOT,
|
NAVIGATION_GODOT,
|
||||||
NAVIGATION_MAYA,
|
NAVIGATION_MAYA,
|
||||||
@ -225,6 +237,8 @@ private:
|
|||||||
void _toggle_camera_preview(bool);
|
void _toggle_camera_preview(bool);
|
||||||
void _init_gizmo_instance(int p_idx);
|
void _init_gizmo_instance(int p_idx);
|
||||||
void _finish_gizmo_instances();
|
void _finish_gizmo_instances();
|
||||||
|
void _selection_result_pressed(int);
|
||||||
|
void _selection_menu_hide();
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Loading…
Reference in New Issue
Block a user