*Update MediaConverter to use the Layout API

*Replace StatusView class with BStringView
*Rename some variables (fBox1 -> fSourcesBox, for example)
*Create MediaFileInfo struct to cache strings for media files, these were
	previously created on each call to MediaFileInfoView::Draw()
*Update MediaFileInfoView class for layout-friendliness and hopefully
	better performance.
*Update other classes for layout-friendliness as well (just remove BRect and
	resizeFlags params)
*Add keyboard accels for Open and Quit items in menuBar
*closes #4197
*fixes CIDs 1545 and 1455



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38346 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alex Wilson 2010-08-24 23:10:44 +00:00
parent 424f57123c
commit dd55ed1aef
12 changed files with 475 additions and 485 deletions

View File

@ -6,9 +6,9 @@ Application MediaConverter :
MediaConverterApp.cpp
MediaConverterWindow.cpp
MediaEncoderWindow.cpp
MediaFileInfo.cpp
MediaFileInfoView.cpp
MediaFileListView.cpp
StatusView.cpp
: be media tracker $(TARGET_LIBSTDC++)
: MediaConverter.rdef

View File

@ -93,8 +93,9 @@ MediaConverterApp::ReadyToRun()
fWin->PostMessage(INIT_FORMAT_MENUS);
}
void
MediaConverterApp::RefsReceived(BMessage *msg)
MediaConverterApp::RefsReceived(BMessage* msg)
{
entry_ref ref;
int32 i = 0;
@ -124,7 +125,7 @@ MediaConverterApp::RefsReceived(BMessage *msg)
alertText << errors << ((errors > 1) ? FILES : FILE)
<< NOTRECOGNIZE << "\n";
alertText << errorFiles;
BAlert *alert = new BAlert(ERROR_LOAD_STRING, alertText.String(),
BAlert* alert = new BAlert(ERROR_LOAD_STRING, alertText.String(),
CONTINUE_STRING , NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT);
alert->Go();
}
@ -163,7 +164,7 @@ MediaConverterApp::StartConverting()
void
MediaConverterApp::SetStatusMessage(const char *message)
MediaConverterApp::SetStatusMessage(const char* message)
{
if (fWin != NULL && fWin->Lock()) {
fWin->SetStatusMessage(message);

View File

@ -1,6 +1,7 @@
// Copyright 1999, Be Incorporated. All Rights Reserved.
// Copyright 2000-2004, Jun Suzuki. All Rights Reserved.
// Copyright 2007, Stephan Aßmus. All Rights Reserved.
// Copyright 2010, Haiku, Inc. All Rights Reserved.
// This file may be used under the terms of the Be Sample Code License.
#include "MediaConverterWindow.h"
@ -11,7 +12,9 @@
#include <Application.h>
#include <Box.h>
#include <Button.h>
#include <ControlLook.h>
#include <FilePanel.h>
#include <LayoutBuilder.h>
#include <Menu.h>
#include <MenuBar.h>
#include <MenuField.h>
@ -28,7 +31,6 @@
#include "MediaFileInfoView.h"
#include "MediaFileListView.h"
#include "MessageConstants.h"
#include "StatusView.h"
#include "Strings.h"
@ -59,7 +61,8 @@ public:
FileFormatMenuItem::FileFormatMenuItem(media_file_format *format)
: BMenuItem(format->pretty_name, new BMessage(FORMAT_SELECT_MESSAGE))
:
BMenuItem(format->pretty_name, new BMessage(FORMAT_SELECT_MESSAGE))
{
memcpy(&fFileFormat, format, sizeof(fFileFormat));
}
@ -83,7 +86,8 @@ class CodecMenuItem : public BMenuItem {
CodecMenuItem::CodecMenuItem(media_codec_info *ci, uint32 msg_type)
: BMenuItem(ci->pretty_name, new BMessage(msg_type))
:
BMenuItem(ci->pretty_name, new BMessage(msg_type))
{
memcpy(&fCodecInfo, ci, sizeof(fCodecInfo));
}
@ -98,20 +102,17 @@ CodecMenuItem::~CodecMenuItem()
MediaConverterWindow::MediaConverterWindow(BRect frame)
: BWindow(frame, "MediaConverter", B_TITLED_WINDOW_LOOK,
B_NORMAL_WINDOW_FEEL, B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS)
, fVideoQuality(75)
, fAudioQuality(75)
, fSaveFilePanel(NULL)
, fOpenFilePanel(NULL)
, fOutputDirSpecified(false)
, fEnabled(true)
, fConverting(false)
, fCancelling(false)
:
BWindow(frame, "MediaConverter", B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS),
fVideoQuality(75),
fAudioQuality(75),
fSaveFilePanel(NULL),
fOpenFilePanel(NULL),
fOutputDirSpecified(false),
fEnabled(true),
fConverting(false),
fCancelling(false)
{
char defaultdirectory[] = "/boot/home";
fOutputDir.SetTo(defaultdirectory);
@ -132,177 +133,109 @@ MediaConverterWindow::MediaConverterWindow(BRect frame)
#endif
BRect dummyRect(0, 0, 10, 10);
fMenuBar = new BMenuBar(dummyRect, "menubar");
fMenuBar = new BMenuBar("menubar");
_CreateMenu();
AddChild(fMenuBar);
// background
BRect r(frame);
r.OffsetTo(0, 0);
BView *background = new BView(r, NULL, B_FOLLOW_ALL_SIDES, 0);
rgb_color c = ui_color(B_PANEL_BACKGROUND_COLOR);
background->SetViewColor(c);
background->SetLowColor(c);
r.InsetBy(5, 25);
fListView = new MediaFileListView();
fListView->SetExplicitMinSize(BSize(100, B_SIZE_UNSET));
BScrollView* scroller = new BScrollView(NULL, fListView, 0, false, true);
// file list view box
BRect r2(r);
r2.bottom = r2.top + 420;
r2.right = r2.left + 150;
fBox1 = new BBox(r2, NULL, B_FOLLOW_ALL);
fSourcesBox = new BBox(B_FANCY_BORDER, scroller);
fSourcesBox->SetLayout(new BGroupLayout(B_HORIZONTAL, 0));
// We give fSourcesBox a layout to provide insets for the sources list
// said insets are adjusted in _UpdateLabels
BRect r3(r2);
r3.OffsetTo(0, 0);
r3.InsetBy(8, 8);
r3.top += be_bold_font->Size() - 3;
bool useHorizontalScrollBar = false;
if (useHorizontalScrollBar)
r3.bottom -= B_H_SCROLL_BAR_HEIGHT;
r3.right -= B_V_SCROLL_BAR_WIDTH;
fListView = new MediaFileListView(r3, B_FOLLOW_ALL);
BScrollView *scroller = new BScrollView(NULL, fListView,
B_FOLLOW_ALL, 0, useHorizontalScrollBar, true);
fBox1->AddChild(scroller);
background->AddChild(fBox1);
fInfoView = new MediaFileInfoView();
fInfoBox = new BBox(B_FANCY_BORDER, fInfoView);
fInfoBox->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH,
B_ALIGN_USE_FULL_HEIGHT));
// info box
r2.left = r2.right + 5;
r2.right = r.right - 5;
r2.bottom = r2.top + 120;
fBox2 = new BBox(r2, NULL, B_FOLLOW_RIGHT | B_FOLLOW_TOP);
// Output format box
fOutputBox = new BBox(B_FANCY_BORDER, NULL);
float padding = be_control_look->DefaultItemSpacing();
BGridLayout* ouputGrid = new BGridLayout(padding, padding);
fOutputBox->SetLayout(ouputGrid);
// fOutputBox's layout is also adjusted in _UpdateLabels
r3 = r2;
r3.OffsetTo(0, 0);
r3.InsetBy(5, 5);
r3.top += 12;
fInfoView = new MediaFileInfoView(r3, B_FOLLOW_ALL);
fBox2->AddChild(fInfoView);
background->AddChild(fBox2);
r2.top = r2.bottom + 5;
r2.bottom = r2.top + 295;
fBox3 = new BBox(r2, NULL, B_FOLLOW_RIGHT | B_FOLLOW_TOP_BOTTOM);
r3 = r2;
r3.OffsetTo(0, 0);
r3.InsetBy(8, 8);
r3.top += be_bold_font->Size() - 3;
BRect r4(r3);
r4.bottom = r4.top + 20;
BPopUpMenu* popmenu = new BPopUpMenu("");
fFormatMenu = new BMenuField(r4, NULL, FORMAT_LABEL, popmenu,
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
fBox3->AddChild(fFormatMenu);
fFormatMenu = new BMenuField(NULL, FORMAT_LABEL, popmenu);
r4.top = r4.bottom + 5;
r4.bottom = r4.top + 20;
popmenu = new BPopUpMenu("");
fAudioMenu = new BMenuField(r4, NULL, AUDIO_LABEL, popmenu,
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
fBox3->AddChild(fAudioMenu);
fAudioMenu = new BMenuField(NULL, AUDIO_LABEL, popmenu);
r4.top = r4.bottom + 5;
r4.bottom = r4.top + 20;
popmenu = new BPopUpMenu("");
fVideoMenu = new BMenuField(r4, NULL, VIDEO_LABEL, popmenu,
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
fBox3->AddChild(fVideoMenu);
fVideoMenu = new BMenuField(NULL, VIDEO_LABEL, popmenu);
// output folder
r4.top = r4.bottom + 5;
r4.bottom = r4.top + 20;
r4.right = 80;
fDestButton = new BButton(r4, NULL, OUTPUT_FOLDER_LABEL,
new BMessage(OUTPUT_FOLDER_MESSAGE),
B_FOLLOW_LEFT | B_FOLLOW_TOP);
fBox3->AddChild(fDestButton);
fDestButton->ResizeToPreferred();
BRect buttonFrame2(fDestButton->Frame());
buttonFrame2.OffsetTo(r.right - buttonFrame2.Width(),
r.bottom - buttonFrame2.Height());
fOutputFolder = new BStringView(r4, NULL, defaultdirectory,
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP, B_WILL_DRAW);
fBox3->AddChild(fOutputFolder);
fOutputFolder->MoveBy(buttonFrame2.Width() + 10, 5);
fOutputFolder->ResizeToPreferred();
fDestButton = new BButton(OUTPUT_FOLDER_LABEL,
new BMessage(OUTPUT_FOLDER_MESSAGE));
BAlignment labelAlignment(be_control_look->DefaultLabelAlignment());
fOutputFolder = new BStringView(NULL, defaultdirectory);
fOutputFolder->SetExplicitAlignment(labelAlignment);
// start/end duration
r4.top = r4.bottom + 10;
r4.bottom = r4.top + 20;
r4.right = r3.right;
fStartDurationTC = new BTextControl(r4, NULL, "", "0", NULL,
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
fBox3->AddChild(fStartDurationTC);
fStartDurationTC = new BTextControl(NULL, NULL, NULL);
fStartDurationTC->SetText("0");
r4.top = r4.bottom + 5;
r4.bottom = r4.top + 20;
fEndDurationTC = new BTextControl(r4, NULL, "", "0", NULL,
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
fBox3->AddChild(fEndDurationTC);
fEndDurationTC = new BTextControl(NULL, NULL, NULL);
fEndDurationTC->SetText("0");
r4.top = r4.bottom + 5;
r4.bottom = r4.top + 50;
// Video Quality
fVideoQualitySlider = new BSlider(r4, "VSlider", "" ,
new BMessage(VIDEO_QUALITY_CHANGED_MESSAGE), 1, 100, B_HORIZONTAL,
B_BLOCK_THUMB, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
fVideoQualitySlider = new BSlider("VSlider", "" ,
new BMessage(VIDEO_QUALITY_CHANGED_MESSAGE), 1, 100, B_HORIZONTAL);
fVideoQualitySlider->SetValue(fVideoQuality);
fVideoQualitySlider->SetEnabled(false);
fBox3->AddChild(fVideoQualitySlider);
r4.top = r4.bottom + 5;
r4.bottom = r4.top + 50;
// Audio Quality
fAudioQualitySlider = new BSlider(r4,"ASlider", "" ,
new BMessage(AUDIO_QUALITY_CHANGED_MESSAGE), 1, 100, B_HORIZONTAL,
B_BLOCK_THUMB, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
fAudioQualitySlider = new BSlider("ASlider", "" ,
new BMessage(AUDIO_QUALITY_CHANGED_MESSAGE), 1, 100, B_HORIZONTAL);
fAudioQualitySlider->SetValue(fAudioQuality);
fAudioQualitySlider->SetEnabled(false);
fBox3->AddChild(fAudioQualitySlider);
background->AddChild(fBox3);
BLayoutBuilder::Grid<>(ouputGrid)
.SetInsets(padding, padding, padding, padding)
.AddMenuField(fFormatMenu, 0, 0)
.AddMenuField(fAudioMenu, 0, 1)
.AddMenuField(fVideoMenu, 0, 2)
.Add(fDestButton, 0, 3)
.Add(fOutputFolder, 1, 3)
.AddTextControl(fStartDurationTC, 0, 4)
.AddTextControl(fEndDurationTC, 0, 5)
.Add(fVideoQualitySlider, 0, 6, 2, 1)
.Add(fAudioQualitySlider, 0, 7, 2, 1);
// buttons
r2.top = r2.bottom + 15;
r2.bottom = r2.top + 20;
r2.left = r.left - 120;
r2.right = r.right;
fPreviewButton = new BButton(r2, NULL, PREVIEW_BUTTON_LABEL,
new BMessage(PREVIEW_MESSAGE), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
background->AddChild(fPreviewButton);
fPreviewButton = new BButton(PREVIEW_BUTTON_LABEL,
new BMessage(PREVIEW_MESSAGE));
fPreviewButton->SetEnabled(false);
fConvertButton = new BButton(r2, NULL, CONVERT_LABEL,
new BMessage(CONVERT_BUTTON_MESSAGE),
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
background->AddChild(fConvertButton);
fConvertButton = new BButton(CONVERT_LABEL,
new BMessage(CONVERT_BUTTON_MESSAGE));
// Status view
r2.bottom = r2.top + 20;
r2.left = r.left;
r2.right = r.right;
fStatusView2 = new StatusView(r2, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM);
background->AddChild(fStatusView2);
r2.top += 15;
r2.bottom += 20;
fStatusView = new StatusView(r2, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM);
background->AddChild(fStatusView);
AddChild(background);
// Status views
fStatus = new BStringView(NULL, NULL);
fStatus->SetExplicitAlignment(labelAlignment);
fFileStatus= new BStringView(NULL, NULL);
fFileStatus->SetExplicitAlignment(labelAlignment);
SetStatusMessage("");
_UpdateLabels();
SetSizeLimits(frame.Width(), 32000, frame.Height(), 32000);
BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
.SetInsets(0, 0, 0, 0)
.Add(fMenuBar)
.AddGrid(padding, padding)
.SetInsets(padding, padding, padding, padding)
.Add(fSourcesBox, 0, 0, 1, 2)
.Add(fInfoBox, 1, 0, 1, 1)
.Add(fOutputBox, 1, 1, 1, 1)
.AddGrid(padding, padding, 0, 2, 2, 1)
.SetInsets(0, 0, 0, 0)
.Add(fStatus, 0, 0)
.Add(fFileStatus, 0, 1)
.Add(fPreviewButton, 2, 0)
.Add(fConvertButton, 3, 0);
}
@ -335,7 +268,7 @@ MediaConverterWindow::DispatchMessage(BMessage *msg, BHandler *handler)
void
MediaConverterWindow::MessageReceived(BMessage *msg)
MediaConverterWindow::MessageReceived(BMessage* msg)
{
status_t status;
entry_ref ref;
@ -487,7 +420,8 @@ MediaConverterWindow::MessageReceived(BMessage *msg)
VERSION"\n"
B_UTF8_COPYRIGHT" 1999, Be Incorporated.\n"
B_UTF8_COPYRIGHT" 2000-2004 Jun Suzuki\n"
B_UTF8_COPYRIGHT" 2007 Stephan Aßmus",
B_UTF8_COPYRIGHT" 2007 Stephan Aßmus\n",
B_UTF8_COPYRIGHT" 2010 Haiku, Inc.",
OK_LABEL))->Go();
break;
}
@ -737,16 +671,18 @@ MediaConverterWindow::BuildFormatMenu()
}
}
void
MediaConverterWindow::SetFileMessage(const char *message)
{
fStatusView->SetStatus(message);
fFileStatus->SetText(message);
}
void
MediaConverterWindow::SetStatusMessage(const char *message)
{
fStatusView2->SetStatus(message);
fStatus->SetText(message);
}
@ -902,110 +838,76 @@ MediaConverterWindow::SetVideoQualityLabel(const char* label)
void
MediaConverterWindow::_UpdateLabels()
{
char buffer[255];
if (fSourcesBox != NULL) {
fSourcesBox->SetLabel(SOURCE_BOX_LABEL);
_UpdateBBoxLayoutInsets(fSourcesBox);
}
if (fBox1 != NULL)
fBox1->SetLabel(SOURCE_BOX_LABEL);
if (fBox2 != NULL)
fBox2->SetLabel(INFO_BOX_LABEL);
if (fBox3 != NULL)
fBox3->SetLabel(OUTPUT_BOX_LABEL);
if (fInfoBox != NULL)
fInfoBox->SetLabel(INFO_BOX_LABEL);
BRect r(Bounds());
float w = 0;
if (fOutputBox != NULL) {
fOutputBox->SetLabel(OUTPUT_BOX_LABEL);
_UpdateBBoxLayoutInsets(fOutputBox);
}
if (fConvertButton != NULL) {
if (fConvertButton != NULL)
fConvertButton->SetLabel(CONVERT_LABEL);
fConvertButton->ResizeToPreferred();
BRect buttonFrame(fConvertButton->Frame());
w = buttonFrame.Width();
buttonFrame.OffsetTo(r.right - w - 10, r.bottom - buttonFrame.Height() - 25);
fConvertButton->MoveTo(buttonFrame.LeftTop());
}
if (fPreviewButton != NULL) {
if (fPreviewButton != NULL)
fPreviewButton->SetLabel(PREVIEW_BUTTON_LABEL);
fPreviewButton->ResizeToPreferred();
BRect buttonFrame(fPreviewButton->Frame());
w = buttonFrame.Width();
buttonFrame.OffsetTo(r.right - w - buttonFrame.Width() - 40,
r.bottom - buttonFrame.Height() - 25);
fPreviewButton->MoveTo(buttonFrame.LeftTop());
}
if (fDestButton != NULL) {
if (fDestButton != NULL)
fDestButton->SetLabel(OUTPUT_FOLDER_LABEL);
fDestButton->ResizeToPreferred();
}
if (fOutputFolder != NULL) {
BRect destrect;
destrect = fDestButton->Frame();
fOutputFolder->MoveTo(destrect.right + 10, destrect.top + 5);
fOutputFolder->ResizeToPreferred();
}
sprintf(buffer, VIDEO_QUALITY_LABEL, (int8)fVideoQuality);
if (fVideoQualitySlider != NULL) {
char buffer[40];
sprintf(buffer, VIDEO_QUALITY_LABEL, (int8)fVideoQuality);
fVideoQualitySlider->SetLabel(buffer);
fVideoQualitySlider->SetLimitLabels(SLIDER_LOW_LABEL,
SLIDER_HIGH_LABEL);
}
sprintf(buffer, AUDIO_QUALITY_LABEL, (int8)fAudioQuality);
if (fAudioQualitySlider != NULL) {
char buffer[40];
sprintf(buffer, AUDIO_QUALITY_LABEL, (int8)fAudioQuality);
fAudioQualitySlider->SetLabel(buffer);
fAudioQualitySlider->SetLimitLabels(SLIDER_LOW_LABEL,
SLIDER_HIGH_LABEL);
}
float maxLabelLen = 0;
if (fStartDurationTC != NULL) {
if (fStartDurationTC != NULL)
fStartDurationTC->SetLabel(START_LABEL);
maxLabelLen = fStartDurationTC->StringWidth(START_LABEL);
}
if (fEndDurationTC != NULL) {
if (fEndDurationTC != NULL)
fEndDurationTC->SetLabel(END_LABEL);
maxLabelLen = MAX(maxLabelLen, fEndDurationTC->StringWidth(END_LABEL));
}
if (fStartDurationTC != NULL)
fStartDurationTC->SetDivider(maxLabelLen + 5);
if (fEndDurationTC != NULL)
fEndDurationTC->SetDivider(maxLabelLen + 5);
if (fFormatMenu != NULL) {
fFormatMenu->SetLabel(FORMAT_LABEL);
maxLabelLen = MAX(maxLabelLen, fFormatMenu->StringWidth(
fFormatMenu->Label()));
}
if (fAudioMenu != NULL) {
fAudioMenu->SetLabel(AUDIO_LABEL);
maxLabelLen = MAX(maxLabelLen, fAudioMenu->StringWidth(
fAudioMenu->Label()));
}
if (fVideoMenu != NULL) {
fVideoMenu->SetLabel(VIDEO_LABEL);
maxLabelLen = MAX(maxLabelLen, fVideoMenu->StringWidth(
fVideoMenu->Label()));
}
maxLabelLen += 10;
if (fStartDurationTC != NULL)
fStartDurationTC->SetDivider(maxLabelLen);
if (fEndDurationTC != NULL)
fEndDurationTC->SetDivider(maxLabelLen);
if (fFormatMenu != NULL)
fFormatMenu->SetDivider(maxLabelLen + 3);
fFormatMenu->SetLabel(FORMAT_LABEL);
if (fAudioMenu != NULL)
fAudioMenu->SetDivider(maxLabelLen + 3);
fAudioMenu->SetLabel(AUDIO_LABEL);
if (fVideoMenu != NULL)
fVideoMenu->SetDivider(maxLabelLen + 3);
fVideoMenu->SetLabel(VIDEO_LABEL);
SetFileMessage(DROP_MEDIA_FILE_LABEL);
}
void
MediaConverterWindow::_UpdateBBoxLayoutInsets(BBox* box)
{
BTwoDimensionalLayout* layout
= dynamic_cast<BTwoDimensionalLayout*>(box->GetLayout());
if (layout) {
float padding = be_control_look->DefaultItemSpacing();
layout->SetInsets(padding, box->TopBorderOffset() + padding, padding,
padding);
}
}
void
MediaConverterWindow::_DestroyMenu()
{
@ -1026,14 +928,15 @@ MediaConverterWindow::_CreateMenu()
menu = new BMenu(FILE_MENU_LABEL);
item = new BMenuItem(OPEN_MENU_LABEL B_UTF8_ELLIPSIS,
new BMessage(OPEN_FILE_MESSAGE));
new BMessage(OPEN_FILE_MESSAGE), 'O');
menu->AddItem(item);
menu->AddSeparatorItem();
item = new BMenuItem(ABOUT_MENU_LABEL B_UTF8_ELLIPSIS,
new BMessage(DISP_ABOUT_MESSAGE));
menu->AddItem(item);
menu->AddSeparatorItem();
item = new BMenuItem(QUIT_MENU_LABEL, new BMessage(QUIT_MESSAGE));
item = new BMenuItem(QUIT_MENU_LABEL, new BMessage(QUIT_MESSAGE), 'Q');
menu->AddItem(item);
fMenuBar->AddItem(menu);

View File

@ -75,25 +75,25 @@ class MediaConverterWindow : public BWindow {
private:
void _UpdateLabels();
void _UpdateBBoxLayoutInsets(BBox* box);
void _CreateMenu();
void _DestroyMenu();
void _SetOutputFolder(BEntry entry);
media_format fDummyFormat;
BButton* fConvertButton;
BButton* fDestButton;
BButton* fPreviewButton;
BBox* fBox1;
BBox* fBox2;
BBox* fBox3;
BBox* fSourcesBox;
BBox* fInfoBox;
BBox* fOutputBox;
BMenuBar* fMenuBar;
BMenuField* fFormatMenu;
BMenuField* fVideoMenu;
BMenuField* fAudioMenu;
StatusView* fStatusView;
StatusView* fStatusView2;
BStringView* fFileStatus;
BStringView* fStatus;
MediaFileListView* fListView;
MediaFileInfoView* fInfoView;
BStringView* fOutputFolder;

View File

@ -0,0 +1,108 @@
// Copyright 1999, Be Incorporated. All Rights Reserved.
// Copyright 2000-2004, Jun Suzuki. All Rights Reserved.
// Copyright 2007, Stephan Aßmus. All Rights Reserved.
// Copyright 2010, Haiku, Inc. All Rights Reserved.
// This file may be used under the terms of the Be Sample Code License.
#include "MediaFileInfo.h"
#include <MediaTrack.h>
MediaFileInfo::MediaFileInfo(BMediaFile* file)
{
LoadInfo(file);
}
void
MediaFileInfo::LoadInfo(BMediaFile* file)
{
_Reset();
if (!file)
return;
BMediaTrack* track;
media_format format;
memset(&format, 0, sizeof(format));
media_codec_info codecInfo;
bool audioDone(false), videoDone(false);
bigtime_t audioDuration = 0;
bigtime_t videoDuration = 0;
int32 tracks = file->CountTracks();
int64 videoFrames = 0;
int64 audioFrames = 0;
for (int32 i = 0; i < tracks && (!audioDone || !videoDone); i++) {
track = file->TrackAt(i);
if (track != NULL) {
track->EncodedFormat(&format);
if (format.IsVideo()) {
memset(&format, 0, sizeof(format));
format.type = B_MEDIA_RAW_VIDEO;
track->DecodedFormat(&format);
media_raw_video_format *rvf = &(format.u.raw_video);
track->GetCodecInfo(&codecInfo);
video.format << codecInfo.pretty_name;
videoDuration = track->Duration();
videoFrames = track->CountFrames();
video.details << (int32)format.Width() << "x"
<< (int32)format.Height() << " "
<< (int32)(rvf->field_rate / rvf->interlace)
<< " fps / " << videoFrames << " frames";
videoDone = true;
} else if (format.IsAudio()) {
memset(&format, 0, sizeof(format));
format.type = B_MEDIA_RAW_AUDIO;
track->DecodedFormat(&format);
media_raw_audio_format *raf = &(format.u.raw_audio);
char bytesPerSample = (char)(raf->format & 0xf);
if (bytesPerSample == 1) {
audio.details << "8 bit ";
} else if (bytesPerSample == 2) {
audio.details << "16 bit ";
} else {
audio.details << bytesPerSample << "byte ";
}
track->GetCodecInfo(&codecInfo);
audio.format << codecInfo.pretty_name;
audioDuration = track->Duration();
audioFrames = track->CountFrames();
audio.details << (float)(raf->frame_rate / 1000.0f) << " kHz";
if (raf->channel_count == 1) {
audio.details << " mono / ";
} else if (raf->channel_count == 2) {
audio.details << " stereo / ";
} else {
audio.details << (int32)raf->channel_count
<< " channel / " ;
}
audio.details << audioFrames << " frames";
audioDone = true;
}
file->ReleaseTrack(track);
}
}
useconds = MAX(audioDuration, videoDuration);
duration << (int32)(useconds / 1000000)
<< " seconds";
}
void
MediaFileInfo::_Reset()
{
audio.details.SetTo("");
audio.format.SetTo("");
video.details.SetTo("");
video.format.SetTo("");
useconds = 0;
duration.SetTo("");
}

View File

@ -0,0 +1,32 @@
/*
Copyright 2010, Haiku, Inc. All Rights Reserved.
This file may be used under the terms of the MIT License.
*/
#ifndef MEDIA_FILE_INFO_H
#define MEDIA_FILE_INFO_H
#include <MediaFile.h>
#include <String.h>
struct MediaInfo {
BString format;
BString details;
};
struct MediaFileInfo {
MediaFileInfo(BMediaFile* file = NULL);
void LoadInfo(BMediaFile* file);
MediaInfo audio;
MediaInfo video;
BString duration;
bigtime_t useconds;
private:
void _Reset();
};
#endif // MEDIA_FILE_INFO_H

View File

@ -4,8 +4,7 @@
// This file may be used under the terms of the Be Sample Code License.
#include "MediaFileInfoView.h"
#include <string.h>
#include <ControlLook.h>
#include <MediaFile.h>
#include <MediaTrack.h>
#include <String.h>
@ -13,13 +12,17 @@
#include "Strings.h"
MediaFileInfoView::MediaFileInfoView(BRect frame, uint32 resizingMode)
: BView(frame, "MediaFileInfoView", resizingMode,
B_FULL_UPDATE_ON_RESIZE | B_WILL_DRAW)
, fRef()
, fMediaFile(NULL)
, fDuration(0)
const float kSpacing = 5.0f;
MediaFileInfoView::MediaFileInfoView()
:
BView("MediaFileInfoView", B_WILL_DRAW | B_SUPPORTS_LAYOUT),
fMinMaxValid(false),
fRef(),
fMediaFile(NULL)
{
SetFont(be_plain_font);
}
@ -31,57 +34,102 @@ MediaFileInfoView::~MediaFileInfoView()
void
MediaFileInfoView::Draw(BRect /*update*/)
{
_ValidateMinMax();
_SetFontFace(B_BOLD_FACE);
font_height fh;
GetFontHeight(&fh);
BPoint p(2, fh.ascent + fh.leading);
BFont font;
GetFont(&font);
font.SetFace(B_BOLD_FACE);
font.SetSize(12);
SetFont(&font);
BPoint labelStart(kSpacing, fh.ascent + fh.leading + 1);
if (fMediaFile == NULL) {
DrawString(NO_FILE_LABEL, p);
DrawString(NO_FILE_LABEL, labelStart);
return;
}
BString aFmt, vFmt, aDetails, vDetails, duration;
_GetFileInfo(&aFmt, &vFmt, &aDetails, &vDetails, &duration);
// draw filename
DrawString(fRef.name, p);
float lineHeight = fh.ascent + fh.descent + fh.leading;
p.y += (float)ceil(lineHeight * 1.5);
float durLen = StringWidth(DURATION_LABEL) + 5;
float audLen = StringWidth(AUDIO_INFO_LABEL) + 5;
float vidLen = StringWidth(VIDEO_INFO_LABEL) + 5;
float maxLen = MAX(durLen, audLen);
maxLen = MAX(maxLen, vidLen);
DrawString(fRef.name, labelStart);
labelStart.y += fLineHeight + kSpacing;
BPoint infoStart(labelStart.x + fMaxLabelWidth + kSpacing, labelStart.y);
// draw labels
DrawString(AUDIO_INFO_LABEL, p + BPoint(maxLen - audLen, 0));
BPoint p2 = p;
p2.x += maxLen + 4;
p.y += lineHeight * 2;
DrawString(VIDEO_INFO_LABEL, p + BPoint(maxLen - vidLen, 0));
p.y += lineHeight * 2;
DrawString(DURATION_LABEL, p + BPoint(maxLen - durLen, 0));
DrawString(AUDIO_INFO_LABEL, labelStart);
labelStart.y += fLineHeight * 2;
DrawString(VIDEO_INFO_LABEL, labelStart);
labelStart.y += fLineHeight * 2;
DrawString(DURATION_LABEL, labelStart);
labelStart.y += fLineHeight * 2;
// draw audio/video/duration info
font.SetFace(B_REGULAR_FACE);
font.SetSize(10);
SetFont(&font);
_SetFontFace(B_REGULAR_FACE);
DrawString(aFmt.String(), p2);
p2.y += lineHeight;
DrawString(aDetails.String(), p2);
p2.y += lineHeight;
DrawString(vFmt.String(), p2);
p2.y += lineHeight;
DrawString(vDetails.String(), p2);
p2.y += lineHeight;
DrawString(duration.String(), p2);
BString* infoStrings[5] = {&fInfo.audio.format, &fInfo.audio.details,
&fInfo.video.format, &fInfo.video.details, &fInfo.duration};
for (int32 i = 0; i < 5; i++) {
DrawString(*infoStrings[i], infoStart);
infoStart.y += fLineHeight;
}
}
BSize
MediaFileInfoView::MinSize()
{
_ValidateMinMax();
return fMinSize;
}
BSize
MediaFileInfoView::MaxSize()
{
return fMinSize;
}
BSize
MediaFileInfoView::PreferredSize()
{
_ValidateMinMax();
return fMinSize;
}
BAlignment
MediaFileInfoView::LayoutAlignment()
{
return BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP);
}
void
MediaFileInfoView::InvalidateLayout(bool /*children*/)
{
fMinMaxValid = false;
BView::InvalidateLayout();
}
void
MediaFileInfoView::SetFont(const BFont* font, uint32 mask)
{
BView::SetFont(font, mask);
if (mask == B_FONT_FACE)
return;
fLineHeight = _LineHeight();
BFont bold(font);
bold.SetFace(B_BOLD_FACE);
fMaxLabelWidth = 0;
BString labels[] = {VIDEO_INFO_LABEL, DURATION_LABEL, AUDIO_INFO_LABEL};
int32 labelCount = sizeof(labels) / sizeof(BString);
fMaxLabelWidth = _MaxLineWidth(labels, labelCount, bold);
fNoFileLabelWidth = ceilf(bold.StringWidth(NO_FILE_LABEL));
InvalidateLayout();
}
@ -107,89 +155,77 @@ MediaFileInfoView::Update(BMediaFile* file, entry_ref* ref)
else
fRef = entry_ref();
fInfo.LoadInfo(file);
InvalidateLayout();
Invalidate();
}
// #pragma mark -
void
MediaFileInfoView::_GetFileInfo(BString* audioFormat, BString* videoFormat,
BString* audioDetails, BString* videoDetails, BString* duration)
float
MediaFileInfoView::_LineHeight()
{
fDuration = 0;
if (fMediaFile == NULL)
return;
BMediaTrack* track;
media_format format;
memset(&format, 0, sizeof(format));
media_codec_info codecInfo;
bool audioDone(false), videoDone(false);
bigtime_t audioDuration = 0;
bigtime_t videoDuration = 0;
int32 tracks = fMediaFile->CountTracks();
int64 videoFrames = 0;
int64 audioFrames = 0;
for (int32 i = 0; i < tracks && (!audioDone || !videoDone); i++) {
track = fMediaFile->TrackAt(i);
if (track != NULL) {
track->EncodedFormat(&format);
if (format.IsVideo()) {
memset(&format, 0, sizeof(format));
format.type = B_MEDIA_RAW_VIDEO;
track->DecodedFormat(&format);
media_raw_video_format *rvf = &(format.u.raw_video);
track->GetCodecInfo(&codecInfo);
*videoFormat << codecInfo.pretty_name;
videoDuration = track->Duration();
videoFrames = track->CountFrames();
*videoDetails << (int32)format.Width() << "x" << (int32)format.Height()
<< " " << (int32)(rvf->field_rate / rvf->interlace)
<< " fps / " << videoFrames << " frames";
videoDone = true;
} else if (format.IsAudio()) {
memset(&format, 0, sizeof(format));
format.type = B_MEDIA_RAW_AUDIO;
track->DecodedFormat(&format);
media_raw_audio_format *raf = &(format.u.raw_audio);
char bytesPerSample = (char)(raf->format & 0xf);
if (bytesPerSample == 1) {
*audioDetails << "8 bit ";
} else if (bytesPerSample == 2) {
*audioDetails << "16 bit ";
} else {
*audioDetails << bytesPerSample << "byte ";
}
track->GetCodecInfo(&codecInfo);
*audioFormat << codecInfo.pretty_name;
audioDuration = track->Duration();
audioFrames = track->CountFrames();
*audioDetails << (float)(raf->frame_rate / 1000.0f) << " kHz";
if (raf->channel_count == 1) {
*audioDetails << " mono / ";
} else if (raf->channel_count == 2) {
*audioDetails << " stereo / ";
} else {
*audioDetails << (int32)raf->channel_count << " channel / " ;
}
*audioDetails << audioFrames << " frames";
audioDone = true;
}
fMediaFile->ReleaseTrack(track);
}
}
fDuration = MAX(audioDuration, videoDuration);
*duration << (int32)(fDuration / 1000000)
<< " seconds";
font_height fontHeight;
GetFontHeight(&fontHeight);
return ceilf(fontHeight.ascent + fontHeight.descent + fontHeight.leading);
}
float
MediaFileInfoView::_MaxLineWidth(BString* strings, int32 count,
const BFont& font)
{
float width = 0;
for (int32 i = 0; i < count; i++)
width = max_c(font.StringWidth(strings[i]), width);
return ceilf(width);
}
void
MediaFileInfoView::_ValidateMinMax()
{
if (fMinMaxValid)
return;
BFont font;
GetFont(&font);
BFont bold(font);
bold.SetFace(B_BOLD_FACE);
fMinSize.Set(0, 0);
if (fMediaFile == NULL) {
fMinSize.width = fNoFileLabelWidth + kSpacing * 2;
fMinSize.height = fLineHeight + kSpacing;
return;
}
fMinSize.height += fLineHeight + kSpacing + 1;
fMinSize.width = ceilf(bold.StringWidth(fRef.name));
BString strings[5] = {fInfo.audio.format, fInfo.audio.details,
fInfo.video.format, fInfo.video.details, fInfo.duration};
float maxInfoWidth = _MaxLineWidth(strings, 5, font);
fMinSize.width = max_c(fMinSize.width, fMaxLabelWidth
+ maxInfoWidth + kSpacing);
fMinSize.width += kSpacing;
fMinSize.height += fLineHeight * 5 + 2 * kSpacing;
// 5 lines of info, w/ spacing above and below (not between lines)
ResetLayoutInvalidation();
fMinMaxValid = true;
}
void
MediaFileInfoView::_SetFontFace(uint16 face)
{
BFont font;
font.SetFace(face);
SetFont(&font, B_FONT_FACE);
}

View File

@ -9,16 +9,26 @@
#include <Entry.h>
#include <View.h>
#include "MediaFileInfo.h"
class BMediaFile;
class BString;
class MediaFileInfoView : public BView {
public:
MediaFileInfoView(BRect frame,
uint32 resizingMode);
MediaFileInfoView();
virtual ~MediaFileInfoView();
virtual BSize MinSize();
virtual BSize MaxSize();
virtual BSize PreferredSize();
virtual BAlignment LayoutAlignment();
virtual void InvalidateLayout(bool children = false);
virtual void SetFont(const BFont* font,
uint32 mask = B_FONT_ALL);
protected:
virtual void Draw(BRect updateRect);
virtual void AttachedToWindow();
@ -26,18 +36,23 @@ class MediaFileInfoView : public BView {
public:
void Update(BMediaFile* file, entry_ref* ref);
bigtime_t Duration() const
{ return fDuration; }
{ return fInfo.useconds; }
private:
void _GetFileInfo(BString* audioFormat,
BString* videoFormat,
BString* audioDetails,
BString* videoDetails,
BString* duration);
void _ValidateMinMax();
float _MaxLineWidth(BString* strings,
int32 stringCount, const BFont& font);
float _LineHeight();
void _SetFontFace(uint16 face);
bool fMinMaxValid;
BSize fMinSize;
float fMaxLabelWidth;
float fNoFileLabelWidth;
float fLineHeight;
entry_ref fRef;
BMediaFile* fMediaFile;
bigtime_t fDuration;
MediaFileInfo fInfo;
};
#endif // MEDIA_FILE_INFO_VIEW_H

View File

@ -37,9 +37,10 @@ MediaFileListItem::~MediaFileListItem()
// #pragma mark - MediaFileListView
MediaFileListView::MediaFileListView(BRect frame, uint32 resizingMode)
: BListView(frame, "MediaFileListView", B_SINGLE_SELECTION_LIST, resizingMode,
B_WILL_DRAW | B_NAVIGABLE | B_FRAME_EVENTS)
MediaFileListView::MediaFileListView()
:
BListView("MediaFileListView", B_SINGLE_SELECTION_LIST, B_WILL_DRAW
| B_NAVIGABLE | B_FRAME_EVENTS)
{
fEnabled = true;
}

View File

@ -26,8 +26,7 @@ public:
class MediaFileListView : public BListView {
public:
MediaFileListView(BRect frame,
uint32 resizingMode);
MediaFileListView();
virtual ~MediaFileListView();
protected:

View File

@ -1,70 +0,0 @@
// Copyright 1999, Be Incorporated. All Rights Reserved.
// Copyright 2000-2004, Jun Suzuki. All Rights Reserved.
// Copyright 2007, Stephan Aßmus. All Rights Reserved.
// This file may be used under the terms of the Be Sample Code License.
#include "StatusView.h"
StatusView::StatusView(BRect frame, uint32 resizingMode)
: BView(frame, "StatusView", resizingMode,
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE)
, fStatusString(B_EMPTY_STRING)
{
frame.OffsetTo(0, 0);
fStatusRect = frame;
// TODO: bad!
BFont font;
GetFont(&font);
font.SetSize(12);
SetFont(&font);
}
StatusView::~StatusView()
{
}
void
StatusView::AttachedToWindow()
{
rgb_color c = Parent()->LowColor();
SetViewColor(c);
SetLowColor(c);
}
void
StatusView::Draw(BRect /*update*/)
{
// TODO: placement information should be cached here
// for better performance
font_height fh;
GetFontHeight(&fh);
DrawString(fStatusString.String(),
fStatusRect.LeftBottom() + BPoint(1, -fh.descent));
}
void
StatusView::MessageReceived(BMessage* message)
{
BView::MessageReceived(message);
}
void
StatusView::SetStatus(const char* text)
{
fStatusString.SetTo(text);
Invalidate();
}
const char*
StatusView::Status()
{
return fStatusString.String();
}

View File

@ -1,35 +0,0 @@
// Copyright 1999, Be Incorporated. All Rights Reserved.
// Copyright 2000-2004, Jun Suzuki. All Rights Reserved.
// Copyright 2007, Stephan Aßmus. All Rights Reserved.
// This file may be used under the terms of the Be Sample Code License.
#ifndef STATUS_VIEW_H
#define STATUS_VIEW_H
#include <String.h>
#include <View.h>
class StatusView : public BView {
public:
StatusView(BRect frame,
uint32 resizingMode);
virtual ~StatusView();
protected:
virtual void AttachedToWindow();
virtual void Draw(BRect update);
virtual void MessageReceived(BMessage* message);
public:
void SetStatus(const char* text);
const char* Status();
private:
BRect fStatusRect;
BString fStatusString;
};
#endif // STATUS_VIEW_H