📄 mediacontrolview.cpp
字号:
/***************************************************************************** * MediaControlView.cpp: beos interface ***************************************************************************** * Copyright (C) 1999, 2000, 2001 VideoLAN * $Id: MediaControlView.cpp 10509 2005-04-01 22:01:24Z titer $ * * 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************//* System headers */#include <InterfaceKit.h>#include <AppKit.h>#include <String.h>#include <string.h>/* VLC headers */#include <vlc/vlc.h>#include <vlc/intf.h>#include <vlc/input.h>extern "C"{ #include <audio_output.h>}/* BeOS interface headers */#include "Bitmaps.h"#include "DrawingTidbits.h"#include "InterfaceWindow.h"#include "MsgVals.h"#include "TransportButton.h"#include "ListViews.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// slider colors are hardcoded here, because that's just// what they currently are within those bitmapsconst 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 };#define DISABLED_SEEK_MESSAGE _("Drop files to play")#define SEEKSLIDER_RANGE 2048enum{ MSG_REWIND = 'rwnd', MSG_FORWARD = 'frwd', MSG_SKIP_BACKWARDS = 'skpb', MSG_SKIP_FORWARD = 'skpf',};// constructorMediaControlView::MediaControlView( intf_thread_t * _p_intf, BRect frame) : BBox(frame, NULL, B_FOLLOW_NONE, B_WILL_DRAW | B_FRAME_EVENTS | B_PULSE_NEEDED, B_PLAIN_BORDER), p_intf( _p_intf ), fCurrentRate(INPUT_RATE_DEFAULT), fCurrentStatus(-1), fBottomControlHeight(0.0), fIsEnabled( true ){ BRect frame(0.0, 0.0, 10.0, 10.0); // Seek Slider fSeekSlider = new SeekSlider( p_intf, frame, "seek slider", this ); 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", 1, AOUT_VOLUME_MAX, new BMessage(VOLUME_CHG)); fVolumeSlider->SetValue( config_GetInt( p_intf, "volume" ) ); AddChild( fVolumeSlider ); // Position Info View fPositionInfo = new PositionInfoView(BRect(0.0, 0.0, 10.0, 10.0), "led", p_intf); fPositionInfo->ResizeToPreferred(); AddChild( fPositionInfo );}// destructorMediaControlView::~MediaControlView(){}// AttachedToWindowvoidMediaControlView::AttachedToWindow(){ // 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()) { float width, height; menuBar->GetPreferredSize(&width, &height);// r.bottom += menuBar->Bounds().Height(); r.bottom += height; // see that our calculated minimal width is not smaller than what // the menubar can be width -= r.Width(); if (width > 0.0) r.right += width; } Window()->SetSizeLimits(r.Width(), r.Width() * 1.8, r.Height(), r.Height() * 1.3); 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);}// FrameResizedvoidMediaControlView::FrameResized(float width, float height){ 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);}// GetPreferredSizevoidMediaControlView::GetPreferredSize(float* width, float* height){ if (width && height) { BRect r(_MinFrame()); *width = r.Width(); *height = r.Height(); }}// MessageReceivedvoidMediaControlView::MessageReceived(BMessage* message){ switch (message->what) { case MSG_REWIND: break; case MSG_FORWARD: break; case MSG_SKIP_BACKWARDS: Window()->PostMessage(NAVIGATE_PREV); break; case MSG_SKIP_FORWARD: Window()->PostMessage(NAVIGATE_NEXT); break; default: BBox::MessageReceived(message); break; }}// PulsevoidMediaControlView::Pulse(){ InterfaceWindow* window = dynamic_cast<InterfaceWindow*>(Window()); if (window && window->IsStopped()) fPlayPause->SetStopped(); unsigned short i_volume; aout_VolumeGet( p_intf, (audio_volume_t*)&i_volume ); fVolumeSlider->SetValue( i_volume );}// SetProgressvoidMediaControlView::SetProgress( float position ){ fSeekSlider->SetPosition( position );}// SetStatusvoidMediaControlView::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: fPlayPause->SetPlaying(); break; case PAUSE_S: fPlayPause->SetPaused(); break; default: fPlayPause->SetStopped(); break; } if (rate != fCurrentRate) { fCurrentRate = rate; if ( rate < INPUT_RATE_DEFAULT ) { // TODO: ... } }}// SetEnabledvoidMediaControlView::SetEnabled(bool enabled){ if( ( enabled && fIsEnabled ) || ( !enabled && !fIsEnabled ) ) { /* do not redraw if it is not necessary */ return; } if( LockLooper() ) { 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 ); UnlockLooper(); fIsEnabled = enabled; }}// SetAudioEnabledvoidMediaControlView::SetAudioEnabled(bool enabled){ fMute->SetEnabled(enabled); fVolumeSlider->SetEnabled(enabled);}// GetVolumeuint32MediaControlView::GetVolume() const{ return fVolumeSlider->Value();}// SetSkippablevoidMediaControlView::SetSkippable(bool backward, bool forward){ fSkipBack->SetEnabled(backward); fSkipForward->SetEnabled(forward);}// SetMutedvoidMediaControlView::SetMuted(bool mute){ fVolumeSlider->SetMuted(mute);}// _LayoutControlsvoidMediaControlView::_LayoutControls(BRect frame) const{ // seek slider BRect r(frame); // 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; // layout time slider and info view float width, height; fPositionInfo->GetBigPreferredSize( &width, &height ); float ratio = width / height; width = r.Height() * ratio; if (frame.Width() - minWidth - MIN_SPACE >= width && frame.Height() >= height) { r.right = r.left + width; fPositionInfo->SetMode(PositionInfoView::MODE_BIG); _LayoutControl(fPositionInfo, r, true, true); frame.left = r.right + MIN_SPACE; r.left = frame.left; r.right = frame.right; // r.bottom = r.top + r.Height() / 2.0 - MIN_SPACE / 2.0; r.bottom = r.top + fSeekSlider->Bounds().Height(); _LayoutControl(fSeekSlider, r, true); } else { fPositionInfo->GetPreferredSize( &width, &height ); fPositionInfo->SetMode(PositionInfoView::MODE_SMALL); fPositionInfo->ResizeTo(width, height); r.bottom = r.top + r.Height() / 2.0 - MIN_SPACE / 2.0; r.right = r.left + fPositionInfo->Bounds().Width(); _LayoutControl(fPositionInfo, r, true ); r.left = r.right + MIN_SPACE; r.right = frame.right; _LayoutControl(fSeekSlider, r, true); } 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.left = frame.left; 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);}// _MinFrameBRect MediaControlView::_MinFrame() const{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -