xref: /haiku/src/apps/resedit/BitmapView.cpp (revision 22c6ae695176ead7d736db8c69472d8ae89dc75f)
1*22c6ae69SDarkWyrm #include "BitmapView.h"
2*22c6ae69SDarkWyrm #include <Entry.h>
3*22c6ae69SDarkWyrm #include <TranslationUtils.h>
4*22c6ae69SDarkWyrm #include <TranslatorRoster.h>
5*22c6ae69SDarkWyrm #include <TranslatorFormats.h>
6*22c6ae69SDarkWyrm #include <Clipboard.h>
7*22c6ae69SDarkWyrm #include <BitmapStream.h>
8*22c6ae69SDarkWyrm #include <MenuItem.h>
9*22c6ae69SDarkWyrm #include <Font.h>
10*22c6ae69SDarkWyrm #include <Alert.h>
11*22c6ae69SDarkWyrm 
12*22c6ae69SDarkWyrm // TODO: Add support for labels
13*22c6ae69SDarkWyrm 
14*22c6ae69SDarkWyrm #define M_REMOVE_IMAGE 'mrmi'
15*22c6ae69SDarkWyrm #define M_PASTE_IMAGE 'mpsi'
16*22c6ae69SDarkWyrm 
17*22c6ae69SDarkWyrm enum
18*22c6ae69SDarkWyrm {
19*22c6ae69SDarkWyrm 	CLIP_NONE=0,
20*22c6ae69SDarkWyrm 	CLIP_BEOS=1,
21*22c6ae69SDarkWyrm 	CLIP_SHOWIMAGE=2,
22*22c6ae69SDarkWyrm 	CLIP_PRODUCTIVE=3
23*22c6ae69SDarkWyrm };
24*22c6ae69SDarkWyrm 
25*22c6ae69SDarkWyrm inline void SetRGBColor(rgb_color *col,uint8 r, uint8 g, uint8 b, uint8 a=255);
26*22c6ae69SDarkWyrm 
27*22c6ae69SDarkWyrm void SetRGBColor(rgb_color *col,uint8 r, uint8 g, uint8 b, uint8 a)
28*22c6ae69SDarkWyrm {
29*22c6ae69SDarkWyrm 	if(col)
30*22c6ae69SDarkWyrm 	{
31*22c6ae69SDarkWyrm 		col->red=r;
32*22c6ae69SDarkWyrm 		col->green=g;
33*22c6ae69SDarkWyrm 		col->blue=b;
34*22c6ae69SDarkWyrm 		col->alpha=a;
35*22c6ae69SDarkWyrm 	}
36*22c6ae69SDarkWyrm }
37*22c6ae69SDarkWyrm 
38*22c6ae69SDarkWyrm BitmapView::BitmapView(BRect frame, const char *name, BMessage *mod, BBitmap *bitmap,
39*22c6ae69SDarkWyrm 	const char *label, border_style borderstyle,int32 resize,int32 flags)
40*22c6ae69SDarkWyrm  : BView(frame, name, resize, flags)
41*22c6ae69SDarkWyrm {
42*22c6ae69SDarkWyrm 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
43*22c6ae69SDarkWyrm 
44*22c6ae69SDarkWyrm 	if(bitmap && bitmap->IsValid())
45*22c6ae69SDarkWyrm 		fBitmap=bitmap;
46*22c6ae69SDarkWyrm 	else
47*22c6ae69SDarkWyrm 		fBitmap=NULL;
48*22c6ae69SDarkWyrm 
49*22c6ae69SDarkWyrm 	if(mod)
50*22c6ae69SDarkWyrm 		SetMessage(mod);
51*22c6ae69SDarkWyrm 
52*22c6ae69SDarkWyrm 	fLabel=label;
53*22c6ae69SDarkWyrm 	fBorderStyle=borderstyle;
54*22c6ae69SDarkWyrm 	fFixedSize=false;
55*22c6ae69SDarkWyrm 	fEnabled=true;
56*22c6ae69SDarkWyrm 	fRemovableBitmap=false;
57*22c6ae69SDarkWyrm 	fAcceptDrops=true;
58*22c6ae69SDarkWyrm 	fAcceptPaste=true;
59*22c6ae69SDarkWyrm 	fConstrainDrops=true;
60*22c6ae69SDarkWyrm 	fMaxWidth=100;
61*22c6ae69SDarkWyrm 	fMaxHeight=100;
62*22c6ae69SDarkWyrm 
63*22c6ae69SDarkWyrm 	fPopUpMenu=new BPopUpMenu("deletepopup",false,false);
64*22c6ae69SDarkWyrm 	fPopUpMenu->AddItem(new BMenuItem("Close This Menu",new BMessage(B_CANCEL)));
65*22c6ae69SDarkWyrm 	fPopUpMenu->AddSeparatorItem();
66*22c6ae69SDarkWyrm 
67*22c6ae69SDarkWyrm 	fPasteItem=new BMenuItem("Paste Photo from Clipboard",new BMessage(M_PASTE_IMAGE));
68*22c6ae69SDarkWyrm 	fPopUpMenu->AddItem(fPasteItem);
69*22c6ae69SDarkWyrm 
70*22c6ae69SDarkWyrm 	fPopUpMenu->AddSeparatorItem();
71*22c6ae69SDarkWyrm 
72*22c6ae69SDarkWyrm 	fRemoveItem=new BMenuItem("Remove Photo",new BMessage(M_REMOVE_IMAGE));
73*22c6ae69SDarkWyrm 	fPopUpMenu->AddItem(fRemoveItem);
74*22c6ae69SDarkWyrm 
75*22c6ae69SDarkWyrm 	CalculateBitmapRect();
76*22c6ae69SDarkWyrm 
77*22c6ae69SDarkWyrm 	// Calculate the offsets for each of the words -- the phrase will be center justified
78*22c6ae69SDarkWyrm 	fNoPhotoWidths[0]=StringWidth("Drop");
79*22c6ae69SDarkWyrm 	fNoPhotoWidths[1]=StringWidth("a");
80*22c6ae69SDarkWyrm 	fNoPhotoWidths[2]=StringWidth("Photo");
81*22c6ae69SDarkWyrm 	fNoPhotoWidths[3]=StringWidth("Here");
82*22c6ae69SDarkWyrm 
83*22c6ae69SDarkWyrm 	font_height fh;
84*22c6ae69SDarkWyrm 	GetFontHeight(&fh);
85*22c6ae69SDarkWyrm 	float totalheight=fh.ascent+fh.descent+fh.leading;
86*22c6ae69SDarkWyrm 	float yoffset=(Bounds().Height()-10-(totalheight*4))/2;
87*22c6ae69SDarkWyrm 	fNoPhotoOffsets[0].Set( (Bounds().Width()-fNoPhotoWidths[0])/2,totalheight+yoffset);
88*22c6ae69SDarkWyrm 	fNoPhotoOffsets[1].Set( (Bounds().Width()-fNoPhotoWidths[1])/2,fNoPhotoOffsets[0].y+totalheight);
89*22c6ae69SDarkWyrm 	fNoPhotoOffsets[2].Set( (Bounds().Width()-fNoPhotoWidths[2])/2,fNoPhotoOffsets[1].y+totalheight);
90*22c6ae69SDarkWyrm 	fNoPhotoOffsets[3].Set( (Bounds().Width()-fNoPhotoWidths[3])/2,fNoPhotoOffsets[2].y+totalheight);
91*22c6ae69SDarkWyrm }
92*22c6ae69SDarkWyrm 
93*22c6ae69SDarkWyrm BitmapView::~BitmapView(void)
94*22c6ae69SDarkWyrm {
95*22c6ae69SDarkWyrm 	delete fPopUpMenu;
96*22c6ae69SDarkWyrm }
97*22c6ae69SDarkWyrm 
98*22c6ae69SDarkWyrm void BitmapView::AttachedToWindow(void)
99*22c6ae69SDarkWyrm {
100*22c6ae69SDarkWyrm 	SetTarget((BHandler*)Window());
101*22c6ae69SDarkWyrm 	fPopUpMenu->SetTargetForItems(this);
102*22c6ae69SDarkWyrm }
103*22c6ae69SDarkWyrm 
104*22c6ae69SDarkWyrm void BitmapView::SetBitmap(BBitmap *bitmap)
105*22c6ae69SDarkWyrm {
106*22c6ae69SDarkWyrm 	if(bitmap && bitmap->IsValid())
107*22c6ae69SDarkWyrm 	{
108*22c6ae69SDarkWyrm 		if(fBitmap==bitmap)
109*22c6ae69SDarkWyrm 			return;
110*22c6ae69SDarkWyrm 
111*22c6ae69SDarkWyrm 		fBitmap=bitmap;
112*22c6ae69SDarkWyrm 	}
113*22c6ae69SDarkWyrm 	else
114*22c6ae69SDarkWyrm 	{
115*22c6ae69SDarkWyrm 		if(fBitmap==NULL)
116*22c6ae69SDarkWyrm 			return;
117*22c6ae69SDarkWyrm 
118*22c6ae69SDarkWyrm 		fBitmap=NULL;
119*22c6ae69SDarkWyrm 	}
120*22c6ae69SDarkWyrm 
121*22c6ae69SDarkWyrm 	CalculateBitmapRect();
122*22c6ae69SDarkWyrm 	if(!IsHidden())
123*22c6ae69SDarkWyrm 		Invalidate();
124*22c6ae69SDarkWyrm }
125*22c6ae69SDarkWyrm 
126*22c6ae69SDarkWyrm void BitmapView::SetEnabled(bool value)
127*22c6ae69SDarkWyrm {
128*22c6ae69SDarkWyrm 	if(fEnabled!=value)
129*22c6ae69SDarkWyrm 	{
130*22c6ae69SDarkWyrm 		fEnabled=value;
131*22c6ae69SDarkWyrm 		Invalidate();
132*22c6ae69SDarkWyrm 	}
133*22c6ae69SDarkWyrm }
134*22c6ae69SDarkWyrm 
135*22c6ae69SDarkWyrm /*
136*22c6ae69SDarkWyrm void BitmapView::SetLabel(const char *label)
137*22c6ae69SDarkWyrm {
138*22c6ae69SDarkWyrm 	if(fLabel.Compare(label)!=0)
139*22c6ae69SDarkWyrm 	{
140*22c6ae69SDarkWyrm 		fLabel=label;
141*22c6ae69SDarkWyrm 
142*22c6ae69SDarkWyrm 		CalculateBitmapRect();
143*22c6ae69SDarkWyrm 		if(!IsHidden())
144*22c6ae69SDarkWyrm 			Invalidate();
145*22c6ae69SDarkWyrm 	}
146*22c6ae69SDarkWyrm }
147*22c6ae69SDarkWyrm */
148*22c6ae69SDarkWyrm 
149*22c6ae69SDarkWyrm void BitmapView::SetStyle(border_style style)
150*22c6ae69SDarkWyrm {
151*22c6ae69SDarkWyrm 	if(fBorderStyle!=style)
152*22c6ae69SDarkWyrm 	{
153*22c6ae69SDarkWyrm 		fBorderStyle=style;
154*22c6ae69SDarkWyrm 
155*22c6ae69SDarkWyrm 		CalculateBitmapRect();
156*22c6ae69SDarkWyrm 		if(!IsHidden())
157*22c6ae69SDarkWyrm 			Invalidate();
158*22c6ae69SDarkWyrm 	}
159*22c6ae69SDarkWyrm }
160*22c6ae69SDarkWyrm 
161*22c6ae69SDarkWyrm void BitmapView::SetFixedSize(bool isfixed)
162*22c6ae69SDarkWyrm {
163*22c6ae69SDarkWyrm 	if(fFixedSize!=isfixed)
164*22c6ae69SDarkWyrm 	{
165*22c6ae69SDarkWyrm 		fFixedSize=isfixed;
166*22c6ae69SDarkWyrm 
167*22c6ae69SDarkWyrm 		CalculateBitmapRect();
168*22c6ae69SDarkWyrm 		if(!IsHidden())
169*22c6ae69SDarkWyrm 			Invalidate();
170*22c6ae69SDarkWyrm 	}
171*22c6ae69SDarkWyrm }
172*22c6ae69SDarkWyrm 
173*22c6ae69SDarkWyrm void BitmapView::MessageReceived(BMessage *msg)
174*22c6ae69SDarkWyrm {
175*22c6ae69SDarkWyrm 	if(msg->WasDropped() && AcceptsDrops())
176*22c6ae69SDarkWyrm 	{
177*22c6ae69SDarkWyrm 		// We'll handle two types of drops: those from Tracker and those from ShowImage
178*22c6ae69SDarkWyrm 		if(msg->what==B_SIMPLE_DATA)
179*22c6ae69SDarkWyrm 		{
180*22c6ae69SDarkWyrm 			int32 actions;
181*22c6ae69SDarkWyrm 			if(msg->FindInt32("be:actions",&actions)==B_OK)
182*22c6ae69SDarkWyrm 			{
183*22c6ae69SDarkWyrm 				// ShowImage drop. This is a negotiated drag&drop, so send a reply
184*22c6ae69SDarkWyrm 				BMessage reply(B_COPY_TARGET), response;
185*22c6ae69SDarkWyrm 				reply.AddString("be:types","image/jpeg");
186*22c6ae69SDarkWyrm 				reply.AddString("be:types","image/png");
187*22c6ae69SDarkWyrm 
188*22c6ae69SDarkWyrm 				msg->SendReply(&reply,&response);
189*22c6ae69SDarkWyrm 
190*22c6ae69SDarkWyrm 				// now, we've gotten the response
191*22c6ae69SDarkWyrm 				if(response.what==B_MIME_DATA)
192*22c6ae69SDarkWyrm 				{
193*22c6ae69SDarkWyrm 					// Obtain and translate the received data
194*22c6ae69SDarkWyrm 					uint8 *imagedata;
195*22c6ae69SDarkWyrm 					ssize_t datasize;
196*22c6ae69SDarkWyrm 
197*22c6ae69SDarkWyrm 					// Try JPEG first
198*22c6ae69SDarkWyrm 					if(response.FindData("image/jpeg",B_MIME_DATA,(const void **)&imagedata,&datasize)!=B_OK)
199*22c6ae69SDarkWyrm 					{
200*22c6ae69SDarkWyrm 						// Try PNG next and piddle out if unsuccessful
201*22c6ae69SDarkWyrm 						if(response.FindData("image/png",B_PNG_FORMAT,(const void **)&imagedata,&datasize)!=B_OK)
202*22c6ae69SDarkWyrm 							return;
203*22c6ae69SDarkWyrm 					}
204*22c6ae69SDarkWyrm 
205*22c6ae69SDarkWyrm 					// Set up to decode into memory
206*22c6ae69SDarkWyrm 					BMemoryIO memio(imagedata,datasize);
207*22c6ae69SDarkWyrm 					BTranslatorRoster *roster=BTranslatorRoster::Default();
208*22c6ae69SDarkWyrm 					BBitmapStream bstream;
209*22c6ae69SDarkWyrm 
210*22c6ae69SDarkWyrm 					if(roster->Translate(&memio,NULL,NULL,&bstream, B_TRANSLATOR_BITMAP)==B_OK)
211*22c6ae69SDarkWyrm 					{
212*22c6ae69SDarkWyrm 						BBitmap *bmp;
213*22c6ae69SDarkWyrm 						if(bstream.DetachBitmap(&bmp)!=B_OK)
214*22c6ae69SDarkWyrm 							return;
215*22c6ae69SDarkWyrm 
216*22c6ae69SDarkWyrm 						SetBitmap(bmp);
217*22c6ae69SDarkWyrm 
218*22c6ae69SDarkWyrm 						if(fConstrainDrops)
219*22c6ae69SDarkWyrm 							ConstrainBitmap();
220*22c6ae69SDarkWyrm 
221*22c6ae69SDarkWyrm 						Invoke();
222*22c6ae69SDarkWyrm 					}
223*22c6ae69SDarkWyrm 				}
224*22c6ae69SDarkWyrm 				return;
225*22c6ae69SDarkWyrm 			}
226*22c6ae69SDarkWyrm 
227*22c6ae69SDarkWyrm 			entry_ref ref;
228*22c6ae69SDarkWyrm 			if(msg->FindRef("refs",&ref)==B_OK)
229*22c6ae69SDarkWyrm 			{
230*22c6ae69SDarkWyrm 				// Tracker drop
231*22c6ae69SDarkWyrm 				BBitmap *bmp=BTranslationUtils::GetBitmap(&ref);
232*22c6ae69SDarkWyrm 				if(bmp)
233*22c6ae69SDarkWyrm 				{
234*22c6ae69SDarkWyrm 					SetBitmap(bmp);
235*22c6ae69SDarkWyrm 
236*22c6ae69SDarkWyrm 					if(fConstrainDrops)
237*22c6ae69SDarkWyrm 						ConstrainBitmap();
238*22c6ae69SDarkWyrm 
239*22c6ae69SDarkWyrm 					Invoke();
240*22c6ae69SDarkWyrm 				}
241*22c6ae69SDarkWyrm 			}
242*22c6ae69SDarkWyrm 		}
243*22c6ae69SDarkWyrm 		return;
244*22c6ae69SDarkWyrm 	}
245*22c6ae69SDarkWyrm 
246*22c6ae69SDarkWyrm 	switch(msg->what)
247*22c6ae69SDarkWyrm 	{
248*22c6ae69SDarkWyrm 		case M_REMOVE_IMAGE:
249*22c6ae69SDarkWyrm 		{
250*22c6ae69SDarkWyrm 			BAlert *alert=new BAlert("Mr. Peeps!","This cannot be undone. Remove the image?","Remove",
251*22c6ae69SDarkWyrm 				"Cancel");
252*22c6ae69SDarkWyrm 			int32 value=alert->Go();
253*22c6ae69SDarkWyrm 			if(value==0)
254*22c6ae69SDarkWyrm 			{
255*22c6ae69SDarkWyrm 				SetBitmap(NULL);
256*22c6ae69SDarkWyrm 
257*22c6ae69SDarkWyrm 				if(Target())
258*22c6ae69SDarkWyrm 				{
259*22c6ae69SDarkWyrm 					BMessenger msgr(Target());
260*22c6ae69SDarkWyrm 
261*22c6ae69SDarkWyrm 					msgr.SendMessage(new BMessage(M_BITMAP_REMOVED));
262*22c6ae69SDarkWyrm 					return;
263*22c6ae69SDarkWyrm 				}
264*22c6ae69SDarkWyrm 			}
265*22c6ae69SDarkWyrm 		}
266*22c6ae69SDarkWyrm 		case M_PASTE_IMAGE:
267*22c6ae69SDarkWyrm 		{
268*22c6ae69SDarkWyrm 			PasteBitmap();
269*22c6ae69SDarkWyrm 
270*22c6ae69SDarkWyrm 			Invoke();
271*22c6ae69SDarkWyrm 		}
272*22c6ae69SDarkWyrm 	}
273*22c6ae69SDarkWyrm 	BView::MessageReceived(msg);
274*22c6ae69SDarkWyrm }
275*22c6ae69SDarkWyrm 
276*22c6ae69SDarkWyrm void BitmapView::Draw(BRect rect)
277*22c6ae69SDarkWyrm {
278*22c6ae69SDarkWyrm 	if(fBitmap)
279*22c6ae69SDarkWyrm 		DrawBitmap(fBitmap,fBitmap->Bounds(),fBitmapRect);
280*22c6ae69SDarkWyrm 	else
281*22c6ae69SDarkWyrm 	{
282*22c6ae69SDarkWyrm 		SetHighColor(0,0,0,80);
283*22c6ae69SDarkWyrm 		SetDrawingMode(B_OP_ALPHA);
284*22c6ae69SDarkWyrm 		DrawString("Drop",fNoPhotoOffsets[0]);
285*22c6ae69SDarkWyrm 		DrawString("a",fNoPhotoOffsets[1]);
286*22c6ae69SDarkWyrm 		DrawString("Photo",fNoPhotoOffsets[2]);
287*22c6ae69SDarkWyrm 		DrawString("Here",fNoPhotoOffsets[3]);
288*22c6ae69SDarkWyrm 		SetDrawingMode(B_OP_COPY);
289*22c6ae69SDarkWyrm 	}
290*22c6ae69SDarkWyrm 
291*22c6ae69SDarkWyrm 	if(fBorderStyle==B_FANCY_BORDER)
292*22c6ae69SDarkWyrm 	{
293*22c6ae69SDarkWyrm 		rgb_color base= {216,216,216,255};
294*22c6ae69SDarkWyrm 		rgb_color work;
295*22c6ae69SDarkWyrm 
296*22c6ae69SDarkWyrm 		SetHighColor(base);
297*22c6ae69SDarkWyrm 		StrokeRect(Bounds().InsetByCopy(2,2));
298*22c6ae69SDarkWyrm 
299*22c6ae69SDarkWyrm 		BeginLineArray(12);
300*22c6ae69SDarkWyrm 
301*22c6ae69SDarkWyrm 		BRect r(Bounds());
302*22c6ae69SDarkWyrm 
303*22c6ae69SDarkWyrm 		work=tint_color(base,B_DARKEN_2_TINT);
304*22c6ae69SDarkWyrm 		AddLine(r.LeftTop(),r.RightTop(),work);
305*22c6ae69SDarkWyrm 		AddLine(r.LeftTop(),r.LeftBottom(),work);
306*22c6ae69SDarkWyrm 		r.left++;
307*22c6ae69SDarkWyrm 
308*22c6ae69SDarkWyrm 		work=tint_color(base,B_DARKEN_4_TINT);
309*22c6ae69SDarkWyrm 		AddLine(r.RightTop(),r.RightBottom(),work);
310*22c6ae69SDarkWyrm 		AddLine(r.LeftBottom(),r.RightBottom(),work);
311*22c6ae69SDarkWyrm 
312*22c6ae69SDarkWyrm 		r.right--;
313*22c6ae69SDarkWyrm 		r.top++;
314*22c6ae69SDarkWyrm 		r.bottom--;
315*22c6ae69SDarkWyrm 
316*22c6ae69SDarkWyrm 
317*22c6ae69SDarkWyrm 		work=tint_color(base,B_LIGHTEN_MAX_TINT);
318*22c6ae69SDarkWyrm 		AddLine(r.LeftTop(),r.RightTop(),work);
319*22c6ae69SDarkWyrm 		AddLine(r.LeftTop(),r.LeftBottom(),work);
320*22c6ae69SDarkWyrm 		r.left++;
321*22c6ae69SDarkWyrm 
322*22c6ae69SDarkWyrm 		work=tint_color(base,B_DARKEN_3_TINT);
323*22c6ae69SDarkWyrm 		AddLine(r.RightTop(),r.RightBottom(),work);
324*22c6ae69SDarkWyrm 		AddLine(r.LeftBottom(),r.RightBottom(),work);
325*22c6ae69SDarkWyrm 
326*22c6ae69SDarkWyrm 		// this rect handled by the above StrokeRect, so inset a total of 2 pixels
327*22c6ae69SDarkWyrm 		r.left++;
328*22c6ae69SDarkWyrm 		r.right-=2;
329*22c6ae69SDarkWyrm 		r.top+=2;
330*22c6ae69SDarkWyrm 		r.bottom-=2;
331*22c6ae69SDarkWyrm 
332*22c6ae69SDarkWyrm 
333*22c6ae69SDarkWyrm 		work=tint_color(base,B_DARKEN_3_TINT);
334*22c6ae69SDarkWyrm 		AddLine(r.LeftTop(),r.RightTop(),work);
335*22c6ae69SDarkWyrm 		AddLine(r.LeftTop(),r.LeftBottom(),work);
336*22c6ae69SDarkWyrm 		r.left++;
337*22c6ae69SDarkWyrm 
338*22c6ae69SDarkWyrm 		work=tint_color(base,B_LIGHTEN_MAX_TINT);
339*22c6ae69SDarkWyrm 		AddLine(r.RightTop(),r.RightBottom(),work);
340*22c6ae69SDarkWyrm 		AddLine(r.LeftBottom(),r.RightBottom(),work);
341*22c6ae69SDarkWyrm 
342*22c6ae69SDarkWyrm 		r.right--;
343*22c6ae69SDarkWyrm 		r.top++;
344*22c6ae69SDarkWyrm 		r.bottom--;
345*22c6ae69SDarkWyrm 		EndLineArray();
346*22c6ae69SDarkWyrm 
347*22c6ae69SDarkWyrm 		SetHighColor(tint_color(base,B_DARKEN_2_TINT));
348*22c6ae69SDarkWyrm 		StrokeRect(r);
349*22c6ae69SDarkWyrm 	}
350*22c6ae69SDarkWyrm 	else
351*22c6ae69SDarkWyrm 	{
352*22c6ae69SDarkWyrm 		// Plain border
353*22c6ae69SDarkWyrm 		SetHighColor(0,0,0);
354*22c6ae69SDarkWyrm 		StrokeRect(fBitmapRect);
355*22c6ae69SDarkWyrm 	}
356*22c6ae69SDarkWyrm }
357*22c6ae69SDarkWyrm 
358*22c6ae69SDarkWyrm void BitmapView::MouseDown(BPoint pt)
359*22c6ae69SDarkWyrm {
360*22c6ae69SDarkWyrm 	BPoint mousept;
361*22c6ae69SDarkWyrm 	uint32 buttons;
362*22c6ae69SDarkWyrm 
363*22c6ae69SDarkWyrm 	GetMouse(&mousept,&buttons);
364*22c6ae69SDarkWyrm 	if(buttons & B_SECONDARY_MOUSE_BUTTON)
365*22c6ae69SDarkWyrm 	{
366*22c6ae69SDarkWyrm 		ConvertToScreen(&mousept);
367*22c6ae69SDarkWyrm 
368*22c6ae69SDarkWyrm 		mousept.x= (mousept.x>5) ? mousept.x-5 : 0;
369*22c6ae69SDarkWyrm 		mousept.y= (mousept.y>5) ? mousept.y-5 : 0;
370*22c6ae69SDarkWyrm 
371*22c6ae69SDarkWyrm 		if(AcceptsPaste() && ClipboardHasBitmap())
372*22c6ae69SDarkWyrm 			fPasteItem->SetEnabled(true);
373*22c6ae69SDarkWyrm 		else
374*22c6ae69SDarkWyrm 			fPasteItem->SetEnabled(false);
375*22c6ae69SDarkWyrm 
376*22c6ae69SDarkWyrm 		if(fRemovableBitmap && fBitmap)
377*22c6ae69SDarkWyrm 			fRemoveItem->SetEnabled(true);
378*22c6ae69SDarkWyrm 		else
379*22c6ae69SDarkWyrm 			fRemoveItem->SetEnabled(false);
380*22c6ae69SDarkWyrm 
381*22c6ae69SDarkWyrm 		fPopUpMenu->Go(mousept,true,true,true);
382*22c6ae69SDarkWyrm 	}
383*22c6ae69SDarkWyrm }
384*22c6ae69SDarkWyrm 
385*22c6ae69SDarkWyrm void BitmapView::FrameResized(float w, float h)
386*22c6ae69SDarkWyrm {
387*22c6ae69SDarkWyrm 	CalculateBitmapRect();
388*22c6ae69SDarkWyrm }
389*22c6ae69SDarkWyrm 
390*22c6ae69SDarkWyrm void BitmapView::CalculateBitmapRect(void)
391*22c6ae69SDarkWyrm {
392*22c6ae69SDarkWyrm 	if(!fBitmap || fFixedSize)
393*22c6ae69SDarkWyrm 	{
394*22c6ae69SDarkWyrm 		fBitmapRect=Bounds().InsetByCopy(1,1);
395*22c6ae69SDarkWyrm 		return;
396*22c6ae69SDarkWyrm 	}
397*22c6ae69SDarkWyrm 
398*22c6ae69SDarkWyrm /*	// Dynamic sizing algorithm
399*22c6ae69SDarkWyrm 	// 1) Check to see if either dimension is bigger than the view's display area
400*22c6ae69SDarkWyrm 	// 2) If smaller along both axes, make bitmap rect centered and return
401*22c6ae69SDarkWyrm 	// 3) Check to see if scaling is to be horizontal or vertical on basis of longer axis
402*22c6ae69SDarkWyrm 	// 4) Calculate scaling factor
403*22c6ae69SDarkWyrm 	// 5) Scale both axes down by scaling factor, accounting for border width
404*22c6ae69SDarkWyrm 	// 6) Center the rectangle in the direction of the smaller axis
405*22c6ae69SDarkWyrm 
406*22c6ae69SDarkWyrm 
407*22c6ae69SDarkWyrm 	uint8 borderwidth=(fBorderStyle==B_FANCY_BORDER)?5:1;
408*22c6ae69SDarkWyrm 
409*22c6ae69SDarkWyrm 	BRect r(Bounds());
410*22c6ae69SDarkWyrm 	r.InsetBy(borderwidth,borderwidth);
411*22c6ae69SDarkWyrm 
412*22c6ae69SDarkWyrm 	if( (fBitmap->Bounds().Width()<=r.Width()) &&
413*22c6ae69SDarkWyrm 			(fBitmap->Bounds().Height()<=r.Height()) )
414*22c6ae69SDarkWyrm 	{
415*22c6ae69SDarkWyrm 		// Smaller than view, so just center and return
416*22c6ae69SDarkWyrm 		fBitmapRect=fBitmap->Bounds();
417*22c6ae69SDarkWyrm 		fBitmapRect.OffsetBy( borderwidth+
418*22c6ae69SDarkWyrm 				((r.Width()-fBitmapRect.Width()-(borderwidth<<2))/2),
419*22c6ae69SDarkWyrm 				((r.Height()-fBitmapRect.Height()-(borderwidth<<2))/2) );
420*22c6ae69SDarkWyrm 		return;
421*22c6ae69SDarkWyrm 	}
422*22c6ae69SDarkWyrm 
423*22c6ae69SDarkWyrm 	float multiplier=fBitmap->Bounds().Width()/fBitmap->Bounds().Height();
424*22c6ae69SDarkWyrm 	float offset;
425*22c6ae69SDarkWyrm 	if(multiplier>1)
426*22c6ae69SDarkWyrm 	{
427*22c6ae69SDarkWyrm 		// Landscape orientation
428*22c6ae69SDarkWyrm 
429*22c6ae69SDarkWyrm 		// Scale rectangle to bounds width and center height
430*22c6ae69SDarkWyrm 		r.bottom=r.top+(r.Width()/multiplier);
431*22c6ae69SDarkWyrm 
432*22c6ae69SDarkWyrm 		offset= ((Bounds().Height()-(borderwidth<<1)) - r.Height())/2;
433*22c6ae69SDarkWyrm 		r.OffsetBy(0,offset);
434*22c6ae69SDarkWyrm 	}
435*22c6ae69SDarkWyrm 	else
436*22c6ae69SDarkWyrm 	{
437*22c6ae69SDarkWyrm 		// Portrait orientation
438*22c6ae69SDarkWyrm 
439*22c6ae69SDarkWyrm 		// Scale rectangle to bounds height and center width
440*22c6ae69SDarkWyrm 		r.right=r.left+(r.Height()*multiplier);
441*22c6ae69SDarkWyrm 
442*22c6ae69SDarkWyrm 		offset= ((Bounds().Width()-(borderwidth<<1)) - r.Width())/2;
443*22c6ae69SDarkWyrm 		r.OffsetBy(offset,0);
444*22c6ae69SDarkWyrm 	}
445*22c6ae69SDarkWyrm 	fBitmapRect=r;
446*22c6ae69SDarkWyrm */
447*22c6ae69SDarkWyrm 
448*22c6ae69SDarkWyrm 	uint8 borderwidth=(fBorderStyle==B_FANCY_BORDER)?5:1;
449*22c6ae69SDarkWyrm 
450*22c6ae69SDarkWyrm 	BRect r(Bounds());
451*22c6ae69SDarkWyrm 	fBitmapRect= ScaleRectToFit(fBitmap->Bounds(),r.InsetByCopy(borderwidth,borderwidth));
452*22c6ae69SDarkWyrm }
453*22c6ae69SDarkWyrm 
454*22c6ae69SDarkWyrm void BitmapView::SetAcceptDrops(bool accept)
455*22c6ae69SDarkWyrm {
456*22c6ae69SDarkWyrm 	fAcceptDrops=accept;
457*22c6ae69SDarkWyrm }
458*22c6ae69SDarkWyrm 
459*22c6ae69SDarkWyrm void BitmapView::SetAcceptPaste(bool accept)
460*22c6ae69SDarkWyrm {
461*22c6ae69SDarkWyrm 	fAcceptPaste=accept;
462*22c6ae69SDarkWyrm }
463*22c6ae69SDarkWyrm 
464*22c6ae69SDarkWyrm void BitmapView::SetConstrainDrops(bool value)
465*22c6ae69SDarkWyrm {
466*22c6ae69SDarkWyrm 	fConstrainDrops=value;
467*22c6ae69SDarkWyrm }
468*22c6ae69SDarkWyrm 
469*22c6ae69SDarkWyrm void BitmapView::MaxBitmapSize(float *width, float *height) const
470*22c6ae69SDarkWyrm {
471*22c6ae69SDarkWyrm 	*width=fMaxWidth;
472*22c6ae69SDarkWyrm 	*height=fMaxHeight;
473*22c6ae69SDarkWyrm }
474*22c6ae69SDarkWyrm 
475*22c6ae69SDarkWyrm void BitmapView::SetMaxBitmapSize(const float &width, const float &height)
476*22c6ae69SDarkWyrm {
477*22c6ae69SDarkWyrm 	fMaxWidth=width;
478*22c6ae69SDarkWyrm 	fMaxHeight=height;
479*22c6ae69SDarkWyrm 
480*22c6ae69SDarkWyrm 	ConstrainBitmap();
481*22c6ae69SDarkWyrm }
482*22c6ae69SDarkWyrm 
483*22c6ae69SDarkWyrm void BitmapView::SetBitmapRemovable(bool isremovable)
484*22c6ae69SDarkWyrm {
485*22c6ae69SDarkWyrm 	fRemovableBitmap=isremovable;
486*22c6ae69SDarkWyrm }
487*22c6ae69SDarkWyrm 
488*22c6ae69SDarkWyrm void BitmapView::ConstrainBitmap(void)
489*22c6ae69SDarkWyrm {
490*22c6ae69SDarkWyrm 	if(!fBitmap || fMaxWidth < 1 || fMaxHeight < 1)
491*22c6ae69SDarkWyrm 		return;
492*22c6ae69SDarkWyrm 
493*22c6ae69SDarkWyrm 	BRect r=ScaleRectToFit(fBitmap->Bounds(),BRect(0,0,fMaxWidth-1,fMaxHeight-1));
494*22c6ae69SDarkWyrm 	r.OffsetTo(0,0);
495*22c6ae69SDarkWyrm 
496*22c6ae69SDarkWyrm 	BBitmap *scaled=new BBitmap(r,fBitmap->ColorSpace(),true);
497*22c6ae69SDarkWyrm 	BView *view=new BView(r,"drawview",0,0);
498*22c6ae69SDarkWyrm 
499*22c6ae69SDarkWyrm 	scaled->Lock();
500*22c6ae69SDarkWyrm 	scaled->AddChild(view);
501*22c6ae69SDarkWyrm 	view->DrawBitmap(fBitmap,fBitmap->Bounds(),scaled->Bounds());
502*22c6ae69SDarkWyrm 	scaled->Unlock();
503*22c6ae69SDarkWyrm 
504*22c6ae69SDarkWyrm 	delete fBitmap;
505*22c6ae69SDarkWyrm 	fBitmap=new BBitmap(scaled,false);
506*22c6ae69SDarkWyrm }
507*22c6ae69SDarkWyrm 
508*22c6ae69SDarkWyrm bool BitmapView::ClipboardHasBitmap(void)
509*22c6ae69SDarkWyrm {
510*22c6ae69SDarkWyrm 	BMessage *clip=NULL,flattened;
511*22c6ae69SDarkWyrm 	uint8 clipval=CLIP_NONE;
512*22c6ae69SDarkWyrm 	bool returnval;
513*22c6ae69SDarkWyrm 
514*22c6ae69SDarkWyrm 	if(be_clipboard->Lock())
515*22c6ae69SDarkWyrm 	{
516*22c6ae69SDarkWyrm 		clip=be_clipboard->Data();
517*22c6ae69SDarkWyrm 		if(!clip->IsEmpty())
518*22c6ae69SDarkWyrm 		{
519*22c6ae69SDarkWyrm 			returnval=(clip->FindMessage("image/bitmap",&flattened)==B_OK);
520*22c6ae69SDarkWyrm 			if(returnval)
521*22c6ae69SDarkWyrm 				clipval=CLIP_BEOS;
522*22c6ae69SDarkWyrm 			else
523*22c6ae69SDarkWyrm 			{
524*22c6ae69SDarkWyrm 				BString string;
525*22c6ae69SDarkWyrm 				returnval=(clip->FindString("class",&string)==B_OK && string=="BBitmap");
526*22c6ae69SDarkWyrm 
527*22c6ae69SDarkWyrm 				// Try method Gobe Productive uses if that, too, didn't work
528*22c6ae69SDarkWyrm 				if(returnval)
529*22c6ae69SDarkWyrm 					clipval=CLIP_SHOWIMAGE;
530*22c6ae69SDarkWyrm 				else
531*22c6ae69SDarkWyrm 				{
532*22c6ae69SDarkWyrm 					returnval=(clip->FindMessage("image/x-vnd.Be-bitmap",&flattened)==B_OK);
533*22c6ae69SDarkWyrm 					if(returnval)
534*22c6ae69SDarkWyrm 						clipval=CLIP_SHOWIMAGE;
535*22c6ae69SDarkWyrm 					else
536*22c6ae69SDarkWyrm 						clipval=CLIP_NONE;
537*22c6ae69SDarkWyrm 				}
538*22c6ae69SDarkWyrm 			}
539*22c6ae69SDarkWyrm 		}
540*22c6ae69SDarkWyrm 		be_clipboard->Unlock();
541*22c6ae69SDarkWyrm 	}
542*22c6ae69SDarkWyrm 	return (clipval!=CLIP_NONE)?true:false;
543*22c6ae69SDarkWyrm }
544*22c6ae69SDarkWyrm 
545*22c6ae69SDarkWyrm BBitmap *BitmapView::BitmapFromClipboard(void)
546*22c6ae69SDarkWyrm {
547*22c6ae69SDarkWyrm 	BMessage *clip=NULL,flattened;
548*22c6ae69SDarkWyrm 	BBitmap *bitmap;
549*22c6ae69SDarkWyrm 
550*22c6ae69SDarkWyrm 	if(!be_clipboard->Lock())
551*22c6ae69SDarkWyrm 		return NULL;
552*22c6ae69SDarkWyrm 
553*22c6ae69SDarkWyrm 	clip=be_clipboard->Data();
554*22c6ae69SDarkWyrm 	if(!clip)
555*22c6ae69SDarkWyrm 		return NULL;
556*22c6ae69SDarkWyrm 
557*22c6ae69SDarkWyrm 	uint8 clipval=CLIP_NONE;
558*22c6ae69SDarkWyrm 
559*22c6ae69SDarkWyrm 	// Try ArtPaint-style storage
560*22c6ae69SDarkWyrm 	status_t status=clip->FindMessage("image/bitmap",&flattened);
561*22c6ae69SDarkWyrm 
562*22c6ae69SDarkWyrm 	// If that didn't work, try ShowImage-style
563*22c6ae69SDarkWyrm 	if(status!=B_OK)
564*22c6ae69SDarkWyrm 	{
565*22c6ae69SDarkWyrm 		BString string;
566*22c6ae69SDarkWyrm 		status=clip->FindString("class",&string);
567*22c6ae69SDarkWyrm 
568*22c6ae69SDarkWyrm 		// Try method Gobe Productive uses if that, too, didn't work
569*22c6ae69SDarkWyrm 		if(status==B_OK && string=="BBitmap")
570*22c6ae69SDarkWyrm 			clipval=CLIP_SHOWIMAGE;
571*22c6ae69SDarkWyrm 		else
572*22c6ae69SDarkWyrm 		{
573*22c6ae69SDarkWyrm 			status=clip->FindMessage("image/x-vnd.Be-bitmap",&flattened);
574*22c6ae69SDarkWyrm 			if(status==B_OK)
575*22c6ae69SDarkWyrm 				clipval=CLIP_PRODUCTIVE;
576*22c6ae69SDarkWyrm 			else
577*22c6ae69SDarkWyrm 				clipval=CLIP_NONE;
578*22c6ae69SDarkWyrm 		}
579*22c6ae69SDarkWyrm 	}
580*22c6ae69SDarkWyrm 	else
581*22c6ae69SDarkWyrm 		clipval=CLIP_BEOS;
582*22c6ae69SDarkWyrm 
583*22c6ae69SDarkWyrm 	be_clipboard->Unlock();
584*22c6ae69SDarkWyrm 
585*22c6ae69SDarkWyrm 	switch(clipval)
586*22c6ae69SDarkWyrm 	{
587*22c6ae69SDarkWyrm 		case CLIP_SHOWIMAGE:
588*22c6ae69SDarkWyrm 		{
589*22c6ae69SDarkWyrm 			// Showimage does it a slightly different way -- it dumps the BBitmap
590*22c6ae69SDarkWyrm 			// data directly to the clipboard message instead of packaging it in
591*22c6ae69SDarkWyrm 			// a bitmap like everyone else.
592*22c6ae69SDarkWyrm 
593*22c6ae69SDarkWyrm 			if(!be_clipboard->Lock())
594*22c6ae69SDarkWyrm 				return NULL;
595*22c6ae69SDarkWyrm 
596*22c6ae69SDarkWyrm 			BMessage datamsg(*be_clipboard->Data());
597*22c6ae69SDarkWyrm 
598*22c6ae69SDarkWyrm 			be_clipboard->Unlock();
599*22c6ae69SDarkWyrm 
600*22c6ae69SDarkWyrm 			const void *buffer;
601*22c6ae69SDarkWyrm 			int32 bufferLength;
602*22c6ae69SDarkWyrm 
603*22c6ae69SDarkWyrm 			BRect frame;
604*22c6ae69SDarkWyrm 			color_space cspace=B_NO_COLOR_SPACE;
605*22c6ae69SDarkWyrm 
606*22c6ae69SDarkWyrm 			status=datamsg.FindRect("_frame",&frame);
607*22c6ae69SDarkWyrm 			if(status!=B_OK)
608*22c6ae69SDarkWyrm 				return NULL;
609*22c6ae69SDarkWyrm 
610*22c6ae69SDarkWyrm 			status=datamsg.FindInt32("_cspace",(int32)cspace);
611*22c6ae69SDarkWyrm 			if(status!=B_OK)
612*22c6ae69SDarkWyrm 				return NULL;
613*22c6ae69SDarkWyrm 			cspace=B_RGBA32;
614*22c6ae69SDarkWyrm 			bitmap=new BBitmap(frame,cspace,true);
615*22c6ae69SDarkWyrm 
616*22c6ae69SDarkWyrm 			status=datamsg.FindData("_data",B_RAW_TYPE,(const void **)&buffer, &bufferLength);
617*22c6ae69SDarkWyrm 			if(status!=B_OK)
618*22c6ae69SDarkWyrm 			{
619*22c6ae69SDarkWyrm 				delete bitmap;
620*22c6ae69SDarkWyrm 				return NULL;
621*22c6ae69SDarkWyrm 			}
622*22c6ae69SDarkWyrm 
623*22c6ae69SDarkWyrm 			memcpy(bitmap->Bits(), buffer, bufferLength);
624*22c6ae69SDarkWyrm 
625*22c6ae69SDarkWyrm 			return bitmap;
626*22c6ae69SDarkWyrm 		}
627*22c6ae69SDarkWyrm 		case CLIP_PRODUCTIVE:
628*22c6ae69SDarkWyrm 		// Productive doesn't name the packaged BBitmap data message the same, but
629*22c6ae69SDarkWyrm 		// uses exactly the same data format.
630*22c6ae69SDarkWyrm 
631*22c6ae69SDarkWyrm 		case CLIP_BEOS:
632*22c6ae69SDarkWyrm 		{
633*22c6ae69SDarkWyrm 			const void *buffer;
634*22c6ae69SDarkWyrm 			int32 bufferLength;
635*22c6ae69SDarkWyrm 
636*22c6ae69SDarkWyrm 			BRect frame;
637*22c6ae69SDarkWyrm 			color_space cspace=B_NO_COLOR_SPACE;
638*22c6ae69SDarkWyrm 
639*22c6ae69SDarkWyrm 			status=flattened.FindRect("_frame",&frame);
640*22c6ae69SDarkWyrm 			if(status!=B_OK)
641*22c6ae69SDarkWyrm 				return NULL;
642*22c6ae69SDarkWyrm 
643*22c6ae69SDarkWyrm 			status=flattened.FindInt32("_cspace",(int32)cspace);
644*22c6ae69SDarkWyrm 			if(status!=B_OK)
645*22c6ae69SDarkWyrm 				return NULL;
646*22c6ae69SDarkWyrm 			cspace=B_RGBA32;
647*22c6ae69SDarkWyrm 			bitmap=new BBitmap(frame,cspace,true);
648*22c6ae69SDarkWyrm 
649*22c6ae69SDarkWyrm 			status=flattened.FindData("_data",B_RAW_TYPE,(const void **)&buffer, &bufferLength);
650*22c6ae69SDarkWyrm 			if(status!=B_OK)
651*22c6ae69SDarkWyrm 			{
652*22c6ae69SDarkWyrm 				delete bitmap;
653*22c6ae69SDarkWyrm 				return NULL;
654*22c6ae69SDarkWyrm 			}
655*22c6ae69SDarkWyrm 
656*22c6ae69SDarkWyrm 			memcpy(bitmap->Bits(), buffer, bufferLength);
657*22c6ae69SDarkWyrm 
658*22c6ae69SDarkWyrm 			return bitmap;
659*22c6ae69SDarkWyrm 		}
660*22c6ae69SDarkWyrm 		default:
661*22c6ae69SDarkWyrm 			return NULL;
662*22c6ae69SDarkWyrm 	}
663*22c6ae69SDarkWyrm 
664*22c6ae69SDarkWyrm 	// shut the compiler up
665*22c6ae69SDarkWyrm 	return NULL;
666*22c6ae69SDarkWyrm }
667*22c6ae69SDarkWyrm 
668*22c6ae69SDarkWyrm BRect ScaleRectToFit(const BRect &from, const BRect &to)
669*22c6ae69SDarkWyrm {
670*22c6ae69SDarkWyrm 	// Dynamic sizing algorithm
671*22c6ae69SDarkWyrm 	// 1) Check to see if either dimension is bigger than the view's display area
672*22c6ae69SDarkWyrm 	// 2) If smaller along both axes, make bitmap rect centered and return
673*22c6ae69SDarkWyrm 	// 3) Check to see if scaling is to be horizontal or vertical on basis of longer axis
674*22c6ae69SDarkWyrm 	// 4) Calculate scaling factor
675*22c6ae69SDarkWyrm 	// 5) Scale both axes down by scaling factor, accounting for border width
676*22c6ae69SDarkWyrm 	// 6) Center the rectangle in the direction of the smaller axis
677*22c6ae69SDarkWyrm 
678*22c6ae69SDarkWyrm 	if(!to.IsValid())
679*22c6ae69SDarkWyrm 		return from;
680*22c6ae69SDarkWyrm 	if(!from.IsValid())
681*22c6ae69SDarkWyrm 		return to;
682*22c6ae69SDarkWyrm 
683*22c6ae69SDarkWyrm 	BRect r(to);
684*22c6ae69SDarkWyrm 
685*22c6ae69SDarkWyrm 	if( (from.Width()<=r.Width()) &&
686*22c6ae69SDarkWyrm 			(from.Height()<=r.Height()) )
687*22c6ae69SDarkWyrm 	{
688*22c6ae69SDarkWyrm 		// Smaller than view, so just center and return
689*22c6ae69SDarkWyrm 		r=from;
690*22c6ae69SDarkWyrm 		r.OffsetBy( (to.Width()-r.Width())/2, (to.Height()-r.Height())/2 );
691*22c6ae69SDarkWyrm 		return r;
692*22c6ae69SDarkWyrm 	}
693*22c6ae69SDarkWyrm 
694*22c6ae69SDarkWyrm 	float multiplier=from.Width()/from.Height();
695*22c6ae69SDarkWyrm 	if(multiplier>1)
696*22c6ae69SDarkWyrm 	{
697*22c6ae69SDarkWyrm 		// Landscape orientation
698*22c6ae69SDarkWyrm 
699*22c6ae69SDarkWyrm 		// Scale rectangle to bounds width and center height
700*22c6ae69SDarkWyrm 		r.bottom=r.top+(r.Width()/multiplier);
701*22c6ae69SDarkWyrm 
702*22c6ae69SDarkWyrm 		r.OffsetBy(0,(to.Height() - r.Height())/2);
703*22c6ae69SDarkWyrm 	}
704*22c6ae69SDarkWyrm 	else
705*22c6ae69SDarkWyrm 	{
706*22c6ae69SDarkWyrm 		// Portrait orientation
707*22c6ae69SDarkWyrm 
708*22c6ae69SDarkWyrm 		// Scale rectangle to bounds height and center width
709*22c6ae69SDarkWyrm 		r.right=r.left+(r.Height()*multiplier);
710*22c6ae69SDarkWyrm 
711*22c6ae69SDarkWyrm 		r.OffsetBy((to.Width() - r.Width())/2,0);
712*22c6ae69SDarkWyrm 	}
713*22c6ae69SDarkWyrm 	return r;
714*22c6ae69SDarkWyrm }
715*22c6ae69SDarkWyrm 
716*22c6ae69SDarkWyrm void BitmapView::RemoveBitmap(void)
717*22c6ae69SDarkWyrm {
718*22c6ae69SDarkWyrm 	SetBitmap(NULL);
719*22c6ae69SDarkWyrm }
720*22c6ae69SDarkWyrm 
721*22c6ae69SDarkWyrm void BitmapView::PasteBitmap(void)
722*22c6ae69SDarkWyrm {
723*22c6ae69SDarkWyrm 	BBitmap *bmp=BitmapFromClipboard();
724*22c6ae69SDarkWyrm 	if(bmp)
725*22c6ae69SDarkWyrm 		SetBitmap(bmp);
726*22c6ae69SDarkWyrm 
727*22c6ae69SDarkWyrm 	if(fConstrainDrops)
728*22c6ae69SDarkWyrm 		ConstrainBitmap();
729*22c6ae69SDarkWyrm }
730