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:
parent
9ea776d708
commit
b8673e4300
@ -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
|
||||
|
@ -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() );
|
||||
|
@ -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;
|
||||
|
||||
|
@ -10,6 +10,7 @@ App CDPlayer :
|
||||
FunctionObjectMessage.cpp
|
||||
Observer.cpp
|
||||
PlayList.cpp
|
||||
TrackMenu.cpp
|
||||
TwoStateDrawButton.cpp
|
||||
TypedList.cpp
|
||||
;
|
||||
|
286
src/apps/cdplayer/TrackMenu.cpp
Normal file
286
src/apps/cdplayer/TrackMenu.cpp
Normal 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(®);
|
||||
}
|
||||
}
|
||||
}
|
40
src/apps/cdplayer/TrackMenu.h
Normal file
40
src/apps/cdplayer/TrackMenu.h
Normal 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
|
Loading…
Reference in New Issue
Block a user