mirror of https://github.com/buggins/dlangui.git
Merge pull request #379 from and3md/calc_widget_sizes
Fix for #354 - wrongly calculated widget sizes.
This commit is contained in:
commit
418c4a6b6e
|
@ -267,7 +267,11 @@ extern (C) int UIAppMain(string[] args) {
|
|||
|
||||
// create window
|
||||
Window window = Platform.instance.createWindow("DlangUI Example 1", null, WindowFlag.Resizable, 800, 700);
|
||||
|
||||
// here you can see window or content resize mode
|
||||
//Window window = Platform.instance.createWindow("DlangUI Example 1", null, WindowFlag.Resizable, 400, 400);
|
||||
//window.windowOrContentResizeMode = WindowOrContentResizeMode.resizeWindow;
|
||||
//window.windowOrContentResizeMode = WindowOrContentResizeMode.scrollWindow;
|
||||
//window.windowOrContentResizeMode = WindowOrContentResizeMode.shrinkWidgets;
|
||||
static if (true) {
|
||||
VerticalLayout contentLayout = new VerticalLayout();
|
||||
|
||||
|
@ -458,6 +462,7 @@ extern (C) int UIAppMain(string[] args) {
|
|||
// most of controls example
|
||||
{
|
||||
LinearLayout controls = new VerticalLayout("controls");
|
||||
controls.layoutHeight(FILL_PARENT);
|
||||
controls.padding = Rect(12.pointsToPixels,12.pointsToPixels,12.pointsToPixels,12.pointsToPixels);
|
||||
|
||||
HorizontalLayout line1 = new HorizontalLayout();
|
||||
|
@ -548,9 +553,12 @@ extern (C) int UIAppMain(string[] args) {
|
|||
|
||||
HorizontalLayout line4 = new HorizontalLayout();
|
||||
line4.layoutWidth(FILL_PARENT);
|
||||
line4.layoutHeight(FILL_PARENT);
|
||||
GroupBox gbgrid = new GroupBox("grid", "StringGridWidget"d, Orientation.Horizontal);
|
||||
StringGridWidget grid = new StringGridWidget("stringgrid");
|
||||
grid.resize(12, 10);
|
||||
gbgrid.layoutWidth(FILL_PARENT);
|
||||
gbgrid.layoutHeight(FILL_PARENT);
|
||||
grid.layoutWidth(FILL_PARENT);
|
||||
grid.layoutHeight(FILL_PARENT);
|
||||
foreach (index, month; ["January"d, "February"d, "March"d, "April"d, "May"d, "June"d, "July"d, "August"d, "September"d, "October"d, "November"d, "December"d])
|
||||
|
|
|
@ -24,6 +24,7 @@ public import dlangui.core.events;
|
|||
import dlangui.core.collections;
|
||||
import dlangui.widgets.widget;
|
||||
import dlangui.widgets.popup;
|
||||
import dlangui.widgets.scrollbar;
|
||||
import dlangui.graphics.drawbuf;
|
||||
import dlangui.core.stdaction;
|
||||
import dlangui.core.asyncsocket;
|
||||
|
@ -91,6 +92,16 @@ enum DialogDisplayMode : ulong {
|
|||
allTypesOfDialogsInPopup = fileDialogInPopup | messageBoxInPopup | inputBoxInPopup | settingsDialogInPopup | userDialogInPopup
|
||||
}
|
||||
|
||||
/// Sets what's should be done when window content is too big
|
||||
enum WindowOrContentResizeMode {
|
||||
/// widgets are shrink to fit in window
|
||||
shrinkWidgets,
|
||||
/// resize window when window is too small
|
||||
resizeWindow,
|
||||
/// add scrollbars to window
|
||||
scrollWindow
|
||||
}
|
||||
|
||||
/// Window state signal listener
|
||||
interface OnWindowStateHandler {
|
||||
/// signal listener - called when state of window is changed
|
||||
|
@ -213,7 +224,16 @@ class Window : CustomEventTarget {
|
|||
protected Widget _mainWidget;
|
||||
protected EventList _eventList;
|
||||
protected uint _flags;
|
||||
|
||||
/// minimal good looking content width
|
||||
protected int _minContentWidth;
|
||||
/// minimal good looking content height
|
||||
protected int _minContentHeight;
|
||||
|
||||
// current content width calculated using _windowOrContentResizeMode flag, usually used in measure()
|
||||
protected int _currentContentWidth;
|
||||
// current content height calculated using _windowOrContentResizeMode flag, usually used in measure()
|
||||
protected int _currentContentHeight;
|
||||
|
||||
@property uint flags() { return _flags; }
|
||||
@property uint backgroundColor() const { return _backgroundColor; }
|
||||
@property void backgroundColor(uint color) { _backgroundColor = color; }
|
||||
|
@ -241,7 +261,21 @@ class Window : CustomEventTarget {
|
|||
@property void caretReplace(bool flg) { _caretReplace = flg; }
|
||||
@property bool caretReplace() { return _caretReplace; }
|
||||
|
||||
// Abstract methods : override in platform implementatino
|
||||
// window content resize mode
|
||||
//protected WindowOrContentResizeMode _windowOrContentResizeMode = WindowOrContentResizeMode.resizeWindow;
|
||||
//protected WindowOrContentResizeMode _windowOrContentResizeMode = WindowOrContentResizeMode.shrinkWidgets;
|
||||
protected WindowOrContentResizeMode _windowOrContentResizeMode = WindowOrContentResizeMode.scrollWindow;
|
||||
|
||||
@property WindowOrContentResizeMode windowOrContentResizeMode() {return _windowOrContentResizeMode; }
|
||||
@property void windowOrContentResizeMode(WindowOrContentResizeMode newMode) {
|
||||
_windowOrContentResizeMode = newMode;
|
||||
if (_mainWidget) {
|
||||
_mainWidget.measure(SIZE_UNSPECIFIED, SIZE_UNSPECIFIED);
|
||||
adjustWindowOrContentSize(_mainWidget.measuredWidth, _mainWidget.measuredHeight);
|
||||
}
|
||||
}
|
||||
|
||||
// Abstract methods : override in platform implementation
|
||||
|
||||
/// show window
|
||||
abstract void show();
|
||||
|
@ -304,26 +338,168 @@ class Window : CustomEventTarget {
|
|||
/// set window rectangle
|
||||
bool moveAndResizeWindow(Rect rc, bool activate = false) { return setWindowState(WindowState.unspecified, activate, rc); }
|
||||
|
||||
// things needed for WindowOrContentResizeMode.scrollWindow:
|
||||
/// vertical scrollbar control
|
||||
protected ScrollBar _vScrollBar = null;
|
||||
/// horizontal scrollbar control
|
||||
protected ScrollBar _hScrollBar = null;
|
||||
|
||||
/// Sets the minimal content size and adjust window or content should be called from window show
|
||||
void adjustWindowOrContentSize(int minContentWidth, int minContentHeight) {
|
||||
_minContentWidth = minContentWidth;
|
||||
_minContentHeight = minContentHeight;
|
||||
if (_windowOrContentResizeMode == WindowOrContentResizeMode.resizeWindow)
|
||||
resizeWindow(Point(minContentWidth, minContentHeight));
|
||||
updateWindowOrContentSize();
|
||||
}
|
||||
|
||||
/// update current content size based on windowOrContentResizeMode flag, usually used when window is resized
|
||||
void updateWindowOrContentSize() {
|
||||
final switch (_windowOrContentResizeMode) {
|
||||
case WindowOrContentResizeMode.shrinkWidgets: {
|
||||
_currentContentWidth = _windowRect.right;
|
||||
_currentContentHeight = _windowRect.bottom;
|
||||
return;
|
||||
}
|
||||
case WindowOrContentResizeMode.resizeWindow: {
|
||||
//maybe should not permit to resize when new window size is smaller than content size, now do nothing
|
||||
_currentContentWidth = _windowRect.right;
|
||||
_currentContentHeight = _windowRect.bottom;
|
||||
break;
|
||||
}
|
||||
case WindowOrContentResizeMode.scrollWindow: {
|
||||
if (_windowRect.right < _minContentWidth) {
|
||||
// create scrollbar
|
||||
_currentContentWidth = _minContentWidth;
|
||||
if (!_hScrollBar) {
|
||||
_hScrollBar = new ScrollBar(null,Orientation.Horizontal);
|
||||
_hScrollBar.scrollEvent = delegate bool (AbstractSlider source, ScrollEvent event) {
|
||||
if (event.action == ScrollAction.SliderMoved || event.action == ScrollAction.SliderReleased)
|
||||
requestLayout();
|
||||
else if (event.action == ScrollAction.PageUp) {
|
||||
source.position = max(0, source.position - _windowRect.right * 3 / 4);
|
||||
requestLayout();
|
||||
} else if (event.action == ScrollAction.PageDown) {
|
||||
source.position = min(source.maxValue - _windowRect.right, source.position + _windowRect.right *3 / 4);
|
||||
requestLayout();
|
||||
} else if (event.action == ScrollAction.LineUp) {
|
||||
source.position = max(0, source.position - _windowRect.right / 10);
|
||||
requestLayout();
|
||||
} else if (event.action == ScrollAction.LineDown) {
|
||||
source.position = min(source.maxValue - _windowRect.right, source.position + _windowRect.right / 10);
|
||||
requestLayout();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
_hScrollBar.measure(_windowRect.right, _windowRect.bottom);
|
||||
if (windowRect().bottom < _minContentHeight)
|
||||
_hScrollBar.setRange(0, _minContentWidth + _hScrollBar.measuredHeight);
|
||||
else
|
||||
_hScrollBar.setRange(0, _minContentWidth);
|
||||
_hScrollBar.pageSize(_windowRect.right);
|
||||
_hScrollBar.position(0);
|
||||
}
|
||||
else {
|
||||
if (_hScrollBar) {
|
||||
destroy(_hScrollBar);
|
||||
_hScrollBar = null;
|
||||
}
|
||||
_currentContentWidth = _windowRect.right;
|
||||
}
|
||||
|
||||
if (windowRect().bottom < _minContentHeight) {
|
||||
// create scrollbar
|
||||
_currentContentHeight = _minContentHeight;
|
||||
if (!_vScrollBar) {
|
||||
_vScrollBar = new ScrollBar(null,Orientation.Vertical);
|
||||
_vScrollBar.scrollEvent = delegate bool (AbstractSlider source, ScrollEvent event) {
|
||||
if (event.action == ScrollAction.SliderMoved || event.action == ScrollAction.SliderReleased)
|
||||
requestLayout();
|
||||
else if (event.action == ScrollAction.PageUp) {
|
||||
source.position = max(0, source.position - _windowRect.bottom * 3 / 4);
|
||||
requestLayout();
|
||||
} else if (event.action == ScrollAction.PageDown) {
|
||||
source.position = min(source.maxValue - _windowRect.bottom, source.position + _windowRect.bottom *3 / 4);
|
||||
requestLayout();
|
||||
} else if (event.action == ScrollAction.LineUp) {
|
||||
source.position = max(0, source.position - _windowRect.bottom / 10);
|
||||
requestLayout();
|
||||
} else if (event.action == ScrollAction.LineDown) {
|
||||
source.position = min(source.maxValue - _windowRect.bottom, source.position + _windowRect.bottom / 10);
|
||||
requestLayout();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
_vScrollBar.measure(_windowRect.right, _windowRect.bottom);
|
||||
if (_hScrollBar)
|
||||
_vScrollBar.setRange(0, _minContentHeight+_hScrollBar.measuredHeight);
|
||||
else
|
||||
_vScrollBar.setRange(0, _minContentHeight);
|
||||
_vScrollBar.pageSize(windowRect().bottom);
|
||||
_vScrollBar.position(0);
|
||||
|
||||
if (!_hScrollBar)
|
||||
_currentContentWidth = _windowRect.right - _vScrollBar.measuredWidth;
|
||||
}
|
||||
else {
|
||||
if (_vScrollBar) {
|
||||
destroy(_vScrollBar);
|
||||
_vScrollBar = null;
|
||||
}
|
||||
_currentContentHeight = _hScrollBar ? _windowRect.bottom - _hScrollBar.measuredHeight : _windowRect.bottom;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// requests layout for main widget and popups
|
||||
void requestLayout() {
|
||||
if (_mainWidget)
|
||||
_mainWidget.requestLayout();
|
||||
if (_hScrollBar)
|
||||
_hScrollBar.requestLayout();
|
||||
if (_vScrollBar)
|
||||
_vScrollBar.requestLayout();
|
||||
foreach(p; _popups)
|
||||
p.requestLayout();
|
||||
if (_tooltip.popup)
|
||||
_tooltip.popup.requestLayout();
|
||||
}
|
||||
void measure() {
|
||||
if (_hScrollBar)
|
||||
_hScrollBar.measure(_dx, _dy);
|
||||
|
||||
if (_vScrollBar)
|
||||
_vScrollBar.measure(_dx, _dy);
|
||||
|
||||
if (_mainWidget !is null) {
|
||||
_mainWidget.measure(_dx, _dy);
|
||||
_mainWidget.measure(_currentContentWidth, _currentContentHeight);
|
||||
}
|
||||
foreach(p; _popups)
|
||||
p.measure(_dx, _dy);
|
||||
p.measure(_currentContentWidth, _currentContentHeight);
|
||||
if (_tooltip.popup)
|
||||
_tooltip.popup.measure(_dx, _dy);
|
||||
_tooltip.popup.measure(_currentContentWidth, _currentContentHeight);
|
||||
}
|
||||
void layout() {
|
||||
Rect rc = Rect(0, 0, _dx, _dy);
|
||||
if (_hScrollBar)
|
||||
_hScrollBar.layout(Rect(0, _dy - _hScrollBar.measuredHeight, _vScrollBar ? _dx - _vScrollBar.measuredWidth : _dx, _dy));
|
||||
|
||||
if (_vScrollBar)
|
||||
_vScrollBar.layout(Rect(_dx - _vScrollBar.measuredWidth, 0, _dx, _hScrollBar ? _dy - _hScrollBar.measuredHeight : _dy));
|
||||
|
||||
int deltaX = 0;
|
||||
if (_hScrollBar)
|
||||
deltaX = -_hScrollBar.position;
|
||||
|
||||
int deltaY = 0;
|
||||
if (_vScrollBar)
|
||||
deltaY = -_vScrollBar.position;
|
||||
|
||||
Rect rc = Rect(deltaX, deltaY, _currentContentWidth + deltaX, _currentContentHeight + deltaY);
|
||||
if (_mainWidget !is null) {
|
||||
_mainWidget.layout(rc);
|
||||
}
|
||||
|
@ -337,9 +513,13 @@ class Window : CustomEventTarget {
|
|||
return;
|
||||
_dx = width;
|
||||
_dy = height;
|
||||
// fix window rect for platforms that don't set it yet
|
||||
_windowRect.right = width;
|
||||
_windowRect.bottom = height;
|
||||
if (_mainWidget !is null) {
|
||||
Log.d("onResize ", _dx, "x", _dy);
|
||||
long measureStart = currentTimeMillis;
|
||||
updateWindowOrContentSize();
|
||||
measure();
|
||||
//Log.d("measured size: ", _mainWidget.measuredWidth, "x", _mainWidget.measuredHeight);
|
||||
long measureEnd = currentTimeMillis;
|
||||
|
@ -496,7 +676,7 @@ class Window : CustomEventTarget {
|
|||
return null;
|
||||
}
|
||||
|
||||
/// returns true if widget is child of either main widget or one of popups
|
||||
/// returns true if widget is child of either main widget, one of popups or window scrollbar
|
||||
bool isChild(Widget w) {
|
||||
if (_mainWidget !is null && _mainWidget.isChild(w))
|
||||
return true;
|
||||
|
@ -506,6 +686,10 @@ class Window : CustomEventTarget {
|
|||
if (_tooltip.popup)
|
||||
if (_tooltip.popup.isChild(w))
|
||||
return true;
|
||||
if (_hScrollBar !is null && _hScrollBar.isChild(w))
|
||||
return true;
|
||||
if (_vScrollBar !is null && _vScrollBar.isChild(w))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -533,6 +717,14 @@ class Window : CustomEventTarget {
|
|||
destroy(_mainWidget);
|
||||
_mainWidget = null;
|
||||
}
|
||||
if (_hScrollBar) {
|
||||
destroy(_hScrollBar);
|
||||
_hScrollBar = null;
|
||||
}
|
||||
if (_vScrollBar) {
|
||||
destroy(_vScrollBar);
|
||||
_vScrollBar = null;
|
||||
}
|
||||
destroy(_eventList);
|
||||
destroy(_timerQueue);
|
||||
_eventList = null;
|
||||
|
@ -627,6 +819,13 @@ class Window : CustomEventTarget {
|
|||
if (_tooltip.popup)
|
||||
_tooltip.popup.onDraw(buf);
|
||||
|
||||
if (_hScrollBar)
|
||||
_hScrollBar.onDraw(buf);
|
||||
if (_vScrollBar)
|
||||
_vScrollBar.onDraw(buf);
|
||||
if (_hScrollBar && _vScrollBar)
|
||||
buf.fillRect(Rect(_vScrollBar.left, _hScrollBar.top, buf.width, buf.height), _backgroundColor);
|
||||
|
||||
long drawEnd = currentTimeMillis;
|
||||
debug(DebugRedraw) {
|
||||
if (drawEnd - drawStart > PERFORMANCE_LOGGING_THRESHOLD_MS)
|
||||
|
@ -931,9 +1130,13 @@ class Window : CustomEventTarget {
|
|||
|
||||
/// handle theme change: e.g. reload some themed resources
|
||||
void dispatchThemeChanged() {
|
||||
if (_hScrollBar)
|
||||
_hScrollBar.onThemeChanged();
|
||||
if (_vScrollBar)
|
||||
_vScrollBar.onThemeChanged();
|
||||
if (_mainWidget)
|
||||
_mainWidget.onThemeChanged();
|
||||
// draw popups
|
||||
// draw popups
|
||||
foreach(p; _popups) {
|
||||
p.onThemeChanged();
|
||||
}
|
||||
|
@ -1128,10 +1331,23 @@ class Window : CustomEventTarget {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
if (!modal)
|
||||
res = dispatchMouseEvent(_mainWidget, event, cursorIsSet);
|
||||
else
|
||||
res = dispatchMouseEvent(modal, event, cursorIsSet);
|
||||
if (!modal) {
|
||||
res = false;
|
||||
if (_hScrollBar)
|
||||
res = dispatchMouseEvent(_hScrollBar, event, cursorIsSet);
|
||||
if (!res && _vScrollBar)
|
||||
res = dispatchMouseEvent(_vScrollBar, event, cursorIsSet);
|
||||
if (!res)
|
||||
res = dispatchMouseEvent(_mainWidget, event, cursorIsSet);
|
||||
}
|
||||
else {
|
||||
if (_hScrollBar)
|
||||
res = dispatchMouseEvent(_hScrollBar, event, cursorIsSet);
|
||||
if (!res && _vScrollBar)
|
||||
res = dispatchMouseEvent(_vScrollBar, event, cursorIsSet);
|
||||
if (!res)
|
||||
res = dispatchMouseEvent(modal, event, cursorIsSet);
|
||||
}
|
||||
}
|
||||
return res || processed || _mainWidget.needDraw;
|
||||
}
|
||||
|
@ -1184,6 +1400,10 @@ class Window : CustomEventTarget {
|
|||
if (_mainWidget is null)
|
||||
return false;
|
||||
checkUpdateNeeded(_mainWidget, needDraw, needLayout, animationActive);
|
||||
if (_hScrollBar)
|
||||
checkUpdateNeeded(_hScrollBar, needDraw, needLayout, animationActive);
|
||||
if (_vScrollBar)
|
||||
checkUpdateNeeded(_vScrollBar, needDraw, needLayout, animationActive);
|
||||
foreach(p; _popups)
|
||||
checkUpdateNeeded(p, needDraw, needLayout, animationActive);
|
||||
if (_tooltip.popup)
|
||||
|
|
|
@ -350,16 +350,15 @@ class SDLWindow : Window {
|
|||
Log.e("Window is shown without main widget");
|
||||
_mainWidget = new Widget();
|
||||
}
|
||||
if (_mainWidget && !(_flags & WindowFlag.Resizable)) {
|
||||
if (_mainWidget) {
|
||||
_mainWidget.measure(SIZE_UNSPECIFIED, SIZE_UNSPECIFIED);
|
||||
SDL_SetWindowSize(_win, _mainWidget.measuredWidth, _mainWidget.measuredHeight);
|
||||
adjustWindowOrContentSize(_mainWidget.measuredWidth, _mainWidget.measuredHeight);
|
||||
}
|
||||
|
||||
SDL_ShowWindow(_win);
|
||||
if (_mainWidget)
|
||||
_mainWidget.setFocus();
|
||||
fixSize();
|
||||
//update(true);
|
||||
//redraw();
|
||||
SDL_RaiseWindow(_win);
|
||||
invalidate();
|
||||
}
|
||||
|
|
|
@ -432,17 +432,13 @@ class Win32Window : Window {
|
|||
_mainWidget = new Widget();
|
||||
}
|
||||
ReleaseCapture();
|
||||
if (!(_flags & WindowFlag.Resizable) && _mainWidget) {
|
||||
|
||||
if (_mainWidget) {
|
||||
_mainWidget.measure(SIZE_UNSPECIFIED, SIZE_UNSPECIFIED);
|
||||
int dx = _mainWidget.measuredWidth;
|
||||
int dy = _mainWidget.measuredHeight;
|
||||
dx += 2 * GetSystemMetrics(SM_CXDLGFRAME);
|
||||
dy += GetSystemMetrics(SM_CYCAPTION) + 2 * GetSystemMetrics(SM_CYDLGFRAME);
|
||||
// TODO: ensure size less than screen size
|
||||
SetWindowPos(_hwnd, HWND_TOP, 0, 0, dx, dy, SWP_NOMOVE| SWP_SHOWWINDOW);
|
||||
} else {
|
||||
ShowWindow(_hwnd, SW_SHOWNORMAL);
|
||||
adjustWindowOrContentSize(_mainWidget.measuredWidth, _mainWidget.measuredHeight);
|
||||
}
|
||||
|
||||
ShowWindow(_hwnd, SW_SHOWNORMAL);
|
||||
if (_mainWidget)
|
||||
_mainWidget.setFocus();
|
||||
SetFocus(_hwnd);
|
||||
|
|
|
@ -428,8 +428,13 @@ class X11Window : DWindow {
|
|||
Log.d("Open GL support is disabled");
|
||||
}
|
||||
}
|
||||
if (_mainWidget)
|
||||
_mainWidget.setFocus();
|
||||
if (_mainWidget) {
|
||||
_mainWidget.measure(SIZE_UNSPECIFIED, SIZE_UNSPECIFIED);
|
||||
_windowRect.right = _dx;// hack to set windowRect, remove when _windowRect will be full supported on X11
|
||||
_windowRect.bottom = _dy;
|
||||
adjustWindowOrContentSize(_mainWidget.measuredWidth, _mainWidget.measuredHeight);
|
||||
_mainWidget.setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
protected final void changeWindowState(int action, Atom firstProperty, Atom secondProperty = None) nothrow
|
||||
|
@ -1537,6 +1542,13 @@ class X11Platform : Platform {
|
|||
w.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
/// handle theme change: e.g. reload some themed resources
|
||||
override void onThemeChanged() {
|
||||
foreach(w; _windowMap)
|
||||
w.dispatchThemeChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
import core.thread;
|
||||
|
|
|
@ -1899,6 +1899,10 @@ class EditLine : EditWidgetBase {
|
|||
protected dstring _measuredText;
|
||||
protected int[] _measuredTextWidths;
|
||||
protected Point _measuredTextSize;
|
||||
|
||||
protected Point _measuredTextToSetWidgetSize;
|
||||
protected dstring _textToSetWidgetSize = "aaaaa"d;
|
||||
protected int[] _measuredTextToSetWidgetSizeWidths;
|
||||
|
||||
protected dchar _passwordChar = 0;
|
||||
/// password character - 0 for normal editor, some character, e.g. '*' to hide text by replacing all characters with this char
|
||||
|
@ -1972,17 +1976,27 @@ class EditLine : EditWidgetBase {
|
|||
//Point sz = font.textSize(text);
|
||||
_measuredText = applyPasswordChar(text);
|
||||
_measuredTextWidths.length = _measuredText.length;
|
||||
int charsMeasured = font.measureText(_measuredText, _measuredTextWidths, int.max, tabSize);
|
||||
int charsMeasured = font.measureText(_measuredText, _measuredTextWidths, MAX_WIDTH_UNSPECIFIED, tabSize);
|
||||
_measuredTextSize.x = charsMeasured > 0 ? _measuredTextWidths[charsMeasured - 1]: 0;
|
||||
_measuredTextSize.y = font.height;
|
||||
return _measuredTextSize;
|
||||
}
|
||||
|
||||
protected Point measureTextToSetWidgetSize() {
|
||||
FontRef font = font();
|
||||
_measuredTextToSetWidgetSizeWidths.length = _textToSetWidgetSize.length;
|
||||
int charsMeasured = font.measureText(_textToSetWidgetSize, _measuredTextToSetWidgetSizeWidths, MAX_WIDTH_UNSPECIFIED, tabSize);
|
||||
_measuredTextToSetWidgetSize.x = charsMeasured > 0 ? _measuredTextToSetWidgetSizeWidths[charsMeasured - 1]: 0;
|
||||
_measuredTextToSetWidgetSize.y = font.height;
|
||||
return _measuredTextToSetWidgetSize;
|
||||
}
|
||||
|
||||
/// measure
|
||||
override void measure(int parentWidth, int parentHeight) {
|
||||
updateFontProps();
|
||||
measureVisibleText();
|
||||
measuredContent(parentWidth, parentHeight, _measuredTextSize.x + _leftPaneWidth, _measuredTextSize.y);
|
||||
measureTextToSetWidgetSize();
|
||||
measuredContent(parentWidth, parentHeight, _measuredTextToSetWidgetSize.x + _leftPaneWidth, _measuredTextToSetWidgetSize.y);
|
||||
}
|
||||
|
||||
override bool handleAction(const Action a) {
|
||||
|
@ -2128,6 +2142,10 @@ class EditBox : EditWidgetBase {
|
|||
protected int[] _visibleLinesWidths; // width (in pixels) of visible lines
|
||||
protected CustomCharProps[][] _visibleLinesHighlights;
|
||||
protected CustomCharProps[][] _visibleLinesHighlightsBuf;
|
||||
|
||||
protected Point _measuredTextToSetWidgetSize;
|
||||
protected dstring _textToSetWidgetSize = "aaaaa/naaaaa"d;
|
||||
protected int[] _measuredTextToSetWidgetSizeWidths;
|
||||
|
||||
override protected int lineCount() {
|
||||
return _content.length;
|
||||
|
@ -2641,6 +2659,16 @@ class EditBox : EditWidgetBase {
|
|||
return textSz;
|
||||
}
|
||||
|
||||
// override to set minimum scrollwidget size - default 100x100
|
||||
override protected Point minimumVisibleContentSize() {
|
||||
FontRef font = font();
|
||||
_measuredTextToSetWidgetSizeWidths.length = _textToSetWidgetSize.length;
|
||||
int charsMeasured = font.measureText(_textToSetWidgetSize, _measuredTextToSetWidgetSizeWidths, MAX_WIDTH_UNSPECIFIED, tabSize);
|
||||
_measuredTextToSetWidgetSize.x = charsMeasured > 0 ? _measuredTextToSetWidgetSizeWidths[charsMeasured - 1]: 0;
|
||||
_measuredTextToSetWidgetSize.y = font.height;
|
||||
return _measuredTextToSetWidgetSize;
|
||||
}
|
||||
|
||||
/// measure
|
||||
override void measure(int parentWidth, int parentHeight) {
|
||||
if (visibility == Visibility.Gone) {
|
||||
|
@ -2657,8 +2685,6 @@ class EditBox : EditWidgetBase {
|
|||
}
|
||||
|
||||
super.measure(parentWidth, parentHeight);
|
||||
// do we need to add vsbwidth, hsbheight ???
|
||||
//measuredContent(parentWidth, parentHeight, textSz.x + vsbwidth, textSz.y + hsbheight);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1533,6 +1533,29 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler
|
|||
sz.y += _rowHeights[i];
|
||||
return sz;
|
||||
}
|
||||
|
||||
/// calculate minimum size of widget
|
||||
override Point minimumVisibleContentSize() {
|
||||
Point sz;
|
||||
if (_cols == 0 || _rows == 0) {
|
||||
sz.x = 100;
|
||||
sz.y = 100;
|
||||
return sz;
|
||||
}
|
||||
// width:
|
||||
if (_cols < 2)
|
||||
sz.x = _colWidths[0];
|
||||
else
|
||||
sz.x = _colWidths[0] + _colWidths[1];
|
||||
|
||||
// height
|
||||
if (_rows < 2)
|
||||
sz.y = _rowHeights[0];
|
||||
else
|
||||
sz.y = _rowHeights[0] + _rowHeights[1];
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
override protected void drawClient(DrawBuf buf) {
|
||||
if (!_cols || !_rows)
|
||||
|
|
|
@ -942,6 +942,11 @@ class ListWidget : WidgetGroup, OnScrollHandler, OnAdapterChangeHandler {
|
|||
if (_adapter)
|
||||
_adapter.onThemeChanged();
|
||||
}
|
||||
|
||||
/// sets minimum size for the list, override to change
|
||||
Point minimumVisibleContentSize() {
|
||||
return Point(100, 100);
|
||||
}
|
||||
|
||||
/// Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
|
||||
override void measure(int parentWidth, int parentHeight) {
|
||||
|
@ -953,6 +958,15 @@ class ListWidget : WidgetGroup, OnScrollHandler, OnAdapterChangeHandler {
|
|||
_itemSizes.length = itemCount;
|
||||
Rect m = margins;
|
||||
Rect p = padding;
|
||||
|
||||
// set widget area to small when first measure
|
||||
if (parentWidth == SIZE_UNSPECIFIED && parentHeight == SIZE_UNSPECIFIED)
|
||||
{
|
||||
Point sz = minimumVisibleContentSize;
|
||||
measuredContent(parentWidth, parentHeight, sz.x, sz.y);
|
||||
return;
|
||||
}
|
||||
|
||||
// calc size constraints for children
|
||||
int pwidth = parentWidth;
|
||||
int pheight = parentHeight;
|
||||
|
@ -1041,6 +1055,7 @@ class ListWidget : WidgetGroup, OnScrollHandler, OnAdapterChangeHandler {
|
|||
}
|
||||
}
|
||||
measuredContent(parentWidth, parentHeight, sz.x + _sbsz.x, sz.y + _sbsz.y);
|
||||
|
||||
if (_scrollbar.visibility == oldScrollbarVisibility) {
|
||||
_needLayout = oldNeedLayout;
|
||||
_scrollbar.cancelLayout();
|
||||
|
|
|
@ -273,6 +273,11 @@ class ScrollWidgetBase : WidgetGroup, OnScrollHandler {
|
|||
return sz;
|
||||
}
|
||||
|
||||
// override to set minimum scrollwidget size - default 100x100
|
||||
Point minimumVisibleContentSize() {
|
||||
return Point(100,100);
|
||||
}
|
||||
|
||||
/// Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
|
||||
override void measure(int parentWidth, int parentHeight) {
|
||||
if (visibility == Visibility.Gone) {
|
||||
|
@ -280,6 +285,7 @@ class ScrollWidgetBase : WidgetGroup, OnScrollHandler {
|
|||
}
|
||||
Rect m = margins;
|
||||
Rect p = padding;
|
||||
|
||||
// calc size constraints for children
|
||||
int pwidth = parentWidth;
|
||||
int pheight = parentHeight;
|
||||
|
@ -293,13 +299,14 @@ class ScrollWidgetBase : WidgetGroup, OnScrollHandler {
|
|||
if (_vscrollbar && _vscrollbarMode == ScrollBarMode.Visible) {
|
||||
_vscrollbar.measure(pwidth, pheight);
|
||||
}
|
||||
Point sz = fullContentSize();
|
||||
Point sz = minimumVisibleContentSize();
|
||||
if (_hscrollbar && _hscrollbarMode == ScrollBarMode.Visible) {
|
||||
sz.y += _hscrollbar.measuredHeight;
|
||||
}
|
||||
if (_vscrollbar && _vscrollbarMode == ScrollBarMode.Visible) {
|
||||
sz.x += _vscrollbar.measuredWidth;
|
||||
}
|
||||
|
||||
measuredContent(parentWidth, parentHeight, sz.x, sz.y);
|
||||
}
|
||||
|
||||
|
|
|
@ -813,6 +813,10 @@ class TreeWidgetBase : ScrollWidget, OnTreeContentChangeListener, OnTreeStateCh
|
|||
super.layout(rc);
|
||||
}
|
||||
|
||||
override Point minimumVisibleContentSize() {
|
||||
return Point(200,200);
|
||||
}
|
||||
|
||||
/// Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
|
||||
override void measure(int parentWidth, int parentHeight) {
|
||||
if (visibility == Visibility.Gone) {
|
||||
|
|
Loading…
Reference in New Issue