## digitalmars.D - Re: simple display (from: GUI library for D)

bearophile <bearophileHUGS lycos.com> writes:
```Adam D. Ruppe:

Here's the D version using the direct to screen functions.

http://rosettacode.org/wiki/Fractal_tree#Python
http://rosettacode.org/wiki/Brownian_tree

The JavaScript processing port site has some more examples in the Demos section:
http://processingjs.org/exhibition

Bye,
bearophile
```
Apr 09 2011
Adam D. Ruppe <destructionator gmail.com> writes:
```bearophile wrote:
http://rosettacode.org/wiki/Fractal_tree#Python

This one's use of recursion caused me to hit what I think is a
compiler bug. Not in the recursion itself, but in a struct's
copy constructor when it had a significant mixin.

I worked around it by declaring a private struct and using a pointer
to it rather than mixing in the implementation directly. I believe
this will be a net-positive too, since ScreenPainter is now
referenced counted.

Here's the implementation:

====
import simpledisplay;
import std.math;

void main() {
// auto image = new Image(600, 600);
auto window = new SimpleWindow(600, 600, "Fractal Tree");

void drawTree(ScreenPainter p, in int x1, in int y1, in real angle, in int
depth) {
if(depth == 0)
return;
immutable x2 = x1 + cast(int) (cos(angle) * depth * 10);
immutable y2 = y1 + cast(int) (sin(angle) * depth * 10);
p.drawLine(Point(x1, y1), Point(x2, y2));

drawTree(p, x2, y2, angle - 0.35, depth - 1);
drawTree(p, x2, y2, angle + 0.35, depth - 1);
}

drawTree(window.draw, 300, 550, -PI / 2, 9);
window.eventLoop(0, (dchar) { window.close(); });
// displayImage(image);
}

===

The reason Image is there, but commented out, is that such things
might be better done as images, then displayed once finished.
But, since we don't have drawing lines to images yet*, I went

(well, I do have my implementation of Bresenham's algorithm, but I
want to see Mathias' code before falling back on mine. Mine worked
well for DOS, but better anti-aliasing is expected nowadays.)

DrawTree takes an existing ScreenPainter so I can limit it's scope
to only where it's used. The new reference counting under the hood
means that while the struct is copied several times here, it isn't
wasteful.

The eventLoop inline delegate allows you to close the window by
pressing any key as well as using the button in the corner. I
don't think the Python version on rosetta code would allow this.

Comparing to the Python version, mine is a little shorter, primarily
due to the much simpler initialization. The Python one took three
lines to do what SimpleWindow's constructor does in one. I also
put the "get_surface" kind of thing that allows drawing inline
to the drawTree line. Like I said above, this was for reasons of
scope, but it coincidentally shaves a line too. As does the struct
destructor doing the job of display.flip().

The last place where I save a couple lines is the event loop, doing
all that in one place instead of a separate function, loop, and
fetcher. (Note: the delegate in there is not strictly necessary!
It handles quit events sanely by default.)

All in all, I'm very happy with this approach so far. It's simple,
it's short, it's readable, it's reasonably efficient, and the
implementation is moderately lean. Everything I was hoping for!
```
Apr 09 2011
```Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit

Am 10.04.2011 04:30, schrieb Adam D. Ruppe:
bearophile wrote:
http://rosettacode.org/wiki/Fractal_tree#Python

This one's use of recursion caused me to hit what I think is a
compiler bug. Not in the recursion itself, but in a struct's
copy constructor when it had a significant mixin.

I worked around it by declaring a private struct and using a pointer
to it rather than mixing in the implementation directly. I believe
this will be a net-positive too, since ScreenPainter is now
referenced counted.

Here's the implementation:

====
import simpledisplay;
import std.math;

void main() {
// auto image = new Image(600, 600);
auto window = new SimpleWindow(600, 600, "Fractal Tree");

void drawTree(ScreenPainter p, in int x1, in int y1, in real angle, in int
depth) {
if(depth == 0)
return;
immutable x2 = x1 + cast(int) (cos(angle) * depth * 10);
immutable y2 = y1 + cast(int) (sin(angle) * depth * 10);
p.drawLine(Point(x1, y1), Point(x2, y2));

drawTree(p, x2, y2, angle - 0.35, depth - 1);
drawTree(p, x2, y2, angle + 0.35, depth - 1);
}

drawTree(window.draw, 300, 550, -PI / 2, 9);
window.eventLoop(0, (dchar) { window.close(); });
// displayImage(image);
}

===

The reason Image is there, but commented out, is that such things
might be better done as images, then displayed once finished.
But, since we don't have drawing lines to images yet*, I went

(well, I do have my implementation of Bresenham's algorithm, but I
want to see Mathias' code before falling back on mine. Mine worked
well for DOS, but better anti-aliasing is expected nowadays.)

DrawTree takes an existing ScreenPainter so I can limit it's scope
to only where it's used. The new reference counting under the hood
means that while the struct is copied several times here, it isn't
wasteful.

The eventLoop inline delegate allows you to close the window by
pressing any key as well as using the button in the corner. I
don't think the Python version on rosetta code would allow this.

Comparing to the Python version, mine is a little shorter, primarily
due to the much simpler initialization. The Python one took three
lines to do what SimpleWindow's constructor does in one. I also
put the "get_surface" kind of thing that allows drawing inline
to the drawTree line. Like I said above, this was for reasons of
scope, but it coincidentally shaves a line too. As does the struct
destructor doing the job of display.flip().

The last place where I save a couple lines is the event loop, doing
all that in one place instead of a separate function, loop, and
fetcher. (Note: the delegate in there is not strictly necessary!
It handles quit events sanely by default.)

All in all, I'm very happy with this approach so far. It's simple,
it's short, it's readable, it's reasonably efficient, and the
implementation is moderately lean. Everything I was hoping for!

Ok, this is what I have so far.
It's code, I have written one year ago and is based on AntiGrain , which
is based on freetype2, which is based on libart?
AntiGrain is under the modified BSD-license.
To prevent license-issues(if it should go into phobos) and to get a
faster version, I'v started form scratch, but this is not finished yet.
But you can get an idea, how it should work.

(well, I do have my implementation of Bresenham's algorithm, but ..

simple lines, I think Bresenham's algorithm (also anti-aliased) will
maybe faster (fewer overhead), but for thicker lines with different
caps, you need polygons anyway, so ...

In the test.d file is an example, which produce the image (.ppm) I have
posted.
(note, you need the Color struct form simpledisplay.d)

have fun,

°Matthias
```
Apr 09 2011
bearophile <bearophileHUGS lycos.com> writes:
```Adam D. Ruppe:

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.

It's better to support multiple windows, otherwise you have to split the single
window "manually" if you want a window with a simulation and a window with a

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.

I don't agree. line(), box(), circle(), etc are so easy to remember and common
that I don't see the need to keep the names of the functions under them.

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.

I don't agree. It's _very_ easy to understand that p.line() is to add a line,
there is no chance of confusion here, the verb of p.drawLine() is implied.

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

In this module shaded pens are less important than usage simplicity. I suggest
to keep things simple here.

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

I think it's acceptable :-)

----------------------------

This one's use of recursion caused me to hit what I think is a
compiler bug. Not in the recursion itself, but in a struct's
copy constructor when it had a significant mixin.

Where is the updated display module?
This doesn't seem to be updated yet:
http://arsdnet.net/dcode/simpledisplay.d

In your little program drawTree() is better "static" (or better, moved out of
the main).

window.eventLoop(0, (dchar){ window.close(); });
==> Default arguments?
window.eventLoop();

Comparing to the Python version, mine is a little shorter,

PyGame is also quite more powerful than your simpledisplay module, you can
write small video games with it. So its API is a little more complex.

All in all, I'm very happy with this approach so far. It's simple,
it's short, it's readable, it's reasonably efficient, and the
implementation is moderately lean. Everything I was hoping for!

Before freezing the API design I suggest to implement many more quite different
examples. Designing APIs is something that can't be done in a hurry :-)

Two features are quite important:

Mouse position, mouse clicks, keys pressed:
http://processingjs.org/learning/topic/pattern

Text:
http://processingjs.org/learning/topic/tickle

---------------

Few more useful features for later:

Transparency:
http://processingjs.org/learning/topic/follow2

Antialiasing:
http://processing.org/learning/topics/penrosetile.html

Polygons, curves:
http://processing.org/learning/topics/softbody.html

http://processingjs.org/learning/topic/blur

Save screen:
http://processing.org/learning/topics/saveoneimage.html

Sprites:
http://processing.org/learning/topics/unlimitedsprites.html

Bye,
bearophile
```
Apr 10 2011
Cliff Hudson <cliff.s.hudson gmail.com> writes:
```--00032555f6c6d5149504a093aa63
Content-Type: text/plain; charset=ISO-8859-1

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.

I don't agree. line(), box(), circle(), etc are so easy to remember and
common that I don't see the need to keep the names of the functions under
them.

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.

I don't agree. It's _very_ easy to understand that p.line() is to add a
line, there is no chance of confusion here, the verb of p.drawLine() is
implied.

design (it just strikes me as weird all around actually.)  If this were
retained mode, something like p.Add(Line(...)) would make sense.  But if the
action is to draw a line, and the target of that action is object p, then
p.drawLine is the most sensible.  The objective here is not to relieve the
user of typing, but to ensure the code is unambiguously clear.  Imagine
p.box. What does that mean?  Draw a box?  Or are we boxing p into some
portable format?  I agree with Adam's original thought that methods should
be verbs.  At least to my mind is reads easier.  YMMV.

- Cliff

--00032555f6c6d5149504a093aa63
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class=
=3D"im">
&gt; Heh, I used to call it box in my DOS programs. But, the functions<br>
&gt; it forwards to are called Rectangle() and XDrawRectangle(), so<br>
&gt; I want to be consistent with them so it&#39;s not a surprise to<br>
&gt; someone already familiar with with the other APIs.<br>
<br>
</div>I don&#39;t agree. line(), box(), circle(), etc are so easy to rememb=
er and common that I don&#39;t see the need to keep the names of the functi=
ons under them.<br>
<div class=3D"im"><br>
<br>
&gt; The reason I went with drawShape instead of just Shape is that<br>
&gt; functions are verbs, so generally, I like their names to be<br>
&gt; verbs too. There&#39;s exceptions, of course, but I don&#39;t these<br=

<br>
</div>I don&#39;t agree. It&#39;s _very_ easy to understand that p.line() i=
s to add a line, there is no chance of confusion here, the verb of p.drawLi=
ne() is implied.<br>
<div class=3D"im"><br></div></blockquote><div>=A0</div><div>I would argue t=
hat p.line is inconsistent with an immediate-mode drawing API design (it ju=
st strikes me as weird all around actually.) =A0If this were retained mode,=
something like p.Add(Line(...)) would make sense. =A0But if the action is =
to draw a line, and the target of that action is object p, then p.drawLine =
is the most sensible. =A0The objective here is not to relieve the user of t=
yping, but to ensure the code is unambiguously clear. =A0Imagine p.box. Wha=
t does that mean? =A0Draw a box? =A0Or are we boxing p into some portable f=
ormat? =A0I agree with Adam&#39;s original thought that methods should be v=
erbs. =A0At least to my mind is reads easier. =A0YMMV.</div>
<div><br></div><div>- Cliff</div></div>

--00032555f6c6d5149504a093aa63--
```
Apr 10 2011