simple text widget

This commit is contained in:
Vadim Lopatin 2014-03-05 16:47:54 +04:00
parent e3204070c2
commit 595e1fc7d6
8 changed files with 160 additions and 49 deletions

View File

@ -271,6 +271,7 @@
</Folder> </Folder>
</Folder> </Folder>
<Folder name="widgets"> <Folder name="widgets">
<File path="src\dlangui\widgets\styles.d" />
<File path="src\dlangui\widgets\widget.d" /> <File path="src\dlangui\widgets\widget.d" />
</Folder> </Folder>
</Folder> </Folder>

View File

@ -55,7 +55,9 @@ extern (C) int UIAppMain(string[] args) {
Log.e("Sample error #", 22); Log.e("Sample error #", 22);
Window window = Platform.instance().createWindow("My Window", null); Window window = Platform.instance().createWindow("My Window", null);
Widget myWidget = new TestWidget(); Widget myWidget = new TextWidget();
myWidget.text = "Some strange text string. 1234567890";
myWidget.alignment = Align.Center;
window.mainWidget = myWidget; window.mainWidget = myWidget;
window.show(); window.show();
window.windowCaption = "New Window Caption"; window.windowCaption = "New Window Caption";

View File

@ -104,6 +104,20 @@ class DrawBuf : RefCountedObject {
alias DrawBufRef = Ref!DrawBuf; alias DrawBufRef = Ref!DrawBuf;
/// RAII setting/restoring of clip rectangle
struct ClipRectSaver {
DrawBuf _buf;
Rect _oldClipRect;
this(DrawBuf buf, Rect newClipRect) {
_buf = buf;
_oldClipRect = buf.clipRect;
buf.clipRect = newClipRect;
}
~this() {
_buf.clipRect = _oldClipRect;
}
}
class ColorDrawBufBase : DrawBuf { class ColorDrawBufBase : DrawBuf {
int _dx; int _dx;
int _dy; int _dy;

View File

@ -4,7 +4,7 @@ public import dlangui.core.types;
public import dlangui.core.logger; public import dlangui.core.logger;
import std.algorithm; import std.algorithm;
enum FontFamily : int { enum FontFamily : ubyte {
SansSerif, SansSerif,
Serif, Serif,
Fantasy, Fantasy,
@ -12,6 +12,11 @@ enum FontFamily : int {
MonoSpace MonoSpace
} }
enum FontWeight : int {
Normal = 400,
Bold = 800
}
struct Glyph struct Glyph
{ {
ubyte blackBoxX; ///< 0: width of glyph ubyte blackBoxX; ///< 0: width of glyph
@ -94,6 +99,14 @@ class Font : RefCountedObject {
abstract @property bool isNull(); abstract @property bool isNull();
// measure text string, return accumulated widths[] (distance to end of n-th character), returns number of measured chars. // measure text string, return accumulated widths[] (distance to end of n-th character), returns number of measured chars.
abstract int measureText(const dchar[] text, ref int[] widths, int maxWidth); abstract int measureText(const dchar[] text, ref int[] widths, int maxWidth);
// measure text string as single line, returns width and height
Point textSize(const dchar[] text, int maxWidth = 3000) {
int[] widths = new int[text.length + 1];
int charsMeasured = measureText(text, widths, maxWidth);
if (charsMeasured < 1)
return Point(0,0);
return Point(widths[charsMeasured - 1], height);
}
// draw text string to buffer // draw text string to buffer
abstract void drawText(DrawBuf buf, int x, int y, const dchar[] text, uint color); abstract void drawText(DrawBuf buf, int x, int y, const dchar[] text, uint color);
abstract Glyph * getCharGlyph(dchar ch); abstract Glyph * getCharGlyph(dchar ch);

View File

@ -21,6 +21,8 @@ public class Window {
abstract public @property string windowCaption(); abstract public @property string windowCaption();
abstract public @property void windowCaption(string caption); abstract public @property void windowCaption(string caption);
public void onResize(int width, int height) { public void onResize(int width, int height) {
if (_dx == width && _dy == height)
return;
_dx = width; _dx = width;
_dy = height; _dy = height;
if (_mainWidget !is null) { if (_mainWidget !is null) {

View File

@ -46,14 +46,14 @@ class Win32Window : Window {
cast(void*)this); // creation parameters cast(void*)this); // creation parameters
} }
Win32ColorDrawBuf getDrawBuf() { Win32ColorDrawBuf getDrawBuf() {
RECT rect; //RECT rect;
GetClientRect(_hwnd, &rect); //GetClientRect(_hwnd, &rect);
int dx = rect.right - rect.left; //int dx = rect.right - rect.left;
int dy = rect.bottom - rect.top; //int dy = rect.bottom - rect.top;
if (_drawbuf is null) if (_drawbuf is null)
_drawbuf = new Win32ColorDrawBuf(dx, dy); _drawbuf = new Win32ColorDrawBuf(_dx, _dy);
else else
_drawbuf.resize(dx, dy); _drawbuf.resize(_dx, _dy);
return _drawbuf; return _drawbuf;
} }
override void show() { override void show() {
@ -230,12 +230,17 @@ LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
int dy = rect.bottom - rect.top; int dy = rect.bottom - rect.top;
//window.onResize(pos.cx, pos.cy); //window.onResize(pos.cx, pos.cy);
window.onResize(dx, dy); window.onResize(dx, dy);
UpdateWindow(hwnd);
} }
return 0; return 0;
case WM_ERASEBKGND: case WM_ERASEBKGND:
return 1; return 1;
case WM_PAINT: case WM_PAINT:
{ {
GetClientRect(hwnd, &rect);
int dx = rect.right - rect.left;
int dy = rect.bottom - rect.top;
window.onResize(dx, dy);
hdc = BeginPaint(hwnd, &ps); hdc = BeginPaint(hwnd, &ps);
Win32ColorDrawBuf buf = window.getDrawBuf(); Win32ColorDrawBuf buf = window.getDrawBuf();
buf.fill(0x808080); buf.fill(0x808080);

View File

@ -0,0 +1,12 @@
module dlangui.widgets.styles;
enum Align : ubyte {
Unspecified = 0,
Left = 1,
Right = 2,
HCenter = Left | Right,
Top = 4,
Bottom = 8,
VCenter = Top | Bottom,
Center = VCenter | HCenter
}

View File

@ -1,39 +1,41 @@
module dlangui.widgets.widget; module dlangui.widgets.widget;
import dlangui.core.types; public import dlangui.core.types;
import dlangui.graphics.drawbuf; public import dlangui.widgets.styles;
public import dlangui.graphics.drawbuf;
public import dlangui.graphics.fonts;
import dlangui.platforms.common.platform; import dlangui.platforms.common.platform;
public class Widget { class Widget {
Rect _pos; protected Rect _pos;
Rect _margins; protected Rect _margins;
Rect _padding; protected Rect _padding;
int _measuredWidth; protected int _measuredWidth;
int _measuredHeight; protected int _measuredHeight;
bool _needLayout; protected bool _needLayout;
bool _needDraw; protected bool _needDraw;
Widget _parent; protected Widget _parent;
Window _window; protected Window _window;
uint _backgroundColor = 0xC0C0C0; protected uint _backgroundColor = 0xC0C0C0;
public this() { this() {
_needLayout = true; _needLayout = true;
_needDraw = true; _needDraw = true;
} }
public @property Rect margins() { return _margins; } @property Rect margins() { return _margins; }
public @property void margins(Rect rc) { _margins = rc; } @property void margins(Rect rc) { _margins = rc; }
public @property Rect padding() { return _padding; } @property Rect padding() { return _padding; }
public @property void padding(Rect rc) { _padding = rc; } @property void padding(Rect rc) { _padding = rc; }
public @property uint backgroundColor() { return _backgroundColor; } @property uint backgroundColor() { return _backgroundColor; }
public @property void backgroundColor(uint color) { _backgroundColor = color; } @property void backgroundColor(uint color) { _backgroundColor = color; }
public @property bool needLayout() { return _needLayout; } @property bool needLayout() { return _needLayout; }
public @property bool needDraw() { return _needDraw; } @property bool needDraw() { return _needDraw; }
public @property int childCount() { return 0; } @property int childCount() { return 0; }
public Widget child(int index) { return null; } Widget child(int index) { return null; }
public @property Widget parent() { return _parent; } @property Widget parent() { return _parent; }
public @property void parent(Widget parent) { _parent = parent; } @property void parent(Widget parent) { _parent = parent; }
public @property Window window() { @property Window window() {
Widget p = this; Widget p = this;
while (p !is null) { while (p !is null) {
if (p._window !is null) if (p._window !is null)
@ -42,37 +44,97 @@ public class Widget {
} }
return null; return null;
} }
public @property void window(Window window) { _window = window; } @property void window(Window window) { _window = window; }
public @property measuredWidth() { return _measuredWidth; } @property measuredWidth() { return _measuredWidth; }
public @property measuredHeight() { return _measuredHeight; } @property measuredHeight() { return _measuredHeight; }
public void measure(int width, int height) { @property int width() { return _pos.width; }
_measuredWidth = _measuredHeight = 0; @property int height() { return _pos.height; }
} void applyMargins(ref Rect rc) {
public void layout(Rect rc) {
_pos = rc;
}
public @property int width() { return _pos.width; }
public @property int height() { return _pos.height; }
public void applyMargins(ref Rect rc) {
Rect m = margins; Rect m = margins;
rc.left += m.left; rc.left += m.left;
rc.top += m.top; rc.top += m.top;
rc.bottom -= m.bottom; rc.bottom -= m.bottom;
rc.right -= m.right; rc.right -= m.right;
} }
public void applyPadding(ref Rect rc) { void applyPadding(ref Rect rc) {
Rect m = padding; Rect m = padding;
rc.left += m.left; rc.left += m.left;
rc.top += m.top; rc.top += m.top;
rc.bottom -= m.bottom; rc.bottom -= m.bottom;
rc.right -= m.right; rc.right -= m.right;
} }
public void onDraw(DrawBuf buf) { void measure(int width, int height) {
_measuredWidth = _measuredHeight = 0;
}
void layout(Rect rc) {
_pos = rc;
_needLayout = false;
}
void onDraw(DrawBuf buf) {
Rect rc = _pos; Rect rc = _pos;
applyMargins(rc); applyMargins(rc);
buf.fillRect(_pos, _backgroundColor); buf.fillRect(_pos, _backgroundColor);
applyPadding(rc); applyPadding(rc);
buf.fillRect(rc.left + rc.width / 2, rc.top, rc.left + rc.width / 2 + 2, rc.bottom, 0xFF8000); buf.fillRect(rc.left + rc.width / 2, rc.top, rc.left + rc.width / 2 + 2, rc.bottom, 0xFF8000);
buf.fillRect(rc.left, rc.top + rc.height / 2, rc.right, rc.top + rc.height / 2 + 2, 0xFF80FF); buf.fillRect(rc.left, rc.top + rc.height / 2, rc.right, rc.top + rc.height / 2 + 2, 0xFF80FF);
_needDraw = false;
}
ref FontRef getFont() {
return FontManager.instance.getFont(24, FontWeight.Normal, false, FontFamily.SansSerif, "Arial");
}
@property dstring text() { return ""; }
@property void text(dstring s) { }
protected uint _textColor = 0x000000;
@property uint textColor() { return _textColor; }
@property void textColor(uint value) { _textColor = value; }
protected ubyte _alignment = Align.Left | Align.Top;
@property ubyte alignment() { return _alignment; }
@property Align valign() { return cast(Align)(_alignment & Align.VCenter); }
@property Align halign() { return cast(Align)(_alignment & Align.HCenter); }
@property void alignment(ubyte value) { _alignment = value; }
void applyAlign(ref Rect rc, Point sz) {
if (valign == Align.Bottom) {
rc.top = rc.bottom - sz.y;
} else if (valign == Align.VCenter) {
int dy = (rc.height - sz.y) / 2;
rc.top += dy;
rc.bottom = rc.top + sz.y;
} else {
rc.bottom = rc.top + sz.y;
}
if (halign == Align.Right) {
rc.left = rc.right - sz.x;
} else if (halign == Align.HCenter) {
int dx = (rc.width - sz.x) / 2;
rc.left += dx;
rc.right = rc.left + sz.x;
} else {
rc.right = rc.left + sz.x;
}
}
}
class TextWidget : Widget {
protected dstring _text;
override @property dstring text() { return _text; }
override @property void text(dstring s) { _text = s; }
override void measure(int width, int height) {
_measuredWidth = _measuredHeight = 0;
}
override void layout(Rect rc) {
_pos = rc;
_needLayout = false;
}
override void onDraw(DrawBuf buf) {
super.onDraw(buf);
Rect rc = _pos;
applyMargins(rc);
buf.fillRect(_pos, _backgroundColor);
applyPadding(rc);
ClipRectSaver(buf, rc);
FontRef font = getFont();
Point sz = font.textSize(text);
applyAlign(rc, sz);
font.drawText(buf, rc.left, rc.top, text, textColor);
} }
} }