MediaPlayer: reworked info window to use layout API.

* Use BStringViews instead of BTextView - it's more flexible (truncation,
  and tool tips), and allows for fine grained updates.
* The file name and location views are now showing tool tips with their
  full contents.
* Also, its look is now less exotic, if boring.
This commit is contained in:
Axel Dörfler
2015-01-23 21:00:29 +01:00
parent 95fdee0bc0
commit 88fed28aff
2 changed files with 403 additions and 268 deletions
+369 -262
View File
@@ -2,6 +2,7 @@
* InfoWin.cpp - Media Player for the Haiku Operating System * InfoWin.cpp - Media Player for the Haiku Operating System
* *
* Copyright (C) 2006 Marcus Overhagen <[email protected]> * Copyright (C) 2006 Marcus Overhagen <[email protected]>
* Copyright 2015 Axel Dörfler <[email protected]>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@@ -27,7 +28,9 @@
#include <Bitmap.h> #include <Bitmap.h>
#include <Catalog.h> #include <Catalog.h>
#include <ControlLook.h>
#include <Debug.h> #include <Debug.h>
#include <LayoutBuilder.h>
#include <MediaDefs.h> #include <MediaDefs.h>
#include <MessageFormat.h> #include <MessageFormat.h>
#include <Mime.h> #include <Mime.h>
@@ -43,86 +46,57 @@
#include "PlaylistItem.h" #include "PlaylistItem.h"
#define NAME "File info" #define MIN_WIDTH 500
#define MIN_WIDTH 400
#define BASE_HEIGHT (32 + 32)
//const rgb_color kGreen = { 152, 203, 152, 255 };
const rgb_color kRed = { 203, 152, 152, 255 };
const rgb_color kBlue = { 0, 0, 220, 255 };
const rgb_color kGreen = { 171, 221, 161, 255 };
const rgb_color kBlack = { 0, 0, 0, 255 };
#undef B_TRANSLATION_CONTEXT #undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "MediaPlayer-InfoWin" #define B_TRANSLATION_CONTEXT "MediaPlayer-InfoWin"
// should later draw an icon
class InfoView : public BView {
public:
InfoView(BRect frame, const char* name, float divider);
virtual ~InfoView();
virtual void Draw(BRect updateRect);
status_t SetIcon(const PlaylistItem* item); class IconView : public BView {
status_t SetIcon(const char* mimeType); public:
void SetGenericIcon(); IconView(const char* name, int32 iconSize);
virtual ~IconView();
status_t SetIcon(const PlaylistItem* item);
status_t SetIcon(const char* mimeType);
void SetGenericIcon();
virtual void GetPreferredSize(float* _width, float* _height);
virtual void AttachedToWindow();
virtual void Draw(BRect updateRect);
private: private:
float fDivider; BBitmap* fIconBitmap;
BBitmap* fIconBitmap;
}; };
InfoView::InfoView(BRect frame, const char *name, float divider) IconView::IconView(const char* name, int32 iconSize)
: BView(frame, name, B_FOLLOW_ALL, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE), :
fDivider(divider), BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
fIconBitmap(NULL) fIconBitmap(NULL)
{ {
BRect rect(0, 0, B_LARGE_ICON - 1, B_LARGE_ICON - 1); fIconBitmap = new BBitmap(BRect(0, 0, iconSize - 1, iconSize - 1),
B_RGBA32);
#ifdef HAIKU_TARGET_PLATFORM_HAIKU SetExplicitMaxSize(PreferredSize());
fIconBitmap = new BBitmap(rect, B_RGBA32);
#else
fIconBitmap = new BBitmap(rect, B_CMAP8);
#endif
} }
InfoView::~InfoView() IconView::~IconView()
{ {
delete fIconBitmap; delete fIconBitmap;
} }
void
InfoView::Draw(BRect updateRect)
{
SetHighColor(kGreen);
BRect r(Bounds());
r.right = r.left + fDivider;
FillRect(r);
if (fIconBitmap) {
float left = r.left + ( r.right - r.left ) / 2 - B_LARGE_ICON / 2;
SetDrawingMode(B_OP_ALPHA);
DrawBitmap(fIconBitmap, BPoint(left, r.top + B_LARGE_ICON / 2));
}
SetHighColor(ui_color(B_DOCUMENT_TEXT_COLOR));
r.left = r.right;
FillRect(r);
}
status_t status_t
InfoView::SetIcon(const PlaylistItem* item) IconView::SetIcon(const PlaylistItem* item)
{ {
return item->GetIcon(fIconBitmap, B_LARGE_ICON); return item->GetIcon(fIconBitmap, B_LARGE_ICON);
} }
status_t status_t
InfoView::SetIcon(const char* mimeTypeString) IconView::SetIcon(const char* mimeTypeString)
{ {
if (!mimeTypeString) if (!mimeTypeString)
return B_BAD_VALUE; return B_BAD_VALUE;
@@ -144,7 +118,7 @@ InfoView::SetIcon(const char* mimeTypeString)
void void
InfoView::SetGenericIcon() IconView::SetGenericIcon()
{ {
// get default icon // get default icon
BMimeType genericType(B_FILE_MIME_TYPE); BMimeType genericType(B_FILE_MIME_TYPE);
@@ -159,67 +133,133 @@ InfoView::SetGenericIcon()
} }
void
IconView::GetPreferredSize(float* _width, float* _height)
{
if (_width != NULL) {
*_width = fIconBitmap->Bounds().Width()
+ 2 * be_control_look->DefaultItemSpacing();
}
if (_height != NULL) {
*_height = fIconBitmap->Bounds().Height()
+ 2 * be_control_look->DefaultItemSpacing();
}
}
void
IconView::AttachedToWindow()
{
if (Parent() != NULL)
SetViewColor(Parent()->ViewColor());
else
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
}
void
IconView::Draw(BRect updateRect)
{
BRect rect(Bounds());
if (fIconBitmap != NULL) {
// Draw bitmap centered within the view
SetDrawingMode(B_OP_ALPHA);
DrawBitmap(fIconBitmap, BPoint(rect.left
+ (rect.Width() - fIconBitmap->Bounds().Width()) / 2,
rect.top + (rect.Height() - fIconBitmap->Bounds().Height()) / 2));
}
}
// #pragma mark - // #pragma mark -
InfoWin::InfoWin(BPoint leftTop, Controller* controller) InfoWin::InfoWin(BPoint leftTop, Controller* controller)
: :
BWindow(BRect(leftTop.x, leftTop.y, leftTop.x + MIN_WIDTH - 1, BWindow(BRect(leftTop.x, leftTop.y, leftTop.x + MIN_WIDTH - 1,
leftTop.y + 300), B_TRANSLATE(NAME), B_TITLED_WINDOW, leftTop.y + 300), B_TRANSLATE("File info"), B_TITLED_WINDOW,
B_ASYNCHRONOUS_CONTROLS | B_NOT_RESIZABLE | B_NOT_ZOOMABLE), B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS | B_NOT_ZOOMABLE),
fController(controller), fController(controller),
fControllerObserver(new ControllerObserver(this, fControllerObserver(new ControllerObserver(this,
OBSERVE_FILE_CHANGES | OBSERVE_TRACK_CHANGES | OBSERVE_STAT_CHANGES)) OBSERVE_FILE_CHANGES | OBSERVE_TRACK_CHANGES | OBSERVE_STAT_CHANGES))
{ {
BRect rect = Bounds(); fIconView = new IconView("background", B_LARGE_ICON);
// accomodate for big fonts
float div = max_c(2 * 32, be_plain_font->StringWidth(
B_TRANSLATE("Display Mode")) + 10);
fInfoView = new InfoView(rect, "background", div);
fInfoView->SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR));
AddChild(fInfoView);
fFilenameView = _CreateInfo("filename");
BFont bigFont(be_plain_font); BFont bigFont(be_plain_font);
bigFont.SetSize(bigFont.Size() + 6); bigFont.SetSize(bigFont.Size() * 1.5f);
font_height fh;
bigFont.GetHeight(&fh);
fFilenameView = new BStringView(
BRect(div + 10, 20, rect.right - 10, 20 + fh.ascent + 5),
"filename", "");
AddChild(fFilenameView);
fFilenameView->SetFont(&bigFont); fFilenameView->SetFont(&bigFont);
fFilenameView->SetViewColor(fInfoView->ViewColor());
fFilenameView->SetLowColor(fInfoView->ViewColor());
#ifdef B_BEOS_VERSION_DANO /* maybe we should support that as well ? */
fFilenameView->SetTruncation(B_TRUNCATE_END);
#endif
rect.top = BASE_HEIGHT; // Create info views
BRect lr(rect); BStringView* containerLabel = _CreateLabel("containerLabel",
BRect cr(rect); B_TRANSLATE("Container"));
lr.right = div - 1; fContainerInfo = _CreateInfo("container");
cr.left = div + 1;
BRect tr;
tr = lr.OffsetToCopy(0, 0).InsetByCopy(5, 1);
fLabelsView = new BTextView(lr, "labels", tr, B_FOLLOW_BOTTOM);
fLabelsView->SetViewColor(kGreen);
fLabelsView->SetAlignment(B_ALIGN_RIGHT);
fLabelsView->SetWordWrap(false);
AddChild(fLabelsView);
tr = cr.OffsetToCopy(0, 0).InsetByCopy(10, 1);
fContentsView = new BTextView(cr, "contents", tr, B_FOLLOW_BOTTOM);
fContentsView->SetWordWrap(false);
AddChild(fContentsView);
fLabelsView->MakeSelectable(); fVideoSeparator = _CreateSeparator();
fContentsView->MakeSelectable(); fVideoLabel = _CreateLabel("videoLabel", B_TRANSLATE("Video"));
fVideoFormatInfo = _CreateInfo("videoFormat");
fVideoConfigInfo = _CreateInfo("videoConfig");
fDisplayModeLabel = _CreateLabel("displayModeLabel",
B_TRANSLATE("Display mode"));
fDisplayModeInfo = _CreateInfo("displayMode");
fAudioSeparator = _CreateSeparator();
fAudioLabel = _CreateLabel("audioLabel", B_TRANSLATE("Audio"));
fAudioFormatInfo = _CreateInfo("audioFormat");
fAudioConfigInfo = _CreateInfo("audioConfig");
BStringView* durationLabel = _CreateLabel("durationLabel",
B_TRANSLATE("Duration"));
fDurationInfo = _CreateInfo("duration");
BStringView* locationLabel = _CreateLabel("locationLabel",
B_TRANSLATE("Location"));
fLocationInfo = _CreateInfo("location");
fCopyrightSeparator = _CreateSeparator();
fCopyrightLabel = _CreateLabel("copyrightLabel", B_TRANSLATE("Copyright"));
fCopyrightInfo = _CreateInfo("copyright");
BLayoutBuilder::Group<>(this, B_VERTICAL)
.SetInsets(B_USE_DEFAULT_SPACING)
.AddGroup(B_HORIZONTAL)
.Add(fIconView, 0)
.Add(fFilenameView, 1)
.End()
.AddGrid(2, 13)
.Add(containerLabel, 0, 0)
.Add(fContainerInfo, 1, 0)
.Add(fVideoSeparator, 0, 1)
.Add(fVideoLabel, 0, 2)
.Add(fVideoFormatInfo, 1, 2)
.Add(fVideoConfigInfo, 1, 3)
.Add(fDisplayModeLabel, 0, 4)
.Add(fDisplayModeInfo, 1, 4)
.Add(fAudioSeparator, 0, 5)
.Add(fAudioLabel, 0, 6)
.Add(fAudioFormatInfo, 1, 6)
.Add(fAudioConfigInfo, 1, 7)
.Add(_CreateSeparator(), 0, 8)
.Add(durationLabel, 0, 9)
.Add(fDurationInfo, 1, 9)
.Add(_CreateSeparator(), 0, 10)
.Add(locationLabel, 0, 11)
.Add(fLocationInfo, 1, 11)
.Add(fCopyrightSeparator, 0, 12)
.Add(fCopyrightLabel, 0, 12)
.Add(fCopyrightInfo, 1, 12)
.SetColumnWeight(0, 0)
.SetColumnWeight(1, 1)
.SetSpacing(B_USE_DEFAULT_SPACING, 0)
.SetExplicitMinSize(BSize(MIN_WIDTH, B_SIZE_UNSET));
fController->AddListener(fControllerObserver); fController->AddListener(fControllerObserver);
Update(); Update();
UpdateSizeLimits();
// Move window on screen if needed // Move window on screen if needed
BScreen screen(this); BScreen screen(this);
if (screen.Frame().bottom < Frame().bottom) if (screen.Frame().bottom < Frame().bottom)
@@ -238,15 +278,6 @@ InfoWin::~InfoWin()
} }
// #pragma mark -
void
InfoWin::FrameResized(float newWidth, float newHeight)
{
}
void void
InfoWin::MessageReceived(BMessage* msg) InfoWin::MessageReceived(BMessage* msg)
{ {
@@ -257,14 +288,14 @@ InfoWin::MessageReceived(BMessage* msg)
Update(INFO_ALL); Update(INFO_ALL);
break; break;
case MSG_CONTROLLER_VIDEO_TRACK_CHANGED: case MSG_CONTROLLER_VIDEO_TRACK_CHANGED:
Update(/*INFO_VIDEO | INFO_STATS*/INFO_ALL); Update(INFO_VIDEO | INFO_STATS);
break; break;
case MSG_CONTROLLER_AUDIO_TRACK_CHANGED: case MSG_CONTROLLER_AUDIO_TRACK_CHANGED:
Update(/*INFO_AUDIO | INFO_STATS*/INFO_ALL); Update(INFO_AUDIO | INFO_STATS);
break; break;
case MSG_CONTROLLER_VIDEO_STATS_CHANGED: case MSG_CONTROLLER_VIDEO_STATS_CHANGED:
case MSG_CONTROLLER_AUDIO_STATS_CHANGED: case MSG_CONTROLLER_AUDIO_STATS_CHANGED:
Update(/*INFO_STATS*/INFO_ALL); Update(INFO_STATS);
break; break;
default: default:
BWindow::MessageReceived(msg); BWindow::MessageReceived(msg);
@@ -294,226 +325,302 @@ InfoWin::Pulse()
void void
InfoWin::ResizeToPreferred() InfoWin::Update(uint32 which)
{ {
if (!fController->Lock())
return;
if ((which & INFO_FILE) != 0)
_UpdateFile();
// video track format information
if ((which & INFO_VIDEO) != 0)
_UpdateVideo();
// audio track format information
if ((which & INFO_AUDIO) != 0)
_UpdateAudio();
// statistics
if ((which & INFO_STATS) != 0) {
_UpdateDuration();
// TODO: demux/video/audio/... perfs (Kb/info)
}
if ((which & INFO_TRANSPORT) != 0) {
// Transport protocol info (file, http, rtsp, ...)
}
if ((which & INFO_COPYRIGHT)!=0)
_UpdateCopyright();
fController->Unlock();
} }
void void
InfoWin::Update(uint32 which) InfoWin::_UpdateFile()
{ {
printf("InfoWin::Update(0x%08" B_PRIx32 ")\n", which); bool iconSet = false;
fLabelsView->SetText(""); if (fController->HasFile()) {
fContentsView->SetText(""); const PlaylistItem* item = fController->Item();
fLabelsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kBlue); iconSet = fIconView->SetIcon(item) == B_OK;
fLabelsView->Insert(" "); media_file_format fileFormat;
fContentsView->SetFontAndColor(be_plain_font, B_FONT_ALL); status_t status = fController->GetFileFormatInfo(&fileFormat);
// fContentsView->Insert(""); if (status == B_OK) {
fContainerInfo->SetText(fileFormat.pretty_name);
if (!iconSet)
iconSet = fIconView->SetIcon(fileFormat.mime_type) == B_OK;
} else
fContainerInfo->SetText(strerror(status));
if (!fController->Lock()) BString info;
return; if (fController->GetLocation(&info) != B_OK)
info = B_TRANSLATE("<unknown>");
fLocationInfo->SetText(info.String());
fLocationInfo->SetToolTip(info.String());
fLabelsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kRed); if (fController->GetName(&info) != B_OK || info.IsEmpty())
info = B_TRANSLATE("<unnamed media>");
fFilenameView->SetText(info.String());
fFilenameView->SetToolTip(info.String());
} else {
fFilenameView->SetText(B_TRANSLATE("<no media>"));
fContainerInfo->SetText("-");
fLocationInfo->SetText("-");
}
status_t err; if (!iconSet)
// video track format information fIconView->SetGenericIcon();
if ((which & INFO_VIDEO) && fController->VideoTrackCount() > 0) { }
BString label = B_TRANSLATE("Video");
fLabelsView->Insert(label << "\n\n\n");
BString s; void
InfoWin::_UpdateVideo()
{
bool visible = fController->VideoTrackCount() > 0;
if (visible) {
BString info;
media_format format; media_format format;
media_raw_video_format videoFormat = {}; media_raw_video_format videoFormat = {};
err = fController->GetEncodedVideoFormat(&format); status_t status = fController->GetEncodedVideoFormat(&format);
if (err < B_OK) { if (status != B_OK) {
s << "(" << strerror(err) << ")\n"; info << "(" << strerror(status) << ")\n";
} else if (format.type == B_MEDIA_ENCODED_VIDEO) { } else if (format.type == B_MEDIA_ENCODED_VIDEO) {
videoFormat = format.u.encoded_video.output; videoFormat = format.u.encoded_video.output;
media_codec_info mci; media_codec_info mci;
err = fController->GetVideoCodecInfo(&mci); status = fController->GetVideoCodecInfo(&mci);
if (err < B_OK) { if (status != B_OK) {
s << B_TRANSLATE("Haiku Media Kit: ") << strerror(err);
if (format.user_data_type == B_CODEC_TYPE_INFO) { if (format.user_data_type == B_CODEC_TYPE_INFO) {
s << (char *)format.user_data << " " info << (char *)format.user_data << " "
<< B_TRANSLATE("(not supported)"); << B_TRANSLATE("(not supported)");
} } else
info = strerror(status);
} else } else
s << mci.pretty_name; //<< "(" << mci.short_name << ")"; info << mci.pretty_name; //<< "(" << mci.short_name << ")";
} else if (format.type == B_MEDIA_RAW_VIDEO) { } else if (format.type == B_MEDIA_RAW_VIDEO) {
videoFormat = format.u.raw_video; videoFormat = format.u.raw_video;
s << B_TRANSLATE("raw video"); info << B_TRANSLATE("raw video");
} else } else
s << B_TRANSLATE("unknown format"); info << B_TRANSLATE("unknown format");
s << "\n";
s << format.Width() << " x " << format.Height(); fVideoFormatInfo->SetText(info.String());
info.SetToFormat("%" B_PRIu32 " x %" B_PRIu32, format.Width(),
format.Height());
// encoded has output as 1st field... // encoded has output as 1st field...
char fpsString[20]; char fpsString[20];
snprintf(fpsString, sizeof(fpsString), B_TRANSLATE("%.3f fps"), snprintf(fpsString, sizeof(fpsString), B_TRANSLATE("%.3f fps"),
videoFormat.field_rate); videoFormat.field_rate);
s << ", " << fpsString << "\n\n"; info << ", " << fpsString;
fContentsView->Insert(s.String());
fVideoConfigInfo->SetText(info.String());
if (fController->IsOverlayActive())
fDisplayModeInfo->SetText(B_TRANSLATE("Overlay"));
else
fDisplayModeInfo->SetText(B_TRANSLATE("DrawBitmap"));
} }
// audio track format information fVideoSeparator->SetVisible(visible);
if ((which & INFO_AUDIO) && fController->AudioTrackCount() > 0) { _SetVisible(fVideoLabel, visible);
BString label = B_TRANSLATE("Audio"); _SetVisible(fVideoFormatInfo, visible);
fLabelsView->Insert(label << "\n\n\n"); _SetVisible(fVideoConfigInfo, visible);
BString s; _SetVisible(fDisplayModeLabel, visible);
_SetVisible(fDisplayModeInfo, visible);
}
void
InfoWin::_UpdateAudio()
{
bool visible = fController->AudioTrackCount() > 0;
if (visible) {
BString info;
media_format format; media_format format;
media_raw_audio_format audioFormat = {}; media_raw_audio_format audioFormat = {};
err = fController->GetEncodedAudioFormat(&format);
//string_for_format(format, buf, sizeof(buf)); status_t status = fController->GetEncodedAudioFormat(&format);
//printf("%s\n", buf); if (status != B_OK) {
if (err < 0) { info << "(" << strerror(status) << ")\n";
s << "(" << strerror(err) << ")\n";
} else if (format.type == B_MEDIA_ENCODED_AUDIO) { } else if (format.type == B_MEDIA_ENCODED_AUDIO) {
audioFormat = format.u.encoded_audio.output; audioFormat = format.u.encoded_audio.output;
media_codec_info mci; media_codec_info mci;
err = fController->GetAudioCodecInfo(&mci); status = fController->GetAudioCodecInfo(&mci);
if (err < 0) { if (status != B_OK) {
s << B_TRANSLATE("Haiku Media Kit: ") << strerror(err);
if (format.user_data_type == B_CODEC_TYPE_INFO) { if (format.user_data_type == B_CODEC_TYPE_INFO) {
s << (char *)format.user_data << " " info << (char *)format.user_data << " "
<< B_TRANSLATE("(not supported)"); << B_TRANSLATE("(not supported)");
} } else
info = strerror(status);
} else } else
s << mci.pretty_name; //<< "(" << mci.short_name << ")"; info = mci.pretty_name;
} else if (format.type == B_MEDIA_RAW_AUDIO) { } else if (format.type == B_MEDIA_RAW_AUDIO) {
audioFormat = format.u.raw_audio; audioFormat = format.u.raw_audio;
s << B_TRANSLATE("raw audio"); info = B_TRANSLATE("raw audio");
} else } else
s << B_TRANSLATE("unknown format"); info = B_TRANSLATE("unknown format");
s << "\n";
fAudioFormatInfo->SetText(info.String());
uint32 bitsPerSample = 8 * (audioFormat.format uint32 bitsPerSample = 8 * (audioFormat.format
& media_raw_audio_format::B_AUDIO_SIZE_MASK); & media_raw_audio_format::B_AUDIO_SIZE_MASK);
uint32 channelCount = audioFormat.channel_count; uint32 channelCount = audioFormat.channel_count;
float sr = audioFormat.frame_rate; float sr = audioFormat.frame_rate;
info.Truncate(0);
if (bitsPerSample > 0) { if (bitsPerSample > 0) {
char bitString[20]; char bitString[20];
snprintf(bitString, sizeof(bitString), B_TRANSLATE("%d Bit"), snprintf(bitString, sizeof(bitString), B_TRANSLATE("%d Bit"),
bitsPerSample); bitsPerSample);
s << bitString << " "; info << bitString << " ";
} }
static BMessageFormat channelFormat(B_TRANSLATE( static BMessageFormat channelFormat(B_TRANSLATE(
"{0, plural, =1{Mono} =2{Stereo} other{# Channels}}")); "{0, plural, =1{Mono} =2{Stereo} other{# Channels}}"));
channelFormat.Format(s, channelCount); channelFormat.Format(info, channelCount);
s << ", "; info << ", ";
if (sr > 0.0) { if (sr > 0.0) {
char rateString[20]; char rateString[20];
snprintf(rateString, sizeof(rateString), snprintf(rateString, sizeof(rateString),
B_TRANSLATE("%.3f kHz"), sr / 1000); B_TRANSLATE("%.3f kHz"), sr / 1000);
s << rateString; info << rateString;
} else { } else {
BString rateString = B_TRANSLATE("%d kHz"); BString rateString = B_TRANSLATE("%d kHz");
rateString.ReplaceFirst("%d", "??"); rateString.ReplaceFirst("%d", "??");
s << rateString; info << rateString;
} }
if (format.type == B_MEDIA_ENCODED_AUDIO) { if (format.type == B_MEDIA_ENCODED_AUDIO) {
float br = format.u.encoded_audio.bit_rate; float br = format.u.encoded_audio.bit_rate;
char string[20] = ""; char string[20] = "";
if (br > 0.0) if (br > 0.0)
s << ", " << string_for_rate(br, string, sizeof(string)); info << ", " << string_for_rate(br, string, sizeof(string));
}
s << "\n\n";
fContentsView->Insert(s.String());
}
// statistics
if ((which & INFO_STATS) && fController->HasFile()) {
BString label = B_TRANSLATE("Duration");
fLabelsView->Insert(label << "\n");
BString s;
bigtime_t d = fController->TimeDuration();
bigtime_t v;
//s << d << "µs; ";
d /= 1000;
v = d / (3600 * 1000);
d = d % (3600 * 1000);
bool hours = v > 0;
if (hours)
s << v << ":";
v = d / (60 * 1000);
d = d % (60 * 1000);
s << v << ":";
v = d / 1000;
if (v < 10)
s << '0';
s << v;
if (hours)
s << " " << B_TRANSLATE_COMMENT("h", "Hours");
else
s << " " << B_TRANSLATE_COMMENT("min", "Minutes");
s << "\n";
fContentsView->Insert(s.String());
// TODO: demux/video/audio/... perfs (Kb/s)
BString content = B_TRANSLATE("Display mode");
fLabelsView->Insert(content << "\n");
if (fController->IsOverlayActive()) {
content = B_TRANSLATE("Overlay");
fContentsView->Insert(content << "\n");
} else {
content = B_TRANSLATE("DrawBitmap");
fContentsView->Insert(content << "\n");
} }
fLabelsView->Insert("\n"); fAudioConfigInfo->SetText(info.String());
fContentsView->Insert("\n");
} }
if (which & INFO_TRANSPORT) { fAudioSeparator->SetVisible(visible);
// Transport protocol info (file, http, rtsp, ...) _SetVisible(fAudioLabel, visible);
} _SetVisible(fAudioFormatInfo, visible);
_SetVisible(fAudioConfigInfo, visible);
if (which & INFO_FILE) { }
bool iconSet = false;
if (fController->HasFile()) {
const PlaylistItem* item = fController->Item(); void
iconSet = fInfoView->SetIcon(item) == B_OK; InfoWin::_UpdateDuration()
media_file_format fileFormat; {
BString s; if (!fController->HasFile()) {
if (fController->GetFileFormatInfo(&fileFormat) == B_OK) { fDurationInfo->SetText("-");
BString label = B_TRANSLATE("Container"); return;
fLabelsView->Insert(label << "\n"); }
s << fileFormat.pretty_name;
s << "\n"; BString info;
fContentsView->Insert(s.String());
if (!iconSet) bigtime_t d = fController->TimeDuration() / 1000;
iconSet = fInfoView->SetIcon(fileFormat.mime_type) == B_OK; bigtime_t v = d / (3600 * 1000);
} else d = d % (3600 * 1000);
fContentsView->Insert("\n"); bool hours = v > 0;
BString label = B_TRANSLATE("Location"); if (hours)
fLabelsView->Insert(label << "\n"); info << v << ":";
if (fController->GetLocation(&s) < B_OK) v = d / (60 * 1000);
s = B_TRANSLATE("<unknown>"); d = d % (60 * 1000);
s << "\n"; info << v << ":";
fContentsView->Insert(s.String()); v = d / 1000;
if (fController->GetName(&s) < B_OK) if (v < 10)
s = B_TRANSLATE("<unnamed media>"); info << '0';
fFilenameView->SetText(s.String()); info << v;
} else { if (hours)
fFilenameView->SetText(B_TRANSLATE("<no media>")); info << " " << B_TRANSLATE_COMMENT("h", "Hours");
} else
if (!iconSet) info << " " << B_TRANSLATE_COMMENT("min", "Minutes");
fInfoView->SetGenericIcon();
} fDurationInfo->SetText(info.String());
}
if ((which & INFO_COPYRIGHT) && fController->HasFile()) {
BString s;
if (fController->GetCopyright(&s) == B_OK && s.Length() > 0) { void
BString label = B_TRANSLATE("Copyright"); InfoWin::_UpdateCopyright()
fLabelsView->Insert(label << "\n\n"); {
s << "\n\n"; BString info;
fContentsView->Insert(s.String());
} bool visible = fController->HasFile()
} && fController->GetCopyright(&info) == B_OK && !info.IsEmpty();
if (visible)
fController->Unlock(); fCopyrightInfo->SetText(info.String());
ResizeToPreferred(); fCopyrightSeparator->SetVisible(visible);
_SetVisible(fCopyrightLabel, visible);
_SetVisible(fCopyrightInfo, visible);
}
// #pragma mark -
BStringView*
InfoWin::_CreateLabel(const char* name, const char* label)
{
static const rgb_color kLabelColor = tint_color(
ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_3_TINT);
BStringView* view = new BStringView(name, label);
view->SetAlignment(B_ALIGN_RIGHT);
view->SetHighColor(kLabelColor);
return view;
}
BStringView*
InfoWin::_CreateInfo(const char* name)
{
BStringView* view = new BStringView(name, "");
view->SetExplicitMinSize(BSize(200, B_SIZE_UNSET));
view->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
view->SetTruncation(B_TRUNCATE_SMART);
return view;
}
BLayoutItem*
InfoWin::_CreateSeparator()
{
return BSpaceLayoutItem::CreateVerticalStrut(
be_control_look->ComposeSpacing(B_USE_HALF_ITEM_SPACING));
}
void
InfoWin::_SetVisible(BView* view, bool visible)
{
bool hidden = view->IsHidden(view);
if (hidden && visible)
view->Show();
else if (!hidden && !visible)
view->Hide();
} }
+34 -6
View File
@@ -24,11 +24,12 @@
#include <Window.h> #include <Window.h>
class BLayoutItem;
class BStringView; class BStringView;
class BTextView; class BTextView;
class Controller; class Controller;
class ControllerObserver; class ControllerObserver;
class InfoView; class IconView;
#define INFO_STATS 0x00000001 #define INFO_STATS 0x00000001
@@ -47,22 +48,49 @@ public:
Controller* controller); Controller* controller);
virtual ~InfoWin(); virtual ~InfoWin();
virtual void FrameResized(float newWidth, float newHeight);
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested(); virtual bool QuitRequested();
virtual void Pulse(); virtual void Pulse();
void ResizeToPreferred();
void Update(uint32 which = INFO_ALL); void Update(uint32 which = INFO_ALL);
private:
void _UpdateFile();
void _UpdateVideo();
void _UpdateAudio();
void _UpdateDuration();
void _UpdateCopyright();
BStringView* _CreateLabel(const char* name,
const char* label);
BStringView* _CreateInfo(const char* name);
BLayoutItem* _CreateSeparator();
void _SetVisible(BView* view, bool visible);
private: private:
Controller* fController; Controller* fController;
ControllerObserver* fControllerObserver; ControllerObserver* fControllerObserver;
InfoView* fInfoView; IconView* fIconView;
BStringView* fFilenameView; BStringView* fFilenameView;
BTextView* fLabelsView;
BTextView* fContentsView; BStringView* fContainerInfo;
BLayoutItem* fVideoSeparator;
BStringView* fVideoLabel;
BStringView* fVideoFormatInfo;
BStringView* fVideoConfigInfo;
BStringView* fDisplayModeLabel;
BStringView* fDisplayModeInfo;
BLayoutItem* fAudioSeparator;
BStringView* fAudioLabel;
BStringView* fAudioFormatInfo;
BStringView* fAudioConfigInfo;
BStringView* fDurationInfo;
BStringView* fLocationInfo;
BLayoutItem* fCopyrightSeparator;
BStringView* fCopyrightLabel;
BStringView* fCopyrightInfo;
}; };
#endif // __FILE_INFO_WIN_H #endif // __FILE_INFO_WIN_H