mirror of https://github.com/adamdruppe/arsd.git
initial visual theme thing
This commit is contained in:
parent
f3d22c9bf4
commit
12149ab75d
79
minigui.d
79
minigui.d
|
|
@ -1215,6 +1215,17 @@ struct WidgetPainter {
|
||||||
+/
|
+/
|
||||||
Rectangle[] invalidatedRectangles;
|
Rectangle[] invalidatedRectangles;
|
||||||
|
|
||||||
|
private static IVisualTheme _visualTheme;
|
||||||
|
|
||||||
|
static @property IVisualTheme visualTheme() {
|
||||||
|
if(_visualTheme is null)
|
||||||
|
_visualTheme = new DefaultVisualTheme();
|
||||||
|
return _visualTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
static @property void visualTheme(IVisualTheme theme) {
|
||||||
|
_visualTheme = theme;
|
||||||
|
}
|
||||||
|
|
||||||
// all this stuff is a dangerous experiment....
|
// all this stuff is a dangerous experiment....
|
||||||
static class ScriptableVersion {
|
static class ScriptableVersion {
|
||||||
|
|
@ -2074,7 +2085,10 @@ class Widget {
|
||||||
painter.setClipRectangle(Point(0, 0), width, height);
|
painter.setClipRectangle(Point(0, 0), width, height);
|
||||||
|
|
||||||
erase(painter);
|
erase(painter);
|
||||||
paint(painter);
|
if(painter.visualTheme)
|
||||||
|
painter.visualTheme.doPaint(this, painter);
|
||||||
|
else
|
||||||
|
paint(painter);
|
||||||
|
|
||||||
redrawRequested = false;
|
redrawRequested = false;
|
||||||
actuallyPainted = true;
|
actuallyPainted = true;
|
||||||
|
|
@ -2838,7 +2852,10 @@ class ScrollableWidget : Widget {
|
||||||
painter.setClipRectangle(scrollOrigin + Point(2, 2) /* border */, width - 4, height - 4);
|
painter.setClipRectangle(scrollOrigin + Point(2, 2) /* border */, width - 4, height - 4);
|
||||||
|
|
||||||
//erase(painter); // we paintFrameAndBackground above so no need
|
//erase(painter); // we paintFrameAndBackground above so no need
|
||||||
paint(painter);
|
if(painter.visualTheme)
|
||||||
|
painter.visualTheme.doPaint(this, painter);
|
||||||
|
else
|
||||||
|
paint(painter);
|
||||||
|
|
||||||
actuallyPainted = true;
|
actuallyPainted = true;
|
||||||
redrawRequested = false;
|
redrawRequested = false;
|
||||||
|
|
@ -8939,3 +8956,61 @@ interface Reflectable {
|
||||||
So generally the existing virtual functions are just the default for the class. But individual objects
|
So generally the existing virtual functions are just the default for the class. But individual objects
|
||||||
or stylesheets can override this. The virtual ones count as tag-level specificity in css.
|
or stylesheets can override this. The virtual ones count as tag-level specificity in css.
|
||||||
+/
|
+/
|
||||||
|
|
||||||
|
interface IVisualTheme {
|
||||||
|
void doPaint(Widget widget, WidgetPainter painter);
|
||||||
|
string getProperty(Widget widget, string propertyName);
|
||||||
|
|
||||||
|
final T getProperty(T, string propertyName)(Widget widget) {
|
||||||
|
return T.init;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int baseClassCount(Class)() {
|
||||||
|
int count = 0;
|
||||||
|
static if(is(Class bases == super)) {
|
||||||
|
foreach(base; bases)
|
||||||
|
static if(is(base == class))
|
||||||
|
count += 1 + baseClassCount!base;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class VisualTheme(CRTP) : IVisualTheme {
|
||||||
|
string getProperty(Widget widget, string propertyName) { return null; }
|
||||||
|
|
||||||
|
final void doPaint(Widget widget, WidgetPainter painter) {
|
||||||
|
auto derived = cast(CRTP) cast(void*) this;
|
||||||
|
|
||||||
|
scope void delegate(Widget, WidgetPainter) bestMatch;
|
||||||
|
int bestMatchScore;
|
||||||
|
|
||||||
|
static if(__traits(hasMember, CRTP, "paint"))
|
||||||
|
foreach(overload; __traits(getOverloads, CRTP, "paint")) {
|
||||||
|
static if(is(typeof(overload) Params == __parameters)) {
|
||||||
|
static assert(Params.length == 2);
|
||||||
|
static assert(is(Params[0] : Widget));
|
||||||
|
static assert(is(Params[1] == WidgetPainter));
|
||||||
|
static assert(is(typeof(&__traits(child, derived, overload)) == delegate));
|
||||||
|
|
||||||
|
alias type = Params[0];
|
||||||
|
if(cast(type) widget) {
|
||||||
|
auto score = baseClassCount!type;
|
||||||
|
|
||||||
|
if(score > bestMatchScore) {
|
||||||
|
bestMatch = cast(typeof(bestMatch)) &__traits(child, derived, overload);
|
||||||
|
bestMatchScore = score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else static assert(0, "paint should be a method.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bestMatch)
|
||||||
|
bestMatch(widget, painter);
|
||||||
|
else
|
||||||
|
widget.paint(painter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class DefaultVisualTheme : VisualTheme!DefaultVisualTheme {}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue