Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

MediaControlView.cpp

00001 /*****************************************************************************
00002  * MediaControlView.cpp: beos interface
00003  *****************************************************************************
00004  * Copyright (C) 1999, 2000, 2001 the VideoLAN team
00005  * $Id: MediaControlView.cpp 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Tony Castley <[email protected]>
00008  *          Stephan Aßmus <[email protected]>
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00023  *****************************************************************************/
00024 
00025 /* System headers */
00026 #include <InterfaceKit.h>
00027 #include <AppKit.h>
00028 #include <String.h>
00029 #include <string.h>
00030 
00031 /* VLC headers */
00032 #include <vlc/vlc.h>
00033 #include <vlc/intf.h>
00034 #include <vlc/input.h>
00035 extern "C"
00036 {
00037   #include <audio_output.h>
00038 }
00039 
00040 /* BeOS interface headers */
00041 #include "Bitmaps.h"
00042 #include "DrawingTidbits.h"
00043 #include "InterfaceWindow.h"
00044 #include "MsgVals.h"
00045 #include "TransportButton.h"
00046 #include "ListViews.h"
00047 #include "MediaControlView.h"
00048 
00049 #define BORDER_INSET 6.0
00050 #define MIN_SPACE 4.0
00051 #define SPEAKER_SLIDER_DIST 6.0
00052 #define VOLUME_MIN_WIDTH 70.0
00053 #define DIM_LEVEL 0.4
00054 #define VOLUME_SLIDER_LAYOUT_WEIGHT 2.0
00055 #define SEEK_SLIDER_KNOB_WIDTH 8.0
00056 
00057 // slider colors are hardcoded here, because that's just
00058 // what they currently are within those bitmaps
00059 const rgb_color kGreen = (rgb_color){ 152, 203, 152, 255 };
00060 const rgb_color kGreenShadow = (rgb_color){ 102, 152, 102, 255 };
00061 const rgb_color kBackground = (rgb_color){ 216, 216, 216, 255 };
00062 const rgb_color kSeekGreen = (rgb_color){ 171, 221, 161, 255 };
00063 const rgb_color kSeekGreenShadow = (rgb_color){ 144, 186, 136, 255 };
00064 const rgb_color kSeekRed = (rgb_color){ 255, 0, 0, 255 };
00065 const rgb_color kSeekRedLight = (rgb_color){ 255, 152, 152, 255 };
00066 const rgb_color kSeekRedShadow = (rgb_color){ 178, 0, 0, 255 };
00067 
00068 #define DISABLED_SEEK_MESSAGE _("Drop files to play")
00069 #define SEEKSLIDER_RANGE 2048
00070 
00071 enum
00072 {
00073         MSG_REWIND                              = 'rwnd',
00074         MSG_FORWARD                             = 'frwd',
00075         MSG_SKIP_BACKWARDS              = 'skpb',
00076         MSG_SKIP_FORWARD                = 'skpf',
00077 };
00078 
00079 // constructor
00080 MediaControlView::MediaControlView( intf_thread_t * _p_intf, BRect frame)
00081         : BBox(frame, NULL, B_FOLLOW_NONE, B_WILL_DRAW | B_FRAME_EVENTS | B_PULSE_NEEDED,
00082                    B_PLAIN_BORDER),
00083       p_intf( _p_intf ),
00084       fCurrentRate(INPUT_RATE_DEFAULT),
00085       fCurrentStatus(-1),
00086       fBottomControlHeight(0.0),
00087       fIsEnabled( true )
00088 {
00089         BRect frame(0.0, 0.0, 10.0, 10.0);
00090         
00091     // Seek Slider
00092     fSeekSlider = new SeekSlider( p_intf, frame, "seek slider", this );
00093     fSeekSlider->SetValue(0);
00094     fSeekSlider->ResizeToPreferred();
00095     AddChild( fSeekSlider );
00096 
00097     // Buttons
00098     // Skip Back
00099     frame.SetRightBottom(kSkipButtonSize);
00100         fBottomControlHeight = kRewindBitmapHeight - 1.0;
00101     fSkipBack = new TransportButton(frame, B_EMPTY_STRING,
00102                                     kSkipBackBitmapBits,
00103                                     kPressedSkipBackBitmapBits,
00104                                     kDisabledSkipBackBitmapBits,
00105                                     new BMessage(MSG_SKIP_BACKWARDS));
00106     AddChild( fSkipBack );
00107 
00108         // Play Pause
00109     frame.SetRightBottom(kPlayButtonSize);
00110         if (fBottomControlHeight < kPlayPauseBitmapHeight - 1.0)
00111                 fBottomControlHeight = kPlayPauseBitmapHeight - 1.0;
00112     fPlayPause = new PlayPauseButton(frame, B_EMPTY_STRING,
00113                                      kPlayButtonBitmapBits,
00114                                      kPressedPlayButtonBitmapBits,
00115                                      kDisabledPlayButtonBitmapBits,
00116                                      kPlayingPlayButtonBitmapBits,
00117                                      kPressedPlayingPlayButtonBitmapBits,
00118                                      kPausedPlayButtonBitmapBits,
00119                                      kPressedPausedPlayButtonBitmapBits,
00120                                      new BMessage(START_PLAYBACK));
00121 
00122     AddChild( fPlayPause );
00123 
00124     // Skip Foward
00125     frame.SetRightBottom(kSkipButtonSize);
00126     fSkipForward = new TransportButton(frame, B_EMPTY_STRING,
00127                                        kSkipForwardBitmapBits,
00128                                        kPressedSkipForwardBitmapBits,
00129                                        kDisabledSkipForwardBitmapBits,
00130                                        new BMessage(MSG_SKIP_FORWARD));
00131     AddChild( fSkipForward );
00132 
00133         // Forward
00134         fForward = new TransportButton(frame, B_EMPTY_STRING,
00135                                                                    kForwardBitmapBits,
00136                                                                    kPressedForwardBitmapBits,
00137                                                                    kDisabledForwardBitmapBits,
00138                                                                    new BMessage(MSG_FORWARD));
00139 //      AddChild( fForward );
00140 
00141         // Rewind
00142         fRewind = new TransportButton(frame, B_EMPTY_STRING,
00143                                                                   kRewindBitmapBits,
00144                                                                   kPressedRewindBitmapBits,
00145                                                                   kDisabledRewindBitmapBits,
00146                                                                   new BMessage(MSG_REWIND));
00147 //      AddChild( fRewind );
00148 
00149     // Stop
00150     frame.SetRightBottom(kStopButtonSize);
00151         if (fBottomControlHeight < kStopBitmapHeight - 1.0)
00152                 fBottomControlHeight = kStopBitmapHeight - 1.0;
00153     fStop = new TransportButton(frame, B_EMPTY_STRING,
00154                                 kStopButtonBitmapBits,
00155                                 kPressedStopButtonBitmapBits,
00156                                 kDisabledStopButtonBitmapBits,
00157                                 new BMessage(STOP_PLAYBACK));
00158         AddChild( fStop );
00159 
00160         // Mute
00161     frame.SetRightBottom(kSpeakerButtonSize);
00162         if (fBottomControlHeight < kSpeakerIconBitmapHeight - 1.0)
00163                 fBottomControlHeight = kSpeakerIconBitmapHeight - 1.0;
00164     fMute = new TransportButton(frame, B_EMPTY_STRING,
00165                                 kSpeakerIconBits,
00166                                 kPressedSpeakerIconBits,
00167                                 kSpeakerIconBits,
00168                                 new BMessage(VOLUME_MUTE));
00169 
00170         AddChild( fMute );
00171 
00172     // Volume Slider
00173         fVolumeSlider = new VolumeSlider(BRect(0.0, 0.0, VOLUME_MIN_WIDTH,
00174                                                                                    kVolumeSliderBitmapHeight - 1.0),
00175                                                                          "volume slider", 1, AOUT_VOLUME_MAX,
00176                                                                          new BMessage(VOLUME_CHG));
00177         fVolumeSlider->SetValue( config_GetInt( p_intf, "volume" ) );
00178         AddChild( fVolumeSlider );
00179         
00180         // Position Info View
00181     fPositionInfo = new PositionInfoView(BRect(0.0, 0.0, 10.0, 10.0), "led",
00182                                          p_intf);
00183     fPositionInfo->ResizeToPreferred();
00184     AddChild( fPositionInfo );
00185 }
00186 
00187 // destructor
00188 MediaControlView::~MediaControlView()
00189 {
00190 }
00191 
00192 // AttachedToWindow
00193 void
00194 MediaControlView::AttachedToWindow()
00195 {
00196         // we are now a valid BHandler
00197         fRewind->SetTarget(this);
00198         fForward->SetTarget(this);
00199         fSkipBack->SetTarget(this);
00200         fSkipForward->SetTarget(this);
00201         fVolumeSlider->SetTarget(Window());
00202 
00203         BRect r(_MinFrame());
00204         if (BMenuBar* menuBar = Window()->KeyMenuBar()) {
00205                 float width, height;
00206                 menuBar->GetPreferredSize(&width, &height);
00207 //              r.bottom += menuBar->Bounds().Height();
00208                 r.bottom += height;
00209                 // see that our calculated minimal width is not smaller than what
00210                 // the menubar can be
00211                 width -= r.Width();
00212                 if (width > 0.0)
00213                         r.right += width;
00214         }
00215 
00216         Window()->SetSizeLimits(r.Width(), r.Width() * 1.8, r.Height(), r.Height() * 1.3);
00217         if (!Window()->Bounds().Contains(r))
00218                 Window()->ResizeTo(r.Width(), r.Height());
00219         else
00220                 FrameResized(Bounds().Width(), Bounds().Height());
00221 
00222         // get pulse message every two frames
00223         Window()->SetPulseRate(80000);
00224 }
00225 
00226 // FrameResized
00227 void
00228 MediaControlView::FrameResized(float width, float height)
00229 {
00230         BRect r(Bounds());
00231         // make sure we don't leave dirty pixels
00232         // (B_FULL_UPDATE_ON_RESIZE == annoying flicker -> this is smarter)
00233         if (fOldBounds.Width() < r.Width())
00234                 Invalidate(BRect(fOldBounds.right, fOldBounds.top + 1.0,
00235                                                  fOldBounds.right, fOldBounds.bottom - 1.0));
00236         else
00237                 Invalidate(BRect(r.right, r.top + 1.0,
00238                                                  r.right, r.bottom - 1.0));
00239         if (fOldBounds.Height() < r.Height())
00240                 Invalidate(BRect(fOldBounds.left + 1.0, fOldBounds.bottom,
00241                                                  fOldBounds.right - 1.0, fOldBounds.bottom));
00242         else
00243                 Invalidate(BRect(r.left + 1.0, r.bottom,
00244                                                  r.right - 1.0, r.bottom));
00245         // remember for next time
00246         fOldBounds = r;
00247         // layout controls
00248         r.InsetBy(BORDER_INSET, BORDER_INSET);
00249         _LayoutControls(r);
00250 }
00251 
00252 // GetPreferredSize
00253 void
00254 MediaControlView::GetPreferredSize(float* width, float* height)
00255 {
00256         if (width && height)
00257         {
00258                 BRect r(_MinFrame());
00259                 *width = r.Width();
00260                 *height = r.Height();
00261         }
00262 }
00263 
00264 // MessageReceived
00265 void
00266 MediaControlView::MessageReceived(BMessage* message)
00267 {
00268         switch (message->what)
00269         {
00270                 case MSG_REWIND:
00271                         break;
00272                 case MSG_FORWARD:
00273                         break;
00274                 case MSG_SKIP_BACKWARDS:
00275                         Window()->PostMessage(NAVIGATE_PREV);
00276                         break;
00277                 case MSG_SKIP_FORWARD:
00278                         Window()->PostMessage(NAVIGATE_NEXT);
00279                         break;
00280                 default:
00281                     BBox::MessageReceived(message);
00282                     break;
00283         }
00284 }
00285 
00286 // Pulse
00287 void
00288 MediaControlView::Pulse()
00289 {
00290         InterfaceWindow* window = dynamic_cast<InterfaceWindow*>(Window());
00291         if (window && window->IsStopped())
00292                         fPlayPause->SetStopped();
00293 
00294     unsigned short i_volume;
00295     aout_VolumeGet( p_intf, (audio_volume_t*)&i_volume );
00296     fVolumeSlider->SetValue( i_volume );
00297 }
00298 
00299 // SetProgress
00300 void
00301 MediaControlView::SetProgress( float position )
00302 {
00303         fSeekSlider->SetPosition( position );
00304 }
00305 
00306 // SetStatus
00307 void
00308 MediaControlView::SetStatus(int status, int rate)
00309 {
00310         // we need to set the button status periodically
00311         // (even if it is the same) to get a blinking button
00312         fCurrentStatus = status;
00313     switch( status )
00314     {
00315         case PLAYING_S:
00316             fPlayPause->SetPlaying();
00317             break;
00318         case PAUSE_S:
00319             fPlayPause->SetPaused();
00320             break;
00321         default:
00322             fPlayPause->SetStopped();
00323             break;
00324     }
00325         if (rate != fCurrentRate)
00326         {
00327                 fCurrentRate = rate;
00328             if ( rate < INPUT_RATE_DEFAULT )
00329             {
00330                 // TODO: ...
00331             }
00332         }
00333 }
00334 
00335 // SetEnabled
00336 void
00337 MediaControlView::SetEnabled(bool enabled)
00338 {
00339     if( ( enabled && fIsEnabled ) ||
00340         ( !enabled && !fIsEnabled ) )
00341     {
00342         /* do not redraw if it is not necessary */
00343         return;
00344     }
00345     
00346         if( LockLooper() )
00347         {
00348                 fSkipBack->SetEnabled( enabled );
00349                 fPlayPause->SetEnabled( enabled );
00350                 fSkipForward->SetEnabled( enabled );
00351                 fStop->SetEnabled( enabled );
00352                 fMute->SetEnabled( enabled );
00353                 fVolumeSlider->SetEnabled( enabled );
00354                 fSeekSlider->SetEnabled( enabled );
00355                 fRewind->SetEnabled( enabled );
00356                 fForward->SetEnabled( enabled );
00357                 UnlockLooper();
00358                 fIsEnabled = enabled;
00359         }
00360 }
00361 
00362 // SetAudioEnabled
00363 void
00364 MediaControlView::SetAudioEnabled(bool enabled)
00365 {
00366         fMute->SetEnabled(enabled);
00367         fVolumeSlider->SetEnabled(enabled);
00368 }
00369 
00370 // GetVolume
00371 uint32
00372 MediaControlView::GetVolume() const
00373 {
00374         return fVolumeSlider->Value();
00375 }
00376 
00377 // SetSkippable
00378 void
00379 MediaControlView::SetSkippable(bool backward, bool forward)
00380 {
00381         fSkipBack->SetEnabled(backward);
00382         fSkipForward->SetEnabled(forward);
00383 }
00384 
00385 // SetMuted
00386 void
00387 MediaControlView::SetMuted(bool mute)
00388 {
00389         fVolumeSlider->SetMuted(mute);
00390 }
00391 
00392 // _LayoutControls
00393 void
00394 MediaControlView::_LayoutControls(BRect frame) const
00395 {
00396         // seek slider
00397         BRect r(frame);
00398         // calculate absolutly minimal width
00399         float minWidth = fSkipBack->Bounds().Width();
00400 //      minWidth += fRewind->Bounds().Width();
00401         minWidth += fStop->Bounds().Width();
00402         minWidth += fPlayPause->Bounds().Width();
00403 //      minWidth += fForward->Bounds().Width();
00404         minWidth += fSkipForward->Bounds().Width();
00405         minWidth += fMute->Bounds().Width();
00406         minWidth += VOLUME_MIN_WIDTH;
00407         
00408         // layout time slider and info view
00409     float width, height;
00410     fPositionInfo->GetBigPreferredSize( &width, &height );
00411     float ratio = width / height;
00412     width = r.Height() * ratio;
00413     if (frame.Width() - minWidth - MIN_SPACE >= width
00414               && frame.Height() >= height)
00415     {
00416         r.right = r.left + width;
00417         fPositionInfo->SetMode(PositionInfoView::MODE_BIG);
00418         _LayoutControl(fPositionInfo, r, true, true);
00419         frame.left = r.right + MIN_SPACE;
00420         r.left = frame.left;
00421         r.right = frame.right;
00422     //    r.bottom = r.top + r.Height() / 2.0 - MIN_SPACE / 2.0;
00423         r.bottom = r.top + fSeekSlider->Bounds().Height();
00424         _LayoutControl(fSeekSlider, r, true);
00425     }
00426     else
00427     {
00428         fPositionInfo->GetPreferredSize( &width, &height );
00429         fPositionInfo->SetMode(PositionInfoView::MODE_SMALL);
00430         fPositionInfo->ResizeTo(width, height);
00431         r.bottom = r.top + r.Height() / 2.0 - MIN_SPACE / 2.0;
00432         r.right = r.left + fPositionInfo->Bounds().Width();
00433         _LayoutControl(fPositionInfo, r, true );
00434         r.left = r.right + MIN_SPACE;
00435         r.right = frame.right;
00436         _LayoutControl(fSeekSlider, r, true);
00437     }
00438         float currentWidth = frame.Width();
00439         float space = (currentWidth - minWidth) / 6.0;//8.0;
00440         // apply weighting
00441         space = MIN_SPACE + (space - MIN_SPACE) / VOLUME_SLIDER_LAYOUT_WEIGHT;
00442         // layout controls with "space" inbetween
00443         r.left = frame.left;
00444         r.top = r.bottom + MIN_SPACE + 1.0;
00445         r.bottom = frame.bottom;
00446         // skip back
00447         r.right = r.left + fSkipBack->Bounds().Width();
00448         _LayoutControl(fSkipBack, r);
00449         // rewind
00450 //      r.left = r.right + space;
00451 //      r.right = r.left + fRewind->Bounds().Width();
00452 //      _LayoutControl(fRewind, r);
00453         // stop
00454         r.left = r.right + space;
00455         r.right = r.left + fStop->Bounds().Width();
00456         _LayoutControl(fStop, r);
00457         // play/pause
00458         r.left = r.right + space;
00459         r.right = r.left + fPlayPause->Bounds().Width();
00460         _LayoutControl(fPlayPause, r);
00461         // forward
00462 //      r.left = r.right + space;
00463 //      r.right = r.left + fForward->Bounds().Width();
00464 //      _LayoutControl(fForward, r);
00465         // skip forward
00466         r.left = r.right + space;
00467         r.right = r.left + fSkipForward->Bounds().Width();
00468         _LayoutControl(fSkipForward, r);
00469         // speaker icon
00470         r.left = r.right + space + space;
00471         r.right = r.left + fMute->Bounds().Width();
00472         _LayoutControl(fMute, r);
00473         // volume slider
00474         r.left = r.right + SPEAKER_SLIDER_DIST; // keep speaker icon and volume slider attached
00475         r.right = frame.right;
00476         _LayoutControl(fVolumeSlider, r, true);
00477 }
00478 
00479 // _MinFrame
00480 BRect           
00481 MediaControlView::_MinFrame() const
00482 {
00483         // add up width of controls along bottom (seek slider will likely adopt)
00484         float minWidth = 2 * BORDER_INSET;
00485         minWidth += fSkipBack->Bounds().Width() + MIN_SPACE;
00486 //      minWidth += fRewind->Bounds().Width() + MIN_SPACE;
00487         minWidth += fStop->Bounds().Width() + MIN_SPACE;
00488         minWidth += fPlayPause->Bounds().Width() + MIN_SPACE;
00489 //      minWidth += fForward->Bounds().Width() + MIN_SPACE;
00490         minWidth += fSkipForward->Bounds().Width() + MIN_SPACE + MIN_SPACE;
00491         minWidth += fMute->Bounds().Width() + SPEAKER_SLIDER_DIST;
00492         minWidth += VOLUME_MIN_WIDTH;
00493 
00494         // add up height of seek slider and heighest control on bottom
00495         float minHeight = 2 * BORDER_INSET;
00496         minHeight += fSeekSlider->Bounds().Height() + MIN_SPACE + MIN_SPACE / 2.0;
00497         minHeight += fBottomControlHeight;
00498         return BRect(0.0, 0.0, minWidth - 1.0, minHeight - 1.0);
00499 }
00500 
00501 // _LayoutControl
00502 void
00503 MediaControlView::_LayoutControl(BView* view, BRect frame,
00504                                  bool resizeWidth, bool resizeHeight) const
00505 {
00506     if (!resizeHeight)
00507             // center vertically
00508             frame.top = (frame.top + frame.bottom) / 2.0 - view->Bounds().Height() / 2.0;
00509         if (!resizeWidth)
00510             //center horizontally
00511                 frame.left = (frame.left + frame.right) / 2.0 - view->Bounds().Width() / 2.0;
00512         view->MoveTo(frame.LeftTop());
00513         float width = resizeWidth ? frame.Width() : view->Bounds().Width();
00514         float height = resizeHeight ? frame.Height() : view->Bounds().Height();
00515     if (resizeWidth || resizeHeight)
00516         view->ResizeTo(width, height);
00517 }
00518 
00519 
00520 
00521 /*****************************************************************************
00522  * SeekSlider
00523  *****************************************************************************/
00524 SeekSlider::SeekSlider( intf_thread_t * _p_intf,
00525                         BRect frame, const char* name, MediaControlView *owner )
00526         : BControl(frame, name, NULL, NULL, B_FOLLOW_NONE,
00527                            B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
00528           p_intf(_p_intf),
00529           fOwner(owner),
00530           fTracking(false)
00531 {
00532         BFont font(be_plain_font);
00533         font.SetSize(9.0);
00534         SetFont(&font);
00535 }
00536 
00537 SeekSlider::~SeekSlider()
00538 {
00539 }
00540 
00541 /*****************************************************************************
00542  * VolumeSlider::AttachedToWindow
00543  *****************************************************************************/
00544 void
00545 SeekSlider::AttachedToWindow()
00546 {
00547         BControl::AttachedToWindow();
00548         SetViewColor(B_TRANSPARENT_32_BIT);
00549 }
00550 
00551 /*****************************************************************************
00552  * VolumeSlider::Draw
00553  *****************************************************************************/
00554 void
00555 SeekSlider::Draw(BRect updateRect)
00556 {
00557         BRect r(Bounds());
00558         float knobWidth2 = SEEK_SLIDER_KNOB_WIDTH / 2.0;
00559         float sliderStart = (r.left + knobWidth2);
00560         float sliderEnd = (r.right - knobWidth2);
00561         float knobPos = sliderStart
00562                                         + floorf((sliderEnd - sliderStart - 1.0) * Value()
00563                                         / SEEKSLIDER_RANGE);
00564         // draw both sides (the original from Be doesn't seem
00565         // to make a difference for enabled/disabled state)
00566 //      DrawBitmapAsync(fLeftSideBits, r.LeftTop());
00567 //      DrawBitmapAsync(fRightSideBits, BPoint(sliderEnd + 1.0, r.top));
00568         // colors for the slider area between the two bitmaps
00569         rgb_color background = kBackground;//ui_color(B_PANEL_BACKGROUND_COLOR);
00570         rgb_color shadow = tint_color(background, B_DARKEN_2_TINT);
00571         rgb_color softShadow = tint_color(background, B_DARKEN_1_TINT);
00572         rgb_color darkShadow = tint_color(background, B_DARKEN_4_TINT);
00573         rgb_color midShadow = tint_color(background, B_DARKEN_3_TINT);
00574         rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
00575         rgb_color softLight = tint_color(background, B_LIGHTEN_1_TINT);
00576         rgb_color green = kSeekGreen;
00577         rgb_color greenShadow = kSeekGreenShadow;
00578         rgb_color black = kBlack;
00579         rgb_color dotGrey = midShadow;
00580         rgb_color dotGreen = greenShadow;
00581         // draw frame
00582         _StrokeFrame(r, softShadow, softShadow, softLight, softLight);
00583         r.InsetBy(1.0, 1.0);
00584         _StrokeFrame(r, black, black, light, light);
00585         if (IsEnabled())
00586         {
00587                 r.InsetBy(1.0, 1.0);
00588                 // inner shadow
00589                 _StrokeFrame(r, greenShadow, greenShadow, green, green);
00590                 r.top++;
00591                 r.left++;
00592                 _StrokeFrame(r, greenShadow, greenShadow, green, green);
00593                 // inside area
00594                 r.InsetBy(1.0, 1.0);
00595                 SetHighColor(green);
00596                 FillRect(r);
00597                 // dots
00598                 int32 dotCount = (int32)(r.Width() / 6.0);
00599                 BPoint dotPos;
00600                 dotPos.y = r.top + 2.0;
00601                 SetHighColor(dotGreen);
00602                 for (int32 i = 0; i < dotCount; i++)
00603                 {
00604                         dotPos.x = sliderStart + i * 6.0 + 5.0;
00605                         StrokeLine(dotPos, BPoint(dotPos.x, dotPos.y + 6.0));
00606                 }
00607                 // slider handle
00608                 r.top -= 4.0;
00609                 r.bottom += 3.0;
00610                 r.left = knobPos - knobWidth2;
00611                 r.right = knobPos + knobWidth2;
00612                 // black outline
00613                 float handleBottomSize = 2.0;
00614                 float handleArrowSize = 6.0;
00615                 BeginLineArray(10);
00616                         // upper handle
00617                         AddLine(BPoint(r.left, r.top + handleBottomSize),
00618                                         BPoint(r.left, r.top), black);
00619                         AddLine(BPoint(r.left + 1.0, r.top),
00620                                         BPoint(r.right, r.top), black);
00621                         AddLine(BPoint(r.right, r.top + 1.0),
00622                                         BPoint(r.right, r.top + handleBottomSize), black);
00623                         AddLine(BPoint(r.right - 1.0, r.top + handleBottomSize + 1.0),
00624                                         BPoint(knobPos, r.top + handleArrowSize), black);
00625                         AddLine(BPoint(knobPos - 1.0, r.top + handleArrowSize - 1.0),
00626                                         BPoint(r.left + 1.0, r.top + handleBottomSize + 1.0), black);
00627                         // lower handle
00628                         AddLine(BPoint(r.left, r.bottom),
00629                                         BPoint(r.left, r.bottom - handleBottomSize), black);
00630                         AddLine(BPoint(r.left + 1.0, r.bottom - handleBottomSize - 1.0),
00631                                         BPoint(knobPos, r.bottom - handleArrowSize), black);
00632                         AddLine(BPoint(knobPos + 1.0, r.bottom - handleArrowSize + 1.0),
00633                                         BPoint(r.right, r.bottom - handleBottomSize), black);
00634                         AddLine(BPoint(r.right, r.bottom - handleBottomSize + 1.0),
00635                                         BPoint(r.right, r.bottom), black);
00636                         AddLine(BPoint(r.right - 1.0, r.bottom),
00637                                         BPoint(r.left + 1.0, r.bottom), black);
00638                 EndLineArray();
00639                 // inner red light and shadow lines
00640                 r.InsetBy(1.0, 1.0);
00641                 handleBottomSize--;
00642                 handleArrowSize -= 2.0;
00643                 BeginLineArray(10);
00644                         // upper handle
00645                         AddLine(BPoint(r.left, r.top + handleBottomSize),
00646                                         BPoint(r.left, r.top), kSeekRedLight);
00647                         AddLine(BPoint(r.left + 1.0, r.top),
00648                                         BPoint(r.right, r.top), kSeekRedLight);
00649                         AddLine(BPoint(r.right, r.top + 1.0),
00650                                         BPoint(r.right, r.top + handleBottomSize), kSeekRedShadow);
00651                         AddLine(BPoint(r.right - 1.0, r.top + handleBottomSize + 1.0),
00652                                         BPoint(knobPos, r.top + handleArrowSize), kSeekRedShadow);
00653                         AddLine(BPoint(knobPos - 1.0, r.top + handleArrowSize - 1.0),
00654                                         BPoint(r.left + 1.0, r.top + handleBottomSize + 1.0), kSeekRedLight);
00655                         // lower handle
00656                         AddLine(BPoint(r.left, r.bottom),
00657                                         BPoint(r.left, r.bottom - handleBottomSize), kSeekRedLight);
00658                         AddLine(BPoint(r.left + 1.0, r.bottom - handleBottomSize - 1.0),
00659                                         BPoint(knobPos, r.bottom - handleArrowSize), kSeekRedLight);
00660                         AddLine(BPoint(knobPos + 1.0, r.bottom - handleArrowSize + 1.0),
00661                                         BPoint(r.right, r.bottom - handleBottomSize), kSeekRedShadow);
00662                         AddLine(BPoint(r.right, r.bottom - handleBottomSize + 1.0),
00663                                         BPoint(r.right, r.bottom), kSeekRedShadow);
00664                         AddLine(BPoint(r.right - 1.0, r.bottom),
00665                                         BPoint(r.left + 1.0, r.bottom), kSeekRedShadow);
00666                 EndLineArray();
00667                 // fill rest of handles with red
00668                 SetHighColor(kSeekRed);
00669                 r.InsetBy(1.0, 1.0);
00670                 handleArrowSize -= 2.0;
00671                 BPoint arrow[3];
00672                 // upper handle arrow
00673                 arrow[0].x = r.left;
00674                 arrow[0].y = r.top;
00675                 arrow[1].x = r.right;
00676                 arrow[1].y = r.top;
00677                 arrow[2].x = knobPos;
00678                 arrow[2].y = r.top + handleArrowSize;
00679                 FillPolygon(arrow, 3);
00680                 // lower handle arrow
00681                 arrow[0].x = r.left;
00682                 arrow[0].y = r.bottom;
00683                 arrow[1].x = r.right;
00684                 arrow[1].y = r.bottom;
00685                 arrow[2].x = knobPos;
00686                 arrow[2].y = r.bottom - handleArrowSize;
00687                 FillPolygon(arrow, 3);
00688         }
00689         else
00690         {
00691                 r.InsetBy(1.0, 1.0);
00692                 _StrokeFrame(r, darkShadow, darkShadow, darkShadow, darkShadow);
00693                 r.InsetBy(1.0, 1.0);
00694                 _StrokeFrame(r, darkShadow, darkShadow, darkShadow, darkShadow);
00695                 r.InsetBy(1.0, 1.0);
00696                 SetHighColor(darkShadow);
00697                 SetLowColor(shadow);
00698                 // stripes
00699                 float width = floorf(StringWidth(DISABLED_SEEK_MESSAGE));
00700                 float textPos = r.left + r.Width() / 2.0 - width / 2.0;
00701                 pattern stripes = {{ 0xc7, 0x8f, 0x1f, 0x3e, 0x7c, 0xf8, 0xf1, 0xe3 }};
00702                 BRect stripesRect(r);
00703                 stripesRect.right = textPos - 5.0;
00704                 FillRect(stripesRect, stripes);
00705                 stripesRect.left = textPos + width + 3.0;
00706                 stripesRect.right = r.right;
00707                 FillRect(stripesRect, stripes);
00708                 // info text
00709                 r.left = textPos - 4.0;
00710                 r.right = textPos + width + 2.0;
00711                 FillRect(r);
00712                 SetHighColor(shadow);
00713                 SetLowColor(darkShadow);
00714                 font_height fh;
00715                 GetFontHeight(&fh);
00716                 DrawString(DISABLED_SEEK_MESSAGE, BPoint(textPos, r.top + ceilf(fh.ascent) - 1.0));
00717         }
00718 }
00719 
00720 /*****************************************************************************
00721  * SeekSlider::MouseDown
00722  *****************************************************************************/
00723 void
00724 SeekSlider::MouseDown(BPoint where)
00725 {
00726         if (IsEnabled() && Bounds().Contains(where))
00727         {
00728                 SetValue(_ValueFor(where.x));
00729                 fTracking = true;
00730                 SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
00731         }
00732 }
00733 
00734 /*****************************************************************************
00735  * SeekSlider::MouseMoved
00736  *****************************************************************************/
00737 void
00738 SeekSlider::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage)
00739 {
00740         if (fTracking)
00741         {
00742                 SetValue(_ValueFor(where.x));
00743         }
00744 }
00745 
00746 /*****************************************************************************
00747  * SeekSlider::MouseUp
00748  *****************************************************************************/
00749 void
00750 SeekSlider::MouseUp(BPoint where)
00751 {
00752         if (fTracking)
00753         {
00754                 fTracking = false;
00755                 input_thread_t * p_input;
00756                 p_input = (input_thread_t *)
00757             vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
00758 
00759         if( p_input )
00760         {
00761                     var_SetFloat( p_input, "position",
00762                                   (float) Value() / SEEKSLIDER_RANGE );
00763                     vlc_object_release( p_input );
00764                 }
00765         }
00766 }
00767 
00768 /*****************************************************************************
00769  * SeekSlider::ResizeToPreferred
00770  *****************************************************************************/
00771 void
00772 SeekSlider::ResizeToPreferred()
00773 {
00774         float width = 15.0 + StringWidth(DISABLED_SEEK_MESSAGE) + 15.0;
00775         ResizeTo(width, 17.0);
00776 }
00777 
00778 /*****************************************************************************
00779  * SeekSlider::SetPosition
00780  *****************************************************************************/
00781 void
00782 SeekSlider::SetPosition(float position)
00783 {
00784         if ( LockLooper() )
00785         {
00786             if( !fTracking )
00787             {
00788                     SetValue( SEEKSLIDER_RANGE * position );
00789                 }
00790                 UnlockLooper();
00791         }
00792 }
00793 
00794 /*****************************************************************************
00795  * SeekSlider::_ValueFor
00796  *****************************************************************************/
00797 int32
00798 SeekSlider::_ValueFor(float xPos) const
00799 {
00800         BRect r(Bounds());
00801         float knobWidth2 = SEEK_SLIDER_KNOB_WIDTH / 2.0;
00802         float sliderStart = (r.left + knobWidth2);
00803         float sliderEnd = (r.right - knobWidth2);
00804         int32 value =  (int32)(((xPos - sliderStart) * SEEKSLIDER_RANGE)
00805                                   / (sliderEnd - sliderStart - 1.0));
00806         if (value < 0)
00807                 value = 0;
00808         if (value > SEEKSLIDER_RANGE)
00809                 value = SEEKSLIDER_RANGE;
00810         return value;
00811 }
00812 
00813 /*****************************************************************************
00814  * SeekSlider::_StrokeFrame
00815  *****************************************************************************/
00816 void
00817 SeekSlider::_StrokeFrame(BRect r, rgb_color left, rgb_color top,
00818                                                  rgb_color right, rgb_color bottom)
00819 {
00820         BeginLineArray(4);
00821                 AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), left);
00822                 AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), top);
00823                 AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), right);
00824                 AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), bottom);
00825         EndLineArray();
00826 }
00827 
00828 /*****************************************************************************
00829  * VolumeSlider
00830  *****************************************************************************/
00831 VolumeSlider::VolumeSlider(BRect frame, const char* name, int32 minValue, int32 maxValue,
00832                                                    BMessage* message, BHandler* target)
00833         : BControl(frame, name, NULL, message, B_FOLLOW_NONE,
00834                            B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
00835           fLeftSideBits(NULL),
00836           fRightSideBits(NULL),
00837           fKnobBits(NULL),
00838           fTracking(false),
00839           fMuted(false),
00840           fMinValue(minValue),
00841           fMaxValue(maxValue)
00842 {
00843         SetTarget(target);
00844 
00845         // create bitmaps
00846         BRect r(BPoint(0.0, 0.0), kVolumeSliderBitmapSize);
00847         fLeftSideBits = new BBitmap(r, B_CMAP8);
00848         fRightSideBits = new BBitmap(r, B_CMAP8);
00849         r.Set(0.0, 0.0, kVolumeSliderKnobBitmapSize.x, kVolumeSliderKnobBitmapSize.y);
00850         fKnobBits = new BBitmap(r, B_CMAP8);
00851 
00852         _MakeBitmaps();
00853 }
00854 
00855 /*****************************************************************************
00856  * VolumeSlider destructor
00857  *****************************************************************************/
00858 VolumeSlider::~VolumeSlider()
00859 {
00860         delete fLeftSideBits;
00861         delete fRightSideBits;
00862         delete fKnobBits;
00863 }
00864 
00865 /*****************************************************************************
00866  * VolumeSlider::AttachedToWindow
00867  *****************************************************************************/
00868 void
00869 VolumeSlider::AttachedToWindow()
00870 {
00871         BControl::AttachedToWindow();
00872         SetViewColor(B_TRANSPARENT_32_BIT);
00873 }
00874 
00875 /*****************************************************************************
00876  * VolumeSlider::SetValue
00877  *****************************************************************************/
00878 void
00879 VolumeSlider::SetValue(int32 value)
00880 {
00881         if (value != Value())
00882         {
00883                 BControl::SetValue(value);
00884                 Invoke();
00885         }
00886 }
00887 
00888 /*****************************************************************************
00889  * VolumeSlider::SetEnabled
00890  *****************************************************************************/
00891 void
00892 VolumeSlider::SetEnabled(bool enable)
00893 {
00894         if (enable != IsEnabled())
00895         {
00896                 BControl::SetEnabled(enable);
00897                 _MakeBitmaps();
00898                 Invalidate();
00899         }
00900 }
00901 
00902 /*****************************************************************************
00903  * VolumeSlider::Draw
00904  *****************************************************************************/
00905 void
00906 VolumeSlider::Draw(BRect updateRect)
00907 {
00908         if (IsValid())
00909         {
00910                 BRect r(Bounds());
00911                 float sliderSideWidth = kVolumeSliderBitmapWidth;
00912                 float sliderStart = (r.left + sliderSideWidth);
00913                 float sliderEnd = (r.right - sliderSideWidth);
00914                 float knobPos = sliderStart
00915                                                 + (sliderEnd - sliderStart - 1.0) * (Value() - fMinValue)
00916                                                 / (fMaxValue - fMinValue);
00917                 // draw both sides (the original from Be doesn't seem
00918                 // to make a difference for enabled/disabled state)
00919                 DrawBitmapAsync(fLeftSideBits, r.LeftTop());
00920                 DrawBitmapAsync(fRightSideBits, BPoint(sliderEnd + 1.0, r.top));
00921                 // colors for the slider area between the two bitmaps
00922                 rgb_color background = kBackground;//ui_color(B_PANEL_BACKGROUND_COLOR);
00923                 rgb_color shadow = tint_color(background, B_DARKEN_2_TINT);
00924                 rgb_color softShadow = tint_color(background, B_DARKEN_1_TINT);
00925                 rgb_color darkShadow = tint_color(background, B_DARKEN_4_TINT);
00926                 rgb_color midShadow = tint_color(background, B_DARKEN_3_TINT);
00927                 rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
00928                 rgb_color softLight = tint_color(background, B_LIGHTEN_1_TINT);
00929                 rgb_color green = kGreen;
00930                 rgb_color greenShadow = kGreenShadow;
00931                 rgb_color black = kBlack;
00932                 rgb_color dotGrey = midShadow;
00933                 rgb_color dotGreen = greenShadow;
00934                 // make dimmed version of colors if we're disabled
00935                 if (!IsEnabled())
00936                 {
00937                         shadow = (rgb_color){ 200, 200, 200, 255 };
00938                         softShadow = dimmed_color_cmap8(softShadow, background, DIM_LEVEL);
00939                         darkShadow = dimmed_color_cmap8(darkShadow, background, DIM_LEVEL);
00940                         midShadow = shadow;
00941                         light = dimmed_color_cmap8(light, background, DIM_LEVEL);
00942                         softLight = dimmed_color_cmap8(softLight, background, DIM_LEVEL);
00943                         green = dimmed_color_cmap8(green, background, DIM_LEVEL);
00944                         greenShadow = dimmed_color_cmap8(greenShadow, background, DIM_LEVEL);
00945                         black = dimmed_color_cmap8(black, background, DIM_LEVEL);
00946                         dotGreen = dotGrey;
00947                 }
00948                 else if (fMuted)
00949                 {
00950                         green = tint_color(kBackground, B_DARKEN_3_TINT);
00951                         greenShadow = tint_color(kBackground, B_DARKEN_4_TINT);
00952                         dotGreen = greenShadow;
00953                 }
00954                 // draw slider edges between bitmaps
00955                 BeginLineArray(7);
00956                         AddLine(BPoint(sliderStart, r.top),
00957                                         BPoint(sliderEnd, r.top), softShadow);
00958                         AddLine(BPoint(sliderStart, r.bottom),
00959                                         BPoint(sliderEnd, r.bottom), softLight);
00960                         r.InsetBy(0.0, 1.0);
00961                         AddLine(BPoint(sliderStart, r.top),
00962                                         BPoint(sliderEnd, r.top), black);
00963                         AddLine(BPoint(sliderStart, r.bottom),
00964                                         BPoint(sliderEnd, r.bottom), light);
00965                         r.top++;
00966                         AddLine(BPoint(sliderStart, r.top),
00967                                         BPoint(knobPos, r.top), greenShadow);
00968                         AddLine(BPoint(knobPos, r.top),
00969                                         BPoint(sliderEnd, r.top), midShadow);
00970                         r.top++;
00971                         AddLine(BPoint(sliderStart, r.top),
00972                                         BPoint(knobPos, r.top), greenShadow);
00973                 EndLineArray();
00974                 // fill rest inside of slider
00975                 r.InsetBy(0.0, 1.0);
00976                 r.left = sliderStart;
00977                 r.right = knobPos;
00978                 SetHighColor(green);
00979                 FillRect(r, B_SOLID_HIGH);
00980                 r.left = knobPos + 1.0;
00981                 r.right = sliderEnd;
00982                 r.top -= 1.0;
00983                 SetHighColor(shadow);
00984                 FillRect(r, B_SOLID_HIGH);
00985                 // draw little dots inside
00986                 int32 dotCount = (int32)((sliderEnd - sliderStart) / 5.0);
00987                 BPoint dotPos;
00988                 dotPos.y = r.top + 4.0;
00989                 for (int32 i = 0; i < dotCount; i++)
00990                 {
00991                         dotPos.x = sliderStart + i * 5.0 + 4.0;
00992                         SetHighColor(dotPos.x < knobPos ? dotGreen : dotGrey);
00993                         StrokeLine(dotPos, BPoint(dotPos.x, dotPos.y + 1.0));
00994                 }
00995                 // draw knob
00996                 r.top -= 1.0;
00997                 SetDrawingMode(B_OP_OVER); // part of knob is transparent
00998                 DrawBitmapAsync(fKnobBits, BPoint(knobPos - kVolumeSliderKnobWidth / 2, r.top));
00999         }
01000 }
01001 
01002 /*****************************************************************************
01003  * VolumeSlider::MouseDown
01004  *****************************************************************************/
01005 void
01006 VolumeSlider::MouseDown(BPoint where)
01007 {
01008         if (Bounds().Contains(where) && IsEnabled())
01009         {
01010                 fTracking = true;
01011                 SetValue(_ValueFor(where.x));
01012                 SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
01013         }
01014 }
01015 
01016 /*****************************************************************************
01017  * VolumeSlider::MouseMoved
01018  *****************************************************************************/
01019 void
01020 VolumeSlider::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
01021 {
01022         if (fTracking)
01023                 SetValue(_ValueFor(where.x));
01024 }
01025 
01026 /*****************************************************************************
01027  * VolumeSlider::MouseUp
01028  *****************************************************************************/
01029 void
01030 VolumeSlider::MouseUp(BPoint where)
01031 {
01032         fTracking = false;
01033 }
01034 
01035 
01036 /*****************************************************************************
01037  * VolumeSlider::IsValid
01038  *****************************************************************************/
01039 bool
01040 VolumeSlider::IsValid() const
01041 {
01042         return (fLeftSideBits && fLeftSideBits->IsValid()
01043                         && fRightSideBits && fRightSideBits->IsValid()
01044                         && fKnobBits && fKnobBits->IsValid());
01045 }
01046 
01047 /*****************************************************************************
01048  * VolumeSlider::SetMuted
01049  *****************************************************************************/
01050 void
01051 VolumeSlider::SetMuted(bool mute)
01052 {
01053         if (mute != fMuted)
01054         {
01055                 fMuted = mute;
01056                 _MakeBitmaps();
01057                 Invalidate();
01058         }
01059 }
01060 
01061 /*****************************************************************************
01062  * VolumeSlider::_MakeBitmaps
01063  *****************************************************************************/
01064 void
01065 VolumeSlider::_MakeBitmaps()
01066 {
01067         if (IsValid())
01068         {
01069                 // left side of slider
01070                 memcpy(fLeftSideBits->Bits(), kVolumeSliderLeftBitmapBits,
01071                            fLeftSideBits->BitsLength());
01072                 // right side of slider
01073                 memcpy(fRightSideBits->Bits(), kVolumeSliderRightBits,
01074                            fRightSideBits->BitsLength());
01075                 // slider knob
01076                 int32 length = fKnobBits->BitsLength();
01077                 memcpy(fKnobBits->Bits(), kVolumeSliderKnobBits, length);
01078                 uint8* bits = (uint8*)fKnobBits->Bits();
01079                 // black was used in the knob to represent transparency
01080                 // use screen to get index for the "transarent" color used in the bitmap
01081                 BScreen screen(B_MAIN_SCREEN_ID);
01082                 uint8 blackIndex = screen.IndexForColor(kBlack);
01083                 // replace black index with transparent index
01084                 for (int32 i = 0; i < length; i++)
01085                         if (bits[i] == blackIndex)
01086                                 bits[i] = B_TRANSPARENT_MAGIC_CMAP8;
01087 
01088                 if (!IsEnabled())
01089                 {
01090                         // make ghosted versions of the bitmaps
01091                         dim_bitmap(fLeftSideBits, kBackground, DIM_LEVEL);
01092                         dim_bitmap(fRightSideBits, kBackground, DIM_LEVEL);
01093                         dim_bitmap(fKnobBits, kBackground, DIM_LEVEL);
01094                 }
01095                 else if (fMuted)
01096                 {
01097                         // replace green color (and shadow) in left slider side
01098                         bits = (uint8*)fLeftSideBits->Bits();
01099                         length = fLeftSideBits->BitsLength();
01100                         uint8 greenIndex = screen.IndexForColor(kGreen);
01101                         uint8 greenShadowIndex = screen.IndexForColor(kGreenShadow);
01102                         rgb_color shadow = tint_color(kBackground, B_DARKEN_3_TINT);
01103                         rgb_color midShadow = tint_color(kBackground, B_DARKEN_4_TINT);
01104                         uint8 replaceIndex = screen.IndexForColor(shadow);
01105                         uint8 replaceShadowIndex = screen.IndexForColor(midShadow);
01106                         for (int32 i = 0; i < length; i++)
01107                         {
01108                                 if (bits[i] == greenIndex)
01109                                         bits[i] = replaceIndex;
01110                                 else if (bits[i] == greenShadowIndex)
01111                                         bits[i] = replaceShadowIndex;
01112                         }
01113                 }
01114         }
01115 }
01116 
01117 /*****************************************************************************
01118  * VolumeSlider::_ValueFor
01119  *****************************************************************************/
01120 int32
01121 VolumeSlider::_ValueFor(float xPos) const
01122 {
01123         BRect r(Bounds());
01124         float sliderStart = (r.left + kVolumeSliderBitmapWidth);
01125         float sliderEnd = (r.right - kVolumeSliderBitmapWidth);
01126         int32 value =  fMinValue + (int32)(((xPos - sliderStart) * (fMaxValue - fMinValue))
01127                                   / (sliderEnd - sliderStart - 1.0));
01128         if (value < fMinValue)
01129                 value = fMinValue;
01130         if (value > fMaxValue)
01131                 value = fMaxValue;
01132         return value;
01133 }
01134 
01135 /*****************************************************************************
01136  * PositionInfoView::PositionInfoView
01137  *****************************************************************************/
01138 PositionInfoView::PositionInfoView( BRect frame, const char* name,
01139                                     intf_thread_t * p_interface )
01140         : BView( frame, name, B_FOLLOW_NONE,
01141                          B_WILL_DRAW | B_PULSE_NEEDED | B_FULL_UPDATE_ON_RESIZE ),
01142           fMode( MODE_SMALL ),
01143           fCurrentFileIndex( -1 ),
01144           fCurrentFileSize( -1 ),
01145           fCurrentTitleIndex( -1 ),
01146           fCurrentTitleSize( -1 ),
01147           fCurrentChapterIndex( -1 ),
01148           fCurrentChapterSize( -1 ),
01149           fSeconds( -1 ),
01150           fTimeString( "-:--:--" ),
01151           fLastPulseUpdate( system_time() ),
01152           fStackedWidthCache( 0.0 ),
01153           fStackedHeightCache( 0.0 )
01154 {
01155     p_intf = p_interface;
01156 
01157         SetViewColor( B_TRANSPARENT_32_BIT );
01158         SetLowColor( kBlack );
01159         SetHighColor( 0, 255, 0, 255 );
01160         SetFontSize( 11.0 );
01161 }
01162 
01163 /*****************************************************************************
01164  * PositionInfoView::~PositionInfoView
01165  *****************************************************************************/
01166 PositionInfoView::~PositionInfoView()
01167 {
01168 }
01169 
01170 /*****************************************************************************
01171  * PositionInfoView::Draw
01172  *****************************************************************************/
01173 void
01174 PositionInfoView::Draw( BRect updateRect )
01175 {
01176         rgb_color background = ui_color( B_PANEL_BACKGROUND_COLOR );
01177         rgb_color shadow = tint_color( background, B_DARKEN_1_TINT );
01178         rgb_color darkShadow = tint_color( background, B_DARKEN_4_TINT );
01179         rgb_color light = tint_color( background, B_LIGHTEN_MAX_TINT );
01180         rgb_color softLight = tint_color( background, B_LIGHTEN_1_TINT );
01181         // frame
01182         BRect r( Bounds() );
01183         BeginLineArray( 8 );
01184                 AddLine( BPoint( r.left, r.bottom ),
01185                                  BPoint( r.left, r.top ), shadow );
01186                 AddLine( BPoint( r.left + 1.0, r.top ),
01187                                  BPoint( r.right, r.top ), shadow );
01188                 AddLine( BPoint( r.right, r.top + 1.0 ),
01189                                  BPoint( r.right, r.bottom ), softLight );
01190                 AddLine( BPoint( r.right - 1.0, r.bottom ),
01191                                  BPoint( r.left + 1.0, r.bottom ), softLight );
01192                 r.InsetBy( 1.0, 1.0 );
01193                 AddLine( BPoint( r.left, r.bottom ),
01194                                  BPoint( r.left, r.top ), darkShadow );
01195                 AddLine( BPoint( r.left + 1.0, r.top ),
01196                                  BPoint( r.right, r.top ), darkShadow );
01197                 AddLine( BPoint( r.right, r.top + 1.0 ),
01198                                  BPoint( r.right, r.bottom ), light );
01199                 AddLine( BPoint( r.right - 1.0, r.bottom ),
01200                                  BPoint( r.left + 1.0, r.bottom ), light );
01201         EndLineArray();
01202         // background
01203         r.InsetBy( 1.0, 1.0 );
01204         FillRect( r, B_SOLID_LOW );
01205         // contents
01206         font_height fh;
01207         GetFontHeight( &fh );
01208         switch ( fMode )
01209         {
01210                 case MODE_SMALL:
01211                 {
01212                         float width = StringWidth( fTimeString.String() );
01213                         DrawString( fTimeString.String(),
01214                                                 BPoint( r.left + r.Width() / 2.0 - width / 2.0,
01215                                                                 r.top + r.Height() / 2.0 + fh.ascent / 2.0 - 1.0 ) );
01216                         break;
01217                 }
01218                 case MODE_BIG:
01219                 {
01220                         BFont font;
01221                         GetFont( &font );
01222                         BFont smallFont = font;
01223                         BFont bigFont = font;
01224                         BFont tinyFont = font;
01225                         smallFont.SetSize( r.Height() / 5.0 );
01226                         bigFont.SetSize( r.Height() / 3.0 );
01227                         tinyFont.SetSize( r.Height() / 7.0 );
01228                         float timeHeight = r.Height() / 2.5;
01229                         float height = ( r.Height() - timeHeight ) / 3.0;
01230                         SetFont( &tinyFont );
01231                         SetHighColor( 0, 180, 0, 255 );
01232                         DrawString( _("File"), BPoint( r.left + 3.0, r.top + height ) );
01233                         DrawString( _("Title"), BPoint( r.left + 3.0, r.top + 2.0 * height ) );
01234                         DrawString( _("Chapter"), BPoint( r.left + 3.0, r.top + 3.0 * height ) );
01235                         SetFont( &smallFont );
01236                         BString helper;
01237                         SetHighColor( 0, 255, 0, 255 );
01238                         // file
01239                         _MakeString( helper, fCurrentFileIndex, fCurrentFileSize );
01240                         float width = StringWidth( helper.String() );
01241                         DrawString( helper.String(), BPoint( r.right - 3.0 - width, r.top + height ) );
01242                         // title
01243                         _MakeString( helper, fCurrentTitleIndex, fCurrentTitleSize );
01244                         width = StringWidth( helper.String() );
01245                         DrawString( helper.String(), BPoint( r.right - 3.0 - width, r.top + 2.0 * height ) );
01246                         // chapter
01247                         _MakeString( helper, fCurrentChapterIndex, fCurrentChapterSize );
01248                         width = StringWidth( helper.String() );
01249                         DrawString( helper.String(), BPoint( r.right - 3.0 - width, r.top + 3.0 * height ) );
01250                         // time
01251                         SetFont( &bigFont );
01252                         width = StringWidth( fTimeString.String() );
01253                         DrawString( fTimeString.String(),
01254                                                 BPoint( r.left + r.Width() / 2.0 - width / 2.0,
01255                                                                 r.bottom - 3.0 ) );
01256                         break;
01257                 }
01258         }
01259 }
01260 
01261 /*****************************************************************************
01262  * PositionInfoView::ResizeToPreferred
01263  *****************************************************************************/
01264 void
01265 PositionInfoView::ResizeToPreferred()
01266 {
01267         float width, height;
01268         GetPreferredSize( &width, &height );
01269         ResizeTo( width, height );
01270 }
01271 
01272 /*****************************************************************************
01273  * PositionInfoView::GetPreferredSize
01274  *****************************************************************************/
01275 void
01276 PositionInfoView::GetPreferredSize( float* width, float* height )
01277 {
01278         if ( width && height )
01279         {
01280                 *width = 5.0 + ceilf( StringWidth( "0:00:00" ) ) + 5.0;
01281                 font_height fh;
01282                 GetFontHeight( &fh );
01283                 *height = 3.0 + ceilf( fh.ascent ) + 3.0;
01284                 fStackedWidthCache = *width * 1.2;
01285                 fStackedHeightCache = *height * 2.7;
01286         }
01287 }
01288 
01289 /*****************************************************************************
01290  * PositionInfoView::Pulse
01291  *****************************************************************************/
01292 void
01293 PositionInfoView::Pulse()
01294 {
01295         // allow for Pulse frequency to be higher, MediaControlView needs it
01296         bigtime_t now = system_time();
01297         if ( now - fLastPulseUpdate > 900000 )
01298         {
01299 #if 0
01300                 int32 index, size;
01301                 p_intf->p_sys->p_wrapper->GetPlaylistInfo( index, size );
01302                 SetFile( index + 1, size );
01303                 p_intf->p_sys->p_wrapper->TitleInfo( index, size );
01304                 SetTitle( index, size );
01305                 p_intf->p_sys->p_wrapper->ChapterInfo( index, size );
01306                 SetChapter( index, size );
01307                 SetTime( p_intf->p_sys->p_wrapper->GetTimeAsString() );
01308                 fLastPulseUpdate = now;
01309 #endif
01310         }
01311 }
01312 
01313 /*****************************************************************************
01314  * PositionInfoView::GetBigPreferredSize
01315  *****************************************************************************/
01316 void
01317 PositionInfoView::GetBigPreferredSize( float* width, float* height )
01318 {
01319         if ( width && height )
01320         {
01321                 *width = fStackedWidthCache;
01322                 *height = fStackedHeightCache;
01323         }
01324 }
01325 
01326 /*****************************************************************************
01327  * PositionInfoView::SetMode
01328  *****************************************************************************/
01329 void
01330 PositionInfoView::SetMode( uint32 mode )
01331 {
01332         if ( fMode != mode )
01333         {
01334                 fMode = mode;
01335                 _InvalidateContents();
01336         }
01337 }
01338 
01339 /*****************************************************************************
01340  * PositionInfoView::SetFile
01341  *****************************************************************************/
01342 void
01343 PositionInfoView::SetFile( int32 index, int32 size )
01344 {
01345         if ( fCurrentFileIndex != index || fCurrentFileSize != size )
01346         {
01347                 fCurrentFileIndex = index;
01348                 fCurrentFileSize = size;
01349                 _InvalidateContents();
01350         }
01351 }
01352 
01353 /*****************************************************************************
01354  * PositionInfoView::SetTitle
01355  *****************************************************************************/
01356 void
01357 PositionInfoView::SetTitle( int32 index, int32 size )
01358 {
01359         if ( fCurrentTitleIndex != index || fCurrentFileSize != size )
01360         {
01361                 fCurrentTitleIndex = index;
01362                 fCurrentTitleSize = size;
01363                 _InvalidateContents();
01364         }
01365 }
01366 
01367 /*****************************************************************************
01368  * PositionInfoView::SetChapter
01369  *****************************************************************************/
01370 void
01371 PositionInfoView::SetChapter( int32 index, int32 size )
01372 {
01373         if ( fCurrentChapterIndex != index || fCurrentFileSize != size )
01374         {
01375                 fCurrentChapterIndex = index;
01376                 fCurrentChapterSize = size;
01377                 _InvalidateContents();
01378         }
01379 }
01380 
01381 /*****************************************************************************
01382  * PositionInfoView::SetTime
01383  *****************************************************************************/
01384 void
01385 PositionInfoView::SetTime( int32 seconds )
01386 {
01387         if ( fSeconds != seconds )
01388         {
01389                 if ( seconds >= 0 )
01390                 {
01391                         int32 minutes = seconds / 60;
01392                         int32 hours = minutes / 60;
01393                         seconds -= minutes * 60 - hours * 60 * 60;
01394                         minutes -= hours * 60;
01395                         fTimeString.SetTo( "" );
01396                         fTimeString << hours << ":" << minutes << ":" << seconds;
01397                 }
01398                 else
01399                         fTimeString.SetTo( "-:--:--" );
01400 
01401                 fSeconds = seconds;
01402                 _InvalidateContents();
01403         }
01404 }
01405 
01406 /*****************************************************************************
01407  * PositionInfoView::SetTime
01408  *****************************************************************************/
01409 void
01410 PositionInfoView::SetTime( const char* string )
01411 {
01412         fTimeString.SetTo( string );
01413         _InvalidateContents();
01414 }
01415 
01416 /*****************************************************************************
01417  * PositionInfoView::_InvalidateContents
01418  *****************************************************************************/
01419 void
01420 PositionInfoView::_InvalidateContents( uint32 which )
01421 {
01422         BRect r( Bounds() );
01423         r.InsetBy( 2.0, 2.0 );
01424         Invalidate( r );
01425 }
01426 
01427 /*****************************************************************************
01428  * PositionInfoView::_InvalidateContents
01429  *****************************************************************************/
01430 void
01431 PositionInfoView::_MakeString( BString& into, int32 index, int32 maxIndex ) const
01432 {
01433         into = "";
01434         if ( index >= 0 && maxIndex >= 0 )
01435                 into << index;
01436         else
01437                 into << "-";
01438         into << "/";
01439         if ( maxIndex >= 0 )
01440                 into << maxIndex;
01441         else
01442                 into << "-";
01443 }

Generated on Tue Dec 20 10:14:37 2005 for vlc-0.8.4a by  doxygen 1.4.2