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