diff --git a/src/apps/mediaplayer/Controller.h b/src/apps/mediaplayer/Controller.h index 05a7623194..9774680b41 100644 --- a/src/apps/mediaplayer/Controller.h +++ b/src/apps/mediaplayer/Controller.h @@ -92,6 +92,7 @@ private: void StopThreads(); private: + friend class InfoWin; enum { MAX_AUDIO_BUFFERS = 8, diff --git a/src/apps/mediaplayer/InfoWin.cpp b/src/apps/mediaplayer/InfoWin.cpp new file mode 100644 index 0000000000..8dea492d88 --- /dev/null +++ b/src/apps/mediaplayer/InfoWin.cpp @@ -0,0 +1,410 @@ +/* + * InfoWin.cpp - Media Player for the Haiku Operating System + * + * Copyright (C) 2006 Marcus Overhagen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#include "InfoWin.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "MainWin.h" + +#define NAME "File Info" +#define MIN_WIDTH 350 + +#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 }; + + +// should later draw an icon +class InfoView : public BView { +public: + InfoView(BRect frame, const char *name, float divider) + : BView(frame, name, B_FOLLOW_ALL, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE) + , fDivider(divider) + { } + virtual ~InfoView() + { } + void Draw(BRect updateRect); + float fDivider; +}; + + +void +InfoView::Draw(BRect updateRect) +{ + SetHighColor(kGreen); + BRect r(Bounds()); + r.right = r.left + fDivider; + FillRect(r); + SetHighColor(ui_color(B_DOCUMENT_TEXT_COLOR)); + r.left = r.right; + FillRect(r); +} + + +InfoWin::InfoWin(MainWin *mainWin) + : BWindow(BRect(100,100,100+MIN_WIDTH-1,350), NAME, B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_NOT_RESIZABLE /* | B_WILL_ACCEPT_FIRST_CLICK */), + fMainWin(mainWin), + fController() +{ + BRect rect; + if (fMainWin->Lock()) { + rect = fMainWin->Frame(); + MoveTo(rect.right, rect.top); + fMainWin->Unlock(); + } + + rect = Bounds(); + + // accomodate for big fonts + float div; + div = MAX(2*32, be_plain_font->StringWidth("Container") + 5); + + fInfoView = new InfoView(rect, "background", div); + fInfoView->SetViewColor(ui_color(B_DOCUMENT_BACKGROUND_COLOR)); + AddChild(fInfoView); + + BFont bigFont(be_plain_font); + bigFont.SetSize(bigFont.Size()+6); + font_height fh; + bigFont.GetHeight(&fh); + fFilenameView = new BStringView(BRect(div+10, 20, + rect.right - 10, + 20 + fh.ascent + 5), + "filename", "Foo.avi"); + fFilenameView->SetFont(&bigFont); + fFilenameView->SetViewColor(fInfoView->ViewColor()); + fFilenameView->SetLowColor(fInfoView->ViewColor()); + AddChild(fFilenameView); + + + rect.top = BASE_HEIGHT; + + BRect lr(rect); + BRect cr(rect); + lr.right = div - 1; + cr.left = div + 1; + BRect tr; + tr = lr.OffsetToCopy(0,0).InsetByCopy(1,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(1,1); + fContentsView = new BTextView(cr, "contents", tr, B_FOLLOW_BOTTOM); + fContentsView->SetWordWrap(false); + AddChild(fContentsView); + + fLabelsView->MakeSelectable(); + fContentsView->MakeSelectable(); + + + Show(); +} + + +InfoWin::~InfoWin() +{ + printf("InfoWin::~InfoWin\n"); + //fInfoListView->MakeEmpty(); + //delete [] fInfoItems; +} + + +void +InfoWin::ResizeToPreferred() +{ +#if 0 + int i; + float height = BASE_HEIGHT; + BListItem *li; + for (i = 0; (li = fInfoListView->ItemAt(i)); i++) { + height += li->Height(); + } + ResizeTo(Bounds().Width(), height); +#endif +} + + +void +InfoWin::Update(uint32 which) +{ + printf("InfoWin::Update(0x%08lx)\n", which); + rgb_color vFgCol = ui_color(B_DOCUMENT_TEXT_COLOR); + + fLabelsView->SelectAll(); + fContentsView->SelectAll(); + fLabelsView->Clear(); + fContentsView->Clear(); + fLabelsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kBlue); + fLabelsView->Insert("File Info\n"); + fContentsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &vFgCol); + fContentsView->Insert("\n"); + + fLabelsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &kRed); + //fContentsView->SetFontAndColor(be_plain_font, B_FONT_ALL, &vFgCol); + + // lock the Main Window as we must access some fields there... + if (fMainWin->LockWithTimeout(500000) < B_OK) + return; // XXX: resend msg to ourselves ? + + Controller *c = fMainWin->fController; + BMediaFile *mf = c->fMediaFile; + + if (which & INFO_VIDEO && c->VideoTrackCount() > 0) { + fLabelsView->Insert("Video\n\n"); + BString s; + media_format fmt; + media_raw_video_format vfmt; + float fps; + c->fVideoTrack->EncodedFormat(&fmt); + if (fmt.type == B_MEDIA_ENCODED_VIDEO) { + vfmt = fmt.u.encoded_video.output; + s << "(encoded video)"; // TODO: get codec + } else if (fmt.type == B_MEDIA_RAW_VIDEO) { + vfmt = fmt.u.raw_video; + s << "raw video"; + } else + s << "unknown format"; + s << "\n"; + s << fmt.Width() << " x " << fmt.Height(); + // encoded has output as 1st field... + fps = vfmt.field_rate; + s << ", " << fps << " fps"; + s << "\n"; + fContentsView->Insert(s.String()); + } + if (which & INFO_AUDIO && c->AudioTrackCount() > 0) { + fLabelsView->Insert("Sound\n\n"); + BString s; + media_format fmt; + media_raw_audio_format afmt; + c->fAudioTrack->EncodedFormat(&fmt); + if (fmt.type == B_MEDIA_ENCODED_AUDIO) { + afmt = fmt.u.encoded_audio.output; + s << "(encoded audio)"; // TODO: get codec + } else if (fmt.type == B_MEDIA_RAW_AUDIO) { + afmt = fmt.u.raw_audio; + s << "raw audio"; + } else + s << "unknown format"; + s << "\n"; + // encoded has output as 1st field... + uint32 bitps = 8 * afmt.format & media_raw_audio_format::B_AUDIO_SIZE_MASK; + uint32 chans = afmt.channel_count; + float sr = afmt.frame_rate; + + s << bitps << "Bit "; + if (chans == 1) + s << "Mono"; + else if (chans == 2) + s << "Stereo"; + else + s << chans << "Channels"; + s << ", "; + if (sr) + s << (1/sr); + else + s << "?"; + s<< " kHz"; + s << "\n"; + fContentsView->Insert(s.String()); + } + if (which & INFO_STATS) { + fLabelsView->Insert("Duration\n"); + BString s; + bigtime_t d = c->Duration(); + bigtime_t v; + + //s << d << "µs; "; + + d /= 1000; + + v = d / (3600 * 1000); + d = d % (3600 * 1000); + if (v) + s << v << ":"; + v = d / (60 * 1000); + d = d % (60 * 1000); + s << v << ":"; + v = d / 1000; + d = d % 1000; + s << v; + if (d) + s << "." << d / 10; + s << "\n"; + fContentsView->Insert(s.String()); + } + if (which & INFO_TRANSPORT) { + } + if ((which & INFO_FILE) && fMainWin->fHasFile) { + media_file_format ff; + if (mf && (mf->GetFileFormatInfo(&ff) == B_OK)) { + fLabelsView->Insert("Container\n"); + BString s; + s << ff.pretty_name; + s << "\n"; + fContentsView->Insert(s.String()); + } + fLabelsView->Insert("Location\n"); + fContentsView->Insert("file://\n"); + fFilenameView->SetText("Bar.avi"); + } + if (which & INFO_COPYRIGHT && mf && mf->Copyright()) { + + fLabelsView->Insert("Copyright\n\n"); + BString s; + s << mf->Copyright(); + s << "\n\n"; + fContentsView->Insert(s.String()); + } + + // we can unlock the main window now and let it work + fMainWin->Unlock(); + + // now resize the window to the list view size... + ResizeToPreferred(); + + if (IsHidden()) + Show(); +} + + +bool +InfoWin::QuitRequested() +{ + Hide(); + return false; +} + + +void +InfoWin::Show() +{ + // notify the main window first + fMainWin->fInfoWinShowing = true; + BWindow::Show(); + //SetPulseRate(1000000); +} + + +void +InfoWin::Hide() +{ + SetPulseRate(0); + BWindow::Hide(); + fMainWin->fInfoWinShowing = false; +} + + +void +InfoWin::Pulse() +{ + if (IsHidden()) + return; + Update(INFO_STATS); +} + +void +InfoWin::FrameResized(float new_width, float new_height) +{ +#if 0 + if (new_width != Bounds().Width() || new_height != Bounds().Height()) { + debugger("size wrong\n"); + } + + bool no_menu = fNoMenu || fIsFullscreen; + bool no_controls = fNoControls || fIsFullscreen; + + printf("FrameResized enter: new_width %.0f, new_height %.0f\n", new_width, new_height); + + int max_video_width = int(new_width) + 1; + int max_video_height = int(new_height) + 1 - (no_menu ? 0 : fMenuBarHeight) - (no_controls ? 0 : fControlsHeight); + + ASSERT(max_video_height >= 0); + + int y = 0; + + if (no_menu) { + if (!fMenuBar->IsHidden()) + fMenuBar->Hide(); + } else { +// fMenuBar->MoveTo(0, y); + fMenuBar->ResizeTo(new_width, fMenuBarHeight - 1); + if (fMenuBar->IsHidden()) + fMenuBar->Show(); + y += fMenuBarHeight; + } + + if (max_video_height == 0) { + if (!fVideoView->IsHidden()) + fVideoView->Hide(); + } else { +// fVideoView->MoveTo(0, y); +// fVideoView->ResizeTo(max_video_width - 1, max_video_height - 1); + ResizeVideoView(0, y, max_video_width, max_video_height); + if (fVideoView->IsHidden()) + fVideoView->Show(); + y += max_video_height; + } + + if (no_controls) { + if (!fControls->IsHidden()) + fControls->Hide(); + } else { + fControls->MoveTo(0, y); + fControls->ResizeTo(new_width, fControlsHeight - 1); + if (fControls->IsHidden()) + fControls->Show(); +// y += fControlsHeight; + } +#endif + + printf("FrameResized leave\n"); +} + + +void +InfoWin::MessageReceived(BMessage *msg) +{ + uint32 which; + switch (msg->what) { + case M_UPDATE_INFO: + if (msg->FindInt32("which", (int32 *)&which) < B_OK) + which = INFO_ALL; + Update(which); + break; + default: + BWindow::MessageReceived(msg); + break; + } +} diff --git a/src/apps/mediaplayer/InfoWin.h b/src/apps/mediaplayer/InfoWin.h new file mode 100644 index 0000000000..818f9b22d5 --- /dev/null +++ b/src/apps/mediaplayer/InfoWin.h @@ -0,0 +1,69 @@ +/* + * MainWin.h - Media Player for the Haiku Operating System + * + * Copyright (C) 2006 Marcus Overhagen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#ifndef __FILE_INFO_WIN_H +#define __FILE_INFO_WIN_H + +#include +#include +#include + +class MainWin; +class Controller; +class InfoView; + +#define M_UPDATE_INFO 'upda' + +#define INFO_STATS 0x00000001 +#define INFO_TRANSPORT 0x00000002 +#define INFO_FILE 0x00000004 +#define INFO_AUDIO 0x00000008 +#define INFO_VIDEO 0x00000010 +#define INFO_COPYRIGHT 0x00000020 + +#define INFO_ALL 0xffffffff + + +class InfoWin : public BWindow +{ +public: + InfoWin(MainWin *mainWin); + ~InfoWin(); + + void FrameResized(float new_width, float new_height); + void MessageReceived(BMessage *msg); + bool QuitRequested(); + virtual void Show(); + virtual void Hide(); + virtual void Pulse(); + + void ResizeToPreferred(); + void Update(uint32 which=INFO_ALL); // threadsafe + + MainWin * fMainWin; + Controller * fController; + + InfoView * fInfoView; + BStringView * fFilenameView; + BTextView * fLabelsView; + BTextView * fContentsView; + +}; + +#endif diff --git a/src/apps/mediaplayer/Jamfile b/src/apps/mediaplayer/Jamfile index 0de2f677f7..34e072044f 100644 --- a/src/apps/mediaplayer/Jamfile +++ b/src/apps/mediaplayer/Jamfile @@ -8,6 +8,7 @@ Application MediaPlayer : Controller.cpp ControllerView.cpp DrawingTidbits.cpp + InfoWin.cpp MainApp.cpp MainWin.cpp Playlist.cpp diff --git a/src/apps/mediaplayer/MainWin.cpp b/src/apps/mediaplayer/MainWin.cpp index 216cfbbb14..cd678a4810 100644 --- a/src/apps/mediaplayer/MainWin.cpp +++ b/src/apps/mediaplayer/MainWin.cpp @@ -87,6 +87,8 @@ enum MainWin::MainWin() : BWindow(BRect(100,100,350,300), NAME, B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS /* | B_WILL_ACCEPT_FIRST_CLICK */) , fFilePanel(NULL) + , fInfoWin(NULL) + , fInfoWinShowing(false) , fHasFile(false) , fHasVideo(false) , fPlaylist(new Playlist) @@ -159,6 +161,10 @@ MainWin::~MainWin() delete fPlaylist; delete fController; delete fFilePanel; + if (fInfoWin) { + fInfoWin->Lock(); + fInfoWin->Quit(); + } } @@ -189,7 +195,7 @@ MainWin::SetupWindow() { printf("MainWin::SetupWindow\n"); - // Pupulate the track menus + // Populate the track menus SetupTrackMenus(); // Enable both if a file was loaded fAudioMenu->SetEnabled(fHasFile); @@ -212,6 +218,8 @@ MainWin::SetupWindow() ResizeWindow(100); fVideoView->MakeFocus(); + + MaybeUpdateFileInfo(); } @@ -582,8 +590,26 @@ MainWin::FrameResized(float new_width, float new_height) void MainWin::ShowFileInfo() { + if (!fInfoWin) + fInfoWin = new InfoWin(this); + BMessenger msgr(fInfoWin); + BMessage m(M_UPDATE_INFO); + m.AddInt32("which", INFO_ALL); + msgr.SendMessage(&m); + msgr.SendMessage(B_WINDOW_ACTIVATED); } +void +MainWin::MaybeUpdateFileInfo(uint32 which) +{ + // Update the Info Window if it's displayed. + if (!fInfoWinShowing) + return; + BMessenger msgr(fInfoWin); + BMessage m(M_UPDATE_INFO); + m.AddInt32("which", which); + msgr.SendMessage(&m); +} void MainWin::ResizeVideoView(int x, int y, int width, int height) @@ -1149,6 +1175,9 @@ MainWin::MessageReceived(BMessage *msg) SelectInterface(msg->what - M_SELECT_INTERFACE - 1); break; } -*/ +*/ + default: + // let BWindow handle the rest + BWindow::MessageReceived(msg); } } diff --git a/src/apps/mediaplayer/MainWin.h b/src/apps/mediaplayer/MainWin.h index 4e5b106c8a..f6f880fea6 100644 --- a/src/apps/mediaplayer/MainWin.h +++ b/src/apps/mediaplayer/MainWin.h @@ -27,6 +27,7 @@ #include #include "Controller.h" #include "ControllerView.h" +#include "InfoWin.h" #include "VideoView.h" #include "Player.h" #include "Playlist.h" @@ -57,6 +58,7 @@ public: void ResizeVideoView(int x, int y, int width, int height); void ShowFileInfo(); + void MaybeUpdateFileInfo(uint32 which=INFO_ALL); // from Player void OpenFile(const entry_ref &ref); @@ -78,6 +80,8 @@ public: VideoView * fVideoView; BFilePanel * fFilePanel; ControllerView * fControls; + InfoWin * fInfoWin; + bool fInfoWinShowing; BMenu * fFileMenu; BMenu * fViewMenu;