diff --git a/examples/helloworld/src/helloworld.d b/examples/helloworld/src/helloworld.d index cb7a0425..432df016 100644 --- a/examples/helloworld/src/helloworld.d +++ b/examples/helloworld/src/helloworld.d @@ -7,7 +7,12 @@ mixin APP_ENTRY_POINT; /// entry point for dlangui based application extern (C) int UIAppMain(string[] args) { // create window + Log.d("Creating window"); + if (!Platform.instance) { + Log.e("Platform.instance is null!!!"); + } Window window = Platform.instance.createWindow("DlangUI example - HelloWorld", null); + Log.d("Window created"); // create some widget to show in window //window.mainWidget = (new Button()).text("Hello, world!"d).margins(Rect(20,20,20,20)); diff --git a/src/dlangui/core/i18n.d b/src/dlangui/core/i18n.d index 20b05a1c..5c83bc99 100644 --- a/src/dlangui/core/i18n.d +++ b/src/dlangui/core/i18n.d @@ -275,7 +275,7 @@ struct UIStringCollection { } /** UI Strings internationalization translator */ -synchronized class UIStringTranslator { +class UIStringTranslator { private UIStringList _main; private UIStringList _fallback; @@ -325,8 +325,8 @@ synchronized class UIStringTranslator { /// create empty translator this() { - _main = new shared UIStringList(); - _fallback = new shared UIStringList(); + _main = new UIStringList(); + _fallback = new UIStringList(); } /** Load translation file(s) */ @@ -357,7 +357,7 @@ synchronized class UIStringTranslator { } /** UI string translator */ -private shared class UIStringList { +private class UIStringList { private dstring[string] _map; /// remove all items void clear() { @@ -433,8 +433,15 @@ private shared class UIStringList { } } +//============================================================== +// Global Shared objects + /** Global UI translator object */ -shared UIStringTranslator i18n; -shared static this() { - i18n = new shared UIStringTranslator(); +private UIStringTranslator _i18n; + +@property UIStringTranslator i18n() { + if (!_i18n) { + _i18n = new UIStringTranslator(); + } + return _i18n; } diff --git a/src/dlangui/dialogs/filedlg.d b/src/dlangui/dialogs/filedlg.d index a3d6f032..2bce75af 100644 --- a/src/dlangui/dialogs/filedlg.d +++ b/src/dlangui/dialogs/filedlg.d @@ -901,5 +901,5 @@ class DirEditLine : FileNameEditLine { } } -import dlangui.widgets.metadata; -mixin(registerWidgets!(FileNameEditLine, DirEditLine)()); +//import dlangui.widgets.metadata; +//mixin(registerWidgets!(FileNameEditLine, DirEditLine)()); diff --git a/src/dlangui/graphics/fonts.d b/src/dlangui/graphics/fonts.d index c8db5fa2..1b0352f2 100644 --- a/src/dlangui/graphics/fonts.d +++ b/src/dlangui/graphics/fonts.d @@ -889,7 +889,3 @@ private: __gshared glyph_gamma_table!65 _gamma65; __gshared glyph_gamma_table!256 _gamma256; -__gshared static this() { - _gamma65 = new glyph_gamma_table!65(1.0); - _gamma256 = new glyph_gamma_table!256(1.0); -} diff --git a/src/dlangui/graphics/ftfonts.d b/src/dlangui/graphics/ftfonts.d index 328539fd..76a4cbb2 100644 --- a/src/dlangui/graphics/ftfonts.d +++ b/src/dlangui/graphics/ftfonts.d @@ -23,28 +23,6 @@ import std.string; import std.utf; __gshared int[string] STD_FONT_FACES; -__gshared static this() { - STD_FONT_FACES = [ - "Arial": 12, - "Times New Roman": 12, - "Courier New": 10, - "DejaVu Serif": 10, - "DejaVu Sans": 10, - "DejaVu Sans Mono": 10, - "Liberation Serif": 11, - "Liberation Sans": 11, - "Liberation Mono": 11, - "Verdana": 10, - "Menlo": 13, - "Consolas": 12, - "DejaVuSansMono": 10, - "Lucida Sans Typewriter": 10, - "Lucida Console": 12, - "FreeMono": 8, - "FreeSans": 8, - "FreeSerif": 8, - ]; -} int stdFontFacePriority(string face) { if (auto p = (face in STD_FONT_FACES)) @@ -580,6 +558,10 @@ class FreeTypeFontManager : FontManager { // load dynaic library try { Log.v("DerelictFT: Loading FreeType library"); + if (!DerelictFT) { + Log.w("DerelictFT is null. Compiler bug? Applying workaround to fix it."); + DerelictFT = new DerelictFTLoader; + } DerelictFT.missingSymbolCallback = &missingSymFunc; Log.v("DerelictFT: Missing symbols callback is registered"); DerelictFT.load(); diff --git a/src/dlangui/graphics/gldrawbuf.d b/src/dlangui/graphics/gldrawbuf.d index 73c28fa6..4ad38b92 100644 --- a/src/dlangui/graphics/gldrawbuf.d +++ b/src/dlangui/graphics/gldrawbuf.d @@ -276,9 +276,11 @@ void onGlyphDestroyedCallback(uint pobject) { private __gshared GLImageCache glImageCache; private __gshared GLGlyphCache glGlyphCache; -shared static this() { - glImageCache = new GLImageCache; - glGlyphCache = new GLGlyphCache; +void initGLCaches() { + if (!glImageCache) + glImageCache = new GLImageCache; + if (!glGlyphCache) + glGlyphCache = new GLGlyphCache; } private abstract class GLCache diff --git a/src/dlangui/graphics/resources.d b/src/dlangui/graphics/resources.d index 8f9e18b6..3daa5ef0 100644 --- a/src/dlangui/graphics/resources.d +++ b/src/dlangui/graphics/resources.d @@ -197,7 +197,7 @@ EmbeddedResource[] embedResourcesFromList(string resourceList)() { } -__gshared static this() { +void embedStandardDlangUIResources() { version (EmbedStandardResources) { embeddedResourceList.addResources(embedResourcesFromList!("standard_resources.list")()); } @@ -910,11 +910,6 @@ __gshared DrawableCache _drawableCache; _drawableCache = cache; } -shared static this() { - _imageCache = new ImageCache(); - _drawableCache = new DrawableCache(); -} - class DrawableCache { static class DrawableCacheItem { string _id; diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index 2cf2b8ef..2fbd6135 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -1299,10 +1299,13 @@ class Platform { if (_uiLanguage.equal(langCode)) return this; _uiLanguage = langCode; + + Log.v("Loading language file"); if (langCode.equal("en")) i18n.load("en.ini"); //"ru.ini", "en.ini" else i18n.load(langCode ~ ".ini", "en.ini"); + Log.v("Calling onThemeChanged"); onThemeChanged(); requestLayout(); return this; @@ -1315,6 +1318,7 @@ class Platform { @property Platform uiTheme(string themeResourceId) { if (_themeId.equal(themeResourceId)) return this; + Log.v("uiTheme setting new theme ", themeResourceId); _themeId = themeResourceId; Theme theme = loadTheme(themeResourceId); if (!theme) { @@ -1331,10 +1335,14 @@ class Platform { /// to set uiLanguage and themeId to default (en, theme_default) if not set yet protected void setDefaultLanguageAndThemeIfNecessary() { - if (!_uiLanguage) + if (!_uiLanguage) { + Log.v("setDefaultLanguageAndThemeIfNecessary : setting UI language"); uiLanguage = "en"; - if (!_themeId) + } + if (!_themeId) { + Log.v("setDefaultLanguageAndThemeIfNecessary : setting UI theme"); uiTheme = "theme_default"; + } } protected string[] _resourceDirs; @@ -1433,6 +1441,11 @@ extern(C) bool initFontManager(); extern(C) void initLogs(); /// call this when all resources are supposed to be freed to report counts of non-freed resources by type extern(C) void releaseResourcesOnAppExit(); +/// call this on application initialization +extern(C) void initResourceManagers(); +/// call this from shared static this() +extern (C) void initSharedResourceManagers(); + diff --git a/src/dlangui/platforms/common/startup.d b/src/dlangui/platforms/common/startup.d index af1dbe43..1c11c8c6 100644 --- a/src/dlangui/platforms/common/startup.d +++ b/src/dlangui/platforms/common/startup.d @@ -211,6 +211,99 @@ extern (C) void initLogs() { Log.i("Logger is initialized"); } +/// call this on application initialization +extern (C) void initResourceManagers() { + Log.d("initResourceManagers()"); + import dlangui.graphics.fonts; + _gamma65 = new glyph_gamma_table!65(1.0); + _gamma256 = new glyph_gamma_table!256(1.0); + static if (ENABLE_FREETYPE) { + import dlangui.graphics.ftfonts; + STD_FONT_FACES = [ + "Arial": 12, + "Times New Roman": 12, + "Courier New": 10, + "DejaVu Serif": 10, + "DejaVu Sans": 10, + "DejaVu Sans Mono": 10, + "Liberation Serif": 11, + "Liberation Sans": 11, + "Liberation Mono": 11, + "Verdana": 10, + "Menlo": 13, + "Consolas": 12, + "DejaVuSansMono": 10, + "Lucida Sans Typewriter": 10, + "Lucida Console": 12, + "FreeMono": 8, + "FreeSans": 8, + "FreeSerif": 8, + ]; + } + static if (ENABLE_OPENGL) { + import dlangui.graphics.gldrawbuf; + initGLCaches(); + } + import dlangui.graphics.resources; + embedStandardDlangUIResources(); + _imageCache = new ImageCache(); + _drawableCache = new DrawableCache(); + version (Windows) { + import dlangui.platforms.windows.win32fonts; + initWin32FontsTables(); + } + + Log.d("Calling initSharedResourceManagers()"); + initSharedResourceManagers(); + + Log.d("Calling initStandardEditorActions()"); + import dlangui.widgets.editors; + initStandardEditorActions(); + + Log.d("Calling registerStandardWidgets()"); + registerStandardWidgets(); + + Log.d("initResourceManagers() -- finished"); +} + +/// register standard widgets to use in DML +void registerStandardWidgets() { + Log.d("Registering standard widgets for DML"); + import dlangui.widgets.metadata; + import dlangui.widgets.widget; + import dlangui.widgets.layouts; + import dlangui.widgets.controls; + import dlangui.widgets.lists; + import dlangui.widgets.combobox; + import dlangui.widgets.editors; + import dlangui.widgets.grid; + import dlangui.dialogs.filedlg; + mixin(registerWidgets!(FileNameEditLine, DirEditLine, //dlangui.dialogs.filedlg + ComboBox, ComboEdit, //dlangui.widgets.combobox + Widget, TextWidget, MultilineTextWidget, Button, ImageWidget, ImageButton, ImageCheckButton, ImageTextButton, + RadioButton, CheckBox, ScrollBar, HSpacer, VSpacer, CanvasWidget, // dlangui.widgets.controls + EditLine, EditBox, LogWidget,//dlangui.widgets.editors + StringGridWidget, //dlangui.widgets.grid + VerticalLayout, HorizontalLayout, TableLayout, FrameLayout, // dlangui.widgets.layouts + ListWidget, StringListWidget,//dlangui.widgets.lists + )("void registerWidgets")); + registerWidgets(); +} + +/// call this from shared static this() +extern (C) void initSharedResourceManagers() { + //Log.d("initSharedResourceManagers()"); + //import dlangui.core.i18n; + //if (!i18n) { + // Log.d("Creating i18n object"); + // i18n = new shared UIStringTranslator(); + //} +} + +shared static this() { + //initSharedResourceManagers(); +} + /// call this when all resources are supposed to be freed to report counts of non-freed resources by type extern (C) void releaseResourcesOnAppExit() { diff --git a/src/dlangui/platforms/dsfml/dsfmlapp.d b/src/dlangui/platforms/dsfml/dsfmlapp.d index 69897919..d3cd9f60 100644 --- a/src/dlangui/platforms/dsfml/dsfmlapp.d +++ b/src/dlangui/platforms/dsfml/dsfmlapp.d @@ -417,6 +417,7 @@ void initDSFMLApp() { Log.d("Initializing DSFML platform"); DSFMLPlatform p = new DSFMLPlatform(); Platform.setInstance(p); + initResourceManagers(); initFontManager(); currentTheme = createDefaultTheme(); diff --git a/src/dlangui/platforms/sdl/sdlapp.d b/src/dlangui/platforms/sdl/sdlapp.d index 035c8751..7749e565 100644 --- a/src/dlangui/platforms/sdl/sdlapp.d +++ b/src/dlangui/platforms/sdl/sdlapp.d @@ -1361,7 +1361,7 @@ int sdlmain(string[] args) { Log.e("******************************************************************"); assert(false); } - + initResourceManagers(); currentTheme = createDefaultTheme(); diff --git a/src/dlangui/platforms/windows/win32fonts.d b/src/dlangui/platforms/windows/win32fonts.d index 42813c8b..4ec0e61c 100644 --- a/src/dlangui/platforms/windows/win32fonts.d +++ b/src/dlangui/platforms/windows/win32fonts.d @@ -107,10 +107,12 @@ private: }; private __gshared lcd_distribution_lut!65 lut; -__gshared static this() { +void initWin32FontsTables() { lut = lcd_distribution_lut!65(0.5, 0.25, 0.125); } + + private int myabs(int n) { return n < 0 ? -n : n; } diff --git a/src/dlangui/platforms/windows/winapp.d b/src/dlangui/platforms/windows/winapp.d index 6bfefabd..b76ac52e 100644 --- a/src/dlangui/platforms/windows/winapp.d +++ b/src/dlangui/platforms/windows/winapp.d @@ -821,9 +821,12 @@ class Win32Platform : Platform { return null; } override Window createWindow(dstring windowCaption, Window parent, uint flags = WindowFlag.Resizable, uint width = 0, uint height = 0) { + Log.d("Platform.createWindow is called"); width = pointsToPixels(width); height = pointsToPixels(height); + Log.v("Platform.createWindow : setDefaultLanguageAndThemeIfNecessary"); setDefaultLanguageAndThemeIfNecessary(); + Log.v("Platform.createWindow : new Win32Window"); return new Win32Window(this, windowCaption, parent, flags, width, height); } @@ -1003,6 +1006,35 @@ string[] splitCmdLine(string line) { private __gshared Win32Platform w32platform; +static if (ENABLE_OPENGL) { + import derelict.opengl3.gl3; + import derelict.opengl3.gl; + + void initOpenGL() { + try { + Log.d("Loading Derelict GL"); + DerelictGL.load(); + DerelictGL3.load(); + Log.d("Derelict GL - loaded"); + // + //// just to check OpenGL context + //Log.i("Trying to setup OpenGL context"); + //Win32Window tmpWindow = new Win32Window(w32platform, ""d, null, 0); + //destroy(tmpWindow); + //if (openglEnabled) + // Log.i("OpenGL support is enabled"); + //else + // Log.w("OpenGL support is disabled"); + //// process messages + //platform.enterMessageLoop(); + } catch (Exception e) { + Log.e("Exception while trying to init OpenGL", e); + setOpenglEnabled(false); + } + } +} + + int myWinMain(void* hInstance, void* hPrevInstance, char* lpCmdLine, int iCmdShow) { initLogs(); @@ -1038,37 +1070,25 @@ int myWinMain(void* hInstance, void* hPrevInstance, char* lpCmdLine, int iCmdSho Log.e("******************************************************************"); assert(false); } + initResourceManagers(); currentTheme = createDefaultTheme(); static if (ENABLE_OPENGL) { - try { - import derelict.opengl3.gl3; - import derelict.opengl3.gl; - DerelictGL.load(); - DerelictGL3.load(); - // - //// just to check OpenGL context - //Log.i("Trying to setup OpenGL context"); - //Win32Window tmpWindow = new Win32Window(w32platform, ""d, null, 0); - //destroy(tmpWindow); - //if (openglEnabled) - // Log.i("OpenGL support is enabled"); - //else - // Log.w("OpenGL support is disabled"); - //// process messages - //platform.enterMessageLoop(); - } catch (Exception e) { - Log.e("Exception while trying to init OpenGL", e); - setOpenglEnabled(false); - } + initOpenGL(); } // Load versions 1.2+ and all supported ARB and EXT extensions. Log.i("Entering UIAppMain: ", args); - int result = UIAppMain(args); - Log.i("UIAppMain returned ", result); + int result = -1; + try { + result = UIAppMain(args); + Log.i("UIAppMain returned ", result); + } catch (Exception e) { + Log.e("Abnormal UIAppMain termination"); + Log.e("UIAppMain exception: ", e); + } releaseResourcesOnAppExit(); diff --git a/src/dlangui/platforms/x11/x11app.d b/src/dlangui/platforms/x11/x11app.d index b5c3ff8b..acd90a3d 100644 --- a/src/dlangui/platforms/x11/x11app.d +++ b/src/dlangui/platforms/x11/x11app.d @@ -1353,6 +1353,7 @@ extern(C) int DLANGUImain(string[] args) Log.e("******************************************************************"); assert(false); } + initResourceManagers(); currentTheme = createDefaultTheme(); diff --git a/src/dlangui/widgets/combobox.d b/src/dlangui/widgets/combobox.d index 76069fb1..a13f95a0 100644 --- a/src/dlangui/widgets/combobox.d +++ b/src/dlangui/widgets/combobox.d @@ -481,5 +481,5 @@ class ComboEdit : ComboBox { } -import dlangui.widgets.metadata; -mixin(registerWidgets!(ComboBox)()); +//import dlangui.widgets.metadata; +//mixin(registerWidgets!(ComboBox)()); diff --git a/src/dlangui/widgets/controls.d b/src/dlangui/widgets/controls.d index 10fccfa6..4cace9a1 100644 --- a/src/dlangui/widgets/controls.d +++ b/src/dlangui/widgets/controls.d @@ -1100,5 +1100,5 @@ class CanvasWidget : Widget { } } -import dlangui.widgets.metadata; -mixin(registerWidgets!(Widget, TextWidget, MultilineTextWidget, Button, ImageWidget, ImageButton, ImageCheckButton, ImageTextButton, RadioButton, CheckBox, ScrollBar, HSpacer, VSpacer, CanvasWidget)()); +//import dlangui.widgets.metadata; +//mixin(registerWidgets!(Widget, TextWidget, MultilineTextWidget, Button, ImageWidget, ImageButton, ImageCheckButton, ImageTextButton, RadioButton, CheckBox, ScrollBar, HSpacer, VSpacer, CanvasWidget)()); diff --git a/src/dlangui/widgets/editors.d b/src/dlangui/widgets/editors.d index e2888a6a..594e700e 100644 --- a/src/dlangui/widgets/editors.d +++ b/src/dlangui/widgets/editors.d @@ -193,7 +193,7 @@ enum EditorActions : int { } -__gshared static this() { +void initStandardEditorActions() { // register editor action names and ids registerActionEnum!EditorActions(); } @@ -2927,5 +2927,5 @@ class FindPanel : HorizontalLayout { } } -import dlangui.widgets.metadata; -mixin(registerWidgets!(EditLine, EditBox, LogWidget)()); +//import dlangui.widgets.metadata; +//mixin(registerWidgets!(EditLine, EditBox, LogWidget)()); diff --git a/src/dlangui/widgets/grid.d b/src/dlangui/widgets/grid.d index 33f74677..5638a93b 100644 --- a/src/dlangui/widgets/grid.d +++ b/src/dlangui/widgets/grid.d @@ -1461,5 +1461,5 @@ class StringGridWidget : StringGridWidgetBase { } } -import dlangui.widgets.metadata; -mixin(registerWidgets!(StringGridWidget)()); +//import dlangui.widgets.metadata; +//mixin(registerWidgets!(StringGridWidget)()); diff --git a/src/dlangui/widgets/layouts.d b/src/dlangui/widgets/layouts.d index 8014c460..b2386947 100644 --- a/src/dlangui/widgets/layouts.d +++ b/src/dlangui/widgets/layouts.d @@ -849,5 +849,5 @@ class TableLayout : WidgetGroupDefaultDrawing { } -import dlangui.widgets.metadata; -mixin(registerWidgets!(VerticalLayout, HorizontalLayout, TableLayout, FrameLayout)()); +//import dlangui.widgets.metadata; +//mixin(registerWidgets!(VerticalLayout, HorizontalLayout, TableLayout, FrameLayout)()); diff --git a/src/dlangui/widgets/lists.d b/src/dlangui/widgets/lists.d index cfa0b1dd..737c161d 100644 --- a/src/dlangui/widgets/lists.d +++ b/src/dlangui/widgets/lists.d @@ -1331,5 +1331,5 @@ class StringListWidget : ListWidget { } } -import dlangui.widgets.metadata; -mixin(registerWidgets!(ListWidget, StringListWidget)()); +//import dlangui.widgets.metadata; +//mixin(registerWidgets!(ListWidget, StringListWidget)()); diff --git a/src/dlangui/widgets/metadata.d b/src/dlangui/widgets/metadata.d index 694c0031..601045c3 100644 --- a/src/dlangui/widgets/metadata.d +++ b/src/dlangui/widgets/metadata.d @@ -77,7 +77,7 @@ string generateRegisterMetadataClass(alias t)() { return "registerWidgetMetadata(\"" ~ t.stringof ~ "\", new " ~ metadataClassName ~ "());\n"; } -string registerWidgets(T...)() { +string registerWidgets(T...)(string registerFunctionName = "__gshared static this") { string classDefs; string registerDefs; foreach(t; T) { @@ -92,7 +92,7 @@ string registerWidgets(T...)() { registerDefs ~= registerdef; //registerWidgetMetadata(T.stringof, new Metadata()); } - return classDefs ~ "\n__gshared static this() {\n" ~ registerDefs ~ "}"; + return classDefs ~ "\n" ~ registerFunctionName ~ "() {\n" ~ registerDefs ~ "}"; } /// returns true if passed name is identifier of registered widget class