File README.md changed (mode: 100644) (index daf3a8e..533da74) |
1 |
1 |
# NHL-DPainter |
# NHL-DPainter |
|
2 |
|
|
2 |
3 |
This repo is a school project for Design Patterns. |
This repo is a school project for Design Patterns. |
3 |
4 |
|
|
4 |
5 |
use 'dub' to compile and run the code. |
use 'dub' to compile and run the code. |
|
... |
... |
use 'dub' to compile and run the code. |
22 |
23 |
|
|
23 |
24 |
- `newPath()`: Clear path from context. |
- `newPath()`: Clear path from context. |
24 |
25 |
|
|
25 |
|
# Vragen |
|
|
26 |
|
# Roadmap |
|
27 |
|
|
|
28 |
|
- Delete group? Hoe? |
|
29 |
|
|
|
30 |
|
- File I/O voor groups. |
26 |
31 |
|
|
27 |
|
- Is het toegstaan om een implementatie aan een interface toe te voegen, zoals |
|
28 |
|
ik in 'command.d' heb gedaan of breekt dit het Command pattern? |
|
|
32 |
|
- Grafische indicatie van een groep. |
29 |
33 |
|
|
30 |
|
- Hoe strict is de grammatica voor de file I/O? Dit programma redeneert vanuit |
|
31 |
|
het centrum van een shape en doet alleen aan non-uniform scaling. Daarom is de |
|
32 |
|
huidige toegepaste grammatica handiger. |
|
|
34 |
|
- `public import Global = dp.global;` en `public import std.stdio; // Debug` |
|
35 |
|
in app.d zetten en daarna alle overbodige imports uit de andere files halen. |
File source/canvas.d changed (mode: 100644) (index 56f90cf..6d5c3e8) |
... |
... |
import gdk.Event; |
5 |
5 |
import cairo.Context; |
import cairo.Context; |
6 |
6 |
import cairo.ImageSurface; |
import cairo.ImageSurface; |
7 |
7 |
|
|
8 |
|
import dp.shape.shape; |
|
9 |
|
import dp.shape.rect, dp.shape.circle, dp.shape.ellipse; |
|
|
8 |
|
import dp.ent.shape; |
|
9 |
|
import dp.ent.rect, dp.ent.circle, dp.ent.ellipse; |
10 |
10 |
import dp.command.create, dp.command.move; |
import dp.command.create, dp.command.move; |
11 |
11 |
|
|
12 |
12 |
import std.stdio; // For debug |
import std.stdio; // For debug |
|
... |
... |
public class Canvas : DrawingArea { |
55 |
55 |
Global.Brush.clone = null; |
Global.Brush.clone = null; |
56 |
56 |
repaint(); |
repaint(); |
57 |
57 |
} |
} |
|
58 |
|
else if(Global.Brush.group !is null && Global.Brush.shape !is null) { |
|
59 |
|
Shape s; |
|
60 |
|
final switch (Global.Brush.shape) { |
|
61 |
|
case "rectangle": |
|
62 |
|
s = new Rectangle(mouseX, mouseY, newContext); |
|
63 |
|
break; |
|
64 |
|
case "circle": |
|
65 |
|
s = new Circle(mouseX, mouseY, newContext); |
|
66 |
|
break; |
|
67 |
|
case "ellipse": |
|
68 |
|
s = new Ellipse(mouseX, mouseY, newContext); |
|
69 |
|
break; |
|
70 |
|
} |
|
71 |
|
Global.History.addCommand(new CreateCmd(s, true)); |
|
72 |
|
Global.Brush.group.add(s); |
|
73 |
|
|
|
74 |
|
Global.Brush.shape = null; |
|
75 |
|
repaint(); |
|
76 |
|
} |
58 |
77 |
else if(Global.Brush.shape !is null) { |
else if(Global.Brush.shape !is null) { |
59 |
78 |
final switch (Global.Brush.shape) { |
final switch (Global.Brush.shape) { |
60 |
79 |
case "rectangle": |
case "rectangle": |
File source/commands/create.d changed (mode: 100644) (index fe3ceae..a772131) |
1 |
1 |
module dp.command.create; |
module dp.command.create; |
2 |
2 |
|
|
3 |
3 |
import dp.command.cmd; |
import dp.command.cmd; |
4 |
|
import dp.shape.shape; |
|
|
4 |
|
import dp.ent.entity; |
5 |
5 |
|
|
6 |
6 |
import Global = dp.global; |
import Global = dp.global; |
7 |
7 |
|
|
8 |
8 |
public class CreateCmd : Command { |
public class CreateCmd : Command { |
9 |
|
private Shape s; |
|
|
9 |
|
private Entity e; |
|
10 |
|
private bool groupmember; |
10 |
11 |
|
|
11 |
|
this(Shape shape) { |
|
12 |
|
s = shape; |
|
|
12 |
|
this(Entity entity, bool groupmember = false) { |
|
13 |
|
e = entity; |
|
14 |
|
this.groupmember = groupmember; |
13 |
15 |
execute(); // Obsolete, but remained for consistency between 'Command' classes. |
execute(); // Obsolete, but remained for consistency between 'Command' classes. |
14 |
16 |
} |
} |
15 |
17 |
|
|
16 |
18 |
public override void execute() { |
public override void execute() { |
17 |
|
s.active = true; |
|
|
19 |
|
e.active = true; |
18 |
20 |
} |
} |
19 |
21 |
|
|
20 |
22 |
public override void undo() { |
public override void undo() { |
21 |
|
s.active = false; |
|
|
23 |
|
e.active = false; |
22 |
24 |
} |
} |
23 |
25 |
|
|
24 |
26 |
public override void render() { |
public override void render() { |
25 |
|
s.render(); |
|
|
27 |
|
//if(!groupmember) |
|
28 |
|
e.render(); |
26 |
29 |
} |
} |
27 |
30 |
|
|
28 |
31 |
public override void check(int x, int y) { |
public override void check(int x, int y) { |
29 |
|
s.checkBounds(x,y); |
|
|
32 |
|
e.checkBounds(x,y); |
30 |
33 |
} |
} |
31 |
34 |
|
|
32 |
35 |
public override void save(Savefile file) { |
public override void save(Savefile file) { |
33 |
|
file.toFile(s); |
|
|
36 |
|
if(!groupmember) |
|
37 |
|
file.toFile(e); |
34 |
38 |
} |
} |
35 |
39 |
} |
} |
File source/commands/load.d changed (mode: 100644) (index cb91ace..ea288ee) |
1 |
1 |
module dp.command.load; |
module dp.command.load; |
2 |
2 |
|
|
3 |
3 |
import dp.command.cmd; |
import dp.command.cmd; |
4 |
|
import dp.shape.shape; |
|
|
4 |
|
import dp.ent.entity; |
5 |
5 |
|
|
6 |
6 |
import Global = dp.global; |
import Global = dp.global; |
7 |
7 |
|
|
8 |
8 |
public class LoadCmd : Command { |
public class LoadCmd : Command { |
9 |
|
private Shape[] shapes; |
|
|
9 |
|
private Entity[] entities; |
10 |
10 |
|
|
11 |
|
this(Shape[] shapes) { |
|
12 |
|
this.shapes = shapes; |
|
|
11 |
|
this(Entity[] entities) { |
|
12 |
|
this.entities = entities; |
13 |
13 |
execute(); // Obsolete, but remained for consistency between 'Command' classes. |
execute(); // Obsolete, but remained for consistency between 'Command' classes. |
14 |
14 |
} |
} |
15 |
15 |
|
|
16 |
16 |
public override void execute() { |
public override void execute() { |
17 |
|
foreach(shape; shapes) |
|
18 |
|
shape.active = true; |
|
|
17 |
|
foreach(e; entities) |
|
18 |
|
e.active = true; |
19 |
19 |
} |
} |
20 |
20 |
|
|
21 |
21 |
public override void undo() { |
public override void undo() { |
22 |
|
foreach(shape; shapes) |
|
23 |
|
shape.active = false; |
|
|
22 |
|
foreach(e; entities) |
|
23 |
|
e.active = false; |
24 |
24 |
} |
} |
25 |
25 |
|
|
26 |
26 |
public override void render() { |
public override void render() { |
27 |
|
foreach(shape; shapes) |
|
28 |
|
shape.render(); |
|
|
27 |
|
foreach(e; entities) |
|
28 |
|
e.render(); |
29 |
29 |
} |
} |
30 |
30 |
|
|
31 |
31 |
public override void check(int x, int y) { |
public override void check(int x, int y) { |
32 |
|
foreach(shape; shapes) |
|
33 |
|
shape.checkBounds(x,y); |
|
|
32 |
|
foreach(e; entities) |
|
33 |
|
e.checkBounds(x,y); |
34 |
34 |
} |
} |
35 |
|
|
|
|
35 |
|
|
36 |
36 |
public override void save(Savefile file) { |
public override void save(Savefile file) { |
37 |
|
foreach(shape; shapes) |
|
38 |
|
file.toFile(shape); |
|
|
37 |
|
foreach(e; entities) |
|
38 |
|
file.toFile(e); |
39 |
39 |
} |
} |
40 |
40 |
} |
} |
File source/entities/circle.d renamed from source/shapes/circle.d (similarity 88%) (mode: 100644) (index 37160e1..00936ce) |
1 |
|
module dp.shape.circle; |
|
|
1 |
|
module dp.ent.circle; |
2 |
2 |
|
|
3 |
3 |
import cairo.Context; |
import cairo.Context; |
4 |
|
import dp.shape.shape; |
|
|
4 |
|
import dp.ent.shape; |
5 |
5 |
import std.conv; |
import std.conv; |
6 |
6 |
|
|
7 |
7 |
import Global = dp.global; |
import Global = dp.global; |
|
... |
... |
class Circle : Shape { |
53 |
53 |
} |
} |
54 |
54 |
|
|
55 |
55 |
protected override void draw() { |
protected override void draw() { |
56 |
|
c.setSourceRgba(Global.Brush.red, Global.Brush.green, Global.Brush.blue, Global.Brush.alpha); |
|
57 |
56 |
c.arc(bounds[0][0] + size, bounds[0][1] + size, size, 0, 2 * pi); |
c.arc(bounds[0][0] + size, bounds[0][1] + size, size, 0, 2 * pi); |
58 |
57 |
} |
} |
59 |
58 |
} |
} |
File source/entities/ellipse.d renamed from source/shapes/ellipse.d (similarity 88%) (mode: 100644) (index 6e1a032..27642ad) |
1 |
|
module dp.shape.ellipse; |
|
|
1 |
|
module dp.ent.ellipse; |
2 |
2 |
|
|
3 |
3 |
import cairo.Context; |
import cairo.Context; |
4 |
|
import dp.shape.shape; |
|
|
4 |
|
import dp.ent.shape; |
5 |
5 |
import std.conv; |
import std.conv; |
6 |
6 |
|
|
7 |
7 |
import Global = dp.global; |
import Global = dp.global; |
|
... |
... |
class Ellipse : Shape { |
53 |
53 |
} |
} |
54 |
54 |
|
|
55 |
55 |
protected override void draw() { |
protected override void draw() { |
56 |
|
c.setSourceRgba(Global.Brush.red, Global.Brush.green, Global.Brush.blue, Global.Brush.alpha); |
|
57 |
|
|
|
58 |
56 |
c.scale(0.5, 1); |
c.scale(0.5, 1); |
59 |
57 |
c.arc(bounds[0][0] * 2 + size, bounds[0][1] + size, size, 0, 2 * pi); |
c.arc(bounds[0][0] * 2 + size, bounds[0][1] + size, size, 0, 2 * pi); |
60 |
58 |
c.scale(2, 1); |
c.scale(2, 1); |
File source/entities/group.d added (mode: 100644) (index 0000000..13c1123) |
|
1 |
|
module dp.ent.group; |
|
2 |
|
|
|
3 |
|
import dp.ent.shape; |
|
4 |
|
import dp.ent.entity; |
|
5 |
|
import dp.file; |
|
6 |
|
|
|
7 |
|
import std.conv; |
|
8 |
|
import std.random; |
|
9 |
|
|
|
10 |
|
import Global = dp.global; |
|
11 |
|
|
|
12 |
|
class Group : Entity { |
|
13 |
|
public int[3] colour; // R, G, B |
|
14 |
|
private Entity[] entities; |
|
15 |
|
|
|
16 |
|
this() { |
|
17 |
|
auto random = rndGen(); |
|
18 |
|
entities = []; |
|
19 |
|
active = true; |
|
20 |
|
colour = [ |
|
21 |
|
uniform(0x0, 0xFF, random), |
|
22 |
|
uniform(0x0, 0xFF, random), |
|
23 |
|
uniform(0x0, 0xFF, random) |
|
24 |
|
]; |
|
25 |
|
} |
|
26 |
|
|
|
27 |
|
@property |
|
28 |
|
public size_t length() { |
|
29 |
|
return entities.length; |
|
30 |
|
} |
|
31 |
|
|
|
32 |
|
@property |
|
33 |
|
public override string type() { |
|
34 |
|
return "group"; |
|
35 |
|
} |
|
36 |
|
|
|
37 |
|
@property |
|
38 |
|
public override string to_string() { |
|
39 |
|
string result = type ~ " " ~ to!string(length) ~ "\n"; |
|
40 |
|
|
|
41 |
|
foreach(e; entities) { |
|
42 |
|
if(e.active) { |
|
43 |
|
result ~= "\t"; |
|
44 |
|
result ~= e.to_string(); |
|
45 |
|
} |
|
46 |
|
} |
|
47 |
|
|
|
48 |
|
return result; |
|
49 |
|
} |
|
50 |
|
|
|
51 |
|
public override void render() { |
|
52 |
|
/*if(!active) |
|
53 |
|
return; |
|
54 |
|
|
|
55 |
|
float[3] tmp = [ |
|
56 |
|
Global.Brush.red, |
|
57 |
|
Global.Brush.green, |
|
58 |
|
Global.Brush.blue |
|
59 |
|
]; |
|
60 |
|
|
|
61 |
|
foreach(e; entities) { |
|
62 |
|
final switch(e.type) { |
|
63 |
|
case "rectangle": |
|
64 |
|
case "circle": |
|
65 |
|
case "ellipse": |
|
66 |
|
Global.Brush.red = 0.3;//colour[0] / 0xFF; |
|
67 |
|
Global.Brush.green = 0.3;//colour[1] / 0xFF; |
|
68 |
|
Global.Brush.blue = 0.3;//colour[2] / 0xFF; |
|
69 |
|
e.render(); |
|
70 |
|
Global.Brush.red = tmp[0]; |
|
71 |
|
Global.Brush.green = tmp[1]; |
|
72 |
|
Global.Brush.blue = tmp[2]; |
|
73 |
|
break; |
|
74 |
|
case "group": |
|
75 |
|
e.render(); |
|
76 |
|
break; |
|
77 |
|
} |
|
78 |
|
} */ |
|
79 |
|
} |
|
80 |
|
|
|
81 |
|
public override void checkBounds(int x, int y) { |
|
82 |
|
if(active) |
|
83 |
|
foreach(e; entities) |
|
84 |
|
e.checkBounds(x,y); |
|
85 |
|
} |
|
86 |
|
|
|
87 |
|
public size_t add(Entity entity) { |
|
88 |
|
size_t index = entities.length++; |
|
89 |
|
|
|
90 |
|
entities[index] = entity; |
|
91 |
|
return index; |
|
92 |
|
} |
|
93 |
|
|
|
94 |
|
public void remove(size_t index) { |
|
95 |
|
for(size_t i = index; i < entities.length; i++) |
|
96 |
|
entities[i] = entities[i+1]; |
|
97 |
|
|
|
98 |
|
entities.length--; |
|
99 |
|
} |
|
100 |
|
|
|
101 |
|
public Entity get(size_t index) { |
|
102 |
|
return entities[index]; |
|
103 |
|
} |
|
104 |
|
} |
File source/entities/rect.d renamed from source/shapes/rect.d (similarity 90%) (mode: 100644) (index 24f1b74..bed8e8d) |
1 |
|
module dp.shape.rect; |
|
|
1 |
|
module dp.ent.rect; |
2 |
2 |
|
|
3 |
3 |
import cairo.Context; |
import cairo.Context; |
4 |
|
import dp.shape.shape; |
|
|
4 |
|
import dp.ent.shape; |
5 |
5 |
import std.conv; |
import std.conv; |
6 |
6 |
|
|
7 |
7 |
import Global = dp.global; |
import Global = dp.global; |
|
... |
... |
class Rectangle : Shape { |
58 |
58 |
} |
} |
59 |
59 |
|
|
60 |
60 |
protected override void draw() { |
protected override void draw() { |
61 |
|
c.setSourceRgba(Global.Brush.red, Global.Brush.green, Global.Brush.blue, Global.Brush.alpha); |
|
62 |
61 |
c.rectangle(bounds[0][0], bounds[0][1], size, size); |
c.rectangle(bounds[0][0], bounds[0][1], size, size); |
63 |
62 |
} |
} |
64 |
63 |
} |
} |
File source/entities/shape.d renamed from source/shapes/shape.d (similarity 65%) (mode: 100644) (index 85bec67..ebd2d4f) |
1 |
|
module dp.shape.shape; |
|
|
1 |
|
module dp.ent.shape; |
2 |
2 |
|
|
3 |
3 |
import cairo.Context; |
import cairo.Context; |
4 |
4 |
import std.conv; |
import std.conv; |
|
5 |
|
import dp.ent.entity; |
|
6 |
|
|
|
7 |
|
import std.stdio; // Debug |
5 |
8 |
|
|
6 |
9 |
import Global = dp.global; |
import Global = dp.global; |
7 |
10 |
|
|
8 |
|
class Shape { |
|
|
11 |
|
class Shape : Entity { |
9 |
12 |
/+ |
/+ |
10 |
13 |
bounds[0][0] = minX |
bounds[0][0] = minX |
11 |
14 |
bounds[1][0] = maxX |
bounds[1][0] = maxX |
|
... |
... |
class Shape { |
13 |
16 |
bounds[1][1] = maxY |
bounds[1][1] = maxY |
14 |
17 |
+/ |
+/ |
15 |
18 |
|
|
|
19 |
|
public double size; |
16 |
20 |
protected Context c; |
protected Context c; |
17 |
21 |
protected double[2][2] bounds; |
protected double[2][2] bounds; |
18 |
|
public double size; |
|
19 |
|
public bool active; |
|
20 |
22 |
|
|
21 |
23 |
this(int x, int y, Context context, double size = 0) { |
this(int x, int y, Context context, double size = 0) { |
22 |
24 |
c = context; |
c = context; |
|
... |
... |
class Shape { |
27 |
29 |
} |
} |
28 |
30 |
|
|
29 |
31 |
@property |
@property |
30 |
|
public abstract string type(); |
|
|
32 |
|
public override string to_string() { |
|
33 |
|
string result = type ~ " "; |
|
34 |
|
result ~= to!string(position[0]) ~ " "; |
|
35 |
|
result ~= to!string(position[1]) ~ " "; |
|
36 |
|
result ~= to!string(size) ~ "\n"; |
|
37 |
|
|
|
38 |
|
return result; |
|
39 |
|
} |
31 |
40 |
|
|
32 |
41 |
// Returns center of shape. |
// Returns center of shape. |
33 |
42 |
@property |
@property |
34 |
43 |
public abstract int[2] position(); |
public abstract int[2] position(); |
35 |
44 |
|
|
36 |
|
/+ |
|
37 |
|
public string toString() { |
|
38 |
|
return text(type, " ", position[0], " ", position[1], " ", size); |
|
39 |
|
} |
|
40 |
|
+/ |
|
41 |
|
|
|
42 |
45 |
public abstract void resize(int amount); |
public abstract void resize(int amount); |
43 |
46 |
|
|
44 |
47 |
protected abstract double[2][2] calcBounds(int x, int y); |
protected abstract double[2][2] calcBounds(int x, int y); |
|
... |
... |
class Shape { |
49 |
52 |
this.bounds = calcBounds(x,y); |
this.bounds = calcBounds(x,y); |
50 |
53 |
} |
} |
51 |
54 |
|
|
52 |
|
public void checkBounds(int x, int y) { |
|
|
55 |
|
public override void checkBounds(int x, int y) { |
53 |
56 |
double[2] p = [to!double(x), to!double(y)]; |
double[2] p = [to!double(x), to!double(y)]; |
54 |
57 |
|
|
55 |
58 |
if ( |
if ( |
|
... |
... |
class Shape { |
62 |
65 |
} |
} |
63 |
66 |
} |
} |
64 |
67 |
|
|
65 |
|
public void render() { |
|
|
68 |
|
public override void render() { |
66 |
69 |
if(active) { |
if(active) { |
|
70 |
|
writeln(type ~ to!string(Global.Brush.red)); |
|
71 |
|
c.setSourceRgba ( |
|
72 |
|
Global.Brush.red, Global.Brush.green, |
|
73 |
|
Global.Brush.blue, Global.Brush.alpha |
|
74 |
|
); |
67 |
75 |
draw(); |
draw(); |
68 |
76 |
c.fill(); |
c.fill(); |
69 |
77 |
} |
} |
File source/file.d changed (mode: 100644) (index 5a454bf..4d8c67e) |
... |
... |
import std.conv; |
6 |
6 |
import std.array; |
import std.array; |
7 |
7 |
import std.string; |
import std.string; |
8 |
8 |
|
|
9 |
|
import dp.shape.shape; |
|
10 |
|
import dp.shape.rect, dp.shape.circle, dp.shape.ellipse; |
|
|
9 |
|
import dp.ent.entity; |
|
10 |
|
import dp.ent.rect, dp.ent.circle, dp.ent.ellipse; |
11 |
11 |
import dp.command.load; |
import dp.command.load; |
12 |
12 |
|
|
13 |
13 |
import Global = dp.global; |
import Global = dp.global; |
|
... |
... |
public class Savefile { |
20 |
20 |
content = ""; |
content = ""; |
21 |
21 |
this.filename = filename; |
this.filename = filename; |
22 |
22 |
} |
} |
23 |
|
|
|
24 |
|
public void toFile(Shape shape) { |
|
|
23 |
|
/* |
|
24 |
|
public void toFile(Shape shape, bool fromGroup = false) { |
25 |
25 |
if(!shape.active) |
if(!shape.active) |
26 |
26 |
return; |
return; |
27 |
27 |
|
|
|
28 |
|
if(fromGroup) |
|
29 |
|
content ~= "\t"; |
|
30 |
|
|
28 |
31 |
content ~= shape.type ~ " "; |
content ~= shape.type ~ " "; |
29 |
32 |
content ~= to!string(shape.position[0]) ~ " "; |
content ~= to!string(shape.position[0]) ~ " "; |
30 |
33 |
content ~= to!string(shape.position[1]) ~ " "; |
content ~= to!string(shape.position[1]) ~ " "; |
31 |
34 |
content ~= to!string(shape.size) ~ "\n"; |
content ~= to!string(shape.size) ~ "\n"; |
32 |
35 |
} |
} |
33 |
36 |
|
|
|
37 |
|
public void toFile(Group group) { |
|
38 |
|
if(group.active) |
|
39 |
|
content ~= "group " ~ to!string(group.length) ~ "\n"; |
|
40 |
|
|
|
41 |
|
group.save(this); |
|
42 |
|
} |
|
43 |
|
*/ |
|
44 |
|
|
|
45 |
|
public void toFile(Entity entity) { |
|
46 |
|
if(entity.active) |
|
47 |
|
content ~= entity.to_string(); |
|
48 |
|
} |
|
49 |
|
|
34 |
50 |
public void fromFile() { |
public void fromFile() { |
35 |
|
Shape[] shapes = []; |
|
|
51 |
|
Entity[] entities = []; |
36 |
52 |
File f = File(filename, "r"); |
File f = File(filename, "r"); |
37 |
53 |
|
|
38 |
54 |
while(!f.eof()) { |
while(!f.eof()) { |
|
... |
... |
public class Savefile { |
41 |
57 |
if(line == "") |
if(line == "") |
42 |
58 |
break; |
break; |
43 |
59 |
|
|
44 |
|
shapes.length++; |
|
45 |
|
shapes[shapes.length - 1] = parseLine(line); |
|
|
60 |
|
entities.length++; |
|
61 |
|
entities[entities.length - 1] = parseLine(line); |
46 |
62 |
} |
} |
47 |
63 |
|
|
48 |
64 |
f.close(); |
f.close(); |
49 |
65 |
|
|
50 |
66 |
Global.History.clear(); |
Global.History.clear(); |
51 |
|
Global.History.addCommand(new LoadCmd(shapes)); |
|
|
67 |
|
Global.History.addCommand(new LoadCmd(entities)); |
52 |
68 |
} |
} |
53 |
69 |
|
|
54 |
70 |
public void save() { |
public void save() { |
|
... |
... |
public class Savefile { |
60 |
76 |
content = ""; |
content = ""; |
61 |
77 |
} |
} |
62 |
78 |
|
|
63 |
|
private Shape parseLine(string line) { |
|
|
79 |
|
private Entity parseLine(string line) { |
64 |
80 |
auto words = line.split(); |
auto words = line.split(); |
65 |
81 |
|
|
66 |
82 |
writeln(words); |
writeln(words); |
File source/frontend/menubar.d changed (mode: 100644) (index 72636ab..2f2bcf9) |
... |
... |
import gtk.MenuBar, gtk.Menu, gtk.MenuItem; |
5 |
5 |
import gtk.Widget; |
import gtk.Widget; |
6 |
6 |
import gdk.Event; |
import gdk.Event; |
7 |
7 |
|
|
8 |
|
import dp.shape.rect; |
|
|
8 |
|
import dp.ent.rect; |
|
9 |
|
import dp.ent.group; |
9 |
10 |
import dp.command.load; |
import dp.command.load; |
|
11 |
|
import dp.command.create; |
|
12 |
|
|
|
13 |
|
import std.conv; |
10 |
14 |
|
|
11 |
15 |
import Global = dp.global; |
import Global = dp.global; |
12 |
16 |
|
|
|
... |
... |
public class Menubar : Box { |
19 |
23 |
menubar.append(new FileMenu()); |
menubar.append(new FileMenu()); |
20 |
24 |
menubar.append(new EditMenu()); |
menubar.append(new EditMenu()); |
21 |
25 |
menubar.append(new ShapeMenu()); |
menubar.append(new ShapeMenu()); |
|
26 |
|
menubar.append(new GroupMenu()); |
22 |
27 |
|
|
23 |
28 |
this.packStart(menubar, false, false, 0); |
this.packStart(menubar, false, false, 0); |
24 |
29 |
} |
} |
|
... |
... |
public class ShapeMenu : MenuItem { // protected |
144 |
149 |
return true; |
return true; |
145 |
150 |
} |
} |
146 |
151 |
} |
} |
|
152 |
|
|
|
153 |
|
public class GroupMenu : MenuItem { // protected |
|
154 |
|
Menu groupMenu; |
|
155 |
|
|
|
156 |
|
MenuItem newGroup; |
|
157 |
|
MenuItem clearGroup; |
|
158 |
|
MenuItem[] existingGroups = []; |
|
159 |
|
|
|
160 |
|
this () { |
|
161 |
|
super("Groups"); |
|
162 |
|
groupMenu = new Menu(); |
|
163 |
|
this.addOnButtonPress(&activateCallback); |
|
164 |
|
|
|
165 |
|
clearGroup = new MenuItem("Clear group selection"); |
|
166 |
|
clearGroup.addOnButtonPress(&clearGroupCallback); |
|
167 |
|
groupMenu.append(clearGroup); |
|
168 |
|
|
|
169 |
|
newGroup = new MenuItem("Add new group"); |
|
170 |
|
newGroup.addOnButtonPress(&newGroupCallback); |
|
171 |
|
groupMenu.append(newGroup); |
|
172 |
|
|
|
173 |
|
setSubmenu(groupMenu); |
|
174 |
|
} |
|
175 |
|
|
|
176 |
|
private bool activateCallback(Event event, Widget widget) { |
|
177 |
|
showAll(); |
|
178 |
|
return false; |
|
179 |
|
} |
|
180 |
|
|
|
181 |
|
private bool clearGroupCallback(Event event, Widget widget) { |
|
182 |
|
Global.Brush.group = null; |
|
183 |
|
Global.selection.update(null); |
|
184 |
|
return true; |
|
185 |
|
} |
|
186 |
|
|
|
187 |
|
private bool newGroupCallback(Event event, Widget widget) { |
|
188 |
|
size_t index = Global.groups.length++; |
|
189 |
|
existingGroups.length = Global.groups.length; |
|
190 |
|
|
|
191 |
|
Global.Brush.group = Global.groups[index] = new Group(); |
|
192 |
|
|
|
193 |
|
existingGroups[index] = new MenuItem("Group " ~ to!string(index)); |
|
194 |
|
existingGroups[index].addOnButtonPress(&exGroupCallback); |
|
195 |
|
groupMenu.append(existingGroups[index]); |
|
196 |
|
exGroupCallback(null, existingGroups[index]); |
|
197 |
|
|
|
198 |
|
return true; |
|
199 |
|
} |
|
200 |
|
|
|
201 |
|
private bool exGroupCallback(Event event, Widget widget) { |
|
202 |
|
MenuItem item = cast(MenuItem) widget; |
|
203 |
|
Global.selection.update(item.getLabel()); |
|
204 |
|
return true; |
|
205 |
|
} |
|
206 |
|
} |
File source/globals.d changed (mode: 100644) (index ccd5fa9..1914165) |
1 |
1 |
module dp.global; |
module dp.global; |
2 |
2 |
|
|
3 |
3 |
import dp.canvas; |
import dp.canvas; |
|
4 |
|
import dp.selection; |
4 |
5 |
import dp.shapeOptions; |
import dp.shapeOptions; |
|
6 |
|
import dp.ent.group; |
5 |
7 |
|
|
6 |
8 |
public import dp.history; |
public import dp.history; |
7 |
9 |
public import Brush = dp.brush; |
public import Brush = dp.brush; |
8 |
10 |
|
|
9 |
11 |
public static Canvas canvas; |
public static Canvas canvas; |
|
12 |
|
public static Selection selection; |
10 |
13 |
public static ShapeOptions shapeOptn; |
public static ShapeOptions shapeOptn; |
11 |
14 |
|
|
|
15 |
|
public static Group[] groups; |
|
16 |
|
|
12 |
17 |
public static void init() { |
public static void init() { |
|
18 |
|
selection = new Selection(); |
13 |
19 |
canvas = new Canvas(500,500); |
canvas = new Canvas(500,500); |
14 |
20 |
shapeOptn = new ShapeOptions(); |
shapeOptn = new ShapeOptions(); |
|
21 |
|
groups = []; |
15 |
22 |
Brush.clone = null; |
Brush.clone = null; |
16 |
23 |
Brush.shape = null; |
Brush.shape = null; |
17 |
24 |
Brush.red = 0.5; |
Brush.red = 0.5; |
18 |
25 |
Brush.green = 0.9; |
Brush.green = 0.9; |
19 |
26 |
Brush.blue = 0.5; |
Brush.blue = 0.5; |
20 |
27 |
Brush.alpha = 0.8; |
Brush.alpha = 0.8; |
|
28 |
|
Brush.group = null; |
21 |
29 |
} |
} |