Commit 4a9a8422 authored by Tony Castley's avatar Tony Castley

src/misc/beos_specific.cpp:

- Implemented VlcApplication::RefsReceived()
- this added ability to open a file by dropping its icon onto the vlc icon
- this makes Open With... work as well
plugins/beos/intf_beos.cpp
- A message is sent to be_app when the interface is created
	(needed to support BApplication::RefsReceived())
plugins/beos/vout_beos.cpp
- reacts on Escape and Tab key to switch fullscreen/window mode
- blanks cursor when no activity
- Fixed a memory leak in VideoWindow::ScreenChanged()
- Fixed the ugly scrambled video content before any decoding actually begins
- Added selectable aspect ratio correction
- Added better error handling when setting the drawing mode
plugins/beos/InterfaceWindow.h/.cpp
- Implemented dynamic view layout
- Fixed crashes in MessageReceived() when no file was loaded
- Implemented disabling of menus when no file is loaded
- Added "Speed" menu
- Added ability to enable navigation menu items according to features of current stream
- Cleaned up code somewhat
- Changed parts of LanguageMenu::GetChannels() to show more user friendly and no invalid entries
- better support for muting and volume info
- better support for scrubbing and detection of stopped stream
plugins/beos/MediaControlView.h/.cpp
- Added dynamic layout of elements
- Exchanged rewind/fastforward buttons for skip buttons that skip to the next chapter if stream supports it.
- made nicer looking SeekSlider similar to BeOS MediaPlayer
- made VolumeSlider similar to BeOS MediaPlayer, plus additional features that one doesn't have (muted state)
- got rid of MediaSlider (no need for it anymore)
- detection of stopped stream
plugins/beos/Bitmaps.h
- Added bitmaps for VolumeSlider
plugins/beos/intf_vlc_wrapper.h/.cpp
- added set_volume() and is_muted() functions
- fixed a bug in toggle_muted()
parent a25aaff5
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -2,9 +2,10 @@
* DrawingTidbits.cpp
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: DrawingTidbits.cpp,v 1.2 2001/03/21 13:42:33 sam Exp $
* $Id: DrawingTidbits.cpp,v 1.2.4.1 2002/09/03 12:00:24 tcastley Exp $
*
* Authors: Tony Castley <tcastley@mail.powerup.com.au>
* Stephan Aßmus <stippi@yellowbites.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -27,6 +28,7 @@
#include "DrawingTidbits.h"
// ShiftComponent
inline uchar
ShiftComponent(uchar component, float percent)
{
......@@ -38,6 +40,7 @@ ShiftComponent(uchar component, float percent)
return (uchar)(255 - percent * (255 - component));
}
// ShiftColor
rgb_color
ShiftColor(rgb_color color, float percent)
{
......@@ -51,6 +54,7 @@ ShiftColor(rgb_color color, float percent)
return result;
}
// CompareColors
static bool
CompareColors(const rgb_color a, const rgb_color b)
{
......@@ -60,18 +64,21 @@ CompareColors(const rgb_color a, const rgb_color b)
&& a.alpha == b.alpha;
}
bool
// ==
bool
operator==(const rgb_color &a, const rgb_color &b)
{
return CompareColors(a, b);
}
bool
// !=
bool
operator!=(const rgb_color &a, const rgb_color &b)
{
return !CompareColors(a, b);
}
// ReplaceColor
void
ReplaceColor(BBitmap *bitmap, rgb_color from, rgb_color to)
{
......@@ -88,6 +95,7 @@ ReplaceColor(BBitmap *bitmap, rgb_color from, rgb_color to)
bits[index] = toIndex;
}
// ReplaceTransparentColor
void
ReplaceTransparentColor(BBitmap *bitmap, rgb_color with)
{
......@@ -103,3 +111,180 @@ ReplaceTransparentColor(BBitmap *bitmap, rgb_color with)
bits[index] = withIndex;
}
// convert_bitmap
status_t
convert_bitmap(BBitmap* inBitmap, BBitmap* outBitmap)
{
status_t status = B_BAD_VALUE;
/* // see that we got valid bitmaps
if (inBitmap && inBitmap->IsValid()
&& outBitmap && outBitmap->IsValid())
{
status = B_MISMATCHED_VALUES;
// see that bitmaps are compatible and that we support the conversion
if (inBitmap->Bounds().Width() == outBitmap->Bounds().Width()
&& inBitmap->Bounds().Height() == outBitmap->Bounds().Height()
&& (outBitmap->ColorSpace() == B_RGB32
|| outBitmap->ColorSpace() == B_RGBA32))
{
int32 width = inBitmap->Bounds().IntegerWidth() + 1;
int32 height = inBitmap->Bounds().IntegerHeight() + 1;
int32 srcBpr = inBitmap->BytesPerRow();
int32 dstBpr = outBitmap->BytesPerRow();
uint8* srcbits = (uint8*)inbitmap->bits();
uint8* dstbits = (uint8*)outbitmap->bits();
switch (inBitmap->ColorSpace())
{
case B_YCbCr422:
for (int32 y = 0; y < height; y ++)
{
for (int32 x = 0; x < width; x += 2)
{
uint8 y =
uint8 cb =
uint8 cr =
}
srcbits += srcBpr;
dstbits += dstBpr;
}
status = B_OK;
break;
case B_YCbCr420:
status = B_OK;
break;
case B_YUV422:
status = B_OK;
break;
case B_RGB32:
memcpy(dstBits, srcBits, inBitmap->BitsLength());
status = B_OK;
break;
default:
status = B_MISMATCHED_VALUES;
break;
}
}
}*/
return status;
}
// clip_float
inline uint8
clip_float(float value)
{
if (value < 0)
value = 0;
if (value > 255)
value = 255;
return (uint8)value;
}
// dim_bitmap
status_t
dim_bitmap(BBitmap* bitmap, rgb_color center, float dimLevel)
{
status_t status = B_BAD_VALUE;
if (bitmap && bitmap->IsValid())
{
switch (bitmap->ColorSpace())
{
case B_CMAP8:
{
BScreen screen(B_MAIN_SCREEN_ID);
if (screen.IsValid())
{
// iterate over each pixel, get the respective
// color from the screen object, find the distance
// to the "center" color and shorten the distance
// by "dimLevel"
int32 length = bitmap->BitsLength();
uint8* bits = (uint8*)bitmap->Bits();
for (int32 i = 0; i < length; i++)
{
// preserve transparent pixels
if (bits[i] != B_TRANSPARENT_MAGIC_CMAP8)
{
// get color for this index
rgb_color c = screen.ColorForIndex(bits[i]);
// red
float dist = (c.red - center.red) * dimLevel;
c.red = clip_float(center.red + dist);
// green
dist = (c.green - center.green) * dimLevel;
c.green = clip_float(center.green + dist);
// blue
dist = (c.blue - center.blue) * dimLevel;
c.blue = clip_float(center.blue + dist);
// write correct index of the dimmed color
// back into bitmap (and hope the match is close...)
bits[i] = screen.IndexForColor(c);
}
}
status = B_OK;
}
break;
}
case B_RGB32:
case B_RGBA32:
{
// iterate over each color component, find the distance
// to the "center" color and shorten the distance
// by "dimLevel"
uint8* bits = (uint8*)bitmap->Bits();
int32 bpr = bitmap->BytesPerRow();
int32 pixels = bitmap->Bounds().IntegerWidth() + 1;
int32 lines = bitmap->Bounds().IntegerHeight() + 1;
// iterate over color components
for (int32 y = 0; y < lines; y++) {
for (int32 x = 0; x < pixels; x++) {
int32 offset = 4 * x; // four bytes per pixel
// blue
float dist = (bits[offset + 0] - center.blue) * dimLevel;
bits[offset + 0] = clip_float(center.blue + dist);
// green
dist = (bits[offset + 1] - center.green) * dimLevel;
bits[offset + 1] = clip_float(center.green + dist);
// red
dist = (bits[offset + 2] - center.red) * dimLevel;
bits[offset + 2] = clip_float(center.red + dist);
// ignore alpha channel
}
// next line
bits += bpr;
}
status = B_OK;
break;
}
default:
status = B_ERROR;
break;
}
}
return status;
}
// dimmed_color_cmap8
rgb_color
dimmed_color_cmap8(rgb_color color, rgb_color center, float dimLevel)
{
BScreen screen(B_MAIN_SCREEN_ID);
if (screen.IsValid())
{
// red
float dist = (color.red - center.red) * dimLevel;
color.red = clip_float(center.red + dist);
// green
dist = (color.green - center.green) * dimLevel;
color.green = clip_float(center.green + dist);
// blue
dist = (color.blue - center.blue) * dimLevel;
color.blue = clip_float(center.blue + dist);
// get color index for dimmed color
int32 index = screen.IndexForColor(color);
// put color at index (closest match in palette
// to dimmed result) into returned color
color = screen.ColorForIndex(index);
}
return color;
}
......@@ -2,9 +2,10 @@
* DrawingTidbits.h
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: DrawingTidbits.h,v 1.2 2001/03/21 13:42:33 sam Exp $
* $Id: DrawingTidbits.h,v 1.2.4.1 2002/09/03 12:00:25 tcastley Exp $
*
* Authors: Tony Castley <tcastley@mail.powerup.com.au>
* Stephan Aßmus <stippi@yellowbites.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -51,5 +52,28 @@ const float kDimLevel = 0.6;
void ReplaceColor(BBitmap *bitmap, rgb_color from, rgb_color to);
void ReplaceTransparentColor(BBitmap *bitmap, rgb_color with);
// bitmaps need to be the same size, or this function will fail
// currently supported conversions:
// B_YCbCr422 -> B_RGB32
// B_YCbCr420 -> B_RGB32
// B_YUV422 -> B_RGB32
// B_RGB32 -> B_RGB32
//status_t convert_bitmap(BBitmap* inBitmap, BBitmap* outBitmap);
#endif
// dims bitmap (in place) by finding the distance of
// the color at each pixel to the provided "center" color
// and shortens that distance by dimLevel
// (dimLevel < 1 -> less contrast)
// (dimLevel > 1 -> more contrast)
// (dimLevel < 0 -> inverted colors)
// currently supported colorspaces:
// B_RGB32
// B_RGBA32
// B_CMAP8
status_t dim_bitmap(BBitmap* bitmap, rgb_color center,
float dimLevel);
rgb_color dimmed_color_cmap8(rgb_color color, rgb_color center,
float dimLevel);
#endif // __DRAWING_TIBITS__
......@@ -2,12 +2,13 @@
* InterfaceWindow.cpp: beos interface
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: InterfaceWindow.cpp,v 1.16.2.2 2002/07/13 11:33:11 tcastley Exp $
* $Id: InterfaceWindow.cpp,v 1.16.2.3 2002/09/03 12:00:24 tcastley Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Tony Castley <tony@castley.net>
* Richard Shepherd <richard@rshepherd.demon.co.uk>
* Stephan Aßmus <stippi@yellowbites.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -58,6 +59,8 @@ extern "C"
#include "intf_vlc_wrapper.h"
#include "InterfaceWindow.h"
#define INTERFACE_UPDATE_TIMEOUT 80000 // 2 frames if at 25 fps
/*****************************************************************************
* InterfaceWindow
......@@ -65,90 +68,112 @@ extern "C"
InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
intf_thread_t *p_interface )
: BWindow( frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK
| B_ASYNCHRONOUS_CONTROLS )
: BWindow( frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK | B_ASYNCHRONOUS_CONTROLS ),
p_intf(p_interface),
b_empty_playlist(p_main->p_playlist->i_size < 0),
file_panel(NULL),
playlist_window(NULL),
fLastUpdateTime(system_time())
{
file_panel = NULL;
playlist_window = NULL;
p_intf = p_interface;
BRect controlRect(0,0,0,0);
b_empty_playlist = (p_main->p_playlist->i_size < 0);
/* set the title bar */
SetName( "interface" );
SetTitle(VOUT_TITLE);
/* set up the main menu */
BMenuBar *menu_bar;
menu_bar = new BMenuBar(controlRect, "main menu");
AddChild( menu_bar );
BMenu *mFile;
BMenu *mAudio;
CDMenu *cd_menu;
BMenu *mNavigation;
BMenu *mConfig;
// set the title bar
SetName( "interface" );
SetTitle(VOUT_TITLE);
// the media control view
p_mediaControl = new MediaControlView( BRect(0.0, 0.0, 250.0, 50.0) );
p_mediaControl->SetViewColor( ui_color(B_PANEL_BACKGROUND_COLOR) );
b_empty_playlist = true;
p_mediaControl->SetEnabled( !b_empty_playlist );
float width, height;
p_mediaControl->GetPreferredSize(&width, &height);
// set up the main menu
fMenuBar = new BMenuBar( BRect(0.0, 0.0, width, 15.0), "main menu",
B_FOLLOW_NONE, B_ITEMS_IN_ROW, false );
// make menu bar resize to correct height
float menuWidth, menuHeight;
fMenuBar->GetPreferredSize(&menuWidth, &menuHeight);
fMenuBar->ResizeTo(width, menuHeight); // don't change! it's a workarround!
// take care of proper size for ourself
height += fMenuBar->Bounds().Height();
ResizeTo(width, height);
p_mediaControl->MoveTo( fMenuBar->Bounds().LeftBottom() + BPoint(0.0, 1.0) );
AddChild( fMenuBar );
AddChild( p_mediaControl );
BMenu *fileMenu;
// BMenu *configMenu;
/* Add the file Menu */
BMenuItem *mItem;
menu_bar->AddItem( mFile = new BMenu( "File" ) );
menu_bar->ResizeToPreferred();
mFile->AddItem( mItem = new BMenuItem( "Open File" B_UTF8_ELLIPSIS,
// Add the file Menu
BMenuItem *mItem;
fMenuBar->AddItem( fileMenu = new BMenu( "File" ) );
fileMenu->AddItem( mItem = new BMenuItem( "Open File" B_UTF8_ELLIPSIS,
new BMessage(OPEN_FILE), 'O') );
cd_menu = new CDMenu( "Open Disc" );
mFile->AddItem( cd_menu );
fileMenu->AddItem( new CDMenu( "Open Disc" ) );
mFile->AddSeparatorItem();
mFile->AddItem( mItem = new BMenuItem( "Play List" B_UTF8_ELLIPSIS,
fileMenu->AddSeparatorItem();
fileMenu->AddItem( mItem = new BMenuItem( "Play List" B_UTF8_ELLIPSIS,
new BMessage(OPEN_PLAYLIST), 'P') );
mFile->AddSeparatorItem();
mFile->AddItem( mItem = new BMenuItem( "About" B_UTF8_ELLIPSIS,
fileMenu->AddSeparatorItem();
fileMenu->AddItem( mItem = new BMenuItem( "About" B_UTF8_ELLIPSIS,
new BMessage(B_ABOUT_REQUESTED), 'A') );
mItem->SetTarget( be_app );
mFile->AddItem(mItem = new BMenuItem( "Quit",
fileMenu->AddItem(mItem = new BMenuItem( "Quit",
new BMessage(B_QUIT_REQUESTED), 'Q') );
fLanguageMenu = new LanguageMenu("Language", AUDIO_ES, p_intf);
fSubtitlesMenu = new LanguageMenu("Subtitles", SPU_ES, p_intf);
/* Add the Audio menu */
menu_bar->AddItem ( mAudio = new BMenu( "Audio" ) );
menu_bar->ResizeToPreferred();
mAudio->AddItem( new LanguageMenu( "Language", AUDIO_ES, p_intf ) );
mAudio->AddItem( new LanguageMenu( "Subtitles", SPU_ES, p_intf ) );
fAudioMenu = new BMenu( "Audio" );
fMenuBar->AddItem ( fAudioMenu );
fAudioMenu->AddItem( fLanguageMenu );
fAudioMenu->AddItem( fSubtitlesMenu );
fPrevTitleMI = new BMenuItem("Prev Title", new BMessage(PREV_TITLE));
fNextTitleMI = new BMenuItem("Next Title", new BMessage(NEXT_TITLE));
fPrevChapterMI = new BMenuItem("Prev Chapter", new BMessage(PREV_CHAPTER));
fNextChapterMI = new BMenuItem("Next Chapter", new BMessage(NEXT_CHAPTER));
/* Add the Navigation menu */
menu_bar->AddItem( mNavigation = new BMenu( "Navigation" ) );
menu_bar->ResizeToPreferred();
mNavigation->AddItem( new BMenuItem( "Prev Title",
new BMessage(PREV_TITLE)) );
mNavigation->AddItem( new BMenuItem( "Next Title",
new BMessage(NEXT_TITLE)) );
mNavigation->AddItem( new BMenuItem( "Prev Chapter",
new BMessage(PREV_CHAPTER)) );
mNavigation->AddItem( new BMenuItem( "Next Chapter",
new BMessage(NEXT_CHAPTER)) );
fNavigationMenu = new BMenu( "Navigation" );
fMenuBar->AddItem( fNavigationMenu );
fNavigationMenu->AddItem(fPrevTitleMI);
fNavigationMenu->AddItem(fNextTitleMI);
fNavigationMenu->AddItem(fPrevChapterMI);
fNavigationMenu->AddItem(fNextChapterMI);
/* Add the Speed menu */
fSpeedMenu = new BMenu("Speed");
fSpeedMenu->SetRadioMode(true);
fSpeedMenu->AddItem( new BMenuItem( "Slow",
new BMessage(SLOWER_PLAY)) );
BMenuItem* normalSpeedItem = new BMenuItem( "Normal",
new BMessage(NORMAL_PLAY));
normalSpeedItem->SetMarked(true); // default to normal speed
fSpeedMenu->AddItem( normalSpeedItem );
fSpeedMenu->AddItem( new BMenuItem( "Fast",
new BMessage(FASTER_PLAY)) );
fSpeedMenu->SetTargetForItems(this);
fMenuBar->AddItem(fSpeedMenu);
/* Add the Config menu */
// menu_bar->AddItem( mConfig = new BMenu( "Config" ) );
// menu_bar->AddItem( configMenu = new BMenu( "Config" ) );
// menu_bar->ResizeToPreferred();
// mConfig->AddItem( miOnTop = new BMenuItem( "Always on Top",
// configMenu->AddItem( miOnTop = new BMenuItem( "Always on Top",
// new BMessage(TOGGLE_ON_TOP)) );
// miOnTop->SetMarked(false);
ResizeTo(260,50 + menu_bar->Bounds().IntegerHeight()+1);
controlRect = Bounds();
controlRect.top += menu_bar->Bounds().IntegerHeight() + 1;
p_mediaControl = new MediaControlView( controlRect );
p_mediaControl->SetViewColor( ui_color(B_PANEL_BACKGROUND_COLOR) );
b_empty_playlist = true;
p_mediaControl->SetEnabled( !b_empty_playlist );
/* Show */
AddChild( p_mediaControl );
_SetMenusEnabled(false);
Show();
}
InterfaceWindow::~InterfaceWindow()
......@@ -156,6 +181,20 @@ InterfaceWindow::~InterfaceWindow()
if (playlist_window) playlist_window->ReallyQuit();
}
/*****************************************************************************
* InterfaceWindow::FrameResized
*****************************************************************************/
void
InterfaceWindow::FrameResized(float width, float height)
{
BRect r(Bounds());
fMenuBar->MoveTo(r.LeftTop());
fMenuBar->ResizeTo(r.Width(), fMenuBar->Bounds().Height());
r.top += fMenuBar->Bounds().Height() + 1.0;
p_mediaControl->MoveTo(r.LeftTop());
p_mediaControl->ResizeTo(r.Width(), r.Height());
}
/*****************************************************************************
* InterfaceWindow::MessageReceived
*****************************************************************************/
......@@ -166,7 +205,7 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
int i_index;
BAlert *alert;
Activate();
// Activate(); // why ?!?
if (p_input_bank->pp_input[0])
{
playback_status = p_input_bank->pp_input[0]->stream.control.i_status;
......@@ -211,7 +250,7 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
{
const char *psz_device;
BString type("dvd");
if( p_message->FindString("device", &psz_device) != B_ERROR )
if( p_message->FindString("device", &psz_device) == B_OK )
{
BString device(psz_device);
Intf_VLCWrapper::openDisc(type, device, 0,0);
......@@ -223,10 +262,13 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
case STOP_PLAYBACK:
// this currently stops playback not nicely
Intf_VLCWrapper::volume_mute();
snooze( 400000 );
Intf_VLCWrapper::playlistStop();
p_mediaControl->SetStatus(NOT_STARTED_S,DEFAULT_RATE);
if (playback_status > UNDEF_S)
{
Intf_VLCWrapper::volume_mute();
snooze( 400000 );
Intf_VLCWrapper::playlistStop();
p_mediaControl->SetStatus(NOT_STARTED_S, DEFAULT_RATE);
}
break;
case START_PLAYBACK:
......@@ -234,7 +276,7 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
case PAUSE_PLAYBACK:
/* toggle between pause and play */
if( p_input_bank->pp_input[0] != NULL )
if (playback_status > UNDEF_S)
{
/* pause if currently playing */
if ( playback_status == PLAYING_S )
......@@ -258,16 +300,31 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
case FASTER_PLAY:
/* cycle the fast playback modes */
Intf_VLCWrapper::volume_mute();
snooze( 400000 );
Intf_VLCWrapper::playFaster();
if (playback_status > UNDEF_S)
{
Intf_VLCWrapper::volume_mute();
snooze( 400000 );
Intf_VLCWrapper::playFaster();
}
break;
case SLOWER_PLAY:
/* cycle the slow playback modes */
Intf_VLCWrapper::volume_mute();
snooze( 400000 );
Intf_VLCWrapper::playSlower();
if (playback_status > UNDEF_S)
{
Intf_VLCWrapper::volume_mute();
snooze( 400000 );
Intf_VLCWrapper::playSlower();
}
break;
case NORMAL_PLAY:
/* restore speed to normal if already playing */
if (playback_status > UNDEF_S)
{
Intf_VLCWrapper::volume_restore();
Intf_VLCWrapper::playlistPlay();
}
break;
case SEEK_PLAYBACK:
......@@ -276,27 +333,34 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
case VOLUME_CHG:
/* adjust the volume */
vlc_mutex_lock( &p_aout_bank->lock );
for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
if (playback_status > UNDEF_S)
{
if( p_aout_bank->pp_aout[i_index]->i_savedvolume )
{
p_aout_bank->pp_aout[i_index]->i_savedvolume = vol_val;
}
else
{
p_aout_bank->pp_aout[i_index]->i_volume = vol_val;
}
/* vlc_mutex_lock( &p_aout_bank->lock );
for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
{
if( p_aout_bank->pp_aout[i_index]->i_savedvolume )
{
p_aout_bank->pp_aout[i_index]->i_savedvolume = vol_val;
}
else
{
p_aout_bank->pp_aout[i_index]->i_volume = vol_val;
}
}
vlc_mutex_unlock( &p_aout_bank->lock );*/
Intf_VLCWrapper::set_volume( vol_val );
p_mediaControl->SetMuted( Intf_VLCWrapper::is_muted() );
}
vlc_mutex_unlock( &p_aout_bank->lock );
break;
case VOLUME_MUTE:
/* toggle muting */
Intf_VLCWrapper::toggle_mute();
p_mediaControl->SetMuted( Intf_VLCWrapper::is_muted() );
break;
case SELECT_CHANNEL:
if (playback_status > UNDEF_S)
{
int32 i = p_message->FindInt32( "channel" );
if ( i == -1 )
......@@ -312,6 +376,7 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
break;
case SELECT_SUBTITLE:
if (playback_status > UNDEF_S)
{
int32 i = p_message->FindInt32( "subtitle" );
if ( i == -1 )
......@@ -326,6 +391,7 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
}
break;
case PREV_TITLE:
if (playback_status > UNDEF_S)
{
int i_id;
i_id = p_input_bank->pp_input[0]->stream.p_selected_area->i_id - 1;
......@@ -338,6 +404,7 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
break;
}
case NEXT_TITLE:
if (playback_status > UNDEF_S)
{
int i_id;
......@@ -350,6 +417,7 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
}
break;
case PREV_CHAPTER:
if (playback_status > UNDEF_S)
{
int i_id;
......@@ -362,6 +430,7 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
}
break;
case NEXT_CHAPTER:
if (playback_status > UNDEF_S)
{
int i_id;
......@@ -397,6 +466,24 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
}
/*****************************************************************************
* InterfaceWindow::QuitRequested
*****************************************************************************/
bool InterfaceWindow::QuitRequested()
{
if (p_input_bank->pp_input[0])
{
Intf_VLCWrapper::volume_mute();
snooze( 400000 );
Intf_VLCWrapper::playlistStop();
p_mediaControl->SetStatus(NOT_STARTED_S, DEFAULT_RATE);
}
p_intf->b_die = 1;
return( true );
}
/*****************************************************************************
* InterfaceWindow::updateInterface
*****************************************************************************/
......@@ -407,18 +494,34 @@ void InterfaceWindow::updateInterface()
if ( acquire_sem(p_mediaControl->fScrubSem) == B_OK )
{
uint64 seekTo = (p_mediaControl->GetSeekTo() *
p_input_bank->pp_input[0]->stream.p_selected_area->i_size) / 100;
p_input_bank->pp_input[0]->stream.p_selected_area->i_size) / 2048;
input_Seek( p_input_bank->pp_input[0], seekTo);
}
else if( Lock() )
{
bool hasTitles = p_input_bank->pp_input[0]->stream.i_area_nb > 1;
bool hasChapters = p_input_bank->pp_input[0]->stream.p_selected_area->i_part_nb > 1;
p_mediaControl->SetStatus(p_input_bank->pp_input[0]->stream.control.i_status,
p_input_bank->pp_input[0]->stream.control.i_rate);
p_mediaControl->SetProgress(p_input_bank->pp_input[0]->stream.p_selected_area->i_tell,
p_input_bank->pp_input[0]->stream.p_selected_area->i_size);
_SetMenusEnabled(true, hasChapters, hasTitles);
bool canSkipBack = false;
bool canSkipForward = false;
if (hasChapters)
{
canSkipBack = p_input_bank->pp_input[0]->stream.p_selected_area->i_part > 0;
canSkipForward = p_input_bank->pp_input[0]->stream.p_selected_area->i_part <
p_input_bank->pp_input[0]->stream.p_selected_area->i_part_nb - 1;
}
p_mediaControl->SetSkippable(canSkipBack, canSkipForward);
p_mediaControl->SetMuted(Intf_VLCWrapper::is_muted());
Unlock();
}
}
else
_SetMenusEnabled(false);
if ( b_empty_playlist != (p_main->p_playlist->i_size < 1) )
{
if (Lock())
......@@ -428,16 +531,51 @@ void InterfaceWindow::updateInterface()
Unlock();
}
}
fLastUpdateTime = system_time();
}
/*****************************************************************************
* InterfaceWindow::QuitRequested
* InterfaceWindow::IsStopped
*****************************************************************************/
bool InterfaceWindow::QuitRequested()
bool
InterfaceWindow::IsStopped() const
{
p_intf->b_die = 1;
return (system_time() - fLastUpdateTime > INTERFACE_UPDATE_TIMEOUT);
}
return( true );
/*****************************************************************************
* InterfaceWindow::_SetMenusEnabled
*****************************************************************************/
void
InterfaceWindow::_SetMenusEnabled(bool hasFile, bool hasChapters, bool hasTitles)
{
if (!hasFile)
{
hasChapters = false;
hasTitles = false;
}
if (Lock())
{
if (fNextChapterMI->IsEnabled() != hasChapters)
fNextChapterMI->SetEnabled(hasChapters);
if (fPrevChapterMI->IsEnabled() != hasChapters)
fPrevChapterMI->SetEnabled(hasChapters);
if (fNextTitleMI->IsEnabled() != hasTitles)
fNextTitleMI->SetEnabled(hasTitles);
if (fPrevTitleMI->IsEnabled() != hasTitles)
fPrevTitleMI->SetEnabled(hasTitles);
if (fAudioMenu->IsEnabled() != hasFile)
fAudioMenu->SetEnabled(hasFile);
if (fNavigationMenu->IsEnabled() != hasFile)
fNavigationMenu->SetEnabled(hasFile);
if (fLanguageMenu->IsEnabled() != hasFile)
fLanguageMenu->SetEnabled(hasFile);
if (fSubtitlesMenu->IsEnabled() != hasFile)
fSubtitlesMenu->SetEnabled(hasFile);
if (fSpeedMenu->IsEnabled() != hasFile)
fSpeedMenu->SetEnabled(hasFile);
Unlock();
}
}
/*****************************************************************************
......@@ -460,7 +598,9 @@ CDMenu::~CDMenu()
*****************************************************************************/
void CDMenu::AttachedToWindow(void)
{
while (RemoveItem((long int)0) != NULL); // remove all items
// remove all items
while (BMenuItem* item = RemoveItem(0L))
delete item;
GetCD("/dev/disk");
BMenu::AttachedToWindow();
}
......@@ -542,10 +682,9 @@ LanguageMenu::~LanguageMenu()
*****************************************************************************/
void LanguageMenu::AttachedToWindow(void)
{
while( RemoveItem((long int)0) != NULL )
{
; // remove all items
}
// remove all items
while (BMenuItem* item = RemoveItem(0L))
delete item;
SetRadioMode(true);
GetChannels();
......@@ -560,30 +699,26 @@ int LanguageMenu::GetChannels()
char *psz_name;
bool b_active;
BMessage *msg;
BMenuItem *menu_item;
int i;
es_descriptor_t *p_es = NULL;
/* Insert the null */
if( kind == AUDIO_ES ) //audio
{
msg = new BMessage(SELECT_CHANNEL);
msg->AddInt32("channel", -1);
}
else
if( kind != AUDIO_ES ) //subtitle
{
msg = new BMessage(SELECT_SUBTITLE);
msg->AddInt32("subtitle", -1);
menu_item = new BMenuItem("None", msg);
AddItem(menu_item);
menu_item->SetMarked(true);
}
BMenuItem *menu_item;
menu_item = new BMenuItem("None", msg);
AddItem(menu_item);
menu_item->SetMarked(TRUE);
if( p_input_bank->pp_input[0] == NULL )
{
return 1;
}
int32 addedItems = 0;
vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );
for( i = 0; i < p_input_bank->pp_input[0]->stream.i_selected_es_number; i++ )
......@@ -598,6 +733,7 @@ int LanguageMenu::GetChannels()
{
if( kind == p_input_bank->pp_input[0]->stream.pp_es[i]->i_cat )
{
addedItems++;
psz_name = p_input_bank->pp_input[0]->stream.pp_es[i]->psz_desc;
if( kind == AUDIO_ES ) //audio
{
......@@ -610,6 +746,9 @@ int LanguageMenu::GetChannels()
msg->AddInt32("subtitle", i);
}
BMenuItem *menu_item;
// workarround for irritating empty strings
if (strcmp(psz_name, "") == 0)
psz_name = "Default";
menu_item = new BMenuItem(psz_name, msg);
AddItem(menu_item);
b_active = (p_es == p_input_bank->pp_input[0]->stream.pp_es[i]);
......@@ -618,6 +757,9 @@ int LanguageMenu::GetChannels()
}
vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );
// enhance readability and separate first item from rest
if (addedItems > 1)
AddItem(new BSeparatorItem(), 1);
}
......
......@@ -2,11 +2,12 @@
* InterfaceWindow.h: BeOS interface window class prototype
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: InterfaceWindow.h,v 1.12.2.2 2002/07/13 11:33:11 tcastley Exp $
* $Id: InterfaceWindow.h,v 1.12.2.3 2002/09/03 12:00:25 tcastley Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Tony Castley <tcastley@mail.powerup.com.au>
* Richard Shepherd <richard@rshepherd.demon.co.uk>
* Stephan Aßmus <stippi@yellowbites.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -22,55 +23,88 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef BEOS_INTERFACE_WINDOW_H
#define BEOS_INTERFACE_WINDOW_H
#include <Menu.h>
#include <Window.h>
class BMenuBar;
class MediaControlView;
class PlayListWindow;
class BFilePanel;
class CDMenu : public BMenu
{
public:
CDMenu(const char *name);
~CDMenu();
void AttachedToWindow(void);
private:
int GetCD(const char *directory);
public:
CDMenu(const char* name);
virtual ~CDMenu();
virtual void AttachedToWindow(void);
private:
int GetCD(const char* directory);
};
class LanguageMenu : public BMenu
{
public:
LanguageMenu(const char *name, int menu_kind,
intf_thread_t *p_interface);
~LanguageMenu();
void AttachedToWindow(void);
private:
intf_thread_t *p_intf;
int kind;
int GetChannels();
public:
LanguageMenu(const char* name,
int menu_kind,
intf_thread_t* p_interface);
virtual ~LanguageMenu();
virtual void AttachedToWindow(void);
private:
intf_thread_t* p_intf;
int kind;
int GetChannels();
};
class InterfaceWindow : public BWindow
{
public:
InterfaceWindow( BRect frame, const char *name,
intf_thread_t *p_interface );
~InterfaceWindow();
public:
InterfaceWindow(BRect frame,
const char* name,
intf_thread_t* p_interface);
virtual ~InterfaceWindow();
// standard window member
virtual void FrameResized(float width, float height);
virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
// standard window member
virtual bool QuitRequested();
virtual void MessageReceived(BMessage *message);
void updateInterface();
// InterfaceWindow
void updateInterface();
bool IsStopped() const;
MediaControlView *p_mediaControl;
MediaControlView* p_mediaControl;
private:
intf_thread_t *p_intf;
bool b_empty_playlist;
BFilePanel *file_panel;
PlayListWindow* playlist_window;
BMenuItem *miOnTop;
es_descriptor_t * p_audio_es;
es_descriptor_t * p_spu_es;
private:
void _SetMenusEnabled(bool hasFile,
bool hasChapters = false,
bool hasTitles = false);
intf_thread_t* p_intf;
bool b_empty_playlist;
BFilePanel* file_panel;
PlayListWindow* playlist_window;
BMenuItem* miOnTop;
es_descriptor_t* p_audio_es;
es_descriptor_t* p_spu_es;
BMenuBar* fMenuBar;
BMenuItem* fNextTitleMI;
BMenuItem* fPrevTitleMI;
BMenuItem* fNextChapterMI;
BMenuItem* fPrevChapterMI;
BMenu* fAudioMenu;
BMenu* fNavigationMenu;
BMenu* fLanguageMenu;
BMenu* fSubtitlesMenu;
BMenu* fSpeedMenu;
bigtime_t fLastUpdateTime;
};
#endif // BEOS_INTERFACE_WINDOW_H
......@@ -2,9 +2,10 @@
* MediaControlView.cpp: beos interface
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: MediaControlView.cpp,v 1.7.2.1 2002/07/13 11:33:11 tcastley Exp $
* $Id: MediaControlView.cpp,v 1.7.2.2 2002/09/03 12:00:24 tcastley Exp $
*
* Authors: Tony Castley <tony@castley.net>
* Stephan Aßmus <stippi@yellowbites.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -39,258 +40,1063 @@ extern "C"
}
/* BeOS interface headers */
#include "MsgVals.h"
#include "Bitmaps.h"
#include "DrawingTidbits.h"
#include "InterfaceWindow.h"
#include "MsgVals.h"
#include "TransportButton.h"
#include "MediaControlView.h"
#define BORDER_INSET 6.0
#define MIN_SPACE 4.0
#define SPEAKER_SLIDER_DIST 6.0
#define VOLUME_MIN_WIDTH 70.0
#define DIM_LEVEL 0.4
#define VOLUME_SLIDER_LAYOUT_WEIGHT 2.0
#define SEEK_SLIDER_KNOB_WIDTH 8.0
MediaControlView::MediaControlView( BRect frame )
: BBox( frame, NULL, B_FOLLOW_ALL, B_WILL_DRAW, B_PLAIN_BORDER )
// slider colors are hardcoded here, because that's just
// what they currently are within those bitmaps
const rgb_color kGreen = (rgb_color){ 152, 203, 152, 255 };
const rgb_color kGreenShadow = (rgb_color){ 102, 152, 102, 255 };
const rgb_color kBackground = (rgb_color){ 216, 216, 216, 255 };
const rgb_color kSeekGreen = (rgb_color){ 171, 221, 161, 255 };
const rgb_color kSeekGreenShadow = (rgb_color){ 144, 186, 136, 255 };
const rgb_color kSeekRed = (rgb_color){ 255, 0, 0, 255 };
const rgb_color kSeekRedLight = (rgb_color){ 255, 152, 152, 255 };
const rgb_color kSeekRedShadow = (rgb_color){ 178, 0, 0, 255 };
const char* kDisabledSeekMessage = "Drop files to play";
enum
{
float xStart = HORZ_SPACE;
float yStart = VERT_SPACE;
fScrubSem = B_ERROR;
BRect controlRect = BRect(xStart,yStart,
frame.Width() - (HORZ_SPACE * 2), 15);
MSG_REWIND = 'rwnd',
MSG_FORWARD = 'frwd',
MSG_SKIP_BACKWARDS = 'skpb',
MSG_SKIP_FORWARD = 'skpf',
};
// constructor
MediaControlView::MediaControlView(BRect frame)
: BBox(frame, NULL, B_FOLLOW_NONE, B_WILL_DRAW | B_FRAME_EVENTS | B_PULSE_NEEDED,
B_PLAIN_BORDER),
fScrubSem(B_ERROR),
fCurrentRate(DEFAULT_RATE),
fCurrentStatus(UNDEF_S),
fBottomControlHeight(0.0)
{
BRect frame(0.0, 0.0, 10.0, 10.0);
/* Seek Status */
rgb_color fill_color = {0,255,0};
p_seek = new SeekSlider(controlRect, this, 0, 100, B_TRIANGLE_THUMB);
p_seek->SetValue(0);
p_seek->UseFillColor(true, &fill_color);
AddChild( p_seek );
yStart += 15 + VERT_SPACE;
/* Buttons */
/* Slow play */
controlRect.SetLeftTop(BPoint(xStart, yStart));
controlRect.SetRightBottom(controlRect.LeftTop() + kSkipButtonSize);
xStart += kRewindBitmapWidth;
p_slow = new TransportButton(controlRect, B_EMPTY_STRING,
kSkipBackBitmapBits,
kPressedSkipBackBitmapBits,
kDisabledSkipBackBitmapBits,
new BMessage(SLOWER_PLAY));
AddChild( p_slow );
/* Play Pause */
controlRect.SetLeftTop(BPoint(xStart, yStart));
controlRect.SetRightBottom(controlRect.LeftTop() + kPlayButtonSize);
xStart += kPlayPauseBitmapWidth + 1.0;
p_play = new PlayPauseButton(controlRect, B_EMPTY_STRING,
kPlayButtonBitmapBits,
kPressedPlayButtonBitmapBits,
kDisabledPlayButtonBitmapBits,
kPlayingPlayButtonBitmapBits,
kPressedPlayingPlayButtonBitmapBits,
kPausedPlayButtonBitmapBits,
kPressedPausedPlayButtonBitmapBits,
new BMessage(START_PLAYBACK));
AddChild( p_play );
/* Fast Foward */
controlRect.SetLeftTop(BPoint(xStart, yStart));
controlRect.SetRightBottom(controlRect.LeftTop() + kSkipButtonSize);
xStart += kRewindBitmapWidth;
p_fast = new TransportButton(controlRect, B_EMPTY_STRING,
kSkipForwardBitmapBits,
kPressedSkipForwardBitmapBits,
kDisabledSkipForwardBitmapBits,
new BMessage(FASTER_PLAY));
AddChild( p_fast );
/* Stop */
controlRect.SetLeftTop(BPoint(xStart, yStart));
controlRect.SetRightBottom(controlRect.LeftTop() + kStopButtonSize);
xStart += kStopBitmapWidth;
p_stop = new TransportButton(controlRect, B_EMPTY_STRING,
kStopButtonBitmapBits,
kPressedStopButtonBitmapBits,
kDisabledStopButtonBitmapBits,
new BMessage(STOP_PLAYBACK));
AddChild( p_stop );
controlRect.SetLeftTop(BPoint(xStart + 5, yStart + 6));
controlRect.SetRightBottom(controlRect.LeftTop() + kSpeakerButtonSize);
xStart += kSpeakerIconBitmapWidth;
p_mute = new TransportButton(controlRect, B_EMPTY_STRING,
kSpeakerIconBits,
kPressedSpeakerIconBits,
kSpeakerIconBits,
new BMessage(VOLUME_MUTE));
AddChild( p_mute );
/* Volume Slider */
p_vol = new MediaSlider(BRect(xStart,20,255,30), new BMessage(VOLUME_CHG),
0, VOLUME_MAX);
p_vol->SetValue(VOLUME_DEFAULT);
p_vol->UseFillColor(true, &fill_color);
AddChild( p_vol );
// Seek Slider
fSeekSlider = new SeekSlider(frame, "seek slider", this, 0, 2047);
fSeekSlider->SetValue(0);
fSeekSlider->ResizeToPreferred();
AddChild( fSeekSlider );
// Buttons
// Skip Back
frame.SetRightBottom(kSkipButtonSize);
fBottomControlHeight = kRewindBitmapHeight - 1.0;
fSkipBack = new TransportButton(frame, B_EMPTY_STRING,
kSkipBackBitmapBits,
kPressedSkipBackBitmapBits,
kDisabledSkipBackBitmapBits,
new BMessage(MSG_SKIP_BACKWARDS));
AddChild( fSkipBack );
// Play Pause
frame.SetRightBottom(kPlayButtonSize);
if (fBottomControlHeight < kPlayPauseBitmapHeight - 1.0)
fBottomControlHeight = kPlayPauseBitmapHeight - 1.0;
fPlayPause = new PlayPauseButton(frame, B_EMPTY_STRING,
kPlayButtonBitmapBits,
kPressedPlayButtonBitmapBits,
kDisabledPlayButtonBitmapBits,
kPlayingPlayButtonBitmapBits,
kPressedPlayingPlayButtonBitmapBits,
kPausedPlayButtonBitmapBits,
kPressedPausedPlayButtonBitmapBits,
new BMessage(START_PLAYBACK));
AddChild( fPlayPause );
// Skip Foward
frame.SetRightBottom(kSkipButtonSize);
fSkipForward = new TransportButton(frame, B_EMPTY_STRING,
kSkipForwardBitmapBits,
kPressedSkipForwardBitmapBits,
kDisabledSkipForwardBitmapBits,
new BMessage(MSG_SKIP_FORWARD));
AddChild( fSkipForward );
// Forward
fForward = new TransportButton(frame, B_EMPTY_STRING,
kForwardBitmapBits,
kPressedForwardBitmapBits,
kDisabledForwardBitmapBits,
new BMessage(MSG_FORWARD));
// AddChild( fForward );
// Rewind
fRewind = new TransportButton(frame, B_EMPTY_STRING,
kRewindBitmapBits,
kPressedRewindBitmapBits,
kDisabledRewindBitmapBits,
new BMessage(MSG_REWIND));
// AddChild( fRewind );
// Stop
frame.SetRightBottom(kStopButtonSize);
if (fBottomControlHeight < kStopBitmapHeight - 1.0)
fBottomControlHeight = kStopBitmapHeight - 1.0;
fStop = new TransportButton(frame, B_EMPTY_STRING,
kStopButtonBitmapBits,
kPressedStopButtonBitmapBits,
kDisabledStopButtonBitmapBits,
new BMessage(STOP_PLAYBACK));
AddChild( fStop );
// Mute
frame.SetRightBottom(kSpeakerButtonSize);
if (fBottomControlHeight < kSpeakerIconBitmapHeight - 1.0)
fBottomControlHeight = kSpeakerIconBitmapHeight - 1.0;
fMute = new TransportButton(frame, B_EMPTY_STRING,
kSpeakerIconBits,
kPressedSpeakerIconBits,
kSpeakerIconBits,
new BMessage(VOLUME_MUTE));
AddChild( fMute );
// Volume Slider
fVolumeSlider = new VolumeSlider(BRect(0.0, 0.0, VOLUME_MIN_WIDTH,
kVolumeSliderBitmapHeight - 1.0),
"volume slider", 0, VOLUME_MAX,
new BMessage(VOLUME_CHG));
fVolumeSlider->SetValue(VOLUME_DEFAULT);
AddChild( fVolumeSlider );
}
// destructor
MediaControlView::~MediaControlView()
{
}
void MediaControlView::MessageReceived(BMessage *message)
// AttachedToWindow
void
MediaControlView::AttachedToWindow()
{
BView::MessageReceived(message);
// we are now a valid BHandler
fRewind->SetTarget(this);
fForward->SetTarget(this);
fSkipBack->SetTarget(this);
fSkipForward->SetTarget(this);
fVolumeSlider->SetTarget(Window());
BRect r(_MinFrame());
if (BMenuBar* menuBar = Window()->KeyMenuBar())
r.bottom += menuBar->Bounds().Height();
Window()->SetSizeLimits(r.Width(), r.Width() * 2.0, r.Height(), r.Height() * 2.0);
if (!Window()->Bounds().Contains(r))
Window()->ResizeTo(r.Width(), r.Height());
else
FrameResized(Bounds().Width(), Bounds().Height());
// get pulse message every two frames
Window()->SetPulseRate(80000);
}
void MediaControlView::SetProgress(uint64 seek, uint64 size)
// FrameResized
void
MediaControlView::FrameResized(float width, float height)
{
p_seek->SetPosition((float)seek/size);
BRect r(Bounds());
// make sure we don't leave dirty pixels
// (B_FULL_UPDATE_ON_RESIZE == annoying flicker -> this is smarter)
if (fOldBounds.Width() < r.Width())
Invalidate(BRect(fOldBounds.right, fOldBounds.top + 1.0,
fOldBounds.right, fOldBounds.bottom - 1.0));
else
Invalidate(BRect(r.right, r.top + 1.0,
r.right, r.bottom - 1.0));
if (fOldBounds.Height() < r.Height())
Invalidate(BRect(fOldBounds.left + 1.0, fOldBounds.bottom,
fOldBounds.right - 1.0, fOldBounds.bottom));
else
Invalidate(BRect(r.left + 1.0, r.bottom,
r.right - 1.0, r.bottom));
// remember for next time
fOldBounds = r;
// layout controls
r.InsetBy(BORDER_INSET, BORDER_INSET);
_LayoutControls(r);
}
void MediaControlView::SetStatus(int status, int rate)
// GetPreferredSize
void
MediaControlView::GetPreferredSize(float* width, float* height)
{
if (width && height)
{
BRect r(_MinFrame());
*width = r.Width();
*height = r.Height();
}
}
// MessageReceived
void
MediaControlView::MessageReceived(BMessage* message)
{
switch (message->what)
{
case MSG_REWIND:
break;
case MSG_FORWARD:
break;
case MSG_SKIP_BACKWARDS:
Window()->PostMessage(PREV_CHAPTER);
break;
case MSG_SKIP_FORWARD:
Window()->PostMessage(NEXT_CHAPTER);
break;
default:
BBox::MessageReceived(message);
break;
}
}
// Pulse
void
MediaControlView::Pulse()
{
InterfaceWindow* window = dynamic_cast<InterfaceWindow*>(Window());
if (window && window->IsStopped())
fPlayPause->SetStopped();
}
// SetProgress
void
MediaControlView::SetProgress(uint64 seek, uint64 size)
{
fSeekSlider->SetPosition((float)seek / (float)size);
}
// SetStatus
void
MediaControlView::SetStatus(int status, int rate)
{
// we need to set the button status periodically
// (even if it is the same) to get a blinking button
fCurrentStatus = status;
switch( status )
{
case PLAYING_S:
case FORWARD_S:
case BACKWARD_S:
case START_S:
p_play->SetPlaying();
fPlayPause->SetPlaying();
break;
case PAUSE_S:
p_play->SetPaused();
fPlayPause->SetPaused();
break;
case UNDEF_S:
case NOT_STARTED_S:
default:
p_play->SetStopped();
fPlayPause->SetStopped();
break;
}
if ( rate < DEFAULT_RATE )
{
}
if (rate != fCurrentRate)
{
fCurrentRate = rate;
if ( rate < DEFAULT_RATE )
{
// TODO: ...
}
}
}
// SetEnabled
void
MediaControlView::SetEnabled(bool enabled)
{
fSkipBack->SetEnabled(enabled);
fPlayPause->SetEnabled(enabled);
fSkipForward->SetEnabled(enabled);
fStop->SetEnabled(enabled);
fMute->SetEnabled(enabled);
fVolumeSlider->SetEnabled(enabled);
fSeekSlider->SetEnabled(enabled);
fRewind->SetEnabled(enabled);
fForward->SetEnabled(enabled);
}
// GetSeekTo
uint32
MediaControlView::GetSeekTo() const
{
return fSeekSlider->Value();
}
void MediaControlView::SetEnabled(bool enabled)
// GetVolume
uint32
MediaControlView::GetVolume() const
{
p_slow->SetEnabled(enabled);
p_play->SetEnabled(enabled);
p_fast->SetEnabled(enabled);
p_stop->SetEnabled(enabled);
p_mute->SetEnabled(enabled);
p_vol->SetEnabled(enabled);
p_seek->SetEnabled(enabled);
return fVolumeSlider->Value();
}
uint32 MediaControlView::GetSeekTo()
// SetSkippable
void
MediaControlView::SetSkippable(bool backward, bool forward)
{
return p_seek->seekTo;
fSkipBack->SetEnabled(backward);
fSkipForward->SetEnabled(forward);
}
uint32 MediaControlView::GetVolume()
// SetMuted
void
MediaControlView::SetMuted(bool mute)
{
return p_vol->Value();
fVolumeSlider->SetMuted(mute);
}
// _LayoutControls
void
MediaControlView::_LayoutControls(BRect frame) const
{
// seek slider
BRect r(frame);
r.bottom = r.top + r.Height() / 2.0 - MIN_SPACE / 2.0;
_LayoutControl(fSeekSlider, r, true);
// calculate absolutly minimal width
float minWidth = fSkipBack->Bounds().Width();
// minWidth += fRewind->Bounds().Width();
minWidth += fStop->Bounds().Width();
minWidth += fPlayPause->Bounds().Width();
// minWidth += fForward->Bounds().Width();
minWidth += fSkipForward->Bounds().Width();
minWidth += fMute->Bounds().Width();
minWidth += VOLUME_MIN_WIDTH;
float currentWidth = frame.Width();
float space = (currentWidth - minWidth) / 6.0;//8.0;
// apply weighting
space = MIN_SPACE + (space - MIN_SPACE) / VOLUME_SLIDER_LAYOUT_WEIGHT;
// layout controls with "space" inbetween
r.top = r.bottom + MIN_SPACE + 1.0;
r.bottom = frame.bottom;
// skip back
r.right = r.left + fSkipBack->Bounds().Width();
_LayoutControl(fSkipBack, r);
// rewind
// r.left = r.right + space;
// r.right = r.left + fRewind->Bounds().Width();
// _LayoutControl(fRewind, r);
// stop
r.left = r.right + space;
r.right = r.left + fStop->Bounds().Width();
_LayoutControl(fStop, r);
// play/pause
r.left = r.right + space;
r.right = r.left + fPlayPause->Bounds().Width();
_LayoutControl(fPlayPause, r);
// forward
// r.left = r.right + space;
// r.right = r.left + fForward->Bounds().Width();
// _LayoutControl(fForward, r);
// skip forward
r.left = r.right + space;
r.right = r.left + fSkipForward->Bounds().Width();
_LayoutControl(fSkipForward, r);
// speaker icon
r.left = r.right + space + space;
r.right = r.left + fMute->Bounds().Width();
_LayoutControl(fMute, r);
// volume slider
r.left = r.right + SPEAKER_SLIDER_DIST; // keep speaker icon and volume slider attached
r.right = frame.right;
_LayoutControl(fVolumeSlider, r, true);
}
// _MinFrame
BRect
MediaControlView::_MinFrame() const
{
// add up width of controls along bottom (seek slider will likely adopt)
float minWidth = 2 * BORDER_INSET;
minWidth += fSkipBack->Bounds().Width() + MIN_SPACE;
// minWidth += fRewind->Bounds().Width() + MIN_SPACE;
minWidth += fStop->Bounds().Width() + MIN_SPACE;
minWidth += fPlayPause->Bounds().Width() + MIN_SPACE;
// minWidth += fForward->Bounds().Width() + MIN_SPACE;
minWidth += fSkipForward->Bounds().Width() + MIN_SPACE + MIN_SPACE;
minWidth += fMute->Bounds().Width() + SPEAKER_SLIDER_DIST;
minWidth += VOLUME_MIN_WIDTH;
// add up height of seek slider and heighest control on bottom
float minHeight = 2 * BORDER_INSET;
minHeight += fSeekSlider->Bounds().Height() + MIN_SPACE + MIN_SPACE / 2.0;
minHeight += fBottomControlHeight;
return BRect(0.0, 0.0, minWidth - 1.0, minHeight - 1.0);
}
// _LayoutControl
void
MediaControlView::_LayoutControl(BView* view, BRect frame, bool resize) const
{
// center vertically
frame.top = (frame.top + frame.bottom) / 2.0 - view->Bounds().Height() / 2.0;
if (!resize)
frame.left = (frame.left + frame.right) / 2.0 - view->Bounds().Width() / 2.0;
view->MoveTo(frame.LeftTop());
if (resize)
view->ResizeTo(frame.Width(), view->Bounds().Height());
}
/*****************************************************************************
* MediaSlider
* SeekSlider
*****************************************************************************/
MediaSlider::MediaSlider( BRect frame, BMessage *p_message,
int32 i_min, int32 i_max )
:BSlider(frame, NULL, NULL, p_message, i_min, i_max )
SeekSlider::SeekSlider(BRect frame, const char* name, MediaControlView *owner,
int32 minValue, int32 maxValue)
: BControl(frame, name, NULL, NULL, B_FOLLOW_NONE,
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
fOwner(owner),
fTracking(false),
fMinValue(minValue),
fMaxValue(maxValue)
{
BFont font(be_plain_font);
font.SetSize(9.0);
SetFont(&font);
}
SeekSlider::~SeekSlider()
{
_EndSeek();
}
MediaSlider::~MediaSlider()
/*****************************************************************************
* VolumeSlider::AttachedToWindow
*****************************************************************************/
void
SeekSlider::AttachedToWindow()
{
BControl::AttachedToWindow();
SetViewColor(B_TRANSPARENT_32_BIT);
}
/*****************************************************************************
* VolumeSlider::Draw
*****************************************************************************/
void
SeekSlider::Draw(BRect updateRect)
{
BRect r(Bounds());
float knobWidth2 = SEEK_SLIDER_KNOB_WIDTH / 2.0;
float sliderStart = (r.left + knobWidth2);
float sliderEnd = (r.right - knobWidth2);
float knobPos = sliderStart
+ floorf((sliderEnd - sliderStart - 1.0) * (Value() - fMinValue)
/ (fMaxValue - fMinValue) + 0.5);
// draw both sides (the original from Be doesn't seem
// to make a difference for enabled/disabled state)
// DrawBitmapAsync(fLeftSideBits, r.LeftTop());
// DrawBitmapAsync(fRightSideBits, BPoint(sliderEnd + 1.0, r.top));
// colors for the slider area between the two bitmaps
rgb_color background = kBackground;//ui_color(B_PANEL_BACKGROUND_COLOR);
rgb_color shadow = tint_color(background, B_DARKEN_2_TINT);
rgb_color softShadow = tint_color(background, B_DARKEN_1_TINT);
rgb_color darkShadow = tint_color(background, B_DARKEN_4_TINT);
rgb_color midShadow = tint_color(background, B_DARKEN_3_TINT);
rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
rgb_color softLight = tint_color(background, B_LIGHTEN_1_TINT);
rgb_color green = kSeekGreen;
rgb_color greenShadow = kSeekGreenShadow;
rgb_color black = kBlack;
rgb_color dotGrey = midShadow;
rgb_color dotGreen = greenShadow;
// draw frame
_StrokeFrame(r, softShadow, softShadow, softLight, softLight);
r.InsetBy(1.0, 1.0);
_StrokeFrame(r, black, black, light, light);
if (IsEnabled())
{
r.InsetBy(1.0, 1.0);
// inner shadow
_StrokeFrame(r, greenShadow, greenShadow, green, green);
r.top++;
r.left++;
_StrokeFrame(r, greenShadow, greenShadow, green, green);
// inside area
r.InsetBy(1.0, 1.0);
SetHighColor(green);
FillRect(r);
// dots
int32 dotCount = (int32)(r.Width() / 6.0);
BPoint dotPos;
dotPos.y = r.top + 2.0;
SetHighColor(dotGreen);
for (int32 i = 0; i < dotCount; i++)
{
dotPos.x = sliderStart + i * 6.0 + 5.0;
StrokeLine(dotPos, BPoint(dotPos.x, dotPos.y + 6.0));
}
// slider handle
r.top -= 4.0;
r.bottom += 3.0;
r.left = knobPos - knobWidth2;
r.right = knobPos + knobWidth2;
// black outline
float handleBottomSize = 2.0;
float handleArrowSize = 6.0;
BeginLineArray(10);
// upper handle
AddLine(BPoint(r.left, r.top + handleBottomSize),
BPoint(r.left, r.top), black);
AddLine(BPoint(r.left + 1.0, r.top),
BPoint(r.right, r.top), black);
AddLine(BPoint(r.right, r.top + 1.0),
BPoint(r.right, r.top + handleBottomSize), black);
AddLine(BPoint(r.right - 1.0, r.top + handleBottomSize + 1.0),
BPoint(knobPos, r.top + handleArrowSize), black);
AddLine(BPoint(knobPos - 1.0, r.top + handleArrowSize - 1.0),
BPoint(r.left + 1.0, r.top + handleBottomSize + 1.0), black);
// lower handle
AddLine(BPoint(r.left, r.bottom),
BPoint(r.left, r.bottom - handleBottomSize), black);
AddLine(BPoint(r.left + 1.0, r.bottom - handleBottomSize - 1.0),
BPoint(knobPos, r.bottom - handleArrowSize), black);
AddLine(BPoint(knobPos + 1.0, r.bottom - handleArrowSize + 1.0),
BPoint(r.right, r.bottom - handleBottomSize), black);
AddLine(BPoint(r.right, r.bottom - handleBottomSize + 1.0),
BPoint(r.right, r.bottom), black);
AddLine(BPoint(r.right - 1.0, r.bottom),
BPoint(r.left + 1.0, r.bottom), black);
EndLineArray();
// inner red light and shadow lines
r.InsetBy(1.0, 1.0);
handleBottomSize--;
handleArrowSize -= 2.0;
BeginLineArray(10);
// upper handle
AddLine(BPoint(r.left, r.top + handleBottomSize),
BPoint(r.left, r.top), kSeekRedLight);
AddLine(BPoint(r.left + 1.0, r.top),
BPoint(r.right, r.top), kSeekRedLight);
AddLine(BPoint(r.right, r.top + 1.0),
BPoint(r.right, r.top + handleBottomSize), kSeekRedShadow);
AddLine(BPoint(r.right - 1.0, r.top + handleBottomSize + 1.0),
BPoint(knobPos, r.top + handleArrowSize), kSeekRedShadow);
AddLine(BPoint(knobPos - 1.0, r.top + handleArrowSize - 1.0),
BPoint(r.left + 1.0, r.top + handleBottomSize + 1.0), kSeekRedLight);
// lower handle
AddLine(BPoint(r.left, r.bottom),
BPoint(r.left, r.bottom - handleBottomSize), kSeekRedLight);
AddLine(BPoint(r.left + 1.0, r.bottom - handleBottomSize - 1.0),
BPoint(knobPos, r.bottom - handleArrowSize), kSeekRedLight);
AddLine(BPoint(knobPos + 1.0, r.bottom - handleArrowSize + 1.0),
BPoint(r.right, r.bottom - handleBottomSize), kSeekRedShadow);
AddLine(BPoint(r.right, r.bottom - handleBottomSize + 1.0),
BPoint(r.right, r.bottom), kSeekRedShadow);
AddLine(BPoint(r.right - 1.0, r.bottom),
BPoint(r.left + 1.0, r.bottom), kSeekRedShadow);
EndLineArray();
// fill rest of handles with red
SetHighColor(kSeekRed);
r.InsetBy(1.0, 1.0);
handleArrowSize -= 2.0;
BPoint arrow[3];
// upper handle arrow
arrow[0].x = r.left;
arrow[0].y = r.top;
arrow[1].x = r.right;
arrow[1].y = r.top;
arrow[2].x = knobPos;
arrow[2].y = r.top + handleArrowSize;
FillPolygon(arrow, 3);
// lower handle arrow
arrow[0].x = r.left;
arrow[0].y = r.bottom;
arrow[1].x = r.right;
arrow[1].y = r.bottom;
arrow[2].x = knobPos;
arrow[2].y = r.bottom - handleArrowSize;
FillPolygon(arrow, 3);
}
else
{
r.InsetBy(1.0, 1.0);
_StrokeFrame(r, darkShadow, darkShadow, darkShadow, darkShadow);
r.InsetBy(1.0, 1.0);
_StrokeFrame(r, darkShadow, darkShadow, darkShadow, darkShadow);
r.InsetBy(1.0, 1.0);
SetHighColor(darkShadow);
SetLowColor(shadow);
// stripes
float width = floorf(StringWidth(kDisabledSeekMessage));
float textPos = r.left + r.Width() / 2.0 - width / 2.0;
pattern stripes = { 0xc7, 0x8f, 0x1f, 0x3e, 0x7c, 0xf8, 0xf1, 0xe3 };
BRect stripesRect(r);
stripesRect.right = textPos - 5.0;
FillRect(stripesRect, stripes);
stripesRect.left = textPos + width + 3.0;
stripesRect.right = r.right;
FillRect(stripesRect, stripes);
// info text
r.left = textPos - 4.0;
r.right = textPos + width + 2.0;
FillRect(r);
SetHighColor(shadow);
SetLowColor(darkShadow);
font_height fh;
GetFontHeight(&fh);
DrawString(kDisabledSeekMessage, BPoint(textPos, r.top + ceilf(fh.ascent) - 1.0));
}
}
void MediaSlider::DrawThumb(void)
/*****************************************************************************
* SeekSlider::MouseDown
*****************************************************************************/
void
SeekSlider::MouseDown(BPoint where)
{
BRect r;
BView *v;
if (IsEnabled() && Bounds().Contains(where))
{
SetValue(_ValueFor(where.x));
fTracking = true;
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
_BeginSeek();
}
}
rgb_color black = {0,0,0};
r = ThumbFrame();
v = OffscreenView();
/*****************************************************************************
* SeekSlider::MouseMoved
*****************************************************************************/
void
SeekSlider::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage)
{
if (fTracking)
{
SetValue(_ValueFor(where.x));
_Seek();
}
}
if(IsEnabled())
{
v->SetHighColor(black);
}
else
{
v->SetHighColor(tint_color(black, B_LIGHTEN_2_TINT));
}
/*****************************************************************************
* SeekSlider::MouseUp
*****************************************************************************/
void
SeekSlider::MouseUp(BPoint where)
{
if (fTracking)
{
fTracking = false;
_EndSeek();
}
}
r.InsetBy(r.IntegerWidth()/4, r.IntegerHeight()/(4 * r.IntegerWidth() / r.IntegerHeight()));
v->StrokeEllipse(r);
/*****************************************************************************
* SeekSlider::ResizeToPreferred
*****************************************************************************/
void
SeekSlider::ResizeToPreferred()
{
float width = 15.0 + StringWidth(kDisabledSeekMessage) + 15.0;
ResizeTo(width, 17.0);
}
if(IsEnabled())
{
v->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
}
else
{
v->SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_2_TINT));
}
/*****************************************************************************
* SeekSlider::SetPosition
*****************************************************************************/
void
SeekSlider::SetPosition(float position)
{
SetValue(fMinValue + (int32)floorf((fMaxValue - fMinValue) * position + 0.5));
}
r.InsetBy(1,1);
v->FillEllipse(r);
/*****************************************************************************
* SeekSlider::_ValueFor
*****************************************************************************/
int32
SeekSlider::_ValueFor(float xPos) const
{
BRect r(Bounds());
float knobWidth2 = SEEK_SLIDER_KNOB_WIDTH / 2.0;
float sliderStart = (r.left + knobWidth2);
float sliderEnd = (r.right - knobWidth2);
int32 value = fMinValue + (int32)(((xPos - sliderStart) * (fMaxValue - fMinValue))
/ (sliderEnd - sliderStart - 1.0));
if (value < fMinValue)
value = fMinValue;
if (value > fMaxValue)
value = fMaxValue;
return value;
}
/*****************************************************************************
* SeekSlider
* SeekSlider::_StrokeFrame
*****************************************************************************/
SeekSlider::SeekSlider( BRect frame, MediaControlView *p_owner, int32 i_min,
int32 i_max, thumb_style thumbType = B_TRIANGLE_THUMB )
:MediaSlider( frame, NULL, i_min, i_max )
void
SeekSlider::_StrokeFrame(BRect r, rgb_color left, rgb_color top,
rgb_color right, rgb_color bottom)
{
fOwner = p_owner;
fMouseDown = false;
BeginLineArray(4);
AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), left);
AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), top);
AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), right);
AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), bottom);
EndLineArray();
}
SeekSlider::~SeekSlider()
/*****************************************************************************
* SeekSlider::_BeginSeek
*****************************************************************************/
void
SeekSlider::_BeginSeek()
{
fOwner->fScrubSem = create_sem(0, "Vlc::fScrubSem");
if (fOwner->fScrubSem >= B_OK)
release_sem(fOwner->fScrubSem);
}
/*****************************************************************************
* SeekSlider::MouseDown
* SeekSlider::_Seek
*****************************************************************************/
void SeekSlider::MouseDown(BPoint where)
void
SeekSlider::_Seek()
{
BSlider::MouseDown(where);
seekTo = ValueForPoint(where);
fOwner->fScrubSem = create_sem(0, "Vlc::fScrubSem");
release_sem(fOwner->fScrubSem);
fMouseDown = true;
if (fOwner->fScrubSem >= B_OK)
delete_sem(fOwner->fScrubSem);
fOwner->fScrubSem = create_sem(0, "Vlc::fScrubSem");
if (fOwner->fScrubSem >= B_OK)
release_sem(fOwner->fScrubSem);
}
/*****************************************************************************
* SeekSlider::MouseUp
* SeekSlider::_EndSeek
*****************************************************************************/
void SeekSlider::MouseMoved(BPoint where, uint32 code, const BMessage *message)
void
SeekSlider::_EndSeek()
{
BSlider::MouseMoved(where, code, message);
if (!fMouseDown)
return;
seekTo = ValueForPoint(where);
release_sem(fOwner->fScrubSem);
if (fOwner->fScrubSem >= B_OK)
delete_sem(fOwner->fScrubSem);
fOwner->fScrubSem = B_ERROR;
}
/*****************************************************************************
* SeekSlider::MouseUp
* VolumeSlider
*****************************************************************************/
VolumeSlider::VolumeSlider(BRect frame, const char* name, int32 minValue, int32 maxValue,
BMessage* message, BHandler* target)
: BControl(frame, name, NULL, message, B_FOLLOW_NONE,
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
fLeftSideBits(NULL),
fRightSideBits(NULL),
fKnobBits(NULL),
fTracking(false),
fMuted(false),
fMinValue(minValue),
fMaxValue(maxValue)
{
SetTarget(target);
// create bitmaps
BRect r(BPoint(0.0, 0.0), kVolumeSliderBitmapSize);
fLeftSideBits = new BBitmap(r, B_CMAP8);
fRightSideBits = new BBitmap(r, B_CMAP8);
r.Set(0.0, 0.0, kVolumeSliderKnobBitmapSize.x, kVolumeSliderKnobBitmapSize.y);
fKnobBits = new BBitmap(r, B_CMAP8);
_MakeBitmaps();
}
/*****************************************************************************
* VolumeSlider destructor
*****************************************************************************/
VolumeSlider::~VolumeSlider()
{
delete fLeftSideBits;
delete fRightSideBits;
delete fKnobBits;
}
/*****************************************************************************
* VolumeSlider::AttachedToWindow
*****************************************************************************/
void
VolumeSlider::AttachedToWindow()
{
BControl::AttachedToWindow();
SetViewColor(B_TRANSPARENT_32_BIT);
}
/*****************************************************************************
* VolumeSlider::SetValue
*****************************************************************************/
void
VolumeSlider::SetValue(int32 value)
{
if (value != Value())
{
BControl::SetValue(value);
Invoke();
}
}
/*****************************************************************************
* VolumeSlider::SetEnabled
*****************************************************************************/
void
VolumeSlider::SetEnabled(bool enable)
{
if (enable != IsEnabled())
{
BControl::SetEnabled(enable);
_MakeBitmaps();
Invalidate();
}
}
/*****************************************************************************
* VolumeSlider::Draw
*****************************************************************************/
void SeekSlider::MouseUp(BPoint where)
void
VolumeSlider::Draw(BRect updateRect)
{
BSlider::MouseUp(where);
seekTo = ValueForPoint(where);
delete_sem(fOwner->fScrubSem);
fOwner->fScrubSem = B_ERROR;
fMouseDown = false;
if (IsValid())
{
BRect r(Bounds());
float sliderSideWidth = kVolumeSliderBitmapWidth;
float sliderStart = (r.left + sliderSideWidth);
float sliderEnd = (r.right - sliderSideWidth);
float knobPos = sliderStart
+ (sliderEnd - sliderStart - 1.0) * (Value() - fMinValue)
/ (fMaxValue - fMinValue);
// draw both sides (the original from Be doesn't seem
// to make a difference for enabled/disabled state)
DrawBitmapAsync(fLeftSideBits, r.LeftTop());
DrawBitmapAsync(fRightSideBits, BPoint(sliderEnd + 1.0, r.top));
// colors for the slider area between the two bitmaps
rgb_color background = kBackground;//ui_color(B_PANEL_BACKGROUND_COLOR);
rgb_color shadow = tint_color(background, B_DARKEN_2_TINT);
rgb_color softShadow = tint_color(background, B_DARKEN_1_TINT);
rgb_color darkShadow = tint_color(background, B_DARKEN_4_TINT);
rgb_color midShadow = tint_color(background, B_DARKEN_3_TINT);
rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
rgb_color softLight = tint_color(background, B_LIGHTEN_1_TINT);
rgb_color green = kGreen;
rgb_color greenShadow = kGreenShadow;
rgb_color black = kBlack;
rgb_color dotGrey = midShadow;
rgb_color dotGreen = greenShadow;
// make dimmed version of colors if we're disabled
if (!IsEnabled())
{
shadow = (rgb_color){ 200, 200, 200, 255 };
softShadow = dimmed_color_cmap8(softShadow, background, DIM_LEVEL);
darkShadow = dimmed_color_cmap8(darkShadow, background, DIM_LEVEL);
midShadow = shadow;
light = dimmed_color_cmap8(light, background, DIM_LEVEL);
softLight = dimmed_color_cmap8(softLight, background, DIM_LEVEL);
green = dimmed_color_cmap8(green, background, DIM_LEVEL);
greenShadow = dimmed_color_cmap8(greenShadow, background, DIM_LEVEL);
black = dimmed_color_cmap8(black, background, DIM_LEVEL);
dotGreen = dotGrey;
}
else if (fMuted)
{
green = tint_color(kBackground, B_DARKEN_3_TINT);
greenShadow = tint_color(kBackground, B_DARKEN_4_TINT);
dotGreen = greenShadow;
}
// draw slider edges between bitmaps
BeginLineArray(7);
AddLine(BPoint(sliderStart, r.top),
BPoint(sliderEnd, r.top), softShadow);
AddLine(BPoint(sliderStart, r.bottom),
BPoint(sliderEnd, r.bottom), softLight);
r.InsetBy(0.0, 1.0);
AddLine(BPoint(sliderStart, r.top),
BPoint(sliderEnd, r.top), black);
AddLine(BPoint(sliderStart, r.bottom),
BPoint(sliderEnd, r.bottom), light);
r.top++;
AddLine(BPoint(sliderStart, r.top),
BPoint(knobPos, r.top), greenShadow);
AddLine(BPoint(knobPos, r.top),
BPoint(sliderEnd, r.top), midShadow);
r.top++;
AddLine(BPoint(sliderStart, r.top),
BPoint(knobPos, r.top), greenShadow);
EndLineArray();
// fill rest inside of slider
r.InsetBy(0.0, 1.0);
r.left = sliderStart;
r.right = knobPos;
SetHighColor(green);
FillRect(r, B_SOLID_HIGH);
r.left = knobPos + 1.0;
r.right = sliderEnd;
r.top -= 1.0;
SetHighColor(shadow);
FillRect(r, B_SOLID_HIGH);
// draw little dots inside
int32 dotCount = (int32)((sliderEnd - sliderStart) / 5.0);
BPoint dotPos;
dotPos.y = r.top + 4.0;
for (int32 i = 0; i < dotCount; i++)
{
dotPos.x = sliderStart + i * 5.0 + 4.0;
SetHighColor(dotPos.x < knobPos ? dotGreen : dotGrey);
StrokeLine(dotPos, BPoint(dotPos.x, dotPos.y + 1.0));
}
// draw knob
r.top -= 1.0;
SetDrawingMode(B_OP_OVER); // part of knob is transparent
DrawBitmapAsync(fKnobBits, BPoint(knobPos - kVolumeSliderKnobWidth / 2, r.top));
}
else
fprintf(stderr, "VolumeSlider::Draw() - Error: no valid bitmaps!");
}
/*****************************************************************************
* VolumeSlider::MouseDown
*****************************************************************************/
void
VolumeSlider::MouseDown(BPoint where)
{
if (Bounds().Contains(where) && IsEnabled())
{
fTracking = true;
SetValue(_ValueFor(where.x));
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
}
}
/*****************************************************************************
* VolumeSlider::MouseMoved
*****************************************************************************/
void
VolumeSlider::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
{
if (fTracking)
SetValue(_ValueFor(where.x));
}
/*****************************************************************************
* VolumeSlider::MouseUp
*****************************************************************************/
void
VolumeSlider::MouseUp(BPoint where)
{
fTracking = false;
}
/*****************************************************************************
* VolumeSlider::IsValid
*****************************************************************************/
bool
VolumeSlider::IsValid() const
{
return (fLeftSideBits && fLeftSideBits->IsValid()
&& fRightSideBits && fRightSideBits->IsValid()
&& fKnobBits && fKnobBits->IsValid());
}
/*****************************************************************************
* VolumeSlider::SetMuted
*****************************************************************************/
void
VolumeSlider::SetMuted(bool mute)
{
if (mute != fMuted)
{
fMuted = mute;
_MakeBitmaps();
Invalidate();
}
}
/*****************************************************************************
* VolumeSlider::_MakeBitmaps
*****************************************************************************/
void
VolumeSlider::_MakeBitmaps()
{
if (IsValid())
{
// left side of slider
memcpy(fLeftSideBits->Bits(), kVolumeSliderLeftBitmapBits,
fLeftSideBits->BitsLength());
// right side of slider
memcpy(fRightSideBits->Bits(), kVolumeSliderRightBits,
fRightSideBits->BitsLength());
// slider knob
int32 length = fKnobBits->BitsLength();
memcpy(fKnobBits->Bits(), kVolumeSliderKnobBits, length);
uint8* bits = (uint8*)fKnobBits->Bits();
// black was used in the knob to represent transparency
// use screen to get index for the "transarent" color used in the bitmap
BScreen screen(B_MAIN_SCREEN_ID);
uint8 blackIndex = screen.IndexForColor(kBlack);
// replace black index with transparent index
for (int32 i = 0; i < length; i++)
if (bits[i] == blackIndex)
bits[i] = B_TRANSPARENT_MAGIC_CMAP8;
if (!IsEnabled())
{
// make ghosted versions of the bitmaps
dim_bitmap(fLeftSideBits, kBackground, DIM_LEVEL);
dim_bitmap(fRightSideBits, kBackground, DIM_LEVEL);
dim_bitmap(fKnobBits, kBackground, DIM_LEVEL);
}
else if (fMuted)
{
// replace green color (and shadow) in left slider side
bits = (uint8*)fLeftSideBits->Bits();
length = fLeftSideBits->BitsLength();
uint8 greenIndex = screen.IndexForColor(kGreen);
uint8 greenShadowIndex = screen.IndexForColor(kGreenShadow);
rgb_color shadow = tint_color(kBackground, B_DARKEN_3_TINT);
rgb_color midShadow = tint_color(kBackground, B_DARKEN_4_TINT);
uint8 replaceIndex = screen.IndexForColor(shadow);
uint8 replaceShadowIndex = screen.IndexForColor(midShadow);
for (int32 i = 0; i < length; i++)
{
if (bits[i] == greenIndex)
bits[i] = replaceIndex;
else if (bits[i] == greenShadowIndex)
bits[i] = replaceShadowIndex;
}
}
}
}
/*****************************************************************************
* VolumeSlider::_ValueFor
*****************************************************************************/
int32
VolumeSlider::_ValueFor(float xPos) const
{
BRect r(Bounds());
float sliderStart = (r.left + kVolumeSliderBitmapWidth);
float sliderEnd = (r.right - kVolumeSliderBitmapWidth);
int32 value = fMinValue + (int32)(((xPos - sliderStart) * (fMaxValue - fMinValue))
/ (sliderEnd - sliderStart - 1.0));
if (value < fMinValue)
value = fMinValue;
if (value > fMaxValue)
value = fMaxValue;
return value;
}
......@@ -2,9 +2,10 @@
* MediaControlView.h: beos interface
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: MediaControlView.h,v 1.2 2001/09/12 01:31:37 tcastley Exp $
* $Id: MediaControlView.h,v 1.2.4.1 2002/09/03 12:00:25 tcastley Exp $
*
* Authors: Tony Castley <tony@castley.net>
* Stephan Aßmus <stippi@yellowbites.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -20,73 +21,147 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define HORZ_SPACE 5.0
#define VERT_SPACE 5.0
#ifndef BEOS_MEDIA_CONTROL_VIEW_H
#define BEOS_MEDIA_CONTROL_VIEW_H
class TransportButton;
#include <Box.h>
#include <Control.h>
class BBitmap;
class PlayPauseButton;
class MediaSlider;
class SeekSlider;
class TransportButton;
class VolumeSlider;
class MediaControlView : public BBox
{
public:
MediaControlView( BRect frame );
~MediaControlView();
virtual void MessageReceived(BMessage *message);
void SetProgress(uint64 seek, uint64 size);
void SetStatus(int status, int rate);
void SetEnabled(bool);
uint32 GetSeekTo();
uint32 GetVolume();
sem_id fScrubSem;
bool fSeeking;
public:
MediaControlView( BRect frame );
virtual ~MediaControlView();
// BBox
virtual void AttachedToWindow();
virtual void FrameResized(float width, float height);
virtual void GetPreferredSize(float* width, float* height);
virtual void MessageReceived(BMessage* message);
virtual void Pulse(); // detect stopped stream
// MediaControlView
void SetProgress(uint64 seek, uint64 size);
void SetStatus(int status, int rate);
void SetEnabled(bool enable);
uint32 GetSeekTo() const;
uint32 GetVolume() const;
void SetSkippable(bool backward,
bool forward);
void SetMuted(bool mute);
sem_id fScrubSem;
private:
MediaSlider * p_vol;
SeekSlider * p_seek;
TransportButton* p_slow;
PlayPauseButton* p_play;
TransportButton* p_fast;
TransportButton* p_stop;
TransportButton* p_mute;
int current_rate;
int current_status;
};
private:
void _LayoutControls(BRect frame) const;
BRect _MinFrame() const;
void _LayoutControl(BView* view,
BRect frame,
bool resize = false) const;
class MediaSlider : public BSlider
{
public:
MediaSlider(BRect frame,
BMessage *message,
int32 minValue,
int32 maxValue);
~MediaSlider();
virtual void DrawThumb(void);
VolumeSlider* fVolumeSlider;
SeekSlider* fSeekSlider;
TransportButton* fSkipBack;
TransportButton* fSkipForward;
TransportButton* fRewind;
TransportButton* fForward;
PlayPauseButton* fPlayPause;
TransportButton* fStop;
TransportButton* fMute;
int fCurrentRate;
int fCurrentStatus;
float fBottomControlHeight;
BRect fOldBounds;
};
class SeekSlider : public MediaSlider
class SeekSlider : public BControl
{
public:
SeekSlider(BRect frame,
MediaControlView *owner,
int32 minValue,
int32 maxValue,
thumb_style thumbType = B_TRIANGLE_THUMB);
~SeekSlider();
uint32 seekTo;
virtual void MouseDown(BPoint);
virtual void MouseUp(BPoint pt);
virtual void MouseMoved(BPoint pt, uint32 c, const BMessage *m);
public:
SeekSlider(BRect frame,
const char* name,
MediaControlView* owner,
int32 minValue,
int32 maxValue);
virtual ~SeekSlider();
// BControl
virtual void AttachedToWindow();
virtual void Draw(BRect updateRect);
virtual void MouseDown(BPoint where);
virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage);
virtual void MouseUp(BPoint where);
virtual void ResizeToPreferred();
// SeekSlider
void SetPosition(float position);
private:
MediaControlView* fOwner;
bool fMouseDown;
int32 _ValueFor(float x) const;
void _StrokeFrame(BRect frame,
rgb_color left,
rgb_color top,
rgb_color right,
rgb_color bottom);
void _BeginSeek();
void _Seek();
void _EndSeek();
MediaControlView* fOwner;
bool fTracking;
int32 fMinValue;
int32 fMaxValue;
};
class VolumeSlider : public BControl
{
public:
VolumeSlider(BRect frame,
const char* name,
int32 minValue,
int32 maxValue,
BMessage* message = NULL,
BHandler* target = NULL);
virtual ~VolumeSlider();
// BControl
virtual void AttachedToWindow();
virtual void SetValue(int32 value);
virtual void SetEnabled(bool enable);
virtual void Draw(BRect updateRect);
virtual void MouseDown(BPoint where);
virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage);
virtual void MouseUp(BPoint where);
// VolumeSlider
bool IsValid() const;
void SetMuted(bool mute);
private:
void _MakeBitmaps();
void _DimBitmap(BBitmap* bitmap);
int32 _ValueFor(float xPos) const;
BBitmap* fLeftSideBits;
BBitmap* fRightSideBits;
BBitmap* fKnobBits;
bool fTracking;
bool fMuted;
int32 fMinValue;
int32 fMaxValue;
};
#endif // BEOS_MEDIA_CONTROL_VIEW_H
......@@ -2,9 +2,10 @@
* MsgVals.h
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: MsgVals.h,v 1.9.2.2 2002/07/13 11:33:11 tcastley Exp $
* $Id: MsgVals.h,v 1.9.2.3 2002/09/03 12:00:25 tcastley Exp $
*
* Authors: Tony Castley <tcastley@mail.powerup.com.au>
* Stephan Aßmus <stippi@yellowbites.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -21,32 +22,39 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/* MsgVals.h */
#ifndef BEOS_MESSAGE_VALUES_H
#define BEOS_MESSAGE_VALUES_H
#define PLAYING 0
#define PAUSED 1
const uint32 OPEN_FILE = 'OPFL';
const uint32 OPEN_DVD = 'OPDV';
const uint32 OPEN_PLAYLIST = 'OPPL';
const uint32 STOP_PLAYBACK = 'STPL';
const uint32 START_PLAYBACK = 'PLAY';
const uint32 PAUSE_PLAYBACK = 'PAPL';
const uint32 FASTER_PLAY = 'FAPL';
const uint32 SLOWER_PLAY = 'SLPL';
const uint32 SEEK_PLAYBACK = 'SEEK';
const uint32 VOLUME_CHG = 'VOCH';
const uint32 VOLUME_MUTE = 'MUTE';
const uint32 SELECT_CHANNEL = 'CHAN';
const uint32 SELECT_SUBTITLE = 'SUBT';
const uint32 PREV_TITLE = 'PRTI';
const uint32 NEXT_TITLE = 'NXTI';
const uint32 PREV_CHAPTER = 'PRCH';
const uint32 NEXT_CHAPTER = 'NXCH';
const uint32 TOGGLE_ON_TOP = 'ONTP';
const uint32 TOGGLE_FULL_SCREEN = 'TGFS';
const uint32 RESIZE_100 = 'RSOR';
const uint32 RESIZE_200 = 'RSDB';
const uint32 ASPECT_CORRECT = 'ASCO';
const uint32 VERT_SYNC = 'VSYN';
const uint32 WINDOW_FEEL = 'WFEL';
const uint32 OPEN_FILE = 'opfl';
const uint32 OPEN_DVD = 'opdv';
const uint32 OPEN_PLAYLIST = 'oppl';
const uint32 STOP_PLAYBACK = 'stpl';
const uint32 START_PLAYBACK = 'play';
const uint32 PAUSE_PLAYBACK = 'papl';
const uint32 FASTER_PLAY = 'fapl';
const uint32 SLOWER_PLAY = 'slpl';
const uint32 NORMAL_PLAY = 'nrpl';
const uint32 SEEK_PLAYBACK = 'seek';
const uint32 VOLUME_CHG = 'voch';
const uint32 VOLUME_MUTE = 'mute';
const uint32 SELECT_CHANNEL = 'chan';
const uint32 SELECT_SUBTITLE = 'subt';
const uint32 PREV_TITLE = 'prti';
const uint32 NEXT_TITLE = 'nxti';
const uint32 PREV_CHAPTER = 'prch';
const uint32 NEXT_CHAPTER = 'nxch';
const uint32 TOGGLE_ON_TOP = 'ontp';
const uint32 TOGGLE_FULL_SCREEN = 'tgfs';
const uint32 RESIZE_100 = 'rsor';
const uint32 RESIZE_200 = 'rsdb';
const uint32 RESIZE_TRUE = 'rstr';
const uint32 ASPECT_CORRECT = 'asco';
const uint32 VERT_SYNC = 'vsyn';
const uint32 WINDOW_FEEL = 'wfel';
const uint32 INTERFACE_CREATED = 'ifcr'; /* see VlcApplication::MessageReceived()
* in src/misc/beos_specific.cpp */
#endif // BEOS_MESSAGE_VALUES_H
......@@ -2,7 +2,7 @@
* PlayListWindow.h: BeOS interface window class prototype
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: PlayListWindow.h,v 1.1.4.1 2002/06/01 10:12:10 tcastley Exp $
* $Id: PlayListWindow.h,v 1.1.4.2 2002/09/03 12:00:25 tcastley Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Tony Castley <tcastley@mail.powerup.com.au>
......@@ -22,7 +22,16 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef BEOS_PLAY_LIST_WINDOW_H
#define BEOS_PLAY_LIST_WINDOW_H
#include <Window.h>
class BFilePanel;
class BListView;
class CDMenu;
class PlayListWindow : public BWindow
{
public:
......@@ -42,4 +51,5 @@ private:
BFilePanel *file_panel;
};
#endif // BEOS_PLAY_LIST_WINDOW_H
......@@ -2,9 +2,10 @@
* TransportButton.cpp
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: TransportButton.cpp,v 1.3 2001/03/21 13:42:33 sam Exp $
* $Id: TransportButton.cpp,v 1.3.4.1 2002/09/03 12:00:24 tcastley Exp $
*
* Authors: Tony Castley <tcastley@mail.powerup.com.au>
* Stephan Aßmus <stippi@yellowbites.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -246,10 +247,8 @@ TransportButton::AttachedToWindow()
void
TransportButton::DetachedFromWindow()
{
if (keyPressFilter) {
if (keyPressFilter)
Window()->RemoveCommonFilter(keyPressFilter);
delete keyPressFilter;
}
_inherited::DetachedFromWindow();
}
......@@ -260,6 +259,7 @@ TransportButton::~TransportButton()
delete pressingMessage;
delete donePressingMessage;
delete bitmaps;
delete keyPressFilter;
}
void
......@@ -274,9 +274,11 @@ TransportButton::WindowActivated(bool state)
void
TransportButton::SetEnabled(bool on)
{
_inherited::SetEnabled(on);
if (!on)
ShortcutKeyUp();
if (on != IsEnabled()) {
_inherited::SetEnabled(on);
if (!on)
ShortcutKeyUp();
}
}
const unsigned char *
......@@ -300,11 +302,31 @@ TransportButton::BitsForMask(uint32 mask) const
BBitmap *
TransportButton::MakeBitmap(uint32 mask)
{
BBitmap *result = new BBitmap(Bounds(), B_COLOR_8_BIT);
result->SetBits(BitsForMask(mask), (Bounds().Width() + 1) * (Bounds().Height() + 1),
0, B_COLOR_8_BIT);
ReplaceTransparentColor(result, Parent()->ViewColor());
BRect r(Bounds());
BBitmap *result = new BBitmap(r, B_CMAP8);
uint8* src = (uint8*)BitsForMask(mask);
if (src && result && result->IsValid()) {
int32 width = r.IntegerWidth() + 1;
int32 height = r.IntegerHeight() + 1;
int32 bpr = result->BytesPerRow();
uint8* dst = (uint8*)result->Bits();
// copy source bits into bitmap line by line,
// taking possible alignment into account
// since the source data has been generated
// by QuickRes, it still contains aligment too
// (hence skipping bpr and not width bytes)
for (int32 y = 0; y < height; y++) {
memcpy(dst, src, bpr);
src += bpr;
dst += bpr;
}
ReplaceTransparentColor(result, Parent()->ViewColor());
} else {
delete result;
result = NULL;
}
return result;
}
......
......@@ -2,7 +2,7 @@
* TransportButton.h
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: TransportButton.h,v 1.3 2001/03/21 13:42:33 sam Exp $
* $Id: TransportButton.h,v 1.3.4.1 2002/09/03 12:00:25 tcastley Exp $
*
* Authors: Tony Castley <tcastley@mail.powerup.com.au>
*
......@@ -180,4 +180,4 @@ private:
typedef TransportButton _inherited;
};
#endif
#endif // __MEDIA_BUTTON__
......@@ -2,11 +2,12 @@
* VideoWindow.h: BeOS video window class prototype
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: VideoWindow.h,v 1.19.2.4 2002/07/11 12:24:45 tcastley Exp $
* $Id: VideoWindow.h,v 1.19.2.5 2002/09/03 12:00:25 tcastley Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Tony Castley <tcastley@mail.powerup.com.au>
* Richard Shepherd <richard@rshepherd.demon.co.uk>
* Stephan Aßmus <stippi@yellowbites.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -22,6 +23,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef BEOS_VIDEO_WINDOW_H
#define BEOS_VIDEO_WINDOW_H
#include <View.h>
#include <Window.h>
#define BITMAP 0
#define OVERLAY 1
#define OPENGL 2
......@@ -50,35 +58,58 @@ colorcombo colspace[]=
class VLCView : public BView
{
public:
VLCView( BRect bounds);
~VLCView();
void MouseDown(BPoint point);
void Draw(BRect updateRect);
public:
VLCView( BRect bounds);
virtual ~VLCView();
virtual void AttachedToWindow();
virtual void MouseDown(BPoint where);
virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage);
virtual void Pulse();
virtual void Draw(BRect updateRect);
virtual void KeyDown(const char* bytes, int32 numBytes);
private:
bigtime_t fLastMouseMovedTime;
bool fCursorHidden;
bool fCursorInside;
};
class VideoWindow : public BWindow
{
public:
// standard constructor and destructor
VideoWindow( int v_width, int v_height,
BRect frame);
~VideoWindow();
void Zoom(BPoint origin, float width, float height);
void FrameResized(float width, float height);
void FrameMoved(BPoint origin);
void ScreenChanged(BRect frame, color_space mode);
void drawBuffer(int bufferIndex);
void WindowActivated(bool active);
int SelectDrawingMode(int width, int height);
virtual void MessageReceived(BMessage *message);
VideoWindow(int v_width,
int v_height,
BRect frame);
virtual ~VideoWindow();
// BWindow
virtual void MessageReceived(BMessage* message);
virtual void Zoom(BPoint origin,
float width, float height);
virtual void FrameResized(float width, float height);
virtual void FrameMoved(BPoint origin);
virtual void ScreenChanged(BRect frame,
color_space mode);
virtual void WindowActivated(bool active);
// VideoWindow
void drawBuffer(int bufferIndex);
void ToggleInterfaceShowing();
void SetInterfaceShowing(bool showIt);
void SetCorrectAspectRatio(bool doIt);
inline bool CorrectAspectRatio() const
{ return fCorrectAspect; }
inline status_t InitCheck() const
{ return fInitStatus; }
// this is the hook controling direct screen connection
int32 i_width; // incomming bitmap size
int32 i_width; // aspect corrected bitmap size
int32 i_height;
BRect winSize; // current window size
bool is_zoomed, vsync;
......@@ -86,14 +117,28 @@ public:
BBitmap *overlaybitmap;
VLCView *view;
int i_buffer;
bool teardownwindow;
volatile bool teardownwindow;
thread_id fDrawThreadID;
int mode;
int colspace_index;
private:
status_t _AllocateBuffers(int width,
int height,
int* mode);
void _FreeBuffers();
void _BlankBitmap(BBitmap* bitmap) const;
void _SetVideoSize(uint32 mode);
struct vout_thread_s *p_vout;
int32 fTrueWidth; // incomming bitmap size
int32 fTrueHeight;
bool fCorrectAspect;
window_feel fCachedFeel;
bool fInterfaceShowing;
status_t fInitStatus;
};
#endif // BEOS_VIDEO_WINDOW_H
......@@ -2,12 +2,13 @@
* intf_beos.cpp: beos interface
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: intf_beos.cpp,v 1.38.2.1 2002/07/13 11:33:11 tcastley Exp $
* $Id: intf_beos.cpp,v 1.38.2.2 2002/09/03 12:00:24 tcastley Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Tony Castley <tony@castley.net>
* Richard Shepherd <richard@rshepherd.demon.co.uk>
* Stephan Aßmus <stippi@yellowbites.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -30,6 +31,8 @@
#include <stdio.h>
#include <stdlib.h> /* malloc(), free() */
#include <InterfaceKit.h>
#include <Application.h>
#include <Message.h>
#include <string.h>
extern "C"
......@@ -44,6 +47,7 @@ extern "C"
#include "InterfaceWindow.h"
#include "intf_vlc_wrapper.h"
#include "MsgVals.h"
extern "C"
{
......@@ -98,6 +102,10 @@ static int intf_Open( intf_thread_t *p_intf )
free( p_intf->p_sys );
intf_ErrMsg( "error: cannot allocate memory for InterfaceWindow" );
return( 1 );
} else {
BMessage message(INTERFACE_CREATED);
message.AddPointer("window", p_intf->p_sys->p_window);
be_app->PostMessage(&message);
}
p_intf->p_sys->b_disabled_menus = 0;
p_intf->p_sys->i_saved_volume = VOLUME_DEFAULT;
......
......@@ -2,11 +2,12 @@
* intf_vlc_wrapper.h: BeOS plugin for vlc (derived from MacOS X port )
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: intf_vlc_wrapper.cpp,v 1.1.2.1 2002/07/13 11:33:11 tcastley Exp $
* $Id: intf_vlc_wrapper.cpp,v 1.1.2.2 2002/09/03 12:00:24 tcastley Exp $
*
* Authors: Florian G. Pflug <fgp@phlo.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
* Tony Casltey <tony@castley.net>
* Stephan Aßmus <stippi@yellowbites.com>
*
* This program is free software{} you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -263,9 +264,38 @@ void Intf_VLCWrapper::volume_restore()
p_aout_bank->pp_aout[0]->i_volume =
p_main->p_intf->p_sys->i_saved_volume;
p_main->p_intf->p_sys->i_saved_volume = 0;
p_main->p_intf->p_sys->b_mute = 0;
}
void Intf_VLCWrapper::set_volume(int value)
{
if( p_aout_bank->pp_aout[0] == NULL ) return;
//printf("Intf_VLCWrapper::set_volume(%ld)\n", value);
// make sure value is within bounds
if (value < 0)
value = 0;
if (value > VOLUME_MAX)
value = VOLUME_MAX;
vlc_mutex_lock( &p_aout_bank->lock );
// unmute volume if muted
if (p_main->p_intf->p_sys->b_mute)
{
p_main->p_intf->p_sys->b_mute = 0;
// p_main->p_intf->p_sys->i_saved_volume = 0;
}
// set every stream to the given value
for(int i = 0 ; i < p_aout_bank->i_count ; i++ )
{
if (p_aout_bank->pp_aout[i])
{
// p_aout_bank->pp_aout[i]->i_savedvolume = 0;
p_aout_bank->pp_aout[i]->i_volume = value;
}
}
vlc_mutex_unlock( &p_aout_bank->lock );
}
void Intf_VLCWrapper::toggle_mute()
{
if( p_aout_bank->pp_aout[0] == NULL ) return;
......@@ -277,7 +307,13 @@ void Intf_VLCWrapper::toggle_mute()
{
Intf_VLCWrapper::volume_mute();
}
p_main->p_intf->p_sys->b_mute = !p_main->p_intf->p_sys->b_mute;
// p_main->p_intf->p_sys->b_mute = !p_main->p_intf->p_sys->b_mute;
}
bool Intf_VLCWrapper::is_muted()
{
if( p_aout_bank->pp_aout[0] == NULL ) return false;
return p_main->p_intf->p_sys->b_mute;
}
void Intf_VLCWrapper::maxvolume()
......
......@@ -2,11 +2,12 @@
* intf_vlc_wrapper.h: BeOS plugin for vlc (derived from MacOS X port )
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: intf_vlc_wrapper.h,v 1.1.2.1 2002/07/13 11:33:11 tcastley Exp $
* $Id: intf_vlc_wrapper.h,v 1.1.2.2 2002/09/03 12:00:25 tcastley Exp $
*
* Authors: Florian G. Pflug <fgp@phlo.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
* Tony Casltey <tony@castley.net>
* Stephan Aßmus <stippi@yellowbites.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -61,7 +62,9 @@ public:
static void playFaster();
static void volume_mute();
static void volume_restore();
static void set_volume(int value);
static void toggle_mute();
static bool is_muted();
static void maxvolume();
// static void fullscreen();
static void eject();
......
......@@ -2,12 +2,13 @@
* vout_beos.cpp: beos video output display method
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: vout_beos.cpp,v 1.58.2.4 2002/07/13 11:33:11 tcastley Exp $
* $Id: vout_beos.cpp,v 1.58.2.5 2002/09/03 12:00:24 tcastley Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Tony Castley <tcastley@mail.powerup.com.au>
* Richard Shepherd <richard@rshepherd.demon.co.uk>
* Stephan Aßmus <stippi@yellowbites.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -70,10 +71,14 @@ typedef struct vout_sys_s
} vout_sys_t;
#define MOUSE_IDLE_TIMEOUT 2000000 // two seconds
#define MIN_AUTO_VSYNC_REFRESH 61 // Hz
/*****************************************************************************
* beos_GetAppWindow : retrieve a BWindow pointer from the window name
*****************************************************************************/
BWindow *beos_GetAppWindow(char *name)
BWindow*
beos_GetAppWindow(char *name)
{
int32 index;
BWindow *window;
......@@ -96,57 +101,96 @@ BWindow *beos_GetAppWindow(char *name)
return window;
}
/*****************************************************************************
* get_interface_window
*****************************************************************************/
BWindow*
get_interface_window()
{
return beos_GetAppWindow(VOUT_TITLE);
}
class BackgroundView : public BView
{
public:
BackgroundView(BRect frame, VLCView* view)
: BView(frame, "background",
B_FOLLOW_ALL, B_FULL_UPDATE_ON_RESIZE),
fVideoView(view)
{
SetViewColor(kBlack);
}
virtual ~BackgroundView() {}
virtual void MouseDown(BPoint where)
{
// convert coordinates
where = fVideoView->ConvertFromParent(where);
// let him handle it
fVideoView->MouseDown(where);
}
virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage)
{
// convert coordinates
where = fVideoView->ConvertFromParent(where);
// let him handle it
fVideoView->MouseMoved(where, transit, dragMessage);
// notice: It might look like transit should be
// B_OUTSIDE_VIEW regardless, but leave it like this,
// otherwise, unwanted things will happen!
}
private:
VLCView* fVideoView;
};
/*****************************************************************************
* VideoWindow constructor and destructor
*****************************************************************************/
VideoWindow::VideoWindow( int v_width, int v_height,
BRect frame )
: BWindow( frame, NULL, B_TITLED_WINDOW,
B_NOT_CLOSABLE | B_NOT_MINIMIZABLE )
VideoWindow::VideoWindow(int v_width, int v_height, BRect frame)
: BWindow(frame, NULL, B_TITLED_WINDOW, B_NOT_CLOSABLE | B_NOT_MINIMIZABLE),
i_width(frame.IntegerWidth()),
i_height(frame.IntegerHeight()),
is_zoomed(false),
vsync(false),
i_buffer(0),
teardownwindow(false),
fTrueWidth(v_width),
fTrueHeight(v_height),
fCorrectAspect(true),
fCachedFeel(B_NORMAL_WINDOW_FEEL),
fInterfaceShowing(false),
fInitStatus(B_ERROR)
{
BView *mainView = new BView( Bounds(), "mainView",
B_FOLLOW_ALL, B_FULL_UPDATE_ON_RESIZE);
AddChild(mainView);
mainView->SetViewColor(kBlack);
/* create the view to do the display */
// create the view to do the display
view = new VLCView( Bounds() );
mainView->AddChild(view);
/* set the VideoWindow variables */
teardownwindow = false;
is_zoomed = false;
i_buffer = 0;
// create background view
BView *mainView = new BackgroundView( Bounds(), view );
AddChild(mainView);
mainView->AddChild(view);
/* call ScreenChanged to set vsync correctly */
BScreen *screen;
display_mode disp_mode;
float refresh;
// figure out if we should use vertical sync by default
BScreen screen(this);
if (screen.IsValid())
{
display_mode mode;
screen.GetMode(&mode);
float refresh = (mode.timing.pixel_clock * 1000)
/ ((mode.timing.h_total)* (mode.timing.v_total));
vsync = (refresh < MIN_AUTO_VSYNC_REFRESH);
}
screen = new BScreen(this);
screen-> GetMode(&disp_mode);
refresh =
(disp_mode.timing.pixel_clock * 1000)/((disp_mode.timing.h_total)*
(disp_mode.timing.v_total));
if (refresh < 61)
{
vsync = true;
}
else
{
vsync = false;
}
delete screen;
mode = SelectDrawingMode(v_width, v_height);
// allocate bitmap buffers
for (int32 i = 0; i < 3; i++)
bitmap[i] = NULL;
fInitStatus = _AllocateBuffers(v_width, v_height, &mode);
// remember current settings
i_width = frame.IntegerWidth();
i_height = frame.IntegerHeight();
// make sure we layout the view correctly
FrameResized(i_width, i_height);
if (mode == OVERLAY)
if (fInitStatus >= B_OK && mode == OVERLAY)
{
overlay_restrictions r;
......@@ -154,7 +198,6 @@ VideoWindow::VideoWindow( int v_width, int v_height,
SetSizeLimits((i_width * r.min_width_scale), i_width * r.max_width_scale,
(i_height * r.min_height_scale), i_height * r.max_height_scale);
}
Show();
}
VideoWindow::~VideoWindow()
......@@ -163,63 +206,156 @@ VideoWindow::~VideoWindow()
teardownwindow = true;
wait_for_thread(fDrawThreadID, &result);
delete bitmap[0];
delete bitmap[1];
delete bitmap[2];
_FreeBuffers();
}
void VideoWindow::MessageReceived( BMessage *p_message )
/*****************************************************************************
* VideoWindow::MessageReceived
*****************************************************************************/
void
VideoWindow::MessageReceived( BMessage *p_message )
{
switch( p_message->what )
{
case TOGGLE_FULL_SCREEN:
BWindow::Zoom();
break;
case RESIZE_100:
case RESIZE_200:
if (is_zoomed)
BWindow::Zoom();
_SetVideoSize(p_message->what);
break;
case VERT_SYNC:
vsync = !vsync;
break;
case WINDOW_FEEL:
{
window_feel winFeel;
if (p_message->FindInt32("WinFeel", (int32*)&winFeel) == B_OK)
{
SetFeel(winFeel);
fCachedFeel = winFeel;
}
}
break;
case ASPECT_CORRECT:
SetCorrectAspectRatio(!fCorrectAspect);
break;
default:
BWindow::MessageReceived( p_message );
break;
}
}
/*****************************************************************************
* VideoWindow::Zoom
*****************************************************************************/
void
VideoWindow::Zoom(BPoint origin, float width, float height )
{
if(is_zoomed)
{
MoveTo(winSize.left, winSize.top);
ResizeTo(winSize.IntegerWidth(), winSize.IntegerHeight());
be_app->ShowCursor();
fInterfaceShowing = true;
}
else
{
BScreen screen(this);
BRect rect = screen.Frame();
Activate();
MoveTo(0.0, 0.0);
ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
be_app->ObscureCursor();
fInterfaceShowing = false;
}
is_zoomed = !is_zoomed;
}
/*****************************************************************************
* VideoWindow::FrameMoved
*****************************************************************************/
void
VideoWindow::FrameMoved(BPoint origin)
{
if (is_zoomed) return ;
winSize = Frame();
}
/*****************************************************************************
* VideoWindow::FrameResized
*****************************************************************************/
void
VideoWindow::FrameResized( float width, float height )
{
switch( p_message->what )
int32 useWidth = fCorrectAspect ? i_width : fTrueWidth;
int32 useHeight = fCorrectAspect ? i_height : fTrueHeight;
float out_width, out_height;
float out_left, out_top;
float width_scale = width / useWidth;
float height_scale = height / useHeight;
if (width_scale <= height_scale)
{
case TOGGLE_FULL_SCREEN:
((BWindow *)this)->Zoom();
break;
case RESIZE_100:
if (is_zoomed)
{
((BWindow *)this)->Zoom();
}
ResizeTo(i_width, i_height);
break;
case RESIZE_200:
if (is_zoomed)
{
((BWindow *)this)->Zoom();
}
ResizeTo(i_width * 2, i_height * 2);
break;
case VERT_SYNC:
vsync = !vsync;
break;
case WINDOW_FEEL:
{
int16 winFeel;
if (p_message->FindInt16("WinFeel", &winFeel) == B_OK)
{
SetFeel((window_feel)winFeel);
}
}
break;
default:
BWindow::MessageReceived( p_message );
break;
out_width = (useWidth * width_scale);
out_height = (useHeight * width_scale);
out_left = 0;
out_top = (height - out_height) / 2;
}
else /* if the height is proportionally smaller */
{
out_width = (useWidth * height_scale);
out_height = (useHeight * height_scale);
out_top = 0;
out_left = (width - out_width) / 2;
}
view->MoveTo(out_left,out_top);
view->ResizeTo(out_width, out_height);
if (!is_zoomed)
winSize = Frame();
}
/*****************************************************************************
* VideoWindow::ScreenChanged
*****************************************************************************/
void
VideoWindow::ScreenChanged(BRect frame, color_space format)
{
BScreen screen(this);
display_mode mode;
screen.GetMode(&mode);
float refresh = (mode.timing.pixel_clock * 1000)
/ ((mode.timing.h_total) * (mode.timing.v_total));
if (refresh < MIN_AUTO_VSYNC_REFRESH)
vsync = true;
}
/*****************************************************************************
* VideoWindow::Activate
*****************************************************************************/
void
VideoWindow::WindowActivated(bool active)
{
}
void VideoWindow::drawBuffer(int bufferIndex)
/*****************************************************************************
* VideoWindow::drawBuffer
*****************************************************************************/
void
VideoWindow::drawBuffer(int bufferIndex)
{
i_buffer = bufferIndex;
// sync to the screen if required
if (vsync)
{
BScreen *screen;
screen = new BScreen(this);
screen-> WaitForRetrace(22000);
delete screen;
BScreen screen(this);
screen.WaitForRetrace(22000);
}
if (LockLooper())
if (fInitStatus >= B_OK && LockLooper())
{
// switch the overlay bitmap
if (mode == OVERLAY)
......@@ -229,107 +365,86 @@ void VideoWindow::drawBuffer(int bufferIndex)
bitmap[i_buffer]->Bounds() ,
view->Bounds(),
&key, B_FOLLOW_ALL,
B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL|
B_OVERLAY_FILTER_HORIZONTAL|B_OVERLAY_FILTER_VERTICAL|
B_OVERLAY_TRANSFER_CHANNEL);
view->SetViewColor(key);
}
else
{
// switch the bitmap
view-> DrawBitmap(bitmap[i_buffer], view->Bounds() );
view->DrawBitmap(bitmap[i_buffer], view->Bounds() );
}
UnlockLooper();
}
}
void VideoWindow::Zoom(BPoint origin, float width, float height )
{
if(is_zoomed)
{
is_zoomed = !is_zoomed;
MoveTo(winSize.left, winSize.top);
ResizeTo(winSize.IntegerWidth(), winSize.IntegerHeight());
be_app->ShowCursor();
}
else
{
is_zoomed = !is_zoomed;
BScreen *screen;
screen = new BScreen(this);
BRect rect = screen->Frame();
delete screen;
MoveTo(0,0);
ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
be_app->ObscureCursor();
}
}
void VideoWindow::FrameMoved(BPoint origin)
/*****************************************************************************
* VideoWindow::SetInterfaceShowing
*****************************************************************************/
void
VideoWindow::ToggleInterfaceShowing()
{
if (is_zoomed) return ;
winSize = Frame();
SetInterfaceShowing(!fInterfaceShowing);
}
void VideoWindow::FrameResized( float width, float height )
/*****************************************************************************
* VideoWindow::SetInterfaceShowing
*****************************************************************************/
void
VideoWindow::SetInterfaceShowing(bool showIt)
{
float out_width, out_height;
float out_left, out_top;
float width_scale = width / i_width;
float height_scale = height / i_height;
if (width_scale <= height_scale)
{
out_width = (i_width * width_scale);
out_height = (i_height * width_scale);
out_left = 0;
out_top = (height - out_height) / 2;
}
else /* if the height is proportionally smaller */
{
out_width = (i_width * height_scale);
out_height = (i_height * height_scale);
out_top = 0;
out_left = (width - out_width) /2;
}
view->MoveTo(out_left,out_top);
view->ResizeTo(out_width, out_height);
if (!is_zoomed)
BWindow* window = get_interface_window();
if (window)
{
winSize = Frame();
}
}
void VideoWindow::ScreenChanged(BRect frame, color_space mode)
{
BScreen *screen;
float refresh;
screen = new BScreen(this);
display_mode disp_mode;
screen-> GetMode(&disp_mode);
refresh =
(disp_mode.timing.pixel_clock * 1000)/((disp_mode.timing.h_total)*
(disp_mode.timing.v_total));
if (refresh < 61)
{
vsync = true;
}
if (showIt)
{
if (fCachedFeel != B_NORMAL_WINDOW_FEEL)
SetFeel(B_NORMAL_WINDOW_FEEL);
window->Activate(true);
SendBehind(window);
}
else
{
SetFeel(fCachedFeel);
Activate(true);
window->SendBehind(this);
}
fInterfaceShowing = showIt;
}
}
void VideoWindow::WindowActivated(bool active)
/*****************************************************************************
* VideoWindow::SetCorrectAspectRatio
*****************************************************************************/
void
VideoWindow::SetCorrectAspectRatio(bool doIt)
{
if (fCorrectAspect != doIt)
{
fCorrectAspect = doIt;
FrameResized(Bounds().Width(), Bounds().Height());
}
}
int VideoWindow::SelectDrawingMode(int width, int height)
/*****************************************************************************
* VideoWindow::_AllocateBuffers
*****************************************************************************/
status_t
VideoWindow::_AllocateBuffers(int width, int height, int* mode)
{
int drawingMode = BITMAP;
// clear any old buffers
_FreeBuffers();
// set default mode
*mode = BITMAP;
BRect bitmapFrame( 0, 0, width, height );
// read from config, if we are supposed to use overlay at all
int noOverlay = !config_GetIntVariable( "overlay" );
// test for overlay capability
for (int i = 0; i < COLOR_COUNT; i++)
{
if (noOverlay) break;
bitmap[0] = new BBitmap ( BRect( 0, 0, width, height ),
bitmap[0] = new BBitmap ( bitmapFrame,
B_BITMAP_WILL_OVERLAY,
colspace[i].colspace);
......@@ -337,13 +452,13 @@ int VideoWindow::SelectDrawingMode(int width, int height)
{
colspace_index = i;
bitmap[1] = new BBitmap( BRect( 0, 0, width, height ), B_BITMAP_WILL_OVERLAY,
bitmap[1] = new BBitmap( bitmapFrame, B_BITMAP_WILL_OVERLAY,
colspace[colspace_index].colspace);
bitmap[2] = new BBitmap( BRect( 0, 0, width, height ), B_BITMAP_WILL_OVERLAY,
bitmap[2] = new BBitmap( bitmapFrame, B_BITMAP_WILL_OVERLAY,
colspace[colspace_index].colspace);
if ( (bitmap[2] && bitmap[2]->InitCheck() == B_OK) )
{
drawingMode = OVERLAY;
*mode = OVERLAY;
rgb_color key;
view->SetViewOverlay(bitmap[0],
bitmap[0]->Bounds() ,
......@@ -356,35 +471,166 @@ int VideoWindow::SelectDrawingMode(int width, int height)
}
else
{
delete bitmap[0];
delete bitmap[1];
delete bitmap[2];
_FreeBuffers();
*mode = BITMAP; // might want to try again with normal bitmaps
}
}
else
{
delete bitmap[0];
}
}
if (drawingMode == BITMAP)
if (*mode == BITMAP)
{
// fallback to RGB32
colspace_index = DEFAULT_COL;
SetTitle(VOUT_TITLE " (Bitmap)");
bitmap[0] = new BBitmap( BRect( 0, 0, width, height ), colspace[colspace_index].colspace);
bitmap[1] = new BBitmap( BRect( 0, 0, width, height ), colspace[colspace_index].colspace);
bitmap[2] = new BBitmap( BRect( 0, 0, width, height ), colspace[colspace_index].colspace);
bitmap[0] = new BBitmap( bitmapFrame, colspace[colspace_index].colspace);
bitmap[1] = new BBitmap( bitmapFrame, colspace[colspace_index].colspace);
bitmap[2] = new BBitmap( bitmapFrame, colspace[colspace_index].colspace);
}
return drawingMode;
// see if everything went well
status_t status = B_ERROR;
for (int32 i = 0; i < 3; i++)
{
if (bitmap[i])
status = bitmap[i]->InitCheck();
if (status < B_OK)
break;
}
if (status >= B_OK)
{
// clear bitmaps to black
for (int32 i = 0; i < 3; i++)
_BlankBitmap(bitmap[i]);
}
return status;
}
/*****************************************************************************
* VLCView::VLCView
* VideoWindow::_FreeBuffers
*****************************************************************************/
VLCView::VLCView(BRect bounds) : BView(bounds, "", B_FOLLOW_NONE,
B_WILL_DRAW)
void
VideoWindow::_FreeBuffers()
{
delete bitmap[0];
bitmap[0] = NULL;
delete bitmap[1];
bitmap[1] = NULL;
delete bitmap[2];
bitmap[2] = NULL;
fInitStatus = B_ERROR;
}
/*****************************************************************************
* VideoWindow::_BlankBitmap
*****************************************************************************/
void
VideoWindow::_BlankBitmap(BBitmap* bitmap) const
{
// no error checking (we do that earlier on and since it's a private function...
// YCbCr:
// Loss/Saturation points are Y 16-235 (absoulte); Cb/Cr 16-240 (center 128)
// YUV:
// Extrema points are Y 0 - 207 (absolute) U -91 - 91 (offset 128) V -127 - 127 (offset 128)
// we only handle weird colorspaces with special care
switch (bitmap->ColorSpace()) {
case B_YCbCr422: {
// Y0[7:0] Cb0[7:0] Y1[7:0] Cr0[7:0] Y2[7:0] Cb2[7:0] Y3[7:0] Cr2[7:0]
int32 height = bitmap->Bounds().IntegerHeight() + 1;
uint8* bits = (uint8*)bitmap->Bits();
int32 bpr = bitmap->BytesPerRow();
for (int32 y = 0; y < height; y++) {
// handle 2 bytes at a time
for (int32 i = 0; i < bpr; i += 2) {
// offset into line
bits[i] = 16;
bits[i + 1] = 128;
}
// next line
bits += bpr;
}
break;
}
case B_YCbCr420: {
// TODO: untested!!
// Non-interlaced only, Cb0 Y0 Y1 Cb2 Y2 Y3 on even scan lines ...
// Cr0 Y0 Y1 Cr2 Y2 Y3 on odd scan lines
int32 height = bitmap->Bounds().IntegerHeight() + 1;
uint8* bits = (uint8*)bitmap->Bits();
int32 bpr = bitmap->BytesPerRow();
for (int32 y = 0; y < height; y += 1) {
// handle 3 bytes at a time
for (int32 i = 0; i < bpr; i += 3) {
// offset into line
bits[i] = 128;
bits[i + 1] = 16;
bits[i + 2] = 16;
}
// next line
bits += bpr;
}
break;
}
case B_YUV422: {
// TODO: untested!!
// U0[7:0] Y0[7:0] V0[7:0] Y1[7:0] U2[7:0] Y2[7:0] V2[7:0] Y3[7:0]
int32 height = bitmap->Bounds().IntegerHeight() + 1;
uint8* bits = (uint8*)bitmap->Bits();
int32 bpr = bitmap->BytesPerRow();
for (int32 y = 0; y < height; y += 1) {
// handle 2 bytes at a time
for (int32 i = 0; i < bpr; i += 2) {
// offset into line
bits[i] = 128;
bits[i + 1] = 0;
}
// next line
bits += bpr;
}
break;
}
default:
memset(bitmap->Bits(), 0, bitmap->BitsLength());
break;
}
}
/*****************************************************************************
* VideoWindow::_SetVideoSize
*****************************************************************************/
void
VideoWindow::_SetVideoSize(uint32 mode)
{
// let size depend on aspect correction
int32 width = fCorrectAspect ? i_width : fTrueWidth;
int32 height = fCorrectAspect ? i_height : fTrueHeight;
switch (mode)
{
case RESIZE_200:
width *= 2;
height *= 2;
break;
case RESIZE_100:
default:
break;
}
ResizeTo(width, height);
is_zoomed = false;
}
/*****************************************************************************
* VLCView::VLCView
*****************************************************************************/
VLCView::VLCView(BRect bounds)
: BView(bounds, "video view", B_FOLLOW_NONE, B_WILL_DRAW | B_PULSE_NEEDED),
fLastMouseMovedTime(system_time()),
fCursorHidden(false),
fCursorInside(false)
{
SetViewColor(B_TRANSPARENT_32_BIT);
}
......@@ -396,77 +642,198 @@ VLCView::~VLCView()
{
}
/*****************************************************************************
* VLCVIew::AttachedToWindow
*****************************************************************************/
void
VLCView::AttachedToWindow()
{
// in order to get keyboard events
MakeFocus(true);
// periodically check if we want to hide the pointer
Window()->SetPulseRate(1000000);
}
/*****************************************************************************
* VLCVIew::MouseDown
*****************************************************************************/
void VLCView::MouseDown(BPoint point)
void
VLCView::MouseDown(BPoint where)
{
BMessage* msg = Window()->CurrentMessage();
int32 clicks = msg->FindInt32("clicks");
VideoWindow* videoWindow = dynamic_cast<VideoWindow*>(Window());
BMessage* msg = Window()->CurrentMessage();
int32 clicks;
uint32 buttons;
msg->FindInt32("clicks", &clicks);
msg->FindInt32("buttons", (int32*)&buttons);
if (videoWindow)
{
if (buttons & B_PRIMARY_MOUSE_BUTTON)
{
if (clicks == 2)
Window()->Zoom();
else
videoWindow->ToggleInterfaceShowing();
}
else
{
if (buttons & B_SECONDARY_MOUSE_BUTTON)
{
BPopUpMenu *menu = new BPopUpMenu("context menu");
menu->SetRadioMode(false);
// Toggle FullScreen
BMenuItem *zoomItem = new BMenuItem("Fullscreen", new BMessage(TOGGLE_FULL_SCREEN));
zoomItem->SetMarked(videoWindow->is_zoomed);
menu->AddItem(zoomItem);
// Resize to 100%
BMenuItem *origItem = new BMenuItem("100%", new BMessage(RESIZE_100));
menu->AddItem(origItem);
// Resize to 200%
BMenuItem *doubleItem = new BMenuItem("200%", new BMessage(RESIZE_200));
menu->AddItem(doubleItem);
menu->AddSeparatorItem();
// Toggle vSync
BMenuItem *vsyncItem = new BMenuItem("Vertical Sync", new BMessage(VERT_SYNC));
vsyncItem->SetMarked(videoWindow->vsync);
menu->AddItem(vsyncItem);
// Correct Aspect Ratio
BMenuItem *aspectItem = new BMenuItem("Correct Aspect Ratio", new BMessage(ASPECT_CORRECT));
aspectItem->SetMarked(videoWindow->CorrectAspectRatio());
menu->AddItem(aspectItem);
menu->AddSeparatorItem();
// Windwo Feel Items
BMessage *winNormFeel = new BMessage(WINDOW_FEEL);
winNormFeel->AddInt32("WinFeel", (int32)B_NORMAL_WINDOW_FEEL);
BMenuItem *normWindItem = new BMenuItem("Normal Window", winNormFeel);
normWindItem->SetMarked(videoWindow->Feel() == B_NORMAL_WINDOW_FEEL);
menu->AddItem(normWindItem);
BMessage *winFloatFeel = new BMessage(WINDOW_FEEL);
winFloatFeel->AddInt32("WinFeel", (int32)B_FLOATING_APP_WINDOW_FEEL);
BMenuItem *onTopWindItem = new BMenuItem("App Top", winFloatFeel);
onTopWindItem->SetMarked(videoWindow->Feel() == B_FLOATING_APP_WINDOW_FEEL);
menu->AddItem(onTopWindItem);
BMessage *winAllFeel = new BMessage(WINDOW_FEEL);
winAllFeel->AddInt32("WinFeel", (int32)B_FLOATING_ALL_WINDOW_FEEL);
BMenuItem *allSpacesWindItem = new BMenuItem("On Top All Workspaces", winAllFeel);
allSpacesWindItem->SetMarked(videoWindow->Feel() == B_FLOATING_ALL_WINDOW_FEEL);
menu->AddItem(allSpacesWindItem);
menu->SetTargetForItems(this);
ConvertToScreen(&where);
menu->Go(where, true, false, true);
}
}
}
fLastMouseMovedTime = system_time();
fCursorHidden = false;
}
VideoWindow *vWindow = (VideoWindow *)Window();
uint32 mouseButtons;
BPoint where;
GetMouse(&where, &mouseButtons, true);
/*****************************************************************************
* VLCVIew::MouseMoved
*****************************************************************************/
void
VLCView::MouseMoved(BPoint point, uint32 transit, const BMessage* dragMessage)
{
fLastMouseMovedTime = system_time();
fCursorHidden = false;
fCursorInside = (transit == B_INSIDE_VIEW || transit == B_ENTERED_VIEW);
}
if ((mouseButtons & B_PRIMARY_MOUSE_BUTTON) && (clicks == 2))
{
Window()->Zoom();
return;
}
else
{
if (mouseButtons & B_SECONDARY_MOUSE_BUTTON)
{
BPopUpMenu *menu = new BPopUpMenu("context menu");
menu->SetRadioMode(false);
// Toggle FullScreen
BMenuItem *zoomItem = new BMenuItem("Fullscreen", new BMessage(TOGGLE_FULL_SCREEN));
zoomItem->SetMarked(vWindow->is_zoomed);
menu->AddItem(zoomItem);
// Resize to 100%
BMenuItem *origItem = new BMenuItem("100%", new BMessage(RESIZE_100));
menu->AddItem(origItem);
// Resize to 200%
BMenuItem *doubleItem = new BMenuItem("200%", new BMessage(RESIZE_200));
menu->AddItem(doubleItem);
menu->AddSeparatorItem();
// Toggle vSync
BMenuItem *vsyncItem = new BMenuItem("Vertical Sync", new BMessage(VERT_SYNC));
vsyncItem->SetMarked(vWindow->vsync);
menu->AddItem(vsyncItem);
menu->AddSeparatorItem();
// Windwo Feel Items
BMessage *winNormFeel = new BMessage(WINDOW_FEEL);
winNormFeel->AddInt16("WinFeel", (int16)B_NORMAL_WINDOW_FEEL);
BMenuItem *normWindItem = new BMenuItem("Normal Window", winNormFeel);
normWindItem->SetMarked(vWindow->Feel() == B_NORMAL_WINDOW_FEEL);
menu->AddItem(normWindItem);
BMessage *winFloatFeel = new BMessage(WINDOW_FEEL);
winFloatFeel->AddInt16("WinFeel", (int16)B_FLOATING_APP_WINDOW_FEEL);
BMenuItem *onTopWindItem = new BMenuItem("App Top", winFloatFeel);
onTopWindItem->SetMarked(vWindow->Feel() == B_FLOATING_APP_WINDOW_FEEL);
menu->AddItem(onTopWindItem);
BMessage *winAllFeel = new BMessage(WINDOW_FEEL);
winAllFeel->AddInt16("WinFeel", (int16)B_FLOATING_ALL_WINDOW_FEEL);
BMenuItem *allSpacesWindItem = new BMenuItem("On Top All Workspaces", winAllFeel);
allSpacesWindItem->SetMarked(vWindow->Feel() == B_FLOATING_ALL_WINDOW_FEEL);
menu->AddItem(allSpacesWindItem);
menu->SetTargetForItems(this);
ConvertToScreen(&where);
menu->Go(where, true, false, true);
}
}
/*****************************************************************************
* VLCVIew::Pulse
*****************************************************************************/
void
VLCView::Pulse()
{
// We are getting the pulse messages no matter if the mouse is over
// this view. If we are in full screen mode, we want to hide the cursor
// even if it is not.
if (!fCursorHidden) {
VideoWindow *videoWindow = dynamic_cast<VideoWindow*>(Window());
if (fCursorInside
&& system_time() - fLastMouseMovedTime > MOUSE_IDLE_TIMEOUT) {
be_app->ObscureCursor();
fCursorHidden = true;
// hide the interface window as well
videoWindow->SetInterfaceShowing(false);
}
}
}
/*****************************************************************************
* VLCVIew::KeyDown
*****************************************************************************/
void
VLCView::KeyDown(const char *bytes, int32 numBytes)
{
VideoWindow *videoWindow = dynamic_cast<VideoWindow*>(Window());
BWindow* interfaceWindow = get_interface_window();
if (videoWindow && numBytes > 0) {
uint32 mods = modifiers();
switch (*bytes) {
case B_TAB:
// toggle window and full screen mode
// not passing on the tab key to the default KeyDown()
// implementation also avoids loosing the keyboard focus
videoWindow->PostMessage(TOGGLE_FULL_SCREEN);
break;
case B_ESCAPE:
// go back to window mode
if (videoWindow->is_zoomed)
videoWindow->PostMessage(TOGGLE_FULL_SCREEN);
break;
case B_SPACE:
// toggle playback
if (interfaceWindow)
interfaceWindow->PostMessage(PAUSE_PLAYBACK);
break;
case B_RIGHT_ARROW:
if (interfaceWindow)
{
if (mods & B_SHIFT_KEY)
// next title
interfaceWindow->PostMessage(NEXT_CHAPTER);
else
// next chapter
interfaceWindow->PostMessage(NEXT_TITLE);
}
break;
case B_LEFT_ARROW:
if (interfaceWindow)
{
if (mods & B_SHIFT_KEY)
// previous title
interfaceWindow->PostMessage(PREV_CHAPTER);
else
// previous chapter
interfaceWindow->PostMessage(PREV_TITLE);
}
break;
case B_UP_ARROW:
// previous file in playlist?
break;
case B_DOWN_ARROW:
// next file in playlist?
break;
default:
BView::KeyDown(bytes, numBytes);
break;
}
}
}
/*****************************************************************************
* VLCVIew::Draw
*****************************************************************************/
void VLCView::Draw(BRect updateRect)
void
VLCView::Draw(BRect updateRect)
{
VideoWindow *win = (VideoWindow *) Window();
if (win->mode == BITMAP)
......@@ -679,11 +1046,14 @@ static int BeosOpenDisplay( vout_thread_t *p_vout )
20 + p_vout->i_window_width - 1,
50 + p_vout->i_window_height - 1 ));
if( p_vout->p_sys->p_window == NULL )
if( p_vout->p_sys->p_window->InitCheck() < B_OK)
{
delete p_vout->p_sys->p_window;
p_vout->p_sys->p_window = NULL;
intf_ErrMsg( "error: cannot allocate memory for VideoWindow" );
return( 1 );
}
} else
p_vout->p_sys->p_window->Show();
return( 0 );
}
......
......@@ -2,7 +2,7 @@
* beos_init.cpp: Initialization for BeOS specific features
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: beos_specific.cpp,v 1.18 2002/04/26 05:43:37 sam Exp $
* $Id: beos_specific.cpp,v 1.18.2.1 2002/09/03 12:00:24 tcastley Exp $
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
*
......@@ -24,6 +24,8 @@
#include <Roster.h>
#include <Path.h>
#include <Alert.h>
#include <Message.h>
#include <Window.h>
#include <stdio.h>
#include <string.h> /* strdup() */
#include <malloc.h> /* free() */
......@@ -44,6 +46,12 @@ public:
virtual void ReadyToRun();
virtual void AboutRequested();
virtual void RefsReceived(BMessage* message);
virtual void MessageReceived(BMessage* message);
private:
BWindow* fInterfaceWindow;
BMessage* fRefsMessage;
};
/*****************************************************************************
......@@ -54,6 +62,9 @@ static vlc_mutex_t app_lock;
static vlc_cond_t app_wait;
static char *psz_program_path;
//const uint32 INTERFACE_CREATED = 'ifcr'; /* message sent from interface */
#include "../../plugins/beos/MsgVals.h"
extern "C"
{
......@@ -131,7 +142,9 @@ static void system_AppThread( void * args )
* VlcApplication: application constructor
*****************************************************************************/
VlcApplication::VlcApplication( char * psz_mimetype )
:BApplication( psz_mimetype )
:BApplication( psz_mimetype ),
fInterfaceWindow( NULL ),
fRefsMessage( NULL )
{
/* Nothing to do, we use the default constructor */
}
......@@ -142,6 +155,7 @@ VlcApplication::VlcApplication( char * psz_mimetype )
VlcApplication::~VlcApplication( )
{
/* Nothing to do, we use the default destructor */
delete fRefsMessage;
}
/*****************************************************************************
......@@ -177,3 +191,47 @@ void VlcApplication::ReadyToRun( )
vlc_mutex_unlock( &app_lock );
}
/*****************************************************************************
* RefsReceived: called when files are sent to our application
* (for example when the user drops fils onto our icon)
*****************************************************************************/
void VlcApplication::RefsReceived(BMessage* message)
{
if (fInterfaceWindow)
fInterfaceWindow->PostMessage(message);
else {
delete fRefsMessage;
fRefsMessage = new BMessage(*message);
}
}
/*****************************************************************************
* MessageReceived: a BeOS applications main message loop
* Since VlcApplication and interface are separated
* in the vlc binary and the interface plugin,
* we use this method to "stick" them together.
* The interface will post a message to the global
* "be_app" pointer when the interface is created
* containing a pointer to the interface window.
* In this way, we can keep a B_REFS_RECEIVED message
* in store for the interface window to handle later.
*****************************************************************************/
void VlcApplication::MessageReceived(BMessage* message)
{
switch (message->what) {
case INTERFACE_CREATED: {
BWindow* interfaceWindow;
if (message->FindPointer("window", (void**)&interfaceWindow) == B_OK) {
fInterfaceWindow = interfaceWindow;
if (fRefsMessage) {
fInterfaceWindow->PostMessage(fRefsMessage);
delete fRefsMessage;
fRefsMessage = NULL;
}
}
break;
}
default:
BApplication::MessageReceived(message);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment