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)
Build interface for ornament creation. adcf22a4e878edc45ac0775a5e15ebf0bb1a937d Jan Allersma 2018-10-08 13:53:52
Use different strats instead of seperate Shapes. a56e1e665a0292d15139eddfd8ebdeb8c95251b4 Jan Allersma 2018-10-01 11:37:45
Fix bug in Rect from commit 6c91140 in other Shapes as well. 4165a5da98dd9a548a222c6160390e4e54026d48 Jan Allersma 2018-09-28 14:53:40
Fully implement File I/O. 45cbb48489a24857cfc76144b38b12ccebfd9e61 Jan Allersma 2018-09-27 16:03:40
Fix GroupMenu bug. be41e51819be1a23e7761ea0662eb188ac641aca Jan Allersma 2018-09-27 14:55:20
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
Commit adcf22a4e878edc45ac0775a5e15ebf0bb1a937d - Build interface for ornament creation.
Note: This interface is still a 'dummy' interface.
To use: right-click on a shape.

I assume that in order for the interface to work properly, the project needs to be refactored in a way that 'Group' is a member of a 'Shape'. That way either the shape or the group could get a new ornament with just needing a reference to the shape.
Author: Jan Allersma
Author date (UTC): 2018-10-08 13:53
Committer name: Jan Allersma
Committer date (UTC): 2018-10-16 13:42
Parent(s): a56e1e665a0292d15139eddfd8ebdeb8c95251b4
Signing key:
Tree: e6644861eeb3bcea820dbb7b15e6210fb8e62f16
File Lines added Lines deleted
source/canvas.d 0 1
source/entities/shape.d 0 5
source/frontend/ornamentDialog.d 103 0
source/frontend/shapeOptions.d 15 1
source/strategies/circle.d 2 4
source/strategies/ellipse.d 2 4
source/strategies/rect.d 2 6
File source/canvas.d changed (mode: 100644) (index b7e5700..da3cd65)
... ... public class Canvas : DrawingArea {
79 79 else if(Global.Brush.shape !is null) { else if(Global.Brush.shape !is null) {
80 80 final switch (Global.Brush.shape) { final switch (Global.Brush.shape) {
81 81 case "rectangle": case "rectangle":
82 writeln("Canvas instantiating rect..");
83 82 Global.History.addCommand(new CreateCmd(new Shape(mouseX, mouseY, newContext, rect))); Global.History.addCommand(new CreateCmd(new Shape(mouseX, mouseY, newContext, rect)));
84 83 break; break;
85 84 case "circle": case "circle":
File source/entities/shape.d changed (mode: 100644) (index cd6c655..e6d4060)
... ... import dp.ent.entity;
4 4 import dp.strat.strat; import dp.strat.strat;
5 5 import cairo.Context; import cairo.Context;
6 6 import std.conv; import std.conv;
7 import std.stdio; // Debug
8 7
9 8 import Global = dp.global; import Global = dp.global;
10 9
 
... ... class Shape : Entity {
22 21 private Strategy strat; private Strategy strat;
23 22
24 23 this(int x, int y, Context context, Strategy strategy, double size = 0) { this(int x, int y, Context context, Strategy strategy, double size = 0) {
25 writeln("Entered constructor of shape.");
26 24 c = context; c = context;
27 25 active = true; active = true;
28 26 this.strat = strategy; this.strat = strategy;
29 27 this.size = size != 0 ? size : strat.initialSize; this.size = size != 0 ? size : strat.initialSize;
30 28 this.bounds = calcBounds(x,y); this.bounds = calcBounds(x,y);
31 writeln("Done! " ~ to!string(getBounds) ~ to!string(getSize));
32 29 } }
33 30
34 31 @property @property
 
... ... class Shape : Entity {
89 86 Global.Brush.red, Global.Brush.green, Global.Brush.red, Global.Brush.green,
90 87 Global.Brush.blue, Global.Brush.alpha Global.Brush.blue, Global.Brush.alpha
91 88 ); );
92 writeln("Rendering..");
93 89 strat.draw(this); strat.draw(this);
94 90 c.fill(); c.fill();
95 writeln("Done!");
96 91 } }
97 92 } }
98 93
File source/frontend/ornamentDialog.d added (mode: 100644) (index 0000000..5b5a173)
1 module dp.win.ornament;
2
3 import gtk.Dialog;
4 import gtk.MessageDialog;
5 import gtk.Label;
6 import gtk.Button;
7 import gtk.Entry;
8 import gtk.RadioButton, gtk.ToggleButton;
9 import gtk.Box;
10
11 import dp.ent.shape;
12
13 import Global = dp.global;
14
15 class OrnamentDialog : Dialog {
16 Shape shape;
17 Entry factorEntry;
18 RadioButton topRd, bottomRd, leftRd, rightRd;
19 string position = "Top"; // Default value since 'topRd' is mnemonic.
20
21 this(Shape shape) {
22 super();
23 setTitle("Attach ornament");
24 this.shape = shape;
25
26 Box box = new Box(Orientation.VERTICAL, 50);
27
28 Box rdBox = new Box(Orientation.HORIZONTAL, 30);
29 Box rdBox1 = new Box(Orientation.VERTICAL, 15);
30 Box rdBox2 = new Box(Orientation.VERTICAL, 15);
31 topRd = new RadioButton("Top");
32 bottomRd = new RadioButton(topRd, "Bottom", false);
33 leftRd = new RadioButton(topRd, "Left", false);
34 rightRd = new RadioButton(topRd, "Right", false);
35
36 topRd.addOnToggled(&toggledRd);
37 bottomRd.addOnToggled(&toggledRd);
38 leftRd.addOnToggled(&toggledRd);
39 rightRd.addOnToggled(&toggledRd);
40
41 rdBox1.add(topRd);
42 rdBox1.add(leftRd);
43 rdBox2.add(bottomRd);
44 rdBox2.add(rightRd);
45 rdBox.add(rdBox1);
46 rdBox.add(rdBox2);
47
48 factorEntry = new Entry();
49 factorEntry.setPlaceholderText("Enter ornament text here");
50
51 Box btnBox = new Box(Orientation.HORIZONTAL, 30);
52 Button shapeBtn = new Button("Add ornament to shape", &clickCallback);
53 Button groupBtn = new Button("Add ornament to group", &clickCallback);
54
55 btnBox.add(shapeBtn);
56 btnBox.add(groupBtn);
57
58 // Content area, containing non-interactable GTK objects.
59 getContentArea().add(new Label("Position of ornament relative to shape/group:"));
60 getContentArea().setBorderWidth(20);
61
62 // Action area, containing interactable GTK objects.
63 box.add(rdBox);
64 box.add(factorEntry);
65 box.add(btnBox);
66 getActionArea().add(box);
67 getActionArea().setBorderWidth(30);
68
69 showAll();
70 }
71
72 private void clickCallback (Button button) {
73 string input = factorEntry.getText();
74
75 if(input != "") {
76 final switch(position) {
77 case "Top":
78 break;
79 case "Bottom":
80 break;
81 case "Left":
82 break;
83 case "Right":
84 break;
85 }
86 this.close();
87 }
88 else {
89 MessageDialog msgd = new MessageDialog (
90 this, DialogFlags.MODAL, MessageType.ERROR, ButtonsType.OK,
91 "Please enter a value.",
92 null
93 );
94 scope(exit) msgd.destroy();
95 msgd.run();
96 }
97 }
98
99 private void toggledRd(ToggleButton rd) {
100 if(rd.getActive)
101 position = rd.getLabel();
102 }
103 }
File source/frontend/shapeOptions.d changed (mode: 100644) (index 4cc0932..d0e98b5)
... ... import gdk.Event;
6 6
7 7 import dp.ent.shape; import dp.ent.shape;
8 8 import dp.command.destruct; import dp.command.destruct;
9 import dp.win.resize;
9 import dp.win.resize, dp.win.ornament;
10 10 import Global = dp.global; import Global = dp.global;
11 11
12 12 import std.stdio; // For debugging. import std.stdio; // For debugging.
13 13
14 14 protected Shape s; protected Shape s;
15 15 protected ResizeDialog rd; protected ResizeDialog rd;
16 protected OrnamentDialog od;
16 17
17 18 public class ShapeOptions : Menu { public class ShapeOptions : Menu {
18 19 this() { this() {
 
... ... public class ShapeOptions : Menu {
20 21 this.append(new DeleteShape()); this.append(new DeleteShape());
21 22 this.append(new MoveShape()); this.append(new MoveShape());
22 23 this.append(new ResizeShape()); this.append(new ResizeShape());
24 this.append(new AddOrnament());
23 25 } }
24 26
25 27 public void selectShape (Shape shape) { // Shows options of param shape. public void selectShape (Shape shape) { // Shows options of param shape.
 
... ... protected class ResizeShape : MenuItem {
67 69 return false; // Hide ShapeOptions when button is released. return false; // Hide ShapeOptions when button is released.
68 70 } }
69 71 } }
72
73 protected class AddOrnament : MenuItem {
74 this() {
75 super("Attach ornament");
76 addOnButtonRelease(&relCallback);
77 }
78
79 private bool relCallback (Event event, Widget widget) {
80 od = new OrnamentDialog(s);
81 return false; // Hide ShapeOptions when button is released.
82 }
83 }
File source/strategies/circle.d changed (mode: 100644) (index 19ff8f3..9c3e051)
... ... import dp.strat.strat;
5 5 private static CircleDrawer _circle; private static CircleDrawer _circle;
6 6
7 7 public static CircleDrawer circle() { public static CircleDrawer circle() {
8 if(_circle is null) {
9 synchronized if(_circle is null) {
8 if(_circle is null)
10 9 _circle = new CircleDrawer; _circle = new CircleDrawer;
11 }
12 }
10
13 11 return _circle; return _circle;
14 12 } }
15 13
File source/strategies/ellipse.d changed (mode: 100644) (index 1f0ae3f..1e10c0a)
... ... import dp.strat.strat;
5 5 private static EllipseDrawer _ellipse; private static EllipseDrawer _ellipse;
6 6
7 7 public static EllipseDrawer ellipse() { public static EllipseDrawer ellipse() {
8 if(_ellipse is null) {
9 synchronized if(_ellipse is null) {
8 if(_ellipse is null)
10 9 _ellipse = new EllipseDrawer; _ellipse = new EllipseDrawer;
11 }
12 }
10
13 11 return _ellipse; return _ellipse;
14 12 } }
15 13
File source/strategies/rect.d changed (mode: 100644) (index d84c9b0..a301072)
1 1 module dp.strat.rect; module dp.strat.rect;
2 2
3 3 import dp.strat.strat; import dp.strat.strat;
4 import std.stdio; // Debug
5 4
6 5 private static RectDrawer _rect; private static RectDrawer _rect;
7 6
8 7 public static RectDrawer rect() { public static RectDrawer rect() {
9 if(_rect is null) {
10 synchronized if(_rect is null) {
8 if(_rect is null)
11 9 _rect = new RectDrawer(); _rect = new RectDrawer();
12 }
13 }
10
14 11 return _rect; return _rect;
15 12 } }
16 13
 
... ... private static class RectDrawer : Strategy {
36 33 } }
37 34
38 35 public override void draw(Shape shape) { public override void draw(Shape shape) {
39 writeln("Drawing..");
40 36 shape.c.rectangle ( shape.c.rectangle (
41 37 shape.getBounds[0][0], shape.getBounds[0][0],
42 38 shape.getBounds[0][1], shape.getBounds[0][1],
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