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)
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 6219eca932d454a7dab5fe8679f07865ce3cf49d - Implement file I/O.
Author: Jan Allersma
Author date (UTC): 2018-09-21 15:52
Committer name: Jan Allersma
Committer date (UTC): 2018-09-21 16:11
Parent(s): 99d8b029c769bc291af73df3fd445da3cbf5bef4
Signing key:
Tree: 006e2d729e0f0c543b84e88ae88fb908900e7f25
File Lines added Lines deleted
README.md 18 1
source/commands/command.d 9 0
source/commands/create.d 4 0
source/commands/load.d 40 0
source/file.d 92 0
source/frontend/menubar.d 47 1
source/history.d 20 0
File README.md changed (mode: 100644) (index 41ac65b..daf3a8e)
... ... use 'dub' to compile and run the code.
6 6 # Useful draw functions for `Context` type # Useful draw functions for `Context` type
7 7
8 8 - `fill()`: fill path, then forget path. - `fill()`: fill path, then forget path.
9
9 10 - `fillPreserve()`: fill path, retain path. - `fillPreserve()`: fill path, retain path.
10 - `fillExtends()`, `strokeExtends()` & `pathExtends()`: return corners (whatever that may be).
11
12 - `fillExtends()`, `strokeExtends()` & `pathExtends()`: return corners
13 (whatever that may be).
14
11 15 - `stroke()`: draw line on path, then forget path. - `stroke()`: draw line on path, then forget path.
16
12 17 - `strokePreserve()`: should be obvious. - `strokePreserve()`: should be obvious.
18
13 19 - `moveTo()`: Move/Pan path. - `moveTo()`: Move/Pan path.
20
14 21 - `scale()`: Scale path. - `scale()`: Scale path.
22
15 23 - `newPath()`: Clear path from context. - `newPath()`: Clear path from context.
24
25 # Vragen
26
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?
29
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.
File source/commands/command.d changed (mode: 100644) (index 0274216..56c688c)
1 1 module dp.command.cmd; module dp.command.cmd;
2 2
3 public import dp.file;
4
3 5 // Should be an interface. Made it a class to prevent the compiler from complaining. // Should be an interface. Made it a class to prevent the compiler from complaining.
4 6 abstract class Command { abstract class Command {
5 7 public abstract void execute(); public abstract void execute();
6 8 public abstract void undo(); public abstract void undo();
7 9 public abstract void render(); public abstract void render();
8 10 public abstract void check(int x, int y); public abstract void check(int x, int y);
11
12 /+
13 The 'save' function should only be overriden by commands that (indirectly)
14 create a new shape (a command that doesn't apply modifications or deletes
15 a shape).
16 +/
17 public void save(Savefile file) {};
9 18 } }
File source/commands/create.d changed (mode: 100644) (index 0383ac4..fe3ceae)
... ... public class CreateCmd : Command {
28 28 public override void check(int x, int y) { public override void check(int x, int y) {
29 29 s.checkBounds(x,y); s.checkBounds(x,y);
30 30 } }
31
32 public override void save(Savefile file) {
33 file.toFile(s);
34 }
31 35 } }
File source/commands/load.d added (mode: 100644) (index 0000000..cb91ace)
1 module dp.command.load;
2
3 import dp.command.cmd;
4 import dp.shape.shape;
5
6 import Global = dp.global;
7
8 public class LoadCmd : Command {
9 private Shape[] shapes;
10
11 this(Shape[] shapes) {
12 this.shapes = shapes;
13 execute(); // Obsolete, but remained for consistency between 'Command' classes.
14 }
15
16 public override void execute() {
17 foreach(shape; shapes)
18 shape.active = true;
19 }
20
21 public override void undo() {
22 foreach(shape; shapes)
23 shape.active = false;
24 }
25
26 public override void render() {
27 foreach(shape; shapes)
28 shape.render();
29 }
30
31 public override void check(int x, int y) {
32 foreach(shape; shapes)
33 shape.checkBounds(x,y);
34 }
35
36 public override void save(Savefile file) {
37 foreach(shape; shapes)
38 file.toFile(shape);
39 }
40 }
File source/file.d added (mode: 100644) (index 0000000..5a454bf)
1 module dp.file;
2
3 import std.stdio;
4 import std.file;
5 import std.conv;
6 import std.array;
7 import std.string;
8
9 import dp.shape.shape;
10 import dp.shape.rect, dp.shape.circle, dp.shape.ellipse;
11 import dp.command.load;
12
13 import Global = dp.global;
14
15 public class Savefile {
16 private string filename;
17 private string content;
18
19 this(string filename) {
20 content = "";
21 this.filename = filename;
22 }
23
24 public void toFile(Shape shape) {
25 if(!shape.active)
26 return;
27
28 content ~= shape.type ~ " ";
29 content ~= to!string(shape.position[0]) ~ " ";
30 content ~= to!string(shape.position[1]) ~ " ";
31 content ~= to!string(shape.size) ~ "\n";
32 }
33
34 public void fromFile() {
35 Shape[] shapes = [];
36 File f = File(filename, "r");
37
38 while(!f.eof()) {
39 string line = strip(f.readln());
40
41 if(line == "")
42 break;
43
44 shapes.length++;
45 shapes[shapes.length - 1] = parseLine(line);
46 }
47
48 f.close();
49
50 Global.History.clear();
51 Global.History.addCommand(new LoadCmd(shapes));
52 }
53
54 public void save() {
55 File f = File(filename, "w");
56
57 f.write(content);
58 f.close();
59
60 content = "";
61 }
62
63 private Shape parseLine(string line) {
64 auto words = line.split();
65
66 writeln(words);
67
68 final switch(words[0]) {
69 case "rectangle":
70 return new Rectangle (
71 to!int(words[1]),
72 to!int(words[2]),
73 Global.canvas.newContext,
74 to!double(words[3])
75 );
76 case "circle":
77 return new Circle (
78 to!int(words[1]),
79 to!int(words[2]),
80 Global.canvas.newContext,
81 to!double(words[3])
82 );
83 case "ellipse":
84 return new Ellipse (
85 to!int(words[1]),
86 to!int(words[2]),
87 Global.canvas.newContext,
88 to!double(words[3])
89 );
90 }
91 }
92 }
File source/frontend/menubar.d changed (mode: 100644) (index bbb3b9f..72636ab)
... ... import gtk.Widget;
6 6 import gdk.Event; import gdk.Event;
7 7
8 8 import dp.shape.rect; import dp.shape.rect;
9 import dp.command.load;
9 10
10 11 import Global = dp.global; import Global = dp.global;
11 12
 
... ... public class Menubar : Box {
15 16
16 17 MenuBar menubar = new MenuBar(); MenuBar menubar = new MenuBar();
17 18
18 //menubar.append(new FileMenu());
19 menubar.append(new FileMenu());
19 20 menubar.append(new EditMenu()); menubar.append(new EditMenu());
20 21 menubar.append(new ShapeMenu()); menubar.append(new ShapeMenu());
21 22
 
... ... public class Menubar : Box {
23 24 } }
24 25 } }
25 26
27 public class FileMenu : MenuItem { // protected
28 Menu fileMenu;
29
30 MenuItem newFile;
31 MenuItem save;
32 MenuItem open;
33
34 this () {
35 super("File");
36 fileMenu = new Menu();
37
38 newFile = new MenuItem("New");
39 newFile.addOnButtonPress(&newCallback);
40 fileMenu.append(newFile);
41
42 save = new MenuItem("Save");
43 save.addOnButtonPress(&saveCallback);
44 fileMenu.append(save);
45
46 open = new MenuItem("Open");
47 open.addOnButtonPress(&openCallback);
48 fileMenu.append(open);
49
50 setSubmenu(fileMenu);
51 }
52
53 private bool newCallback(Event event, Widget widget) {
54 Global.History.clear();
55 Global.History.addCommand(new LoadCmd([]));
56 Global.canvas.repaint();
57 return true;
58 }
59
60 private bool saveCallback(Event event, Widget widget) {
61 Global.History.save("./test.sav");
62 return true;
63 }
64
65 private bool openCallback(Event event, Widget widget) {
66 Global.History.load("./test.sav");
67 Global.canvas.repaint();
68 return true;
69 }
70 }
71
26 72 public class EditMenu : MenuItem { // protected public class EditMenu : MenuItem { // protected
27 73 Menu editMenu; Menu editMenu;
28 74
File source/history.d changed (mode: 100644) (index e439364..feae2f7)
1 1 module dp.history; module dp.history;
2 2
3 3 import dp.command.cmd; import dp.command.cmd;
4 import dp.file;
4 5
5 6 import Global = dp.global; // Geen dependency-cycle? import Global = dp.global; // Geen dependency-cycle?
6 7
 
... ... static class History {
55 56 foreach(command; commands) foreach(command; commands)
56 57 command.check(x,y); command.check(x,y);
57 58 } }
59
60 public static void clear() {
61 cmdPtr = 0;
62 }
63
64 public static void save(string filename) {
65 Savefile file = new Savefile(filename);
66
67 foreach(command; commands)
68 command.save(file);
69
70 file.save();
71 }
72
73 public static void load(string filename) {
74 Savefile file = new Savefile(filename);
75
76 file.fromFile();
77 }
58 78 } }
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