File: | home/HaikuArchives/ArtPaint/artpaint/tools/StraightLineTool.cpp |
Warning: | line 248, 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) && |
113 | (fToolSettings.mode == B_CONTROL_OFF)) { |
114 | view_polygon = new HSPolygon(point_list,4); |
115 | BPolygon *bpoly = view_polygon->GetBPolygon(); |
116 | view->StrokePolygon(bpoly); |
117 | delete bpoly; |
118 | } |
119 | else |
120 | view->StrokeLine(original_view_point, view_point); |
121 | window->Unlock(); |
122 | |
123 | float angle = 0; |
124 | while (buttons) { |
125 | window->Lock(); |
126 | view->getCoords(&point,&buttons,&view_point); |
127 | if (modifiers() & B_LEFT_SHIFT_KEY) { |
128 | // Make the new point be so that the angle is a multiple of 45°. |
129 | float x_diff,y_diff; |
130 | x_diff = fabs(original_point.x-point.x); |
131 | y_diff = fabs(original_point.y-point.y); |
132 | |
133 | if (x_diff < y_diff) { |
134 | if (x_diff < y_diff/2) |
135 | x_diff = 0; |
136 | else |
137 | x_diff = y_diff; |
138 | } |
139 | else { |
140 | if (y_diff < x_diff/2) |
141 | y_diff = 0; |
142 | else |
143 | y_diff = x_diff; |
144 | } |
145 | |
146 | float signed_x_diff = (point.x-original_point.x); |
147 | float signed_y_diff = (point.y-original_point.y); |
148 | |
149 | if (signed_x_diff != 0) |
150 | point.x = original_point.x + x_diff * signed_x_diff/fabs(signed_x_diff); |
151 | |
152 | if (signed_y_diff != 0) |
153 | point.y = original_point.y + y_diff * signed_y_diff/fabs(signed_y_diff); |
154 | |
155 | x_diff = fabs(original_view_point.x-view_point.x); |
156 | y_diff = fabs(original_view_point.y-view_point.y); |
157 | |
158 | if (x_diff < y_diff) { |
159 | if (x_diff < y_diff/2) |
160 | x_diff = 0; |
161 | else |
162 | x_diff = y_diff; |
163 | } |
164 | else { |
165 | if (y_diff < x_diff/2) |
166 | y_diff = 0; |
167 | else |
168 | y_diff = x_diff; |
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) && |
193 | (fToolSettings.mode == B_CONTROL_OFF)) { |
194 | if (view_polygon != NULL__null) { |
195 | BRect bbox = view_polygon->BoundingBox(); |
196 | view->Draw(bbox); |
197 | } |
198 | point_list[0] = new_rect.LeftTop(); |
199 | point_list[1] = new_rect.RightTop(); |
200 | point_list[2] = new_rect.RightBottom(); |
201 | point_list[3] = new_rect.LeftBottom(); |
202 | view_polygon = new HSPolygon(point_list,4); |
203 | angle = atan2((view_point.y-original_view_point.y), |
204 | (view_point.x - original_view_point.x)) * 180 / M_PI3.14159265358979323846; |
205 | view_polygon->Rotate(original_view_point,angle); |
206 | BPolygon *bpoly = view_polygon->GetBPolygon(); |
207 | view->StrokePolygon(bpoly); |
208 | delete bpoly; |
209 | } |
210 | else { |
211 | 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)); |
212 | 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)); |
213 | 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)); |
214 | 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)); |
215 | BRect bbox(left, top, right, bottom); |
216 | view->Draw(bbox); |
217 | view->StrokeLine(original_view_point,view_point); |
218 | angle = atan2((view_point.y-original_view_point.y), |
219 | (view_point.x - original_view_point.x)) * 180 / M_PI3.14159265358979323846; |
220 | prev_view_point = view_point; |
221 | } |
222 | old_rect = new_rect; |
223 | } |
224 | window->Unlock(); |
225 | snooze(20 * 1000); |
226 | } |
227 | int32 size = GetCurrentValue(SIZE_OPTION); |
228 | bool draw_line = true; |
229 | new_rect = old_rect; |
230 | if (fToolSettings.mode == B_CONTROL_ON) { // Adjust the width of the line. |
231 | bool continue_adjusting_width = true; |
232 | BPoint p1 = original_point; |
233 | BPoint width_point; |
234 | view_polygon = new HSPolygon(NULL__null,0); |
235 | BRect orig_rect = bitmap_rect; |
236 | orig_rect.bottom = orig_rect.top = original_point.y; |
237 | |
238 | size = 0; |
239 | |
240 | while (continue_adjusting_width) { |
241 | if (is_clicks_data_valid) { |
242 | continue_adjusting_width = false; |
243 | is_clicks_data_valid = false; |
244 | } |
245 | else if (is_keys_data_valid) { |
246 | if (last_key_event_bytes[0] == B_ESCAPE) { |
247 | continue_adjusting_width = false; |
248 | draw_line = false; |
Value stored to 'draw_line' is never read | |
249 | } |
250 | is_keys_data_valid = false; |
251 | } |
252 | else { |
253 | if (view->LockLooper()) { |
254 | new_rect = orig_rect; |
255 | new_rect.bottom += size/2; |
256 | new_rect.top -= size/2; |
257 | new_rect = view->convertBitmapRectToView(new_rect); |
258 | if (new_rect != old_rect) { |
259 | if (size > 0) { |
260 | BRect bbox = view_polygon->BoundingBox(); |
261 | view->Draw(bbox); |
262 | point_list[0] = new_rect.LeftTop(); |
263 | point_list[1] = new_rect.RightTop(); |
264 | point_list[2] = new_rect.RightBottom(); |
265 | point_list[3] = new_rect.LeftBottom(); |
266 | view_polygon = new HSPolygon(point_list,4); |
267 | view_polygon->Rotate(original_view_point,angle); |
268 | BPolygon* bpoly = view_polygon->GetBPolygon(); |
269 | view->StrokePolygon(bpoly); |
270 | delete bpoly; |
271 | } |
272 | old_rect = new_rect; |
273 | } |
274 | view->getCoords(&width_point,&buttons); |
275 | view->UnlockLooper(); |
276 | width_point = width_point-p1; |
277 | BPoint spare = width_point; |
278 | width_point.x = cos(-angle / 180 * M_PI3.14159265358979323846) * spare.x - |
279 | sin(-angle / 180 * M_PI3.14159265358979323846) * spare.y; |
280 | width_point.y = sin(-angle / 180 * M_PI3.14159265358979323846) * spare.x + |
281 | cos(-angle / 180 * M_PI3.14159265358979323846) * spare.y; |
282 | size = (int32)(2 * fabs(width_point.y)); |
283 | } |
284 | snooze(20 * 1000); |
285 | } |
286 | } |
287 | } |
288 | delete view_polygon; |
289 | |
290 | bool anti_alias = true; |
291 | if (GetCurrentValue(ANTI_ALIASING_LEVEL_OPTION) == B_CONTROL_OFF) |
292 | anti_alias = false; |
293 | |
294 | if (size > 1) |
295 | drawer->DrawLine(original_point,point,RGBColorToBGRA(c),size,anti_alias,selection); |
296 | else |
297 | drawer->DrawHairLine(original_point,point,RGBColorToBGRA(c),anti_alias,selection); |
298 | |
299 | BRect updated_rect = MakeRectFromPoints(original_point, point); |
300 | |
301 | // This extension might actually be too little. |
302 | updated_rect.left -= size/2; |
303 | updated_rect.top -= size/2; |
304 | updated_rect.right += size/2; |
305 | updated_rect.bottom += size/2; |
306 | |
307 | SetLastUpdatedRect(updated_rect); |
308 | window->Lock(); |
309 | view->SetDrawingMode(old_mode); |
310 | view->UpdateImage(updated_rect); |
311 | view->Sync(); |
312 | window->Unlock(); |
313 | |
314 | delete drawer; |
315 | |
316 | the_script->AddPoint(original_point); |
317 | the_script->AddPoint(point); |
318 | return the_script; |
319 | } |
320 | |
321 | return NULL__null; |
322 | } |
323 | |
324 | |
325 | int32 |
326 | StraightLineTool::UseToolWithScript(ToolScript*,BBitmap*) |
327 | { |
328 | return B_OK((int)0); |
329 | } |
330 | |
331 | |
332 | BView* |
333 | StraightLineTool::ConfigView() |
334 | { |
335 | return new StraightLineToolConfigView(this); |
336 | } |
337 | |
338 | |
339 | const void* |
340 | StraightLineTool::ToolCursor() const |
341 | { |
342 | return HS_LINE_CURSOR; |
343 | } |
344 | |
345 | |
346 | const char* |
347 | StraightLineTool::HelpString(bool isInUse) const |
348 | { |
349 | return (isInUse |
350 | ? B_TRANSLATE("Drawing a straight line.")BLocaleRoster::Default()->GetCatalog()->GetString(("Drawing a straight line." ), "Tools") |
351 | : B_TRANSLATE("Click to draw a straight line.")BLocaleRoster::Default()->GetCatalog()->GetString(("Click to draw a straight line." ), "Tools")); |
352 | } |
353 | |
354 | |
355 | // #pragma mark -- StraightLineToolConfigView |
356 | |
357 | |
358 | StraightLineToolConfigView::StraightLineToolConfigView(DrawingTool* tool) |
359 | : DrawingToolConfigView(tool) |
360 | { |
361 | if (BLayout* layout = GetLayout()) { |
362 | BMessage* message = new BMessage(OPTION_CHANGED); |
363 | message->AddInt32("option", SIZE_OPTION); |
364 | message->AddInt32("value", tool->GetCurrentValue(SIZE_OPTION)); |
365 | |
366 | fLineSize = new NumberSliderControl( |
367 | B_TRANSLATE("Width:")BLocaleRoster::Default()->GetCatalog()->GetString(("Width:" ), "Tools"), |
368 | "1", message, 1, 100, false); |
369 | |
370 | message = new BMessage(OPTION_CHANGED); |
371 | message->AddInt32("option", ANTI_ALIASING_LEVEL_OPTION); |
372 | message->AddInt32("value", 0x00000000); |
373 | |
374 | fAntiAliasing = |
375 | new BCheckBox(B_TRANSLATE("Enable antialiasing")BLocaleRoster::Default()->GetCatalog()->GetString(("Enable antialiasing" ), "Tools"), |
376 | message); |
377 | if (tool->GetCurrentValue(ANTI_ALIASING_LEVEL_OPTION) != B_CONTROL_OFF) |
378 | fAntiAliasing->SetValue(B_CONTROL_ON); |
379 | |
380 | message = new BMessage(OPTION_CHANGED); |
381 | message->AddInt32("option", MODE_OPTION); |
382 | message->AddInt32("value", 0x00000000); |
383 | |
384 | fAdjustableWidth = |
385 | new BCheckBox(B_TRANSLATE("Adjustable width")BLocaleRoster::Default()->GetCatalog()->GetString(("Adjustable width" ), "Tools"), |
386 | message); |
387 | if (tool->GetCurrentValue(MODE_OPTION) != B_CONTROL_OFF) |
388 | fAdjustableWidth->SetValue(B_CONTROL_ON); |
389 | |
390 | BGridLayout* lineSizeLayout = LayoutSliderGrid(fLineSize); |
391 | |
392 | layout->AddView(BGroupLayoutBuilder(B_VERTICAL, kWidgetSpacing) |
393 | .Add(lineSizeLayout) |
394 | .AddStrut(kWidgetSpacing) |
395 | .Add(SeparatorView(B_TRANSLATE("Options")BLocaleRoster::Default()->GetCatalog()->GetString(("Options" ), "Tools"))) |
396 | .AddGroup(B_VERTICAL, kWidgetSpacing) |
397 | .Add(fAdjustableWidth) |
398 | .Add(fAntiAliasing) |
399 | .SetInsets(kWidgetInset, 0.0, 0.0, 0.0) |
400 | .End() |
401 | .TopView() |
402 | ); |
403 | } |
404 | } |
405 | |
406 | |
407 | void |
408 | StraightLineToolConfigView::AttachedToWindow() |
409 | { |
410 | DrawingToolConfigView::AttachedToWindow(); |
411 | |
412 | fLineSize->SetTarget(this); |
413 | fAntiAliasing->SetTarget(this); |
414 | fAdjustableWidth->SetTarget(this); |
415 | } |