File: | home/HaikuArchives/ArtPaint/artpaint/viewmanipulators/TranslationManipulator.cpp |
Warning: | line 493, column 2 Potential leak of memory pointed to by 'settings' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
34 | using ArtPaint::Interface::NumberControl; | |||
35 | ||||
36 | ||||
37 | TranslationManipulator::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 | ||||
54 | TranslationManipulator::~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 | ||||
67 | void 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 | ||||
86 | BBitmap* 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 | ||||
217 | int32 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 | ||||
378 | ManipulatorSettings* TranslationManipulator::ReturnSettings() | |||
379 | { | |||
380 | return new TranslationManipulatorSettings(settings); | |||
381 | } | |||
382 | ||||
383 | ||||
384 | void 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 | ||||
405 | void 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 | ||||
439 | BView* | |||
440 | TranslationManipulator::MakeConfigurationView(const BMessenger& target) | |||
441 | { | |||
442 | config_view = new TranslationManipulatorView(this, target); | |||
| ||||
443 | config_view->SetValues(settings->x_translation, settings->y_translation); | |||
444 | return config_view; | |||
445 | } | |||
446 | ||||
447 | ||||
448 | void | |||
449 | TranslationManipulator::SetValues(float x, float y) | |||
450 | { | |||
451 | settings->x_translation = x; | |||
452 | settings->y_translation = y; | |||
453 | } | |||
454 | ||||
455 | ||||
456 | const char* | |||
457 | TranslationManipulator::ReturnName() | |||
458 | { | |||
459 | return B_TRANSLATE("Translate" B_UTF8_ELLIPSIS)BLocaleRoster::Default()->GetCatalog()->GetString(("Translate" "\xE2\x80\xA6"), "Manipulators"); | |||
460 | } | |||
461 | ||||
462 | ||||
463 | const char* | |||
464 | TranslationManipulator::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 | ||||
473 | TranslationManipulatorView::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(); | |||
492 | fXControl->SetValue(settings->x_translation); | |||
493 | fYControl->SetValue(settings->y_translation); | |||
| ||||
494 | } | |||
495 | ||||
496 | ||||
497 | void | |||
498 | TranslationManipulatorView::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 | ||||
514 | void | |||
515 | TranslationManipulatorView::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 | ||||
533 | void | |||
534 | TranslationManipulatorView::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 | ||||
546 | void | |||
547 | TranslationManipulatorView::SetTarget(const BMessenger& target) | |||
548 | { | |||
549 | fTarget = target; | |||
550 | } |