mirror of https://github.com/buggins/dlangui.git
Merge pull request #498 from dayllenger/optimizations
Measure & layout optimizations
This commit is contained in:
commit
513a98a332
|
@ -513,6 +513,55 @@ struct Ref(T) { // if (T is RefCountedObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
This struct allows to not execute some code if some variables was not changed since the last check.
|
||||||
|
Used for optimizations.
|
||||||
|
|
||||||
|
Reference types, arrays and pointers are compared by reference.
|
||||||
|
*/
|
||||||
|
struct CalcSaver(Params...) {
|
||||||
|
import std.typecons : Tuple;
|
||||||
|
Tuple!Params values;
|
||||||
|
|
||||||
|
bool check(Params args) {
|
||||||
|
bool changed;
|
||||||
|
foreach (i, arg; args) {
|
||||||
|
if (values[i] !is arg) {
|
||||||
|
values[i] = arg;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
unittest {
|
||||||
|
|
||||||
|
class A { }
|
||||||
|
|
||||||
|
CalcSaver!(uint, double[], A) saver;
|
||||||
|
|
||||||
|
uint x = 5;
|
||||||
|
double[] arr = [1, 2, 3];
|
||||||
|
A a = new A();
|
||||||
|
|
||||||
|
assert(saver.check(x, arr, a));
|
||||||
|
// values are not changing
|
||||||
|
assert(!saver.check(x, arr, a));
|
||||||
|
assert(!saver.check(x, arr, a));
|
||||||
|
assert(!saver.check(x, arr, a));
|
||||||
|
assert(!saver.check(x, arr, a));
|
||||||
|
|
||||||
|
x = 8;
|
||||||
|
arr ~= 25;
|
||||||
|
a = new A();
|
||||||
|
// values are changed
|
||||||
|
assert(saver.check(x, arr, a));
|
||||||
|
assert(!saver.check(x, arr, a));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
// some utility functions
|
// some utility functions
|
||||||
|
|
||||||
|
|
|
@ -115,20 +115,26 @@ class TextWidget : Widget {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CalcSaver!(Font, dstring, uint, uint) _measureSaver;
|
||||||
|
|
||||||
override void measure(int parentWidth, int parentHeight) {
|
override void measure(int parentWidth, int parentHeight) {
|
||||||
FontRef font = font();
|
FontRef font = font();
|
||||||
//auto measureStart = std.datetime.Clock.currAppTick;
|
uint w = (maxLines == 1) ? MAX_WIDTH_UNSPECIFIED :
|
||||||
Point sz;
|
parentWidth - margins.left - margins.right - padding.left - padding.right;
|
||||||
if (maxLines == 1) {
|
uint flags = textFlags;
|
||||||
sz = font.textSize(text, MAX_WIDTH_UNSPECIFIED, 4, 0, textFlags);
|
|
||||||
} else {
|
// optimization: do not measure if nothing changed
|
||||||
sz = font.measureMultilineText(text,maxLines,parentWidth-margins.left-margins.right-padding.left-padding.right, 4, 0, textFlags);
|
if (_measureSaver.check(font.get, text, w, flags) || _needLayout) {
|
||||||
|
Point sz;
|
||||||
|
if (maxLines == 1) {
|
||||||
|
sz = font.textSize(text, w, 4, 0, flags);
|
||||||
|
} else {
|
||||||
|
sz = font.measureMultilineText(text, maxLines, w, 4, 0, flags);
|
||||||
|
}
|
||||||
|
// it's not very correct, but in such simple widget it doesn't make issues
|
||||||
|
measuredContent(SIZE_UNSPECIFIED, SIZE_UNSPECIFIED, sz.x, sz.y);
|
||||||
|
_needLayout = false;
|
||||||
}
|
}
|
||||||
//auto measureEnd = std.datetime.Clock.currAppTick;
|
|
||||||
//auto duration = measureEnd - measureStart;
|
|
||||||
//if (duration.length > 10)
|
|
||||||
// Log.d("TextWidget measureText took ", duration.length, " ticks");
|
|
||||||
measuredContent(parentWidth, parentHeight, sz.x, sz.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override void onDraw(DrawBuf buf) {
|
override void onDraw(DrawBuf buf) {
|
||||||
|
|
|
@ -643,7 +643,7 @@ class FrameLayout : WidgetGroupDefaultDrawing {
|
||||||
applyPadding(rc);
|
applyPadding(rc);
|
||||||
for (int i = 0; i < _children.count; i++) {
|
for (int i = 0; i < _children.count; i++) {
|
||||||
Widget item = _children.get(i);
|
Widget item = _children.get(i);
|
||||||
if (item.visibility != Visibility.Gone) {
|
if (item.visibility == Visibility.Visible) {
|
||||||
item.layout(rc);
|
item.layout(rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -657,6 +657,7 @@ class FrameLayout : WidgetGroupDefaultDrawing {
|
||||||
Widget item = _children.get(i);
|
Widget item = _children.get(i);
|
||||||
if (item.compareId(ID)) {
|
if (item.compareId(ID)) {
|
||||||
item.visibility = Visibility.Visible;
|
item.visibility = Visibility.Visible;
|
||||||
|
item.requestLayout();
|
||||||
foundWidget = item;
|
foundWidget = item;
|
||||||
found = true;
|
found = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue