ketmar focused and glpatch

This commit is contained in:
Adam D. Ruppe 2017-04-01 19:45:42 -04:00
parent 3f1888df1a
commit a909ac717c
1 changed files with 143 additions and 27 deletions

View File

@ -1237,7 +1237,7 @@ class SimpleWindow : CapableOfHandlingNativeEvent {
atom on X11 and the FlashWindow function on Windows. atom on X11 and the FlashWindow function on Windows.
+/ +/
void requestAttention() { void requestAttention() {
if(focused) if(_focused)
return; return;
version(Windows) { version(Windows) {
@ -1255,7 +1255,7 @@ class SimpleWindow : CapableOfHandlingNativeEvent {
} else static assert(0); } else static assert(0);
} }
private bool focused; // FIXME:I might make a getter for this public later private bool _focused;
version(X11) private bool demandingAttention; version(X11) private bool demandingAttention;
@ -1276,6 +1276,9 @@ class SimpleWindow : CapableOfHandlingNativeEvent {
/// Returns true if the window has been closed. /// Returns true if the window has been closed.
final @property bool closed() { return _closed; } final @property bool closed() { return _closed; }
/// Returns true if the window is focused.
final @property bool focused() { return _focused; }
private bool _visible; private bool _visible;
/// Returns true if the window is visible (mapped). /// Returns true if the window is visible (mapped).
final @property bool visible() { return _visible; } final @property bool visible() { return _visible; }
@ -3678,10 +3681,10 @@ struct Pen {
+/ +/
/// NOT IMPLEMENTED /// Style of lines drawn
enum Style { enum Style {
Solid, /// Solid, /// a solid line
Dashed /// Dashed /// a dashed line
} }
} }
@ -5044,7 +5047,16 @@ version(Windows) {
if(p.color.a == 0) { if(p.color.a == 0) {
pen = GetStockObject(NULL_PEN); pen = GetStockObject(NULL_PEN);
} else { } else {
pen = CreatePen(PS_SOLID, p.width, RGB(p.color.r, p.color.g, p.color.b)); int style = PS_SOLID;
final switch(p.style) {
case Pen.Style.Solid:
style = PS_SOLID;
break;
case Pen.Style.Dashed:
style = PS_DASH;
break;
}
pen = CreatePen(style, p.width, RGB(p.color.r, p.color.g, p.color.b));
} }
auto orig = SelectObject(hdc, pen); auto orig = SelectObject(hdc, pen);
if(originalPen is null) if(originalPen is null)
@ -5535,7 +5547,7 @@ version(Windows) {
break; break;
case WM_SETFOCUS: case WM_SETFOCUS:
case WM_KILLFOCUS: case WM_KILLFOCUS:
wind.focused = msg == WM_SETFOCUS; wind._focused = msg == WM_SETFOCUS;
if(wind.onFocusChange) if(wind.onFocusChange)
wind.onFocusChange(msg == WM_SETFOCUS); wind.onFocusChange(msg == WM_SETFOCUS);
break; break;
@ -6043,7 +6055,18 @@ version(X11) {
_pen = p; _pen = p;
_outlineColor = p.color; _outlineColor = p.color;
XSetLineAttributes(display, gc, p.width, 0, 0, 0); int style;
final switch(p.style) {
case Pen.Style.Solid:
style = 0 /*LineSolid*/;
break;
case Pen.Style.Dashed:
style = 1 /*LineOnOffDash*/;
break;
}
XSetLineAttributes(display, gc, p.width, style, 0, 0);
if(p.color.a == 0) { if(p.color.a == 0) {
foregroundIsNotTransparent = false; foregroundIsNotTransparent = false;
@ -7471,7 +7494,7 @@ version(X11) {
if (e.type == EventType.FocusIn) XSetICFocus(win.xic); else XUnsetICFocus(win.xic); if (e.type == EventType.FocusIn) XSetICFocus(win.xic); else XUnsetICFocus(win.xic);
} }
win.focused = e.type == EventType.FocusIn; win._focused = e.type == EventType.FocusIn;
if(win.demandingAttention) if(win.demandingAttention)
demandAttention(*win, false); demandAttention(*win, false);
@ -9202,8 +9225,24 @@ struct Visual
void Xutf8DrawString(Display*, Drawable, XFontSet, GC, int, int, in char*, int); void Xutf8DrawString(Display*, Drawable, XFontSet, GC, int, int, in char*, int);
int XSetFunction(Display*, GC, int); int XSetFunction(Display*, GC, int);
enum GXcopy = 0x3; enum {
enum GXxor = 0x6; GXclear = 0x0, /* 0 */
GXand = 0x1, /* src AND dst */
GXandReverse = 0x2, /* src AND NOT dst */
GXcopy = 0x3, /* src */
GXandInverted = 0x4, /* NOT src AND dst */
GXnoop = 0x5, /* dst */
GXxor = 0x6, /* src XOR dst */
GXor = 0x7, /* src OR dst */
GXnor = 0x8, /* NOT src AND NOT dst */
GXequiv = 0x9, /* NOT src XOR dst */
GXinvert = 0xa, /* NOT dst */
GXorReverse = 0xb, /* src OR NOT dst */
GXcopyInverted = 0xc, /* NOT src */
GXorInverted = 0xd, /* NOT src OR dst */
GXnand = 0xe, /* NOT src OR NOT dst */
GXset = 0xf, /* 1 */
}
GC XCreateGC(Display*, Drawable, uint, void*); GC XCreateGC(Display*, Drawable, uint, void*);
int XCopyGC(Display*, GC, uint, GC); int XCopyGC(Display*, GC, uint, GC);
@ -10374,9 +10413,11 @@ mixin template ExperimentalTextComponent() {
} }
} }
struct InlineElement { static class InlineElement {
string text; string text;
BlockElement containingBlock;
Color color = Color.black; Color color = Color.black;
Color backgroundColor = Color.transparent; Color backgroundColor = Color.transparent;
ushort styles; ushort styles;
@ -10397,6 +10438,41 @@ mixin template ExperimentalTextComponent() {
else else
return boundingBox.right; return boundingBox.right;
} }
InlineElement clone() {
auto ie = new InlineElement();
ie.tupleof = this.tupleof;
return ie;
}
InlineElement getPreviousInlineElement() {
InlineElement prev = null;
foreach(ie; this.containingBlock.parts) {
if(ie is this)
break;
prev = ie;
}
if(prev is null) {
BlockElement pb;
BlockElement cb = this.containingBlock;
moar:
foreach(ie; this.containingBlock.containingLayout.blocks) {
if(ie is cb)
break;
pb = ie;
}
if(pb is null)
return null;
if(pb.parts.length == 0) {
cb = pb;
goto moar;
}
prev = pb.parts[$-1];
}
return prev;
}
} }
// Block elements are used entirely for positioning inline elements, // Block elements are used entirely for positioning inline elements,
@ -10407,6 +10483,8 @@ mixin template ExperimentalTextComponent() {
int whiteSpace; // pre, pre-wrap, wrap int whiteSpace; // pre, pre-wrap, wrap
TextLayout containingLayout;
// inputs // inputs
Point where; Point where;
Size minimumSize; Size minimumSize;
@ -10422,7 +10500,7 @@ mixin template ExperimentalTextComponent() {
} }
struct TextIdentifyResult { struct TextIdentifyResult {
InlineElement* element; InlineElement element;
size_t offset; size_t offset;
} }
@ -10457,21 +10535,32 @@ mixin template ExperimentalTextComponent() {
this.boundingBox = boundingBox; this.boundingBox = boundingBox;
} }
BlockElement addBlock(Rectangle margin = Rectangle(0, 0, 0, 0), Rectangle padding = Rectangle(0, 0, 0, 0)) { BlockElement addBlock(InlineElement after = null, Rectangle margin = Rectangle(0, 0, 0, 0), Rectangle padding = Rectangle(0, 0, 0, 0)) {
auto be = new BlockElement(); auto be = new BlockElement();
blocks ~= be; be.containingLayout = this;
if(after is null)
blocks ~= be;
else {
foreach(idx, b; blocks) {
if(b is after.containingBlock) {
blocks = blocks[0 .. idx + 1] ~ be ~ blocks[idx + 1 .. $];
break;
}
}
}
return be; return be;
} }
void clear() { void clear() {
blocks = null; blocks = null;
carat = Carat.init;
} }
void addText(Args...)(Args args) { void addText(Args...)(Args args) {
if(blocks.length == 0) if(blocks.length == 0)
addBlock(); addBlock();
InlineElement ie; InlineElement ie = new InlineElement();
foreach(idx, arg; args) { foreach(idx, arg; args) {
static if(is(typeof(arg) == ForegroundColor)) static if(is(typeof(arg) == ForegroundColor))
ie.color = arg; ie.color = arg;
@ -10488,9 +10577,11 @@ mixin template ExperimentalTextComponent() {
if(a == '\n') { if(a == '\n') {
ie.text = arg[lastLineIndex .. cidx]; ie.text = arg[lastLineIndex .. cidx];
lastLineIndex = cidx + 1; lastLineIndex = cidx + 1;
blocks[$-1].parts ~= ie; ie.containingBlock = blocks[$-1];
blocks[$-1].parts ~= ie.clone;
ie.text = "\n"; ie.text = "\n";
blocks[$-1].parts ~= ie; ie.containingBlock = blocks[$-1];
blocks[$-1].parts ~= ie.clone;
addBlock(); addBlock();
} else { } else {
@ -10498,8 +10589,9 @@ mixin template ExperimentalTextComponent() {
} }
ie.text = arg[lastLineIndex .. $]; ie.text = arg[lastLineIndex .. $];
blocks[$-1].parts ~= ie; ie.containingBlock = blocks[$-1];
carat = Carat(this, &(blocks[$-1].parts[$-1]), ie.text.length); blocks[$-1].parts ~= ie.clone;
carat = Carat(this, blocks[$-1].parts[$-1], blocks[$-1].parts[$-1].text.length);
} }
} }
} }
@ -10511,7 +10603,7 @@ mixin template ExperimentalTextComponent() {
TextIdentifyResult identify(int x, int y) { TextIdentifyResult identify(int x, int y) {
foreach(block; blocks) { foreach(block; blocks) {
foreach(ref part; block.parts) { foreach(part; block.parts) {
if(x >= part.boundingBox.left && x < part.boundingBox.right && y >= part.boundingBox.top && y < part.boundingBox.bottom) { if(x >= part.boundingBox.left && x < part.boundingBox.right && y >= part.boundingBox.top && y < part.boundingBox.bottom) {
// FIXME binary search // FIXME binary search
@ -10522,7 +10614,7 @@ mixin template ExperimentalTextComponent() {
break; break;
} }
return TextIdentifyResult(&part, tidx); return TextIdentifyResult(part, tidx);
} }
} }
} }
@ -10670,18 +10762,42 @@ mixin template ExperimentalTextComponent() {
if(carat.offset == e.text.length) { if(carat.offset == e.text.length) {
e.text ~= cast(char) ch; // FIXME e.text ~= cast(char) ch; // FIXME
carat.offset++; carat.offset++;
if(ch == 10) {
auto c = carat.inlineElement.clone;
c.text = null;
auto b = addBlock(c);
c.containingBlock = b;
b.parts ~= c;
carat = Carat(this, c, 0);
}
} else { } else {
// FIXME cast char sucks // FIXME cast char sucks
e.text = e.text[0 .. carat.offset + 1] ~ cast(char) ch ~ e.text[carat.offset + 1 .. $]; if(ch == 10) {
carat.offset++; auto c = carat.inlineElement.clone;
c.text = e.text[carat.offset + 1 .. $];
e.text = e.text[0 .. carat.offset + 1] ~ cast(char) ch;
auto b = addBlock(c);
c.containingBlock = b;
b.parts ~= c;
carat = Carat(this, c, 0);
} else {
e.text = e.text[0 .. carat.offset + 1] ~ cast(char) ch ~ e.text[carat.offset + 1 .. $];
carat.offset++;
}
} }
} }
void backspace() { void backspace() {
try_again:
auto e = carat.inlineElement; auto e = carat.inlineElement;
if(e is null) if(e is null)
return; return;
if(carat.offset == 0) if(carat.offset == 0) {
return; auto prev = e.getPreviousInlineElement();
carat.inlineElement = prev;
carat.offset = prev is null ? 0 : prev.text.length;
goto try_again;
}
// FIXME: what if it spans parts? // FIXME: what if it spans parts?
if(carat.offset == e.text.length) { if(carat.offset == e.text.length) {
e.text = e.text[0 .. $-1]; e.text = e.text[0 .. $-1];
@ -10737,7 +10853,7 @@ mixin template ExperimentalTextComponent() {
struct Carat { struct Carat {
TextLayout layout; TextLayout layout;
InlineElement* inlineElement; InlineElement inlineElement;
int offset; int offset;
} }