1 module creator.core.path; 2 import std.path; 3 import std.process; 4 import std.file : getcwd, mkdirRecurse, exists; 5 6 private { 7 string cachedConfigDir; 8 string cachedImguiFileDir; 9 string cachedFontDir; 10 string cachedLocaleDir; 11 } 12 13 /** 14 The name of the folder inochi creator config gets thrown in to. 15 */ 16 enum APP_FOLDER_NAME = ".inochi-creator"; 17 18 /** 19 Name of environment variable to force a configuration path 20 */ 21 enum ENV_CONFIG_PATH = "INOCHI_CONFIG_PATH"; 22 23 /** 24 Returns the app configuration directory for the platform 25 */ 26 string incGetAppConfigPath() { 27 if (cachedConfigDir) return cachedConfigDir; 28 string appDataDir; 29 30 // Once this function has completed cache the result. 31 scope(success) { 32 cachedConfigDir = appDataDir; 33 34 // Also make sure the folder exists 35 if (!exists(cachedConfigDir)) { 36 mkdirRecurse(cachedConfigDir); 37 } 38 } 39 40 // On Windows %AppData% is used. 41 // Example: C:/Users/USERNAME/AppData/Roaming/.inochi-creatorS 42 version(Windows) { 43 appDataDir = environment.get("AppData"); 44 } 45 46 // On Linux the app data dir is in $XDG_CONFIG_DIR, $HOME/.config or $HOME 47 // Example: /home/USERNAME/.inochi-creator 48 else version(linux) { 49 appDataDir = environment.get("XDG_CONFIG_HOME"); 50 if (!appDataDir) appDataDir = buildPath(environment.get("HOME"), ".config"); 51 } 52 53 // On macOS things are thrown in to $HOME/Library/Application Support 54 // Example: /home/USERNAME/Library/Application Support/.inochi-creator 55 else version(OSX) { 56 appDataDir = environment.get("HOME"); 57 if (appDataDir) appDataDir = buildPath(appDataDir, "Library", "Application Support"); 58 } 59 60 // On other POSIX platforms just assume $HOME exists. 61 // Example: /home/USERNAME/.inochi-creator 62 else version(posix) { 63 appDataDir = environment.get("HOME"); 64 } 65 66 // Allow packagers, etc. to specify a forced config directory. 67 string inForcedConfigDir = environment.get(ENV_CONFIG_PATH); 68 if (inForcedConfigDir) { 69 return inForcedConfigDir; 70 } 71 72 if (!appDataDir) appDataDir = getcwd(); 73 appDataDir = buildPath(appDataDir, APP_FOLDER_NAME); 74 return appDataDir; 75 } 76 77 /** 78 Gets the directory for an imgui config file. 79 */ 80 string incGetAppImguiConfigFile() { 81 if (cachedImguiFileDir) return cachedImguiFileDir; 82 cachedImguiFileDir = buildPath(incGetAppConfigPath(), "imgui.ini"); 83 return cachedImguiFileDir; 84 } 85 86 /** 87 Gets directory for custom fonts 88 */ 89 string incGetAppFontsPath() { 90 if (cachedFontDir) return cachedFontDir; 91 cachedFontDir = buildPath(incGetAppConfigPath(), "fonts"); 92 if (!exists(cachedFontDir)) { 93 94 // Create our font directory 95 mkdirRecurse(cachedFontDir); 96 97 // Create our font dir and install our fonts 98 import std.file : write; 99 100 write(buildPath(cachedFontDir, "OpenDyslexic.otf"), import("OpenDyslexic.otf")); 101 // TODO: Write a license file for OpenDyslexic? 102 } 103 return cachedFontDir; 104 } 105 106 /** 107 Gets directory for custom fonts 108 */ 109 string incGetAppLocalePath() { 110 if (cachedLocaleDir) return cachedLocaleDir; 111 cachedLocaleDir = buildPath(incGetAppConfigPath(), "i18n"); 112 if (!exists(cachedLocaleDir)) { 113 114 // Create our font directory 115 mkdirRecurse(cachedLocaleDir); 116 } 117 return cachedLocaleDir; 118 }