void VisualShaderEditor::_update_graph() { if (updating) return; if (visual_shader.is_null()) return; graph->set_scroll_ofs(visual_shader->get_graph_offset() * EDSCALE); VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); graph->clear_connections(); //erase all nodes for (int i = 0; i < graph->get_child_count(); i++) { if (Object::cast_to<GraphNode>(graph->get_child(i))) { memdelete(graph->get_child(i)); i--; } } static const Color type_color[3] = { Color::html("#61daf4"), Color::html("#d67dee"), Color::html("#f6a86e") }; List<VisualShader::Connection> connections; visual_shader->get_node_connections(type, &connections); Ref<StyleBoxEmpty> label_style = make_empty_stylebox(2, 1, 2, 1); Vector<int> nodes = visual_shader->get_node_list(type); for (int n_i = 0; n_i < nodes.size(); n_i++) { Vector2 position = visual_shader->get_node_position(type, nodes[n_i]); Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, nodes[n_i]); GraphNode *node = memnew(GraphNode); graph->add_child(node); /*if (!vsnode->is_connected("changed", this, "_node_changed")) { vsnode->connect("changed", this, "_node_changed", varray(vsnode->get_instance_id()), CONNECT_DEFERRED); }*/ node->set_offset(position); node->set_title(vsnode->get_caption()); node->set_name(itos(nodes[n_i])); if (nodes[n_i] >= 2) { node->set_show_close_button(true); node->connect("close_request", this, "_delete_request", varray(nodes[n_i]), CONNECT_DEFERRED); } node->connect("dragged", this, "_node_dragged", varray(nodes[n_i])); Control *custom_editor = NULL; int port_offset = 0; Ref<VisualShaderNodeUniform> uniform = vsnode; if (uniform.is_valid()) { LineEdit *uniform_name = memnew(LineEdit); uniform_name->set_text(uniform->get_uniform_name()); node->add_child(uniform_name); uniform_name->connect("text_entered", this, "_line_edit_changed", varray(uniform_name, nodes[n_i])); uniform_name->connect("focus_exited", this, "_line_edit_focus_out", varray(uniform_name, nodes[n_i])); if (vsnode->get_input_port_count() == 0 && vsnode->get_output_port_count() == 1 && vsnode->get_output_port_name(0) == "") { //shortcut VisualShaderNode::PortType port_right = vsnode->get_output_port_type(0); node->set_slot(0, false, VisualShaderNode::PORT_TYPE_SCALAR, Color(), true, port_right, type_color[port_right]); continue; } port_offset++; } for (int i = 0; i < plugins.size(); i++) { custom_editor = plugins.write[i]->create_editor(vsnode); if (custom_editor) { break; } } if (custom_editor && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == "")) { //will be embedded in first port } else if (custom_editor) { port_offset++; node->add_child(custom_editor); custom_editor = NULL; } for (int i = 0; i < MAX(vsnode->get_input_port_count(), vsnode->get_output_port_count()); i++) { if (vsnode->is_port_separator(i)) { node->add_child(memnew(HSeparator)); port_offset++; } bool valid_left = i < vsnode->get_input_port_count(); VisualShaderNode::PortType port_left = VisualShaderNode::PORT_TYPE_SCALAR; bool port_left_used = false; String name_left; if (valid_left) { name_left = vsnode->get_input_port_name(i); port_left = vsnode->get_input_port_type(i); for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { if (E->get().to_node == nodes[n_i] && E->get().to_port == i) { port_left_used = true; } } } bool valid_right = i < vsnode->get_output_port_count(); VisualShaderNode::PortType port_right = VisualShaderNode::PORT_TYPE_SCALAR; String name_right; if (valid_right) { name_right = vsnode->get_output_port_name(i); port_right = vsnode->get_output_port_type(i); } HBoxContainer *hb = memnew(HBoxContainer); Variant default_value; if (valid_left && !port_left_used) { default_value = vsnode->get_input_port_default_value(i); } if (default_value.get_type() != Variant::NIL) { // only a label Button *button = memnew(Button); hb->add_child(button); button->connect("pressed", this, "_edit_port_default_input", varray(button, nodes[n_i], i)); switch (default_value.get_type()) { case Variant::COLOR: { button->set_custom_minimum_size(Size2(30, 0) * EDSCALE); button->connect("draw", this, "_draw_color_over_button", varray(button, default_value)); } break; case Variant::INT: case Variant::REAL: { button->set_text(String::num(default_value, 4)); } break; case Variant::VECTOR3: { Vector3 v = default_value; button->set_text(String::num(v.x, 3) + "," + String::num(v.y, 3) + "," + String::num(v.z, 3)); } break; default: {} } } if (i == 0 && custom_editor) { hb->add_child(custom_editor); custom_editor->set_h_size_flags(SIZE_EXPAND_FILL); } else { if (valid_left) { Label *label = memnew(Label); label->set_text(name_left); label->add_style_override("normal", label_style); //more compact hb->add_child(label); } hb->add_spacer(); if (valid_right) { Label *label = memnew(Label); label->set_text(name_right); label->set_align(Label::ALIGN_RIGHT); label->add_style_override("normal", label_style); //more compact hb->add_child(label); } } if (valid_right && edit_type->get_selected() == VisualShader::TYPE_FRAGMENT) { TextureButton *preview = memnew(TextureButton); preview->set_toggle_mode(true); preview->set_normal_texture(get_icon("GuiVisibilityHidden", "EditorIcons")); preview->set_pressed_texture(get_icon("GuiVisibilityVisible", "EditorIcons")); preview->set_v_size_flags(SIZE_SHRINK_CENTER); if (vsnode->get_output_port_for_preview() == i) { preview->set_pressed(true); } preview->connect("pressed", this, "_preview_select_port", varray(nodes[n_i], i), CONNECT_DEFERRED); hb->add_child(preview); } node->add_child(hb); node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], valid_right, port_right, type_color[port_right]); if (EditorSettings::get_singleton()->get("interface/theme/use_graph_node_headers")) { Ref<StyleBoxFlat> sb = node->get_stylebox("frame", "GraphNode"); Color c = sb->get_border_color(MARGIN_TOP); Color mono_color = ((c.r + c.g + c.b) / 3) < 0.7 ? Color(1.0, 1.0, 1.0) : Color(0.0, 0.0, 0.0); mono_color.a = 0.85; c = mono_color; node->add_color_override("title_color", c); c.a = 0.7; node->add_color_override("close_color", c); } } if (vsnode->get_output_port_for_preview() >= 0) { VisualShaderNodePortPreview *port_preview = memnew(VisualShaderNodePortPreview); port_preview->setup(visual_shader, type, nodes[n_i], vsnode->get_output_port_for_preview()); port_preview->set_h_size_flags(SIZE_SHRINK_CENTER); node->add_child(port_preview); } String error = vsnode->get_warning(visual_shader->get_mode(), type); if (error != String()) { Label *error_label = memnew(Label); error_label->add_color_override("font_color", get_color("error_color", "Editor")); error_label->set_text(error); node->add_child(error_label); } } for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { int from = E->get().from_node; int from_idx = E->get().from_port; int to = E->get().to_node; int to_idx = E->get().to_port; graph->connect_node(itos(from), from_idx, itos(to), to_idx); } }
void ProjectManager::_load_recent_projects() { while(scroll_childs->get_child_count()>0) { memdelete( scroll_childs->get_child(0)); } List<PropertyInfo> properties; EditorSettings::get_singleton()->get_property_list(&properties); Color font_color = get_color("font_color","Tree"); List<ProjectItem> projects; List<ProjectItem> favorite_projects; for(List<PropertyInfo>::Element *E=properties.front();E;E=E->next()) { String _name = E->get().name; if (!_name.begins_with("projects/") && !_name.begins_with("favorite_projects/")) continue; bool favorite = (_name.begins_with("favorite_projects/"))?true:false; String project = _name.get_slice("/",1); String path = EditorSettings::get_singleton()->get(_name); String conf=path.plus_file("engine.cfg"); uint64_t last_modified = 0; if (FileAccess::exists(conf)) last_modified = FileAccess::get_modified_time(conf); String fscache = path.plus_file(".fscache"); if (FileAccess::exists(fscache)) { uint64_t cache_modified = FileAccess::get_modified_time(fscache); if ( cache_modified > last_modified ) last_modified = cache_modified; } ProjectItem item(project, path, conf, last_modified, favorite); if (favorite) favorite_projects.push_back(item); else projects.push_back(item); } projects.sort(); favorite_projects.sort(); for(List<ProjectItem>::Element *E=projects.front();E;) { List<ProjectItem>::Element *next = E->next(); if (favorite_projects.find(E->get()) != NULL) projects.erase(E->get()); E=next; } for(List<ProjectItem>::Element *E=favorite_projects.back();E;E=E->prev()) { projects.push_front(E->get()); } Ref<Texture> favorite_icon = get_icon("Favorites","EditorIcons"); for(List<ProjectItem>::Element *E=projects.front();E;E=E->next()) { ProjectItem &item = E->get(); String project = item.project; String path = item.path; String conf = item.conf; bool is_favorite = item.favorite; Ref<ConfigFile> cf = memnew( ConfigFile ); Error err = cf->load(conf); ERR_CONTINUE(err!=OK); Ref<Texture> icon; String project_name="Unnamed Project"; if (cf->has_section_key("application","icon")) { String appicon = cf->get_value("application","icon"); if (appicon!="") { Image img; Error err = img.load(appicon.replace_first("res://",path+"/")); if (err==OK) { img.resize(64,64); Ref<ImageTexture> it = memnew( ImageTexture ); it->create_from_image(img); icon=it; } } } if (cf->has_section_key("application","name")) { project_name = cf->get_value("application","name"); } if (icon.is_null()) { icon=get_icon("DefaultProjectIcon","EditorIcons"); } String main_scene; if (cf->has_section_key("application","main_scene")) { main_scene = cf->get_value("application","main_scene"); } HBoxContainer *hb = memnew( HBoxContainer ); hb->set_meta("name",project); hb->set_meta("main_scene",main_scene); hb->set_meta("favorite",is_favorite); hb->connect("draw",this,"_panel_draw",varray(hb)); hb->connect("input_event",this,"_panel_input",varray(hb)); VBoxContainer *favorite_box = memnew( VBoxContainer ); TextureButton *favorite = memnew( TextureButton ); favorite->set_normal_texture(favorite_icon); if (!is_favorite) favorite->set_opacity(0.2); favorite->set_v_size_flags(SIZE_EXPAND); favorite->connect("pressed",this,"_favorite_pressed",varray(hb)); favorite_box->add_child(favorite); hb->add_child(favorite_box); TextureFrame *tf = memnew( TextureFrame ); tf->set_texture(icon); hb->add_child(tf); VBoxContainer *vb = memnew(VBoxContainer); hb->add_child(vb); EmptyControl *ec = memnew( EmptyControl ); ec->set_minsize(Size2(0,1)); vb->add_child(ec); Label *title = memnew( Label(project_name) ); title->add_font_override("font",get_font("large","Fonts")); title->add_color_override("font_color",font_color); vb->add_child(title); Label *fpath = memnew( Label(path) ); vb->add_child(fpath); fpath->set_opacity(0.5); fpath->add_color_override("font_color",font_color); scroll_childs->add_child(hb); } erase_btn->set_disabled(selected_list.size()<1); open_btn->set_disabled(selected_list.size()<1); run_btn->set_disabled(selected_list.size()<1 || (selected_list.size()==1 && single_selected_main=="")); }
bool BaseFeatureLayer::Initialize() { RETURN_FALSE_IF_FALSE(ILayer::Initialize()); TextureButton* returnButton = NodeFactory::Instance().CreateTextureButton("Close.png", "CloseSelected.png"); returnButton->OnTap += Bind(&BaseFeatureLayer::OnReturn,this); returnButton->SetDock(DockPoint::LeftTop); returnButton->SetAnchor(0.f, 1.f); AddChild(returnButton); TextureButton* refreshButton = NodeFactory::Instance().CreateTextureButton("Refresh.png", "RefreshSelected.png"); refreshButton->OnTap += Bind(&BaseFeatureLayer::OnRefresh, this); refreshButton->SetDock(DockPoint::MiddleBottom); refreshButton->SetAnchor(0.5f, 0.f); AddChild(refreshButton); float xPadding = refreshButton->Size().Width*0.5f + 100.f; TextureButton* leftButton = NodeFactory::Instance().CreateTextureButton("Left.png", "LeftSelected.png"); leftButton->OnTap += Bind(&BaseFeatureLayer::OnLeft, this); leftButton->SetDock(DockPoint::MiddleBottom); leftButton->SetAnchor(0.5f, 0.f); leftButton->SetRelativePosition(Point2F(-xPadding, 0.f)); AddChild(leftButton); TextureButton* rightButton = NodeFactory::Instance().CreateTextureButton("Left.png", "LeftSelected.png"); rightButton->OnTap += Bind(&BaseFeatureLayer::OnRight, this); rightButton->SetDock(DockPoint::MiddleBottom); rightButton->SetAnchor(0.5f, 0.f); rightButton->SetRelativePosition(Point2F(xPadding, 0.f)); rightButton->SetFlipX(true); AddChild(rightButton); return true; }
void ProjectManager::_load_recent_projects() { ProjectListFilter::FilterOption filter_option = project_filter->get_filter_option(); String search_term = project_filter->get_search_term(); while(scroll_childs->get_child_count()>0) { memdelete( scroll_childs->get_child(0)); } Map<String, String> selected_list_copy = selected_list; List<PropertyInfo> properties; EditorSettings::get_singleton()->get_property_list(&properties); Color font_color = gui_base->get_color("font_color","Tree"); List<ProjectItem> projects; List<ProjectItem> favorite_projects; for(List<PropertyInfo>::Element *E=properties.front();E;E=E->next()) { String _name = E->get().name; if (!_name.begins_with("projects/") && !_name.begins_with("favorite_projects/")) continue; String path = EditorSettings::get_singleton()->get(_name); if (filter_option == ProjectListFilter::FILTER_PATH && search_term!="" && path.findn(search_term)==-1) continue; String project = _name.get_slice("/",1); String conf=path.plus_file("engine.cfg"); bool favorite = (_name.begins_with("favorite_projects/"))?true:false; uint64_t last_modified = 0; if (FileAccess::exists(conf)) { last_modified = FileAccess::get_modified_time(conf); String fscache = path.plus_file(".fscache"); if (FileAccess::exists(fscache)) { uint64_t cache_modified = FileAccess::get_modified_time(fscache); if ( cache_modified > last_modified ) last_modified = cache_modified; } ProjectItem item(project, path, conf, last_modified, favorite); if (favorite) favorite_projects.push_back(item); else projects.push_back(item); } else { //project doesn't exist on disk but it's in the XML settings file EditorSettings::get_singleton()->erase(_name); //remove it } } projects.sort(); favorite_projects.sort(); for(List<ProjectItem>::Element *E=projects.front();E;) { List<ProjectItem>::Element *next = E->next(); if (favorite_projects.find(E->get()) != NULL) projects.erase(E->get()); E=next; } for(List<ProjectItem>::Element *E=favorite_projects.back();E;E=E->prev()) { projects.push_front(E->get()); } Ref<Texture> favorite_icon = get_icon("Favorites","EditorIcons"); for(List<ProjectItem>::Element *E=projects.front();E;E=E->next()) { ProjectItem &item = E->get(); String project = item.project; String path = item.path; String conf = item.conf; bool is_favorite = item.favorite; Ref<ConfigFile> cf = memnew( ConfigFile ); Error err = cf->load(conf); ERR_CONTINUE(err!=OK); String project_name=TTR("Unnamed Project"); if (cf->has_section_key("application","name")) { project_name = static_cast<String>(cf->get_value("application","name")).xml_unescape(); } if (filter_option==ProjectListFilter::FILTER_NAME && search_term!="" && project_name.findn(search_term)==-1) continue; Ref<Texture> icon; if (cf->has_section_key("application","icon")) { String appicon = cf->get_value("application","icon"); if (appicon!="") { Image img; Error err = img.load(appicon.replace_first("res://",path+"/")); if (err==OK) { img.resize(64,64); Ref<ImageTexture> it = memnew( ImageTexture ); it->create_from_image(img); icon=it; } } } if (icon.is_null()) { icon=get_icon("DefaultProjectIcon","EditorIcons"); } String main_scene; if (cf->has_section_key("application","main_scene")) { main_scene = cf->get_value("application","main_scene"); } selected_list_copy.erase(project); HBoxContainer *hb = memnew( HBoxContainer ); hb->set_meta("name",project); hb->set_meta("main_scene",main_scene); hb->set_meta("favorite",is_favorite); hb->connect("draw",this,"_panel_draw",varray(hb)); hb->connect("input_event",this,"_panel_input",varray(hb)); hb->add_constant_override("separation",10*EDSCALE); VBoxContainer *favorite_box = memnew( VBoxContainer ); TextureButton *favorite = memnew( TextureButton ); favorite->set_normal_texture(favorite_icon); if (!is_favorite) favorite->set_opacity(0.2); favorite->set_v_size_flags(SIZE_EXPAND); favorite->connect("pressed",this,"_favorite_pressed",varray(hb)); favorite_box->add_child(favorite); hb->add_child(favorite_box); TextureFrame *tf = memnew( TextureFrame ); tf->set_texture(icon); hb->add_child(tf); VBoxContainer *vb = memnew(VBoxContainer); hb->add_child(vb); Control *ec = memnew( Control ); ec->set_custom_minimum_size(Size2(0,1)); vb->add_child(ec); Label *title = memnew( Label(project_name) ); title->add_font_override("font", gui_base->get_font("large","Fonts")); title->add_color_override("font_color",font_color); vb->add_child(title); Label *fpath = memnew( Label(path) ); vb->add_child(fpath); fpath->set_opacity(0.5); fpath->add_color_override("font_color",font_color); scroll_childs->add_child(hb); } for (Map<String,String>::Element *E = selected_list_copy.front();E;E = E->next()) { String key = E->key(); selected_list.erase(key); } scroll->set_v_scroll(0); _update_project_buttons(); EditorSettings::get_singleton()->save(); tabs->set_current_tab(0); }
TextureButton* NodeFactory::CreateTextureButton(const FileIdRef& normalTextureName, const FileIdRef& selectedTextureName/*=FileId::Empty*/, const FileIdRef& disabledTextureName/*=FileId::Empty*/, const FileIdRef& disabledSelectedTextureName/*=FileId::Empty*/) { TextureButton* button = new TextureButton(StringRef::Empty, normalTextureName, selectedTextureName, disabledTextureName, disabledSelectedTextureName); button->Initialize(); return button; }