mirror of https://github.com/buggins/dlangui.git
Merge pull request #491 from dayllenger/memoize
Powerful optimization: memoize
This commit is contained in:
commit
33a7501bb9
|
@ -74,11 +74,11 @@ enum FontWeight : int {
|
||||||
Bold = 800
|
Bold = 800
|
||||||
}
|
}
|
||||||
|
|
||||||
immutable dchar UNICODE_SOFT_HYPHEN_CODE = 0x00ad;
|
enum dchar UNICODE_SOFT_HYPHEN_CODE = 0x00ad;
|
||||||
immutable dchar UNICODE_ZERO_WIDTH_SPACE = 0x200b;
|
enum dchar UNICODE_ZERO_WIDTH_SPACE = 0x200b;
|
||||||
immutable dchar UNICODE_NO_BREAK_SPACE = 0x00a0;
|
enum dchar UNICODE_NO_BREAK_SPACE = 0x00a0;
|
||||||
immutable dchar UNICODE_HYPHEN = 0x2010;
|
enum dchar UNICODE_HYPHEN = 0x2010;
|
||||||
immutable dchar UNICODE_NB_HYPHEN = 0x2011;
|
enum dchar UNICODE_NB_HYPHEN = 0x2011;
|
||||||
|
|
||||||
/// custom character properties - for char-by-char drawing of text string with different character color and style
|
/// custom character properties - for char-by-char drawing of text string with different character color and style
|
||||||
struct CustomCharProps {
|
struct CustomCharProps {
|
||||||
|
@ -124,7 +124,7 @@ static if (ENABLE_OPENGL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// constant for measureText maxWidth paramenter - to tell that all characters of text string should be measured.
|
/// constant for measureText maxWidth paramenter - to tell that all characters of text string should be measured.
|
||||||
immutable int MAX_WIDTH_UNSPECIFIED = int.max;
|
enum int MAX_WIDTH_UNSPECIFIED = int.max;
|
||||||
|
|
||||||
/** Instance of font with specific size, weight, face, etc.
|
/** Instance of font with specific size, weight, face, etc.
|
||||||
*
|
*
|
||||||
|
@ -322,13 +322,20 @@ class Font : RefCountedObject {
|
||||||
* tabOffset = when string is drawn not from left position, use to move tab stops left/right
|
* tabOffset = when string is drawn not from left position, use to move tab stops left/right
|
||||||
* textFlags = TextFlag bit set - to control underline, hotkey label processing, etc...
|
* textFlags = TextFlag bit set - to control underline, hotkey label processing, etc...
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
Point textSize(const dchar[] text, int maxWidth = MAX_WIDTH_UNSPECIFIED, int tabSize = 4, int tabOffset = 0, uint textFlags = 0) {
|
Point textSize(dstring text, int maxWidth = MAX_WIDTH_UNSPECIFIED, int tabSize = 4, int tabOffset = 0, uint textFlags = 0) {
|
||||||
if (_textSizeBuffer.length < text.length + 1)
|
return textSizeMemoized(this, text, maxWidth, tabSize, tabOffset, textFlags);
|
||||||
_textSizeBuffer.length = text.length + 1;
|
}
|
||||||
int charsMeasured = measureText(text, _textSizeBuffer, maxWidth, tabSize, tabOffset, textFlags);
|
|
||||||
|
import std.functional;
|
||||||
|
alias textSizeMemoized = memoize!(Font.textSizeImpl);
|
||||||
|
|
||||||
|
static Point textSizeImpl(Font font, const dchar[] text, int maxWidth = MAX_WIDTH_UNSPECIFIED, int tabSize = 4, int tabOffset = 0, uint textFlags = 0) {
|
||||||
|
if (font._textSizeBuffer.length < text.length + 1)
|
||||||
|
font._textSizeBuffer.length = text.length + 1;
|
||||||
|
int charsMeasured = font.measureText(text, font._textSizeBuffer, maxWidth, tabSize, tabOffset, textFlags);
|
||||||
if (charsMeasured < 1)
|
if (charsMeasured < 1)
|
||||||
return Point(0,0);
|
return Point(0,0);
|
||||||
return Point(_textSizeBuffer[charsMeasured - 1], height);
|
return Point(font._textSizeBuffer[charsMeasured - 1], font.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************************
|
/*****************************************************************************************
|
||||||
|
|
|
@ -622,7 +622,11 @@ private void FillColor(uint color, Color[] buf_slice) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float[] convertColors(uint[] cols) pure nothrow {
|
|
||||||
|
import std.functional;
|
||||||
|
alias convertColors = memoize!(convertColorsImpl);
|
||||||
|
|
||||||
|
float[] convertColorsImpl(uint[] cols) pure nothrow {
|
||||||
float[] colors;
|
float[] colors;
|
||||||
colors.length = cols.length * 4;
|
colors.length = cols.length * 4;
|
||||||
foreach(i; 0 .. cols.length) {
|
foreach(i; 0 .. cols.length) {
|
||||||
|
|
|
@ -410,7 +410,7 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
|
||||||
foreach(ref ch; s)
|
foreach(ref ch; s)
|
||||||
ch = '9';
|
ch = '9';
|
||||||
FontRef fnt = font;
|
FontRef fnt = font;
|
||||||
Point sz = fnt.textSize(s);
|
Point sz = fnt.textSize(cast(immutable)s);
|
||||||
_lineNumbersWidth = sz.x;
|
_lineNumbersWidth = sz.x;
|
||||||
}
|
}
|
||||||
_leftPaneWidth = _lineNumbersWidth + _modificationMarksWidth + _foldingWidth + _iconsWidth;
|
_leftPaneWidth = _lineNumbersWidth + _modificationMarksWidth + _foldingWidth + _iconsWidth;
|
||||||
|
@ -765,7 +765,7 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
|
||||||
return _wantTabs;
|
return _wantTabs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// sets tab size (in number of spaces)
|
/// ditto
|
||||||
@property EditWidgetBase wantTabs(bool wantTabs) {
|
@property EditWidgetBase wantTabs(bool wantTabs) {
|
||||||
_wantTabs = wantTabs;
|
_wantTabs = wantTabs;
|
||||||
return this;
|
return this;
|
||||||
|
@ -1884,7 +1884,6 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
|
||||||
EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, [event.text]);
|
EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, [event.text]);
|
||||||
_content.performOperation(op, this);
|
_content.performOperation(op, this);
|
||||||
}
|
}
|
||||||
if (focused) startCaretBlinking();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1894,9 +1893,7 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
|
||||||
//if (event.keyCode == KeyCode.RETURN && !readOnly && !_content.multiline) {
|
//if (event.keyCode == KeyCode.RETURN && !readOnly && !_content.multiline) {
|
||||||
// return true;
|
// return true;
|
||||||
//}
|
//}
|
||||||
bool res = super.onKeyEvent(event);
|
return super.onKeyEvent(event);
|
||||||
//if (focused) startCaretBlinking();
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle Ctrl + Left mouse click on text
|
/// Handle Ctrl + Left mouse click on text
|
||||||
|
@ -2166,6 +2163,9 @@ class EditLine : EditWidgetBase {
|
||||||
|
|
||||||
/// measure
|
/// measure
|
||||||
override void measure(int parentWidth, int parentHeight) {
|
override void measure(int parentWidth, int parentHeight) {
|
||||||
|
if (visibility == Visibility.Gone)
|
||||||
|
return;
|
||||||
|
|
||||||
updateFontProps();
|
updateFontProps();
|
||||||
measureVisibleText();
|
measureVisibleText();
|
||||||
measureTextToSetWidgetSize();
|
measureTextToSetWidgetSize();
|
||||||
|
@ -2242,11 +2242,9 @@ class EditLine : EditWidgetBase {
|
||||||
// line inside selection
|
// line inside selection
|
||||||
Rect startrc = textPosToClient(_selectionRange.start);
|
Rect startrc = textPosToClient(_selectionRange.start);
|
||||||
Rect endrc = textPosToClient(_selectionRange.end);
|
Rect endrc = textPosToClient(_selectionRange.end);
|
||||||
int startx = startrc.left + _clientRect.left;
|
|
||||||
int endx = endrc.left + _clientRect.left;
|
|
||||||
Rect rc = lineRect;
|
Rect rc = lineRect;
|
||||||
rc.left = startx;
|
rc.left = startrc.left + _clientRect.left;
|
||||||
rc.right = endx;
|
rc.right = endrc.left + _clientRect.left;
|
||||||
if (!rc.empty) {
|
if (!rc.empty) {
|
||||||
// draw selection rect for line
|
// draw selection rect for line
|
||||||
buf.fillRect(rc, focused ? _selectionColorFocused : _selectionColorNormal);
|
buf.fillRect(rc, focused ? _selectionColorFocused : _selectionColorNormal);
|
||||||
|
@ -2269,17 +2267,11 @@ class EditLine : EditWidgetBase {
|
||||||
applyMargins(rc);
|
applyMargins(rc);
|
||||||
applyPadding(rc);
|
applyPadding(rc);
|
||||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||||
|
|
||||||
FontRef font = font();
|
FontRef font = font();
|
||||||
dstring txt = applyPasswordChar(text);
|
dstring txt = applyPasswordChar(text);
|
||||||
Point sz = font.textSize(txt);
|
|
||||||
//applyAlign(rc, sz);
|
drawLineBackground(buf, _clientRect, _clientRect);
|
||||||
Rect lineRect = _clientRect;
|
|
||||||
lineRect.left = _clientRect.left - _scrollPos.x;
|
|
||||||
lineRect.right = lineRect.left + calcLineWidth(txt);
|
|
||||||
Rect visibleRect = lineRect;
|
|
||||||
visibleRect.left = _clientRect.left;
|
|
||||||
visibleRect.right = _clientRect.right;
|
|
||||||
drawLineBackground(buf, lineRect, visibleRect);
|
|
||||||
font.drawText(buf, rc.left - _scrollPos.x, rc.top, txt, textColor, tabSize);
|
font.drawText(buf, rc.left - _scrollPos.x, rc.top, txt, textColor, tabSize);
|
||||||
|
|
||||||
drawCaret(buf);
|
drawCaret(buf);
|
||||||
|
@ -2366,9 +2358,9 @@ class EditBox : EditWidgetBase {
|
||||||
|
|
||||||
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
||||||
override void layout(Rect rc) {
|
override void layout(Rect rc) {
|
||||||
if (visibility == Visibility.Gone) {
|
if (visibility == Visibility.Gone)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if (rc != _pos)
|
if (rc != _pos)
|
||||||
_contentChanged = true;
|
_contentChanged = true;
|
||||||
Rect contentRc = rc;
|
Rect contentRc = rc;
|
||||||
|
@ -2928,9 +2920,9 @@ class EditBox : EditWidgetBase {
|
||||||
|
|
||||||
/// measure
|
/// measure
|
||||||
override void measure(int parentWidth, int parentHeight) {
|
override void measure(int parentWidth, int parentHeight) {
|
||||||
if (visibility == Visibility.Gone) {
|
if (visibility == Visibility.Gone)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
updateFontProps();
|
updateFontProps();
|
||||||
updateMaxLineWidth();
|
updateMaxLineWidth();
|
||||||
int findPanelHeight;
|
int findPanelHeight;
|
||||||
|
@ -3341,7 +3333,7 @@ class EditBox : EditWidgetBase {
|
||||||
FontRef font = font();
|
FontRef font = font();
|
||||||
for (int i = 0; i < _visibleLines.length; i++) {
|
for (int i = 0; i < _visibleLines.length; i++) {
|
||||||
dstring txt = _visibleLines[i];
|
dstring txt = _visibleLines[i];
|
||||||
Rect lineRect = rc;
|
Rect lineRect;
|
||||||
lineRect.left = _clientRect.left - _scrollPos.x;
|
lineRect.left = _clientRect.left - _scrollPos.x;
|
||||||
lineRect.right = lineRect.left + calcLineWidth(_content[_firstVisibleLine + i]);
|
lineRect.right = lineRect.left + calcLineWidth(_content[_firstVisibleLine + i]);
|
||||||
lineRect.top = _clientRect.top + i * _lineHeight;
|
lineRect.top = _clientRect.top + i * _lineHeight;
|
||||||
|
@ -3558,9 +3550,9 @@ class LogWidget : EditBox {
|
||||||
|
|
||||||
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
||||||
override void layout(Rect rc) {
|
override void layout(Rect rc) {
|
||||||
if (visibility == Visibility.Gone) {
|
if (visibility == Visibility.Gone)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
super.layout(rc);
|
super.layout(rc);
|
||||||
if (_scrollLock) {
|
if (_scrollLock) {
|
||||||
measureVisibleText();
|
measureVisibleText();
|
||||||
|
|
|
@ -53,6 +53,7 @@ class TabItem {
|
||||||
private UIString _label;
|
private UIString _label;
|
||||||
private UIString _tooltipText;
|
private UIString _tooltipText;
|
||||||
private long _lastAccessTs;
|
private long _lastAccessTs;
|
||||||
|
|
||||||
this(string id, string labelRes, string iconRes = null, dstring tooltipText = null) {
|
this(string id, string labelRes, string iconRes = null, dstring tooltipText = null) {
|
||||||
_id = id;
|
_id = id;
|
||||||
_label.id = labelRes;
|
_label.id = labelRes;
|
||||||
|
@ -73,6 +74,7 @@ class TabItem {
|
||||||
_lastAccessTs = _lastAccessCounter++;
|
_lastAccessTs = _lastAccessCounter++;
|
||||||
_tooltipText = UIString.fromRaw(tooltipText);
|
_tooltipText = UIString.fromRaw(tooltipText);
|
||||||
}
|
}
|
||||||
|
|
||||||
@property string iconId() const { return _iconRes; }
|
@property string iconId() const { return _iconRes; }
|
||||||
@property string id() const { return _id; }
|
@property string id() const { return _id; }
|
||||||
@property ref UIString text() { return _label; }
|
@property ref UIString text() { return _label; }
|
||||||
|
@ -83,6 +85,7 @@ class TabItem {
|
||||||
void updateAccessTs() {
|
void updateAccessTs() {
|
||||||
_lastAccessTs = _lastAccessCounter++; //std.datetime.Clock.currStdTime;
|
_lastAccessTs = _lastAccessCounter++; //std.datetime.Clock.currStdTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// tooltip text
|
/// tooltip text
|
||||||
@property dstring tooltipText() {
|
@property dstring tooltipText() {
|
||||||
if (_tooltipText.empty)
|
if (_tooltipText.empty)
|
||||||
|
@ -123,6 +126,7 @@ class TabItemWidget : HorizontalLayout {
|
||||||
Signal!TabCloseHandler tabClose;
|
Signal!TabCloseHandler tabClose;
|
||||||
@property TabItem tabItem() { return _item; }
|
@property TabItem tabItem() { return _item; }
|
||||||
@property TabControl tabControl() { return cast(TabControl)parent; }
|
@property TabControl tabControl() { return cast(TabControl)parent; }
|
||||||
|
|
||||||
this(TabItem item, bool enableCloseButton = true) {
|
this(TabItem item, bool enableCloseButton = true) {
|
||||||
styleId = STYLE_TAB_UP_BUTTON;
|
styleId = STYLE_TAB_UP_BUTTON;
|
||||||
_enableCloseButton = enableCloseButton;
|
_enableCloseButton = enableCloseButton;
|
||||||
|
@ -153,6 +157,7 @@ class TabItemWidget : HorizontalLayout {
|
||||||
if (_closeButton)
|
if (_closeButton)
|
||||||
_closeButton.tooltipText = _item.tooltipText;
|
_closeButton.tooltipText = _item.tooltipText;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// tooltip text - when not empty, widget will show tooltips automatically; for advanced tooltips - override hasTooltip and createTooltip
|
/// tooltip text - when not empty, widget will show tooltips automatically; for advanced tooltips - override hasTooltip and createTooltip
|
||||||
override @property dstring tooltipText() { return _item.tooltipText; }
|
override @property dstring tooltipText() { return _item.tooltipText; }
|
||||||
/// tooltip text - when not empty, widget will show tooltips automatically; for advanced tooltips - override hasTooltip and createTooltip
|
/// tooltip text - when not empty, widget will show tooltips automatically; for advanced tooltips - override hasTooltip and createTooltip
|
||||||
|
@ -180,10 +185,12 @@ class TabItemWidget : HorizontalLayout {
|
||||||
styleId = tabButtonStyle;
|
styleId = tabButtonStyle;
|
||||||
_label.styleId = tabButtonTextStyle;
|
_label.styleId = tabButtonTextStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
override void onDraw(DrawBuf buf) {
|
override void onDraw(DrawBuf buf) {
|
||||||
//debug Log.d("TabWidget.onDraw ", id);
|
//debug Log.d("TabWidget.onDraw ", id);
|
||||||
super.onDraw(buf);
|
super.onDraw(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool onClick(Widget source) {
|
protected bool onClick(Widget source) {
|
||||||
if (source.compareId("CLOSE")) {
|
if (source.compareId("CLOSE")) {
|
||||||
Log.d("tab close button pressed");
|
Log.d("tab close button pressed");
|
||||||
|
@ -192,6 +199,7 @@ class TabItemWidget : HorizontalLayout {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property TabItem item() {
|
@property TabItem item() {
|
||||||
return _item;
|
return _item;
|
||||||
}
|
}
|
||||||
|
@ -334,6 +342,7 @@ class TabControl : WidgetGroupDefaultDrawing {
|
||||||
styleId = _tabStyle;
|
styleId = _tabStyle;
|
||||||
addChild(_moreButton); // first child is always MORE button, the rest corresponds to tab list
|
addChild(_moreButton); // first child is always MORE button, the rest corresponds to tab list
|
||||||
}
|
}
|
||||||
|
|
||||||
void setStyles(string tabStyle, string tabButtonStyle, string tabButtonTextStyle) {
|
void setStyles(string tabStyle, string tabButtonStyle, string tabButtonTextStyle) {
|
||||||
_tabStyle = tabStyle;
|
_tabStyle = tabStyle;
|
||||||
_tabButtonStyle = tabButtonStyle;
|
_tabButtonStyle = tabButtonStyle;
|
||||||
|
@ -533,6 +542,7 @@ class TabControl : WidgetGroupDefaultDrawing {
|
||||||
TabItem item = new TabItem(id, label, iconId, tooltipText);
|
TabItem item = new TabItem(id, label, iconId, tooltipText);
|
||||||
return addTab(item, -1, enableCloseButton);
|
return addTab(item, -1, enableCloseButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MenuItem getMoreButtonPopupMenu() {
|
protected MenuItem getMoreButtonPopupMenu() {
|
||||||
if (moreButtonPopupMenu.assigned) {
|
if (moreButtonPopupMenu.assigned) {
|
||||||
if (auto menu = moreButtonPopupMenu(this)) {
|
if (auto menu = moreButtonPopupMenu(this)) {
|
||||||
|
@ -553,6 +563,7 @@ class TabControl : WidgetGroupDefaultDrawing {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// try to invoke popup menu, return true if popup menu is shown
|
/// try to invoke popup menu, return true if popup menu is shown
|
||||||
protected bool handleMorePopupMenu() {
|
protected bool handleMorePopupMenu() {
|
||||||
if (auto menu = getMoreButtonPopupMenu()) {
|
if (auto menu = getMoreButtonPopupMenu()) {
|
||||||
|
@ -567,6 +578,7 @@ class TabControl : WidgetGroupDefaultDrawing {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// override to handle specific actions
|
/// override to handle specific actions
|
||||||
override bool handleAction(const Action a) {
|
override bool handleAction(const Action a) {
|
||||||
if (a.id == StandardAction.TabSelectItem) {
|
if (a.id == StandardAction.TabSelectItem) {
|
||||||
|
@ -575,6 +587,7 @@ class TabControl : WidgetGroupDefaultDrawing {
|
||||||
}
|
}
|
||||||
return super.handleAction(a);
|
return super.handleAction(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool onMouse(Widget source, MouseEvent event) {
|
protected bool onMouse(Widget source, MouseEvent event) {
|
||||||
if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) {
|
if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) {
|
||||||
if (source.compareId("MORE")) {
|
if (source.compareId("MORE")) {
|
||||||
|
@ -594,6 +607,7 @@ class TabControl : WidgetGroupDefaultDrawing {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
|
/// Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
|
||||||
override void measure(int parentWidth, int parentHeight) {
|
override void measure(int parentWidth, int parentHeight) {
|
||||||
//Log.d("tabControl.measure enter");
|
//Log.d("tabControl.measure enter");
|
||||||
|
@ -627,6 +641,7 @@ class TabControl : WidgetGroupDefaultDrawing {
|
||||||
measuredContent(parentWidth, parentHeight, sz.x, sz.y);
|
measuredContent(parentWidth, parentHeight, sz.x, sz.y);
|
||||||
//Log.d("tabControl.measure exit");
|
//Log.d("tabControl.measure exit");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
||||||
override void layout(Rect rc) {
|
override void layout(Rect rc) {
|
||||||
//Log.d("tabControl.layout enter");
|
//Log.d("tabControl.layout enter");
|
||||||
|
@ -736,7 +751,6 @@ class TabControl : WidgetGroupDefaultDrawing {
|
||||||
if (tabChanged.assigned)
|
if (tabChanged.assigned)
|
||||||
tabChanged(_selectedTabId, previousSelectedTab);
|
tabChanged(_selectedTabId, previousSelectedTab);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// container for widgets controlled by TabControl
|
/// container for widgets controlled by TabControl
|
||||||
|
@ -799,6 +813,7 @@ class TabHost : FrameLayout, TabHandler {
|
||||||
requestLayout();
|
requestLayout();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// add new tab by id and label string
|
/// add new tab by id and label string
|
||||||
TabHost addTab(Widget widget, dstring label, string iconId = null, bool enableCloseButton = false, dstring tooltipText = null) {
|
TabHost addTab(Widget widget, dstring label, string iconId = null, bool enableCloseButton = false, dstring tooltipText = null) {
|
||||||
assert(_tabControl !is null, "No TabControl set for TabHost");
|
assert(_tabControl !is null, "No TabControl set for TabHost");
|
||||||
|
@ -810,6 +825,7 @@ class TabHost : FrameLayout, TabHandler {
|
||||||
addChild(widget);
|
addChild(widget);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// add new tab by id and label string resource id
|
/// add new tab by id and label string resource id
|
||||||
TabHost addTab(Widget widget, string labelResourceId, string iconId = null, bool enableCloseButton = false, dstring tooltipText = null) {
|
TabHost addTab(Widget widget, string labelResourceId, string iconId = null, bool enableCloseButton = false, dstring tooltipText = null) {
|
||||||
assert(_tabControl !is null, "No TabControl set for TabHost");
|
assert(_tabControl !is null, "No TabControl set for TabHost");
|
||||||
|
|
|
@ -366,7 +366,7 @@ public:
|
||||||
requestLayout();
|
requestLayout();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
immutable static int FOCUS_RECT_PADDING = 2;
|
static enum FOCUS_RECT_PADDING = 2;
|
||||||
/// get padding (between background bounds and content of widget)
|
/// get padding (between background bounds and content of widget)
|
||||||
@property Rect padding() const {
|
@property Rect padding() const {
|
||||||
// get max padding from style padding and background drawable padding
|
// get max padding from style padding and background drawable padding
|
||||||
|
@ -640,16 +640,16 @@ public:
|
||||||
/// returns widget visibility (Visible, Invisible, Gone)
|
/// returns widget visibility (Visible, Invisible, Gone)
|
||||||
@property Visibility visibility() { return _visibility; }
|
@property Visibility visibility() { return _visibility; }
|
||||||
/// sets widget visibility (Visible, Invisible, Gone)
|
/// sets widget visibility (Visible, Invisible, Gone)
|
||||||
@property Widget visibility(Visibility visible) {
|
@property Widget visibility(Visibility newVisibility) {
|
||||||
if (_visibility != visible) {
|
if (_visibility != newVisibility) {
|
||||||
if ((_visibility == Visibility.Gone) || (visible == Visibility.Gone)) {
|
if ((_visibility == Visibility.Gone) || (newVisibility == Visibility.Gone)) {
|
||||||
if (parent)
|
if (parent)
|
||||||
parent.requestLayout();
|
parent.requestLayout();
|
||||||
else
|
else
|
||||||
requestLayout();
|
requestLayout();
|
||||||
} else
|
} else
|
||||||
invalidate();
|
invalidate();
|
||||||
_visibility = visible;
|
_visibility = newVisibility;
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -868,9 +868,9 @@ public:
|
||||||
this.rect = widget.pos;
|
this.rect = widget.pos;
|
||||||
}
|
}
|
||||||
static if (BACKEND_GUI) {
|
static if (BACKEND_GUI) {
|
||||||
static immutable int NEAR_THRESHOLD = 10;
|
static enum NEAR_THRESHOLD = 10;
|
||||||
} else {
|
} else {
|
||||||
static immutable int NEAR_THRESHOLD = 1;
|
static enum NEAR_THRESHOLD = 1;
|
||||||
}
|
}
|
||||||
bool nearX(TabOrderInfo v) {
|
bool nearX(TabOrderInfo v) {
|
||||||
return v.rect.left >= rect.left - NEAR_THRESHOLD && v.rect.left <= rect.left + NEAR_THRESHOLD;
|
return v.rect.left >= rect.left - NEAR_THRESHOLD && v.rect.left <= rect.left + NEAR_THRESHOLD;
|
||||||
|
|
Loading…
Reference in New Issue