simple display (from: GUI library for D)

Adam D. Ruppe destructionator at gmail.com
Sat Apr 9 17:58:33 PDT 2011


bearophile wrote:
> The length=150 too is better to be set as immutable.

Yeah, I made that change after copy/pasting the code into my
newsgroup post. win, painter, angle, and angular velocity were
the only things left mutable in the end.

> The delegate inside eventLoop doesn't need the ().

I put it there for consistency with other events. While there
are no other handlers in this example, there can be, and all the
other ones take arguments.

> Color(255, 255, 255) ==> Color.white
> painter.clearAll(Color.white)
> auto win = new SimpleWindow(512, 512, "Pendulum");

Yeah, those are reasonable.

> win.eventLoop(10, {...})  does this semantics work with more than
> one window too?

I believe so, yes, but I haven't tried it and wouldn't mind if
it didn't. If you need to use multiple windows at the same time,
it'd probably be better to use DFL, DWT, GTK, Qt, etc. etc.

> drawRectangle => rectangle or even "box"

Heh, I used to call it box in my DOS programs. But, the functions
it forwards to are called Rectangle() and XDrawRectangle(), so
I want to be consistent with them so it's not a surprise to
someone already familiar with with the other APIs.

The reason I went with drawShape instead of just Shape is that
functions are verbs, so generally, I like their names to be
verbs too. There's exceptions, of course, but I don't these
fit.

> outline => pen?

Pens do more than just color. I guess the real question is how
complex should it be able to get?

In the underlying APIs, you can make a pen with a color, a
width, and a style (solid, dashed, etc). Since they both can
do it, I think I will add it.

(Some more advanced APIs can even do things like gradient pens. I
hope the image manipulation functions we write will eventually
be able to do this too, but since plain old X can't, it won't
happen for the display painter.)

Perhaps:

painter.pen = Pen(Color(r, g, b), 1, Pen.Style.solid);

(Or maybe new Pen()... have to think about that.)

And offer an overload for the simple case where you only care
about color. (or keep the current fillColor property.)

Then, of course, something similar for Brush, which is used
to fill the background.

But, here, the idea was to keep it simple, so I went with just
color. I guess that might be too simple.

> This is not so nice...

I'm sympathetic, but I don't agree losing the struct would be good.

Even if the struct proves to be unnecessary (which it might be - I
think you can hold on to a window HDC as long as you like, but it's
not something I see often so I think it's discouraged), I'd still
keep it.

Having an automatic constructor and destructor available gives
some flexibility on the implementation side without inconveniencing
the user beyond a single function.

For example, the implicit double buffering done here. You don't
have to think about flipping it. It just works. Better yet, the
implementation can disable it at will. BitBlt is slow over Remote
Desktop on Windows, making double buffering laggy. But, you, the
user, don't really need to know that, since it wasn't your problem
in the first place. The ScreenPainter can make it's own decision
about it.

> Reading keyboard chars, and mouse clicks & movements is very
> useful.

For that, you can pass other handlers to eventLoop. I still intend
to define a few more you can use.

> Another useful thing is to plot a matrix of rgb or int or ubyte
> in grey shades, to speed up some basic usage. In PyGame/Numpy
> there is surfarray for this.

Sounds like what you'd use the Image class for, so I think we're
good on that too.


====

A note: since I posted last, I changed my mind on something, and
bearophile, I rather doubt you'll like it...

Before, it was drawRectangle(int x1, int y2, int width, int height);

Now, it is drawRectangle(Point upperLeft, Size size);

So, at the usage, you now need to put in some more parenthesis
and say what you mean:

painter.drawRectangle(Point(0, 0), Size(win.width, win.height));


Why did I do this? Well, consider the following:

drawRectangle(int x1, int y1, int x2, int y2);

(This is, in fact, the signature in Windows GDI, whereas Xlib
 user width/height.)


The types there are no different than the above, but meaning has
changed. I'd be ok with saying "RTFM" to avoid having to use
the structs.

But, RTFM doesn't let you overload it, whereas the types do. Now,
it can offer both

drawRectangle(Point upperLeft, Size size);

*and*

drawRectangle(Point upperLeft, Point lowerRight);

I'm sure you were thinking about named arguments for a moment
there about width/height vs x2/y2. I did too. But, named arguments
don't really exist in D (you can do them via library magic but not
without) so it's moot, and I don't believe named arguments would
offer the overloading possibilities, which I like. It can save
some math while being quite natural.

The Point struct also makes drawPolygon look a lot better, so
it's of general use.


More information about the Digitalmars-d mailing list