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 "InternalEditors.h"
9#include "ResourceData.h"
10
11#include <Message.h>
12#include <Messenger.h>
13#include <ScrollView.h>
14#include <String.h>
15
16#include <stdlib.h>
17
18StringEditor::StringEditor(const BRect &frame, ResourceData *data,
19							BHandler *owner)
20  :	Editor(frame, data, owner)
21{
22	if (data->GetName())
23		SetTitle(data->GetName());
24
25	fView = new StringEditView(Bounds());
26	AddChild(fView);
27
28	if (data->IsAttribute())
29		fView->EnableID(false);
30	else
31		fView->SetID(data->GetIDString());
32	fView->SetName(data->GetName());
33	fView->SetValue(data->GetData());
34}
35
36
37void
38StringEditor::MessageReceived(BMessage *msg)
39{
40	if (msg->what == M_UPDATE_RESOURCE) {
41		// We have to have an ID, so if the squirrely developer didn't give us
42		// one, don't do anything
43		if (fView->GetID()) {
44			int32 newid = atol(fView->GetID());
45			GetData()->SetID(newid);
46		}
47		GetData()->SetName(fView->GetName());
48		GetData()->SetData(fView->GetValue(), strlen(fView->GetValue()));
49
50		BMessage updatemsg(M_UPDATE_RESOURCE);
51		updatemsg.AddPointer("item", GetData());
52		BMessenger msgr(GetOwner());
53		msgr.SendMessage(&updatemsg);
54		PostMessage(B_QUIT_REQUESTED);
55
56	} else {
57		Editor::MessageReceived(msg);
58	}
59}
60
61
62Editor::Editor(const BRect &frame, ResourceData *data, BHandler *owner)
63  :	BWindow(frame, "Untitled", B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS),
64  	fResData(data),
65  	fOwner(owner)
66{
67}
68
69
70Editor::~Editor(void)
71{
72}
73
74
75StringEditView::StringEditView(const BRect &frame)
76  :	BView(frame, "edit", B_FOLLOW_ALL, B_WILL_DRAW)
77{
78	SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
79
80	BRect r;
81
82	float labelwidth = be_plain_font->StringWidth("ID: ");
83	float strwidth = be_plain_font->StringWidth("(attr) ");
84
85	font_height fh;
86	be_plain_font->GetHeight(&fh);
87	float strheight = fh.ascent + fh.descent + fh.leading + 5;
88
89	fIDBox = new BTextControl(BRect(10, 10, 10 + (strwidth + labelwidth) + 15,
90									10 + strheight),
91							  "id", "ID: ", "", NULL);
92	fIDBox->SetDivider(labelwidth + 5);
93	AddChild(fIDBox);
94
95	r = fIDBox->Frame();
96	r.OffsetBy(r.Width() + 10, 0);
97	r.right = Bounds().right - 10;
98	fNameBox = new BTextControl(r, "name", "Name: ", "", NULL,
99								B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
100	fNameBox->SetDivider(be_plain_font->StringWidth("Name: ") + 5);
101	AddChild(fNameBox);
102
103	r.OffsetBy(0, r.Height() + 10);
104	r.left = 10;
105	r.right -= B_V_SCROLL_BAR_WIDTH;
106	BRect textRect(r.OffsetToCopy(0.0, 0.0));
107	textRect.InsetBy(5.0, 5.0);
108	fValueView = new BTextView(r, "value", textRect, B_FOLLOW_ALL);
109
110	BScrollView *scrollView = new BScrollView("scrollView", fValueView,
111												B_FOLLOW_ALL, 0, false, true);
112	AddChild(scrollView);
113
114	fOK = new BButton(BRect(10, 10, 11, 11), "ok", "Cancel", new BMessage(M_UPDATE_RESOURCE),
115					  B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
116	fOK->ResizeToPreferred();
117	fOK->SetLabel("OK");
118	AddChild(fOK);
119
120	fOK->MoveTo(r.right - fOK->Bounds().Width(), r.bottom + 10);
121	r = fOK->Frame();
122	r.OffsetBy(-r.Width() - 10, 0);
123	fCancel = new BButton(r, "cancel", "Cancel", new BMessage(B_QUIT_REQUESTED),
124					  B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
125	AddChild(fCancel);
126}
127
128
129StringEditView::~StringEditView(void)
130{
131}
132
133
134void
135StringEditView::AttachedToWindow(void)
136{
137	if (Bounds().Height() < fCancel->Frame().bottom + 10) {
138		BView *view = FindView("scrollView");
139		view->SetResizingMode(B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
140		fOK->SetResizingMode(B_FOLLOW_RIGHT);
141		fCancel->SetResizingMode(B_FOLLOW_RIGHT);
142		Window()->ResizeTo(Window()->Bounds().Width(), fCancel->Frame().bottom + 10);
143		view->SetResizingMode(B_FOLLOW_ALL);
144		fOK->SetResizingMode(B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
145		fCancel->SetResizingMode(B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
146	}
147
148	Window()->SetSizeLimits(Window()->Bounds().Width(), 30000,
149							Window()->Bounds().Height(), 30000);
150}
151
152
153float
154StringEditView::GetPreferredWidth(void) const
155{
156	float idwidth = be_plain_font->StringWidth("ID: ") +
157					be_plain_font->StringWidth("(attr) ") + 15.0;
158	float namewidth = be_plain_font->StringWidth("Name: ") +
159					be_plain_font->StringWidth(fNameBox->Text()) + 15.0;
160	return idwidth + namewidth + 100;
161}
162
163
164float
165StringEditView::GetPreferredHeight(void) const
166{
167	font_height fh;
168	be_plain_font->GetHeight(&fh);
169	float strheight = fh.ascent + fh.descent + fh.leading + 5;
170	float lineCount = fValueView->CountLines() < 5.0 ? fValueView->CountLines() : 5.0;
171	return fOK->Frame().Height() + (strheight * lineCount) + 40.0;
172}
173
174