diff --git a/examples/example1/src/main.d b/examples/example1/src/main.d index 7449c85a..50a67858 100644 --- a/examples/example1/src/main.d +++ b/examples/example1/src/main.d @@ -7,6 +7,23 @@ import std.conv; mixin APP_ENTRY_POINT; +Widget createAboutWidget() +{ + LinearLayout res = new VerticalLayout(); + res.padding(Rect(10,10,10,10)); + res.addChild(new TextWidget(null, "DLangUI demo app"d)); + res.addChild(new TextWidget(null, "(C) Vadim Lopatin, 2014"d)); + res.addChild(new TextWidget(null, "http://github.com/buggins/dlangui"d)); + Button closeButton = new Button("close", "Close"d); + closeButton.onClickListener = delegate(Widget src) { + Log.i("Closing window"); + res.window.close(); + return true; + }; + res.addChild(closeButton); + return res; +} + class SampleAnimationWidget : Widget { ulong animationProgress; this(string ID) { @@ -174,7 +191,14 @@ extern (C) int UIAppMain(string[] args) { windowItem.add(new Action(30, "MENU_WINDOW_PREFERENCES")); MenuItem helpItem = new MenuItem(new Action(4, "MENU_HELP"c)); helpItem.add(new Action(40, "MENU_HELP_VIEW_HELP")); - helpItem.add(new Action(41, "MENU_HELP_ABOUT")); + MenuItem aboutItem = new MenuItem(new Action(41, "MENU_HELP_ABOUT")); + helpItem.add(aboutItem); + aboutItem.onMenuItemClick = delegate(MenuItem item) { + Window wnd = Platform.instance.createWindow("About...", null, WindowFlag.Modal); + wnd.mainWidget = createAboutWidget(); + wnd.show(); + return true; + }; mainMenuItems.add(fileItem); mainMenuItems.add(editItem); mainMenuItems.add(viewItem); @@ -185,7 +209,10 @@ extern (C) int UIAppMain(string[] args) { Log.d("mainMenu.onMenuItemListener", item.label); const Action a = item.action; if (a) { - if (window.focusedWidget) + if (a.id == 12) { + window.close(); + return true; + } else if (window.focusedWidget) return window.focusedWidget.handleAction(a); else return contentLayout.handleAction(a); diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index e5ee048e..0d03ecf7 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -30,6 +30,17 @@ import dlangui.graphics.drawbuf; private import dlangui.graphics.gldrawbuf; private import std.algorithm; +/// window creation flags +enum WindowFlag : uint { + /// window can be resized + Resizable = 1, + /// window should be shown in fullscreen mode + Fullscreen = 2, + /// modal window - grabs input focus + Modal = 4, +} + + /** * Window abstraction layer. Widgets can be shown only inside window. * @@ -536,6 +547,8 @@ class Window { } /// request window redraw abstract void invalidate(); + /// close window + abstract void close(); } /** @@ -556,7 +569,12 @@ class Platform { @property static Platform instance() { return _instance; } - abstract Window createWindow(string windowCaption, Window parent); + + /// create window + abstract Window createWindow(string windowCaption, Window parent, uint flags = WindowFlag.Resizable); + /// close window + abstract void closeWindow(Window w); + abstract int enterMessageLoop(); /// retrieves text from clipboard (when mouseBuffer == true, use mouse selection clipboard - under linux) abstract dstring getClipboardText(bool mouseBuffer = false); diff --git a/src/dlangui/platforms/sdl/sdlapp.d b/src/dlangui/platforms/sdl/sdlapp.d index 9b9f7ccd..051a3eaf 100644 --- a/src/dlangui/platforms/sdl/sdlapp.d +++ b/src/dlangui/platforms/sdl/sdlapp.d @@ -58,11 +58,11 @@ version(USE_SDL) { SDLPlatform _platform; SDL_Window * _win; SDL_Renderer* _renderer; - this(SDLPlatform platform, string caption, Window parent) { + this(SDLPlatform platform, string caption, Window parent, uint flags) { _platform = platform; _caption = caption; debug Log.d("Creating SDL window"); - create(); + create(flags); } ~this() { @@ -84,9 +84,17 @@ version(USE_SDL) { private SDL_GLContext _context; } - bool create() { - uint windowFlags = SDL_WINDOW_RESIZABLE; - version(USE_OPENGL) { + protected uint _flags; + bool create(uint flags) { + _flags = flags; + uint windowFlags = 0; + if (flags & WindowFlag.Resizable) + windowFlags |= SDL_WINDOW_RESIZABLE; + if (flags & WindowFlag.Fullscreen) + windowFlags |= SDL_WINDOW_FULLSCREEN; + if (flags & WindowFlag.Modal) + windowFlags |= SDL_WINDOW_INPUT_GRABBED; + version(USE_OPENGL) { if (_enableOpengl) windowFlags |= SDL_WINDOW_OPENGL; } @@ -144,9 +152,20 @@ version(USE_SDL) { override void show() { Log.d("SDLWindow.show()"); + if (_mainWidget && !(_flags & WindowFlag.Resizable)) { + _mainWidget.measure(SIZE_UNSPECIFIED, SIZE_UNSPECIFIED); + SDL_SetWindowSize(_win, _mainWidget.measuredWidth, _mainWidget.measuredHeight); + } SDL_ShowWindow(_win); } + /// close window + override void close() { + Log.d("SDLWindow.close()"); + _platform.closeWindow(this); + } + + protected string _caption; override @property string windowCaption() { @@ -662,6 +681,14 @@ version(USE_SDL) { return null; } + SDLWindow _windowToClose; + + /// close window + override void closeWindow(Window w) { + SDLWindow window = cast(SDLWindow)w; + _windowToClose = window; + } + /// calls request layout for all windows override void requestLayout() { foreach(w; _windowMap) { @@ -684,8 +711,8 @@ version(USE_SDL) { } - override Window createWindow(string windowCaption, Window parent) { - SDLWindow res = new SDLWindow(this, windowCaption, parent); + override Window createWindow(string windowCaption, Window parent, uint flags = WindowFlag.Resizable) { + SDLWindow res = new SDLWindow(this, windowCaption, parent, flags); _windowMap[res.windowId] = res; return res; } @@ -699,7 +726,7 @@ version(USE_SDL) { Log.i("entering message loop"); SDL_Event event; bool quit = false; - while(true) { + while(!quit) { //redrawWindows(); //if (SDL_PollEvent(&event)) { @@ -709,6 +736,7 @@ version(USE_SDL) { if (event.type == SDL_QUIT) { Log.i("event.type == SDL_QUIT"); + quit = true; break; } if (_redrawEventId && event.type == _redrawEventId) { @@ -832,7 +860,23 @@ version(USE_SDL) { // not supported event break; } - } + if (_windowToClose) { + if (_windowToClose.windowId in _windowMap) { + Log.i("Platform.closeWindow()"); + _windowMap.remove(_windowToClose.windowId); + SDL_DestroyWindow(_windowToClose._win); + Log.i("windowMap.length=", _windowMap.length); + destroy(_windowToClose); + } + _windowToClose = null; + } + // + if (_windowMap.length == 0) { + //quit = true; + SDL_Quit(); + quit = true; + } + } } Log.i("exiting message loop"); return 0;