Subject | Hash | Author | Date (UTC) |
---|---|---|---|
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 |
File | Lines added | Lines deleted |
---|---|---|
README.md | 10 | 11 |
source/commands/resize.d | 8 | 6 |
source/frontend/mainWindow.d | 0 | 0 |
source/frontend/menubar.d | 0 | 0 |
source/frontend/resizeDialog.d | 64 | 0 |
source/frontend/shapeOptions.d | 4 | 4 |
source/history.d | 4 | 2 |
source/shapes/rect.d | 10 | 0 |
source/shapes/shape.d | 2 | 0 |
File README.md changed (mode: 100644) (index 9917291..41ac65b) | |||
... | ... | This repo is a school project for Design Patterns. | |
3 | 3 | ||
4 | 4 | use 'dub' to compile and run the code. | use 'dub' to compile and run the code. |
5 | 5 | ||
6 | # NOTES | ||
7 | |||
8 | * CheckBounds werkt retrograde (laatst toegevoegde item eerst checken) en stopt na een collision. | ||
9 | |||
10 | # TODO | ||
11 | |||
12 | * Undo en redo werkt nog niet helemaal lekker. Waarschijnlijk als gevolg van het niet gebruiken van pointers in de 'shapes' array. | ||
13 | |||
14 | * File IO op undo redo afstemmen. | ||
15 | |||
16 | * Commands door een enkele klasse laten uitvoeren (?) | ||
6 | # Useful draw functions for `Context` type | ||
7 | |||
8 | - `fill()`: fill path, then forget path. | ||
9 | - `fillPreserve()`: fill path, retain path. | ||
10 | - `fillExtends()`, `strokeExtends()` & `pathExtends()`: return corners (whatever that may be). | ||
11 | - `stroke()`: draw line on path, then forget path. | ||
12 | - `strokePreserve()`: should be obvious. | ||
13 | - `moveTo()`: Move/Pan path. | ||
14 | - `scale()`: Scale path. | ||
15 | - `newPath()`: Clear path from context. |
File source/commands/resize.d copied from file source/commands/destruct.d (similarity 61%) (mode: 100644) (index 893b57c..646fa24) | |||
1 | module dp.command.destruct; // don't use 'dp.command.delete' as module. Causes bug. | ||
1 | module dp.command.resize; | ||
2 | 2 | ||
3 | 3 | import dp.command.cmd; | import dp.command.cmd; |
4 | 4 | import dp.shape.shape; | import dp.shape.shape; |
5 | 5 | ||
6 | 6 | import Global = dp.global; | import Global = dp.global; |
7 | 7 | ||
8 | public class DestructCmd : Command { | ||
8 | public class ResizeCmd : Command { | ||
9 | 9 | private Shape s; | private Shape s; |
10 | private int amount; | ||
10 | 11 | ||
11 | this(Shape shape) { | ||
12 | s = shape; | ||
12 | this(Shape shape, int amount) { | ||
13 | s = shape; | ||
14 | this.amount = amount; | ||
13 | 15 | execute(); | execute(); |
14 | 16 | } | } |
15 | 17 | ||
16 | 18 | public override void execute() { | public override void execute() { |
17 | s.active = false; | ||
19 | s.resize(amount); | ||
18 | 20 | } | } |
19 | 21 | ||
20 | 22 | public override void undo() { | public override void undo() { |
21 | s.active = true; | ||
23 | s.resize(-amount); | ||
22 | 24 | } | } |
23 | 25 | ||
24 | 26 | public override void render() { | public override void render() { |
File source/frontend/mainWindow.d renamed from source/windows/mainWindow.d (similarity 100%) |
File source/frontend/menubar.d renamed from source/menubar.d (similarity 100%) |
File source/frontend/resizeDialog.d added (mode: 100644) (index 0000000..7cec216) | |||
1 | module dp.win.resize; | ||
2 | |||
3 | import gtk.Dialog; | ||
4 | import gtk.MessageDialog; | ||
5 | import gtk.Label; | ||
6 | import gtk.Button; | ||
7 | import gtk.Entry; | ||
8 | |||
9 | import dp.shape.shape; | ||
10 | import dp.history; | ||
11 | import dp.command.resize; | ||
12 | |||
13 | import Global = dp.global; | ||
14 | |||
15 | import std.stdio; // Debug | ||
16 | |||
17 | import std.string, std.conv; | ||
18 | |||
19 | class ResizeDialog : Dialog { | ||
20 | Shape shape; | ||
21 | Entry factorEntry; | ||
22 | |||
23 | this(Shape shape) { | ||
24 | super(); | ||
25 | setTitle("Resize shape"); | ||
26 | this.shape = shape; | ||
27 | |||
28 | factorEntry = new Entry(); | ||
29 | factorEntry.setPlaceholderText("amount"); | ||
30 | |||
31 | Button confirmBtn = new Button("Resize!", &clickCallback); | ||
32 | |||
33 | // Content area, containing non-interactable GTK objects. | ||
34 | getContentArea().add(new Label("By what amount should the shape be resized?")); | ||
35 | getContentArea().setBorderWidth(20); | ||
36 | |||
37 | // Action area, containing interactable GTK objects. | ||
38 | getActionArea().add(factorEntry); | ||
39 | getActionArea().add(confirmBtn); | ||
40 | |||
41 | showAll(); | ||
42 | } | ||
43 | |||
44 | void clickCallback (Button button) { | ||
45 | int amount = 1; | ||
46 | string input = factorEntry.getText(); | ||
47 | |||
48 | if(isNumeric(input)) { | ||
49 | amount = parse!int(input); | ||
50 | History.addCommand(new ResizeCmd(shape, amount)); | ||
51 | Global.canvas.repaint(); | ||
52 | this.close(); | ||
53 | } | ||
54 | else { | ||
55 | MessageDialog msgd = new MessageDialog ( | ||
56 | this, DialogFlags.MODAL, MessageType.ERROR, ButtonsType.OK, | ||
57 | "'" ~ input ~ "' is an invalid amount. Please use numbers only.", | ||
58 | null | ||
59 | ); | ||
60 | scope(exit) msgd.destroy(); | ||
61 | msgd.run(); | ||
62 | } | ||
63 | } | ||
64 | } |
File source/frontend/shapeOptions.d renamed from source/shapeOptions.d (similarity 92%) (mode: 100644) (index 6ec1d54..e3a2650) | |||
... | ... | import gdk.Event; | |
6 | 6 | ||
7 | 7 | import dp.shape.shape; | import dp.shape.shape; |
8 | 8 | import dp.command.destruct; | import dp.command.destruct; |
9 | //import dp.win.resize; | ||
9 | import dp.win.resize; | ||
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 | //protected ResizeDialog rd; | ||
15 | protected ResizeDialog rd; | ||
16 | 16 | ||
17 | 17 | public class ShapeOptions : Menu { | public class ShapeOptions : Menu { |
18 | 18 | this() { | this() { |
19 | 19 | super(); | super(); |
20 | 20 | this.append(new DeleteShape()); | this.append(new DeleteShape()); |
21 | 21 | this.append(new MoveShape()); | this.append(new MoveShape()); |
22 | //this.append(new ResizeShape()); | ||
22 | this.append(new ResizeShape()); | ||
23 | 23 | } | } |
24 | 24 | ||
25 | 25 | public void selectShape (Shape shape) { // Shows options of param shape. | public void selectShape (Shape shape) { // Shows options of param shape. |
... | ... | protected class ResizeShape : MenuItem { | |
63 | 63 | } | } |
64 | 64 | ||
65 | 65 | private bool relCallback (Event event, Widget widget) { | private bool relCallback (Event event, Widget widget) { |
66 | //rd = new ResizeDialog(s); | ||
66 | rd = new ResizeDialog(s); | ||
67 | 67 | return false; // Hide ShapeOptions when button is released. | return false; // Hide ShapeOptions when button is released. |
68 | 68 | } | } |
69 | 69 | } | } |
File source/history.d changed (mode: 100644) (index da42fb2..e439364) | |||
... | ... | static class History { | |
13 | 13 | private static bool belowZero; | private static bool belowZero; |
14 | 14 | ||
15 | 15 | public static void addCommand(Command cmd) { | public static void addCommand(Command cmd) { |
16 | belowZero = false; | ||
17 | 16 | if(cmdPtr != commands.length) | if(cmdPtr != commands.length) |
18 | 17 | commands.length = cmdPtr; | commands.length = cmdPtr; |
18 | |||
19 | 19 | commands.length++; | commands.length++; |
20 | writeln(commands.length); | ||
21 | 20 | commands[cmdPtr] = cmd; | commands[cmdPtr] = cmd; |
22 | 21 | cmdPtr = commands.length; | cmdPtr = commands.length; |
22 | belowZero = false; | ||
23 | |||
24 | writeln(commands.length); | ||
23 | 25 | writeln(cmdPtr); | writeln(cmdPtr); |
24 | 26 | } | } |
25 | 27 |
File source/shapes/rect.d changed (mode: 100644) (index 302036d..27e7fe4) | |||
... | ... | class Rectangle : Shape { | |
25 | 25 | ]; | ]; |
26 | 26 | } | } |
27 | 27 | ||
28 | public override void resize(int amount) { | ||
29 | int[2] newPos = [ | ||
30 | to!int(bounds[0][0] + size / 2), | ||
31 | to!int(bounds[0][1] + size / 2) | ||
32 | ]; | ||
33 | |||
34 | size += amount; | ||
35 | this.bounds = calcBounds(newPos[0], newPos[1]); | ||
36 | } | ||
37 | |||
28 | 38 | protected override void initSize(double size) { | protected override void initSize(double size) { |
29 | 39 | this.size = size != 0 ? size : 125; | this.size = size != 0 ? size : 125; |
30 | 40 | } | } |
File source/shapes/shape.d changed (mode: 100644) (index 1a62119..85bec67) | |||
... | ... | class Shape { | |
39 | 39 | } | } |
40 | 40 | +/ | +/ |
41 | 41 | ||
42 | public abstract void resize(int amount); | ||
43 | |||
42 | 44 | protected abstract double[2][2] calcBounds(int x, int y); | protected abstract double[2][2] calcBounds(int x, int y); |
43 | 45 | protected abstract void initSize(double size); | protected abstract void initSize(double size); |
44 | 46 | protected abstract void draw(); | protected abstract void draw(); |