web.d updates

This commit is contained in:
Adam D. Ruppe 2015-08-04 20:49:07 -04:00
parent 7d7b37273d
commit 40fbab4e1f
8 changed files with 198 additions and 10 deletions

7
dom.d
View File

@ -14,9 +14,11 @@
and adding spaces is easier than using LT macros everywhere.
BTW: this file depends on arsd.characterencodings, so help it
correctly read files from the internet. You should be able to
BTW: this file optionally depends on arsd.characterencodings, to
help it correctly read files from the internet. You should be able to
get characterencodings.d from the same place you got this file.
If you want it to stand alone, just always use the `parseUtf8` function.
*/
module arsd.dom;
@ -38,6 +40,7 @@ bool isConvenientAttribute(string name) {
"src", "content", "pattern",
"placeholder", "required", "alt",
"rel",
"method", "action", "enctype"
];
foreach(l; list)
if(name == l) return true;

View File

@ -271,7 +271,7 @@ version(exception_2_example) {
alias enforce = enforceBase!ExceptionBase;
import core.stdc.stdio;
//auto fp = enforce!fopen("nofile.txt".ptr, "rb".ptr);
auto fp = enforce!fopen("nofile.txt".ptr, "rb".ptr);
// construct, passing it error details as data, not strings.

View File

@ -68,8 +68,12 @@ final class OpenGlTexture {
// For easy 2d drawing of it
void draw(Point where, int width = 0, int height = 0, float rotation = 0.0, Color bg = Color.white) {
draw(where.x, where.y, width, height, rotation, bg);
}
void draw(float x, float y, int width = 0, int height = 0, float rotation = 0.0, Color bg = Color.white) {
glPushMatrix();
glTranslatef(where.x, where.y, 0);
glTranslatef(x, y, 0);
glRotatef(rotation, 0,0, 1);
if(width == 0)

View File

@ -904,8 +904,7 @@ struct var {
return this.opEquals(var(t));
}
public bool opEquals(T:var)(T t) {
public bool opEquals(T:var)(T t) const {
// FIXME: should this be == or === ?
if(this._type != t._type)
return false;
@ -1127,7 +1126,8 @@ struct var {
} else if(_type == Type.Object) {
// objects might overload opIndex
var* n = new var();
*n = this["opIndex"](idx);
if("opIndex" in this)
*n = this["opIndex"](idx);
return *n;
}
version(jsvar_throw)

View File

@ -6,6 +6,37 @@
module arsd.minigui;
/*
The main goals of minigui.d are to:
1) Provide basic widgets that just work in a lightweight lib.
I basically want things comparable to a plain HTML form,
plus the easy and obvious things you expect from Windows
apps like a menu.
2) Use native things when possible for best functionality with
least library weight.
3) Give building blocks to provide easy extension for your
custom widgets, or hooking into additional native widgets
I didn't wrap.
4) Provide interfaces for easy interaction between third
party minigui extensions. (event model, perhaps
signals/slots, drop-in ease of use bits.)
5) Zero non-system dependencies, including Phobos as much as
I reasonably can. It must only import arsd.color and
my simpledisplay.d. If you need more, it will have to be
an extension module.
6) An easy layout system that generally works.
A stretch goal is to make it easy to make gui forms with code,
some kind of resource file (xml?) and even a wysiwyg designer.
Another stretch goal is to make it easy to hook data into the gui,
including from reflection. So like auto-generate a form from a
function signature or struct definition, or show a list from an
array that automatically updates as the array is changed. Then,
your program focuses on the data more than the gui interaction.
STILL NEEDED:
* combo box. (this is diff than select because you can free-form edit too. more like a lineedit with autoselect)
* slider

View File

@ -2457,6 +2457,7 @@ version(Windows) {
HWND hwnd;
int oldWidth;
int oldHeight;
bool inSizeMove;
// the extern(Windows) wndproc should just forward to this
int windowProcedure(HWND hwnd, uint msg, WPARAM wParam, LPARAM lParam) {
@ -2476,6 +2477,12 @@ version(Windows) {
case WM_SIZE:
width = LOWORD(lParam);
height = HIWORD(lParam);
// I want to avoid tearing in the windows (my code is inefficient
// so this is a hack around that) so while sizing, we don't trigger,
// but we do want to trigger on events like mazimize.
if(!inSizeMove)
goto size_changed;
break;
// I don't like the tearing I get when redrawing on WM_SIZE
// (I know there's other ways to fix that but I don't like that behavior anyway)
@ -2483,12 +2490,16 @@ version(Windows) {
case 0x0231: /* WM_ENTERSIZEMOVE */
oldWidth = this.width;
oldHeight = this.height;
inSizeMove = true;
break;
case 0x0232: /* WM_EXITSIZEMOVE */
inSizeMove = false;
// nothing relevant changed, don't bother redrawing
if(oldWidth == width && oldHeight == height)
break;
size_changed:
// note: OpenGL windows don't use a backing bmp, so no need to change them
// if resizability is anything other than allowResizing, it is meant to either stretch the one image or just do nothing
if(openglMode == OpenGlOptions.no && resizability == Resizablity.allowResizing) {

View File

@ -3104,6 +3104,145 @@ version(Windows) {
extern(Windows) HRESULT SHGetFolderPathA(HWND, int, HANDLE, DWORD, LPSTR);
}
/* Like getting a line, printing a lot of lines is kinda important too, so I'm including
that widget here too. */
struct ScrollbackBuffer {
struct LineComponent {
string text;
int color = Color.DEFAULT;
int background = Color.DEFAULT;
void delegate() onclick;
}
struct Line {
LineComponent[] components;
int length() {
int l = 0;
foreach(c; components)
l += c.text.length;
return l;
}
}
// FIXME: limit scrollback lines.length
Line[] lines;
string name;
int scrollbackPosition;
void drawInto(Terminal* terminal, in int x, in int y, in int width, in int height) {
if(lines.length == 0)
return;
/* We need to figure out how much is going to fit
in a first pass, so we can figure out where to
start drawing */
int remaining = height + scrollbackPosition;
int start = lines.length;
int howMany = 0;
// we'll work backwards to figure out how much will fit...
// this will give accurate per-line things even with changing width and wrapping
// while being generally efficient - we usually want to show the end of the list
// anyway; actually using the scrollback is a bit of an exceptional case.
foreach_reverse(line; lines) {
int written = 0;
foreach(component; line.components) {
auto towrite = component.text;
written += towrite.length;
while(written > width) {
written -= width;
remaining--;
if(remaining <= 0)
break;
}
}
remaining--;
start--;
howMany++;
if(remaining <= 0)
break;
}
// second pass: actually draw it
int linePos = remaining;
foreach(idx, line; lines[start .. start + howMany]) {
int written = 0;
terminal.moveTo(x, y + ((linePos >= 0) ? linePos : 0));
foreach(component; line.components) {
terminal.color(component.color, component.background);
auto towrite = component.text;
while(linePos < 0 && width < towrite.length) {
towrite = towrite[width .. $];
linePos++;
}
terminal.write(towrite);
written += towrite.length;
while(written > width) {
written -= width;
linePos++;
if(linePos >= height)
break;
}
}
if(written < width)
foreach(i; written .. width)
terminal.write(" ");
linePos++;
if(linePos >= height)
break;
}
foreach(i; linePos .. height) {
if(i >= 0 && i < height) {
terminal.moveTo(x, y + i);
foreach(w; 0 .. width)
terminal.write(" ");
}
}
}
void addLine(string line) {
lines ~= Line([LineComponent(line)]);
}
void scrollUp(int lines = 1) {
scrollbackPosition += lines;
if(scrollbackPosition >= this.lines.length)
scrollbackPosition = this.lines.length - 1;
}
void scrollDown(int lines = 1) {
scrollbackPosition -= lines;
if(scrollbackPosition < 0)
scrollbackPosition = 0;
}
// does scrolling via wheel and keyboard and also clicks on content
void handleEvent() {
}
}
/*
// more efficient scrolling

6
web.d
View File

@ -1843,12 +1843,12 @@ Form createAutomaticForm(Document document, string action, in Parameter[] parame
input.name = param.name;
input.innerText = param.value;
input.rows = "7";
input.attrs.rows = "7";
auto idx = type.indexOf("-");
if(idx != -1) {
idx++;
input.rows = type[idx .. $];
input.attrs.rows = type[idx .. $];
}
} else {
input = Element.make("input");
@ -4021,7 +4021,7 @@ void translateQsa(Document document, Cgi cgi, string logicalScriptName = null) {
string[][string] vars;
foreach(k, v; cgi.getArray)
vars[k] = cast(string[]) v;
foreach(k, v; decodeVariablesSingle(a.qsa)) {
foreach(k, v; decodeVariablesSingle(a.attrs.qsa)) {
if(k in cgi.get && cgi.get[k] == v)
matches++;
possibilities++;