File: | home/HaikuArchives/ArtPaint/artpaint/tools/StraightLineTool.cpp |
Warning: | line 245, column 7 Value stored to 'draw_line' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright 2003, Heikki Suhonen |
3 | * Copyright 2009, Karsten Heimrich |
4 | * Distributed under the terms of the MIT License. |
5 | * |
6 | * Authors: |
7 | * Heikki Suhonen <heikki.suhonen@gmail.com> |
8 | * Karsten Heimrich <host.haiku@gmx.de> |
9 | * Dale Cieslak <dcieslak@yahoo.com> |
10 | * |
11 | */ |
12 | |
13 | #include "StraightLineTool.h" |
14 | |
15 | #include "BitmapDrawer.h" |
16 | #include "Cursors.h" |
17 | #include "HSPolygon.h" |
18 | #include "Image.h" |
19 | #include "ImageView.h" |
20 | #include "NumberSliderControl.h" |
21 | #include "PaintApplication.h" |
22 | #include "Selection.h" |
23 | #include "ToolScript.h" |
24 | #include "UtilityClasses.h" |
25 | |
26 | |
27 | #include <Catalog.h> |
28 | #include <CheckBox.h> |
29 | #include <GridLayoutBuilder.h> |
30 | #include <GroupLayoutBuilder.h> |
31 | #include <SeparatorView.h> |
32 | #include <Window.h> |
33 | |
34 | |
35 | #include <math.h> |
36 | #include <stdio.h> |
37 | |
38 | |
39 | #undef B_TRANSLATION_CONTEXT"Tools" |
40 | #define B_TRANSLATION_CONTEXT"Tools" "Tools" |
41 | |
42 | |
43 | using ArtPaint::Interface::NumberSliderControl; |
44 | |
45 | |
46 | StraightLineTool::StraightLineTool() |
47 | : DrawingTool(B_TRANSLATE("Straight line tool")BLocaleRoster::Default()->GetCatalog()->GetString(("Straight line tool" ), "Tools"), |
48 | STRAIGHT_LINE_TOOL) |
49 | { |
50 | fOptions = SIZE_OPTION | ANTI_ALIASING_LEVEL_OPTION | MODE_OPTION; |
51 | fOptionsCount = 3; |
52 | |
53 | SetOption(SIZE_OPTION, 1); |
54 | SetOption(MODE_OPTION, B_CONTROL_ON); |
55 | SetOption(ANTI_ALIASING_LEVEL_OPTION, B_CONTROL_OFF); |
56 | } |
57 | |
58 | |
59 | StraightLineTool::~StraightLineTool() |
60 | { |
61 | } |
62 | |
63 | |
64 | ToolScript* |
65 | StraightLineTool::UseTool(ImageView* view, uint32 buttons, BPoint point, |
66 | BPoint view_point) |
67 | { |
68 | // In this function we calculate the line as a polygon. We make the polygon |
69 | // by first making a horizontal rectangle of appropriate size and the |
70 | // rotating around the starting-point by proper angle. |
71 | |
72 | // Wait for the last_updated_region to become empty |
73 | while (LastUpdatedRect().IsValid()) |
74 | snooze(50000); |
75 | |
76 | BWindow *window = view->Window(); |
77 | drawing_mode old_mode; |
78 | BBitmap *bitmap = view->ReturnImage()->ReturnActiveBitmap(); |
79 | // BView *bitmap_view = view->getBufferView(); |
80 | |
81 | Selection *selection = view->GetSelection(); |
82 | |
83 | if (window != NULL__null) { |
84 | ToolScript* the_script = new ToolScript(Type(), fToolSettings, |
85 | ((PaintApplication*)be_app)->Color(true)); |
86 | |
87 | BitmapDrawer *drawer = new BitmapDrawer(bitmap); |
88 | |
89 | BPoint original_point,original_view_point,prev_view_point; |
90 | BRect bitmap_rect,old_rect,new_rect; |
91 | HSPolygon *view_polygon = NULL__null; |
92 | BPoint point_list[4]; |
93 | |
94 | window->Lock(); |
95 | old_mode = view->DrawingMode(); |
96 | view->SetDrawingMode(B_OP_INVERT); |
97 | window->Unlock(); |
98 | original_point = point; |
99 | rgb_color c = ((PaintApplication*)be_app)->Color(true); |
100 | |
101 | prev_view_point = original_view_point = view_point; |
102 | bitmap_rect = BRect(point.x, point.y - |
103 | floor(((float)GetCurrentValue(SIZE_OPTION) - 1.0) / 2.0), point.x, |
104 | point.y + ceil(((float)GetCurrentValue(SIZE_OPTION) - 1.0) / 2.0)); |
105 | old_rect = new_rect = view->convertBitmapRectToView(bitmap_rect); |
106 | point_list[0] = new_rect.LeftTop(); |
107 | point_list[1] = new_rect.RightTop(); |
108 | point_list[2] = new_rect.RightBottom(); |
109 | point_list[3] = new_rect.LeftBottom(); |
110 | |
111 | window->Lock(); |
112 | if ((GetCurrentValue(SIZE_OPTION) > 2) && (fToolSettings.mode == B_CONTROL_OFF)) { |
113 | view_polygon = new HSPolygon(point_list,4); |
114 | BPolygon *bpoly = view_polygon->GetBPolygon(); |
115 | view->StrokePolygon(bpoly); |
116 | delete bpoly; |
117 | } |
118 | else |
119 | view->StrokeLine(original_view_point,view_point); |
120 | window->Unlock(); |
121 | |
122 | float angle = 0; |
123 | while (buttons) { |
124 | window->Lock(); |
125 | view->getCoords(&point,&buttons,&view_point); |
126 | if (modifiers() & B_LEFT_SHIFT_KEY) { |
127 | // Make the new point be so that the angle is a multiple of 45°. |
128 | float x_diff,y_diff; |
129 | x_diff = fabs(original_point.x-point.x); |
130 | y_diff = fabs(original_point.y-point.y); |
131 | |
132 | if (x_diff < y_diff) { |
133 | if (x_diff < y_diff/2) |
134 | x_diff = 0; |
135 | else |
136 | x_diff = y_diff; |
137 | } |
138 | else { |
139 | if (y_diff < x_diff/2) |
140 | y_diff = 0; |
141 | else |
142 | y_diff = x_diff; |
143 | } |
144 | |
145 | float signed_x_diff = (point.x-original_point.x); |
146 | float signed_y_diff = (point.y-original_point.y); |
147 | |
148 | if (signed_x_diff != 0) |
149 | point.x = original_point.x + x_diff * signed_x_diff/fabs(signed_x_diff); |
150 | |
151 | if (signed_y_diff != 0) |
152 | point.y = original_point.y + y_diff * signed_y_diff/fabs(signed_y_diff); |
153 | |
154 | x_diff = fabs(original_view_point.x-view_point.x); |
155 | y_diff = fabs(original_view_point.y-view_point.y); |
156 | |
157 | if (x_diff < y_diff) { |
158 | if (x_diff < y_diff/2) |
159 | x_diff = 0; |
160 | else |
161 | x_diff = y_diff; |
162 | } |
163 | else { |
164 | if (y_diff < x_diff/2) |
165 | y_diff = 0; |
166 | else |
167 | y_diff = x_diff; |
168 | } |
169 | |
170 | |
171 | signed_x_diff = (view_point.x-original_view_point.x); |
172 | signed_y_diff = (view_point.y-original_view_point.y); |
173 | if (signed_x_diff != 0) { |
174 | view_point.x = original_view_point.x + |
175 | x_diff * signed_x_diff / fabs(signed_x_diff); |
176 | } |
177 | |
178 | if (signed_y_diff != 0) { |
179 | view_point.y = original_view_point.y + |
180 | y_diff * signed_y_diff / fabs(signed_y_diff); |
181 | } |
182 | } |
183 | |
184 | bitmap_rect = BRect(original_point.x, |
185 | original_point.y - floor(((float)GetCurrentValue(SIZE_OPTION) - 1.0) / 2.0), |
186 | original_point.x + sqrt(pow(original_point.x - point.x, 2) + |
187 | pow(original_point.y - point.y, 2)), original_point.y + |
188 | ceil(((float)GetCurrentValue(SIZE_OPTION) - 1.0) / 2.0)); |
189 | |
190 | new_rect = view->convertBitmapRectToView(bitmap_rect); |
191 | if (old_rect != new_rect) { |
192 | if ((GetCurrentValue(SIZE_OPTION) > 2) && (fToolSettings.mode == B_CONTROL_OFF)) { |
193 | BRect bbox = view_polygon->BoundingBox(); |
194 | view->Draw(bbox); |
195 | point_list[0] = new_rect.LeftTop(); |
196 | point_list[1] = new_rect.RightTop(); |
197 | point_list[2] = new_rect.RightBottom(); |
198 | point_list[3] = new_rect.LeftBottom(); |
199 | view_polygon = new HSPolygon(point_list,4); |
200 | angle = atan2((view_point.y-original_view_point.y), |
201 | (view_point.x - original_view_point.x)) * 180 / M_PI3.14159265358979323846; |
202 | view_polygon->Rotate(original_view_point,angle); |
203 | BPolygon *bpoly = view_polygon->GetBPolygon(); |
204 | view->StrokePolygon(bpoly); |
205 | delete bpoly; |
206 | } |
207 | else { |
208 | float left = min_c(original_view_point.x, prev_view_point.x)((original_view_point.x)>(prev_view_point.x)?(prev_view_point .x):(original_view_point.x)); |
209 | float top = min_c(original_view_point.y, prev_view_point.y)((original_view_point.y)>(prev_view_point.y)?(prev_view_point .y):(original_view_point.y)); |
210 | float right = max_c(original_view_point.x, prev_view_point.x)((original_view_point.x)>(prev_view_point.x)?(original_view_point .x):(prev_view_point.x)); |
211 | float bottom = max_c(original_view_point.y, prev_view_point.y)((original_view_point.y)>(prev_view_point.y)?(original_view_point .y):(prev_view_point.y)); |
212 | BRect bbox(left, top, right, bottom); |
213 | view->Draw(bbox); |
214 | view->StrokeLine(original_view_point,view_point); |
215 | angle = atan2((view_point.y-original_view_point.y), |
216 | (view_point.x - original_view_point.x)) * 180 / M_PI3.14159265358979323846; |
217 | prev_view_point = view_point; |
218 | } |
219 | old_rect = new_rect; |
220 | } |
221 | window->Unlock(); |
222 | snooze(20 * 1000); |
223 | } |
224 | int32 size = GetCurrentValue(SIZE_OPTION); |
225 | bool draw_line = true; |
226 | new_rect = old_rect; |
227 | if (fToolSettings.mode == B_CONTROL_ON) { // Adjust the width of the line. |
228 | bool continue_adjusting_width = true; |
229 | BPoint p1 = original_point; |
230 | BPoint width_point; |
231 | view_polygon = new HSPolygon(NULL__null,0); |
232 | BRect orig_rect = bitmap_rect; |
233 | orig_rect.bottom = orig_rect.top = original_point.y; |
234 | |
235 | size = 0; |
236 | |
237 | while (continue_adjusting_width) { |
238 | if (is_clicks_data_valid) { |
239 | continue_adjusting_width = false; |
240 | is_clicks_data_valid = false; |
241 | } |
242 | else if (is_keys_data_valid) { |
243 | if (last_key_event_bytes[0] == B_ESCAPE) { |
244 | continue_adjusting_width = false; |
245 | draw_line = false; |
Value stored to 'draw_line' is never read | |
246 | } |
247 | is_keys_data_valid = false; |
248 | } |
249 | else { |
250 | if (view->LockLooper()) { |
251 | new_rect = orig_rect; |
252 | new_rect.bottom += size/2; |
253 | new_rect.top -= size/2; |
254 | new_rect = view->convertBitmapRectToView(new_rect); |
255 | if (new_rect != old_rect) { |
256 | if (size > 0) { |
257 | BRect bbox = view_polygon->BoundingBox(); |
258 | view->Draw(bbox); |
259 | point_list[0] = new_rect.LeftTop(); |
260 | point_list[1] = new_rect.RightTop(); |
261 | point_list[2] = new_rect.RightBottom(); |
262 | point_list[3] = new_rect.LeftBottom(); |
263 | view_polygon = new HSPolygon(point_list,4); |
264 | view_polygon->Rotate(original_view_point,angle); |
265 | BPolygon* bpoly = view_polygon->GetBPolygon(); |
266 | view->StrokePolygon(bpoly); |
267 | delete bpoly; |
268 | } |
269 | old_rect = new_rect; |
270 | } |
271 | view->getCoords(&width_point,&buttons); |
272 | view->UnlockLooper(); |
273 | width_point = width_point-p1; |
274 | BPoint spare = width_point; |
275 | width_point.x = cos(-angle / 180 * M_PI3.14159265358979323846) * spare.x - |
276 | sin(-angle / 180 * M_PI3.14159265358979323846) * spare.y; |
277 | width_point.y = sin(-angle / 180 * M_PI3.14159265358979323846) * spare.x + |
278 | cos(-angle / 180 * M_PI3.14159265358979323846) * spare.y; |
279 | size = (int32)(2 * fabs(width_point.y)); |
280 | } |
281 | snooze(20 * 1000); |
282 | } |
283 | } |
284 | } |
285 | delete view_polygon; |
286 | |
287 | bool anti_alias = true; |
288 | if (GetCurrentValue(ANTI_ALIASING_LEVEL_OPTION) == B_CONTROL_OFF) |
289 | anti_alias = false; |
290 | |
291 | if (size > 1) |
292 | drawer->DrawLine(original_point,point,RGBColorToBGRA(c),size,anti_alias,selection); |
293 | else |
294 | drawer->DrawHairLine(original_point,point,RGBColorToBGRA(c),anti_alias,selection); |
295 | |
296 | BRect updated_rect = MakeRectFromPoints(original_point, point); |
297 | |
298 | // This extension might actually be too little. |
299 | updated_rect.left -= size/2; |
300 | updated_rect.top -= size/2; |
301 | updated_rect.right += size/2; |
302 | updated_rect.bottom += size/2; |
303 | |
304 | SetLastUpdatedRect(updated_rect); |
305 | window->Lock(); |
306 | view->SetDrawingMode(old_mode); |
307 | view->UpdateImage(updated_rect); |
308 | view->Sync(); |
309 | window->Unlock(); |
310 | |
311 | delete drawer; |
312 | |
313 | the_script->AddPoint(original_point); |
314 | the_script->AddPoint(point); |
315 | return the_script; |
316 | } |
317 | |
318 | return NULL__null; |
319 | } |
320 | |
321 | |
322 | int32 |
323 | StraightLineTool::UseToolWithScript(ToolScript*,BBitmap*) |
324 | { |
325 | return B_OK((int)0); |
326 | } |
327 | |
328 | |
329 | BView* |
330 | StraightLineTool::ConfigView() |
331 | { |
332 | return new StraightLineToolConfigView(this); |
333 | } |
334 | |
335 | |
336 | const void* |
337 | StraightLineTool::ToolCursor() const |
338 | { |
339 | return HS_LINE_CURSOR; |
340 | } |
341 | |
342 | |
343 | const char* |
344 | StraightLineTool::HelpString(bool isInUse) const |
345 | { |
346 | return (isInUse |
347 | ? B_TRANSLATE("Drawing a straight line.")BLocaleRoster::Default()->GetCatalog()->GetString(("Drawing a straight line." ), "Tools") |
348 | : B_TRANSLATE("Click to draw a straight line.")BLocaleRoster::Default()->GetCatalog()->GetString(("Click to draw a straight line." ), "Tools")); |
349 | } |
350 | |
351 | |
352 | // #pragma mark -- StraightLineToolConfigView |
353 | |
354 | |
355 | StraightLineToolConfigView::StraightLineToolConfigView(DrawingTool* tool) |
356 | : DrawingToolConfigView(tool) |
357 | { |
358 | if (BLayout* layout = GetLayout()) { |
359 | BMessage* message = new BMessage(OPTION_CHANGED); |
360 | message->AddInt32("option", SIZE_OPTION); |
361 | message->AddInt32("value", tool->GetCurrentValue(SIZE_OPTION)); |
362 | |
363 | fLineSize = new NumberSliderControl( |
364 | B_TRANSLATE("Width:")BLocaleRoster::Default()->GetCatalog()->GetString(("Width:" ), "Tools"), |
365 | "1", message, 1, 100, false); |
366 | |
367 | message = new BMessage(OPTION_CHANGED); |
368 | message->AddInt32("option", ANTI_ALIASING_LEVEL_OPTION); |
369 | message->AddInt32("value", 0x00000000); |
370 | |
371 | fAntiAliasing = |
372 | new BCheckBox(B_TRANSLATE("Enable antialiasing")BLocaleRoster::Default()->GetCatalog()->GetString(("Enable antialiasing" ), "Tools"), |
373 | message); |
374 | if (tool->GetCurrentValue(ANTI_ALIASING_LEVEL_OPTION) != B_CONTROL_OFF) |
375 | fAntiAliasing->SetValue(B_CONTROL_ON); |
376 | |
377 | message = new BMessage(OPTION_CHANGED); |
378 | message->AddInt32("option", MODE_OPTION); |
379 | message->AddInt32("value", 0x00000000); |
380 | |
381 | fAdjustableWidth = |
382 | new BCheckBox(B_TRANSLATE("Adjustable width")BLocaleRoster::Default()->GetCatalog()->GetString(("Adjustable width" ), "Tools"), |
383 | message); |
384 | if (tool->GetCurrentValue(MODE_OPTION) != B_CONTROL_OFF) |
385 | fAdjustableWidth->SetValue(B_CONTROL_ON); |
386 | |
387 | BGridLayout* lineSizeLayout = LayoutSliderGrid(fLineSize); |
388 | |
389 | layout->AddView(BGroupLayoutBuilder(B_VERTICAL, kWidgetSpacing) |
390 | .Add(lineSizeLayout) |
391 | .AddStrut(kWidgetSpacing) |
392 | .Add(SeparatorView(B_TRANSLATE("Options")BLocaleRoster::Default()->GetCatalog()->GetString(("Options" ), "Tools"))) |
393 | .AddGroup(B_VERTICAL, kWidgetSpacing) |
394 | .Add(fAdjustableWidth) |
395 | .Add(fAntiAliasing) |
396 | .SetInsets(kWidgetInset, 0.0, 0.0, 0.0) |
397 | .End() |
398 | .TopView() |
399 | ); |
400 | } |
401 | } |
402 | |
403 | |
404 | void |
405 | StraightLineToolConfigView::AttachedToWindow() |
406 | { |
407 | DrawingToolConfigView::AttachedToWindow(); |
408 | |
409 | fLineSize->SetTarget(this); |
410 | fAntiAliasing->SetTarget(this); |
411 | fAdjustableWidth->SetTarget(this); |
412 | } |