From f458c4d9d014f61011cb36a87ba6b9b37ffcf061 Mon Sep 17 00:00:00 2001 From: and3md Date: Thu, 29 Jun 2017 20:15:17 +0200 Subject: [PATCH 1/5] Grid: ability to set how many columns/rows get to measure widget size. --- src/dlangui/widgets/grid.d | 46 +++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/dlangui/widgets/grid.d b/src/dlangui/widgets/grid.d index 27844b0b..8d450b48 100644 --- a/src/dlangui/widgets/grid.d +++ b/src/dlangui/widgets/grid.d @@ -59,7 +59,7 @@ import dlangui.widgets.scroll; import dlangui.widgets.menu; import std.conv; import std.container.rbtree; -import std.algorithm : equal; +import std.algorithm : equal, min; /// cellPopupMenu signal handler interface interface CellPopupMenuHandler { @@ -1534,6 +1534,32 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler return sz; } + protected int _minVisibleCols = 2; + protected int _minVisibleRows = 2; + + /// returns number of columns from 0 that are taken to measure minimum visible width + @property int minVisibleCols() { + return _minVisibleCols; + } + + /// sets number of columns from 0 that are taken to measure minimum visible width + @property void minVisibleCols(int newMinVisibleCols) { + _minVisibleCols = newMinVisibleCols; + requestLayout(); + } + + /// returns number of rows from 0 that are taken to measure minimum visible height + @property int minVisibleRows() { + return _minVisibleRows; + } + + /// sets number of rows from 0 that are taken to measure minimum visible height, if there are too little rows last row height is multiplied + @property void minVisibleRows(int newMinVisibleRows) { + _minVisibleRows = newMinVisibleRows; + requestLayout(); + } + + /// calculate minimum size of widget override Point minimumVisibleContentSize() { Point sz; @@ -1542,18 +1568,18 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler sz.y = 100; return sz; } + // width: - if (_cols < 2) - sz.x = _colWidths[0]; - else - sz.x = _colWidths[0] + _colWidths[1]; + for (int i = 0 ; i < min(_cols, _minVisibleCols) ; i++) + sz.x += _colWidths[i]; // height - if (_rows < 2) - sz.y = _rowHeights[0]; - else - sz.y = _rowHeights[0] + _rowHeights[1]; - + for (int i = 0 ; i < min(_rows, _minVisibleRows) ; i++) + sz.y += _rowHeights[i]; + + if (_rows<_minVisibleRows) + sz.y += (_minVisibleRows - _rows) * _rowHeights[_rows-1]; + return sz; } From 2bebff9404c42ed10a852de8112183137f953743 Mon Sep 17 00:00:00 2001 From: and3md Date: Thu, 29 Jun 2017 20:17:03 +0200 Subject: [PATCH 2/5] Restore window on SDL resets size and pos to values from window create on linux. --- src/dlangui/platforms/sdl/sdlapp.d | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/dlangui/platforms/sdl/sdlapp.d b/src/dlangui/platforms/sdl/sdlapp.d index 824df97d..560f623c 100644 --- a/src/dlangui/platforms/sdl/sdlapp.d +++ b/src/dlangui/platforms/sdl/sdlapp.d @@ -399,8 +399,17 @@ class SDLWindow : Window { res = true; break; case WindowState.normal: - if (_windowState != WindowState.normal) + if (_windowState != WindowState.normal) { SDL_RestoreWindow(_win); + version(linux) { + // some SDL versions, reset windows size and position to values from create window (SDL 2.0.4) on linux (don't know how it works on macOS) + if (newWindowRect.bottom == int.min && newWindowRect.right == int.min) + SDL_SetWindowSize(_win, _windowRect.right, _windowRect.bottom); + + if (newWindowRect.top == int.min && newWindowRect.left == int.min) + SDL_SetWindowPosition(_win, _windowRect.left, _windowRect.top); + } + } res = true; break; default: From ab1ddc7529ea8d444439a6963d4fc6ea1479cb5a Mon Sep 17 00:00:00 2001 From: and3md Date: Thu, 29 Jun 2017 20:19:49 +0200 Subject: [PATCH 3/5] Add MeasureWindow flag to Window helps if you want window with scrollbars but first measure content size. --- src/dlangui/platforms/common/platform.d | 2 ++ src/dlangui/platforms/sdl/sdlapp.d | 3 +++ src/dlangui/platforms/windows/winapp.d | 3 ++- src/dlangui/platforms/x11/x11app.d | 2 ++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index 18b03337..02736566 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -52,6 +52,8 @@ enum WindowFlag : uint { Fullscreen = 2, /// modal window - grabs input focus Modal = 4, + /// measure window size on window.show() - helps if you want scrollWindow but on show() you want to set window to mainWidget measured size + MeasureSize = 8, } /// Window states diff --git a/src/dlangui/platforms/sdl/sdlapp.d b/src/dlangui/platforms/sdl/sdlapp.d index 560f623c..9e47a5c0 100644 --- a/src/dlangui/platforms/sdl/sdlapp.d +++ b/src/dlangui/platforms/sdl/sdlapp.d @@ -352,6 +352,9 @@ class SDLWindow : Window { } if (_mainWidget) { _mainWidget.measure(SIZE_UNSPECIFIED, SIZE_UNSPECIFIED); + if (flags & WindowFlag.MeasureSize) { + resizeWindow(Point(_mainWidget.measuredWidth, _mainWidget.measuredHeight)); + } adjustWindowOrContentSize(_mainWidget.measuredWidth, _mainWidget.measuredHeight); } diff --git a/src/dlangui/platforms/windows/winapp.d b/src/dlangui/platforms/windows/winapp.d index 2eda59c6..0d284fcf 100644 --- a/src/dlangui/platforms/windows/winapp.d +++ b/src/dlangui/platforms/windows/winapp.d @@ -432,9 +432,10 @@ class Win32Window : Window { _mainWidget = new Widget(); } ReleaseCapture(); - if (_mainWidget) { _mainWidget.measure(SIZE_UNSPECIFIED, SIZE_UNSPECIFIED); + if (flags & WindowFlag.MeasureSize) + resizeWindow(Point(_mainWidget.measuredWidth, _mainWidget.measuredHeight)); adjustWindowOrContentSize(_mainWidget.measuredWidth, _mainWidget.measuredHeight); } diff --git a/src/dlangui/platforms/x11/x11app.d b/src/dlangui/platforms/x11/x11app.d index a5c01e62..211df819 100644 --- a/src/dlangui/platforms/x11/x11app.d +++ b/src/dlangui/platforms/x11/x11app.d @@ -430,6 +430,8 @@ class X11Window : DWindow { } if (_mainWidget) { _mainWidget.measure(SIZE_UNSPECIFIED, SIZE_UNSPECIFIED); + if (flags & WindowFlag.MeasureSize) + resizeWindow(Point(_mainWidget.measuredWidth, _mainWidget.measuredHeight)); _windowRect.right = _dx;// hack to set windowRect, remove when _windowRect will be full supported on X11 _windowRect.bottom = _dy; adjustWindowOrContentSize(_mainWidget.measuredWidth, _mainWidget.measuredHeight); From c8ebb6bd6870526405dc0b02b17af66492111591 Mon Sep 17 00:00:00 2001 From: and3md Date: Thu, 29 Jun 2017 20:22:54 +0200 Subject: [PATCH 4/5] Fix setWindowState() on windows, change resize behavior to be compatible with SDL. --- src/dlangui/platforms/windows/winapp.d | 30 ++++++++++++++++---------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/dlangui/platforms/windows/winapp.d b/src/dlangui/platforms/windows/winapp.d index 0d284fcf..d1d4983e 100644 --- a/src/dlangui/platforms/windows/winapp.d +++ b/src/dlangui/platforms/windows/winapp.d @@ -488,26 +488,34 @@ class Win32Window : Window { default: break; } + res = true; } - return true; + break; case WindowState.maximized: - if (_windowState != WindowState.maximized || activate) + if (_windowState != WindowState.maximized || activate) { ShowWindow(_hwnd, activate ? SW_SHOWMAXIMIZED : SW_MAXIMIZE); - return true; + res = true; + } + break; case WindowState.minimized: - if (_windowState != WindowState.minimized || activate) + if (_windowState != WindowState.minimized || activate) { ShowWindow(_hwnd, activate ? SW_SHOWMINIMIZED : SW_MINIMIZE); - return true; + res = true; + } + break; case WindowState.hidden: - if (_windowState != WindowState.hidden) + if (_windowState != WindowState.hidden) { ShowWindow(_hwnd, SW_HIDE); - return true; - case WindowState.normal: + res = true; + } + break; + case WindowState.normal: if (_windowState != WindowState.normal || activate) { ShowWindow(_hwnd, activate ? SW_SHOWNORMAL : SW_SHOWNA); // SW_RESTORE + res = true; } - res = true; break; + default: break; } @@ -520,13 +528,13 @@ class Win32Window : Window { // no position specified if (newWindowRect.bottom != int.min && newWindowRect.right != int.min) { // change size only - SetWindowPos(_hwnd, NULL, 0, 0, newWindowRect.right, newWindowRect.bottom, flags | SWP_NOMOVE); + SetWindowPos(_hwnd, NULL, 0, 0, newWindowRect.right + 2 * GetSystemMetrics(SM_CXDLGFRAME), newWindowRect.bottom + GetSystemMetrics(SM_CYCAPTION) + 2 * GetSystemMetrics(SM_CYDLGFRAME), flags | SWP_NOMOVE); return true; } } else { if (newWindowRect.bottom != int.min && newWindowRect.right != int.min) { // change size and position - SetWindowPos(_hwnd, NULL, newWindowRect.left, newWindowRect.top, newWindowRect.width, newWindowRect.height, flags); + SetWindowPos(_hwnd, NULL, newWindowRect.left, newWindowRect.top, newWindowRect.right + 2 * GetSystemMetrics(SM_CXDLGFRAME), newWindowRect.bottom + GetSystemMetrics(SM_CYCAPTION) + 2 * GetSystemMetrics(SM_CYDLGFRAME), flags); return true; } else { // change position only From e8f7d2ded48b366c59eb9e8b0c840ea4f754b9af Mon Sep 17 00:00:00 2001 From: and3md Date: Thu, 29 Jun 2017 20:30:43 +0200 Subject: [PATCH 5/5] Fix dialogs to be compatible with new window size/content managment. --- src/dlangui/dialogs/dialog.d | 2 ++ src/dlangui/dialogs/filedlg.d | 17 +++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/dlangui/dialogs/dialog.d b/src/dlangui/dialogs/dialog.d index 029eee5b..4a098ebb 100644 --- a/src/dlangui/dialogs/dialog.d +++ b/src/dlangui/dialogs/dialog.d @@ -208,6 +208,8 @@ class Dialog : VerticalLayout { _popup = _parentWindow.showPopup(_frame); _popup.flags(PopupFlags.Modal); } else { + if (_initialWidth == 0 && _initialHeight == 0) + wflags |= WindowFlag.MeasureSize; _window = Platform.instance.createWindow(_caption, _parentWindow, wflags, _initialWidth, _initialHeight); static if (BACKEND_GUI) { if (_window && _icon) diff --git a/src/dlangui/dialogs/filedlg.d b/src/dlangui/dialogs/filedlg.d index 2bac87e0..36bfdd47 100644 --- a/src/dlangui/dialogs/filedlg.d +++ b/src/dlangui/dialogs/filedlg.d @@ -600,6 +600,8 @@ class FileDialog : Dialog, CustomGridCellAdapter { _fileList.multiSelect = _allowMultipleFiles; _fileList.cellPopupMenu = &getCellPopupMenu; _fileList.menuItemAction = &handleAction; + _fileList.minVisibleRows = 10; + _fileList.minVisibleCols = 4; _fileList.keyEvent = delegate(Widget source, KeyEvent event) { if (_shortcutHelper.onKeyEvent(event)) @@ -766,13 +768,15 @@ class FilePathPanelButtons : WidgetGroupDefaultDrawing { override void measure(int parentWidth, int parentHeight) { Rect m = margins; Rect p = padding; + // calc size constraints for children - int pwidth = parentWidth; - int pheight = parentHeight; + int pwidth = 0; + int pheight = 0; if (parentWidth != SIZE_UNSPECIFIED) - pwidth -= m.left + m.right + p.left + p.right; + pwidth = parentWidth - (m.left + m.right + p.left + p.right); + if (parentHeight != SIZE_UNSPECIFIED) - pheight -= m.top + m.bottom + p.top + p.bottom; + pheight = parentHeight - (m.top + m.bottom + p.top + p.bottom); int reservedForEmptySpace = parentWidth / 20; if (reservedForEmptySpace > 40.pointsToPixels) reservedForEmptySpace = 40.pointsToPixels; @@ -785,17 +789,14 @@ class FilePathPanelButtons : WidgetGroupDefaultDrawing { bool exceeded = false; for (int i = 0; i < _children.count; i++) { Widget item = _children.get(i); - item.visibility = Visibility.Visible; item.measure(pwidth, pheight); if (sz.y < item.measuredHeight) sz.y = item.measuredHeight; if (sz.x + item.measuredWidth > pwidth) { exceeded = true; } - if (!exceeded || i == 0) // at least one item must be visible + if (!exceeded || i == 0) // at least one item must be measured sz.x += item.measuredWidth; - else - item.visibility = Visibility.Gone; } measuredContent(parentWidth, parentHeight, sz.x, sz.y); }