Browse Source

Merge pull request #4296 from Paulb23/code_editor_themes

Added color themes to the text editor
Rémi Verschelde 9 years ago
parent
commit
b777b32470

+ 167 - 19
tools/editor/editor_settings.cpp

@@ -221,6 +221,12 @@ void EditorSettings::create() {
 			dir->change_dir("..");
 		}
 
+		if (dir->change_dir("text_editor_themes")!=OK) {
+			dir->make_dir("text_editor_themes");
+		} else {
+			dir->change_dir("..");
+		}
+
 		if (dir->change_dir("tmp")!=OK) {
 			dir->make_dir("tmp");
 		} else {
@@ -280,6 +286,7 @@ void EditorSettings::create() {
 
 		singleton->setup_network();
 		singleton->load_favorites();
+		singleton->list_text_editor_themes();
 
 		return;
 
@@ -304,7 +311,7 @@ void EditorSettings::create() {
 	singleton->settings_path=config_path+"/"+config_dir;
 	singleton->_load_defaults(extra_config);
 	singleton->setup_network();
-
+	singleton->list_text_editor_themes();
 
 }
 
@@ -391,24 +398,11 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
 	set("global/default_project_export_path","");
 	hints["global/default_project_export_path"]=PropertyInfo(Variant::STRING,"global/default_project_export_path",PROPERTY_HINT_GLOBAL_DIR);
 	set("global/show_script_in_scene_tabs",false);
-	set("text_editor/background_color",Color::html("3b000000"));
-	set("text_editor/caret_color",Color::html("aaaaaa"));
-	set("text_editor/line_number_color",Color::html("66aaaaaa"));
-	set("text_editor/text_color",Color::html("aaaaaa"));
-	set("text_editor/text_selected_color",Color::html("000000"));
-	set("text_editor/keyword_color",Color::html("ffffb3"));
-	set("text_editor/base_type_color",Color::html("a4ffd4"));
-	set("text_editor/engine_type_color",Color::html("83d3ff"));
-	set("text_editor/function_color",Color::html("66a2ce"));
-	set("text_editor/member_variable_color",Color::html("e64e59"));
-	set("text_editor/comment_color",Color::html("676767"));
-	set("text_editor/string_color",Color::html("ef6ebe"));
-	set("text_editor/number_color",Color::html("EB9532"));
-	set("text_editor/symbol_color",Color::html("badfff"));
-	set("text_editor/selection_color",Color::html("7b5dbe"));
-	set("text_editor/brace_mismatch_color",Color(1,0.2,0.2));
-	set("text_editor/current_line_color",Color(0.3,0.5,0.8,0.15));
-	set("text_editor/word_highlighted_color",Color(0.8,0.9,0.9,0.15));
+
+	set("text_editor/color_theme","Default");
+	hints["text_editor/color_theme"]=PropertyInfo(Variant::STRING,"text_editor/color_theme",PROPERTY_HINT_ENUM,"Default");
+
+	_load_default_text_editor_theme();
 
 	set("text_editor/syntax_highlighting", true);
 
@@ -542,6 +536,27 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
 
 
 
+}
+
+void EditorSettings::_load_default_text_editor_theme() {
+	set("text_editor/background_color",Color::html("3b000000"));
+	set("text_editor/caret_color",Color::html("aaaaaa"));
+	set("text_editor/line_number_color",Color::html("66aaaaaa"));
+	set("text_editor/text_color",Color::html("aaaaaa"));
+	set("text_editor/text_selected_color",Color::html("000000"));
+	set("text_editor/keyword_color",Color::html("ffffb3"));
+	set("text_editor/base_type_color",Color::html("a4ffd4"));
+	set("text_editor/engine_type_color",Color::html("83d3ff"));
+	set("text_editor/function_color",Color::html("66a2ce"));
+	set("text_editor/member_variable_color",Color::html("e64e59"));
+	set("text_editor/comment_color",Color::html("676767"));
+	set("text_editor/string_color",Color::html("ef6ebe"));
+	set("text_editor/number_color",Color::html("EB9532"));
+	set("text_editor/symbol_color",Color::html("badfff"));
+	set("text_editor/selection_color",Color::html("7b5dbe"));
+	set("text_editor/brace_mismatch_color",Color(1,0.2,0.2));
+	set("text_editor/current_line_color",Color(0.3,0.5,0.8,0.15));
+	set("text_editor/word_highlighted_color",Color(0.8,0.9,0.9,0.15));
 }
 
 void EditorSettings::notify_changes() {
@@ -644,6 +659,139 @@ void EditorSettings::load_favorites() {
 
 }
 
+void EditorSettings::list_text_editor_themes() {
+	String themes="Default";
+	DirAccess *d = DirAccess::open(settings_path + "/text_editor_themes");
+	if (d) {
+		d->list_dir_begin();
+		String file = d->get_next();
+		while(file != String()) {
+			if (file.extension() == "tet" && file.basename().to_lower() != "default") {
+				themes += "," + file.basename();
+			}
+			file = d->get_next();
+		}
+		d->list_dir_end();
+		memdelete(d);
+	}
+	add_property_hint(PropertyInfo(Variant::STRING,"text_editor/color_theme",PROPERTY_HINT_ENUM,themes));
+}
+
+void EditorSettings::load_text_editor_theme() {
+	if (get("text_editor/color_theme") == "Default") {
+		_load_default_text_editor_theme();	// sorry for "Settings changed" console spam
+		return;
+	}
+
+	String theme_path = get_settings_path() + "/text_editor_themes/" + get("text_editor/color_theme") + ".tet";
+
+	Ref<ConfigFile> cf = memnew( ConfigFile );
+	Error err = cf->load(theme_path);
+
+	if (err != OK) {
+		return;
+	}
+
+	List<String> keys;
+	cf->get_section_keys("color_theme", &keys);
+
+	for(List<String>::Element *E=keys.front();E;E=E->next()) {
+		String key = E->get();
+		String val = cf->get_value("color_theme", key);
+
+		// don't load if it's not already there!
+		if (has("text_editor/" + key)) {
+
+			// make sure it is actually a color
+			if (val.is_valid_html_color() && key.find("color") >= 0) {
+				props["text_editor/"+key].variant = Color::html(val);	// change manually to prevent "Settings changed" console spam
+			}
+		}
+	}
+	emit_signal("settings_changed");
+	// if it doesn't load just use what is currently loaded
+}
+
+bool EditorSettings::import_text_editor_theme(String p_file) {
+
+	if (!p_file.ends_with(".tet")) {
+		return false;
+	} else {
+		if (p_file.get_file().to_lower() == "default.tet") {
+			return false;
+		}
+
+		DirAccess *d = DirAccess::open(settings_path + "/text_editor_themes");
+		if (d) {
+			d->copy(p_file, settings_path + "/text_editor_themes/" + p_file.get_file());
+			memdelete(d);
+			return true;
+		}
+	}
+	return false;
+}
+
+bool EditorSettings::save_text_editor_theme() {
+
+	String p_file = get("text_editor/color_theme");
+
+	if (p_file.get_file().to_lower() == "default") {
+		return false;
+	}
+	String theme_path = get_settings_path() + "/text_editor_themes/" + p_file + ".tet";
+	return _save_text_editor_theme(theme_path);
+}
+
+bool EditorSettings::save_text_editor_theme_as(String p_file) {
+	if (!p_file.ends_with(".tet")) {
+		p_file += ".tet";
+	}
+
+	if (p_file.get_file().to_lower() == "default.tet") {
+		return false;
+	}
+	if(_save_text_editor_theme(p_file)) {
+
+		// switch to theme is saved in the theme directory
+		list_text_editor_themes();
+		String theme_name = p_file.substr(0, p_file.length() - 4).get_file();
+
+		if (p_file.get_base_dir() == get_settings_path() + "/text_editor_themes") {
+			set("text_editor/color_theme", theme_name);
+			load_text_editor_theme();
+		}
+		return true;
+	}
+	return false;
+}
+
+bool EditorSettings::_save_text_editor_theme(String p_file) {
+	String theme_section = "color_theme";
+	Ref<ConfigFile> cf = memnew( ConfigFile );	// hex is better?
+	cf->set_value(theme_section, "background_color", ((Color)get("text_editor/background_color")).to_html());
+	cf->set_value(theme_section, "caret_color", ((Color)get("text_editor/caret_color")).to_html());
+	cf->set_value(theme_section, "text_color", ((Color)get("text_editor/text_color")).to_html());
+	cf->set_value(theme_section, "text_selected_color", ((Color)get("text_editor/text_selected_color")).to_html());
+	cf->set_value(theme_section, "keyword_color", ((Color)get("text_editor/keyword_color")).to_html());
+	cf->set_value(theme_section, "base_type_color", ((Color)get("text_editor/base_type_color")).to_html());
+	cf->set_value(theme_section, "engine_type_color", ((Color)get("text_editor/engine_type_color")).to_html());
+	cf->set_value(theme_section, "function_color", ((Color)get("text_editor/function_color")).to_html());
+	cf->set_value(theme_section, "member_variable_color", ((Color)get("text_editor/member_variable_color")).to_html());
+	cf->set_value(theme_section, "comment_color", ((Color)get("text_editor/comment_color")).to_html());
+	cf->set_value(theme_section, "string_color", ((Color)get("text_editor/string_color")).to_html());
+	cf->set_value(theme_section, "number_color", ((Color)get("text_editor/number_color")).to_html());
+	cf->set_value(theme_section, "symbol_color", ((Color)get("text_editor/symbol_color")).to_html());
+	cf->set_value(theme_section, "selection_color", ((Color)get("text_editor/selection_color")).to_html());
+	cf->set_value(theme_section, "brace_mismatch_color", ((Color)get("text_editor/brace_mismatch_color")).to_html());
+	cf->set_value(theme_section, "current_line_color", ((Color)get("text_editor/current_line_color")).to_html());
+	cf->set_value(theme_section, "word_highlighted_color", ((Color)get("text_editor/word_highlighted_color")).to_html());
+	Error err = cf->save(p_file);
+
+	if (err == OK) {
+		return true;
+	}
+	return false;
+}
 
 void EditorSettings::_bind_methods() {
 

+ 9 - 0
tools/editor/editor_settings.h

@@ -84,6 +84,9 @@ private:
 
 
 	void _load_defaults(Ref<ConfigFile> p_extra_config = NULL);
+	void _load_default_text_editor_theme();
+
+	bool _save_text_editor_theme(String p_file);
 
 	String project_config_path;
 
@@ -130,6 +133,12 @@ public:
 
 	void load_favorites();
 
+	void list_text_editor_themes();
+	void load_text_editor_theme();
+	bool import_text_editor_theme(String p_file);
+	bool save_text_editor_theme();
+	bool save_text_editor_theme_as(String p_file);
+
 	EditorSettings();
 	~EditorSettings();
 

+ 64 - 0
tools/editor/plugins/script_editor_plugin.cpp

@@ -951,6 +951,23 @@ void ScriptEditor::swap_lines(TextEdit *tx, int line1, int line2)
     tx->cursor_set_line(line2);
 }
 
+void ScriptEditor::_file_dialog_action(String p_file) {
+
+	switch (file_dialog_option) {
+		case FILE_SAVE_THEME_AS: {
+			if(!EditorSettings::get_singleton()->save_text_editor_theme_as(p_file)) {
+				editor->show_warning(TTR("Error while saving theme"), TTR("Error saving"));
+			}
+		} break;
+		case FILE_IMPORT_THEME: {
+			if(!EditorSettings::get_singleton()->import_text_editor_theme(p_file)) {
+				editor->show_warning(TTR("Error importing theme"), TTR("Error importing"));
+			}
+		} break;
+	}
+	file_dialog_option = -1;
+}
+
 void ScriptEditor::_menu_option(int p_option) {
 
 
@@ -990,6 +1007,33 @@ void ScriptEditor::_menu_option(int p_option) {
 
 #endif
 		} break;
+		case FILE_IMPORT_THEME: {
+			file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE);
+			file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+			file_dialog_option = FILE_IMPORT_THEME;
+			file_dialog->clear_filters();
+			file_dialog->add_filter("*.tet");
+			file_dialog->popup_centered_ratio();
+			file_dialog->set_title(TTR("Import Theme"));
+		} break;
+		case FILE_RELOAD_THEME: {
+			EditorSettings::get_singleton()->load_text_editor_theme();
+		} break;
+		case FILE_SAVE_THEME: {
+			if(!EditorSettings::get_singleton()->save_text_editor_theme()) {
+				editor->show_warning(TTR("Error while saving theme"), TTR("Error saving"));
+			}
+		} break;
+		case FILE_SAVE_THEME_AS: {
+			file_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
+			file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+			file_dialog_option = FILE_SAVE_THEME_AS;
+			file_dialog->clear_filters();
+			file_dialog->add_filter("*.tet");
+			file_dialog->set_current_path(EditorSettings::get_singleton()->get_settings_path() + "/text_editor_themes/" + EditorSettings::get_singleton()->get("text_editor/color_theme"));
+			file_dialog->popup_centered_ratio();
+			file_dialog->set_title(TTR("Save Theme As.."));
+		} break;
 		case SEARCH_HELP: {
 
 			help_search_dialog->popup();
@@ -2122,6 +2166,13 @@ void ScriptEditor::_editor_settings_changed() {
 		autosave_timer->stop();
 	}
 
+	if (current_theme == "") {
+		current_theme = EditorSettings::get_singleton()->get("text_editor/color_theme");
+	} else if (current_theme != EditorSettings::get_singleton()->get("text_editor/color_theme")) {
+		current_theme = EditorSettings::get_singleton()->get("text_editor/color_theme");
+		EditorSettings::get_singleton()->load_text_editor_theme();
+	}
+
 	for(int i=0;i<tab_container->get_child_count();i++) {
 
 		ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>();
@@ -2364,6 +2415,7 @@ void ScriptEditor::set_scene_root_script( Ref<Script> p_script ) {
 
 void ScriptEditor::_bind_methods() {
 
+	ObjectTypeDB::bind_method("_file_dialog_action",&ScriptEditor::_file_dialog_action);
 	ObjectTypeDB::bind_method("_tab_changed",&ScriptEditor::_tab_changed);
 	ObjectTypeDB::bind_method("_menu_option",&ScriptEditor::_menu_option);
 	ObjectTypeDB::bind_method("_close_current_tab",&ScriptEditor::_close_current_tab);
@@ -2395,6 +2447,8 @@ void ScriptEditor::_bind_methods() {
 
 ScriptEditor::ScriptEditor(EditorNode *p_editor) {
 
+	current_theme = "";
+
 	completion_cache = memnew( EditorScriptCodeCompletionCache );
 	restoring_layout=false;
 	waiting_update_names=false;
@@ -2433,6 +2487,11 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
 	file_menu->get_popup()->add_item(TTR("History Prev"),WINDOW_PREV,KEY_MASK_CTRL|KEY_MASK_ALT|KEY_LEFT);
 	file_menu->get_popup()->add_item(TTR("History Next"),WINDOW_NEXT,KEY_MASK_CTRL|KEY_MASK_ALT|KEY_RIGHT);
 	file_menu->get_popup()->add_separator();
+	file_menu->get_popup()->add_item(TTR("Import Theme"), FILE_IMPORT_THEME);
+	file_menu->get_popup()->add_item(TTR("Reload Theme"), FILE_RELOAD_THEME);
+	file_menu->get_popup()->add_item(TTR("Save Theme"), FILE_SAVE_THEME);
+	file_menu->get_popup()->add_item(TTR("Save Theme As"), FILE_SAVE_THEME_AS);
+	file_menu->get_popup()->add_separator();
 	file_menu->get_popup()->add_item(TTR("Close"),FILE_CLOSE,KEY_MASK_CMD|KEY_W);
 	file_menu->get_popup()->connect("item_pressed", this,"_menu_option");
 
@@ -2586,6 +2645,11 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
 	add_child(script_create_dialog);
 	script_create_dialog->connect("script_created", this, "_script_created");
 
+	file_dialog_option = -1;
+	file_dialog = memnew( EditorFileDialog );
+	add_child(file_dialog);
+	file_dialog->connect("file_selected", this,"_file_dialog_action");
+
 	goto_line_dialog = memnew(GotoLineDialog);
 	add_child(goto_line_dialog);
 

+ 9 - 0
tools/editor/plugins/script_editor_plugin.h

@@ -122,6 +122,10 @@ class ScriptEditor : public VBoxContainer {
 		FILE_SAVE,
 		FILE_SAVE_AS,
 		FILE_SAVE_ALL,
+		FILE_IMPORT_THEME,
+		FILE_RELOAD_THEME,
+		FILE_SAVE_THEME,
+		FILE_SAVE_THEME_AS,
 		FILE_CLOSE,
 		EDIT_UNDO,
 		EDIT_REDO,
@@ -179,6 +183,7 @@ class ScriptEditor : public VBoxContainer {
 	ItemList *script_list;
 	HSplitContainer *script_split;
 	TabContainer *tab_container;
+	EditorFileDialog *file_dialog;
 	FindReplaceDialog *find_replace_dialog;
 	GotoLineDialog *goto_line_dialog;
 	ConfirmationDialog *erase_tab_confirm;
@@ -186,6 +191,8 @@ class ScriptEditor : public VBoxContainer {
 	ScriptEditorDebugger* debugger;
 	ToolButton *scripts_visible;
 
+	String current_theme;
+
 	TextureFrame *script_icon;
 	Label *script_name_label;
 
@@ -277,6 +284,8 @@ class ScriptEditor : public VBoxContainer {
 	void _update_script_colors();
 	void _update_modified_scripts_for_external_editor();
 
+	int file_dialog_option;
+	void _file_dialog_action(String p_file);
 
 	static ScriptEditor *script_editor;
 protected:

+ 3 - 0
tools/editor/settings_config_dialog.cpp

@@ -45,6 +45,7 @@ void EditorSettingsDialog::_settings_changed() {
 
 
 	timer->start();
+	property_editor->get_property_editor()->update_tree(); // else color's won't update when theme is selected.
 }
 
 void EditorSettingsDialog::_settings_save() {
@@ -70,6 +71,8 @@ void EditorSettingsDialog::popup_edit_settings() {
 	if (!EditorSettings::get_singleton())
 		return;
 
+	EditorSettings::get_singleton()->list_text_editor_themes(); // make sure we have an up to date list of themes
+
 	property_editor->edit(EditorSettings::get_singleton());
 	property_editor->get_property_editor()->update_tree();