mirror of https://github.com/buggins/dlangui.git
Merge branch 'master' of github.com:buggins/dlangui
This commit is contained in:
commit
fc479a1cfa
|
@ -840,6 +840,25 @@ void main()
|
||||||
|
|
||||||
tabs.addTab((new SampleAnimationWidget("tab6")).layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT), "TAB_ANIMATION"c);
|
tabs.addTab((new SampleAnimationWidget("tab6")).layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT), "TAB_ANIMATION"c);
|
||||||
|
|
||||||
|
CanvasWidget canvas = new CanvasWidget("canvas");
|
||||||
|
canvas.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
|
||||||
|
canvas.onDrawListener = delegate(CanvasWidget canvas, DrawBuf buf, Rect rc) {
|
||||||
|
buf.fill(0xFFFFFF);
|
||||||
|
int x = rc.left;
|
||||||
|
int y = rc.top;
|
||||||
|
buf.fillRect(Rect(x+20, y+20, x+150, y+200), 0x80FF80);
|
||||||
|
buf.fillRect(Rect(x+90, y+80, x+250, y+250), 0x80FF80FF);
|
||||||
|
canvas.font.drawText(buf, x + 40, y + 50, "fillRect()"d, 0xC080C0);
|
||||||
|
buf.drawFrame(Rect(x + 400, y + 30, x + 550, y + 150), 0x204060, Rect(2,3,4,5), 0x80704020);
|
||||||
|
canvas.font.drawText(buf, x + 400, y + 5, "drawFrame()"d, 0x208020);
|
||||||
|
canvas.font.drawText(buf, x + 300, y + 100, "drawPixel()"d, 0x000080);
|
||||||
|
for (int i = 0; i < 80; i++)
|
||||||
|
buf.drawPixel(x+300 + i * 4, y+140 + i * 3 % 100, 0xFF0000 + i * 2);
|
||||||
|
canvas.font.drawText(buf, x + 200, y + 250, "drawLine()"d, 0x800020);
|
||||||
|
for (int i = 0; i < 40; i+=3)
|
||||||
|
buf.drawLine(Point(x+200 + i * 4, y+290), Point(x+150 + i * 7, y+420 + i * 2), 0x008000 + i * 5);
|
||||||
|
};
|
||||||
|
tabs.addTab(canvas, "TAB_CANVAS"c);
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
|
|
@ -32,4 +32,5 @@ TAB_BUTTONS=Buttons
|
||||||
TAB_ANIMATION=Animation
|
TAB_ANIMATION=Animation
|
||||||
TAB_TABLE_LAYOUT=Table layout
|
TAB_TABLE_LAYOUT=Table layout
|
||||||
TAB_EDITORS=Editors
|
TAB_EDITORS=Editors
|
||||||
|
TAB_CANVAS=Canvas
|
||||||
|
|
||||||
|
|
|
@ -260,6 +260,8 @@ class DrawBuf : RefCountedObject {
|
||||||
abstract void fill(uint color);
|
abstract void fill(uint color);
|
||||||
/// fill rectangle with solid color (clipping is applied)
|
/// fill rectangle with solid color (clipping is applied)
|
||||||
abstract void fillRect(Rect rc, uint color);
|
abstract void fillRect(Rect rc, uint color);
|
||||||
|
/// draw pixel at (x, y) with specified color
|
||||||
|
abstract void drawPixel(int x, int y, uint color);
|
||||||
/// draw 8bit alpha image - usually font glyph using specified color (clipping is applied)
|
/// draw 8bit alpha image - usually font glyph using specified color (clipping is applied)
|
||||||
abstract void drawGlyph(int x, int y, Glyph * glyph, uint color);
|
abstract void drawGlyph(int x, int y, Glyph * glyph, uint color);
|
||||||
/// draw source buffer rectangle contents to destination buffer
|
/// draw source buffer rectangle contents to destination buffer
|
||||||
|
@ -336,6 +338,50 @@ class DrawBuf : RefCountedObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// draw line from point p1 to p2 with specified color
|
||||||
|
void drawLine(Point p1, Point p2, uint colour) {
|
||||||
|
if (p1.x < _clipRect.left && p2.x < _clipRect.left)
|
||||||
|
return;
|
||||||
|
if (p1.y < _clipRect.top && p2.y < _clipRect.top)
|
||||||
|
return;
|
||||||
|
if (p1.x >= _clipRect.right && p2.x >= _clipRect.right)
|
||||||
|
return;
|
||||||
|
if (p1.y >= _clipRect.bottom && p2.y >= _clipRect.bottom)
|
||||||
|
return;
|
||||||
|
// from rosettacode.org
|
||||||
|
import std.math: abs;
|
||||||
|
immutable int dx = p2.x - p1.x;
|
||||||
|
immutable int ix = (dx > 0) - (dx < 0);
|
||||||
|
immutable int dx2 = abs(dx) * 2;
|
||||||
|
int dy = p2.y - p1.y;
|
||||||
|
immutable int iy = (dy > 0) - (dy < 0);
|
||||||
|
immutable int dy2 = abs(dy) * 2;
|
||||||
|
drawPixel(p1.x, p1.y, colour);
|
||||||
|
if (dx2 >= dy2) {
|
||||||
|
int error = dy2 - (dx2 / 2);
|
||||||
|
while (p1.x != p2.x) {
|
||||||
|
if (error >= 0 && (error || (ix > 0))) {
|
||||||
|
error -= dx2;
|
||||||
|
p1.y += iy;
|
||||||
|
}
|
||||||
|
error += dy2;
|
||||||
|
p1.x += ix;
|
||||||
|
drawPixel(p1.x, p1.y, colour);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int error = dx2 - (dy2 / 2);
|
||||||
|
while (p1.y != p2.y) {
|
||||||
|
if (error >= 0 && (error || (iy > 0))) {
|
||||||
|
error -= dy2;
|
||||||
|
p1.x += ix;
|
||||||
|
}
|
||||||
|
error += dx2;
|
||||||
|
p1.y += iy;
|
||||||
|
drawPixel(p1.x, p1.y, colour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// create drawbuf with copy of current buffer with changed colors (returns this if not supported)
|
/// create drawbuf with copy of current buffer with changed colors (returns this if not supported)
|
||||||
DrawBuf transformColors(ref ColorTransform transform) {
|
DrawBuf transformColors(ref ColorTransform transform) {
|
||||||
return this;
|
return this;
|
||||||
|
@ -646,6 +692,22 @@ class ColorDrawBufBase : DrawBuf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// draw pixel at (x, y) with specified color
|
||||||
|
override void drawPixel(int x, int y, uint color) {
|
||||||
|
if (!_clipRect.isPointInside(x, y))
|
||||||
|
return;
|
||||||
|
color = applyAlpha(color);
|
||||||
|
uint * row = scanLine(y);
|
||||||
|
uint alpha = color >> 24;
|
||||||
|
if (!alpha) {
|
||||||
|
row[x] = color;
|
||||||
|
} else if (alpha < 254) {
|
||||||
|
// apply blending
|
||||||
|
row[x] = blendARGB(row[x], color, alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class GrayDrawBuf : DrawBuf {
|
class GrayDrawBuf : DrawBuf {
|
||||||
|
@ -828,11 +890,11 @@ class GrayDrawBuf : DrawBuf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
override void fillRect(Rect rc, uint color) {
|
override void fillRect(Rect rc, uint color) {
|
||||||
ubyte cl = rgbToGray(color);
|
|
||||||
if (applyClipping(rc)) {
|
if (applyClipping(rc)) {
|
||||||
|
uint alpha = color >> 24;
|
||||||
|
ubyte cl = rgbToGray(color);
|
||||||
for (int y = rc.top; y < rc.bottom; y++) {
|
for (int y = rc.top; y < rc.bottom; y++) {
|
||||||
ubyte * row = scanLine(y);
|
ubyte * row = scanLine(y);
|
||||||
uint alpha = color >> 24;
|
|
||||||
for (int x = rc.left; x < rc.right; x++) {
|
for (int x = rc.left; x < rc.right; x++) {
|
||||||
if (!alpha)
|
if (!alpha)
|
||||||
row[x] = cl;
|
row[x] = cl;
|
||||||
|
@ -844,6 +906,22 @@ class GrayDrawBuf : DrawBuf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// draw pixel at (x, y) with specified color
|
||||||
|
override void drawPixel(int x, int y, uint color) {
|
||||||
|
if (!_clipRect.isPointInside(x, y))
|
||||||
|
return;
|
||||||
|
color = applyAlpha(color);
|
||||||
|
ubyte cl = rgbToGray(color);
|
||||||
|
ubyte * row = scanLine(y);
|
||||||
|
uint alpha = color >> 24;
|
||||||
|
if (!alpha) {
|
||||||
|
row[x] = cl;
|
||||||
|
} else if (alpha < 254) {
|
||||||
|
// apply blending
|
||||||
|
row[x] = blendGray(row[x], cl, alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ColorDrawBuf : ColorDrawBufBase {
|
class ColorDrawBuf : ColorDrawBufBase {
|
||||||
|
|
|
@ -100,7 +100,17 @@ class GLDrawBuf : DrawBuf, GLConfigCallback {
|
||||||
if (!isFullyTransparentColor(color) && applyClipping(rc))
|
if (!isFullyTransparentColor(color) && applyClipping(rc))
|
||||||
_scene.add(new SolidRectSceneItem(rc, color));
|
_scene.add(new SolidRectSceneItem(rc, color));
|
||||||
}
|
}
|
||||||
/// draw 8bit alpha image - usually font glyph using specified color (clipping is applied)
|
/// draw pixel at (x, y) with specified color
|
||||||
|
override void drawPixel(int x, int y, uint color) {
|
||||||
|
assert(_scene !is null);
|
||||||
|
if (!_clipRect.isPointInside(x, y))
|
||||||
|
return;
|
||||||
|
color = applyAlpha(color);
|
||||||
|
if (isFullyTransparentColor(color))
|
||||||
|
return;
|
||||||
|
_scene.add(new SolidRectSceneItem(Rect(x, y, x + 1, y + 1), color));
|
||||||
|
}
|
||||||
|
/// draw 8bit alpha image - usually font glyph using specified color (clipping is applied)
|
||||||
override void drawGlyph(int x, int y, Glyph * glyph, uint color) {
|
override void drawGlyph(int x, int y, Glyph * glyph, uint color) {
|
||||||
assert(_scene !is null);
|
assert(_scene !is null);
|
||||||
Rect dstrect = Rect(x,y, x + glyph.correctedBlackBoxX, y + glyph.blackBoxY);
|
Rect dstrect = Rect(x,y, x + glyph.correctedBlackBoxX, y + glyph.blackBoxY);
|
||||||
|
|
|
@ -994,3 +994,38 @@ class ScrollBar : AbstractSlider, OnClickHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// interface - slot for onClick
|
||||||
|
interface OnDrawHandler {
|
||||||
|
void doDraw(CanvasWidget canvas, DrawBuf buf, Rect rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// canvas widget - draw on it either by overriding of doDraw() or by assigning of onDrawListener
|
||||||
|
class CanvasWidget : Widget {
|
||||||
|
|
||||||
|
Listener!OnDrawHandler onDrawListener;
|
||||||
|
|
||||||
|
this(string ID = null) {
|
||||||
|
super(ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
override void measure(int parentWidth, int parentHeight) {
|
||||||
|
measuredContent(parentWidth, parentHeight, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void doDraw(DrawBuf buf, Rect rc) {
|
||||||
|
if (onDrawListener.assigned)
|
||||||
|
onDrawListener(this, buf, rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
override void onDraw(DrawBuf buf) {
|
||||||
|
if (visibility != Visibility.Visible)
|
||||||
|
return;
|
||||||
|
super.onDraw(buf);
|
||||||
|
Rect rc = _pos;
|
||||||
|
applyMargins(rc);
|
||||||
|
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||||
|
applyPadding(rc);
|
||||||
|
doDraw(buf, rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue