Added menu selector like in R5's player.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13648 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
DarkWyrm 2005-07-12 18:51:30 +00:00
parent 9ea776d708
commit b8673e4300
6 changed files with 359 additions and 4 deletions

View File

@ -454,7 +454,10 @@ CDEngine::StopSkipping()
void
CDEngine::SelectTrack(int32 trackNumber)
{
sCDDevice.Play(trackNumber);
sPlayList.SetCurrentTrack(trackNumber);
if(playState.GetState() == kPlaying)
sCDDevice.Play(trackNumber);
trackState.UpdateNow();
}
void

View File

@ -33,6 +33,7 @@ enum
{
M_STOP='mstp',
M_PLAY,
M_SELECT_TRACK,
M_NEXT_TRACK,
M_PREV_TRACK,
M_FFWD,
@ -74,7 +75,12 @@ void CDPlayer::BuildGUI(void)
fPlayColor.blue = 40;
fPlayColor.alpha = 255;
BRect r(5,5,230,25);
BRect r;
r.left = 5;
r.top = 5;
r.right = (Bounds().Width()/2) - 7;
r.bottom = 25;
// Assemble the CD Title box
fCDBox = new BBox(r,"TrackBox");
@ -89,6 +95,10 @@ void CDPlayer::BuildGUI(void)
fCDTitle->SetHighColor(200,200,200);
fCDTitle->SetFont(be_bold_font);
r.OffsetBy(0, r.Height() + 5);
fTrackMenu = new TrackMenu(r, "TrackMenu", new BMessage(M_SELECT_TRACK));
AddChild(fTrackMenu);
r.Set(fCDTitle->Frame().right + 15,5,Bounds().right - 5,25);
fTrackBox = new BBox(r,"TrackBox",B_FOLLOW_TOP);
AddChild(fTrackBox);
@ -105,7 +115,7 @@ void CDPlayer::BuildGUI(void)
r.OffsetBy(0, r.Height() + 5);
fTimeBox = new BBox(r,"TimeBox",B_FOLLOW_LEFT_RIGHT);
AddChild(fTimeBox);
view = new BView( fTimeBox->Bounds().InsetByCopy(2,2), "view",B_FOLLOW_ALL,B_WILL_DRAW);
view->SetViewColor(0,7,34);
fTimeBox->AddChild(view);
@ -259,6 +269,11 @@ CDPlayer::MessageReceived(BMessage *msg)
}
break;
}
case M_SELECT_TRACK:
{
engine->SelectTrack(fTrackMenu->Value()+1);
break;
}
case M_NEXT_TRACK:
{
engine->SkipOneForward();
@ -339,7 +354,11 @@ CDPlayer::NoticeChange(Notifier *notifier)
else
if(trs)
{
// TODO: Update track count indicator once there is one
if(fTrackMenu->CountItems() != engine->TrackStateWatcher()->GetNumTracks())
fTrackMenu->SetItemCount(engine->TrackStateWatcher()->GetNumTracks());
fTrackMenu->SetValue(engine->TrackStateWatcher()->GetTrack()-1);
UpdateCDInfo();
}
else
@ -566,6 +585,7 @@ CDPlayer::AttachedToWindow()
fSave->SetTarget(this);
fShuffle->SetTarget(this);
fRepeat->SetTarget(this);
fTrackMenu->SetTarget(this);
}
void
@ -580,6 +600,8 @@ CDPlayer::FrameResized(float new_width, float new_height)
float half = (new_width / 2);
fCDBox->ResizeTo( half - 7, fCDBox->Bounds().Height() );
fTrackMenu->ResizeTo( half - 7, fTrackMenu->Bounds().Height() );
fTrackMenu->Invalidate();
fTrackBox->MoveTo(half + 8, fTrackBox->Frame().top);
fTrackBox->ResizeTo( Bounds().right - (half + 8) - 5, fTrackBox->Bounds().Height() );

View File

@ -18,6 +18,7 @@
#include "Observer.h"
#include "CDEngine.h"
#include "TrackMenu.h"
class DrawButton;
class TwoStateDrawButton;
@ -75,6 +76,8 @@ private:
BBox *fCDBox,
*fTrackBox,
*fTimeBox;
TrackMenu *fTrackMenu;
CDState fCDState;

View File

@ -10,6 +10,7 @@ App CDPlayer :
FunctionObjectMessage.cpp
Observer.cpp
PlayList.cpp
TrackMenu.cpp
TwoStateDrawButton.cpp
TypedList.cpp
;

View File

@ -0,0 +1,286 @@
#include <Message.h>
#include <Region.h>
#include <Window.h>
#include <String.h>
#include <Font.h>
#include "TrackMenu.h"
#include <stdio.h>
TrackMenu::TrackMenu(const BRect &frame, const char *name, BMessage *msg,
const int32 &resize, const int32 &flags)
: BView(frame,name,resize,flags),
BInvoker(msg,NULL),
fCurrentItem(-1),
fCount(0),
fIsTracking(false)
{
SetViewColor(20,20,20);
fItemRect.Set(1,1,1 + StringWidth("00") + 3, Bounds().bottom - 1);
BFont font;
font.SetSize(11);
font.SetSpacing(B_STRING_SPACING);
SetFont(&font);
font_height fh;
GetFontHeight(&fh);
fFontHeight = fh.ascent + fh.descent + fh.leading;
}
TrackMenu::~TrackMenu(void)
{
}
void
TrackMenu::AttachedToWindow(void)
{
if (!Messenger().IsValid())
SetTarget(Window());
BView::AttachedToWindow();
}
void
TrackMenu::MessageReceived(BMessage *msg)
{
switch(msg->what)
{
default:
{
BView::MessageReceived(msg);
break;
}
}
}
void
TrackMenu::SetItemCount(const int32 &count)
{
if(count < 0)
{
fCount = 0;
fCurrentItem = -1;
Invalidate();
return;
}
fCount = count;
if(fCurrentItem > fCount - 1)
fCurrentItem = fCount - 1;
else
if(fCurrentItem < 0)
fCurrentItem = 0;
Invalidate();
}
void
TrackMenu::SetValue(const int32 &value)
{
if(value < 0 || value > fCount)
return;
if(value != Value())
{
fCurrentItem = value;
Invalidate();
}
}
int32
TrackMenu::ItemAt(const BPoint &pt)
{
// TODO: Optimize. This is simple, but costly in performance
BRect r(fItemRect);
for(int32 i=0; i<fCount; i++)
{
if(r.Contains(pt))
return i;
r.OffsetBy(r.Width()+1,0);
}
return -1;
}
void
TrackMenu::MouseDown(BPoint point)
{
BPoint pt(point);
int32 saveditem = fCurrentItem;
int32 item = ItemAt(pt);
if(item >= 0)
{
fCurrentItem = item;
Invalidate();
// Shamelessly stolen from BButton. :D
if (Window()->Flags() & B_ASYNCHRONOUS_CONTROLS)
{
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
fIsTracking = true;
} else
{
uint32 buttons;
do
{
Window()->UpdateIfNeeded();
snooze(40000);
GetMouse(&pt, &buttons, true);
int32 mouseitem = ItemAt(pt);
if(mouseitem > -1)
{
fCurrentItem = mouseitem;
Draw(Bounds());
}
} while (buttons != 0);
if(fCurrentItem != saveditem)
Invoke();
}
}
}
void
TrackMenu::MouseUp(BPoint pt)
{
if(!fIsTracking)
return;
int32 item = ItemAt(pt);
if(item >= 0)
Invoke();
fIsTracking = false;
}
void
TrackMenu::MouseMoved(BPoint pt, uint32 transit, const BMessage *msg)
{
if(!fIsTracking)
return;
int32 item = ItemAt(pt);
if(item >= 0)
{
fCurrentItem = item;
Invalidate();
}
}
void
TrackMenu::Draw(BRect update)
{
rgb_color dark = {20,20,20,255};
rgb_color light = {200,200,200,255};
BPoint pt1,pt2;
// Draw the frame
SetHighColor(dark);
pt1.Set(0,0);
pt2 = Bounds().RightTop();
StrokeLine(pt1,pt2);
pt2.Set(0,Bounds().bottom);
StrokeLine(pt1,pt2);
SetHighColor(255,255,255);
pt1 = Bounds().RightBottom();
pt2.Set(Bounds().right, 1);
StrokeLine(pt1,pt2);
pt2.Set(1,Bounds().bottom);
StrokeLine(pt1,pt2);
// Draw the items
BRect r(fItemRect);
for(int32 i=0; i<fCount; i++)
{
// Draw the item's frame
if(i == fCurrentItem)
SetHighColor(dark);
else
SetHighColor(light);
pt1.Set(r.left,r.top);
pt2.Set(r.right,r.top);
StrokeLine(pt1,pt2);
pt2.Set(r.left,r.bottom);
StrokeLine(pt1,pt2);
if(i == fCurrentItem)
{
SetHighColor(light);
pt1.Set(r.right,r.bottom);
pt2.Set(r.right, r.top + 1);
StrokeLine(pt1,pt2);
pt2.Set(r.left + 1,r.bottom);
StrokeLine(pt1,pt2);
SetHighColor(light);
FillRect(r.InsetByCopy(1,1));
SetHighColor(dark);
}
else
if(i == fCount - 1)
{
SetHighColor(light);
pt1.Set(r.right,r.bottom);
pt2.Set(r.right, r.top + 1);
StrokeLine(pt1,pt2);
}
// Draw the label, center justified
BString label;
label << (i + 1);
BPoint labelpt;
labelpt.x = r.left + (r.Width() - StringWidth(label.String()))/2 + 2;
labelpt.y = r.bottom - (r.Height() - fFontHeight + 4)/2;
if(i == fCurrentItem)
{
SetHighColor(dark);
SetLowColor(light);
}
else
{
SetHighColor(light);
SetLowColor(dark);
}
DrawString(label.String(),labelpt);
// Setup for next iteration
r.OffsetBy(r.Width()+1,0);
if(r.left > Bounds().right - 2)
{
ConstrainClippingRegion(NULL);
break;
}
if(r.right > Bounds().right - 2)
{
r.right = Bounds().right - 2;
BRegion reg(r);
ConstrainClippingRegion(&reg);
}
}
}

View File

@ -0,0 +1,40 @@
#ifndef TRACKMENU_H
#define TRACKMENU_H
#include <View.h>
#include <Invoker.h>
class TrackMenu : public BView, public BInvoker
{
public:
TrackMenu(const BRect &frame, const char *name, BMessage *msg,
const int32 &resize = B_FOLLOW_LEFT | B_FOLLOW_TOP,
const int32 &flags = B_WILL_DRAW);
~TrackMenu(void);
void AttachedToWindow(void);
void MessageReceived(BMessage *msg);
void Draw(BRect update);
void MouseDown(BPoint pt);
void MouseUp(BPoint pt);
void MouseMoved(BPoint pt, uint32 transit, const BMessage *msg);
int32 CountItems(void) const { return fCount; }
void SetItemCount(const int32 &count);
int32 Value(void) const { return fCurrentItem; }
void SetValue(const int32 &value);
private:
int32 ItemAt(const BPoint &pt);
int32 fCurrentItem;
int32 fCount;
BRect fItemRect;
bool fIsTracking;
float fFontHeight;
};
#endif