1/*
2 * Copyright (c) 2005-2010, Haiku, Inc.
3 * Distributed under the terms of the MIT license.
4 *
5 * Author:
6 *		DarkWyrm <darkwyrm@gmail.com>
7 */
8#include "BitmapView.h"
9#include "InternalEditors.h"
10#include "ResourceData.h"
11
12#include <DataIO.h>
13#include <TranslationUtils.h>
14
15#define M_IMAGE_CHANGED 'imch'
16
17ImageEditor::ImageEditor(const BRect &frame, ResourceData *data, BHandler *owner)
18  :	Editor(frame, data, owner)
19{
20	SetFlags(Flags()  | B_NOT_RESIZABLE | B_NOT_ZOOMABLE);
21	SetTitle(data->GetName());
22
23	// Set up the image and the viewer for such
24	BMemoryIO memio(data->GetData(), data->GetLength());
25	fImage = BTranslationUtils::GetBitmap(&memio);
26
27	BRect imgsize;
28	if (fImage)
29		imgsize = ScaleRectToFit(fImage->Bounds(), BRect(0, 0, 200, 200));
30	else
31		imgsize.Set(0, 0, 200, 200);
32
33	BView *back = new BView(Bounds(), "back", B_FOLLOW_ALL, B_WILL_DRAW);
34	back->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
35	AddChild(back);
36
37	BRect r;
38
39	float labelwidth = be_plain_font->StringWidth("ID: ");
40	float strwidth = be_plain_font->StringWidth("(attr) ");
41
42	font_height fh;
43	be_plain_font->GetHeight(&fh);
44	float strheight = fh.ascent + fh.descent + fh.leading + 5;
45
46	fIDBox = new BTextControl(BRect(10, 10, 10 + (strwidth + labelwidth) + 15,
47									10 + strheight),
48							  "id", "ID: ", data->GetIDString(), NULL);
49	fIDBox->SetDivider(labelwidth + 5);
50	back->AddChild(fIDBox);
51
52	r = fIDBox->Frame();
53	r.OffsetBy(r.Width() + 10, 0);
54	r.right = Bounds().right - 10;
55	fNameBox = new BTextControl(r, "name", "Name: ", data->GetName(), NULL,
56								B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
57	fNameBox->SetDivider(be_plain_font->StringWidth("Name: ") + 5);
58	back->AddChild(fNameBox);
59
60	r = imgsize;
61
62	r.OffsetTo( (Bounds().Width() - r.Width()) / 2, fNameBox->Frame().bottom + 10);
63	fImageView = new BitmapView(r, "imageview", new BMessage(M_IMAGE_CHANGED), fImage,
64								NULL, B_PLAIN_BORDER, B_FOLLOW_NONE,
65								B_WILL_DRAW | B_FRAME_EVENTS);
66	back->AddChild(fImageView);
67	fImageView->SetConstrainDrops(false);
68
69	// No limit on bitmap size
70	fImageView->SetMaxBitmapSize(0, 0);
71	fImageView->SetBitmapRemovable(false);
72
73	fOK = new BButton(BRect(10, 10, 11, 11), "ok", "Cancel", new BMessage(M_UPDATE_RESOURCE),
74					  B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
75	fOK->ResizeToPreferred();
76	fOK->SetLabel("OK");
77	fOK->MakeDefault(true);
78	back->AddChild(fOK);
79
80	fOK->MoveTo(Bounds().right - fOK->Bounds().Width() - 10,
81				Bounds().bottom - fOK->Bounds().Height() - 10);
82	r = fOK->Frame();
83
84	r.OffsetBy(-r.Width() - 10, 0);
85	fCancel = new BButton(r, "cancel", "Cancel", new BMessage(B_QUIT_REQUESTED),
86					  B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
87	back->AddChild(fCancel);
88
89	ResizeTo(MAX(fImageView->Frame().right, fNameBox->Frame().right) + 20,
90			fImageView->Frame().bottom + fOK->Frame().Height() + 20);
91
92	SetSizeLimits(Bounds().right, 30000, Bounds().bottom, 30000);
93}
94
95
96ImageEditor::~ImageEditor(void)
97{
98	delete fImage;
99}
100
101
102void
103ImageEditor::MessageReceived(BMessage *msg)
104{
105	if (msg->WasDropped()) {
106		fImageView->MessageReceived(msg);
107	} else if (msg->what == M_IMAGE_CHANGED) {
108		fImage = fImageView->GetBitmap();
109		BRect r = ScaleRectToFit(fImage->Bounds(), BRect(0, 0, 200, 200));
110		fImageView->ResizeTo(r.Width(), r.Height());
111		ResizeTo(MAX(fImageView->Frame().right, fNameBox->Frame().right) + 20,
112				fImageView->Frame().bottom + fOK->Frame().Height() + 20);
113	} else
114		BWindow::MessageReceived(msg);
115}
116
117
118void
119ImageEditor::FrameResized(float w, float h)
120{
121	fImageView->MoveTo( (w - fImageView->Bounds().Width()) / 2,
122						fNameBox->Frame().bottom + 10);
123}
124