kapstok / NHL-DePa2 (public) (License: Unspecified) (since 2018-11-09) (hash sha1)
Design Patterns school project; a GUI using multiple Design Patterns.
List of commits:
Subject Hash Author Date (UTC)
Fix TODO's from previous commit. 89d8172b77336a6c18f30521147eb81287961f11 Jan Allersma 2018-09-27 14:06:30
Add groups as preparation for step 3. a91368128e7444f69b3a30ee4d17f9063c8846b8 Jan Allersma 2018-09-26 18:31:49
Fix minor bug. Small cleanup 'ellipse' code. 6c911405eb8e48ffe2d63aaff5255adbd4aec889 Jan Allersma 2018-09-21 18:10:01
Implement file I/O. 6219eca932d454a7dab5fe8679f07865ce3cf49d Jan Allersma 2018-09-21 15:52:45
Add shape 'ellipse'. 99d8b029c769bc291af73df3fd445da3cbf5bef4 Jan Allersma 2018-09-21 10:44:36
Add shape 'circle'. 092cb3c3f788b461192a6e164955c53acaf58720 Jan Allersma 2018-09-21 09:35:27
Add resize option (again). 08c95e97268cf9d74bcb963503eec512e528edfe Jan Allersma 2018-09-20 18:09:03
Fix undo bug. 6ab126be633075923cdcce53044e2468f967db41 Jan Allersma 2018-09-20 10:46:50
Implement 'delete shape' feature. 16d42472d44a9dae988c4745c90c791a8770541b Jan Allersma 2018-09-19 09:04:40
Fix undo/redo for 'MoveCmd'. be51bea021bfe5ff79e16a92d350677aed736ddd Jan Allersma 2018-09-19 08:49:55
Implement shapeOptions without undo/redo. bbe699f41e5dacbfdadfaa879452ac2f4501f5a1 Jan Allersma 2018-09-18 19:44:44
WIP: Restore 'shapeOptions.d'. 888b8ea647c0f25cfbeefcd97ee7ebb59e7f0751 Jan Allersma 2018-09-18 15:46:05
Rebuild project from scratch. df0f2f82a86581ba9fa3a169d63a950229341a9f Jan Allersma 2018-09-18 15:04:32
Add resize option. 961e464090918d83690ff66838f2fc96c6ad213a Jan Allersma 2018-09-13 18:29:44
Make `MoveCmd` Command-oriented. 2970a8d862285752551be2464422375ca958357f Jan Allersma 2018-09-12 15:33:17
Change of strategy: Make project command-oriented. ce40dffb1675661922411eeb07f148f61a176c22 Jan Allersma 2018-09-12 11:35:45
Initial commit. 38c8818349679937ae25dde38949202ec45ea7b2 Jan Allersma 2018-09-11 20:21:57
Commit 89d8172b77336a6c18f30521147eb81287961f11 - Fix TODO's from previous commit.
NOTE: Undo/redo doesn't work properly when using a LoadCmd.

It might be worth considering a sepration between Entities and Commands.

It hasn't been tested yet wether recursion on Groups work properly.
Author: Jan Allersma
Author date (UTC): 2018-09-27 14:06
Committer name: Jan Allersma
Committer date (UTC): 2018-10-05 17:17
Parent(s): a91368128e7444f69b3a30ee4d17f9063c8846b8
Signing key:
Tree: f1b9889e0cdd2b618d2b0d2c022858658e9b1806
File Lines added Lines deleted
README.md 0 7
source/canvas.d 1 1
source/commands/create.d 10 13
source/commands/load.d 16 14
source/entities/entity.d 1 0
source/entities/group.d 19 26
source/file.d 38 33
source/frontend/menubar.d 10 10
source/globals.d 1 3
source/groups.d 28 0
source/history.d 8 0
File README.md changed (mode: 100644) (index 533da74..9918e23)
... ... use 'dub' to compile and run the code.
26 26 # Roadmap # Roadmap
27 27
28 28 - Delete group? Hoe? - Delete group? Hoe?
29
30 - File I/O voor groups.
31
32 - Grafische indicatie van een groep.
33
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 6d5c3e8..dd56a96)
... ... public class Canvas : DrawingArea {
68 68 s = new Ellipse(mouseX, mouseY, newContext); s = new Ellipse(mouseX, mouseY, newContext);
69 69 break; break;
70 70 } }
71 Global.History.addCommand(new CreateCmd(s, true));
71 Global.History.addCommand(new CreateCmd(s));
72 72 Global.Brush.group.add(s); Global.Brush.group.add(s);
73 73
74 74 Global.Brush.shape = null; Global.Brush.shape = null;
File source/commands/create.d changed (mode: 100644) (index a772131..ab1e0a4)
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.ent.entity;
4 import dp.ent.shape;
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 Entity e;
10 private bool groupmember;
9 private Shape s;
11 10
12 this(Entity entity, bool groupmember = false) {
13 e = entity;
14 this.groupmember = groupmember;
11 this(Shape shape) {
12 s = shape;
15 13 execute(); // Obsolete, but remained for consistency between 'Command' classes. execute(); // Obsolete, but remained for consistency between 'Command' classes.
16 14 } }
17 15
18 16 public override void execute() { public override void execute() {
19 e.active = true;
17 s.active = true;
20 18 } }
21 19
22 20 public override void undo() { public override void undo() {
23 e.active = false;
21 s.active = false;
24 22 } }
25 23
26 24 public override void render() { public override void render() {
27 //if(!groupmember)
28 e.render();
25 s.render();
29 26 } }
30 27
31 28 public override void check(int x, int y) { public override void check(int x, int y) {
32 e.checkBounds(x,y);
29 s.checkBounds(x,y);
33 30 } }
34 31
35 32 public override void save(Savefile file) { public override void save(Savefile file) {
36 if(!groupmember)
37 file.toFile(e);
33 if(s.saveable)
34 file.toFile(s);
38 35 } }
39 36 } }
File source/commands/load.d changed (mode: 100644) (index ea288ee..b09fa76)
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.ent.entity;
4 import dp.ent.shape;
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 Entity[] entities;
9 private Shape[] shapes;
10 10
11 this(Entity[] entities) {
12 this.entities = entities;
11 this(Shape[] shapes) {
12 this.shapes = shapes;
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(e; entities)
18 e.active = true;
17 foreach(s; shapes)
18 s.active = true;
19 19 } }
20 20
21 21 public override void undo() { public override void undo() {
22 foreach(e; entities)
23 e.active = false;
22 foreach(s; shapes)
23 s.active = false;
24 24 } }
25 25
26 26 public override void render() { public override void render() {
27 foreach(e; entities)
28 e.render();
27 foreach(s; shapes)
28 s.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(e; entities)
33 e.checkBounds(x,y);
32 foreach(s; shapes)
33 s.checkBounds(x,y);
34 34 } }
35 35
36 36 public override void save(Savefile file) { public override void save(Savefile file) {
37 foreach(e; entities)
38 file.toFile(e);
37 foreach(s; shapes) {
38 if(s.saveable)
39 file.toFile(s);
40 }
39 41 } }
40 42 } }
File source/entities/entity.d changed (mode: 100644) (index 010741f..cd94cae)
... ... module dp.ent.entity;
2 2
3 3 class Entity { class Entity {
4 4 public bool active = true; public bool active = true;
5 public bool saveable = true;
5 6
6 7 @property @property
7 8 public abstract string type(); public abstract string type();
File source/entities/group.d changed (mode: 100644) (index 13c1123..c8c43b7)
... ... import dp.file;
6 6
7 7 import std.conv; import std.conv;
8 8 import std.random; import std.random;
9 import std.stdio; // Debug
9 10
10 11 import Global = dp.global; import Global = dp.global;
11 12
12 13 class Group : Entity { class Group : Entity {
13 public int[3] colour; // R, G, B
14 public double[3] colour; // R, G, B
14 15 private Entity[] entities; private Entity[] entities;
15 16
16 17 this() { this() {
 
... ... class Group : Entity {
18 19 entities = []; entities = [];
19 20 active = true; active = true;
20 21 colour = [ colour = [
21 uniform(0x0, 0xFF, random),
22 uniform(0x0, 0xFF, random),
23 uniform(0x0, 0xFF, random)
22 uniform(0.00L, 1.00L, random),
23 uniform(0.00L, 1.00L, random),
24 uniform(0.00L, 1.00L, random)
24 25 ]; ];
26
27 writeln(colour);
25 28 } }
26 29
27 30 @property @property
 
... ... class Group : Entity {
49 52 } }
50 53
51 54 public override void render() { public override void render() {
52 /*if(!active)
53 return;
54
55 float[3] tmp = [
55 double[3] tmp = [
56 56 Global.Brush.red, Global.Brush.red,
57 57 Global.Brush.green, Global.Brush.green,
58 58 Global.Brush.blue Global.Brush.blue
59 59 ]; ];
60 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 } */
61 Global.Brush.red = colour[0];
62 Global.Brush.green = colour[1];
63 Global.Brush.blue = colour[2];
64
65 foreach(e; entities)
66 e.render();
67
68 Global.Brush.red = tmp[0];
69 Global.Brush.green = tmp[1];
70 Global.Brush.blue = tmp[2];
79 71 } }
80 72
81 73 public override void checkBounds(int x, int y) { public override void checkBounds(int x, int y) {
 
... ... class Group : Entity {
88 80 size_t index = entities.length++; size_t index = entities.length++;
89 81
90 82 entities[index] = entity; entities[index] = entity;
83 entity.saveable = false;
91 84 return index; return index;
92 85 } }
93 86
File source/file.d changed (mode: 100644) (index 4d8c67e..cbadc6e)
... ... import std.conv;
6 6 import std.array; import std.array;
7 7 import std.string; import std.string;
8 8
9 import dp.ent.entity;
10 import dp.ent.rect, dp.ent.circle, dp.ent.ellipse;
9 import dp.ent.entity, dp.ent.shape;
10 import dp.ent.rect, dp.ent.circle, dp.ent.ellipse, dp.ent.group;
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, bool fromGroup = false) {
25 if(!shape.active)
26 return;
27
28 if(fromGroup)
29 content ~= "\t";
30
31 content ~= shape.type ~ " ";
32 content ~= to!string(shape.position[0]) ~ " ";
33 content ~= to!string(shape.position[1]) ~ " ";
34 content ~= to!string(shape.size) ~ "\n";
35 }
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 23
45 24 public void toFile(Entity entity) { public void toFile(Entity entity) {
46 25 if(entity.active) if(entity.active)
 
... ... public class Savefile {
48 27 } }
49 28
50 29 public void fromFile() { public void fromFile() {
51 Entity[] entities = [];
30 int depth = 0;
31 Shape[] entities = [];
32 Group group;
33
34 Global.Groups.clear();
52 35 File f = File(filename, "r"); File f = File(filename, "r");
53 36
54 37 while(!f.eof()) { while(!f.eof()) {
 
... ... public class Savefile {
57 40 if(line == "") if(line == "")
58 41 break; break;
59 42
60 entities.length++;
61 entities[entities.length - 1] = parseLine(line);
43 depth = groupsize(line);
44
45 if(depth > 0) {
46 group = Global.Groups.newGroup;
47
48 for(int i = 0; i < depth; i++) {
49 line = strip(f.readln());
50 group.add(parseLine(line)); // Should check wether it is a new group.
51 }
52 } else {
53 entities.length++;
54 entities[entities.length - 1] = parseLine(line);
55 }
62 56 } }
63 57
64 58 f.close(); f.close();
 
... ... public class Savefile {
76 70 content = ""; content = "";
77 71 } }
78 72
79 private Entity parseLine(string line) {
73 // TODO: Should be called by a similar function that checks wether the
74 // line is in a group.
75 private Shape parseLine(string line) {
80 76 auto words = line.split(); auto words = line.split();
81 77
82 78 writeln(words); writeln(words);
 
... ... public class Savefile {
97 93 to!double(words[3]) to!double(words[3])
98 94 ); );
99 95 case "ellipse": case "ellipse":
100 return new Ellipse (
101 to!int(words[1]),
102 to!int(words[2]),
103 Global.canvas.newContext,
104 to!double(words[3])
105 );
96 return new Ellipse (
97 to!int(words[1]),
98 to!int(words[2]),
99 Global.canvas.newContext,
100 to!double(words[3])
101 );
106 102 } }
107 103 } }
104
105 private int groupsize(string line) {
106 auto words = line.split();
107
108 if(words[0] != "group")
109 return 0;
110
111 return to!int(words[1]);
112 }
108 113 } }
File source/frontend/menubar.d changed (mode: 100644) (index 2f2bcf9..8589464)
... ... public class GroupMenu : MenuItem { // protected
174 174 } }
175 175
176 176 private bool activateCallback(Event event, Widget widget) { private bool activateCallback(Event event, Widget widget) {
177 existingGroups.length = Global.Groups.length;
178
179 for(size_t i = 0; i < existingGroups.length; i++) {
180 existingGroups[i] = new MenuItem("Group " ~ to!string(i));
181 existingGroups[i].addOnButtonPress(&exGroupCallback);
182 groupMenu.append(existingGroups[i]);
183 }
184
177 185 showAll(); showAll();
178 186 return false; return false;
179 187 } }
 
... ... public class GroupMenu : MenuItem { // protected
185 193 } }
186 194
187 195 private bool newGroupCallback(Event event, Widget widget) { 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
196 Global.Brush.group = Global.Groups.newGroup;
197 Global.selection.update("Group " ~ to!string(Global.Groups.length-1));
198 198 return true; return true;
199 199 } }
200 200
File source/globals.d changed (mode: 100644) (index 1914165..d85e2e9)
... ... import dp.shapeOptions;
6 6 import dp.ent.group; import dp.ent.group;
7 7
8 8 public import dp.history; public import dp.history;
9 public import dp.groups;
9 10 public import Brush = dp.brush; public import Brush = dp.brush;
10 11
11 12 public static Canvas canvas; public static Canvas canvas;
12 13 public static Selection selection; public static Selection selection;
13 14 public static ShapeOptions shapeOptn; public static ShapeOptions shapeOptn;
14 15
15 public static Group[] groups;
16
17 16 public static void init() { public static void init() {
18 17 selection = new Selection(); selection = new Selection();
19 18 canvas = new Canvas(500,500); canvas = new Canvas(500,500);
20 19 shapeOptn = new ShapeOptions(); shapeOptn = new ShapeOptions();
21 groups = [];
22 20 Brush.clone = null; Brush.clone = null;
23 21 Brush.shape = null; Brush.shape = null;
24 22 Brush.red = 0.5; Brush.red = 0.5;
File source/groups.d added (mode: 100644) (index 0000000..7a0f9e7)
1 module dp.groups;
2
3 import dp.ent.group;
4
5 public static class Groups {
6 private static Group[] groups = [];
7
8 @property
9 public static size_t length() {
10 return groups.length;
11 }
12
13 @property
14 public static Group[] get() {
15 return groups;
16 }
17
18 @property
19 public static Group newGroup() {
20 groups.length++;
21 groups[groups.length-1] = new Group();
22 return groups[groups.length-1];
23 }
24
25 public static void clear() {
26 groups = [];
27 }
28 }
File source/history.d changed (mode: 100644) (index feae2f7..99ebc26)
... ... static class History {
50 50 public static void render() { public static void render() {
51 51 foreach(command; commands) foreach(command; commands)
52 52 command.render(); command.render();
53
54 foreach(group; Global.Groups.get)
55 group.render();
53 56 } }
54 57
55 58 public static void CheckBounds(int x, int y) { public static void CheckBounds(int x, int y) {
 
... ... static class History {
67 70 foreach(command; commands) foreach(command; commands)
68 71 command.save(file); command.save(file);
69 72
73 foreach(group; Global.Groups.get) {
74 if(group.saveable)
75 file.toFile(group);
76 }
77
70 78 file.save(); file.save();
71 79 } }
72 80
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/kapstok/NHL-DePa2

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/kapstok/NHL-DePa2

Clone this repository using git:
git clone git://git.rocketgit.com/user/kapstok/NHL-DePa2

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main