Bug Summary

File:home/HaikuArchives/ArtPaint/artpaint/viewmanipulators/TranslationManipulator.cpp
Warning:line 493, column 2
Potential leak of memory pointed to by 'settings'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-haiku -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name TranslationManipulator.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /boot/system/lib/clang/12.0.1 -iquote ./ -iquote artpaint/ -iquote artpaint/Utilities/ -iquote artpaint/application/ -iquote artpaint/controls/ -iquote artpaint/layers/ -iquote artpaint/paintwindow/ -iquote artpaint/tools/ -iquote artpaint/viewmanipulators/ -iquote artpaint/windows/ -iquote objects_artpaint/ -isystem /boot/system/develop/headers/private/interface -internal-isystem /system/develop/headers/c++ -internal-isystem /system/develop/headers/c++/x86_64-unknown-haiku -internal-isystem /system/develop/headers/c++/backward -O3 -fdeprecated-macro -fdebug-compilation-dir /boot/home/HaikuArchives/ArtPaint -ferror-limit 19 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /tmp/scan-build-2022-06-19-103017-1294-1 -x c++ artpaint/viewmanipulators/TranslationManipulator.cpp
1/*
2 * Copyright 2003, Heikki Suhonen
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Heikki Suhonen <heikki.suhonen@gmail.com>
7 *
8 */
9
10#include "ImageView.h"
11#include "MessageConstants.h"
12#include "NumberControl.h"
13#include "Selection.h"
14#include "TranslationManipulator.h"
15
16
17#include <Catalog.h>
18#include <ClassInfo.h>
19#include <LayoutBuilder.h>
20#include <StatusBar.h>
21#include <Window.h>
22
23
24#include <new>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28
29
30#undef B_TRANSLATION_CONTEXT"Manipulators"
31#define B_TRANSLATION_CONTEXT"Manipulators" "Manipulators"
32
33
34using ArtPaint::Interface::NumberControl;
35
36
37TranslationManipulator::TranslationManipulator(BBitmap *bm)
38 : WindowGUIManipulator()
39 , copy_of_the_preview_bitmap(NULL__null)
40{
41 preview_bitmap = bm;
42 if (preview_bitmap != NULL__null)
43 copy_of_the_preview_bitmap = DuplicateBitmap(preview_bitmap);
44
45 settings = new TranslationManipulatorSettings();
46 previous_x_translation = 0;
47 previous_y_translation = 0;
48
49 last_calculated_resolution = 0;
50 lowest_available_quality = 4;
51}
52
53
54TranslationManipulator::~TranslationManipulator()
55{
56 delete settings;
57 delete copy_of_the_preview_bitmap;
58
59 if (config_view != NULL__null) {
60 config_view->RemoveSelf();
61 delete config_view;
62 }
63
64}
65
66
67void TranslationManipulator::MouseDown(BPoint point,uint32,BView*,bool first)
68{
69 if (first)
70 previous_point = point;
71 else {
72// previous_x_translation = settings->x_translation;
73// previous_y_translation = settings->y_translation;
74
75 settings->x_translation += point.x - previous_point.x;
76 settings->y_translation += point.y - previous_point.y;
77
78 previous_point = point;
79
80 if (config_view != NULL__null)
81 config_view->SetValues(settings->x_translation,settings->y_translation);
82 }
83}
84
85
86BBitmap* TranslationManipulator::ManipulateBitmap(ManipulatorSettings *set,BBitmap *original,Selection *selection,BStatusBar *status_bar)
87{
88// printf("TranslationManipulator::ManipulateBitmap\n");
89 TranslationManipulatorSettings *new_settings = cast_as(set,TranslationManipulatorSettings)(dynamic_cast<TranslationManipulatorSettings*>(set));
90
91 if ((status_bar != NULL__null) && (status_bar->Window() != NULL__null)) {
92 if (status_bar->Window()->LockWithTimeout(0) == B_OK((int)0)) {
93 status_bar->Update(100);
94 status_bar->Window()->Unlock();
95 }
96 }
97
98 if (new_settings == NULL__null) {
99 return NULL__null;
100 }
101 if (original == NULL__null) {
102 return NULL__null;
103 }
104 if ((new_settings->x_translation == 0) && (new_settings->y_translation == 0)) {
105 return NULL__null;
106 }
107
108 BBitmap *new_bitmap;
109 if (original != preview_bitmap) {
110 original->Lock();
111 BRect bitmap_frame = original->Bounds();
112 new_bitmap = new BBitmap(bitmap_frame,B_RGB_32_BIT);
113 original->Unlock();
114 if (new_bitmap->IsValid() == FALSE0) {
115 throw std::bad_alloc();
116 }
117 }
118 else {
119 new_bitmap = original;
120 original = copy_of_the_preview_bitmap;
121 }
122
123 union {
124 uint8 bytes[4];
125 uint32 word;
126 } background;
127 // Transparent background.
128 background.bytes[0] = 0xFF;
129 background.bytes[1] = 0xFF;
130 background.bytes[2] = 0xFF;
131 background.bytes[3] = 0x00;
132
133
134 // This function assumes that the both bitmaps are of same size.
135 uint32 *target_bits = (uint32*)new_bitmap->Bits();
136 uint32 *source_bits = (uint32*)original->Bits();
137 uint32 target_bpr = new_bitmap->BytesPerRow()/4;
138 uint32 source_bpr = original->BytesPerRow()/4;
139// printf("test5\n");
140 int32 width = (int32)min_c(new_bitmap->Bounds().Width()+1,original->Bounds().Width()+1)((new_bitmap->Bounds().Width()+1)>(original->Bounds(
).Width()+1)?(original->Bounds().Width()+1):(new_bitmap->
Bounds().Width()+1))
;
141 int32 height = (int32)min_c(new_bitmap->Bounds().Height()+1,original->Bounds().Height()+1)((new_bitmap->Bounds().Height()+1)>(original->Bounds
().Height()+1)?(original->Bounds().Height()+1):(new_bitmap
->Bounds().Height()+1))
;
142// printf("%d %d\n",width,height);
143
144 // We have to copy translations so that we do translation for all pixels
145 // with the same values
146 int32 x_translation_local = ((int32)new_settings->x_translation);
147 int32 y_translation_local = ((int32)new_settings->y_translation);
148// printf("%d %d\n",x_translation_local,y_translation_local);
149 if (selection->IsEmpty()) {
150// printf("Selection is empty\n");
151 // First clear the target bitmap. Here the clearing of the whole bitmap is not usually necessary.
152 // Actually this loop combined with the next should only set each pixel in the bitmap exactly once.
153 for (int32 y=0;y<height;y++) {
154 for (int32 x=0;x<width;x++) {
155 *(target_bits + x + y*target_bpr) = background.word;
156 }
157 }
158// printf("Cleared the target\n");
159 // Copy only the points that are within the intersection of
160 // original_bitmap->Bounds() and original_bitmap->Bounds().OffsetBy(x_translation,y_translation)
161 int32 target_x_offset = max_c(0,x_translation_local)((0)>(x_translation_local)?(0):(x_translation_local));
162 int32 target_y_offset = max_c(0,y_translation_local)((0)>(y_translation_local)?(0):(y_translation_local));
163 int32 source_x_offset = max_c(0,-x_translation_local)((0)>(-x_translation_local)?(0):(-x_translation_local));
164 int32 source_y_offset = max_c(0,-y_translation_local)((0)>(-y_translation_local)?(0):(-y_translation_local));
165
166 for (int32 y = 0;y<height - abs(y_translation_local);y++) {
167 for (int32 x = 0;x<width - abs(x_translation_local);x++) {
168 *(target_bits + x+target_x_offset + (y + target_y_offset)*target_bpr)
169 = *(source_bits + x+source_x_offset + (y + source_y_offset)*source_bpr);
170 }
171 }
172 }
173 else {
174 // First reset the picture
175 for (int32 y=0;y<height;y++) {
176 for (int32 x=0;x<width;x++) {
177 *(target_bits + x + y*target_bpr) = *(source_bits + x + y*source_bpr);
178 }
179 }
180
181 // Then clear the selection
182 BRect selection_bounds = selection->GetBoundingRect();
183 int32 left = (int32)selection_bounds.left;
184 int32 right = (int32)selection_bounds.right;
185 int32 top = (int32)selection_bounds.top;
186 int32 bottom = (int32)selection_bounds.bottom;
187 for (int32 y=top;y<=bottom;y++) {
188 for (int32 x=left;x<=right;x++) {
189 if (selection->ContainsPoint(x,y))
190 *(target_bits + x + y*target_bpr) = background.word;
191 }
192 }
193
194
195 selection_bounds = selection->GetBoundingRect();
196 selection_bounds.OffsetBy(settings->x_translation,settings->y_translation);
197 selection_bounds = selection_bounds & original->Bounds() & new_bitmap->Bounds();
198 left = (int32)selection_bounds.left;
199 right = (int32)selection_bounds.right;
200 top = (int32)selection_bounds.top;
201 bottom = (int32)selection_bounds.bottom;
202 for (int32 y=top;y<=bottom;y++) {
203 for (int32 x=left;x<=right;x++) {
204 int32 new_x = (int32)(x - new_settings->x_translation);
205 int32 new_y = (int32)(y - new_settings->y_translation);
206 if (selection->ContainsPoint(new_x,new_y))
207 *(target_bits + x + y*target_bpr) = *(source_bits + new_x + new_y*source_bpr);
208 }
209 }
210// printf("Did the translation\n");
211 }
212
213 return new_bitmap;
214}
215
216
217int32 TranslationManipulator::PreviewBitmap(Selection *selection,bool full_quality,BRegion *updated_region)
218{
219 if ((preview_bitmap == NULL__null) || (copy_of_the_preview_bitmap == NULL__null))
220 return 0;
221 // First decide the resolution of the bitmap
222 if ((previous_x_translation == settings->x_translation) && (previous_y_translation == settings->y_translation) && (full_quality == FALSE0)) {
223 if (last_calculated_resolution <= highest_available_quality) {
224 last_calculated_resolution = 0;
225 if (full_quality == TRUE1) {
226 updated_region->Set(preview_bitmap->Bounds());
227 return 1;
228 }
229 else
230 return 0;
231 }
232 else {
233 if (full_quality == FALSE0)
234 last_calculated_resolution = last_calculated_resolution / 2;
235 else
236 last_calculated_resolution = min_c(1,last_calculated_resolution/2)((1)>(last_calculated_resolution/2)?(last_calculated_resolution
/2):(1))
;
237 }
238 }
239 else if (full_quality == TRUE1)
240 last_calculated_resolution = 1;
241 else
242 last_calculated_resolution = lowest_available_quality;
243
244 if (last_calculated_resolution > 0) {
245 union {
246 uint8 bytes[4];
247 uint32 word;
248 } background;
249 // Transparent background.
250 background.bytes[0] = 0xFF;
251 background.bytes[1] = 0xFF;
252 background.bytes[2] = 0xFF;
253 background.bytes[3] = 0x00;
254
255
256 // This function assumes that the both bitmaps are of same size.
257 uint32 *target_bits = (uint32*)preview_bitmap->Bits();
258 uint32 *source_bits = (uint32*)copy_of_the_preview_bitmap->Bits();
259 uint32 target_bpr = preview_bitmap->BytesPerRow()/4;
260 uint32 source_bpr = copy_of_the_preview_bitmap->BytesPerRow()/4;
261
262 int32 width = (int32)min_c(preview_bitmap->Bounds().Width()+1,copy_of_the_preview_bitmap->Bounds().Width()+1)((preview_bitmap->Bounds().Width()+1)>(copy_of_the_preview_bitmap
->Bounds().Width()+1)?(copy_of_the_preview_bitmap->Bounds
().Width()+1):(preview_bitmap->Bounds().Width()+1))
;
263 int32 height = (int32)min_c(preview_bitmap->Bounds().Height()+1,copy_of_the_preview_bitmap->Bounds().Height()+1)((preview_bitmap->Bounds().Height()+1)>(copy_of_the_preview_bitmap
->Bounds().Height()+1)?(copy_of_the_preview_bitmap->Bounds
().Height()+1):(preview_bitmap->Bounds().Height()+1))
;
264
265 // We have to copy translations so that we do translation for all pixels
266 // with the same values
267 int32 x_translation_local = ((int32)settings->x_translation)/last_calculated_resolution*last_calculated_resolution;
268 int32 y_translation_local = ((int32)settings->y_translation)/last_calculated_resolution*last_calculated_resolution;
269 if (selection->IsEmpty()) {
270 // First clear the target bitmap.
271 BRegion to_be_cleared;
272 to_be_cleared.Set(uncleared_rect);
273// uncleared_rect.PrintToStream();
274 uncleared_rect.left = max_c(0,x_translation_local)((0)>(x_translation_local)?(0):(x_translation_local));
275 uncleared_rect.top = max_c(0,y_translation_local)((0)>(y_translation_local)?(0):(y_translation_local));
276 uncleared_rect.right = min_c(width-1,width-1+x_translation_local)((width-1)>(width-1+x_translation_local)?(width-1+x_translation_local
):(width-1))
;
277 uncleared_rect.bottom = min_c(height-1,height-1+y_translation_local)((height-1)>(height-1+y_translation_local)?(height-1+y_translation_local
):(height-1))
;
278 to_be_cleared.Exclude(uncleared_rect);
279 for (int32 i=0;i<to_be_cleared.CountRects();i++) {
280 BRect rect = to_be_cleared.RectAt(i);
281 int32 left = (int32)(floor(rect.left / last_calculated_resolution) * last_calculated_resolution);
282 int32 top = (int32)(floor(rect.top / last_calculated_resolution) * last_calculated_resolution);
283 int32 right = (int32)(ceil(rect.right / last_calculated_resolution) * last_calculated_resolution);
284 int32 bottom = (int32)(ceil(rect.bottom / last_calculated_resolution) * last_calculated_resolution);
285 // printf("left %d, top %d, res: %d\n",left,top,last_calculated_resolution);
286 for (int32 y=top;y<=bottom;y += last_calculated_resolution) {
287 for (int32 x=left;x<=right;x += last_calculated_resolution) {
288 *(target_bits + x + y*target_bpr) = background.word;
289 }
290 }
291 }
292 // Copy only the points that are within the intersection of
293 // original_bitmap->Bounds() and original_bitmap->Bounds().OffsetBy(x_translation,y_translation)
294 int32 target_x_offset = max_c(0,x_translation_local)((0)>(x_translation_local)?(0):(x_translation_local));
295 int32 target_y_offset = max_c(0,y_translation_local)((0)>(y_translation_local)?(0):(y_translation_local));
296 int32 source_x_offset = max_c(0,-x_translation_local)((0)>(-x_translation_local)?(0):(-x_translation_local));
297 int32 source_y_offset = max_c(0,-y_translation_local)((0)>(-y_translation_local)?(0):(-y_translation_local));
298
299 for (int32 y = 0;y<height - abs(y_translation_local);y += last_calculated_resolution) {
300 for (int32 x = 0;x<width - abs(x_translation_local);x += last_calculated_resolution) {
301 *(target_bits + x+target_x_offset + (y + target_y_offset)*target_bpr)
302 = *(source_bits + x+source_x_offset + (y + source_y_offset)*source_bpr);
303 }
304 }
305
306 updated_region->Set(uncleared_rect);
307 updated_region->Include(&to_be_cleared);
308// updated_region->Set(preview_bitmap->Bounds());
309 }
310 else {
311 selection->Translate(x_translation_local-previous_x_translation,y_translation_local-previous_y_translation);
312
313 // First reset the picture
314 BRegion to_be_cleared;
315 to_be_cleared.Set(uncleared_rect);
316 uncleared_rect = selection->GetBoundingRect();
317 uncleared_rect.OffsetBy(x_translation_local,y_translation_local);
318 uncleared_rect.InsetBy(-1,-1);
319 uncleared_rect = uncleared_rect & preview_bitmap->Bounds();
320 for (int32 i=0;i<to_be_cleared.CountRects();i++) {
321 BRect rect = to_be_cleared.RectAt(i);
322 int32 left = (int32)(floor(rect.left / last_calculated_resolution) * last_calculated_resolution);
323 int32 top = (int32)(floor(rect.top / last_calculated_resolution) * last_calculated_resolution);
324 int32 right = (int32)(floor(rect.right / last_calculated_resolution) * last_calculated_resolution);
325 int32 bottom = (int32)(floor(rect.bottom / last_calculated_resolution) * last_calculated_resolution);
326
327 for (int32 y=top;y<=bottom;y += last_calculated_resolution) {
328 for (int32 x=left;x<=right;x += last_calculated_resolution) {
329 *(target_bits + x + y*target_bpr) = *(source_bits + x + y*source_bpr);
330 }
331 }
332 }
333
334 // Then do the selection
335 BRect selection_bounds = selection->GetBoundingRect();
336 selection_bounds.left = ceil(selection_bounds.left / last_calculated_resolution)*last_calculated_resolution;
337 selection_bounds.top = ceil(selection_bounds.top / last_calculated_resolution)*last_calculated_resolution;
338 int32 left = (int32)selection_bounds.left;
339 int32 right = (int32)selection_bounds.right;
340 int32 top = (int32)selection_bounds.top;
341 int32 bottom = (int32)selection_bounds.bottom;
342 for (int32 y=top;y<=bottom;y += last_calculated_resolution) {
343 for (int32 x=left;x<=right;x += last_calculated_resolution) {
344 if (selection->ContainsPoint(x,y))
345 *(target_bits + x + y*target_bpr) = background.word;
346 }
347 }
348
349
350
351 selection_bounds = selection->GetBoundingRect();
352 selection_bounds.OffsetBy(settings->x_translation,settings->y_translation);
353 selection_bounds = selection_bounds & preview_bitmap->Bounds();
354 selection_bounds.left = ceil(selection_bounds.left / last_calculated_resolution)*last_calculated_resolution;
355 selection_bounds.top = ceil(selection_bounds.top / last_calculated_resolution)*last_calculated_resolution;
356 left = (int32)selection_bounds.left;
357 right = (int32)selection_bounds.right;
358 top = (int32)selection_bounds.top;
359 bottom = (int32)selection_bounds.bottom;
360 for (int32 y=top;y<=bottom;y += last_calculated_resolution) {
361 for (int32 x=left;x<=right;x += last_calculated_resolution) {
362 int32 new_x = (int32)(x - settings->x_translation);
363 int32 new_y = (int32)(y - settings->y_translation);
364 if (selection->ContainsPoint(new_x,new_y))
365 *(target_bits + x + y*target_bpr) = *(source_bits + new_x + new_y*source_bpr);
366 }
367 }
368
369 updated_region->Set(uncleared_rect);
370 updated_region->Include(&to_be_cleared);
371 }
372 previous_x_translation = x_translation_local;
373 previous_y_translation = y_translation_local;
374 }
375 return last_calculated_resolution;
376}
377
378ManipulatorSettings* TranslationManipulator::ReturnSettings()
379{
380 return new TranslationManipulatorSettings(settings);
3
Memory is allocated
381}
382
383
384void TranslationManipulator::Reset(Selection *sel)
385{
386 sel->Translate(int32(-settings->x_translation), int32(-settings->y_translation));
387 settings->x_translation = 0;
388 settings->y_translation = 0;
389 previous_x_translation = 0;
390 previous_y_translation = 0;
391
392 if (preview_bitmap != NULL__null) {
393 // memcpy seems to be about 10-15% faster that copying with loop.
394 uint32 *source = (uint32*)copy_of_the_preview_bitmap->Bits();
395 uint32 *target = (uint32*)preview_bitmap->Bits();
396 uint32 bits_length = preview_bitmap->BitsLength();
397
398 memcpy(target,source,bits_length);
399
400 uncleared_rect = preview_bitmap->Bounds();
401 }
402}
403
404
405void TranslationManipulator::SetPreviewBitmap(BBitmap *bm)
406{
407 delete copy_of_the_preview_bitmap;
408 preview_bitmap = bm;
409 if (preview_bitmap != NULL__null) {
410 copy_of_the_preview_bitmap = DuplicateBitmap(preview_bitmap);
411 }
412 else {
413 copy_of_the_preview_bitmap = NULL__null;
414 }
415
416 if (preview_bitmap != NULL__null) {
417 double speed = GetSystemClockSpeed() / 1000;
418
419 BRect bounds = preview_bitmap->Bounds();
420 float num_pixels = (bounds.Width()+1) * (bounds.Height() + 1);
421 lowest_available_quality = 1;
422
423 while ((2*num_pixels/lowest_available_quality/lowest_available_quality) > speed)
424 lowest_available_quality *= 2;
425
426 highest_available_quality = max_c(lowest_available_quality/2,1)((lowest_available_quality/2)>(1)?(lowest_available_quality
/2):(1))
;
427
428 uncleared_rect = preview_bitmap->Bounds();
429 }
430 else {
431 lowest_available_quality = 1;
432 highest_available_quality = 1;
433 }
434 last_calculated_resolution = lowest_available_quality;
435}
436
437
438
439BView*
440TranslationManipulator::MakeConfigurationView(const BMessenger& target)
441{
442 config_view = new TranslationManipulatorView(this, target);
1
Calling constructor for 'TranslationManipulatorView'
443 config_view->SetValues(settings->x_translation, settings->y_translation);
444 return config_view;
445}
446
447
448void
449TranslationManipulator::SetValues(float x, float y)
450{
451 settings->x_translation = x;
452 settings->y_translation = y;
453}
454
455
456const char*
457TranslationManipulator::ReturnName()
458{
459 return B_TRANSLATE("Translate" B_UTF8_ELLIPSIS)BLocaleRoster::Default()->GetCatalog()->GetString(("Translate"
"\xE2\x80\xA6"), "Manipulators")
;
460}
461
462
463const char*
464TranslationManipulator::ReturnHelpString()
465{
466 return B_TRANSLATE("Drag the image to correct position.")BLocaleRoster::Default()->GetCatalog()->GetString(("Drag the image to correct position."
), "Manipulators")
;
467}
468
469
470// #pragma mark -- TranslationManipulatorView
471
472
473TranslationManipulatorView::TranslationManipulatorView(
474 TranslationManipulator* manipulator, const BMessenger& target)
475 : WindowGUIManipulatorView()
476 , fTarget(target)
477 , fManipulator(manipulator)
478{
479 fXControl = new NumberControl("X:", "9999˚",
480 new BMessage(HS_MANIPULATOR_ADJUSTING_FINISHED'Mafi'), 5, true);
481
482 fYControl = new NumberControl("Y:", "9999˚",
483 new BMessage(HS_MANIPULATOR_ADJUSTING_FINISHED'Mafi'), 5, true);
484
485 SetLayout(BLayoutBuilder::Group<>(this, B_HORIZONTAL)
486 .Add(fXControl)
487 .Add(fYControl)
488 );
489
490 TranslationManipulatorSettings* settings
491 = (TranslationManipulatorSettings*)manipulator->ReturnSettings();
2
Calling 'TranslationManipulator::ReturnSettings'
4
Returned allocated memory
492 fXControl->SetValue(settings->x_translation);
493 fYControl->SetValue(settings->y_translation);
5
Potential leak of memory pointed to by 'settings'
494}
495
496
497void
498TranslationManipulatorView::AttachedToWindow()
499{
500 fXControl->SetTarget(this);
501 fYControl->SetTarget(this);
502
503 if (BView* parent = Parent()) {
504 SetLowColor(parent->LowColor());
505 SetViewColor(parent->ViewColor());
506 }
507
508 fXControl->MakeFocus(true);
509
510 WindowGUIManipulatorView::AttachedToWindow();
511}
512
513
514void
515TranslationManipulatorView::MessageReceived(BMessage* message)
516{
517 switch (message->what) {
518 case HS_MANIPULATOR_ADJUSTING_FINISHED'Mafi': {
519 if (fManipulator)
520 fManipulator->SetValues(fXControl->Value(), fYControl->Value());
521
522 if (fTarget.IsValid())
523 fTarget.SendMessage(message);
524 } break;
525
526 default: {
527 WindowGUIManipulatorView::MessageReceived(message);
528 } break;
529 }
530}
531
532
533void
534TranslationManipulatorView::SetValues(float x, float y)
535{
536 BWindow* window = Window();
537 if (window && window->Lock()) {
538 fXControl->SetValue(int32(x));
539 fYControl->SetValue(int32(y));
540
541 window->Unlock();
542 }
543}
544
545
546void
547TranslationManipulatorView::SetTarget(const BMessenger& target)
548{
549 fTarget = target;
550}