xref: /haiku/src/apps/mediaconverter/MediaFileInfoView.cpp (revision 89d652d5e0defd9d095c778709cef82f5f10c357)
1 // Copyright 1999, Be Incorporated. All Rights Reserved.
2 // Copyright 2000-2004, Jun Suzuki. All Rights Reserved.
3 // Copyright 2007, Stephan Aßmus. All Rights Reserved.
4 // This file may be used under the terms of the Be Sample Code License.
5 #include "MediaFileInfoView.h"
6 
7 #include <Alert.h>
8 #include <ControlLook.h>
9 #include <MediaFile.h>
10 #include <MediaTrack.h>
11 #include <String.h>
12 
13 #include "Strings.h"
14 
15 
16 const float kSpacing = 5.0f;
17 
18 
19 MediaFileInfoView::MediaFileInfoView()
20 	:
21 	BView("MediaFileInfoView", B_WILL_DRAW | B_SUPPORTS_LAYOUT),
22 	fMinMaxValid(false),
23 	fRef(),
24 	fMediaFile(NULL)
25 {
26 	SetFont(be_plain_font);
27 }
28 
29 
30 MediaFileInfoView::~MediaFileInfoView()
31 {
32 }
33 
34 
35 void
36 MediaFileInfoView::Draw(BRect /*update*/)
37 {
38 	_ValidateMinMax();
39 
40 	_SetFontFace(B_BOLD_FACE);
41 
42 	font_height fh;
43 	GetFontHeight(&fh);
44 	BPoint labelStart(kSpacing, fh.ascent + fh.leading + 1);
45 
46 	if (fMediaFile == NULL) {
47 		DrawString(NO_FILE_LABEL, labelStart);
48 		return;
49 	}
50 
51 	// draw filename
52 	DrawString(fRef.name, labelStart);
53 	labelStart.y += fLineHeight + kSpacing;
54 	BPoint infoStart(labelStart.x + fMaxLabelWidth + kSpacing, labelStart.y);
55 
56 	// draw labels
57 	DrawString(AUDIO_INFO_LABEL, labelStart);
58 	labelStart.y += fLineHeight * 2;
59 
60 	DrawString(VIDEO_INFO_LABEL, labelStart);
61 	labelStart.y += fLineHeight * 2;
62 
63 	DrawString(DURATION_LABEL, labelStart);
64 	labelStart.y += fLineHeight * 2;
65 
66 	// draw audio/video/duration info
67 	_SetFontFace(B_REGULAR_FACE);
68 
69 	BString* infoStrings[5] = {&fInfo.audio.format, &fInfo.audio.details,
70 		&fInfo.video.format, &fInfo.video.details, &fInfo.duration};
71 	for (int32 i = 0; i < 5; i++) {
72 		DrawString(*infoStrings[i], infoStart);
73 		infoStart.y += fLineHeight;
74 	}
75 }
76 
77 
78 BSize
79 MediaFileInfoView::MinSize()
80 {
81 	_ValidateMinMax();
82 	return fMinSize;
83 }
84 
85 
86 BSize
87 MediaFileInfoView::MaxSize()
88 {
89 	return fMinSize;
90 }
91 
92 
93 BSize
94 MediaFileInfoView::PreferredSize()
95 {
96 	_ValidateMinMax();
97 	return fMinSize;
98 }
99 
100 
101 BAlignment
102 MediaFileInfoView::LayoutAlignment()
103 {
104 	return BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP);
105 }
106 
107 
108 void
109 MediaFileInfoView::InvalidateLayout(bool /*children*/)
110 {
111 	fMinMaxValid = false;
112 	BView::InvalidateLayout();
113 }
114 
115 
116 void
117 MediaFileInfoView::SetFont(const BFont* font, uint32 mask)
118 {
119 	BView::SetFont(font, mask);
120 	if (mask == B_FONT_FACE)
121 		return;
122 
123 	fLineHeight = _LineHeight();
124 	BFont bold(font);
125 	bold.SetFace(B_BOLD_FACE);
126 	fMaxLabelWidth = 0;
127 
128 	BString labels[] = {VIDEO_INFO_LABEL, DURATION_LABEL, AUDIO_INFO_LABEL};
129 	int32 labelCount = sizeof(labels) / sizeof(BString);
130 	fMaxLabelWidth = _MaxLineWidth(labels, labelCount, bold);
131 
132 	fNoFileLabelWidth = ceilf(bold.StringWidth(NO_FILE_LABEL));
133 	InvalidateLayout();
134 }
135 
136 
137 void
138 MediaFileInfoView::AttachedToWindow()
139 {
140 	rgb_color c = Parent()->LowColor();
141 	SetViewColor(c);
142 	SetLowColor(c);
143 }
144 
145 
146 void
147 MediaFileInfoView::Update(BMediaFile* file, entry_ref* ref)
148 {
149 	if (fMediaFile == file)
150 		return;
151 
152 	fMediaFile = file;
153 
154 	if (file != NULL && ref != NULL)
155 		fRef = *ref;
156 	else
157 		fRef = entry_ref();
158 
159 	status_t ret = fInfo.LoadInfo(file);
160 	if (ret != B_OK) {
161 		BString error("An error has occurred reading the "
162 			"file info.\n\nError : ");
163 		error << strerror(ret);
164 		BAlert* alert = new BAlert("File Error", error.String(),
165 			"OK");
166 		alert->Go(NULL);
167 	}
168 
169 	InvalidateLayout();
170 	Invalidate();
171 }
172 
173 
174 float
175 MediaFileInfoView::_LineHeight()
176 {
177 	font_height fontHeight;
178 	GetFontHeight(&fontHeight);
179 	return ceilf(fontHeight.ascent + fontHeight.descent + fontHeight.leading);
180 }
181 
182 
183 float
184 MediaFileInfoView::_MaxLineWidth(BString* strings, int32 count,
185 	const BFont& font)
186 {
187 	float width = 0;
188 	for (int32 i = 0; i < count; i++)
189 		width = max_c(font.StringWidth(strings[i]), width);
190 
191 	return ceilf(width);
192 }
193 
194 
195 void
196 MediaFileInfoView::_ValidateMinMax()
197 {
198 	if (fMinMaxValid)
199 		return;
200 
201 	BFont font;
202 	GetFont(&font);
203 
204 	BFont bold(font);
205 	bold.SetFace(B_BOLD_FACE);
206 	fMinSize.Set(0, 0);
207 
208 	if (fMediaFile == NULL) {
209 		fMinSize.width =  fNoFileLabelWidth + kSpacing * 2;
210 		fMinSize.height = fLineHeight + kSpacing;
211 		return;
212 	}
213 
214 	fMinSize.height += fLineHeight + kSpacing + 1;
215 	fMinSize.width = ceilf(bold.StringWidth(fRef.name));
216 
217 	BString strings[5] = {fInfo.audio.format, fInfo.audio.details,
218 		fInfo.video.format, fInfo.video.details, fInfo.duration};
219 	float maxInfoWidth = _MaxLineWidth(strings, 5, font);
220 
221 	fMinSize.width = max_c(fMinSize.width, fMaxLabelWidth
222 		+ maxInfoWidth + kSpacing);
223 	fMinSize.width += kSpacing;
224 
225 	fMinSize.height += fLineHeight * 5 + 2 * kSpacing;
226 		// 5 lines of info, w/ spacing above and below (not between lines)
227 
228 	ResetLayoutInvalidation();
229 	fMinMaxValid = true;
230 }
231 
232 
233 void
234 MediaFileInfoView::_SetFontFace(uint16 face)
235 {
236 	BFont font;
237 	font.SetFace(face);
238 	SetFont(&font, B_FONT_FACE);
239 }
240 
241