Universalize draw-over API for EditorPlugins

- Now it is usable from both `CanvasItem` and `Spatial` editors.
- `EditorPlugin` API changes:
 - `forward_draw_over_canvas()` becomes `forward_draw_over_viewport()`.
 - `update_canvas()` becomes `update_overlays()`, which now triggers the update of every overlay on top of any 2D or 3D viewports present. Also now it returns the number of such viewports, which is useful whenever you need to know the number of draw-over calls you'll get.
 - New: `[set/is]_force_draw_over_forwarding_enabled()` to force overlaying regardless it handles the current object type, in a similar fashion as `[set/is]_input_event_forwarding_always_enabled`. This kind of overlay is also on top of those for regular handled node types.
 - New: `forward_force_draw_over_canvas()`, which is the callback that gets called for plugins that enable forced overlaying.
This commit is contained in:
Pedro J. Estébanez 2017-10-29 20:32:09 +01:00
parent 2e5dfbdb4b
commit 3f31925b18
17 changed files with 105 additions and 40 deletions

View file

@ -5624,6 +5624,7 @@ EditorNode::EditorNode() {
editor_plugin_screen = NULL;
editor_plugins_over = memnew(EditorPluginList);
editor_plugins_force_over = memnew(EditorPluginList);
editor_plugins_force_input_forwarding = memnew(EditorPluginList);
_edit_current();
@ -5748,6 +5749,7 @@ EditorNode::~EditorNode() {
memdelete(EditorHelp::get_doc_data());
memdelete(editor_selection);
memdelete(editor_plugins_over);
memdelete(editor_plugins_force_over);
memdelete(editor_plugins_force_input_forwarding);
memdelete(file_server);
memdelete(progress_hb);
@ -5801,10 +5803,17 @@ bool EditorPluginList::forward_spatial_gui_input(Camera *p_camera, const Ref<Inp
return discard;
}
void EditorPluginList::forward_draw_over_canvas(Control *p_canvas) {
void EditorPluginList::forward_draw_over_viewport(Control *p_overlay) {
for (int i = 0; i < plugins_list.size(); i++) {
plugins_list[i]->forward_draw_over_canvas(p_canvas);
plugins_list[i]->forward_draw_over_viewport(p_overlay);
}
}
void EditorPluginList::forward_force_draw_over_viewport(Control *p_overlay) {
for (int i = 0; i < plugins_list.size(); i++) {
plugins_list[i]->forward_force_draw_over_viewport(p_overlay);
}
}

View file

@ -378,6 +378,7 @@ private:
Vector<EditorPlugin *> editor_plugins;
EditorPlugin *editor_plugin_screen;
EditorPluginList *editor_plugins_over;
EditorPluginList *editor_plugins_force_over;
EditorPluginList *editor_plugins_force_input_forwarding;
EditorHistory editor_history;
@ -636,6 +637,7 @@ public:
EditorPlugin *get_editor_plugin_screen() { return editor_plugin_screen; }
EditorPluginList *get_editor_plugins_over() { return editor_plugins_over; }
EditorPluginList *get_editor_plugins_force_over() { return editor_plugins_force_over; }
EditorPluginList *get_editor_plugins_force_input_forwarding() { return editor_plugins_force_input_forwarding; }
PropertyEditor *get_property_editor() { return property_editor; }
VBoxContainer *get_property_editor_vb() { return prop_editor_vb; }
@ -820,7 +822,8 @@ public:
void edit(Object *p_object);
bool forward_gui_input(const Ref<InputEvent> &p_event);
bool forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled);
void forward_draw_over_canvas(Control *p_canvas);
void forward_draw_over_viewport(Control *p_overlay);
void forward_force_draw_over_viewport(Control *p_overlay);
void add_plugin(EditorPlugin *p_plugin);
void clear();
bool empty();

View file

@ -375,6 +375,12 @@ void EditorPlugin::set_input_event_forwarding_always_enabled() {
always_input_forwarding_list->add_plugin(this);
}
void EditorPlugin::set_force_draw_over_forwarding_enabled() {
force_draw_over_forwarding_enabled = true;
EditorPluginList *always_draw_over_forwarding_list = EditorNode::get_singleton()->get_editor_plugins_force_over();
always_draw_over_forwarding_list->add_plugin(this);
}
void EditorPlugin::notify_scene_changed(const Node *scn_root) {
if (scn_root == NULL) return;
emit_signal("scene_changed", scn_root);
@ -410,15 +416,38 @@ bool EditorPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
return false;
}
void EditorPlugin::forward_draw_over_canvas(Control *p_canvas) {
void EditorPlugin::forward_draw_over_viewport(Control *p_overlay) {
if (get_script_instance() && get_script_instance()->has_method("forward_draw_over_canvas")) {
get_script_instance()->call("forward_draw_over_canvas", p_canvas);
if (get_script_instance() && get_script_instance()->has_method("forward_draw_over_viewport")) {
get_script_instance()->call("forward_draw_over_viewport", p_overlay);
}
}
void EditorPlugin::update_canvas() {
CanvasItemEditor::get_singleton()->get_viewport_control()->update();
void EditorPlugin::forward_force_draw_over_viewport(Control *p_overlay) {
if (get_script_instance() && get_script_instance()->has_method("forward_force_draw_over_viewport")) {
get_script_instance()->call("forward_force_draw_over_viewport", p_overlay);
}
}
// Updates the overlays of the 2D viewport or, if in 3D mode, of every 3D viewport.
int EditorPlugin::update_overlays() const {
if (SpatialEditor::get_singleton()->is_visible()) {
int count = 0;
for (int i = 0; i < SpatialEditor::VIEWPORTS_COUNT; i++) {
SpatialEditorViewport *vp = SpatialEditor::get_singleton()->get_editor_viewport(i);
if (vp->is_visible()) {
vp->update_surface();
count++;
}
}
return count;
} else {
// This will update the normal viewport itself as well
CanvasItemEditor::get_singleton()->get_viewport_control()->update();
return 1;
}
}
bool EditorPlugin::forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event) {
@ -590,7 +619,7 @@ void EditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_custom_type", "type", "base", "script", "icon"), &EditorPlugin::add_custom_type);
ClassDB::bind_method(D_METHOD("remove_custom_type", "type"), &EditorPlugin::remove_custom_type);
ClassDB::bind_method(D_METHOD("update_canvas"), &EditorPlugin::update_canvas);
ClassDB::bind_method(D_METHOD("update_overlays"), &EditorPlugin::update_overlays);
ClassDB::bind_method(D_METHOD("make_bottom_panel_item_visible", "item"), &EditorPlugin::make_bottom_panel_item_visible);
ClassDB::bind_method(D_METHOD("hide_bottom_panel"), &EditorPlugin::hide_bottom_panel);
@ -602,11 +631,13 @@ void EditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_export_plugin", "exporter"), &EditorPlugin::add_export_plugin);
ClassDB::bind_method(D_METHOD("remove_export_plugin", "exporter"), &EditorPlugin::remove_export_plugin);
ClassDB::bind_method(D_METHOD("set_input_event_forwarding_always_enabled"), &EditorPlugin::set_input_event_forwarding_always_enabled);
ClassDB::bind_method(D_METHOD("set_force_draw_over_forwarding_enabled"), &EditorPlugin::set_force_draw_over_forwarding_enabled);
ClassDB::bind_method(D_METHOD("get_editor_interface"), &EditorPlugin::get_editor_interface);
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "forward_canvas_gui_input", PropertyInfo(Variant::TRANSFORM2D, "canvas_xform"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_draw_over_canvas", PropertyInfo(Variant::TRANSFORM2D, "canvas_xform"), PropertyInfo(Variant::OBJECT, "canvas", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_force_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "forward_spatial_gui_input", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
MethodInfo gizmo = MethodInfo(Variant::OBJECT, "create_spatial_gizmo", PropertyInfo(Variant::OBJECT, "for_spatial", PROPERTY_HINT_RESOURCE_TYPE, "Spatial"));
gizmo.return_val.hint = PROPERTY_HINT_RESOURCE_TYPE;
@ -653,6 +684,7 @@ void EditorPlugin::_bind_methods() {
EditorPlugin::EditorPlugin() {
undo_redo = NULL;
input_event_forwarding_always_enabled = false;
force_draw_over_forwarding_enabled = false;
last_main_screen_name = "";
}

View file

@ -102,6 +102,7 @@ class EditorPlugin : public Node {
UndoRedo *_get_undo_redo() { return undo_redo; }
bool input_event_forwarding_always_enabled;
bool force_draw_over_forwarding_enabled;
String last_main_screen_name;
@ -151,13 +152,17 @@ public:
void set_input_event_forwarding_always_enabled();
bool is_input_event_forwarding_always_enabled() { return input_event_forwarding_always_enabled; }
void set_force_draw_over_forwarding_enabled();
bool is_force_draw_over_forwarding_enabled() { return force_draw_over_forwarding_enabled; }
void notify_main_screen_changed(const String &screen_name);
void notify_scene_changed(const Node *scn_root);
void notify_scene_closed(const String &scene_filepath);
virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial *p_spatial);
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event);
virtual void forward_draw_over_canvas(Control *p_canvas);
virtual void forward_draw_over_viewport(Control *p_overlay);
virtual void forward_force_draw_over_viewport(Control *p_overlay);
virtual bool forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event);
virtual String get_name() const;
virtual bool has_main_screen() const;
@ -178,7 +183,7 @@ public:
EditorInterface *get_editor_interface();
void update_canvas();
int update_overlays() const;
void queue_save_layout() const;

View file

@ -490,7 +490,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
return false;
}
void AbstractPolygon2DEditor::forward_draw_over_canvas(Control *p_canvas) {
void AbstractPolygon2DEditor::forward_draw_over_viewport(Control *p_overlay) {
if (!_get_node())
return;

View file

@ -136,7 +136,7 @@ protected:
public:
bool forward_gui_input(const Ref<InputEvent> &p_event);
void forward_draw_over_canvas(Control *p_canvas);
void forward_draw_over_viewport(Control *p_overlay);
void edit(Node *p_polygon);
AbstractPolygon2DEditor(EditorNode *p_editor, bool p_wip_destructive = true);
@ -152,7 +152,7 @@ class AbstractPolygon2DEditorPlugin : public EditorPlugin {
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return polygon_editor->forward_gui_input(p_event); }
virtual void forward_draw_over_canvas(Control *p_canvas) { polygon_editor->forward_draw_over_canvas(p_canvas); }
virtual void forward_draw_over_viewport(Control *p_overlay) { polygon_editor->forward_draw_over_viewport(p_overlay); }
bool has_main_screen() const { return false; }
virtual String get_name() const { return klass; }

View file

@ -2955,8 +2955,13 @@ void CanvasItemEditor::_draw_viewport() {
EditorPluginList *over_plugin_list = editor->get_editor_plugins_over();
if (!over_plugin_list->empty()) {
over_plugin_list->forward_draw_over_canvas(viewport);
over_plugin_list->forward_draw_over_viewport(viewport);
}
EditorPluginList *force_over_plugin_list = editor->get_editor_plugins_force_over();
if (!force_over_plugin_list->empty()) {
force_over_plugin_list->forward_force_draw_over_viewport(viewport);
}
_draw_bones();
}

View file

@ -414,7 +414,7 @@ void CollisionShape2DEditor::_get_current_shape_type() {
canvas_item_editor->get_viewport_control()->update();
}
void CollisionShape2DEditor::forward_draw_over_canvas(Control *p_canvas) {
void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
if (!node) {
return;
@ -448,8 +448,8 @@ void CollisionShape2DEditor::forward_draw_over_canvas(Control *p_canvas) {
handles[0] = Point2(radius, -height);
handles[1] = Point2(0, -(height + radius));
p_canvas->draw_texture(h, gt.xform(handles[0]) - size);
p_canvas->draw_texture(h, gt.xform(handles[1]) - size);
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
} break;
@ -459,7 +459,7 @@ void CollisionShape2DEditor::forward_draw_over_canvas(Control *p_canvas) {
handles.resize(1);
handles[0] = Point2(shape->get_radius(), 0);
p_canvas->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
} break;
@ -478,8 +478,8 @@ void CollisionShape2DEditor::forward_draw_over_canvas(Control *p_canvas) {
handles[0] = shape->get_normal() * shape->get_d();
handles[1] = shape->get_normal() * (shape->get_d() + 30.0);
p_canvas->draw_texture(h, gt.xform(handles[0]) - size);
p_canvas->draw_texture(h, gt.xform(handles[1]) - size);
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
} break;
@ -489,7 +489,7 @@ void CollisionShape2DEditor::forward_draw_over_canvas(Control *p_canvas) {
handles.resize(1);
handles[0] = Point2(0, shape->get_length());
p_canvas->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
} break;
@ -501,8 +501,8 @@ void CollisionShape2DEditor::forward_draw_over_canvas(Control *p_canvas) {
handles[0] = Point2(ext.x, 0);
handles[1] = Point2(0, -ext.y);
p_canvas->draw_texture(h, gt.xform(handles[0]) - size);
p_canvas->draw_texture(h, gt.xform(handles[1]) - size);
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
} break;
@ -513,8 +513,8 @@ void CollisionShape2DEditor::forward_draw_over_canvas(Control *p_canvas) {
handles[0] = shape->get_a();
handles[1] = shape->get_b();
p_canvas->draw_texture(h, gt.xform(handles[0]) - size);
p_canvas->draw_texture(h, gt.xform(handles[1]) - size);
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
} break;
}

View file

@ -74,7 +74,7 @@ protected:
public:
bool forward_canvas_gui_input(const Ref<InputEvent> &p_event);
void forward_draw_over_canvas(Control *p_canvas);
void forward_draw_over_viewport(Control *p_overlay);
void edit(Node *p_node);
CollisionShape2DEditor(EditorNode *p_editor);
@ -88,7 +88,7 @@ class CollisionShape2DEditorPlugin : public EditorPlugin {
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return collision_shape_2d_editor->forward_canvas_gui_input(p_event); }
virtual void forward_draw_over_canvas(Control *p_canvas) { return collision_shape_2d_editor->forward_draw_over_canvas(p_canvas); }
virtual void forward_draw_over_viewport(Control *p_overlay) { return collision_shape_2d_editor->forward_draw_over_viewport(p_overlay); }
virtual String get_name() const { return "CollisionShape2D"; }
bool has_main_screen() const { return false; }

View file

@ -318,7 +318,7 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return false;
}
void LightOccluder2DEditor::forward_draw_over_canvas(Control *p_canvas) {
void LightOccluder2DEditor::forward_draw_over_viewport(Control *p_overlay) {
if (!node || !node->get_occluder_polygon().is_valid())
return;

View file

@ -82,7 +82,7 @@ protected:
public:
Vector2 snap_point(const Vector2 &p_point) const;
void forward_draw_over_canvas(Control *p_canvas);
void forward_draw_over_viewport(Control *p_overlay);
bool forward_gui_input(const Ref<InputEvent> &p_event);
void edit(Node *p_collision_polygon);
LightOccluder2DEditor(EditorNode *p_editor);
@ -97,7 +97,7 @@ class LightOccluder2DEditorPlugin : public EditorPlugin {
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return light_occluder_editor->forward_gui_input(p_event); }
virtual void forward_draw_over_canvas(Control *p_canvas) { return light_occluder_editor->forward_draw_over_canvas(p_canvas); }
virtual void forward_draw_over_viewport(Control *p_overlay) { return light_occluder_editor->forward_draw_over_viewport(p_overlay); }
virtual String get_name() const { return "LightOccluder2D"; }
bool has_main_screen() const { return false; }

View file

@ -269,7 +269,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return false;
}
void Path2DEditor::forward_draw_over_canvas(Control *p_canvas) {
void Path2DEditor::forward_draw_over_viewport(Control *p_overlay) {
if (!node)
return;

View file

@ -94,7 +94,7 @@ protected:
public:
bool forward_gui_input(const Ref<InputEvent> &p_event);
void forward_draw_over_canvas(Control *p_canvas);
void forward_draw_over_viewport(Control *p_overlay);
void edit(Node *p_path2d);
Path2DEditor(EditorNode *p_editor);
};
@ -108,7 +108,7 @@ class Path2DEditorPlugin : public EditorPlugin {
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return path2d_editor->forward_gui_input(p_event); }
virtual void forward_draw_over_canvas(Control *p_canvas) { return path2d_editor->forward_draw_over_canvas(p_canvas); }
virtual void forward_draw_over_viewport(Control *p_overlay) { return path2d_editor->forward_draw_over_viewport(p_overlay); }
virtual String get_name() const { return "Path2D"; }
bool has_main_screen() const { return false; }

View file

@ -2332,6 +2332,16 @@ static void draw_indicator_bar(Control &surface, real_t fill, Ref<Texture> icon)
void SpatialEditorViewport::_draw() {
EditorPluginList *over_plugin_list = EditorNode::get_singleton()->get_editor_plugins_over();
if (!over_plugin_list->empty()) {
over_plugin_list->forward_draw_over_viewport(surface);
}
EditorPluginList *force_over_plugin_list = editor->get_editor_plugins_force_over();
if (!force_over_plugin_list->empty()) {
force_over_plugin_list->forward_force_draw_over_viewport(surface);
}
if (surface->has_focus()) {
Size2 size = surface->get_size();
Rect2 r = Rect2(Point2(), size);

View file

@ -311,6 +311,7 @@ protected:
static void _bind_methods();
public:
void update_surface() { surface->update(); }
void update_transform_gizmo_view();
void set_can_preview(Camera *p_preview);
@ -389,6 +390,8 @@ class SpatialEditor : public VBoxContainer {
GDCLASS(SpatialEditor, VBoxContainer);
public:
static const unsigned int VIEWPORTS_COUNT = 4;
enum ToolMode {
TOOL_MODE_SELECT,
@ -403,8 +406,6 @@ public:
};
private:
static const unsigned int VIEWPORTS_COUNT = 4;
EditorNode *editor;
EditorSelection *editor_selection;

View file

@ -1183,7 +1183,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return false;
}
void TileMapEditor::forward_draw_over_canvas(Control *p_canvas) {
void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
if (!node)
return;

View file

@ -184,7 +184,7 @@ public:
HBoxContainer *get_toolbar() const { return toolbar; }
bool forward_gui_input(const Ref<InputEvent> &p_event);
void forward_draw_over_canvas(Control *p_canvas);
void forward_draw_over_viewport(Control *p_overlay);
void edit(Node *p_tile_map);
@ -200,7 +200,7 @@ class TileMapEditorPlugin : public EditorPlugin {
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return tile_map_editor->forward_gui_input(p_event); }
virtual void forward_draw_over_canvas(Control *p_canvas) { tile_map_editor->forward_draw_over_canvas(p_canvas); }
virtual void forward_draw_over_viewport(Control *p_overlay) { tile_map_editor->forward_draw_over_viewport(p_overlay); }
virtual String get_name() const { return "TileMap"; }
bool has_main_screen() const { return false; }