Merge pull request #64221 from KoBeWi/shadrag
Add drag and drop support to shader list
This commit is contained in:
commit
547a5a2f10
2 changed files with 123 additions and 0 deletions
|
@ -1257,6 +1257,17 @@ void ShaderEditorPlugin::_update_shader_list_status() {
|
|||
}
|
||||
}
|
||||
|
||||
void ShaderEditorPlugin::_move_shader_tab(int p_from, int p_to) {
|
||||
if (p_from == p_to) {
|
||||
return;
|
||||
}
|
||||
EditedShader es = edited_shaders[p_from];
|
||||
edited_shaders.remove_at(p_from);
|
||||
edited_shaders.insert(p_to, es);
|
||||
shader_tabs->move_child(shader_tabs->get_tab_control(p_from), p_to);
|
||||
_update_shader_list();
|
||||
}
|
||||
|
||||
void ShaderEditorPlugin::edit(Object *p_object) {
|
||||
EditedShader es;
|
||||
|
||||
|
@ -1451,6 +1462,109 @@ void ShaderEditorPlugin::_shader_include_created(Ref<ShaderInclude> p_shader_inc
|
|||
EditorNode::get_singleton()->push_item(p_shader_inc.ptr());
|
||||
}
|
||||
|
||||
Variant ShaderEditorPlugin::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
|
||||
if (shader_list->get_item_count() == 0) {
|
||||
return Variant();
|
||||
}
|
||||
|
||||
int idx = shader_list->get_item_at_position(p_point);
|
||||
if (idx < 0) {
|
||||
return Variant();
|
||||
}
|
||||
|
||||
HBoxContainer *drag_preview = memnew(HBoxContainer);
|
||||
String preview_name = shader_list->get_item_text(idx);
|
||||
Ref<Texture2D> preview_icon = shader_list->get_item_icon(idx);
|
||||
|
||||
if (!preview_icon.is_null()) {
|
||||
TextureRect *tf = memnew(TextureRect);
|
||||
tf->set_texture(preview_icon);
|
||||
tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
|
||||
drag_preview->add_child(tf);
|
||||
}
|
||||
Label *label = memnew(Label(preview_name));
|
||||
drag_preview->add_child(label);
|
||||
main_split->set_drag_preview(drag_preview);
|
||||
|
||||
Dictionary drag_data;
|
||||
drag_data["type"] = "shader_list_element";
|
||||
drag_data["shader_list_element"] = idx;
|
||||
|
||||
return drag_data;
|
||||
}
|
||||
|
||||
bool ShaderEditorPlugin::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
|
||||
Dictionary d = p_data;
|
||||
if (!d.has("type")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (String(d["type"]) == "shader_list_element") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (String(d["type"]) == "files") {
|
||||
Vector<String> files = d["files"];
|
||||
|
||||
if (files.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
String file = files[i];
|
||||
if (ResourceLoader::exists(file, "Shader")) {
|
||||
Ref<Shader> shader = ResourceLoader::load(file);
|
||||
if (shader.is_valid()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ShaderEditorPlugin::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
|
||||
if (!can_drop_data_fw(p_point, p_data, p_from)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Dictionary d = p_data;
|
||||
if (!d.has("type")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (String(d["type"]) == "shader_list_element") {
|
||||
int idx = d["shader_list_element"];
|
||||
int new_idx = shader_list->get_item_at_position(p_point);
|
||||
_move_shader_tab(idx, new_idx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (String(d["type"]) == "files") {
|
||||
Vector<String> files = d["files"];
|
||||
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
String file = files[i];
|
||||
if (!ResourceLoader::exists(file, "Shader")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Ref<Resource> res = ResourceLoader::load(file);
|
||||
if (res.is_valid()) {
|
||||
edit(res.ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderEditorPlugin::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_get_drag_data_fw", "point", "from"), &ShaderEditorPlugin::get_drag_data_fw);
|
||||
ClassDB::bind_method(D_METHOD("_can_drop_data_fw", "point", "data", "from"), &ShaderEditorPlugin::can_drop_data_fw);
|
||||
ClassDB::bind_method(D_METHOD("_drop_data_fw", "point", "data", "from"), &ShaderEditorPlugin::drop_data_fw);
|
||||
}
|
||||
|
||||
ShaderEditorPlugin::ShaderEditorPlugin() {
|
||||
main_split = memnew(HSplitContainer);
|
||||
|
||||
|
@ -1483,6 +1597,7 @@ ShaderEditorPlugin::ShaderEditorPlugin() {
|
|||
vb->add_child(shader_list);
|
||||
shader_list->connect("item_selected", callable_mp(this, &ShaderEditorPlugin::_shader_selected));
|
||||
shader_list->connect("item_clicked", callable_mp(this, &ShaderEditorPlugin::_shader_list_clicked));
|
||||
shader_list->set_drag_forwarding(this);
|
||||
|
||||
main_split->add_child(vb);
|
||||
vb->set_custom_minimum_size(Size2(200, 300) * EDSCALE);
|
||||
|
|
|
@ -250,6 +250,14 @@ class ShaderEditorPlugin : public EditorPlugin {
|
|||
void _shader_created(Ref<Shader> p_shader);
|
||||
void _shader_include_created(Ref<ShaderInclude> p_shader_inc);
|
||||
void _update_shader_list_status();
|
||||
void _move_shader_tab(int p_from, int p_to);
|
||||
|
||||
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
|
||||
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
|
||||
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
virtual void edit(Object *p_object) override;
|
||||
|
|
Loading…
Reference in a new issue