mirror of https://github.com/buggins/dlangui.git
Merge branch 'master' of https://github.com/buggins/dlangui into again_adding_WIDGET_STYLE_CONSOLE
This commit is contained in:
commit
3a97a60ee8
5
dub.json
5
dub.json
|
@ -38,7 +38,8 @@
|
|||
"./examples/tetris/",
|
||||
"./examples/opengl/",
|
||||
"./examples/ircclient/",
|
||||
"./examples/spreadsheet/"
|
||||
"./examples/spreadsheet/",
|
||||
"./examples/dragon/"
|
||||
],
|
||||
|
||||
"configurations": [
|
||||
|
@ -64,7 +65,7 @@
|
|||
{
|
||||
"name": "console",
|
||||
"versions": ["USE_CONSOLE", "EmbedStandardResources"],
|
||||
"excludedSourceFiles": ["3rdparty/*"]
|
||||
"excludedSourceFiles": ["3rdparty/*GL*", "3rdparty/android", "3rdparty/dimage", "3rdparty/fontconfig/*", "3rdparty/icontheme", "3rdparty/jni.d"]
|
||||
},
|
||||
{
|
||||
"name": "external",
|
||||
|
|
|
@ -8,36 +8,33 @@ import dlangui.widgets.scroll;
|
|||
|
||||
class DragonView : ScrollWidget {
|
||||
|
||||
int _scaleX;
|
||||
int _scaleY;
|
||||
int _middleX;
|
||||
int _middleY;
|
||||
int _dx;
|
||||
int _dy;
|
||||
int _x0;
|
||||
int _y0;
|
||||
int _length = 1000;
|
||||
int _dir0 = 0; // either 0 or 1
|
||||
int _straightLen = 10;
|
||||
int _roundLen = 4;
|
||||
uint _bgcolor = 0x101010;
|
||||
uint _grid1color = 0x303030;
|
||||
uint _grid2color = 0x202020;
|
||||
uint _grid3color = 0x181818;
|
||||
uint _curve1color = 0x4050FF;
|
||||
uint _curve2color = 0xFF4040;
|
||||
uint _curve3color = 0x30FF20;
|
||||
uint _curve4color = 0xC000D0;
|
||||
Point[8] _directionVectors = [
|
||||
Point(4, 0),
|
||||
Point(3, -3),
|
||||
Point(0, -4),
|
||||
Point(-3, -3),
|
||||
Point(-4, 0),
|
||||
Point(-3, 3),
|
||||
Point(0, 4),
|
||||
Point(3, 3),
|
||||
];
|
||||
private {
|
||||
int _scaleX;
|
||||
int _scaleY;
|
||||
int _middleX;
|
||||
int _middleY;
|
||||
int _dx;
|
||||
int _dy;
|
||||
int _x0;
|
||||
int _y0;
|
||||
int _length = 256;
|
||||
int _dir0 = 0; // either 0 or 1
|
||||
int _straightLen = 10;
|
||||
int _roundLen = 4;
|
||||
uint _bgcolor = 0x101010;
|
||||
uint _grid1color = 0x303030;
|
||||
uint _grid2color = 0x202020;
|
||||
uint _grid3color = 0x181818;
|
||||
uint _curve1color = 0x4050FF;
|
||||
uint _curve2color = 0xFF4040;
|
||||
uint _curve3color = 0x30C020;
|
||||
uint _curve4color = 0xC000D0;
|
||||
bool[4] _partVisible = [true, true, true, true];
|
||||
|
||||
bool _needRepaint = true;
|
||||
Point[8] _directionVectors;
|
||||
}
|
||||
|
||||
|
||||
ColorDrawBuf _drawBuf;
|
||||
|
||||
|
@ -55,7 +52,7 @@ class DragonView : ScrollWidget {
|
|||
_dy = dy;
|
||||
_fullScrollableArea.right = dx;
|
||||
_fullScrollableArea.bottom = dy;
|
||||
_visibleScrollableArea.left = dx / 2 - 300;
|
||||
_visibleScrollableArea.left = dx / 2 - 400;
|
||||
_visibleScrollableArea.top = dy / 2 - 300;
|
||||
_visibleScrollableArea.right = _visibleScrollableArea.left + 400;
|
||||
_visibleScrollableArea.bottom = _visibleScrollableArea.top + 400;
|
||||
|
@ -67,6 +64,7 @@ class DragonView : ScrollWidget {
|
|||
}
|
||||
_middleX = _fullScrollableArea.width / 2;
|
||||
_middleY = _fullScrollableArea.height / 2;
|
||||
_needRepaint = true;
|
||||
drawCurve();
|
||||
}
|
||||
|
||||
|
@ -111,6 +109,18 @@ class DragonView : ScrollWidget {
|
|||
}
|
||||
_x0 = vectors[1].x;
|
||||
_y0 = vectors[1].y;
|
||||
repaint();
|
||||
}
|
||||
|
||||
bool getPartVisible(int n) {
|
||||
return _partVisible[n & 3];
|
||||
}
|
||||
void setPartVisible(int n, bool flgVisible) {
|
||||
n = n & 3;
|
||||
if (_partVisible[n] != flgVisible) {
|
||||
_partVisible[n] = flgVisible;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@property int straightLen() {
|
||||
|
@ -120,7 +130,6 @@ class DragonView : ScrollWidget {
|
|||
if (_straightLen != n) {
|
||||
_straightLen = n;
|
||||
setVectors();
|
||||
drawCurve();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -131,7 +140,6 @@ class DragonView : ScrollWidget {
|
|||
if (_roundLen != n) {
|
||||
_roundLen = n;
|
||||
setVectors();
|
||||
drawCurve();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -141,26 +149,38 @@ class DragonView : ScrollWidget {
|
|||
@property DragonView length(int n) {
|
||||
if (_length != n) {
|
||||
_length = n;
|
||||
drawCurve();
|
||||
repaint();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
void repaint() {
|
||||
_needRepaint = true;
|
||||
invalidate();
|
||||
}
|
||||
@property int rotation() {
|
||||
return _dir0;
|
||||
}
|
||||
@property DragonView rotation(int angle) {
|
||||
if (_dir0 != (angle & 7)) {
|
||||
_dir0 = angle & 7;
|
||||
drawCurve();
|
||||
_needRepaint = true;
|
||||
repaint();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/// Draw widget at its position to buffer
|
||||
override void onDraw(DrawBuf buf) {
|
||||
if (_needRepaint)
|
||||
drawCurve();
|
||||
super.onDraw(buf);
|
||||
}
|
||||
|
||||
void drawLine(Point pt1, Point pt2, uint color) {
|
||||
pt1.x += _middleX;
|
||||
pt2.x += _middleX;
|
||||
pt1.y += _middleY;
|
||||
pt2.y += _middleY;
|
||||
pt1.y = _middleY - pt1.y;
|
||||
pt2.y = _middleY - pt2.y;
|
||||
_drawBuf.drawLine(pt1, pt2, color);
|
||||
}
|
||||
|
||||
|
@ -214,56 +234,63 @@ class DragonView : ScrollWidget {
|
|||
}
|
||||
|
||||
void drawSegment(ref Point currentPoint, ref int currentDir, int n, uint color, int mirror) {
|
||||
int mx = _middleX + _scaleX * 2;
|
||||
int my = _middleY + _scaleY * 2;
|
||||
bool insideView = currentPoint.x >= -mx && currentPoint.x <= mx && currentPoint.y >= -my && currentPoint.y <= my;
|
||||
int delta = getDirectionDelta(n) * mirror;
|
||||
Point nextPoint = currentPoint + _directionVectors[currentDir];
|
||||
drawLine(currentPoint, nextPoint, color);
|
||||
if (insideView)
|
||||
drawLine(currentPoint, nextPoint, color);
|
||||
currentPoint = nextPoint;
|
||||
currentDir = (currentDir + delta) & 7;
|
||||
nextPoint = currentPoint + _directionVectors[currentDir];
|
||||
drawLine(currentPoint, nextPoint, color);
|
||||
if (insideView)
|
||||
drawLine(currentPoint, nextPoint, color);
|
||||
currentPoint = nextPoint;
|
||||
currentDir = (currentDir + delta) & 7;
|
||||
}
|
||||
|
||||
void drawCurve() {
|
||||
drawBackground();
|
||||
// segment 1
|
||||
void drawLines() {
|
||||
int dir;
|
||||
Point p0;
|
||||
//Point p0 = Point(_directionVectors[_dir0].y, _directionVectors[_dir0 + 1].y );
|
||||
Point pt;
|
||||
if (_dir0 == 0)
|
||||
p0 = Point(0, _directionVectors[_dir0 + 1].y);
|
||||
else
|
||||
p0 = Point(-_directionVectors[0].x / 2, _directionVectors[_dir0 + 1].y / 2);
|
||||
//Point p0 = Point(-_directionVectors[0].x * 0, -_directionVectors[0].y / 2);
|
||||
Point pt;
|
||||
///*
|
||||
dir = 0 + _dir0;
|
||||
//Point pt = Point(_directionVectors[dir + 1].x - _scaleX, _directionVectors[dir].y);
|
||||
pt = p0 - (_directionVectors[dir] + _directionVectors[dir + 1]);
|
||||
for(int i = 0; i < _length; i++)
|
||||
drawSegment(pt, dir, i, _curve1color, 1);
|
||||
// segment 1
|
||||
if (_partVisible[0]) {
|
||||
dir = 0 + _dir0;
|
||||
pt = p0 - (_directionVectors[dir] + _directionVectors[dir + 1]);
|
||||
for(int i = 0; i < _length; i++)
|
||||
drawSegment(pt, dir, i, _curve1color, 1);
|
||||
}
|
||||
// segment 2
|
||||
///*
|
||||
dir = 4 + _dir0;
|
||||
//pt = Point(-_directionVectors[dir + 1].x - _directionVectors[dir].x - _scaleX, _directionVectors[dir].y);
|
||||
pt = p0 + _directionVectors[dir + 1];//_directionVectors[dir].y
|
||||
for(int i = -1; i > -_length; i--)
|
||||
drawSegment(pt, dir, i, _curve2color, -1);
|
||||
//*/
|
||||
///*
|
||||
if (_partVisible[1]) {
|
||||
dir = 4 + _dir0;
|
||||
pt = p0 + _directionVectors[dir + 1];
|
||||
for(int i = -1; i > -_length; i--)
|
||||
drawSegment(pt, dir, i, _curve2color, -1);
|
||||
}
|
||||
// segment 3
|
||||
dir = 4 + _dir0;
|
||||
pt = p0 - (_directionVectors[dir - 1] + _directionVectors[dir]);
|
||||
for(int i = 0; i < _length; i++)
|
||||
drawSegment(pt, dir, i, _curve3color, 1);
|
||||
if (_partVisible[2]) {
|
||||
dir = 4 + _dir0;
|
||||
pt = p0 - (_directionVectors[dir - 1] + _directionVectors[dir]);
|
||||
for(int i = 0; i < _length; i++)
|
||||
drawSegment(pt, dir, i, _curve3color, 1);
|
||||
}
|
||||
// segment 4
|
||||
dir = 0 + _dir0;
|
||||
pt = p0 + _directionVectors[(dir - 1) & 7];
|
||||
for(int i = -1; i > -_length; i--)
|
||||
drawSegment(pt, dir, i, _curve4color, -1);
|
||||
//*/
|
||||
invalidate();
|
||||
if (_partVisible[3]) {
|
||||
dir = 0 + _dir0;
|
||||
pt = p0 + _directionVectors[(dir - 1) & 7];
|
||||
for(int i = -1; i > -_length; i--)
|
||||
drawSegment(pt, dir, i, _curve4color, -1);
|
||||
}
|
||||
}
|
||||
void drawCurve() {
|
||||
drawBackground();
|
||||
drawLines();
|
||||
_needRepaint = false;
|
||||
}
|
||||
|
||||
/// calculate full content size in pixels
|
||||
|
@ -289,13 +316,46 @@ class DragonView : ScrollWidget {
|
|||
|
||||
}
|
||||
|
||||
immutable SLIDER_ACCELERATION_STEP = 64;
|
||||
|
||||
int sliderToSize(int n) {
|
||||
int limit = 0;
|
||||
int total = 0;
|
||||
int factor = 1;
|
||||
for(;;) {
|
||||
int newlimit = limit + SLIDER_ACCELERATION_STEP;
|
||||
if (n < newlimit) {
|
||||
return total + (n - limit) * factor;
|
||||
}
|
||||
total += SLIDER_ACCELERATION_STEP * factor;
|
||||
limit = newlimit;
|
||||
factor *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
int sizeToSlider(int n) {
|
||||
int limit = 0;
|
||||
int total = 0;
|
||||
int factor = 1;
|
||||
for(;;) {
|
||||
int newlimit = limit + SLIDER_ACCELERATION_STEP;
|
||||
int newtotal = total + SLIDER_ACCELERATION_STEP * factor;
|
||||
if (n < newtotal) {
|
||||
return limit + (n - total) / factor;
|
||||
}
|
||||
total = newtotal;
|
||||
limit = newlimit;
|
||||
factor *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/// entry point for dlangui based application
|
||||
extern (C) int UIAppMain(string[] args) {
|
||||
|
||||
// create window
|
||||
Log.d("Creating window");
|
||||
Window window = Platform.instance.createWindow("DlangUI example - Dragon Curve", null);
|
||||
Log.d("Window created");
|
||||
Window window = Platform.instance.createWindow("DlangUI example : Dragon Curve"d, null, WindowFlag.Resizable, 800, 600);
|
||||
int n = sliderToSize(1000);
|
||||
int n2 = sizeToSlider(n);
|
||||
|
||||
DragonView dragon = new DragonView("DRAGON_VIEW");
|
||||
|
||||
|
@ -309,7 +369,7 @@ extern (C) int UIAppMain(string[] args) {
|
|||
dragon.roundLen = event.position;
|
||||
break;
|
||||
case "size":
|
||||
dragon.length = event.position;
|
||||
dragon.length = sliderToSize(event.position);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -338,10 +398,30 @@ extern (C) int UIAppMain(string[] args) {
|
|||
cbRotate.checkChange = delegate(Widget w, bool check) {
|
||||
dragon.rotation(check ? 1 : 0); return true;
|
||||
};
|
||||
auto cbPartVisible0 = new CheckBox(null, " A1"d);
|
||||
controls1.addChild(cbPartVisible0).checked(dragon.getPartVisible(0));
|
||||
cbPartVisible0.checkChange = delegate(Widget w, bool check) {
|
||||
dragon.setPartVisible(0, check); return true;
|
||||
};
|
||||
auto cbPartVisible1 = new CheckBox(null, " A2"d);
|
||||
controls1.addChild(cbPartVisible1).checked(dragon.getPartVisible(1));
|
||||
cbPartVisible1.checkChange = delegate(Widget w, bool check) {
|
||||
dragon.setPartVisible(1, check); return true;
|
||||
};
|
||||
auto cbPartVisible2 = new CheckBox(null, " B1"d);
|
||||
controls1.addChild(cbPartVisible2).checked(dragon.getPartVisible(2));
|
||||
cbPartVisible2.checkChange = delegate(Widget w, bool check) {
|
||||
dragon.setPartVisible(2, check); return true;
|
||||
};
|
||||
auto cbPartVisible3 = new CheckBox(null, " B2"d);
|
||||
controls1.addChild(cbPartVisible3).checked(dragon.getPartVisible(3));
|
||||
cbPartVisible3.checkChange = delegate(Widget w, bool check) {
|
||||
dragon.setPartVisible(3, check); return true;
|
||||
};
|
||||
|
||||
controls1.addChild(new TextWidget(null," Size"d));
|
||||
auto sliderSize = new SliderWidget("size");
|
||||
sliderSize.setRange(2, 10000).position(dragon.length).layoutWeight(10).fillHorizontal;
|
||||
sliderSize.setRange(2, 1000).position(sizeToSlider(dragon.length)).layoutWeight(10).fillHorizontal;
|
||||
sliderSize.scrollEvent = onScrollEvent;
|
||||
controls1.addChild(sliderSize);
|
||||
|
||||
|
|
|
@ -166,7 +166,7 @@ struct Listener(RETURN_T, T1...)
|
|||
}
|
||||
/// disconnect all listeners
|
||||
final void clear() {
|
||||
_listener = null;
|
||||
_listener = null;
|
||||
}
|
||||
alias get this;
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ struct Signal(T1) if (is(T1 == interface) && __traits(allMembers, T1).length ==
|
|||
}
|
||||
/// disconnect all listeners
|
||||
final void clear() {
|
||||
_listeners.clear();
|
||||
_listeners.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,6 +297,6 @@ struct Signal(RETURN_T, T1...)
|
|||
}
|
||||
/// disconnect all listeners
|
||||
final void clear() {
|
||||
_listeners.clear();
|
||||
_listeners.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -594,3 +643,76 @@ dstring normalizeEndOfLineCharacters(dstring s) {
|
|||
}
|
||||
return cast(dstring)res;
|
||||
}
|
||||
|
||||
/// C malloc allocated array wrapper
|
||||
struct MallocBuf(T) {
|
||||
import core.stdc.stdlib : realloc, free;
|
||||
private T * _allocated;
|
||||
private uint _allocatedSize;
|
||||
private uint _length;
|
||||
/// get pointer
|
||||
@property T * ptr() { return _allocated; }
|
||||
/// get length
|
||||
@property uint length() { return _length; }
|
||||
/// set new length
|
||||
@property void length(uint len) {
|
||||
if (len > _allocatedSize) {
|
||||
reserve(_allocatedSize ? len * 2 : len);
|
||||
}
|
||||
_length = len;
|
||||
}
|
||||
/// const array[index];
|
||||
T opIndex(uint index) const {
|
||||
assert(index < _length);
|
||||
return _allocated[index];
|
||||
}
|
||||
/// ref array[index];
|
||||
ref T opIndex(uint index) {
|
||||
assert(index < _length);
|
||||
return _allocated[index];
|
||||
}
|
||||
/// array[index] = value;
|
||||
void opIndexAssign(uint index, T value) {
|
||||
assert(index < _length);
|
||||
_allocated[index] = value;
|
||||
}
|
||||
/// array[index] = value;
|
||||
void opIndexAssign(uint index, T[] values) {
|
||||
assert(index + values.length < _length);
|
||||
_allocated[index .. index + values.length] = values[];
|
||||
}
|
||||
/// array[a..b]
|
||||
T[] opSlice(uint a, uint b) {
|
||||
assert(a <= b && b <= _length);
|
||||
return _allocated[a .. b];
|
||||
}
|
||||
/// array[]
|
||||
T[] opSlice() {
|
||||
return _allocated ? _allocated[0 .. _length] : null;
|
||||
}
|
||||
/// array[$]
|
||||
uint opDollar() { return _length; }
|
||||
~this() {
|
||||
clear();
|
||||
}
|
||||
/// free allocated memory, set length to 0
|
||||
void clear() {
|
||||
if (_allocated)
|
||||
free(_allocated);
|
||||
_allocatedSize = 0;
|
||||
_length = 0;
|
||||
}
|
||||
/// make sure buffer capacity is at least (size) items
|
||||
void reserve(uint size) {
|
||||
if (_allocatedSize < size) {
|
||||
_allocated = cast(T*)realloc(_allocated, T.sizeof * size);
|
||||
_allocatedSize = size;
|
||||
}
|
||||
}
|
||||
/// fill buffer with specified value
|
||||
void fill(T value) {
|
||||
if (_length) {
|
||||
_allocated[0 .. _length] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1233,14 +1233,15 @@ class ColorDrawBufBase : DrawBuf {
|
|||
}
|
||||
|
||||
class GrayDrawBuf : DrawBuf {
|
||||
int _dx;
|
||||
int _dy;
|
||||
protected int _dx;
|
||||
protected int _dy;
|
||||
/// returns buffer bits per pixel
|
||||
override @property int bpp() { return 8; }
|
||||
@property override int width() { return _dx; }
|
||||
@property override int height() { return _dy; }
|
||||
|
||||
ubyte[] _buf;
|
||||
protected MallocBuf!ubyte _buf;
|
||||
|
||||
this(int width, int height) {
|
||||
resize(width, height);
|
||||
}
|
||||
|
@ -1473,7 +1474,7 @@ class GrayDrawBuf : DrawBuf {
|
|||
}
|
||||
|
||||
class ColorDrawBuf : ColorDrawBufBase {
|
||||
uint[] _buf;
|
||||
protected MallocBuf!uint _buf;
|
||||
|
||||
/// create ARGB8888 draw buf of specified width and height
|
||||
this(int width, int height) {
|
||||
|
@ -1482,9 +1483,8 @@ class ColorDrawBuf : ColorDrawBufBase {
|
|||
/// create copy of ColorDrawBuf
|
||||
this(ColorDrawBuf v) {
|
||||
this(v.width, v.height);
|
||||
//_buf.length = v._buf.length;
|
||||
foreach(i; 0 .. _buf.length)
|
||||
_buf[i] = v._buf[i];
|
||||
if (auto len = _buf.length)
|
||||
_buf.ptr[0 .. len] = v._buf.ptr[0 .. len];
|
||||
}
|
||||
/// create resized copy of ColorDrawBuf
|
||||
this(ColorDrawBuf v, int dx, int dy) {
|
||||
|
@ -1494,7 +1494,7 @@ class ColorDrawBuf : ColorDrawBufBase {
|
|||
}
|
||||
|
||||
void invertAndPreMultiplyAlpha() {
|
||||
foreach(ref pixel; _buf) {
|
||||
foreach(ref pixel; _buf[]) {
|
||||
uint a = (pixel >> 24) & 0xFF;
|
||||
uint r = (pixel >> 16) & 0xFF;
|
||||
uint g = (pixel >> 8) & 0xFF;
|
||||
|
@ -1510,12 +1510,12 @@ class ColorDrawBuf : ColorDrawBufBase {
|
|||
}
|
||||
|
||||
void invertAlpha() {
|
||||
foreach(ref pixel; _buf)
|
||||
foreach(ref pixel; _buf[])
|
||||
pixel ^= 0xFF000000;
|
||||
}
|
||||
|
||||
void invertByteOrder() {
|
||||
foreach(ref pixel; _buf) {
|
||||
foreach(ref pixel; _buf[]) {
|
||||
pixel = (pixel & 0xFF00FF00) |
|
||||
((pixel & 0xFF0000) >> 16) |
|
||||
((pixel & 0xFF) << 16);
|
||||
|
@ -1524,7 +1524,7 @@ class ColorDrawBuf : ColorDrawBufBase {
|
|||
|
||||
// for passing of image to OpenGL texture
|
||||
void invertAlphaAndByteOrder() {
|
||||
foreach(ref pixel; _buf) {
|
||||
foreach(ref pixel; _buf[]) {
|
||||
pixel = ((pixel & 0xFF00FF00) |
|
||||
((pixel & 0xFF0000) >> 16) |
|
||||
((pixel & 0xFF) << 16));
|
||||
|
@ -1643,9 +1643,9 @@ class ColorDrawBuf : ColorDrawBufBase {
|
|||
uint[] tmpbuf;
|
||||
tmpbuf.length = _buf.length;
|
||||
// do horizontal blur
|
||||
blurOneDimension(_buf, tmpbuf, blurSize, true);
|
||||
blurOneDimension(_buf[], tmpbuf, blurSize, true);
|
||||
// then do vertical blur
|
||||
blurOneDimension(tmpbuf, _buf, blurSize, false);
|
||||
blurOneDimension(tmpbuf, _buf[], blurSize, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -115,20 +115,26 @@ class TextWidget : Widget {
|
|||
return this;
|
||||
}
|
||||
|
||||
override void measure(int parentWidth, int parentHeight) {
|
||||
private CalcSaver!(Font, dstring, uint, uint) _measureSaver;
|
||||
|
||||
override void measure(int parentWidth, int parentHeight) {
|
||||
FontRef font = font();
|
||||
//auto measureStart = std.datetime.Clock.currAppTick;
|
||||
Point sz;
|
||||
if (maxLines == 1) {
|
||||
sz = font.textSize(text, MAX_WIDTH_UNSPECIFIED, 4, 0, textFlags);
|
||||
} else {
|
||||
sz = font.measureMultilineText(text,maxLines,parentWidth-margins.left-margins.right-padding.left-padding.right, 4, 0, textFlags);
|
||||
uint w = (maxLines == 1) ? MAX_WIDTH_UNSPECIFIED :
|
||||
parentWidth - margins.left - margins.right - padding.left - padding.right;
|
||||
uint flags = textFlags;
|
||||
|
||||
// optimization: do not measure if nothing changed
|
||||
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) {
|
||||
|
|
|
@ -643,7 +643,7 @@ class FrameLayout : WidgetGroupDefaultDrawing {
|
|||
applyPadding(rc);
|
||||
for (int i = 0; i < _children.count; i++) {
|
||||
Widget item = _children.get(i);
|
||||
if (item.visibility != Visibility.Gone) {
|
||||
if (item.visibility == Visibility.Visible) {
|
||||
item.layout(rc);
|
||||
}
|
||||
}
|
||||
|
@ -657,6 +657,7 @@ class FrameLayout : WidgetGroupDefaultDrawing {
|
|||
Widget item = _children.get(i);
|
||||
if (item.compareId(ID)) {
|
||||
item.visibility = Visibility.Visible;
|
||||
item.requestLayout();
|
||||
foundWidget = item;
|
||||
found = true;
|
||||
} else {
|
||||
|
|
|
@ -1 +1 @@
|
|||
v0.9.167
|
||||
v0.9.169
|
Loading…
Reference in New Issue