MediaControlView.cpp
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:45k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * MediaControlView.cpp: beos interface
  3.  *****************************************************************************
  4.  * Copyright (C) 1999, 2000, 2001 VideoLAN
  5.  * $Id: MediaControlView.cpp 8449 2004-08-17 20:55:55Z titer $
  6.  *
  7.  * Authors: Tony Castley <tony@castley.net>
  8.  *          Stephan Aßmus <stippi@yellowbites.com>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24. /* System headers */
  25. #include <InterfaceKit.h>
  26. #include <AppKit.h>
  27. #include <String.h>
  28. #include <string.h>
  29. /* VLC headers */
  30. #include <vlc/vlc.h>
  31. #include <vlc/intf.h>
  32. #include <vlc/input.h>
  33. extern "C"
  34. {
  35.   #include <audio_output.h>
  36. }
  37. /* BeOS interface headers */
  38. #include "Bitmaps.h"
  39. #include "DrawingTidbits.h"
  40. #include "InterfaceWindow.h"
  41. #include "MsgVals.h"
  42. #include "TransportButton.h"
  43. #include "ListViews.h"
  44. #include "MediaControlView.h"
  45. #define BORDER_INSET 6.0
  46. #define MIN_SPACE 4.0
  47. #define SPEAKER_SLIDER_DIST 6.0
  48. #define VOLUME_MIN_WIDTH 70.0
  49. #define DIM_LEVEL 0.4
  50. #define VOLUME_SLIDER_LAYOUT_WEIGHT 2.0
  51. #define SEEK_SLIDER_KNOB_WIDTH 8.0
  52. // slider colors are hardcoded here, because that's just
  53. // what they currently are within those bitmaps
  54. const rgb_color kGreen = (rgb_color){ 152, 203, 152, 255 };
  55. const rgb_color kGreenShadow = (rgb_color){ 102, 152, 102, 255 };
  56. const rgb_color kBackground = (rgb_color){ 216, 216, 216, 255 };
  57. const rgb_color kSeekGreen = (rgb_color){ 171, 221, 161, 255 };
  58. const rgb_color kSeekGreenShadow = (rgb_color){ 144, 186, 136, 255 };
  59. const rgb_color kSeekRed = (rgb_color){ 255, 0, 0, 255 };
  60. const rgb_color kSeekRedLight = (rgb_color){ 255, 152, 152, 255 };
  61. const rgb_color kSeekRedShadow = (rgb_color){ 178, 0, 0, 255 };
  62. #define DISABLED_SEEK_MESSAGE _("Drop files to play")
  63. #define SEEKSLIDER_RANGE 2048
  64. enum
  65. {
  66. MSG_REWIND = 'rwnd',
  67. MSG_FORWARD = 'frwd',
  68. MSG_SKIP_BACKWARDS = 'skpb',
  69. MSG_SKIP_FORWARD = 'skpf',
  70. };
  71. // constructor
  72. MediaControlView::MediaControlView( intf_thread_t * _p_intf, BRect frame)
  73. : BBox(frame, NULL, B_FOLLOW_NONE, B_WILL_DRAW | B_FRAME_EVENTS | B_PULSE_NEEDED,
  74.    B_PLAIN_BORDER),
  75.       p_intf( _p_intf ),
  76.       fCurrentRate(INPUT_RATE_DEFAULT),
  77.       fCurrentStatus(-1),
  78.       fBottomControlHeight(0.0),
  79.       fIsEnabled( true )
  80. {
  81. BRect frame(0.0, 0.0, 10.0, 10.0);
  82.     // Seek Slider
  83.     fSeekSlider = new SeekSlider( p_intf, frame, "seek slider", this );
  84.     fSeekSlider->SetValue(0);
  85.     fSeekSlider->ResizeToPreferred();
  86.     AddChild( fSeekSlider );
  87.     // Buttons
  88.     // Skip Back
  89.     frame.SetRightBottom(kSkipButtonSize);
  90. fBottomControlHeight = kRewindBitmapHeight - 1.0;
  91.     fSkipBack = new TransportButton(frame, B_EMPTY_STRING,
  92.                                     kSkipBackBitmapBits,
  93.                                     kPressedSkipBackBitmapBits,
  94.                                     kDisabledSkipBackBitmapBits,
  95.                                     new BMessage(MSG_SKIP_BACKWARDS));
  96.     AddChild( fSkipBack );
  97. // Play Pause
  98.     frame.SetRightBottom(kPlayButtonSize);
  99. if (fBottomControlHeight < kPlayPauseBitmapHeight - 1.0)
  100. fBottomControlHeight = kPlayPauseBitmapHeight - 1.0;
  101.     fPlayPause = new PlayPauseButton(frame, B_EMPTY_STRING,
  102.                                      kPlayButtonBitmapBits,
  103.                                      kPressedPlayButtonBitmapBits,
  104.                                      kDisabledPlayButtonBitmapBits,
  105.                                      kPlayingPlayButtonBitmapBits,
  106.                                      kPressedPlayingPlayButtonBitmapBits,
  107.                                      kPausedPlayButtonBitmapBits,
  108.                                      kPressedPausedPlayButtonBitmapBits,
  109.                                      new BMessage(START_PLAYBACK));
  110.     AddChild( fPlayPause );
  111.     // Skip Foward
  112.     frame.SetRightBottom(kSkipButtonSize);
  113.     fSkipForward = new TransportButton(frame, B_EMPTY_STRING,
  114.                                        kSkipForwardBitmapBits,
  115.                                        kPressedSkipForwardBitmapBits,
  116.                                        kDisabledSkipForwardBitmapBits,
  117.                                        new BMessage(MSG_SKIP_FORWARD));
  118.     AddChild( fSkipForward );
  119. // Forward
  120. fForward = new TransportButton(frame, B_EMPTY_STRING,
  121.    kForwardBitmapBits,
  122.    kPressedForwardBitmapBits,
  123.    kDisabledForwardBitmapBits,
  124.    new BMessage(MSG_FORWARD));
  125. // AddChild( fForward );
  126. // Rewind
  127. fRewind = new TransportButton(frame, B_EMPTY_STRING,
  128.   kRewindBitmapBits,
  129.   kPressedRewindBitmapBits,
  130.   kDisabledRewindBitmapBits,
  131.   new BMessage(MSG_REWIND));
  132. // AddChild( fRewind );
  133.     // Stop
  134.     frame.SetRightBottom(kStopButtonSize);
  135. if (fBottomControlHeight < kStopBitmapHeight - 1.0)
  136. fBottomControlHeight = kStopBitmapHeight - 1.0;
  137.     fStop = new TransportButton(frame, B_EMPTY_STRING,
  138.                                 kStopButtonBitmapBits,
  139.                                 kPressedStopButtonBitmapBits,
  140.                                 kDisabledStopButtonBitmapBits,
  141.                                 new BMessage(STOP_PLAYBACK));
  142. AddChild( fStop );
  143. // Mute
  144.     frame.SetRightBottom(kSpeakerButtonSize);
  145. if (fBottomControlHeight < kSpeakerIconBitmapHeight - 1.0)
  146. fBottomControlHeight = kSpeakerIconBitmapHeight - 1.0;
  147.     fMute = new TransportButton(frame, B_EMPTY_STRING,
  148.                                 kSpeakerIconBits,
  149.                                 kPressedSpeakerIconBits,
  150.                                 kSpeakerIconBits,
  151.                                 new BMessage(VOLUME_MUTE));
  152. AddChild( fMute );
  153.     // Volume Slider
  154. fVolumeSlider = new VolumeSlider(BRect(0.0, 0.0, VOLUME_MIN_WIDTH,
  155.    kVolumeSliderBitmapHeight - 1.0),
  156.  "volume slider", 1, AOUT_VOLUME_MAX,
  157.  new BMessage(VOLUME_CHG));
  158. fVolumeSlider->SetValue( config_GetInt( p_intf, "volume" ) );
  159. AddChild( fVolumeSlider );
  160. // Position Info View
  161.     fPositionInfo = new PositionInfoView(BRect(0.0, 0.0, 10.0, 10.0), "led",
  162.                                          p_intf);
  163.     fPositionInfo->ResizeToPreferred();
  164.     AddChild( fPositionInfo );
  165. }
  166. // destructor
  167. MediaControlView::~MediaControlView()
  168. {
  169. }
  170. // AttachedToWindow
  171. void
  172. MediaControlView::AttachedToWindow()
  173. {
  174. // we are now a valid BHandler
  175. fRewind->SetTarget(this);
  176. fForward->SetTarget(this);
  177. fSkipBack->SetTarget(this);
  178. fSkipForward->SetTarget(this);
  179. fVolumeSlider->SetTarget(Window());
  180. BRect r(_MinFrame());
  181. if (BMenuBar* menuBar = Window()->KeyMenuBar()) {
  182. float width, height;
  183. menuBar->GetPreferredSize(&width, &height);
  184. // r.bottom += menuBar->Bounds().Height();
  185. r.bottom += height;
  186. // see that our calculated minimal width is not smaller than what
  187. // the menubar can be
  188. printf("preferred: width: %f, height: %f - width: %fn", width, height, r.Width());
  189. width -= r.Width();
  190. if (width > 0.0)
  191. r.right += width;
  192. }
  193. Window()->SetSizeLimits(r.Width(), r.Width() * 1.8, r.Height(), r.Height() * 1.3);
  194. if (!Window()->Bounds().Contains(r))
  195. Window()->ResizeTo(r.Width(), r.Height());
  196. else
  197. FrameResized(Bounds().Width(), Bounds().Height());
  198. // get pulse message every two frames
  199. Window()->SetPulseRate(80000);
  200. }
  201. // FrameResized
  202. void
  203. MediaControlView::FrameResized(float width, float height)
  204. {
  205. BRect r(Bounds());
  206. // make sure we don't leave dirty pixels
  207. // (B_FULL_UPDATE_ON_RESIZE == annoying flicker -> this is smarter)
  208. if (fOldBounds.Width() < r.Width())
  209. Invalidate(BRect(fOldBounds.right, fOldBounds.top + 1.0,
  210.  fOldBounds.right, fOldBounds.bottom - 1.0));
  211. else
  212. Invalidate(BRect(r.right, r.top + 1.0,
  213.  r.right, r.bottom - 1.0));
  214. if (fOldBounds.Height() < r.Height())
  215. Invalidate(BRect(fOldBounds.left + 1.0, fOldBounds.bottom,
  216.  fOldBounds.right - 1.0, fOldBounds.bottom));
  217. else
  218. Invalidate(BRect(r.left + 1.0, r.bottom,
  219.  r.right - 1.0, r.bottom));
  220. // remember for next time
  221. fOldBounds = r;
  222. // layout controls
  223. r.InsetBy(BORDER_INSET, BORDER_INSET);
  224. _LayoutControls(r);
  225. }
  226. // GetPreferredSize
  227. void
  228. MediaControlView::GetPreferredSize(float* width, float* height)
  229. {
  230. if (width && height)
  231. {
  232. BRect r(_MinFrame());
  233. *width = r.Width();
  234. *height = r.Height();
  235. }
  236. }
  237. // MessageReceived
  238. void
  239. MediaControlView::MessageReceived(BMessage* message)
  240. {
  241. switch (message->what)
  242. {
  243. case MSG_REWIND:
  244. break;
  245. case MSG_FORWARD:
  246. break;
  247. case MSG_SKIP_BACKWARDS:
  248. Window()->PostMessage(NAVIGATE_PREV);
  249. break;
  250. case MSG_SKIP_FORWARD:
  251. Window()->PostMessage(NAVIGATE_NEXT);
  252. break;
  253. default:
  254.     BBox::MessageReceived(message);
  255.     break;
  256. }
  257. }
  258. // Pulse
  259. void
  260. MediaControlView::Pulse()
  261. {
  262. InterfaceWindow* window = dynamic_cast<InterfaceWindow*>(Window());
  263. if (window && window->IsStopped())
  264. fPlayPause->SetStopped();
  265.     unsigned short i_volume;
  266.     aout_VolumeGet( p_intf, (audio_volume_t*)&i_volume );
  267.     fVolumeSlider->SetValue( i_volume );
  268. }
  269. // SetProgress
  270. void
  271. MediaControlView::SetProgress( float position )
  272. {
  273. fSeekSlider->SetPosition( position );
  274. }
  275. // SetStatus
  276. void
  277. MediaControlView::SetStatus(int status, int rate)
  278. {
  279. // we need to set the button status periodically
  280. // (even if it is the same) to get a blinking button
  281. fCurrentStatus = status;
  282.     switch( status )
  283.     {
  284.         case PLAYING_S:
  285.             fPlayPause->SetPlaying();
  286.             break;
  287.         case PAUSE_S:
  288.             fPlayPause->SetPaused();
  289.             break;
  290.         default:
  291.             fPlayPause->SetStopped();
  292.             break;
  293.     }
  294. if (rate != fCurrentRate)
  295. {
  296. fCurrentRate = rate;
  297.     if ( rate < INPUT_RATE_DEFAULT )
  298.     {
  299.      // TODO: ...
  300.     }
  301. }
  302. }
  303. // SetEnabled
  304. void
  305. MediaControlView::SetEnabled(bool enabled)
  306. {
  307.     if( ( enabled && fIsEnabled ) ||
  308.         ( !enabled && !fIsEnabled ) )
  309.     {
  310.         /* do not redraw if it is not necessary */
  311.         return;
  312.     }
  313.     
  314. if( LockLooper() )
  315. {
  316. fSkipBack->SetEnabled( enabled );
  317. fPlayPause->SetEnabled( enabled );
  318. fSkipForward->SetEnabled( enabled );
  319. fStop->SetEnabled( enabled );
  320. fMute->SetEnabled( enabled );
  321. fVolumeSlider->SetEnabled( enabled );
  322. fSeekSlider->SetEnabled( enabled );
  323. fRewind->SetEnabled( enabled );
  324. fForward->SetEnabled( enabled );
  325. UnlockLooper();
  326. fIsEnabled = enabled;
  327. }
  328. }
  329. // SetAudioEnabled
  330. void
  331. MediaControlView::SetAudioEnabled(bool enabled)
  332. {
  333. fMute->SetEnabled(enabled);
  334. fVolumeSlider->SetEnabled(enabled);
  335. }
  336. // GetVolume
  337. uint32
  338. MediaControlView::GetVolume() const
  339. {
  340. return fVolumeSlider->Value();
  341. }
  342. // SetSkippable
  343. void
  344. MediaControlView::SetSkippable(bool backward, bool forward)
  345. {
  346. fSkipBack->SetEnabled(backward);
  347. fSkipForward->SetEnabled(forward);
  348. }
  349. // SetMuted
  350. void
  351. MediaControlView::SetMuted(bool mute)
  352. {
  353. fVolumeSlider->SetMuted(mute);
  354. }
  355. // _LayoutControls
  356. void
  357. MediaControlView::_LayoutControls(BRect frame) const
  358. {
  359. // seek slider
  360. BRect r(frame);
  361. // calculate absolutly minimal width
  362. float minWidth = fSkipBack->Bounds().Width();
  363. // minWidth += fRewind->Bounds().Width();
  364. minWidth += fStop->Bounds().Width();
  365. minWidth += fPlayPause->Bounds().Width();
  366. // minWidth += fForward->Bounds().Width();
  367. minWidth += fSkipForward->Bounds().Width();
  368. minWidth += fMute->Bounds().Width();
  369. minWidth += VOLUME_MIN_WIDTH;
  370. // layout time slider and info view
  371.     float width, height;
  372.     fPositionInfo->GetBigPreferredSize( &width, &height );
  373.     float ratio = width / height;
  374.     width = r.Height() * ratio;
  375.     if (frame.Width() - minWidth - MIN_SPACE >= width
  376.               && frame.Height() >= height)
  377.     {
  378.         r.right = r.left + width;
  379.         fPositionInfo->SetMode(PositionInfoView::MODE_BIG);
  380.         _LayoutControl(fPositionInfo, r, true, true);
  381.         frame.left = r.right + MIN_SPACE;
  382.         r.left = frame.left;
  383.         r.right = frame.right;
  384.     //    r.bottom = r.top + r.Height() / 2.0 - MIN_SPACE / 2.0;
  385.         r.bottom = r.top + fSeekSlider->Bounds().Height();
  386.         _LayoutControl(fSeekSlider, r, true);
  387.     }
  388.     else
  389.     {
  390.         fPositionInfo->GetPreferredSize( &width, &height );
  391.         fPositionInfo->SetMode(PositionInfoView::MODE_SMALL);
  392.         fPositionInfo->ResizeTo(width, height);
  393.         r.bottom = r.top + r.Height() / 2.0 - MIN_SPACE / 2.0;
  394.         r.right = r.left + fPositionInfo->Bounds().Width();
  395.         _LayoutControl(fPositionInfo, r, true );
  396.         r.left = r.right + MIN_SPACE;
  397.         r.right = frame.right;
  398.         _LayoutControl(fSeekSlider, r, true);
  399.     }
  400. float currentWidth = frame.Width();
  401. float space = (currentWidth - minWidth) / 6.0;//8.0;
  402. // apply weighting
  403. space = MIN_SPACE + (space - MIN_SPACE) / VOLUME_SLIDER_LAYOUT_WEIGHT;
  404. // layout controls with "space" inbetween
  405. r.left = frame.left;
  406. r.top = r.bottom + MIN_SPACE + 1.0;
  407. r.bottom = frame.bottom;
  408. // skip back
  409. r.right = r.left + fSkipBack->Bounds().Width();
  410. _LayoutControl(fSkipBack, r);
  411. // rewind
  412. // r.left = r.right + space;
  413. // r.right = r.left + fRewind->Bounds().Width();
  414. // _LayoutControl(fRewind, r);
  415. // stop
  416. r.left = r.right + space;
  417. r.right = r.left + fStop->Bounds().Width();
  418. _LayoutControl(fStop, r);
  419. // play/pause
  420. r.left = r.right + space;
  421. r.right = r.left + fPlayPause->Bounds().Width();
  422. _LayoutControl(fPlayPause, r);
  423. // forward
  424. // r.left = r.right + space;
  425. // r.right = r.left + fForward->Bounds().Width();
  426. // _LayoutControl(fForward, r);
  427. // skip forward
  428. r.left = r.right + space;
  429. r.right = r.left + fSkipForward->Bounds().Width();
  430. _LayoutControl(fSkipForward, r);
  431. // speaker icon
  432. r.left = r.right + space + space;
  433. r.right = r.left + fMute->Bounds().Width();
  434. _LayoutControl(fMute, r);
  435. // volume slider
  436. r.left = r.right + SPEAKER_SLIDER_DIST; // keep speaker icon and volume slider attached
  437. r.right = frame.right;
  438. _LayoutControl(fVolumeSlider, r, true);
  439. }
  440. // _MinFrame
  441. BRect           
  442. MediaControlView::_MinFrame() const
  443. {
  444. // add up width of controls along bottom (seek slider will likely adopt)
  445. float minWidth = 2 * BORDER_INSET;
  446. minWidth += fSkipBack->Bounds().Width() + MIN_SPACE;
  447. // minWidth += fRewind->Bounds().Width() + MIN_SPACE;
  448. minWidth += fStop->Bounds().Width() + MIN_SPACE;
  449. minWidth += fPlayPause->Bounds().Width() + MIN_SPACE;
  450. // minWidth += fForward->Bounds().Width() + MIN_SPACE;
  451. minWidth += fSkipForward->Bounds().Width() + MIN_SPACE + MIN_SPACE;
  452. minWidth += fMute->Bounds().Width() + SPEAKER_SLIDER_DIST;
  453. minWidth += VOLUME_MIN_WIDTH;
  454. // add up height of seek slider and heighest control on bottom
  455. float minHeight = 2 * BORDER_INSET;
  456. minHeight += fSeekSlider->Bounds().Height() + MIN_SPACE + MIN_SPACE / 2.0;
  457. minHeight += fBottomControlHeight;
  458. return BRect(0.0, 0.0, minWidth - 1.0, minHeight - 1.0);
  459. }
  460. // _LayoutControl
  461. void
  462. MediaControlView::_LayoutControl(BView* view, BRect frame,
  463.                                  bool resizeWidth, bool resizeHeight) const
  464. {
  465.     if (!resizeHeight)
  466.     // center vertically
  467.     frame.top = (frame.top + frame.bottom) / 2.0 - view->Bounds().Height() / 2.0;
  468. if (!resizeWidth)
  469.     //center horizontally
  470. frame.left = (frame.left + frame.right) / 2.0 - view->Bounds().Width() / 2.0;
  471. view->MoveTo(frame.LeftTop());
  472. float width = resizeWidth ? frame.Width() : view->Bounds().Width();
  473. float height = resizeHeight ? frame.Height() : view->Bounds().Height();
  474.     if (resizeWidth || resizeHeight)
  475.         view->ResizeTo(width, height);
  476. }
  477. /*****************************************************************************
  478.  * SeekSlider
  479.  *****************************************************************************/
  480. SeekSlider::SeekSlider( intf_thread_t * _p_intf,
  481.                         BRect frame, const char* name, MediaControlView *owner )
  482. : BControl(frame, name, NULL, NULL, B_FOLLOW_NONE,
  483.    B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
  484.   p_intf(_p_intf),
  485.   fOwner(owner),
  486.   fTracking(false)
  487. {
  488. BFont font(be_plain_font);
  489. font.SetSize(9.0);
  490. SetFont(&font);
  491. }
  492. SeekSlider::~SeekSlider()
  493. {
  494. }
  495. /*****************************************************************************
  496.  * VolumeSlider::AttachedToWindow
  497.  *****************************************************************************/
  498. void
  499. SeekSlider::AttachedToWindow()
  500. {
  501. BControl::AttachedToWindow();
  502. SetViewColor(B_TRANSPARENT_32_BIT);
  503. }
  504. /*****************************************************************************
  505.  * VolumeSlider::Draw
  506.  *****************************************************************************/
  507. void
  508. SeekSlider::Draw(BRect updateRect)
  509. {
  510. BRect r(Bounds());
  511. float knobWidth2 = SEEK_SLIDER_KNOB_WIDTH / 2.0;
  512. float sliderStart = (r.left + knobWidth2);
  513. float sliderEnd = (r.right - knobWidth2);
  514. float knobPos = sliderStart
  515. + floorf((sliderEnd - sliderStart - 1.0) * Value()
  516. / SEEKSLIDER_RANGE);
  517. // draw both sides (the original from Be doesn't seem
  518. // to make a difference for enabled/disabled state)
  519. // DrawBitmapAsync(fLeftSideBits, r.LeftTop());
  520. // DrawBitmapAsync(fRightSideBits, BPoint(sliderEnd + 1.0, r.top));
  521. // colors for the slider area between the two bitmaps
  522. rgb_color background = kBackground;//ui_color(B_PANEL_BACKGROUND_COLOR);
  523. rgb_color shadow = tint_color(background, B_DARKEN_2_TINT);
  524. rgb_color softShadow = tint_color(background, B_DARKEN_1_TINT);
  525. rgb_color darkShadow = tint_color(background, B_DARKEN_4_TINT);
  526. rgb_color midShadow = tint_color(background, B_DARKEN_3_TINT);
  527. rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
  528. rgb_color softLight = tint_color(background, B_LIGHTEN_1_TINT);
  529. rgb_color green = kSeekGreen;
  530. rgb_color greenShadow = kSeekGreenShadow;
  531. rgb_color black = kBlack;
  532. rgb_color dotGrey = midShadow;
  533. rgb_color dotGreen = greenShadow;
  534. // draw frame
  535. _StrokeFrame(r, softShadow, softShadow, softLight, softLight);
  536. r.InsetBy(1.0, 1.0);
  537. _StrokeFrame(r, black, black, light, light);
  538. if (IsEnabled())
  539. {
  540. r.InsetBy(1.0, 1.0);
  541. // inner shadow
  542. _StrokeFrame(r, greenShadow, greenShadow, green, green);
  543. r.top++;
  544. r.left++;
  545. _StrokeFrame(r, greenShadow, greenShadow, green, green);
  546. // inside area
  547. r.InsetBy(1.0, 1.0);
  548. SetHighColor(green);
  549. FillRect(r);
  550. // dots
  551. int32 dotCount = (int32)(r.Width() / 6.0);
  552. BPoint dotPos;
  553. dotPos.y = r.top + 2.0;
  554. SetHighColor(dotGreen);
  555. for (int32 i = 0; i < dotCount; i++)
  556. {
  557. dotPos.x = sliderStart + i * 6.0 + 5.0;
  558. StrokeLine(dotPos, BPoint(dotPos.x, dotPos.y + 6.0));
  559. }
  560. // slider handle
  561. r.top -= 4.0;
  562. r.bottom += 3.0;
  563. r.left = knobPos - knobWidth2;
  564. r.right = knobPos + knobWidth2;
  565. // black outline
  566. float handleBottomSize = 2.0;
  567. float handleArrowSize = 6.0;
  568. BeginLineArray(10);
  569. // upper handle
  570. AddLine(BPoint(r.left, r.top + handleBottomSize),
  571. BPoint(r.left, r.top), black);
  572. AddLine(BPoint(r.left + 1.0, r.top),
  573. BPoint(r.right, r.top), black);
  574. AddLine(BPoint(r.right, r.top + 1.0),
  575. BPoint(r.right, r.top + handleBottomSize), black);
  576. AddLine(BPoint(r.right - 1.0, r.top + handleBottomSize + 1.0),
  577. BPoint(knobPos, r.top + handleArrowSize), black);
  578. AddLine(BPoint(knobPos - 1.0, r.top + handleArrowSize - 1.0),
  579. BPoint(r.left + 1.0, r.top + handleBottomSize + 1.0), black);
  580. // lower handle
  581. AddLine(BPoint(r.left, r.bottom),
  582. BPoint(r.left, r.bottom - handleBottomSize), black);
  583. AddLine(BPoint(r.left + 1.0, r.bottom - handleBottomSize - 1.0),
  584. BPoint(knobPos, r.bottom - handleArrowSize), black);
  585. AddLine(BPoint(knobPos + 1.0, r.bottom - handleArrowSize + 1.0),
  586. BPoint(r.right, r.bottom - handleBottomSize), black);
  587. AddLine(BPoint(r.right, r.bottom - handleBottomSize + 1.0),
  588. BPoint(r.right, r.bottom), black);
  589. AddLine(BPoint(r.right - 1.0, r.bottom),
  590. BPoint(r.left + 1.0, r.bottom), black);
  591. EndLineArray();
  592. // inner red light and shadow lines
  593. r.InsetBy(1.0, 1.0);
  594. handleBottomSize--;
  595. handleArrowSize -= 2.0;
  596. BeginLineArray(10);
  597. // upper handle
  598. AddLine(BPoint(r.left, r.top + handleBottomSize),
  599. BPoint(r.left, r.top), kSeekRedLight);
  600. AddLine(BPoint(r.left + 1.0, r.top),
  601. BPoint(r.right, r.top), kSeekRedLight);
  602. AddLine(BPoint(r.right, r.top + 1.0),
  603. BPoint(r.right, r.top + handleBottomSize), kSeekRedShadow);
  604. AddLine(BPoint(r.right - 1.0, r.top + handleBottomSize + 1.0),
  605. BPoint(knobPos, r.top + handleArrowSize), kSeekRedShadow);
  606. AddLine(BPoint(knobPos - 1.0, r.top + handleArrowSize - 1.0),
  607. BPoint(r.left + 1.0, r.top + handleBottomSize + 1.0), kSeekRedLight);
  608. // lower handle
  609. AddLine(BPoint(r.left, r.bottom),
  610. BPoint(r.left, r.bottom - handleBottomSize), kSeekRedLight);
  611. AddLine(BPoint(r.left + 1.0, r.bottom - handleBottomSize - 1.0),
  612. BPoint(knobPos, r.bottom - handleArrowSize), kSeekRedLight);
  613. AddLine(BPoint(knobPos + 1.0, r.bottom - handleArrowSize + 1.0),
  614. BPoint(r.right, r.bottom - handleBottomSize), kSeekRedShadow);
  615. AddLine(BPoint(r.right, r.bottom - handleBottomSize + 1.0),
  616. BPoint(r.right, r.bottom), kSeekRedShadow);
  617. AddLine(BPoint(r.right - 1.0, r.bottom),
  618. BPoint(r.left + 1.0, r.bottom), kSeekRedShadow);
  619. EndLineArray();
  620. // fill rest of handles with red
  621. SetHighColor(kSeekRed);
  622. r.InsetBy(1.0, 1.0);
  623. handleArrowSize -= 2.0;
  624. BPoint arrow[3];
  625. // upper handle arrow
  626. arrow[0].x = r.left;
  627. arrow[0].y = r.top;
  628. arrow[1].x = r.right;
  629. arrow[1].y = r.top;
  630. arrow[2].x = knobPos;
  631. arrow[2].y = r.top + handleArrowSize;
  632. FillPolygon(arrow, 3);
  633. // lower handle arrow
  634. arrow[0].x = r.left;
  635. arrow[0].y = r.bottom;
  636. arrow[1].x = r.right;
  637. arrow[1].y = r.bottom;
  638. arrow[2].x = knobPos;
  639. arrow[2].y = r.bottom - handleArrowSize;
  640. FillPolygon(arrow, 3);
  641. }
  642. else
  643. {
  644. r.InsetBy(1.0, 1.0);
  645. _StrokeFrame(r, darkShadow, darkShadow, darkShadow, darkShadow);
  646. r.InsetBy(1.0, 1.0);
  647. _StrokeFrame(r, darkShadow, darkShadow, darkShadow, darkShadow);
  648. r.InsetBy(1.0, 1.0);
  649. SetHighColor(darkShadow);
  650. SetLowColor(shadow);
  651. // stripes
  652. float width = floorf(StringWidth(DISABLED_SEEK_MESSAGE));
  653. float textPos = r.left + r.Width() / 2.0 - width / 2.0;
  654. pattern stripes = {{ 0xc7, 0x8f, 0x1f, 0x3e, 0x7c, 0xf8, 0xf1, 0xe3 }};
  655. BRect stripesRect(r);
  656. stripesRect.right = textPos - 5.0;
  657. FillRect(stripesRect, stripes);
  658. stripesRect.left = textPos + width + 3.0;
  659. stripesRect.right = r.right;
  660. FillRect(stripesRect, stripes);
  661. // info text
  662. r.left = textPos - 4.0;
  663. r.right = textPos + width + 2.0;
  664. FillRect(r);
  665. SetHighColor(shadow);
  666. SetLowColor(darkShadow);
  667. font_height fh;
  668. GetFontHeight(&fh);
  669. DrawString(DISABLED_SEEK_MESSAGE, BPoint(textPos, r.top + ceilf(fh.ascent) - 1.0));
  670. }
  671. }
  672. /*****************************************************************************
  673.  * SeekSlider::MouseDown
  674.  *****************************************************************************/
  675. void
  676. SeekSlider::MouseDown(BPoint where)
  677. {
  678. if (IsEnabled() && Bounds().Contains(where))
  679. {
  680. SetValue(_ValueFor(where.x));
  681. fTracking = true;
  682. SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
  683. }
  684. }
  685. /*****************************************************************************
  686.  * SeekSlider::MouseMoved
  687.  *****************************************************************************/
  688. void
  689. SeekSlider::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage)
  690. {
  691. if (fTracking)
  692. {
  693. SetValue(_ValueFor(where.x));
  694. }
  695. }
  696. /*****************************************************************************
  697.  * SeekSlider::MouseUp
  698.  *****************************************************************************/
  699. void
  700. SeekSlider::MouseUp(BPoint where)
  701. {
  702. if (fTracking)
  703. {
  704. fTracking = false;
  705. input_thread_t * p_input;
  706. p_input = (input_thread_t *)
  707.             vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
  708.         if( p_input )
  709.         {
  710.     var_SetFloat( p_input, "position",
  711.                   (float) Value() / SEEKSLIDER_RANGE );
  712.     vlc_object_release( p_input );
  713. }
  714. }
  715. }
  716. /*****************************************************************************
  717.  * SeekSlider::ResizeToPreferred
  718.  *****************************************************************************/
  719. void
  720. SeekSlider::ResizeToPreferred()
  721. {
  722. float width = 15.0 + StringWidth(DISABLED_SEEK_MESSAGE) + 15.0;
  723. ResizeTo(width, 17.0);
  724. }
  725. /*****************************************************************************
  726.  * SeekSlider::SetPosition
  727.  *****************************************************************************/
  728. void
  729. SeekSlider::SetPosition(float position)
  730. {
  731. if ( LockLooper() )
  732. {
  733.     if( !fTracking )
  734.     {
  735.     SetValue( SEEKSLIDER_RANGE * position );
  736. }
  737. UnlockLooper();
  738. }
  739. }
  740. /*****************************************************************************
  741.  * SeekSlider::_ValueFor
  742.  *****************************************************************************/
  743. int32
  744. SeekSlider::_ValueFor(float xPos) const
  745. {
  746. BRect r(Bounds());
  747. float knobWidth2 = SEEK_SLIDER_KNOB_WIDTH / 2.0;
  748. float sliderStart = (r.left + knobWidth2);
  749. float sliderEnd = (r.right - knobWidth2);
  750. int32 value =  (int32)(((xPos - sliderStart) * SEEKSLIDER_RANGE)
  751.   / (sliderEnd - sliderStart - 1.0));
  752. if (value < 0)
  753. value = 0;
  754. if (value > SEEKSLIDER_RANGE)
  755. value = SEEKSLIDER_RANGE;
  756. return value;
  757. }
  758. /*****************************************************************************
  759.  * SeekSlider::_StrokeFrame
  760.  *****************************************************************************/
  761. void
  762. SeekSlider::_StrokeFrame(BRect r, rgb_color left, rgb_color top,
  763.  rgb_color right, rgb_color bottom)
  764. {
  765. BeginLineArray(4);
  766. AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), left);
  767. AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), top);
  768. AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), right);
  769. AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), bottom);
  770. EndLineArray();
  771. }
  772. /*****************************************************************************
  773.  * VolumeSlider
  774.  *****************************************************************************/
  775. VolumeSlider::VolumeSlider(BRect frame, const char* name, int32 minValue, int32 maxValue,
  776.    BMessage* message, BHandler* target)
  777. : BControl(frame, name, NULL, message, B_FOLLOW_NONE,
  778.    B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
  779.   fLeftSideBits(NULL),
  780.   fRightSideBits(NULL),
  781.   fKnobBits(NULL),
  782.   fTracking(false),
  783.   fMuted(false),
  784.   fMinValue(minValue),
  785.   fMaxValue(maxValue)
  786. {
  787. SetTarget(target);
  788. // create bitmaps
  789. BRect r(BPoint(0.0, 0.0), kVolumeSliderBitmapSize);
  790. fLeftSideBits = new BBitmap(r, B_CMAP8);
  791. fRightSideBits = new BBitmap(r, B_CMAP8);
  792. r.Set(0.0, 0.0, kVolumeSliderKnobBitmapSize.x, kVolumeSliderKnobBitmapSize.y);
  793. fKnobBits = new BBitmap(r, B_CMAP8);
  794. _MakeBitmaps();
  795. }
  796. /*****************************************************************************
  797.  * VolumeSlider destructor
  798.  *****************************************************************************/
  799. VolumeSlider::~VolumeSlider()
  800. {
  801. delete fLeftSideBits;
  802. delete fRightSideBits;
  803. delete fKnobBits;
  804. }
  805. /*****************************************************************************
  806.  * VolumeSlider::AttachedToWindow
  807.  *****************************************************************************/
  808. void
  809. VolumeSlider::AttachedToWindow()
  810. {
  811. BControl::AttachedToWindow();
  812. SetViewColor(B_TRANSPARENT_32_BIT);
  813. }
  814. /*****************************************************************************
  815.  * VolumeSlider::SetValue
  816.  *****************************************************************************/
  817. void
  818. VolumeSlider::SetValue(int32 value)
  819. {
  820. if (value != Value())
  821. {
  822. BControl::SetValue(value);
  823. Invoke();
  824. }
  825. }
  826. /*****************************************************************************
  827.  * VolumeSlider::SetEnabled
  828.  *****************************************************************************/
  829. void
  830. VolumeSlider::SetEnabled(bool enable)
  831. {
  832. if (enable != IsEnabled())
  833. {
  834. BControl::SetEnabled(enable);
  835. _MakeBitmaps();
  836. Invalidate();
  837. }
  838. }
  839. /*****************************************************************************
  840.  * VolumeSlider::Draw
  841.  *****************************************************************************/
  842. void
  843. VolumeSlider::Draw(BRect updateRect)
  844. {
  845. if (IsValid())
  846. {
  847. BRect r(Bounds());
  848. float sliderSideWidth = kVolumeSliderBitmapWidth;
  849. float sliderStart = (r.left + sliderSideWidth);
  850. float sliderEnd = (r.right - sliderSideWidth);
  851. float knobPos = sliderStart
  852. + (sliderEnd - sliderStart - 1.0) * (Value() - fMinValue)
  853. / (fMaxValue - fMinValue);
  854. // draw both sides (the original from Be doesn't seem
  855. // to make a difference for enabled/disabled state)
  856. DrawBitmapAsync(fLeftSideBits, r.LeftTop());
  857. DrawBitmapAsync(fRightSideBits, BPoint(sliderEnd + 1.0, r.top));
  858. // colors for the slider area between the two bitmaps
  859. rgb_color background = kBackground;//ui_color(B_PANEL_BACKGROUND_COLOR);
  860. rgb_color shadow = tint_color(background, B_DARKEN_2_TINT);
  861. rgb_color softShadow = tint_color(background, B_DARKEN_1_TINT);
  862. rgb_color darkShadow = tint_color(background, B_DARKEN_4_TINT);
  863. rgb_color midShadow = tint_color(background, B_DARKEN_3_TINT);
  864. rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
  865. rgb_color softLight = tint_color(background, B_LIGHTEN_1_TINT);
  866. rgb_color green = kGreen;
  867. rgb_color greenShadow = kGreenShadow;
  868. rgb_color black = kBlack;
  869. rgb_color dotGrey = midShadow;
  870. rgb_color dotGreen = greenShadow;
  871. // make dimmed version of colors if we're disabled
  872. if (!IsEnabled())
  873. {
  874. shadow = (rgb_color){ 200, 200, 200, 255 };
  875. softShadow = dimmed_color_cmap8(softShadow, background, DIM_LEVEL);
  876. darkShadow = dimmed_color_cmap8(darkShadow, background, DIM_LEVEL);
  877. midShadow = shadow;
  878. light = dimmed_color_cmap8(light, background, DIM_LEVEL);
  879. softLight = dimmed_color_cmap8(softLight, background, DIM_LEVEL);
  880. green = dimmed_color_cmap8(green, background, DIM_LEVEL);
  881. greenShadow = dimmed_color_cmap8(greenShadow, background, DIM_LEVEL);
  882. black = dimmed_color_cmap8(black, background, DIM_LEVEL);
  883. dotGreen = dotGrey;
  884. }
  885. else if (fMuted)
  886. {
  887. green = tint_color(kBackground, B_DARKEN_3_TINT);
  888. greenShadow = tint_color(kBackground, B_DARKEN_4_TINT);
  889. dotGreen = greenShadow;
  890. }
  891. // draw slider edges between bitmaps
  892. BeginLineArray(7);
  893. AddLine(BPoint(sliderStart, r.top),
  894. BPoint(sliderEnd, r.top), softShadow);
  895. AddLine(BPoint(sliderStart, r.bottom),
  896. BPoint(sliderEnd, r.bottom), softLight);
  897. r.InsetBy(0.0, 1.0);
  898. AddLine(BPoint(sliderStart, r.top),
  899. BPoint(sliderEnd, r.top), black);
  900. AddLine(BPoint(sliderStart, r.bottom),
  901. BPoint(sliderEnd, r.bottom), light);
  902. r.top++;
  903. AddLine(BPoint(sliderStart, r.top),
  904. BPoint(knobPos, r.top), greenShadow);
  905. AddLine(BPoint(knobPos, r.top),
  906. BPoint(sliderEnd, r.top), midShadow);
  907. r.top++;
  908. AddLine(BPoint(sliderStart, r.top),
  909. BPoint(knobPos, r.top), greenShadow);
  910. EndLineArray();
  911. // fill rest inside of slider
  912. r.InsetBy(0.0, 1.0);
  913. r.left = sliderStart;
  914. r.right = knobPos;
  915. SetHighColor(green);
  916. FillRect(r, B_SOLID_HIGH);
  917. r.left = knobPos + 1.0;
  918. r.right = sliderEnd;
  919. r.top -= 1.0;
  920. SetHighColor(shadow);
  921. FillRect(r, B_SOLID_HIGH);
  922. // draw little dots inside
  923. int32 dotCount = (int32)((sliderEnd - sliderStart) / 5.0);
  924. BPoint dotPos;
  925. dotPos.y = r.top + 4.0;
  926. for (int32 i = 0; i < dotCount; i++)
  927. {
  928. dotPos.x = sliderStart + i * 5.0 + 4.0;
  929. SetHighColor(dotPos.x < knobPos ? dotGreen : dotGrey);
  930. StrokeLine(dotPos, BPoint(dotPos.x, dotPos.y + 1.0));
  931. }
  932. // draw knob
  933. r.top -= 1.0;
  934. SetDrawingMode(B_OP_OVER); // part of knob is transparent
  935. DrawBitmapAsync(fKnobBits, BPoint(knobPos - kVolumeSliderKnobWidth / 2, r.top));
  936. }
  937. }
  938. /*****************************************************************************
  939.  * VolumeSlider::MouseDown
  940.  *****************************************************************************/
  941. void
  942. VolumeSlider::MouseDown(BPoint where)
  943. {
  944. if (Bounds().Contains(where) && IsEnabled())
  945. {
  946. fTracking = true;
  947. SetValue(_ValueFor(where.x));
  948. SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
  949. }
  950. }
  951. /*****************************************************************************
  952.  * VolumeSlider::MouseMoved
  953.  *****************************************************************************/
  954. void
  955. VolumeSlider::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
  956. {
  957. if (fTracking)
  958. SetValue(_ValueFor(where.x));
  959. }
  960. /*****************************************************************************
  961.  * VolumeSlider::MouseUp
  962.  *****************************************************************************/
  963. void
  964. VolumeSlider::MouseUp(BPoint where)
  965. {
  966. fTracking = false;
  967. }
  968. /*****************************************************************************
  969.  * VolumeSlider::IsValid
  970.  *****************************************************************************/
  971. bool
  972. VolumeSlider::IsValid() const
  973. {
  974. return (fLeftSideBits && fLeftSideBits->IsValid()
  975. && fRightSideBits && fRightSideBits->IsValid()
  976. && fKnobBits && fKnobBits->IsValid());
  977. }
  978. /*****************************************************************************
  979.  * VolumeSlider::SetMuted
  980.  *****************************************************************************/
  981. void
  982. VolumeSlider::SetMuted(bool mute)
  983. {
  984. if (mute != fMuted)
  985. {
  986. fMuted = mute;
  987. _MakeBitmaps();
  988. Invalidate();
  989. }
  990. }
  991. /*****************************************************************************
  992.  * VolumeSlider::_MakeBitmaps
  993.  *****************************************************************************/
  994. void
  995. VolumeSlider::_MakeBitmaps()
  996. {
  997. if (IsValid())
  998. {
  999. // left side of slider
  1000. memcpy(fLeftSideBits->Bits(), kVolumeSliderLeftBitmapBits,
  1001.    fLeftSideBits->BitsLength());
  1002. // right side of slider
  1003. memcpy(fRightSideBits->Bits(), kVolumeSliderRightBits,
  1004.    fRightSideBits->BitsLength());
  1005. // slider knob
  1006. int32 length = fKnobBits->BitsLength();
  1007. memcpy(fKnobBits->Bits(), kVolumeSliderKnobBits, length);
  1008. uint8* bits = (uint8*)fKnobBits->Bits();
  1009. // black was used in the knob to represent transparency
  1010. // use screen to get index for the "transarent" color used in the bitmap
  1011. BScreen screen(B_MAIN_SCREEN_ID);
  1012. uint8 blackIndex = screen.IndexForColor(kBlack);
  1013. // replace black index with transparent index
  1014. for (int32 i = 0; i < length; i++)
  1015. if (bits[i] == blackIndex)
  1016. bits[i] = B_TRANSPARENT_MAGIC_CMAP8;
  1017. if (!IsEnabled())
  1018. {
  1019. // make ghosted versions of the bitmaps
  1020. dim_bitmap(fLeftSideBits, kBackground, DIM_LEVEL);
  1021. dim_bitmap(fRightSideBits, kBackground, DIM_LEVEL);
  1022. dim_bitmap(fKnobBits, kBackground, DIM_LEVEL);
  1023. }
  1024. else if (fMuted)
  1025. {
  1026. // replace green color (and shadow) in left slider side
  1027. bits = (uint8*)fLeftSideBits->Bits();
  1028. length = fLeftSideBits->BitsLength();
  1029. uint8 greenIndex = screen.IndexForColor(kGreen);
  1030. uint8 greenShadowIndex = screen.IndexForColor(kGreenShadow);
  1031. rgb_color shadow = tint_color(kBackground, B_DARKEN_3_TINT);
  1032. rgb_color midShadow = tint_color(kBackground, B_DARKEN_4_TINT);
  1033. uint8 replaceIndex = screen.IndexForColor(shadow);
  1034. uint8 replaceShadowIndex = screen.IndexForColor(midShadow);
  1035. for (int32 i = 0; i < length; i++)
  1036. {
  1037. if (bits[i] == greenIndex)
  1038. bits[i] = replaceIndex;
  1039. else if (bits[i] == greenShadowIndex)
  1040. bits[i] = replaceShadowIndex;
  1041. }
  1042. }
  1043. }
  1044. }
  1045. /*****************************************************************************
  1046.  * VolumeSlider::_ValueFor
  1047.  *****************************************************************************/
  1048. int32
  1049. VolumeSlider::_ValueFor(float xPos) const
  1050. {
  1051. BRect r(Bounds());
  1052. float sliderStart = (r.left + kVolumeSliderBitmapWidth);
  1053. float sliderEnd = (r.right - kVolumeSliderBitmapWidth);
  1054. int32 value =  fMinValue + (int32)(((xPos - sliderStart) * (fMaxValue - fMinValue))
  1055.   / (sliderEnd - sliderStart - 1.0));
  1056. if (value < fMinValue)
  1057. value = fMinValue;
  1058. if (value > fMaxValue)
  1059. value = fMaxValue;
  1060. return value;
  1061. }
  1062. /*****************************************************************************
  1063.  * PositionInfoView::PositionInfoView
  1064.  *****************************************************************************/
  1065. PositionInfoView::PositionInfoView( BRect frame, const char* name,
  1066.                                     intf_thread_t * p_interface )
  1067. : BView( frame, name, B_FOLLOW_NONE,
  1068.  B_WILL_DRAW | B_PULSE_NEEDED | B_FULL_UPDATE_ON_RESIZE ),
  1069.   fMode( MODE_SMALL ),
  1070.   fCurrentFileIndex( -1 ),
  1071.   fCurrentFileSize( -1 ),
  1072.   fCurrentTitleIndex( -1 ),
  1073.   fCurrentTitleSize( -1 ),
  1074.   fCurrentChapterIndex( -1 ),
  1075.   fCurrentChapterSize( -1 ),
  1076.   fSeconds( -1 ),
  1077.   fTimeString( "-:--:--" ),
  1078.   fLastPulseUpdate( system_time() ),
  1079.   fStackedWidthCache( 0.0 ),
  1080.   fStackedHeightCache( 0.0 )
  1081. {
  1082.     p_intf = p_interface;
  1083. SetViewColor( B_TRANSPARENT_32_BIT );
  1084. SetLowColor( kBlack );
  1085. SetHighColor( 0, 255, 0, 255 );
  1086. SetFontSize( 11.0 );
  1087. }
  1088. /*****************************************************************************
  1089.  * PositionInfoView::~PositionInfoView
  1090.  *****************************************************************************/
  1091. PositionInfoView::~PositionInfoView()
  1092. {
  1093. }
  1094. /*****************************************************************************
  1095.  * PositionInfoView::Draw
  1096.  *****************************************************************************/
  1097. void
  1098. PositionInfoView::Draw( BRect updateRect )
  1099. {
  1100. rgb_color background = ui_color( B_PANEL_BACKGROUND_COLOR );
  1101. rgb_color shadow = tint_color( background, B_DARKEN_1_TINT );
  1102. rgb_color darkShadow = tint_color( background, B_DARKEN_4_TINT );
  1103. rgb_color light = tint_color( background, B_LIGHTEN_MAX_TINT );
  1104. rgb_color softLight = tint_color( background, B_LIGHTEN_1_TINT );
  1105. // frame
  1106. BRect r( Bounds() );
  1107. BeginLineArray( 8 );
  1108. AddLine( BPoint( r.left, r.bottom ),
  1109.  BPoint( r.left, r.top ), shadow );
  1110. AddLine( BPoint( r.left + 1.0, r.top ),
  1111.  BPoint( r.right, r.top ), shadow );
  1112. AddLine( BPoint( r.right, r.top + 1.0 ),
  1113.  BPoint( r.right, r.bottom ), softLight );
  1114. AddLine( BPoint( r.right - 1.0, r.bottom ),
  1115.  BPoint( r.left + 1.0, r.bottom ), softLight );
  1116. r.InsetBy( 1.0, 1.0 );
  1117. AddLine( BPoint( r.left, r.bottom ),
  1118.  BPoint( r.left, r.top ), darkShadow );
  1119. AddLine( BPoint( r.left + 1.0, r.top ),
  1120.  BPoint( r.right, r.top ), darkShadow );
  1121. AddLine( BPoint( r.right, r.top + 1.0 ),
  1122.  BPoint( r.right, r.bottom ), light );
  1123. AddLine( BPoint( r.right - 1.0, r.bottom ),
  1124.  BPoint( r.left + 1.0, r.bottom ), light );
  1125. EndLineArray();
  1126. // background
  1127. r.InsetBy( 1.0, 1.0 );
  1128. FillRect( r, B_SOLID_LOW );
  1129. // contents
  1130. font_height fh;
  1131. GetFontHeight( &fh );
  1132. switch ( fMode )
  1133. {
  1134. case MODE_SMALL:
  1135. {
  1136. float width = StringWidth( fTimeString.String() );
  1137. DrawString( fTimeString.String(),
  1138. BPoint( r.left + r.Width() / 2.0 - width / 2.0,
  1139. r.top + r.Height() / 2.0 + fh.ascent / 2.0 - 1.0 ) );
  1140. break;
  1141. }
  1142. case MODE_BIG:
  1143. {
  1144. BFont font;
  1145. GetFont( &font );
  1146. BFont smallFont = font;
  1147. BFont bigFont = font;
  1148. BFont tinyFont = font;
  1149. smallFont.SetSize( r.Height() / 5.0 );
  1150. bigFont.SetSize( r.Height() / 3.0 );
  1151. tinyFont.SetSize( r.Height() / 7.0 );
  1152. float timeHeight = r.Height() / 2.5;
  1153. float height = ( r.Height() - timeHeight ) / 3.0;
  1154. SetFont( &tinyFont );
  1155. SetHighColor( 0, 180, 0, 255 );
  1156. DrawString( _("File"), BPoint( r.left + 3.0, r.top + height ) );
  1157. DrawString( _("Title"), BPoint( r.left + 3.0, r.top + 2.0 * height ) );
  1158. DrawString( _("Chapter"), BPoint( r.left + 3.0, r.top + 3.0 * height ) );
  1159. SetFont( &smallFont );
  1160. BString helper;
  1161. SetHighColor( 0, 255, 0, 255 );
  1162. // file
  1163. _MakeString( helper, fCurrentFileIndex, fCurrentFileSize );
  1164. float width = StringWidth( helper.String() );
  1165. DrawString( helper.String(), BPoint( r.right - 3.0 - width, r.top + height ) );
  1166. // title
  1167. _MakeString( helper, fCurrentTitleIndex, fCurrentTitleSize );
  1168. width = StringWidth( helper.String() );
  1169. DrawString( helper.String(), BPoint( r.right - 3.0 - width, r.top + 2.0 * height ) );
  1170. // chapter
  1171. _MakeString( helper, fCurrentChapterIndex, fCurrentChapterSize );
  1172. width = StringWidth( helper.String() );
  1173. DrawString( helper.String(), BPoint( r.right - 3.0 - width, r.top + 3.0 * height ) );
  1174. // time
  1175. SetFont( &bigFont );
  1176. width = StringWidth( fTimeString.String() );
  1177. DrawString( fTimeString.String(),
  1178. BPoint( r.left + r.Width() / 2.0 - width / 2.0,
  1179. r.bottom - 3.0 ) );
  1180. break;
  1181. }
  1182. }
  1183. }
  1184. /*****************************************************************************
  1185.  * PositionInfoView::ResizeToPreferred
  1186.  *****************************************************************************/
  1187. void
  1188. PositionInfoView::ResizeToPreferred()
  1189. {
  1190. float width, height;
  1191. GetPreferredSize( &width, &height );
  1192. ResizeTo( width, height );
  1193. }
  1194. /*****************************************************************************
  1195.  * PositionInfoView::GetPreferredSize
  1196.  *****************************************************************************/
  1197. void
  1198. PositionInfoView::GetPreferredSize( float* width, float* height )
  1199. {
  1200. if ( width && height )
  1201. {
  1202. *width = 5.0 + ceilf( StringWidth( "0:00:00" ) ) + 5.0;
  1203. font_height fh;
  1204. GetFontHeight( &fh );
  1205. *height = 3.0 + ceilf( fh.ascent ) + 3.0;
  1206. fStackedWidthCache = *width * 1.2;
  1207. fStackedHeightCache = *height * 2.7;
  1208. }
  1209. }
  1210. /*****************************************************************************
  1211.  * PositionInfoView::Pulse
  1212.  *****************************************************************************/
  1213. void
  1214. PositionInfoView::Pulse()
  1215. {
  1216. // allow for Pulse frequency to be higher, MediaControlView needs it
  1217. bigtime_t now = system_time();
  1218. if ( now - fLastPulseUpdate > 900000 )
  1219. {
  1220. #if 0
  1221. int32 index, size;
  1222. p_intf->p_sys->p_wrapper->GetPlaylistInfo( index, size );
  1223. SetFile( index + 1, size );
  1224. p_intf->p_sys->p_wrapper->TitleInfo( index, size );
  1225. SetTitle( index, size );
  1226. p_intf->p_sys->p_wrapper->ChapterInfo( index, size );
  1227. SetChapter( index, size );
  1228. SetTime( p_intf->p_sys->p_wrapper->GetTimeAsString() );
  1229. fLastPulseUpdate = now;
  1230. #endif
  1231. }
  1232. }
  1233. /*****************************************************************************
  1234.  * PositionInfoView::GetBigPreferredSize
  1235.  *****************************************************************************/
  1236. void
  1237. PositionInfoView::GetBigPreferredSize( float* width, float* height )
  1238. {
  1239. if ( width && height )
  1240. {
  1241. *width = fStackedWidthCache;
  1242. *height = fStackedHeightCache;
  1243. }
  1244. }
  1245. /*****************************************************************************
  1246.  * PositionInfoView::SetMode
  1247.  *****************************************************************************/
  1248. void
  1249. PositionInfoView::SetMode( uint32 mode )
  1250. {
  1251. if ( fMode != mode )
  1252. {
  1253. fMode = mode;
  1254. _InvalidateContents();
  1255. }
  1256. }
  1257. /*****************************************************************************
  1258.  * PositionInfoView::SetFile
  1259.  *****************************************************************************/
  1260. void
  1261. PositionInfoView::SetFile( int32 index, int32 size )
  1262. {
  1263. if ( fCurrentFileIndex != index || fCurrentFileSize != size )
  1264. {
  1265. fCurrentFileIndex = index;
  1266. fCurrentFileSize = size;
  1267. _InvalidateContents();
  1268. }
  1269. }
  1270. /*****************************************************************************
  1271.  * PositionInfoView::SetTitle
  1272.  *****************************************************************************/
  1273. void
  1274. PositionInfoView::SetTitle( int32 index, int32 size )
  1275. {
  1276. if ( fCurrentTitleIndex != index || fCurrentFileSize != size )
  1277. {
  1278. fCurrentTitleIndex = index;
  1279. fCurrentTitleSize = size;
  1280. _InvalidateContents();
  1281. }
  1282. }
  1283. /*****************************************************************************
  1284.  * PositionInfoView::SetChapter
  1285.  *****************************************************************************/
  1286. void
  1287. PositionInfoView::SetChapter( int32 index, int32 size )
  1288. {
  1289. if ( fCurrentChapterIndex != index || fCurrentFileSize != size )
  1290. {
  1291. fCurrentChapterIndex = index;
  1292. fCurrentChapterSize = size;
  1293. _InvalidateContents();
  1294. }
  1295. }
  1296. /*****************************************************************************
  1297.  * PositionInfoView::SetTime
  1298.  *****************************************************************************/
  1299. void
  1300. PositionInfoView::SetTime( int32 seconds )
  1301. {
  1302. if ( fSeconds != seconds )
  1303. {
  1304. if ( seconds >= 0 )
  1305. {
  1306. int32 minutes = seconds / 60;
  1307. int32 hours = minutes / 60;
  1308. seconds -= minutes * 60 - hours * 60 * 60;
  1309. minutes -= hours * 60;
  1310. fTimeString.SetTo( "" );
  1311. fTimeString << hours << ":" << minutes << ":" << seconds;
  1312. }
  1313. else
  1314. fTimeString.SetTo( "-:--:--" );
  1315. fSeconds = seconds;
  1316. _InvalidateContents();
  1317. }
  1318. }
  1319. /*****************************************************************************
  1320.  * PositionInfoView::SetTime
  1321.  *****************************************************************************/
  1322. void
  1323. PositionInfoView::SetTime( const char* string )
  1324. {
  1325. fTimeString.SetTo( string );
  1326. _InvalidateContents();
  1327. }
  1328. /*****************************************************************************
  1329.  * PositionInfoView::_InvalidateContents
  1330.  *****************************************************************************/
  1331. void
  1332. PositionInfoView::_InvalidateContents( uint32 which )
  1333. {
  1334. BRect r( Bounds() );
  1335. r.InsetBy( 2.0, 2.0 );
  1336. Invalidate( r );
  1337. }
  1338. /*****************************************************************************
  1339.  * PositionInfoView::_InvalidateContents
  1340.  *****************************************************************************/
  1341. void
  1342. PositionInfoView::_MakeString( BString& into, int32 index, int32 maxIndex ) const
  1343. {
  1344. into = "";
  1345. if ( index >= 0 && maxIndex >= 0 )
  1346. into << index;
  1347. else
  1348. into << "-";
  1349. into << "/";
  1350. if ( maxIndex >= 0 )
  1351. into << maxIndex;
  1352. else
  1353. into << "-";
  1354. }