more improvements

This commit is contained in:
Adam D. Ruppe 2017-04-03 23:10:22 -04:00
parent df9c912bd9
commit 7ac954a3fa
3 changed files with 177 additions and 73 deletions

43
color.d
View File

@ -1274,6 +1274,49 @@ struct Rectangle {
int top; ///
int right; ///
int bottom; ///
///
this(int left, int top, int right, int bottom) {
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
///
this(Point upperLeft, Point lowerRight) {
this(upperLeft.x, upperLeft.y, lowerRight.x, lowerRight.y);
}
///
this(Point upperLeft, Size size) {
this(upperLeft.x, upperLeft.y, upperLeft.x + size.width, upperLeft.y + size.height);
}
///
@property Point upperLeft() {
return Point(left, top);
}
///
@property Point lowerRight() {
return Point(right, bottom);
}
///
@property Size size() {
return Size(width, height);
}
///
@property int width() {
return right - left;
}
///
@property int height() {
return bottom - top;
}
}
/++

103
minigui.d
View File

@ -1170,20 +1170,12 @@ class Widget {
}
protected void privatePaint(ScreenPainter painter, int lox, int loy) {
painter.originX = lox + x;
painter.originY = loy + y;
static if(UsingSimpledisplayX11) {
XRectangle[1] rects;
rects[0] = XRectangle(cast(short)(lox + x), cast(short)(loy + y), cast(short) width, cast(short) height);
XSetClipRectangles(XDisplayConnection.get, painter.impl.gc, 0, 0, rects.ptr, 1, 0);
} else {
version(Windows) {
auto region = CreateRectRgn(lox + x, loy + y, lox + x + width, loy + y + height);
SelectClipRgn(painter.impl.hdc, region);
DeleteObject(region);
}
}
painter.setClipRectangle(Point(0, 0), width, height);
if(paint !is null)
paint(painter);
foreach(child; children)
@ -1346,6 +1338,41 @@ class Window : Widget {
}
});
version(win32_widgets)
win.handleNativeEvent = delegate int(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if(hwnd !is this.win.impl.hwnd)
return 1; // we don't care...
switch(msg) {
case WM_COMMAND:
switch(HIWORD(wParam)) {
case 0:
// case BN_CLICKED: aka 0
case 1:
auto idm = LOWORD(wParam);
if(auto item = idm in Action.mapping) {
foreach(handler; (*item).triggered)
handler();
/*
auto event = new Event("triggered", *item);
event.button = idm;
event.dispatch();
*/
} else {
auto handle = cast(HWND) lParam;
if(auto widgetp = handle in Widget.nativeMapping) {
(*widgetp).handleWmCommand(HIWORD(wParam), LOWORD(wParam));
}
}
break;
default:
return 1;
}
break;
default: return 1; // not handled, pass it on
}
return 0;
};
defaultEventHandlers["keydown"] = delegate void(Widget ignored, Event event) {
Widget _this = event.target;
@ -1605,41 +1632,6 @@ class MainWindow : Window {
this.statusBar.parts[0].content = _this.statusTip; // ~ " " ~ event.target.toString();
};
version(win32_widgets)
win.handleNativeEvent = delegate int(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if(hwnd !is this.win.impl.hwnd)
return 1; // we don't care...
switch(msg) {
case WM_COMMAND:
switch(HIWORD(wParam)) {
case 0:
// case BN_CLICKED: aka 0
case 1:
auto idm = LOWORD(wParam);
if(auto item = idm in Action.mapping) {
foreach(handler; (*item).triggered)
handler();
/*
auto event = new Event("triggered", *item);
event.button = idm;
event.dispatch();
*/
} else {
auto handle = cast(HWND) lParam;
if(auto widgetp = handle in Widget.nativeMapping) {
(*widgetp).handleWmCommand(HIWORD(wParam), LOWORD(wParam));
}
}
break;
default:
return 1;
}
break;
default: return 1; // not handled, pass it on
}
return 0;
};
_clientArea = new ClientAreaWidget();
_clientArea.x = 0;
_clientArea.y = 0;
@ -1811,16 +1803,23 @@ class ToolButton : Button {
painter.fillColor = Color.white;
painter.outlineColor = Color.white;
painter.drawRectangle(Point(6, 3) * multiplier, Point(9, 5) * multiplier);
painter.drawRectangle(Point(5, 9) * multiplier, Point(10, 12) * multiplier);
// the slider
painter.drawRectangle(Point(5, 2) * multiplier, Point(10, 5) * multiplier);
// the label
painter.drawRectangle(Point(4, 8) * multiplier, Point(11, 12) * multiplier);
painter.fillColor = Color.black;
painter.outlineColor = Color.black;
// the disc window
painter.drawRectangle(Point(8, 3) * multiplier, Point(9, 4) * multiplier);
break;
case GenericIcons.Open:
painter.fillColor = Color.white;
painter.drawPolygon(
Point(2, 4) * multiplier, Point(2, 12) * multiplier, Point(13, 12) * multiplier, Point(13, 3) * multiplier,
Point(9, 3) * multiplier, Point(9, 4) * multiplier, Point(2, 4) * multiplier);
painter.drawLine(Point(3, 6) * multiplier, Point(9, 6) * multiplier);
painter.drawLine(Point(9, 7) * multiplier, Point(13, 7) * multiplier);
painter.drawLine(Point(2, 6) * multiplier, Point(13, 7) * multiplier);
//painter.drawLine(Point(9, 6) * multiplier, Point(13, 7) * multiplier);
break;
case GenericIcons.Copy:
painter.fillColor = Color.white;
@ -1839,7 +1838,7 @@ class ToolButton : Button {
painter.drawRectangle(Point(2, 3) * multiplier, Point(11, 11) * multiplier);
painter.drawRectangle(Point(6, 8) * multiplier, Point(13, 13) * multiplier);
painter.drawLine(Point(6, 2) * multiplier, Point(4, 5) * multiplier);
painter.drawLine(Point(7, 2) * multiplier, Point(9, 5) * multiplier);
painter.drawLine(Point(6, 2) * multiplier, Point(9, 5) * multiplier);
painter.fillColor = Color.black;
painter.drawRectangle(Point(4, 5) * multiplier, Point(9, 6) * multiplier);
break;
@ -2025,7 +2024,9 @@ class StatusBar : Widget {
int remainingLength = this.width;
foreach(idx, part; this.partsArray) {
auto partWidth = part.width ? part.width : ((idx + 1 == this.partsArray.length) ? remainingLength : 100);
painter.setClipRectangle(Point(cpos, 0), partWidth, height);
draw3dFrame(cpos, 0, partWidth, height, painter, FrameStyle.sunk);
painter.setClipRectangle(Point(cpos + 2, 2), partWidth - 4, height - 4);
painter.drawText(Point(cpos + 4, 0), part.content, Point(width, height), TextAlignment.VerticalCenter);
cpos += partWidth;
remainingLength -= partWidth;

View File

@ -4135,8 +4135,16 @@ struct ScreenPainter {
window.activeScreenPainter = impl;
// writeln("constructed");
}
originalPen = impl._activePen;
originalFillColor = impl._fillColor;
originalClipRectangle = impl._clipRectangle;
}
private Pen originalPen;
private Color originalFillColor;
private arsd.color.Rectangle originalClipRectangle;
~this() {
impl.referenceCount--;
//writeln("refcount -- ", impl.referenceCount);
@ -4144,6 +4152,13 @@ struct ScreenPainter {
//writeln("destructed");
impl.dispose();
window.activeScreenPainter = null;
} else {
// there is still an active reference, reset stuff so the
// next user doesn't get weirdness via the reference
this.rasterOp = RasterOp.normal;
pen = originalPen;
fillColor = originalFillColor;
impl.setClipRectangle(originalClipRectangle.left, originalClipRectangle.top, originalClipRectangle.width, originalClipRectangle.height);
}
}
@ -4152,6 +4167,18 @@ struct ScreenPainter {
//writeln("refcount ++ ", impl.referenceCount);
}
/// Sets the clipping region for drawing. If width == 0 && height == 0, disabled clipping.
void setClipRectangle(Point pt, int width, int height) {
transform(pt);
impl.setClipRectangle(pt.x, pt.y, width, height);
}
/// ditto
void setClipRectangle(arsd.color.Rectangle rect) {
setClipRectangle(rect.upperLeft, rect.width, rect.height);
}
///
void setFont(OperatingSystemFont font) {
impl.setFont(font);
@ -4162,14 +4189,23 @@ struct ScreenPainter {
return impl.fontHeight();
}
private Pen activePen;
int originX;
int originY;
///
@property void pen(Pen p) {
activePen = p;
impl.pen(p);
}
///
@property void outlineColor(Color c) {
impl.outlineColor(c);
if(activePen.color == c)
return;
activePen.color = c;
impl.pen(activePen);
}
///
@ -4187,9 +4223,6 @@ struct ScreenPainter {
p.y += originY;
}
int originX;
int originY;
void updateDisplay() {
// FIXME this should do what the dtor does
}
@ -5190,6 +5223,21 @@ version(Windows) {
SelectObject(hdc, defaultGuiFont);
}
arsd.color.Rectangle _clipRectangle;
void setClipRectangle(int x, int y, int width, int height) {
_clipRectangle = arsd.color.Rectangle(Point(x, y), Size(width, height));
if(width == 0 || height == 0) {
SelectClipRgn(hdc, null);
} else {
auto region = CreateRectRgn(x, y, x + width, y + height);
SelectClipRgn(hdc, region);
DeleteObject(region);
}
}
// just because we can on Windows...
//void create(Image image);
@ -5255,11 +5303,6 @@ version(Windows) {
}
@property void outlineColor(Color c) {
_activePen.color = c;
pen = _activePen;
}
@property void rasterOp(RasterOp op) {
int mode;
final switch(op) {
@ -5275,9 +5318,11 @@ version(Windows) {
HBRUSH originalBrush;
HBRUSH currentBrush;
Color _fillColor = Color(1, 1, 1, 1); // what are the odds that they'd set this??
@property void fillColor(Color c) {
// FIXME: we probably don't need to call all this if the brush
// is already good
if(c == _fillColor)
return;
_fillColor = c;
HBRUSH brush;
if(c.a == 0) {
brush = GetStockObject(HOLLOW_BRUSH);
@ -5326,10 +5371,15 @@ version(Windows) {
}
Size textSize(string text) {
bool dummyX;
if(text.length == 0) {
text = " ";
dummyX = true;
}
RECT rect;
WCharzBuffer buffer = WCharzBuffer(text);
DrawTextW(hdc, buffer.ptr, cast(int) buffer.length, &rect, DT_CALCRECT);
return Size(rect.right, rect.bottom);
return Size(dummyX ? 0 : rect.right, rect.bottom);
}
void drawText(int x, int y, int x2, int y2, scope const(char)[] text, uint alignment) {
@ -6214,6 +6264,19 @@ version(X11) {
}
}
arsd.color.Rectangle _clipRectangle;
void setClipRectangle(int x, int y, int width, int height) {
_clipRectangle = arsd.color.Rectangle(Point(x, y), Size(width, height));
if(width == 0 || height == 0)
XSetClipMask(display, gc, None);
else {
XRectangle[1] rects;
rects[0] = XRectangle(cast(short)(x), cast(short)(y), cast(short) width, cast(short) height);
XSetClipRectangles(XDisplayConnection.get, gc, 0, 0, rects.ptr, 1, 0);
}
}
void setFont(OperatingSystemFont font) {
if(font && font.font) {
this.font = font.font;
@ -6254,13 +6317,13 @@ version(X11) {
bool backgroundIsNotTransparent = true;
bool foregroundIsNotTransparent = true;
Pen _pen;
Pen _activePen;
Color _outlineColor;
Color _fillColor;
@property void pen(Pen p) {
_pen = p;
_activePen = p;
_outlineColor = p.color;
int style;
@ -6289,13 +6352,6 @@ version(X11) {
cast(uint) p.color.b);
}
@property void outlineColor(Color c) {
if(_pen.color == c)
return; // don't double call for performance
_pen.color = c;
pen = _pen;
}
@property void rasterOp(RasterOp op) {
int mode;
final switch(op) {
@ -6332,7 +6388,8 @@ version(X11) {
void swapColors() {
auto tmp = _fillColor;
fillColor = _outlineColor;
outlineColor = tmp;
_activePen.color = tmp;
pen(_activePen);
}
void drawImage(int x, int y, Image i, int ix, int iy, int w, int h) {
@ -10940,6 +10997,7 @@ mixin template ExperimentalTextComponent() {
}
void drawInto(ScreenPainter painter, bool focused = false) {
painter.setClipRectangle(boundingBox);
auto pos = Point(boundingBox.left, boundingBox.top);
int lastHeight;
@ -11001,6 +11059,7 @@ mixin template ExperimentalTextComponent() {
int caratLastDrawnX, caratLastDrawnY1, caratLastDrawnY2;
bool caratShowingOnScreen = false;
void drawCarat(ScreenPainter painter) {
painter.setClipRectangle(boundingBox);
int x, y1, y2;
if(carat.inlineElement is null) {
x = boundingBox.left;
@ -11032,6 +11091,7 @@ mixin template ExperimentalTextComponent() {
}
void eraseCarat(ScreenPainter painter) {
painter.setClipRectangle(boundingBox);
if(!caratShowingOnScreen) return;
painter.pen = Pen(Color.white, 1);
painter.rasterOp = RasterOp.xor;