From e6782a24aff47354ccdc5d58f604d34c5dcedc2f Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Thu, 17 Apr 2014 10:25:04 +0400 Subject: [PATCH] simplify app initialization code --- examples/example1/src/main.d | 49 +++++-------------- src/dlangui/all.d | 26 ++++++++++ src/dlangui/core/i18n.d | 13 +++++ src/dlangui/core/types.d | 65 +++++++++++++++++++++++++ src/dlangui/graphics/resources.d | 16 +++++- src/dlangui/platforms/common/platform.d | 38 +++++++++------ 6 files changed, 155 insertions(+), 52 deletions(-) diff --git a/examples/example1/src/main.d b/examples/example1/src/main.d index 939111ce..3f4e74fe 100644 --- a/examples/example1/src/main.d +++ b/examples/example1/src/main.d @@ -4,45 +4,22 @@ import dlangui.all; import std.stdio; import std.conv; -version (linux) { - //pragma(lib, "png"); - pragma(lib, "xcb"); - pragma(lib, "xcb-shm"); - pragma(lib, "xcb-image"); - pragma(lib, "X11-xcb"); - pragma(lib, "X11"); - pragma(lib, "dl"); -} -/// workaround for link issue when WinMain is located in library -version(Windows) { - private import win32.windows; - private import dlangui.platforms.windows.winapp; - extern (Windows) - int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, - LPSTR lpCmdLine, int nCmdShow) - { - return DLANGUIWinMain(hInstance, hPrevInstance, - lpCmdLine, nCmdShow); - } -} +mixin APP_ENTRY_POINT; /// entry point for dlangui based application extern (C) int UIAppMain(string[] args) { - // setup resource dir - version (Windows) { - string resourceDir = exePath() ~ "..\\res\\"; - string i18nDir = exePath() ~ "..\\res\\i18n\\"; - } else { - string resourceDir = exePath() ~ "../../res/"; - string i18nDir = exePath() ~ "../../res/i18n/"; - } - string[] imageDirs = [ - resourceDir + // resource directory search paths + string[] resourceDirs = [ + appendPath(exePath, "../res/"), // for Visual D and DUB builds + appendPath(exePath, "../../res/") // for Mono-D builds ]; - drawableCache.resourcePaths = imageDirs; - i18n.resourceDir = i18nDir; - i18n.load("ru.ini", "en.ini"); + // setup resource directories - will use only existing directories + drawableCache.setResourcePaths(resourceDirs); + // setup i18n - look for i18n directory inside one of passed directories + i18n.findTranslationsDir(resourceDirs); + // select translation file - for english language + i18n.load("en.ini"); //"ru.ini", "en.ini" // create window Window window = Platform.instance().createWindow("My Window", null); @@ -162,9 +139,7 @@ extern (C) int UIAppMain(string[] args) { window.mainWidget = (new Button()).text("sample button"); } window.show(); - //window.showPopup((new TextWidget()).text("POPUP"d)); - window.windowCaption = "New Window Caption"; - + //window.windowCaption = "New Window Caption"; // run message loop return Platform.instance().enterMessageLoop(); } diff --git a/src/dlangui/all.d b/src/dlangui/all.d index 8f55b0f2..8df92728 100644 --- a/src/dlangui/all.d +++ b/src/dlangui/all.d @@ -8,7 +8,33 @@ This module is just to simplify import of most useful DLANGUI modules. Synopsis: ---- +// helloworld import dlangui.all; +// required in one of modules +mixin DLANGUI_ENTRY_POINT; + +/// entry point for dlangui based application +extern (C) int UIAppMain(string[] args) { + // resource directory search paths + string[] resourceDirs = [ + appendPath(exePath, "../res/"), // for Visual D and DUB builds + appendPath(exePath, "../../res/") // for Mono-D builds + ]; + // setup resource directories - will use only existing directories + drawableCache.setResourcePaths(resourceDirs); + // setup i18n - look for i18n directory inside one of passed directories + i18n.findTranslationsDir(resourceDirs); + // select translation file - for english language + i18n.load("en.ini"); //"ru.ini", "en.ini" + + // create window + Window window = Platform.instance().createWindow("My Window", null); + window.mainWidget = (new Button()).text("Hello world"d); + // run message loop + return Platform.instance().enterMessageLoop(); +} + + ---- Copyright: Vadim Lopatin, 2014 diff --git a/src/dlangui/core/i18n.d b/src/dlangui/core/i18n.d index 83cca1fe..d7c13e0a 100644 --- a/src/dlangui/core/i18n.d +++ b/src/dlangui/core/i18n.d @@ -40,6 +40,7 @@ Authors: $(WEB coolreader.org, Vadim Lopatin) */ module dlangui.core.i18n; +import dlangui.core.types; import dlangui.core.logger; import std.utf; @@ -108,6 +109,18 @@ class UIStringTranslator { @property string resourceDir() { return _resourceDir; } /// set i18n resource directory @property void resourceDir(string dir) { _resourceDir = dir; } + /// looks for i18n directory inside one of passed dirs, and uses first found as directory to read i18n files from + string findTranslationsDir(string[] dirs ...) { + import std.file; + foreach(dir; dirs) { + string path = appendPath(dir, "i18n/"); + if (exists(path) && isDir(path)) { + _resourceDir = path; + return _resourceDir; + } + } + return null; + } /// convert resource path - зкуpend resource dir if necessary string convertResourcePath(string filename) { diff --git a/src/dlangui/core/types.d b/src/dlangui/core/types.d index 8e944e5c..c9b5ac09 100644 --- a/src/dlangui/core/types.d +++ b/src/dlangui/core/types.d @@ -286,3 +286,68 @@ enum State : uint { Parent = 0x10000, // use parent's state } + + +version (Windows) { + immutable char PATH_DELIMITER = '\\'; +} else { + immutable char PATH_DELIMITER = '/'; +} + +/// returns true if char ch is / or \ slash +bool isPathDelimiter(char ch) { + return ch == '/' || ch == '\\'; +} + +/// returns current executable path only, including last path delimiter +@property string exePath() { + import std.file; + string path = thisExePath(); + int lastSlash = 0; + for (int i = 0; i < path.length; i++) + if (path[i] == PATH_DELIMITER) + lastSlash = i; + return path[0 .. lastSlash + 1]; +} + +/// converts path delimiters to standard for platform inplace in buffer(e.g. / to \ on windows, \ to / on posix), returns buf +char[] convertPathDelimiters(char[] buf) { + foreach(ref ch; buf) { + version (Windows) { + if (ch == '/') + ch = '\\'; + } else { + if (ch == '\\') + ch = '/'; + } + } + return buf; +} + +/// converts path delimiters to standard for platform (e.g. / to \ on windows, \ to / on posix) +string convertPathDelimiters(string src) { + char[] buf = src.dup; + return cast(string)convertPathDelimiters(buf); +} + +/// appends file path parts with proper delimiters e.g. appendPath("/home/user", ".myapp", "config") => "/home/user/.myapp/config" +string appendPath(string[] pathItems ...) { + char[] buf; + foreach (s; pathItems) { + if (buf.length && !isPathDelimiter(buf[$-1])) + buf ~= PATH_DELIMITER; + buf ~= s; + } + return convertPathDelimiters(buf).dup; +} + +/// appends file path parts with proper delimiters (as well converts delimiters inside path to system) to buffer e.g. appendPath("/home/user", ".myapp", "config") => "/home/user/.myapp/config" +char[] appendPath(char[] buf, string[] pathItems ...) { + foreach (s; pathItems) { + if (buf.length && !isPathDelimiter(buf[$-1])) + buf ~= PATH_DELIMITER; + buf ~= s; + } + return convertPathDelimiters(buf); +} + diff --git a/src/dlangui/graphics/resources.d b/src/dlangui/graphics/resources.d index c3cd8caf..6099b40a 100644 --- a/src/dlangui/graphics/resources.d +++ b/src/dlangui/graphics/resources.d @@ -701,8 +701,22 @@ class DrawableCache { @property string[] resourcePaths() { return _resourcePaths; } + /// set resource directory paths as variable number of parameters + void setResourcePaths(string[] paths ...) { + resourcePaths(paths); + } + /// set resource directory paths array (only existing dirs will be added) @property void resourcePaths(string[] paths) { - _resourcePaths = paths; + string[] existingPaths; + foreach(path; paths) { + if (exists(path) && isDir(path)) { + existingPaths ~= path; + Log.d("DrawableCache: adding path ", path, " to resource dir list."); + } else { + Log.d("DrawableCache: path ", path, " does not exist."); + } + } + _resourcePaths = existingPaths; clear(); } /// concatenates path with resource id and extension, returns pathname if there is such file, null if file does not exist diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index 709b8db1..396a8a30 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -491,19 +491,29 @@ version (USE_OPENGL) { } } -version (Windows) { - immutable char PATH_DELIMITER = '\\'; -} else { - immutable char PATH_DELIMITER = '/'; -} -/// returns current executable path only, including last path delimiter -string exePath() { - import std.file; - string path = thisExePath(); - int lastSlash = 0; - for (int i = 0; i < path.length; i++) - if (path[i] == PATH_DELIMITER) - lastSlash = i; - return path[0 .. lastSlash + 1]; +/// put "mixin APP_ENTRY_POINT;" to main module of your dlangui based app +mixin template APP_ENTRY_POINT() { + version (linux) { + //pragma(lib, "png"); + pragma(lib, "xcb"); + pragma(lib, "xcb-shm"); + pragma(lib, "xcb-image"); + pragma(lib, "X11-xcb"); + pragma(lib, "X11"); + pragma(lib, "dl"); + } + + /// workaround for link issue when WinMain is located in library + version(Windows) { + private import win32.windows; + private import dlangui.platforms.windows.winapp; + extern (Windows) + int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpCmdLine, int nCmdShow) + { + return DLANGUIWinMain(hInstance, hPrevInstance, + lpCmdLine, nCmdShow); + } + } }