Skip to content

Commit e730afc

Browse files
more tools stuff
1 parent 09fa649 commit e730afc

16 files changed

+192
-61
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ wsedit-test-*
1414
*.obj
1515
*.lst
1616
dub.selections.json
17+
test.wsp

res/logo.png

-3.24 KB
Loading

res/x_tiles/simpleTileset_blue.png

66.9 KB
Loading

res/x_tiles/simpleTileset_brown.png

66.9 KB
Loading

res/x_tiles/simpleTileset_green.png

66.9 KB
Loading

res/x_tiles/simpleTileset_pink.png

66.9 KB
Loading

res/x_tiles/simpleTileset_violet.png

66.9 KB
Loading

res/x_tiles/simpleTileset_white.png

66.9 KB
Loading

res/x_tiles/simpleTileset_yellow.png

66.9 KB
Loading

source/wsedit/ir/scene.d

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module wsedit.ir.scene;
22
import wsedit.math;
3+
import containers.list;
34

45
/**
56
A scene
@@ -27,7 +28,7 @@ public:
2728
Vector2i tileSize;
2829

2930
/// Regions of the scene
30-
Region[] regions;
31+
List!Region regions;
3132

3233
/// The currently selected region
3334
uint selectedRegion = 0;

source/wsedit/math.d

+40-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
module wsedit.math;
2+
public import std.math;
3+
public import std.algorithm.comparison : clamp;
4+
import std.format;
25

36
/**
47
A point in 2D space
@@ -14,6 +17,20 @@ struct Vector2 {
1417
Y coordinate
1518
*/
1619
double y = 0.0;
20+
21+
/**
22+
Gets wether a vector is within a circle
23+
24+
center = center of circle
25+
radius = radius of circle
26+
*/
27+
bool isInCircle(Vector2 center, double radius) {
28+
return sqrt(pow(center.x-x, 2) + pow(center.y - y, 2)) <= radius;
29+
}
30+
31+
string toString() {
32+
return "[x=%f, y=%f]".format(x, y);
33+
}
1734
}
1835

1936
/**
@@ -31,6 +48,9 @@ struct Vector2i {
3148
*/
3249
int y = 0;
3350

51+
string toString() {
52+
return "[x=%d, y=%d]".format(x, y);
53+
}
3454
}
3555

3656
/**
@@ -74,10 +94,10 @@ struct Rectangle {
7494
*/
7595
bool intersects(Rectangle other) {
7696
return !(
77-
other.left >= this.right ||
78-
other.right <= this.left ||
79-
other.top >= this.bottom ||
80-
other.bottom <= this.top
97+
other.left > this.right ||
98+
other.right < this.left ||
99+
other.top > this.bottom ||
100+
other.bottom < this.top
81101
);
82102
}
83103

@@ -86,10 +106,10 @@ struct Rectangle {
86106
*/
87107
bool intersects(Vector2 other) {
88108
return !(
89-
other.x >= this.right ||
90-
other.x <= this.left ||
91-
other.y >= this.bottom ||
92-
other.y <= this.top
109+
other.x > this.right ||
110+
other.x < this.left ||
111+
other.y > this.bottom ||
112+
other.y < this.top
93113
);
94114
}
95115

@@ -98,17 +118,25 @@ struct Rectangle {
98118
*/
99119
bool intersects(Vector2i other) {
100120
return !(
101-
other.x >= this.right ||
102-
other.x <= this.left ||
103-
other.y >= this.bottom ||
104-
other.y <= this.top
121+
other.x > this.right ||
122+
other.x < this.left ||
123+
other.y > this.bottom ||
124+
other.y < this.top
105125
);
106126
}
107127

128+
Rectangle expand(int x, int y) {
129+
return Rectangle(this.x-x, this.y-y, this.width+(x*2), this.height+(y*2));
130+
}
131+
108132
/**
109133
Gets the cetner of this rectangle
110134
*/
111135
Vector2 center() {
112136
return Vector2(cast(double)x+cast(double)(width/2), cast(double)y+cast(double)(height/2));
113137
}
138+
139+
string toString() {
140+
return "[x=%d, y=%d, w=%d, h=%d]".format(x, y, width, height);
141+
}
114142
}

source/wsedit/subsystem/wsrenderer.d

+2-2
Original file line numberDiff line numberDiff line change
@@ -380,12 +380,12 @@ public:
380380
ctx.paint();
381381

382382
// Draw wereshift logo
383-
ctx.translate(widgetArea.width/2, widgetArea.height/2);
383+
ctx.translate(widgetArea.width/2, (widgetArea.height/2));
384384
ctx.setSourcePixbuf(wseditLogo, -originX, -originY);
385385
ctx.paint();
386386

387387
// Draw info text
388-
ctx.translate(-(extents.width/2), originY-32);
388+
ctx.translate(-(extents.width/2), originY+16);
389389
ctx.setSourceRgb(1, 1, 1);
390390
ctx.showText(subtext);
391391

source/wsedit/tools/regions/deletetool.d

-22
This file was deleted.
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module wsedit.tools.regions.erasertool;
2+
import wsedit.tools;
3+
import wsedit.math;
4+
5+
/**
6+
Eraser tool
7+
*/
8+
class EraserTool : Tool {
9+
private:
10+
11+
public:
12+
this(Workspace workspace, ToolGroup group) {
13+
super("Eraser Tool", "edit-delete-symbolic", group, workspace);
14+
}
15+
16+
override void draw(Renderer renderer) {
17+
18+
}
19+
20+
override void update(Mouse mouse) {
21+
int tileWidth = workspace.scene.tileSize.x;
22+
int tileHeight = workspace.scene.tileSize.y;
23+
24+
Vector2 mousePosition = workspace.camera.toScene(mouse.position);
25+
26+
27+
// We've started dragging
28+
if (mouse.isButtonPressed(MouseButton.Left)) {
29+
30+
int tileX = (cast(int)mousePosition.x)/tileWidth;
31+
int tileY = (cast(int)mousePosition.y)/tileHeight;
32+
33+
foreach(i; 0..workspace.scene.regions.count) {
34+
if (workspace.scene.regions[i].area.intersects(Vector2i(tileX, tileY))) {
35+
workspace.scene.regions.removeAt(i);
36+
continue;
37+
}
38+
}
39+
}
40+
}
41+
}

source/wsedit/tools/regions/package.d

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ import std.format;
55

66
public import wsedit.tools.regions.regiontool;
77
public import wsedit.tools.regions.createtool;
8+
public import wsedit.tools.regions.erasertool;
89

910
class RegionsGroup : ToolGroup {
1011
public:
1112
this(Workspace workspace) {
1213
super("Regions", "zoom-fit-best-symbolic", workspace);
13-
tools = [new RegionTool(workspace, this), new CreateTool(workspace, this)];
14+
tools = [new RegionTool(workspace, this), new EraserTool(workspace, this), new CreateTool(workspace, this)];
1415
}
1516

1617
override void draw(Renderer renderer) {

source/wsedit/tools/regions/regiontool.d

+104-23
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
module wsedit.tools.regions.regiontool;
22
import wsedit.tools;
33
import wsedit.ir;
4+
import wsedit.ir.scene;
45
import wsedit.math;
6+
import std.format;
7+
8+
enum ResizeMode {
9+
None = 0,
10+
Right = 1,
11+
Bottom = 2,
12+
Corner = 3,
13+
}
14+
15+
enum HANDLE_RADIUS = 8.0;
516

617
/**
718
Select tool
@@ -14,8 +25,14 @@ private:
1425

1526
int mstartX;
1627
int mstartY;
28+
29+
ResizeMode resizeMode;
1730

1831
Region selectedRegion;
32+
Region hRegion;
33+
Vector2 mousePosition;
34+
Vector2 surfMousePosition;
35+
1936

2037
public:
2138

@@ -24,54 +41,118 @@ public:
2441
}
2542

2643
override void draw(Renderer renderer) {
27-
44+
if (hRegion !is null) {
45+
Vector2 renderPos = Vector2(
46+
surfMousePosition.x+(32*workspace.camera.zoom),
47+
surfMousePosition.y+(32*workspace.camera.zoom)
48+
);
49+
50+
renderer.renderBadge(
51+
resizeMode == ResizeMode.None ?
52+
"Move" : "Resize",
53+
workspace.camera.toScene(renderPos),
54+
1.1/workspace.camera.zoom
55+
);
56+
}
2857
}
2958

3059
override void update(Mouse mouse) {
3160
int tileWidth = workspace.scene.tileSize.x;
3261
int tileHeight = workspace.scene.tileSize.y;
3362

34-
Vector2 mousePosition = workspace.camera.toScene(mouse.position);
63+
mousePosition = workspace.camera.toScene(mouse.position);
64+
surfMousePosition = mouse.position;
3565

3666
// We've stopped dragging
3767
if (mouse.isButtonReleased(MouseButton.Left) && selectedRegion !is null) {
3868
selectedRegion = null;
3969
}
40-
41-
// We've started dragging
42-
if (mouse.isButtonPressed(MouseButton.Left) && selectedRegion is null) {
43-
44-
int tileX = (cast(int)mousePosition.x)/tileWidth;
45-
int tileY = (cast(int)mousePosition.y)/tileHeight;
4670

47-
foreach(region; workspace.scene.regions) {
48-
if (region.area.intersects(Vector2i(tileX, tileY))) {
71+
// Prepare tile position
72+
int tileX = cast(int)(mousePosition.x/cast(double)tileWidth);
73+
int tileY = cast(int)(mousePosition.y/cast(double)tileHeight);
4974

50-
// The internal selected region is only for moving
51-
selectedRegion = region;
75+
// Handle modes
76+
if (selectedRegion is null) {
77+
hRegion = null;
78+
resizeMode = ResizeMode.None;
5279

53-
// This region is for the toolbar :)
54-
workspace.selectedRegion = region;
80+
foreach(region; workspace.scene.regions) {
81+
Rectangle actualArea = Rectangle(
82+
region.area.x*tileWidth,
83+
region.area.y*tileHeight,
84+
(region.area.width*tileWidth)+cast(int)HANDLE_RADIUS,
85+
(region.area.height*tileHeight)+cast(int)HANDLE_RADIUS
86+
);
87+
88+
if (actualArea.intersects(mousePosition)) {
89+
hRegion = region;
90+
91+
double right = region.area.right*tileWidth;
92+
double bottom = region.area.bottom*tileHeight;
93+
94+
double selX = clamp(mousePosition.x, region.area.left*tileWidth, region.area.right*tileWidth);
95+
double selY = clamp(mousePosition.y, region.area.top*tileHeight, region.area.bottom*tileHeight);
96+
97+
if (mousePosition.isInCircle(Vector2(selX, bottom), HANDLE_RADIUS)) {
98+
resizeMode |= ResizeMode.Bottom;
99+
}
100+
101+
if (mousePosition.isInCircle(Vector2(right, selY), HANDLE_RADIUS)) {
102+
resizeMode |= ResizeMode.Right;
103+
}
55104

56-
startX = region.area.x;
57-
startY = region.area.y;
58105
mstartX = cast(int)mousePosition.x;
59106
mstartY = cast(int)mousePosition.y;
60-
continue;
107+
108+
if (!resizeMode) {
109+
startX = region.area.x;
110+
startY = region.area.y;
111+
} else {
112+
startX = region.area.width;
113+
startY = region.area.height;
114+
}
115+
116+
if (mouse.isButtonPressed(MouseButton.Left)) {
117+
// The internal selected region is only for moving
118+
selectedRegion = region;
119+
120+
// This region is for the toolbar :)
121+
workspace.selectedRegion = region;
122+
}
123+
break;
61124
}
62125
}
63126
}
64127

65128
// We're dragging
66129
if (mouse.isButtonPressed(MouseButton.Left) && selectedRegion !is null) {
67130

68-
int tileX = ((cast(int)mousePosition.x)-mstartX)/tileWidth;
69-
int tileY = ((cast(int)mousePosition.y)-mstartY)/tileHeight;
131+
tileX = ((cast(int)mousePosition.x)-mstartX)/tileWidth;
132+
tileY = ((cast(int)mousePosition.y)-mstartY)/tileHeight;
70133

71-
selectedRegion.area.x = startX+tileX;
72-
selectedRegion.area.y = startY+tileY;
73-
foreach(region; workspace.scene.regions) {
74-
region.scanOverlaps();
134+
if (resizeMode > 0) {
135+
// RESIZE MODE
136+
if ((resizeMode & ResizeMode.Right) > 0) {
137+
selectedRegion.area.width = startX+tileX;
138+
if (selectedRegion.area.width <= 1) selectedRegion.area.width = 1;
139+
}
140+
141+
if ((resizeMode & ResizeMode.Bottom) > 0) {
142+
selectedRegion.area.height = startY+tileY;
143+
if (selectedRegion.area.height <= 1) selectedRegion.area.height = 1;
144+
}
145+
146+
foreach(region; workspace.scene.regions) {
147+
region.scanOverlaps();
148+
}
149+
} else {
150+
// MOVE MODE
151+
selectedRegion.area.x = startX+tileX;
152+
selectedRegion.area.y = startY+tileY;
153+
foreach(region; workspace.scene.regions) {
154+
region.scanOverlaps();
155+
}
75156
}
76157
}
77158
}

0 commit comments

Comments
 (0)