Retooled the GUI for the app - much easier on the eyes, fits in better with MediaPlayer (and looks better ;-) and flicker is no longer a problem.
Header has been added to files Style updates to source files, also. I may have missed a bit, but it sure is much closer than before git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20104 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
4ecd017140
commit
a68270fe2c
1399
src/apps/cdplayer/ButtonBitmaps.h
Normal file
1399
src/apps/cdplayer/ButtonBitmaps.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author:
|
||||
* DarkWyrm <bpmagic@columbus.rr.com>
|
||||
*/
|
||||
#include "CDAudioDevice.h"
|
||||
|
||||
#include <unistd.h>
|
||||
@ -12,14 +19,16 @@
|
||||
#include <errno.h>
|
||||
#include "scsi.h"
|
||||
|
||||
|
||||
cdaudio_data::cdaudio_data(const int32 &id, const int32 &count,
|
||||
const int32 &disclength)
|
||||
const int32 &disclength)
|
||||
: disc_id(id),
|
||||
track_count(count),
|
||||
length(disclength)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
cdaudio_data::cdaudio_data(const cdaudio_data &from)
|
||||
: disc_id(from.disc_id),
|
||||
track_count(from.track_count),
|
||||
@ -27,6 +36,7 @@ cdaudio_data::cdaudio_data(const cdaudio_data &from)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
cdaudio_data &
|
||||
cdaudio_data::operator=(const cdaudio_data &from)
|
||||
{
|
||||
@ -37,18 +47,21 @@ cdaudio_data::operator=(const cdaudio_data &from)
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
cdaudio_time::cdaudio_time(const int32 min,const int32 &sec)
|
||||
: minutes(min),
|
||||
seconds(sec)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
cdaudio_time::cdaudio_time(const cdaudio_time &from)
|
||||
: minutes(from.minutes),
|
||||
seconds(from.seconds)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
cdaudio_time &
|
||||
cdaudio_time::operator=(const cdaudio_time &from)
|
||||
{
|
||||
@ -57,6 +70,7 @@ cdaudio_time::operator=(const cdaudio_time &from)
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
cdaudio_time
|
||||
cdaudio_time::operator+(const cdaudio_time &from)
|
||||
{
|
||||
@ -65,22 +79,21 @@ cdaudio_time::operator+(const cdaudio_time &from)
|
||||
time.minutes = minutes + from.minutes;
|
||||
time.seconds = seconds + from.seconds;
|
||||
|
||||
while(time.seconds > 59)
|
||||
{
|
||||
while (time.seconds > 59) {
|
||||
time.minutes++;
|
||||
time.seconds-=60;
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
|
||||
cdaudio_time
|
||||
cdaudio_time::operator-(const cdaudio_time &from)
|
||||
{
|
||||
cdaudio_time time;
|
||||
|
||||
int32 tsec = ((minutes * 60) + seconds) - ((from.minutes * 60) + from.seconds);
|
||||
if(tsec<0)
|
||||
{
|
||||
if (tsec < 0) {
|
||||
time.minutes = 0;
|
||||
time.seconds = 0;
|
||||
return time;
|
||||
@ -92,16 +105,18 @@ cdaudio_time::operator-(const cdaudio_time &from)
|
||||
return time;
|
||||
}
|
||||
|
||||
|
||||
CDAudioDevice::CDAudioDevice(void)
|
||||
{
|
||||
FindDrives("/dev/disk");
|
||||
if(CountDrives()>0)
|
||||
if (CountDrives() > 0)
|
||||
SetDrive(0);
|
||||
}
|
||||
|
||||
|
||||
CDAudioDevice::~CDAudioDevice(void)
|
||||
{
|
||||
for(int32 i=0; i<fDriveList.CountItems(); i++)
|
||||
for (int32 i = 0; i < fDriveList.CountItems(); i++)
|
||||
delete (BString*) fDriveList.ItemAt(i);
|
||||
}
|
||||
|
||||
@ -110,8 +125,7 @@ CDAudioDevice::~CDAudioDevice(void)
|
||||
bool
|
||||
CDAudioDevice::Play(const int16 &track)
|
||||
{
|
||||
if(GetState() == kNoCD)
|
||||
{
|
||||
if (GetState() == kNoCD) {
|
||||
// no CD available, bail out
|
||||
ioctl(fFileHandle, B_LOAD_MEDIA, 0, 0);
|
||||
return false;
|
||||
@ -125,8 +139,7 @@ CDAudioDevice::Play(const int16 &track)
|
||||
playtrack.end_index = 1;
|
||||
|
||||
status_t result = ioctl(fFileHandle, B_SCSI_PLAY_TRACK, &playtrack);
|
||||
if (result != B_OK)
|
||||
{
|
||||
if (result != B_OK) {
|
||||
printf("Couldn't play track: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
@ -134,53 +147,53 @@ CDAudioDevice::Play(const int16 &track)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CDAudioDevice::Pause(void)
|
||||
{
|
||||
status_t result = ioctl(fFileHandle, B_SCSI_PAUSE_AUDIO);
|
||||
if (result != B_OK)
|
||||
{
|
||||
if (result != B_OK) {
|
||||
printf("Couldn't pause track: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CDAudioDevice::Resume(void)
|
||||
{
|
||||
CDState state = GetState();
|
||||
if(state == kNoCD)
|
||||
{
|
||||
if (state == kNoCD) {
|
||||
// no CD available, bail out
|
||||
ioctl(fFileHandle, B_LOAD_MEDIA, 0, 0);
|
||||
return false;
|
||||
} else {
|
||||
if (state == kStopped)
|
||||
return Play(0);
|
||||
}
|
||||
else
|
||||
if(state == kStopped)
|
||||
return Play(0);
|
||||
|
||||
status_t result = ioctl(fFileHandle, B_SCSI_RESUME_AUDIO);
|
||||
if (result != B_OK)
|
||||
{
|
||||
if (result != B_OK) {
|
||||
printf("Couldn't resume track: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CDAudioDevice::Stop(void)
|
||||
{
|
||||
status_t result = ioctl(fFileHandle, B_SCSI_STOP_AUDIO);
|
||||
if (result != B_OK)
|
||||
{
|
||||
if (result != B_OK) {
|
||||
printf("Couldn't stop CD: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// open or close the CD tray
|
||||
bool
|
||||
CDAudioDevice::Eject(void)
|
||||
@ -195,14 +208,14 @@ CDAudioDevice::Eject(void)
|
||||
media_status == B_DEV_DOOR_OPEN ?
|
||||
B_LOAD_MEDIA : B_EJECT_DEVICE);
|
||||
|
||||
if (result != B_OK)
|
||||
{
|
||||
if (result != B_OK) {
|
||||
printf("Couldn't eject CD: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CDAudioDevice::StartFastFwd(void)
|
||||
{
|
||||
@ -210,14 +223,14 @@ CDAudioDevice::StartFastFwd(void)
|
||||
scan.direction = 1;
|
||||
scan.speed = 1;
|
||||
status_t result = ioctl(fFileHandle, B_SCSI_SCAN, &scan);
|
||||
if (result != B_OK)
|
||||
{
|
||||
if (result != B_OK) {
|
||||
printf("Couldn't fast forward: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CDAudioDevice::StopFastFwd(void)
|
||||
{
|
||||
@ -225,14 +238,14 @@ CDAudioDevice::StopFastFwd(void)
|
||||
scan.direction = 0;
|
||||
scan.speed = 1;
|
||||
status_t result = ioctl(fFileHandle, B_SCSI_SCAN, &scan);
|
||||
if (result != B_OK)
|
||||
{
|
||||
if (result != B_OK) {
|
||||
printf("Couldn't stop fast forwarding: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CDAudioDevice::StartRewind(void)
|
||||
{
|
||||
@ -240,14 +253,14 @@ CDAudioDevice::StartRewind(void)
|
||||
scan.direction = -1;
|
||||
scan.speed = 1;
|
||||
status_t result = ioctl(fFileHandle, B_SCSI_SCAN, &scan);
|
||||
if (result != B_OK)
|
||||
{
|
||||
if (result != B_OK) {
|
||||
printf("Couldn't rewind: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CDAudioDevice::StopRewind(void)
|
||||
{
|
||||
@ -255,14 +268,14 @@ CDAudioDevice::StopRewind(void)
|
||||
scan.direction = 0;
|
||||
scan.speed = 1;
|
||||
status_t result = ioctl(fFileHandle, B_SCSI_SCAN, &scan);
|
||||
if (result != B_OK)
|
||||
{
|
||||
if (result != B_OK) {
|
||||
printf("Couldn't stop rewinding: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CDAudioDevice::SetVolume(uint8 value)
|
||||
{
|
||||
@ -273,14 +286,14 @@ CDAudioDevice::SetVolume(uint8 value)
|
||||
vol.port0_volume=value;
|
||||
|
||||
status_t result = ioctl(fFileHandle,B_SCSI_SET_VOLUME,&vol);
|
||||
if (result != B_OK)
|
||||
{
|
||||
if (result != B_OK) {
|
||||
printf("Couldn't set volume: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
CDAudioDevice::GetVolume(void)
|
||||
{
|
||||
@ -289,6 +302,7 @@ CDAudioDevice::GetVolume(void)
|
||||
return vol.port0_volume;
|
||||
}
|
||||
|
||||
|
||||
// check the current CD play state
|
||||
CDState
|
||||
CDAudioDevice::GetState(void)
|
||||
@ -303,17 +317,16 @@ CDAudioDevice::GetState(void)
|
||||
status_t result = ioctl(fFileHandle, B_SCSI_GET_POSITION, &pos);
|
||||
if (result != B_OK)
|
||||
return kNoCD;
|
||||
else
|
||||
if ((!pos.position[1]) || (pos.position[1] >= 0x13) ||
|
||||
((pos.position[1] == 0x12) && (!pos.position[6])))
|
||||
else if ((!pos.position[1]) || (pos.position[1] >= 0x13) ||
|
||||
((pos.position[1] == 0x12) && (!pos.position[6])))
|
||||
return kStopped;
|
||||
else
|
||||
if (pos.position[1] == 0x11)
|
||||
else if (pos.position[1] == 0x11)
|
||||
return kPlaying;
|
||||
else
|
||||
return kPaused;
|
||||
}
|
||||
|
||||
|
||||
int16
|
||||
CDAudioDevice::CountTracks(void)
|
||||
{
|
||||
@ -326,6 +339,7 @@ CDAudioDevice::CountTracks(void)
|
||||
return toc.toc_data[3];
|
||||
}
|
||||
|
||||
|
||||
// Get the 0-based index of the current track
|
||||
int16
|
||||
CDAudioDevice::GetTrack(void)
|
||||
@ -349,23 +363,24 @@ CDAudioDevice::GetTrack(void)
|
||||
return pos.position[6];
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
CDAudioDevice::CountDrives(void)
|
||||
{
|
||||
return fDriveList.CountItems();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CDAudioDevice::SetDrive(const int32 &drive)
|
||||
{
|
||||
BString *path = (BString*) fDriveList.ItemAt(drive);
|
||||
|
||||
if(!path)
|
||||
if (!path)
|
||||
return false;
|
||||
|
||||
int device = open(path->String(), O_RDONLY);
|
||||
if(device >= 0)
|
||||
{
|
||||
if (device >= 0) {
|
||||
fFileHandle = device;
|
||||
fDrivePath = path;
|
||||
fDriveIndex = drive;
|
||||
@ -375,45 +390,46 @@ CDAudioDevice::SetDrive(const int32 &drive)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
CDAudioDevice::GetDrivePath(void) const
|
||||
{
|
||||
if(!fDrivePath)
|
||||
if (!fDrivePath)
|
||||
return NULL;
|
||||
|
||||
return fDrivePath->String();
|
||||
}
|
||||
|
||||
int32 CDAudioDevice::FindDrives(const char *path)
|
||||
|
||||
int32
|
||||
CDAudioDevice::FindDrives(const char *path)
|
||||
{
|
||||
BDirectory dir(path);
|
||||
|
||||
if(dir.InitCheck() != B_OK)
|
||||
if (dir.InitCheck() != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
dir.Rewind();
|
||||
|
||||
BEntry entry;
|
||||
while(dir.GetNextEntry(&entry) >= 0)
|
||||
{
|
||||
while (dir.GetNextEntry(&entry) >= 0) {
|
||||
BPath path;
|
||||
const char *name;
|
||||
entry_ref e;
|
||||
|
||||
if(entry.GetPath(&path) != B_OK)
|
||||
if (entry.GetPath(&path) != B_OK)
|
||||
continue;
|
||||
|
||||
name = path.Path();
|
||||
if(entry.GetRef(&e) != B_OK)
|
||||
if (entry.GetRef(&e) != B_OK)
|
||||
continue;
|
||||
|
||||
if(entry.IsDirectory())
|
||||
{
|
||||
if (entry.IsDirectory()) {
|
||||
// ignore floppy -- it is not silent
|
||||
if(strcmp(e.name, "floppy") == 0)
|
||||
if (strcmp(e.name, "floppy") == 0)
|
||||
continue;
|
||||
else
|
||||
if(strcmp(e.name, "ata") == 0)
|
||||
if (strcmp(e.name, "ata") == 0)
|
||||
continue;
|
||||
|
||||
// Note that if we check for the count here, we could
|
||||
@ -421,23 +437,20 @@ int32 CDAudioDevice::FindDrives(const char *path)
|
||||
// that are available, so we keep searching even if we've found one
|
||||
FindDrives(name);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int devfd;
|
||||
device_geometry g;
|
||||
|
||||
// ignore partitions
|
||||
if(strcmp(e.name, "raw") != 0)
|
||||
if (strcmp(e.name, "raw") != 0)
|
||||
continue;
|
||||
|
||||
devfd = open(name, O_RDONLY);
|
||||
if(devfd < 0)
|
||||
if (devfd < 0)
|
||||
continue;
|
||||
|
||||
if(ioctl(devfd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0)
|
||||
{
|
||||
if(g.device_type == B_CD)
|
||||
if (ioctl(devfd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0) {
|
||||
if (g.device_type == B_CD)
|
||||
fDriveList.AddItem(new BString(name));
|
||||
}
|
||||
close(devfd);
|
||||
@ -446,6 +459,7 @@ int32 CDAudioDevice::FindDrives(const char *path)
|
||||
return fDriveList.CountItems();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CDAudioDevice::GetTime(cdaudio_time &track, cdaudio_time &disc)
|
||||
{
|
||||
@ -463,8 +477,7 @@ CDAudioDevice::GetTime(cdaudio_time &track, cdaudio_time &disc)
|
||||
return false;
|
||||
|
||||
if ((!pos.position[1]) || (pos.position[1] >= 0x13) ||
|
||||
((pos.position[1] == 0x12) && (!pos.position[6])))
|
||||
{
|
||||
((pos.position[1] == 0x12) && (!pos.position[6]))) {
|
||||
// This indicates that we have a CD, but we are stopped.
|
||||
return false;
|
||||
}
|
||||
@ -476,6 +489,7 @@ CDAudioDevice::GetTime(cdaudio_time &track, cdaudio_time &disc)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CDAudioDevice::GetTimeForTrack(const int16 &index, cdaudio_time &track)
|
||||
{
|
||||
@ -487,7 +501,7 @@ CDAudioDevice::GetTimeForTrack(const int16 &index, cdaudio_time &track)
|
||||
|
||||
int16 trackcount = toc.toc_data[3] - toc.toc_data[2] + 1;
|
||||
|
||||
if(index < 1 || index > trackcount)
|
||||
if (index < 1 || index > trackcount)
|
||||
return false;
|
||||
|
||||
TrackDescriptor *desc = (TrackDescriptor*)&(toc.toc_data[4]);
|
||||
@ -501,6 +515,7 @@ CDAudioDevice::GetTimeForTrack(const int16 &index, cdaudio_time &track)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CDAudioDevice::GetTimeForDisc(cdaudio_time &disc)
|
||||
{
|
||||
@ -519,13 +534,14 @@ CDAudioDevice::GetTimeForDisc(cdaudio_time &disc)
|
||||
return true;
|
||||
}
|
||||
|
||||
struct ConvertedToc
|
||||
{
|
||||
|
||||
struct ConvertedToc {
|
||||
int32 min;
|
||||
int32 sec;
|
||||
int32 frame;
|
||||
};
|
||||
|
||||
|
||||
static int32
|
||||
cddb_sum(int n)
|
||||
{
|
||||
@ -538,6 +554,7 @@ cddb_sum(int n)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
CDAudioDevice::GetDiscID(void)
|
||||
{
|
||||
@ -555,8 +572,7 @@ CDAudioDevice::GetDiscID(void)
|
||||
ConvertedToc tocData[100];
|
||||
|
||||
// figure out the disc ID
|
||||
for (int index = 0; index < 100; index++)
|
||||
{
|
||||
for (int index = 0; index < 100; index++) {
|
||||
tocData[index].min = toc.toc_data[9 + 8*index];
|
||||
tocData[index].sec = toc.toc_data[10 + 8*index];
|
||||
tocData[index].frame = toc.toc_data[11 + 8*index];
|
||||
@ -565,8 +581,7 @@ CDAudioDevice::GetDiscID(void)
|
||||
|
||||
int32 sum1 = 0;
|
||||
int32 sum2 = 0;
|
||||
for (int index = 0; index < numTracks; index++)
|
||||
{
|
||||
for (int index = 0; index < numTracks; index++) {
|
||||
sum1 += cddb_sum((tocData[index].min * 60) + tocData[index].sec);
|
||||
|
||||
// the following is probably running over too far
|
||||
@ -578,7 +593,9 @@ CDAudioDevice::GetDiscID(void)
|
||||
return id;
|
||||
}
|
||||
|
||||
bool CDAudioDevice::IsDataTrack(const int16 &track)
|
||||
|
||||
bool
|
||||
CDAudioDevice::IsDataTrack(const int16 &track)
|
||||
{
|
||||
scsi_toc toc;
|
||||
status_t result = ioctl(fFileHandle, B_SCSI_GET_TOC, &toc);
|
||||
@ -587,12 +604,12 @@ bool CDAudioDevice::IsDataTrack(const int16 &track)
|
||||
return false;
|
||||
|
||||
TrackDescriptor *trackindex = (TrackDescriptor*) &(toc.toc_data[4]);
|
||||
if(track>toc.toc_data[3])
|
||||
if (track > toc.toc_data[3])
|
||||
return false;
|
||||
|
||||
// At least under R5, the SCSI CD drive has each legitimate audio track
|
||||
// have a value of 0x10. Data tracks have a value of 0x14;
|
||||
if(trackindex[track].adr_control & 4)
|
||||
if (trackindex[track].adr_control & 4)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -1,3 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author:
|
||||
* DarkWyrm <bpmagic@columbus.rr.com>
|
||||
*/
|
||||
#ifndef CDAUDIODEVICE_H
|
||||
#define CDAUDIODEVICE_H
|
||||
|
||||
@ -9,8 +16,7 @@
|
||||
// descriptors, which are each 8 bytes. We don't really need the first 5 bytes
|
||||
// of the track descriptor, so we'll just ignore them. All we really want is the
|
||||
// length of each track, which happen to be the last 3 bytes of the descriptor.
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint8 reserved;
|
||||
uint8 adr_control; // bytes 0-3 are control, 4-7 are ADR
|
||||
uint8 track_number;
|
||||
@ -20,7 +26,7 @@ typedef struct
|
||||
uint8 min;
|
||||
uint8 sec;
|
||||
uint8 frame;
|
||||
}TrackDescriptor;
|
||||
} TrackDescriptor;
|
||||
|
||||
enum CDState {
|
||||
kNoCD=0,
|
||||
@ -35,27 +41,27 @@ enum CDState {
|
||||
class cdaudio_time
|
||||
{
|
||||
public:
|
||||
cdaudio_time(const int32 min=-1,const int32 &sec=-1);
|
||||
cdaudio_time(const cdaudio_time &from);
|
||||
cdaudio_time &operator=(const cdaudio_time &from);
|
||||
cdaudio_time operator+(const cdaudio_time &from);
|
||||
cdaudio_time operator-(const cdaudio_time &from);
|
||||
cdaudio_time(const int32 min=-1,const int32 &sec=-1);
|
||||
cdaudio_time(const cdaudio_time &from);
|
||||
cdaudio_time &operator=(const cdaudio_time &from);
|
||||
cdaudio_time operator+(const cdaudio_time &from);
|
||||
cdaudio_time operator-(const cdaudio_time &from);
|
||||
|
||||
int32 minutes;
|
||||
int32 seconds;
|
||||
int32 minutes;
|
||||
int32 seconds;
|
||||
};
|
||||
|
||||
class cdaudio_data
|
||||
{
|
||||
public:
|
||||
cdaudio_data(const int32 &id=-1, const int32 &count=-1,
|
||||
const int32 &disclength=-1);
|
||||
cdaudio_data(const cdaudio_data &from);
|
||||
cdaudio_data &operator=(const cdaudio_data &from);
|
||||
cdaudio_data(const int32 &id = -1, const int32 &count = -1,
|
||||
const int32 &disclength = -1);
|
||||
cdaudio_data(const cdaudio_data &from);
|
||||
cdaudio_data &operator=(const cdaudio_data &from);
|
||||
|
||||
int32 disc_id;
|
||||
int32 track_count;
|
||||
int32 length;
|
||||
int32 disc_id;
|
||||
int32 track_count;
|
||||
int32 length;
|
||||
|
||||
BString frame_offsets;
|
||||
};
|
||||
|
@ -42,8 +42,7 @@ const int kTerminatingSignal = SIGINT; // SIGCONT;
|
||||
// descriptors, which are each 8 bytes. We don't really need the first 5 bytes
|
||||
// of the track descriptor, so we'll just ignore them. All we really want is the
|
||||
// length of each track, which happen to be the last 3 bytes of the descriptor.
|
||||
typedef struct TrackRecord
|
||||
{
|
||||
typedef struct TrackRecord {
|
||||
int8 unused[5];
|
||||
|
||||
int8 min;
|
||||
@ -58,6 +57,7 @@ CDDBData::CDDBData(int32 discid)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CDDBData::CDDBData(const CDDBData &from)
|
||||
: fDiscID(from.fDiscID),
|
||||
fArtist(from.fArtist),
|
||||
@ -68,41 +68,41 @@ CDDBData::CDDBData(const CDDBData &from)
|
||||
{
|
||||
STRACE(("CDDBData::Copy Constructor\n"));
|
||||
|
||||
for(int32 i=0; i<from.fTrackList.CountItems(); i++)
|
||||
{
|
||||
for (int32 i = 0; i < from.fTrackList.CountItems(); i++) {
|
||||
BString *string = (BString*)from.fTrackList.ItemAt(i);
|
||||
cdaudio_time *time = (cdaudio_time*)from.fTimeList.ItemAt(i);
|
||||
|
||||
if(!string || !time)
|
||||
if (!string || !time)
|
||||
continue;
|
||||
|
||||
AddTrack(string->String(),*time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CDDBData::~CDDBData(void)
|
||||
{
|
||||
STRACE(("CDDBData::~CDDBData\n"));
|
||||
EmptyLists();
|
||||
}
|
||||
|
||||
|
||||
CDDBData &
|
||||
CDDBData::operator=(const CDDBData &from)
|
||||
{
|
||||
EmptyLists();
|
||||
fDiscID=from.fDiscID;
|
||||
fArtist=from.fArtist;
|
||||
fAlbum=from.fAlbum;
|
||||
fGenre=from.fGenre;
|
||||
fDiscTime=from.fDiscTime;
|
||||
fYear=fYear;
|
||||
fDiscID = from.fDiscID;
|
||||
fArtist = from.fArtist;
|
||||
fAlbum = from.fAlbum;
|
||||
fGenre = from.fGenre;
|
||||
fDiscTime = from.fDiscTime;
|
||||
fYear = fYear;
|
||||
|
||||
for(int32 i=0; i<from.fTrackList.CountItems(); i++)
|
||||
{
|
||||
for (int32 i = 0; i < from.fTrackList.CountItems(); i++) {
|
||||
BString *string = (BString*)from.fTrackList.ItemAt(i);
|
||||
cdaudio_time *time = (cdaudio_time*)from.fTimeList.ItemAt(i);
|
||||
|
||||
if(!string || !time)
|
||||
if (!string || !time)
|
||||
continue;
|
||||
|
||||
AddTrack(string->String(),*time);
|
||||
@ -110,41 +110,42 @@ CDDBData::operator=(const CDDBData &from)
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CDDBData::MakeEmpty(void)
|
||||
{
|
||||
STRACE(("CDDBData::MakeEmpty\n"));
|
||||
|
||||
EmptyLists();
|
||||
fDiscID=-1;
|
||||
fArtist="";
|
||||
fAlbum="";
|
||||
fGenre="";
|
||||
fDiscTime.minutes=-1;
|
||||
fDiscTime.seconds=-1;
|
||||
fYear=-1;
|
||||
fDiscID = -1;
|
||||
fArtist = "";
|
||||
fAlbum = "";
|
||||
fGenre = "";
|
||||
fDiscTime.minutes = -1;
|
||||
fDiscTime.seconds = -1;
|
||||
fYear = -1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CDDBData::EmptyLists(void)
|
||||
{
|
||||
STRACE(("CDDBData::EmptyLists\n"));
|
||||
|
||||
for(int32 i=0; i<fTrackList.CountItems(); i++)
|
||||
{
|
||||
for (int32 i = 0; i < fTrackList.CountItems(); i++) {
|
||||
BString *string = (BString*)fTrackList.ItemAt(i);
|
||||
delete string;
|
||||
}
|
||||
fTrackList.MakeEmpty();
|
||||
|
||||
for(int32 j=0; j<fTimeList.CountItems(); j++)
|
||||
{
|
||||
for (int32 j = 0; j < fTimeList.CountItems(); j++) {
|
||||
cdaudio_time *time = (cdaudio_time*)fTimeList.ItemAt(j);
|
||||
delete time;
|
||||
}
|
||||
fTimeList.MakeEmpty();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
CDDBData::Load(const entry_ref &ref)
|
||||
{
|
||||
@ -152,42 +153,37 @@ CDDBData::Load(const entry_ref &ref)
|
||||
|
||||
BFile file(&ref, B_READ_ONLY);
|
||||
|
||||
if(file.InitCheck()!=B_OK)
|
||||
{
|
||||
if (file.InitCheck() != B_OK) {
|
||||
STRACE(("CDDBData::Load failed\n"));
|
||||
return file.InitCheck();
|
||||
}
|
||||
|
||||
attr_info info;
|
||||
|
||||
if(file.GetAttrInfo("Audio:Genre",&info)==B_OK && info.size > 0)
|
||||
{
|
||||
char genredata[info.size+2];
|
||||
if (file.GetAttrInfo("Audio:Genre",&info) == B_OK && info.size > 0) {
|
||||
char genredata[info.size + 2];
|
||||
|
||||
if(file.ReadAttr("Audio:Genre",B_STRING_TYPE,0,genredata,info.size)>0)
|
||||
if (file.ReadAttr("Audio:Genre",B_STRING_TYPE,0,genredata,info.size) > 0)
|
||||
fGenre = genredata;
|
||||
}
|
||||
|
||||
if(file.GetAttrInfo("Audio:Year",&info)==B_OK && info.size > 0)
|
||||
{
|
||||
if (file.GetAttrInfo("Audio:Year",&info)==B_OK && info.size > 0) {
|
||||
int32 data;
|
||||
|
||||
if(file.ReadAttr("Audio:Year",B_INT32_TYPE,0,&data,info.size)>0)
|
||||
if (file.ReadAttr("Audio:Year",B_INT32_TYPE,0,&data,info.size) > 0)
|
||||
fYear = data;
|
||||
}
|
||||
|
||||
// TODO: Attempt reading the file before attempting to read the attributes
|
||||
if(file.GetAttrInfo("CD:tracks",&info)==B_OK && info.size > 0)
|
||||
{
|
||||
char trackdata[info.size+2];
|
||||
if (file.GetAttrInfo("CD:tracks",&info)==B_OK && info.size > 0) {
|
||||
char trackdata[info.size + 2];
|
||||
|
||||
if(file.ReadAttr("CD:tracks",B_STRING_TYPE,0,trackdata,info.size)>0)
|
||||
{
|
||||
if (file.ReadAttr("CD:tracks",B_STRING_TYPE,0,trackdata,info.size) > 0) {
|
||||
trackdata[info.size] = 0;
|
||||
BString tmp = GetLineFromString(trackdata);
|
||||
char *index;
|
||||
|
||||
if(fTrackList.CountItems()>0)
|
||||
if (fTrackList.CountItems() > 0)
|
||||
EmptyLists();
|
||||
|
||||
fArtist = tmp;
|
||||
@ -198,12 +194,10 @@ CDDBData::Load(const entry_ref &ref)
|
||||
STRACE(("CDDBData::Load: Album set to %s\n",fAlbum.String()));
|
||||
|
||||
index = strchr(trackdata,'\n') + 1;
|
||||
while(*index)
|
||||
{
|
||||
while (*index) {
|
||||
tmp = GetLineFromString(index);
|
||||
|
||||
if(tmp.CountChars()>0)
|
||||
{
|
||||
if (tmp.CountChars() > 0) {
|
||||
BString *newtrack = new BString(tmp);
|
||||
cdaudio_time *time = new cdaudio_time;
|
||||
time->minutes = 0;
|
||||
@ -233,7 +227,7 @@ CDDBData::Load(void)
|
||||
// This uses the default R5 path
|
||||
|
||||
BPath path;
|
||||
if(find_directory(B_USER_DIRECTORY, &path, true)!=B_OK)
|
||||
if (find_directory(B_USER_DIRECTORY, &path, true) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
path.Append("cd");
|
||||
@ -242,11 +236,11 @@ CDDBData::Load(void)
|
||||
BString filename(path.Path());
|
||||
filename << "/" << Artist() << " - " << Album();
|
||||
|
||||
if(filename.Compare("Artist")==0)
|
||||
if (filename.Compare("Artist")==0)
|
||||
filename << "." << DiscID();
|
||||
|
||||
BEntry entry(filename.String());
|
||||
if(entry.InitCheck()!=B_OK)
|
||||
if (entry.InitCheck() != B_OK)
|
||||
return entry.InitCheck();
|
||||
|
||||
entry_ref ref;
|
||||
@ -261,7 +255,7 @@ CDDBData::Save(void)
|
||||
// This uses the default R5 path
|
||||
|
||||
BPath path;
|
||||
if(find_directory(B_USER_DIRECTORY, &path, true)!=B_OK)
|
||||
if (find_directory(B_USER_DIRECTORY, &path, true) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
path.Append("cd");
|
||||
@ -270,7 +264,7 @@ CDDBData::Save(void)
|
||||
BString filename(path.Path());
|
||||
filename << "/" << Artist() << " - " << Album();
|
||||
|
||||
if(filename.Compare("Artist")==0)
|
||||
if (filename.Compare("Artist")==0)
|
||||
filename << "." << DiscID();
|
||||
|
||||
return Save(filename.String());
|
||||
@ -279,15 +273,13 @@ CDDBData::Save(void)
|
||||
status_t
|
||||
CDDBData::Save(const char *filename)
|
||||
{
|
||||
if(!filename)
|
||||
{
|
||||
if (!filename) {
|
||||
STRACE(("CDDBData::Save failed - NULL filename\n"));
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
BFile file(filename, B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
|
||||
if(file.InitCheck() != B_OK)
|
||||
{
|
||||
if (file.InitCheck() != B_OK) {
|
||||
STRACE(("CDDBData::Save failed - couldn't create file %s\n",filename));
|
||||
return file.InitCheck();
|
||||
}
|
||||
@ -305,12 +297,11 @@ CDDBData::Save(const char *filename)
|
||||
BString tracksattr(fArtist);
|
||||
tracksattr << " - " << fAlbum << "\n";
|
||||
|
||||
for(int32 i=0; i<fTrackList.CountItems(); i++)
|
||||
{
|
||||
for (int32 i = 0; i < fTrackList.CountItems(); i++) {
|
||||
BString *trackstr = (BString *)fTrackList.ItemAt(i);
|
||||
cdaudio_time *time= (cdaudio_time*)fTimeList.ItemAt(i);
|
||||
|
||||
if(!trackstr || !time)
|
||||
if (!trackstr || !time)
|
||||
continue;
|
||||
|
||||
entry = *trackstr;
|
||||
@ -326,12 +317,12 @@ CDDBData::Save(const char *filename)
|
||||
|
||||
file.WriteAttr("CD:key", B_INT32_TYPE, 0, &fDiscID, sizeof(int32));
|
||||
STRACE(("CDDBData::Save: Wrote CD identifier: %ld(%lx)\n",fDiscID,fDiscID));
|
||||
file.WriteAttr("CD:tracks", B_STRING_TYPE, 0, tracksattr.String(), tracksattr.Length()+1);
|
||||
file.WriteAttr("CD:tracks", B_STRING_TYPE, 0, tracksattr.String(), tracksattr.Length() + 1);
|
||||
|
||||
if(fGenre.CountChars()>0)
|
||||
file.WriteAttr("Audio:Genre",B_STRING_TYPE,0, fGenre.String(), fGenre.Length()+1);
|
||||
if (fGenre.CountChars() > 0)
|
||||
file.WriteAttr("Audio:Genre",B_STRING_TYPE,0, fGenre.String(), fGenre.Length() + 1);
|
||||
|
||||
if(fYear>0)
|
||||
if (fYear > 0)
|
||||
file.WriteAttr("Audio:Year",B_INT32_TYPE,0,&fYear,sizeof(int32));
|
||||
|
||||
return B_OK;
|
||||
@ -346,15 +337,13 @@ CDDBData::CountTracks(void) const
|
||||
bool
|
||||
CDDBData::RenameTrack(const int32 &index, const char *newname)
|
||||
{
|
||||
if(!newname)
|
||||
{
|
||||
if (!newname) {
|
||||
STRACE(("CDDBData::RenameTrack failed - NULL newname\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
BString *name = (BString*)fTrackList.ItemAt(index);
|
||||
if(name)
|
||||
{
|
||||
if (name) {
|
||||
STRACE(("CDDBData::RenameTrack(%ld,%s)\n",index,newname));
|
||||
name->SetTo(newname);
|
||||
return true;
|
||||
@ -368,8 +357,7 @@ void
|
||||
CDDBData::AddTrack(const char *track, const cdaudio_time &time,
|
||||
const int16 &index)
|
||||
{
|
||||
if(!track)
|
||||
{
|
||||
if (!track) {
|
||||
STRACE(("CDDBData::AddTrack failed - NULL name\n"));
|
||||
return;
|
||||
}
|
||||
@ -395,7 +383,7 @@ const char *
|
||||
CDDBData::TrackAt(const int16 &index) const
|
||||
{
|
||||
BString *track = (BString*)fTrackList.ItemAt(index);
|
||||
if(!track)
|
||||
if (!track)
|
||||
return NULL;
|
||||
|
||||
return track->String();
|
||||
@ -432,29 +420,26 @@ CDDBQuery::SetToSite(const char *server, int32 port)
|
||||
void
|
||||
CDDBQuery::SetToCD(const char *path)
|
||||
{
|
||||
if(!path)
|
||||
if (!path)
|
||||
return;
|
||||
|
||||
// Get the SCSI table of contents from the device passed to us
|
||||
int device = open(path, O_RDONLY);
|
||||
if(device < 0)
|
||||
if (device < 0)
|
||||
return;
|
||||
|
||||
status_t result = ioctl(device, B_SCSI_GET_TOC, &fSCSIData);
|
||||
|
||||
close(device);
|
||||
|
||||
if(result != B_OK)
|
||||
if (result != B_OK)
|
||||
return;
|
||||
|
||||
// Calculate the disc's CDDB ID
|
||||
if (fState == kInitial)
|
||||
{
|
||||
if (fState == kInitial) {
|
||||
fCDData.SetDiscID(GetDiscID(&fSCSIData));
|
||||
fCDData.SetDiscTime(GetDiscTime(&fSCSIData));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int32 discID = GetDiscID(&fSCSIData);
|
||||
|
||||
if (fCDData.DiscID() == discID)
|
||||
@ -471,8 +456,7 @@ CDDBQuery::SetToCD(const char *path)
|
||||
|
||||
if (fThread >= 0)
|
||||
resume_thread(fThread);
|
||||
else
|
||||
{
|
||||
else {
|
||||
fState = kError;
|
||||
result = fThread;
|
||||
}
|
||||
@ -500,7 +484,7 @@ status_t
|
||||
CDDBQuery::GetSites(bool (*eachFunc)(const char *site, int port, const char *latitude,
|
||||
const char *longitude, const char *description, void *state), void *passThru)
|
||||
{
|
||||
if(!IsConnected())
|
||||
if (!IsConnected())
|
||||
Connect();
|
||||
|
||||
BString tmp;
|
||||
@ -508,19 +492,17 @@ CDDBQuery::GetSites(bool (*eachFunc)(const char *site, int port, const char *lat
|
||||
tmp = "sites\n";
|
||||
STRACE((">%s", tmp.String()));
|
||||
|
||||
if(fSocket.Send(tmp.String(), tmp.Length())==-1)
|
||||
if (fSocket.Send(tmp.String(), tmp.Length())==-1)
|
||||
return B_ERROR;
|
||||
|
||||
ReadLine(tmp);
|
||||
|
||||
if(tmp.FindFirst("210") == -1)
|
||||
{
|
||||
if (tmp.FindFirst("210") == -1) {
|
||||
Disconnect();
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (;;) {
|
||||
BString site;
|
||||
int32 sitePort;
|
||||
BString latitude;
|
||||
@ -551,17 +533,16 @@ CDDBQuery::GetSites(bool (*eachFunc)(const char *site, int port, const char *lat
|
||||
bool
|
||||
CDDBQuery::GetData(CDDBData *data, bigtime_t timeout)
|
||||
{
|
||||
if(!data)
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
bigtime_t deadline = system_time() + timeout;
|
||||
while (fState == kReading)
|
||||
{
|
||||
while (fState == kReading) {
|
||||
snooze(50000);
|
||||
if (system_time() > deadline)
|
||||
break;
|
||||
}
|
||||
if(fState != kDone)
|
||||
if (fState != kDone)
|
||||
return false;
|
||||
|
||||
*data = fCDData;
|
||||
@ -591,8 +572,7 @@ CDDBQuery::GetDiscID(const scsi_toc *toc)
|
||||
|
||||
int32 sum1 = 0;
|
||||
int32 sum2 = 0;
|
||||
for (int index = 0; index < numTracks; index++)
|
||||
{
|
||||
for (int index = 0; index < numTracks; index++) {
|
||||
sum1 += cddb_sum((tocData[index].min * 60) + tocData[index].sec);
|
||||
|
||||
// the following is probably running over too far
|
||||
@ -612,8 +592,7 @@ CDDBQuery::OffsetsToString(const scsi_toc *toc)
|
||||
int32 numTracks = toc->toc_data[3] - toc->toc_data[2] + 1;
|
||||
|
||||
BString string;
|
||||
for (int index = 0; index < numTracks; index++)
|
||||
{
|
||||
for (int index = 0; index < numTracks; index++) {
|
||||
string << tocData[index].min * 4500 + tocData[index].sec * 75
|
||||
+ tocData[index].frame << ' ';
|
||||
}
|
||||
@ -647,8 +626,7 @@ CDDBQuery::GetTrackTimes(const scsi_toc *toc, vector<cdaudio_time> ×)
|
||||
TrackRecord *tocData = (TrackRecord*)&(toc->toc_data[4]);
|
||||
int16 trackCount = toc->toc_data[3] - toc->toc_data[2] + 1;
|
||||
|
||||
for (int index = 0; index < trackCount+1; index++)
|
||||
{
|
||||
for (int index = 0; index < trackCount + 1; index++) {
|
||||
cdaudio_time cdtime;
|
||||
cdtime.minutes = tocData[index].min;
|
||||
cdtime.seconds = tocData[index].sec;
|
||||
@ -676,8 +654,7 @@ CDDBQuery::ReadFromServer(BString &data)
|
||||
|
||||
STRACE((">%s", query.String()));
|
||||
|
||||
if(fSocket.Send(query.String(), query.Length())==-1)
|
||||
{
|
||||
if (fSocket.Send(query.String(), query.Length())==-1) {
|
||||
Disconnect();
|
||||
return B_ERROR;
|
||||
}
|
||||
@ -689,10 +666,8 @@ CDDBQuery::ReadFromServer(BString &data)
|
||||
BString category;
|
||||
BString queryDiscID(idString);
|
||||
|
||||
if(tmp.FindFirst("200") != 0)
|
||||
{
|
||||
if(tmp.FindFirst("211") == 0)
|
||||
{
|
||||
if (tmp.FindFirst("200") != 0) {
|
||||
if (tmp.FindFirst("211") == 0) {
|
||||
// A 211 means that the query was not exact. To make sure that we don't
|
||||
// have a problem with this in the future, we will choose the first entry that
|
||||
// the server returns. This may or may not be wise, but in my experience, the first
|
||||
@ -712,24 +687,19 @@ CDDBQuery::ReadFromServer(BString &data)
|
||||
// This is to suck up any more search results that the server sends us.
|
||||
BString throwaway;
|
||||
ReadLine(throwaway);
|
||||
while(throwaway.ByteAt(0) != '.')
|
||||
while (throwaway.ByteAt(0) != '.')
|
||||
ReadLine(throwaway);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// We get here for any time the CDDB server does not recognize the CD, amongst other things
|
||||
STRACE(("CDDB lookup error: %s\n",tmp.String()));
|
||||
fCDData.SetGenre("misc");
|
||||
return B_NAME_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
GetToken(tmp.String() + 3, category);
|
||||
}
|
||||
STRACE(("CDDBQuery::ReadFromServer: Genre: %s\n",category.String()));
|
||||
if(!category.Length())
|
||||
{
|
||||
if (!category.Length()) {
|
||||
STRACE(("Set genre to 'misc'\n"));
|
||||
category = "misc";
|
||||
}
|
||||
@ -737,14 +707,12 @@ CDDBQuery::ReadFromServer(BString &data)
|
||||
// Query for the disc's data - artist, album, tracks, etc.
|
||||
query = "";
|
||||
query << "cddb read " << category << ' ' << queryDiscID << '\n' ;
|
||||
if(fSocket.Send(query.String(), query.Length())==-1)
|
||||
{
|
||||
if (fSocket.Send(query.String(), query.Length())==-1) {
|
||||
Disconnect();
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
while (true) {
|
||||
ReadLine(tmp);
|
||||
|
||||
if (tmp == "." || tmp == ".\n")
|
||||
@ -759,17 +727,17 @@ CDDBQuery::ReadFromServer(BString &data)
|
||||
status_t
|
||||
CDDBQuery::Connect()
|
||||
{
|
||||
if(fConnected)
|
||||
if (fConnected)
|
||||
Disconnect();
|
||||
|
||||
BNetAddress address;
|
||||
|
||||
status_t status = address.SetTo(fServerName.String(), fPort);
|
||||
if(status != B_OK)
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = fSocket.Connect(address);
|
||||
if(status != B_OK)
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
fConnected = true;
|
||||
@ -790,8 +758,7 @@ CDDBQuery::IsConnected() const
|
||||
void
|
||||
CDDBQuery::Disconnect()
|
||||
{
|
||||
if(fConnected)
|
||||
{
|
||||
if (fConnected) {
|
||||
fSocket.Close();
|
||||
fConnected = false;
|
||||
}
|
||||
@ -803,8 +770,7 @@ CDDBQuery::ReadLine(BString &buffer)
|
||||
buffer = "";
|
||||
unsigned char ch;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (;;) {
|
||||
if (fSocket.Receive(&ch, 1) <= 0)
|
||||
break;
|
||||
|
||||
@ -813,23 +779,20 @@ CDDBQuery::ReadLine(BString &buffer)
|
||||
// be in a non-ASCII encoding, such as Latin-1 or UTF8. The problem lies in Be's implementation
|
||||
// of BString, which does not support UTF8 string assignments. The Be Book says we have to
|
||||
// flatten the string and adjust the character counts manually. Man, this *really* sucks.
|
||||
if(ch > 0x7f)
|
||||
{
|
||||
if (ch > 0x7f) {
|
||||
// Obviously non-ASCII character detected. Let's see if it's Latin-1 or UTF8.
|
||||
unsigned char *string, *stringindex;
|
||||
int32 length = buffer.Length();
|
||||
|
||||
// The first byte of a UTF8 string will be 110xxxxx
|
||||
if( ((ch & 0xe0) == 0xc0))
|
||||
{
|
||||
if ( ((ch & 0xe0) == 0xc0)) {
|
||||
// This is UTF8. Get the next byte
|
||||
unsigned char ch2;
|
||||
if (fSocket.Receive(&ch2, 1) <= 0)
|
||||
break;
|
||||
|
||||
if( (ch2 & 0xc0) == 0x80)
|
||||
{
|
||||
string = (unsigned char *)buffer.LockBuffer(length+10);
|
||||
if ( (ch2 & 0xc0) == 0x80) {
|
||||
string = (unsigned char *)buffer.LockBuffer(length + 10);
|
||||
stringindex = string + length;
|
||||
|
||||
stringindex[0] = ch;
|
||||
@ -847,39 +810,34 @@ CDDBQuery::ReadLine(BString &buffer)
|
||||
char srcstr[2], deststr[5];
|
||||
int32 srclen, destlen, state;
|
||||
|
||||
srcstr[0]=ch;
|
||||
srcstr[1]='\0';
|
||||
srcstr[0] = ch;
|
||||
srcstr[1] = '\0';
|
||||
srclen = 1;
|
||||
destlen = 5;
|
||||
memset(deststr,0,5);
|
||||
|
||||
if(convert_to_utf8(B_ISO1_CONVERSION,srcstr,&srclen,deststr,&destlen,&state)==B_OK)
|
||||
{
|
||||
if (convert_to_utf8(B_ISO1_CONVERSION,srcstr,&srclen,deststr,&destlen,&state)==B_OK) {
|
||||
// We succeeded. Amazing. Now we hack the string into having the character
|
||||
length = buffer.Length();
|
||||
|
||||
string = (unsigned char *)buffer.LockBuffer(length+10);
|
||||
string = (unsigned char *)buffer.LockBuffer(length + 10);
|
||||
stringindex = string + length;
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
for (int i = 0; i < 5; i++) {
|
||||
stringindex[i] = deststr[i];
|
||||
if(!deststr[i])
|
||||
if (!deststr[i])
|
||||
break;
|
||||
}
|
||||
|
||||
buffer.UnlockBuffer();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// well, we tried. Append the character to the string and live with it
|
||||
buffer+=ch;
|
||||
buffer += ch;
|
||||
}
|
||||
}
|
||||
else
|
||||
buffer +=ch;
|
||||
} else
|
||||
buffer += ch;
|
||||
|
||||
if(ch == '\n')
|
||||
if (ch == '\n')
|
||||
break;
|
||||
}
|
||||
|
||||
@ -895,18 +853,17 @@ CDDBQuery::IdentifySelf()
|
||||
username = getenv("USER");
|
||||
hostname = getenv("HOSTNAME");
|
||||
|
||||
if(username.Length() < 1)
|
||||
if (username.Length() < 1)
|
||||
username = "baron";
|
||||
|
||||
if(hostname.Length() < 1)
|
||||
if (hostname.Length() < 1)
|
||||
hostname = "haiku";
|
||||
|
||||
BString tmp;
|
||||
tmp << "cddb hello " << username << " " << hostname << " HaikuCDPlayer 1.0\n";
|
||||
|
||||
STRACE((">%s", tmp.String()));
|
||||
if(fSocket.Send(tmp.String(), tmp.Length())==-1)
|
||||
{
|
||||
if (fSocket.Send(tmp.String(), tmp.Length())==-1) {
|
||||
Disconnect();
|
||||
return B_ERROR;
|
||||
}
|
||||
@ -930,8 +887,7 @@ CDDBQuery::OpenContentFile(const int32 &discID)
|
||||
BVolumeRoster roster;
|
||||
BVolume volume;
|
||||
roster.Rewind();
|
||||
while (roster.GetNextVolume(&volume) == B_OK)
|
||||
{
|
||||
while (roster.GetNextVolume(&volume) == B_OK) {
|
||||
if (volume.IsReadOnly() || !volume.IsPersistent() || !volume.KnowsAttr()
|
||||
|| !volume.KnowsQuery())
|
||||
continue;
|
||||
@ -945,22 +901,20 @@ CDDBQuery::OpenContentFile(const int32 &discID)
|
||||
if (query.Fetch() != B_OK)
|
||||
continue;
|
||||
|
||||
if(query.GetNextRef(&ref) == B_OK)
|
||||
if (query.GetNextRef(&ref) == B_OK)
|
||||
break;
|
||||
}
|
||||
|
||||
status_t status = fCDData.Load(ref);
|
||||
if(status == B_NO_INIT)
|
||||
{
|
||||
if (status == B_NO_INIT) {
|
||||
// We receive this error when the Load() function couldn't load the track times
|
||||
// This just means that we get it from the SCSI data given to us in SetToCD
|
||||
vector<cdaudio_time> times;
|
||||
GetTrackTimes(&fSCSIData,times);
|
||||
|
||||
for(int32 i=0; i<fCDData.CountTracks(); i++)
|
||||
{
|
||||
for (int32 i = 0; i < fCDData.CountTracks(); i++) {
|
||||
cdaudio_time *item = fCDData.TrackTimeAt(i);
|
||||
*item = times[i+1] - times[i];
|
||||
*item = times[i + 1] - times[i];
|
||||
}
|
||||
|
||||
status = B_OK;
|
||||
@ -976,19 +930,15 @@ CDDBQuery::QueryThread(void *owner)
|
||||
|
||||
signal(kTerminatingSignal, DoNothing);
|
||||
|
||||
if(query->OpenContentFile(query->fCDData.DiscID())!=B_OK)
|
||||
{
|
||||
if (query->OpenContentFile(query->fCDData.DiscID()) != B_OK) {
|
||||
// new content file, read it in from the server
|
||||
if(query->Connect()==B_OK)
|
||||
{
|
||||
if (query->Connect()==B_OK) {
|
||||
BString data;
|
||||
|
||||
query->ReadFromServer(data);
|
||||
query->ParseData(data);
|
||||
query->WriteFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// We apparently couldn't connect to the server, so we'll need to handle
|
||||
// creating tracknames. Note that we do not save to disk. This is because it should
|
||||
// be up to the user what to do.
|
||||
@ -1007,7 +957,7 @@ void
|
||||
CDDBQuery::WriteFile(void)
|
||||
{
|
||||
BPath path;
|
||||
if(find_directory(B_USER_DIRECTORY, &path, true)!=B_OK)
|
||||
if (find_directory(B_USER_DIRECTORY, &path, true) != B_OK)
|
||||
return;
|
||||
|
||||
path.Append("cd");
|
||||
@ -1016,7 +966,7 @@ CDDBQuery::WriteFile(void)
|
||||
BString filename(path.Path());
|
||||
filename << "/" << fCDData.Artist() << " - " << fCDData.Album();
|
||||
|
||||
if(filename.Compare("Artist")==0)
|
||||
if (filename.Compare("Artist")==0)
|
||||
filename << "." << fCDData.DiscID();
|
||||
|
||||
fCDData.Save(filename.String());
|
||||
@ -1025,7 +975,7 @@ CDDBQuery::WriteFile(void)
|
||||
void
|
||||
CDDBQuery::SetDefaultInfo(void)
|
||||
{
|
||||
for(int16 i = fCDData.CountTracks(); i>=0; i--)
|
||||
for (int16 i = fCDData.CountTracks(); i >= 0; i--)
|
||||
fCDData.RemoveTrack(i);
|
||||
|
||||
vector<cdaudio_time> trackTimes;
|
||||
@ -1036,16 +986,15 @@ CDDBQuery::SetDefaultInfo(void)
|
||||
fCDData.SetAlbum("Audio CD");
|
||||
fCDData.SetGenre("Misc");
|
||||
|
||||
for(int32 i=0; i<trackCount; i++)
|
||||
{
|
||||
for (int32 i = 0; i < trackCount; i++) {
|
||||
BString trackname("Track ");
|
||||
|
||||
if(i<9)
|
||||
if (i < 9)
|
||||
trackname << "0";
|
||||
|
||||
trackname << i+1;
|
||||
trackname << i + 1;
|
||||
|
||||
cdaudio_time time = trackTimes[i+1] - trackTimes[i];
|
||||
cdaudio_time time = trackTimes[i + 1] - trackTimes[i];
|
||||
fCDData.AddTrack(trackname.String(),time);
|
||||
}
|
||||
}
|
||||
@ -1056,34 +1005,31 @@ CDDBQuery::ParseData(const BString &data)
|
||||
// Can't simply call MakeEmpty() because the thread is spawned when the discID kept in fCDData
|
||||
// is not the same as what's in the drive and MakeEmpty invalidates *everything* in the object.
|
||||
// Considering that we reassign everything here, simply emptying the track list should be sufficient
|
||||
for(int16 i = fCDData.CountTracks(); i>=0; i--)
|
||||
for (int16 i = fCDData.CountTracks(); i >= 0; i--)
|
||||
fCDData.RemoveTrack(i);
|
||||
|
||||
vector<cdaudio_time> trackTimes;
|
||||
GetTrackTimes(&fSCSIData,trackTimes);
|
||||
int32 trackCount = GetTrackCount(&fSCSIData);
|
||||
|
||||
if(data.CountChars()<1)
|
||||
{
|
||||
if (data.CountChars() < 1) {
|
||||
// This case occurs when the CDDB lookup fails. On these occasions, we need to generate
|
||||
// the file ourselves. This is actually pretty easy.
|
||||
fCDData.SetArtist("Artist");
|
||||
fCDData.SetAlbum("Audio CD");
|
||||
fCDData.SetGenre("Misc");
|
||||
|
||||
for(int32 i=0; i<trackCount; i++)
|
||||
{
|
||||
for (int32 i = 0; i < trackCount; i++) {
|
||||
BString trackname("Track ");
|
||||
|
||||
if(i<9)
|
||||
if (i < 9)
|
||||
trackname << "0";
|
||||
|
||||
trackname << i+1;
|
||||
trackname << i + 1;
|
||||
|
||||
cdaudio_time time = trackTimes[i+1] - trackTimes[i];
|
||||
cdaudio_time time = trackTimes[i + 1] - trackTimes[i];
|
||||
fCDData.AddTrack(trackname.String(),time);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: This function is dog slow, but it works. Optimize.
|
||||
@ -1094,8 +1040,7 @@ CDDBQuery::ParseData(const BString &data)
|
||||
int32 pos;
|
||||
|
||||
pos = data.FindFirst("DYEAR=");
|
||||
if(pos > 0)
|
||||
{
|
||||
if (pos > 0) {
|
||||
BString artist,album;
|
||||
artist = album = GetLineFromString(data.String() + sizeof("DYEAR") + pos);
|
||||
|
||||
@ -1106,13 +1051,12 @@ CDDBQuery::ParseData(const BString &data)
|
||||
}
|
||||
|
||||
pos = data.FindFirst("DTITLE=");
|
||||
if(pos > 0)
|
||||
{
|
||||
if (pos > 0) {
|
||||
BString artist,album;
|
||||
artist = album = GetLineFromString(data.String() + sizeof("DTITLE") + pos);
|
||||
|
||||
pos = artist.FindFirst(" / ");
|
||||
if(pos > 0)
|
||||
if (pos > 0)
|
||||
artist.Truncate(pos);
|
||||
fCDData.SetArtist(artist.String());
|
||||
|
||||
@ -1122,22 +1066,20 @@ CDDBQuery::ParseData(const BString &data)
|
||||
|
||||
BString category = GetLineFromString(data.String() + 4);
|
||||
pos = category.FindFirst(" ");
|
||||
if(pos > 0)
|
||||
if (pos > 0)
|
||||
category.Truncate(pos);
|
||||
fCDData.SetGenre(category.String());
|
||||
|
||||
pos = data.FindFirst("TTITLE0=");
|
||||
if(pos > 0)
|
||||
{
|
||||
int32 trackCount=0;
|
||||
BString searchString="TTITLE0=";
|
||||
if (pos > 0) {
|
||||
int32 trackCount = 0;
|
||||
BString searchString = "TTITLE0=";
|
||||
|
||||
while(pos > 0)
|
||||
{
|
||||
while (pos > 0) {
|
||||
BString trackName = data.String() + pos + searchString.Length();
|
||||
trackName.Truncate(trackName.FindFirst("\n"));
|
||||
|
||||
cdaudio_time tracktime=trackTimes[trackCount+1] - trackTimes[trackCount];
|
||||
cdaudio_time tracktime = trackTimes[trackCount + 1] - trackTimes[trackCount];
|
||||
fCDData.AddTrack(trackName.String(),tracktime);
|
||||
|
||||
trackCount++;
|
||||
@ -1150,20 +1092,20 @@ CDDBQuery::ParseData(const BString &data)
|
||||
|
||||
void CDDBQuery::SetData(const CDDBData &data)
|
||||
{
|
||||
fCDData=data;
|
||||
fCDData = data;
|
||||
}
|
||||
|
||||
BString
|
||||
GetLineFromString(const char *string)
|
||||
{
|
||||
if(!string)
|
||||
if (!string)
|
||||
return NULL;
|
||||
|
||||
BString out(string);
|
||||
|
||||
int32 linefeed = out.FindFirst("\n");
|
||||
|
||||
if(linefeed > 0)
|
||||
if (linefeed > 0)
|
||||
out.Truncate(linefeed);
|
||||
|
||||
return out;
|
||||
|
@ -1,3 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author:
|
||||
* DarkWyrm <bpmagic@columbus.rr.com>
|
||||
*/
|
||||
#include <Alert.h>
|
||||
#include <Application.h>
|
||||
#include <Bitmap.h>
|
||||
@ -15,6 +22,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ButtonBitmaps.h"
|
||||
#include "CDPlayer.h"
|
||||
#include "DrawButton.h"
|
||||
#include "DoubleShotDrawButton.h"
|
||||
@ -24,11 +32,9 @@
|
||||
#include <TranslatorRoster.h>
|
||||
#include <BitmapStream.h>
|
||||
|
||||
enum
|
||||
{
|
||||
M_STOP='mstp',
|
||||
enum {
|
||||
M_STOP = 'mstp',
|
||||
M_PLAY,
|
||||
M_SELECT_TRACK,
|
||||
M_NEXT_TRACK,
|
||||
M_PREV_TRACK,
|
||||
M_FFWD,
|
||||
@ -41,36 +47,53 @@ enum
|
||||
M_SET_CD_TITLE
|
||||
};
|
||||
|
||||
CDPlayer::CDPlayer(BRect frame, const char *name, uint32 resizeMask, uint32 flags)
|
||||
: BView(frame, name, resizeMask, flags | B_FRAME_EVENTS),
|
||||
fCDQuery("freedb.freedb.org")
|
||||
class CDPlayerWindow : public BWindow
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
public:
|
||||
CDPlayerWindow(void);
|
||||
bool QuitRequested(void);
|
||||
};
|
||||
|
||||
inline void
|
||||
SetLabel(BStringView *label, const char *text)
|
||||
{
|
||||
if (strcmp(label->Text(),text) != 0)
|
||||
label->SetText(text);
|
||||
}
|
||||
|
||||
|
||||
CDPlayer::CDPlayer(BRect frame, const char *name, uint32 resizeMask, uint32 flags)
|
||||
: BView(frame, name, resizeMask, flags | B_FRAME_EVENTS),
|
||||
fCDQuery("freedb.freedb.org")
|
||||
{
|
||||
SetViewColor(216,216,216);
|
||||
|
||||
fVolume=255;
|
||||
fVolume = 255;
|
||||
|
||||
BuildGUI();
|
||||
|
||||
if(fCDDrive.CountDrives()<1)
|
||||
{
|
||||
BAlert *alert = new BAlert("CDPlayer","It appears that there are no CD drives on your"
|
||||
"computer or there is no system software to support one."
|
||||
" Sorry.","OK");
|
||||
if (fCDDrive.CountDrives() < 1) {
|
||||
BAlert *alert = new BAlert("CDPlayer","It appears that there are no CD drives"
|
||||
" on your computer or there is no system software"
|
||||
" to support one. Sorry.","OK");
|
||||
alert->Go();
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
|
||||
fWindowState=fCDDrive.GetState();
|
||||
fWindowState = fCDDrive.GetState();
|
||||
fVolumeSlider->SetValue(fCDDrive.GetVolume());
|
||||
WatchCDState();
|
||||
}
|
||||
|
||||
|
||||
CDPlayer::~CDPlayer()
|
||||
{
|
||||
fCDDrive.Stop();
|
||||
}
|
||||
|
||||
void CDPlayer::BuildGUI(void)
|
||||
|
||||
void
|
||||
CDPlayer::BuildGUI(void)
|
||||
{
|
||||
fStopColor.red = 80;
|
||||
fStopColor.green = 164;
|
||||
@ -82,152 +105,100 @@ void CDPlayer::BuildGUI(void)
|
||||
fPlayColor.blue = 40;
|
||||
fPlayColor.alpha = 255;
|
||||
|
||||
BRect r;
|
||||
r.left = 5;
|
||||
r.top = 5;
|
||||
r.right = (Bounds().Width()/2) - 7;
|
||||
BRect r(Bounds().InsetByCopy(10,10));
|
||||
BBox *box = new BBox(r,"",B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
|
||||
AddChild(box);
|
||||
|
||||
r = box->Bounds().InsetByCopy(10,10);
|
||||
r.bottom = 25;
|
||||
|
||||
float labelWidth, labelHeight;
|
||||
fCDTitle = new BStringView(r,"CDTitle","CD drive is empty", B_FOLLOW_LEFT_RIGHT);
|
||||
fCDTitle->GetPreferredSize(&labelWidth, &labelHeight);
|
||||
fCDTitle->ResizeTo(r.Width(), labelHeight);
|
||||
box->AddChild(fCDTitle);
|
||||
|
||||
// Assemble the CD Title box
|
||||
fCDBox = new BBox(r,"TrackBox");
|
||||
AddChild(fCDBox);
|
||||
r.bottom = r.top + labelHeight;
|
||||
r.OffsetBy(0, r.Height() + 5);
|
||||
|
||||
BView *view = new BView( fCDBox->Bounds().InsetByCopy(2,2), "view",B_FOLLOW_ALL,B_WILL_DRAW);
|
||||
view->SetViewColor(20,20,20);
|
||||
fCDBox->AddChild(view);
|
||||
|
||||
fCDTitle = new BStringView(view->Bounds(),"CDTitle","", B_FOLLOW_ALL);
|
||||
view->AddChild(fCDTitle);
|
||||
fCDTitle->SetHighColor(200,200,200);
|
||||
fCDTitle->SetFont(be_bold_font);
|
||||
fCurrentTrack = new BStringView(r,"TrackNumber","",B_FOLLOW_LEFT_RIGHT);
|
||||
box->AddChild(fCurrentTrack);
|
||||
|
||||
r.OffsetBy(0, r.Height() + 5);
|
||||
fTrackMenu = new TrackMenu(r, "TrackMenu", new BMessage(M_SELECT_TRACK));
|
||||
AddChild(fTrackMenu);
|
||||
r.right = r.left + (r.Width() / 2);
|
||||
fTrackTime = new BStringView(r,"TrackTime","Track: --:-- / --:--",B_FOLLOW_LEFT_RIGHT);
|
||||
box->AddChild(fTrackTime);
|
||||
|
||||
r.Set(fCDTitle->Frame().right + 15,5,Bounds().right - 5,25);
|
||||
fTrackBox = new BBox(r,"TrackBox",B_FOLLOW_TOP);
|
||||
AddChild(fTrackBox);
|
||||
|
||||
view = new BView( fTrackBox->Bounds().InsetByCopy(2,2), "view",B_FOLLOW_ALL,B_WILL_DRAW);
|
||||
view->SetViewColor(0,34,7);
|
||||
fTrackBox->AddChild(view);
|
||||
r.OffsetTo(box->Bounds().right / 2, r.top);
|
||||
fDiscTime = new BStringView(r,"DiscTime","Disc: --:-- / --:--",B_FOLLOW_RIGHT);
|
||||
box->AddChild(fDiscTime);
|
||||
|
||||
fCurrentTrack = new BStringView( view->Bounds(),"TrackNumber","",B_FOLLOW_ALL);
|
||||
view->AddChild(fCurrentTrack);
|
||||
fCurrentTrack->SetHighColor(fStopColor);
|
||||
fCurrentTrack->SetFont(be_bold_font);
|
||||
box->ResizeTo(box->Bounds().Width(), fDiscTime->Frame().bottom + 10);
|
||||
|
||||
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);
|
||||
|
||||
r = view->Bounds();
|
||||
r.right /= 2;
|
||||
|
||||
fTrackTime = new BStringView(r,"TrackTime","Track --:-- / --:--",B_FOLLOW_LEFT_RIGHT);
|
||||
view->AddChild(fTrackTime);
|
||||
fTrackTime->SetHighColor(120,120,255);
|
||||
fTrackTime->SetFont(be_bold_font);
|
||||
|
||||
r.right = view->Bounds().right;
|
||||
r.left = fTrackTime->Frame().right + 1;
|
||||
|
||||
fDiscTime = new BStringView(r,"DiscTime","Disc --:-- / --:--",B_FOLLOW_RIGHT);
|
||||
view->AddChild(fDiscTime);
|
||||
fDiscTime->SetHighColor(120,120,255);
|
||||
fDiscTime->SetFont(be_bold_font);
|
||||
|
||||
fVolumeSlider = new BSlider( BRect(0,0,75,30), "VolumeSlider", "Volume", new BMessage(M_SET_VOLUME),0,255);
|
||||
fVolumeSlider->MoveTo(5, Bounds().bottom - 10 - fVolumeSlider->Frame().Height());
|
||||
AddChild(fVolumeSlider);
|
||||
|
||||
fStop = new DrawButton( BRect(0,0,1,1), "Stop", BTranslationUtils::GetBitmap(B_PNG_FORMAT,"stop_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"stop_down"), new BMessage(M_STOP),
|
||||
B_FOLLOW_BOTTOM, B_WILL_DRAW);
|
||||
fStop = new DrawButton(BRect(0,0,1,1), "Stop",
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"stop_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"stop_down"),
|
||||
new BMessage(M_STOP), B_FOLLOW_BOTTOM, B_WILL_DRAW);
|
||||
fStop->ResizeToPreferred();
|
||||
fStop->MoveTo(fVolumeSlider->Frame().right + 10, Bounds().bottom - 5 - fStop->Frame().Height());
|
||||
fStop->MoveTo(10, box->Frame().bottom + 15);
|
||||
fStop->SetDisabled(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"stop_disabled"));
|
||||
AddChild(fStop);
|
||||
float stopTop = fStop->Frame().top;
|
||||
|
||||
fPlay = new TwoStateDrawButton( BRect(0,0,1,1), "Play",
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_down"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"pause_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"pause_down"),
|
||||
new BMessage(M_PLAY), B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
|
||||
fPlay = new TwoStateDrawButton(BRect(0,0,1,1), "Play",
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_down"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_up_on"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_down_on"),
|
||||
new BMessage(M_PLAY), B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
|
||||
fPlay->ResizeToPreferred();
|
||||
fPlay->MoveTo(fStop->Frame().right + 2, Bounds().bottom - 5 - fPlay->Frame().Height());
|
||||
fPlay->SetDisabled(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_disabled"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"pause_disabled"));
|
||||
fPlay->MoveTo(fStop->Frame().right + 2, stopTop);
|
||||
AddChild(fPlay);
|
||||
|
||||
fPrevTrack = new DrawButton( BRect(0,0,1,1), "PrevTrack", BTranslationUtils::GetBitmap(B_PNG_FORMAT,"prev_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"prev_down"), new BMessage(M_PREV_TRACK),
|
||||
B_FOLLOW_BOTTOM, B_WILL_DRAW);
|
||||
fPrevTrack = new DrawButton(BRect(0,0,1,1), "PrevTrack",
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"prev_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"prev_down"),
|
||||
new BMessage(M_PREV_TRACK), B_FOLLOW_BOTTOM,
|
||||
B_WILL_DRAW);
|
||||
fPrevTrack->ResizeToPreferred();
|
||||
fPrevTrack->MoveTo(fPlay->Frame().right + 10, Bounds().bottom - 5 - fPrevTrack->Frame().Height());
|
||||
fPrevTrack->SetDisabled(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"prev_disabled"));
|
||||
fPrevTrack->MoveTo(fPlay->Frame().right + 10, stopTop);
|
||||
AddChild(fPrevTrack);
|
||||
|
||||
fNextTrack = new DrawButton( BRect(0,0,1,1), "NextTrack", BTranslationUtils::GetBitmap(B_PNG_FORMAT,"next_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"next_down"), new BMessage(M_NEXT_TRACK),
|
||||
B_FOLLOW_BOTTOM, B_WILL_DRAW);
|
||||
fNextTrack = new DrawButton(BRect(0,0,1,1), "NextTrack",
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"next_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"next_down"),
|
||||
new BMessage(M_NEXT_TRACK), B_FOLLOW_BOTTOM,
|
||||
B_WILL_DRAW);
|
||||
fNextTrack->ResizeToPreferred();
|
||||
fNextTrack->MoveTo(fPrevTrack->Frame().right + 2, Bounds().bottom - 5 - fNextTrack->Frame().Height());
|
||||
fNextTrack->SetDisabled(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"next_disabled"));
|
||||
fNextTrack->MoveTo(fPrevTrack->Frame().right + 2, stopTop);
|
||||
AddChild(fNextTrack);
|
||||
|
||||
fRewind = new DoubleShotDrawButton( BRect(0,0,1,1), "Rewind",
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"rew_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"rew_down"),
|
||||
new BMessage(M_REWIND), B_FOLLOW_BOTTOM, B_WILL_DRAW);
|
||||
fRewind = new DoubleShotDrawButton(BRect(0,0,1,1), "Rewind",
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"rew_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"rew_down"),
|
||||
new BMessage(M_REWIND), B_FOLLOW_BOTTOM, B_WILL_DRAW);
|
||||
fRewind->ResizeToPreferred();
|
||||
fRewind->MoveTo(fNextTrack->Frame().right + 10, Bounds().bottom - 5 - fRewind->Frame().Height());
|
||||
fRewind->SetDisabled(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"rew_disabled"));
|
||||
fRewind->MoveTo(fNextTrack->Frame().right + 10, stopTop);
|
||||
AddChild(fRewind);
|
||||
|
||||
fFastFwd = new DoubleShotDrawButton( BRect(0,0,1,1), "FastFwd",
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"ffwd_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"ffwd_down"),
|
||||
new BMessage(M_FFWD), B_FOLLOW_BOTTOM, B_WILL_DRAW);
|
||||
fFastFwd = new DoubleShotDrawButton(BRect(0,0,1,1), "FastFwd",
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"ffwd_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"ffwd_down"),
|
||||
new BMessage(M_FFWD), B_FOLLOW_BOTTOM, B_WILL_DRAW);
|
||||
fFastFwd->ResizeToPreferred();
|
||||
fFastFwd->MoveTo(fRewind->Frame().right + 2, Bounds().bottom - 5 - fFastFwd->Frame().Height());
|
||||
fFastFwd->SetDisabled(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"ffwd_disabled"));
|
||||
fFastFwd->MoveTo(fRewind->Frame().right + 2, stopTop);
|
||||
AddChild(fFastFwd);
|
||||
|
||||
fEject = new DrawButton( BRect(0,0,1,1), "Eject", BTranslationUtils::GetBitmap(B_PNG_FORMAT,"eject_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"eject_down"), new BMessage(M_EJECT),
|
||||
B_FOLLOW_BOTTOM, B_WILL_DRAW);
|
||||
fEject->ResizeToPreferred();
|
||||
fEject->MoveTo(fFastFwd->Frame().right + 20, Bounds().bottom - 5 - fEject->Frame().Height());
|
||||
fEject->SetDisabled(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"eject_disabled"));
|
||||
AddChild(fEject);
|
||||
|
||||
fSave = new DrawButton( BRect(0,0,1,1), "Save", BTranslationUtils::GetBitmap(B_PNG_FORMAT,"save_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"save_down"), new BMessage(M_SAVE),
|
||||
B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
fSave->ResizeToPreferred();
|
||||
fSave->MoveTo(fEject->Frame().right + 20, Bounds().bottom - 5 - fSave->Frame().Height());
|
||||
fSave->SetDisabled(BTranslationUtils::GetBitmap(B_PNG_FORMAT,"save_disabled"));
|
||||
AddChild(fSave);
|
||||
fSave->SetEnabled(false);
|
||||
|
||||
fShuffle = new TwoStateDrawButton( BRect(0,0,1,1), "Shuffle",
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"shuffle_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"shuffle_down"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"shuffle_up_on"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"shuffle_down_on"),
|
||||
new BMessage(M_SHUFFLE), B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
fShuffle->ResizeToPreferred();
|
||||
fShuffle->MoveTo(fSave->Frame().right + 2, Bounds().bottom - 5 - fShuffle->Frame().Height());
|
||||
AddChild(fShuffle);
|
||||
r.left = 10;
|
||||
r.right = fPlay->Frame().right;
|
||||
r.top = fStop->Frame().bottom + 14;
|
||||
r.bottom = r.top + kVolumeSliderBitmapHeight - 1.0;
|
||||
fVolumeSlider = new VolumeSlider(r,"VolumeSlider",0,255, new BMessage(M_SET_VOLUME),
|
||||
this);
|
||||
fVolumeSlider->ResizeToPreferred();
|
||||
AddChild(fVolumeSlider);
|
||||
|
||||
fRepeat = new TwoStateDrawButton( BRect(0,0,1,1), "Repeat",
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"repeat_up"),
|
||||
@ -236,99 +207,100 @@ void CDPlayer::BuildGUI(void)
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"repeat_down_on"),
|
||||
new BMessage(M_REPEAT), B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
fRepeat->ResizeToPreferred();
|
||||
fRepeat->MoveTo(fShuffle->Frame().right + 2, Bounds().bottom - 5 - fRepeat->Frame().Height());
|
||||
fRepeat->MoveTo(fPrevTrack->Frame().left,
|
||||
fVolumeSlider->Frame().top -
|
||||
((fRepeat->Frame().Height() - fVolumeSlider->Frame().Height()) / 2));
|
||||
AddChild(fRepeat);
|
||||
|
||||
fShuffle = new TwoStateDrawButton(BRect(0,0,1,1), "Shuffle",
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"shuffle_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"shuffle_down"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"shuffle_up_on"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"shuffle_down_on"),
|
||||
new BMessage(M_SHUFFLE), B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
fShuffle->ResizeToPreferred();
|
||||
fShuffle->MoveTo(fNextTrack->Frame().left + 2,fRepeat->Frame().top);
|
||||
AddChild(fShuffle);
|
||||
|
||||
fEject = new DrawButton(BRect(0,0,1,1), "Eject",
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"eject_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"eject_down"),
|
||||
new BMessage(M_EJECT), B_FOLLOW_BOTTOM, B_WILL_DRAW);
|
||||
fEject->ResizeToPreferred();
|
||||
fEject->MoveTo(fFastFwd->Frame().left, fShuffle->Frame().top);
|
||||
AddChild(fEject);
|
||||
|
||||
ResizeTo(fFastFwd->Frame().right + 10, fVolumeSlider->Frame().bottom + 10);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CDPlayer::MessageReceived(BMessage *msg)
|
||||
{
|
||||
switch (msg->what)
|
||||
{
|
||||
case M_SET_VOLUME:
|
||||
{
|
||||
switch (msg->what) {
|
||||
case M_SET_VOLUME: {
|
||||
fCDDrive.SetVolume(fVolumeSlider->Value());
|
||||
break;
|
||||
}
|
||||
case M_STOP:
|
||||
{
|
||||
fWindowState=kStopped;
|
||||
case M_STOP: {
|
||||
if (fWindowState == kPaused) {
|
||||
fPlay->SetBitmaps(0, BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_down"));
|
||||
fPlay->SetState(1);
|
||||
}
|
||||
fWindowState = kStopped;
|
||||
fCDDrive.Stop();
|
||||
break;
|
||||
}
|
||||
case M_PLAY:
|
||||
{
|
||||
case M_PLAY: {
|
||||
// If we are currently playing, then we will be showing
|
||||
// the pause images and will want to switch back to the play images
|
||||
if(fWindowState==kPlaying)
|
||||
{
|
||||
fWindowState=kPaused;
|
||||
if (fWindowState == kPlaying) {
|
||||
fWindowState = kPaused;
|
||||
fCDDrive.Pause();
|
||||
}
|
||||
else
|
||||
if(fWindowState==kPaused)
|
||||
{
|
||||
fWindowState=kPlaying;
|
||||
fPlay->SetBitmaps(0, BTranslationUtils::GetBitmap(B_PNG_FORMAT,"paused_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"paused_down"));
|
||||
} else if (fWindowState == kPaused) {
|
||||
fWindowState = kPlaying;
|
||||
fCDDrive.Resume();
|
||||
}
|
||||
else
|
||||
{
|
||||
fWindowState=kPlaying;
|
||||
fPlay->SetBitmaps(0, BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_up"),
|
||||
BTranslationUtils::GetBitmap(B_PNG_FORMAT,"play_down"));
|
||||
} else {
|
||||
fWindowState = kPlaying;
|
||||
fCDDrive.Play(fPlayList.GetCurrentTrack());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case M_SELECT_TRACK:
|
||||
{
|
||||
fPlayList.SetCurrentTrack(fTrackMenu->Value()+1);
|
||||
fWindowState=kPlaying;
|
||||
if(!fCDDrive.Play(fPlayList.GetCurrentTrack()))
|
||||
{
|
||||
fWindowState=kStopped;
|
||||
fCDDrive.Stop();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case M_EJECT:
|
||||
{
|
||||
case M_EJECT: {
|
||||
fCDDrive.Eject();
|
||||
break;
|
||||
}
|
||||
case M_NEXT_TRACK:
|
||||
{
|
||||
case M_NEXT_TRACK: {
|
||||
int16 next = fPlayList.GetNextTrack();
|
||||
if(next <= 0)
|
||||
{
|
||||
if (next <= 0) {
|
||||
// force a "wrap around" when possible. This makes it
|
||||
// possible for the user to be able to, for example, jump
|
||||
// back to the first track from the last one with 1 button push
|
||||
next = fPlayList.GetFirstTrack();
|
||||
}
|
||||
|
||||
if(next > 0)
|
||||
{
|
||||
if (next > 0) {
|
||||
CDState state = fCDDrive.GetState();
|
||||
if(state == kPlaying)
|
||||
{
|
||||
while(!fCDDrive.Play(next))
|
||||
{
|
||||
if (state == kPlaying) {
|
||||
while(!fCDDrive.Play(next)) {
|
||||
next = fPlayList.GetNextTrack();
|
||||
if(next<1)
|
||||
{
|
||||
fWindowState=kStopped;
|
||||
if (next < 1) {
|
||||
fWindowState = kStopped;
|
||||
fCDDrive.Stop();
|
||||
fPlayList.Rewind();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if(state == kPaused)
|
||||
{
|
||||
else if (state == kPaused) {
|
||||
fCDDrive.Play(next);
|
||||
fCDDrive.Pause();
|
||||
}
|
||||
}
|
||||
else
|
||||
fPlayList.SetCurrentTrack(next);
|
||||
|
||||
@ -337,41 +309,31 @@ CDPlayer::MessageReceived(BMessage *msg)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case M_PREV_TRACK:
|
||||
{
|
||||
case M_PREV_TRACK: {
|
||||
int16 prev = fPlayList.GetPreviousTrack();
|
||||
if(prev <= 0)
|
||||
{
|
||||
if (prev <= 0) {
|
||||
// force a "wrap around" when possible. This makes it
|
||||
// possible for the user to be able to, for example, jump
|
||||
// back to the first track from the last one with 1 button push
|
||||
prev = fPlayList.GetLastTrack();
|
||||
}
|
||||
|
||||
if(prev > 0)
|
||||
{
|
||||
if (prev > 0) {
|
||||
CDState state = fCDDrive.GetState();
|
||||
if(state == kPlaying)
|
||||
{
|
||||
while(!fCDDrive.Play(prev))
|
||||
{
|
||||
if (state == kPlaying) {
|
||||
while(!fCDDrive.Play(prev)) {
|
||||
prev = fPlayList.GetPreviousTrack();
|
||||
if(prev < 1)
|
||||
{
|
||||
fWindowState=kStopped;
|
||||
if (prev < 1) {
|
||||
fWindowState = kStopped;
|
||||
fCDDrive.Stop();
|
||||
fPlayList.Rewind();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if(state == kPaused)
|
||||
{
|
||||
} else if (state == kPaused) {
|
||||
fCDDrive.Play(prev);
|
||||
fCDDrive.Pause();
|
||||
}
|
||||
else
|
||||
} else
|
||||
fPlayList.SetCurrentTrack(prev);
|
||||
|
||||
// Force an update for better responsiveness
|
||||
@ -379,72 +341,55 @@ CDPlayer::MessageReceived(BMessage *msg)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case M_FFWD:
|
||||
{
|
||||
if(fFastFwd->Value() == B_CONTROL_ON)
|
||||
case M_FFWD: {
|
||||
if (fFastFwd->Value() == B_CONTROL_ON)
|
||||
fCDDrive.StartFastFwd();
|
||||
else
|
||||
fCDDrive.StopFastFwd();
|
||||
break;
|
||||
}
|
||||
case M_REWIND:
|
||||
{
|
||||
if(fRewind->Value() == B_CONTROL_ON)
|
||||
case M_REWIND: {
|
||||
if (fRewind->Value() == B_CONTROL_ON)
|
||||
fCDDrive.StartRewind();
|
||||
else
|
||||
fCDDrive.StopRewind();
|
||||
break;
|
||||
}
|
||||
case M_SAVE:
|
||||
{
|
||||
// TODO: Implement
|
||||
break;
|
||||
}
|
||||
|
||||
case M_SHUFFLE:
|
||||
{
|
||||
if(fPlayList.IsShuffled())
|
||||
{
|
||||
case M_SHUFFLE: {
|
||||
if (fPlayList.IsShuffled()) {
|
||||
int16 track = fPlayList.GetCurrentTrack();
|
||||
fPlayList.SetShuffle(false);
|
||||
fPlayList.SetStartingTrack(track);
|
||||
fPlayList.SetTrackCount(fCDDrive.CountTracks());
|
||||
fShuffle->SetState(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
fPlayList.SetTrackCount(fCDDrive.CountTracks());
|
||||
fPlayList.SetShuffle(true);
|
||||
fShuffle->SetState(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case M_REPEAT:
|
||||
{
|
||||
if(fPlayList.IsLoop())
|
||||
{
|
||||
case M_REPEAT: {
|
||||
if (fPlayList.IsLoop()) {
|
||||
fPlayList.SetLoop(false);
|
||||
fRepeat->SetState(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
fPlayList.SetLoop(true);
|
||||
fRepeat->SetState(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
default: {
|
||||
BView::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CDPlayer::AttachedToWindow()
|
||||
{
|
||||
fVolumeSlider->SetTarget(this);
|
||||
fStop->SetTarget(this);
|
||||
fPlay->SetTarget(this);
|
||||
fNextTrack->SetTarget(this);
|
||||
@ -452,38 +397,10 @@ CDPlayer::AttachedToWindow()
|
||||
fFastFwd->SetTarget(this);
|
||||
fRewind->SetTarget(this);
|
||||
fEject->SetTarget(this);
|
||||
fSave->SetTarget(this);
|
||||
fShuffle->SetTarget(this);
|
||||
fRepeat->SetTarget(this);
|
||||
fTrackMenu->SetTarget(this);
|
||||
}
|
||||
|
||||
void
|
||||
CDPlayer::FrameResized(float new_width, float new_height)
|
||||
{
|
||||
// We implement this method because there is no resizing mode to split the window's
|
||||
// width into two and have a box fill each half
|
||||
|
||||
// The boxes are laid out with 5 pixels between the window edge and each box.
|
||||
// Additionally, 15 pixels of padding are between the two boxes themselves
|
||||
|
||||
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() );
|
||||
|
||||
fTimeBox->MoveTo(half + 8, fTimeBox->Frame().top);
|
||||
fTimeBox->ResizeTo( Bounds().right - (half + 8) - 5, fTimeBox->Bounds().Height() );
|
||||
|
||||
fRepeat->MoveTo(new_width - fRepeat->Bounds().right - 5, fRepeat->Frame().top);
|
||||
|
||||
fShuffle->MoveTo(fRepeat->Frame().left - fShuffle->Bounds().Width() - 2, fShuffle->Frame().top);
|
||||
fSave->MoveTo(fShuffle->Frame().left - fSave->Bounds().Width() - 2, fSave->Frame().top);
|
||||
}
|
||||
|
||||
void
|
||||
CDPlayer::Pulse()
|
||||
@ -491,127 +408,95 @@ CDPlayer::Pulse()
|
||||
WatchCDState();
|
||||
}
|
||||
|
||||
void CDPlayer::WatchCDState(void)
|
||||
|
||||
void
|
||||
CDPlayer::WatchCDState(void)
|
||||
{
|
||||
// One watcher function to rule them all
|
||||
|
||||
// first, watch the one setting independent of having a CD: volume
|
||||
uint8 drivevolume = fCDDrive.GetVolume();
|
||||
if(fVolume == drivevolume)
|
||||
{
|
||||
fVolume=drivevolume;
|
||||
if (fVolume == drivevolume) {
|
||||
fVolume = drivevolume;
|
||||
fVolumeSlider->SetValue(fVolume);
|
||||
}
|
||||
|
||||
// Second, establish whether or not we have a CD in the drive
|
||||
CDState playstate = fCDDrive.GetState();
|
||||
bool internal_track_change=false;
|
||||
bool internal_track_change = false;
|
||||
|
||||
if(playstate == kNoCD)
|
||||
{
|
||||
if (playstate == kNoCD) {
|
||||
// Yes, we have no bananas!
|
||||
|
||||
if(fWindowState != kNoCD)
|
||||
{
|
||||
// Do something only if there is a change in the app's play state
|
||||
if (fWindowState != kNoCD) {
|
||||
// We have just discovered that we have no bananas
|
||||
fWindowState = kNoCD;
|
||||
|
||||
// Because we are changing play states, we will need to update the GUI
|
||||
|
||||
fCDData.SetDiscID(-1);
|
||||
fCDTitle->SetText("No CD");
|
||||
SetLabel(fCDTitle,"CD drive is empty");
|
||||
|
||||
fCurrentTrack->SetText("");
|
||||
fCurrentTrack->SetHighColor(fStopColor);
|
||||
fCurrentTrack->Invalidate();
|
||||
fTrackMenu->SetItemCount(0);
|
||||
fTrackTime->SetText("Track --:-- / --:--");
|
||||
fDiscTime->SetText("Disc --:-- / --:--");
|
||||
SetLabel(fCurrentTrack,"");
|
||||
SetLabel(fTrackTime,"Track: --:-- / --:--");
|
||||
SetLabel(fDiscTime,"Disc: --:-- / --:--");
|
||||
fPlayList.SetTrackCount(0);
|
||||
fPlayList.SetStartingTrack(1);
|
||||
fPlayList.SetCurrentTrack(1);
|
||||
|
||||
if(fPlay->GetState()==1)
|
||||
if (fPlay->GetState() == 1)
|
||||
fPlay->SetState(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No change in the app's play state, so do nothing
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Now otherwise handle the play state
|
||||
if(playstate == kStopped)
|
||||
{
|
||||
if(fWindowState == kPlaying)
|
||||
{
|
||||
internal_track_change=true;
|
||||
if (playstate == kStopped) {
|
||||
if (fWindowState == kPlaying) {
|
||||
internal_track_change = true;
|
||||
|
||||
// This means that the drive finished playing the song, so get the next one
|
||||
// from the list and play it
|
||||
int16 next = fPlayList.GetNextTrack();
|
||||
if(next > 0)
|
||||
if (next > 0)
|
||||
fCDDrive.Play(next);
|
||||
}
|
||||
|
||||
if(fPlay->GetState()==1)
|
||||
{
|
||||
if (fPlay->GetState() == 1)
|
||||
fPlay->SetState(0);
|
||||
fCurrentTrack->SetHighColor(fStopColor);
|
||||
fCurrentTrack->Invalidate();
|
||||
}
|
||||
}
|
||||
else
|
||||
if(playstate == kPlaying)
|
||||
{
|
||||
if(fPlay->GetState()==0)
|
||||
} else if (playstate == kPlaying) {
|
||||
if (fPlay->GetState() == 0)
|
||||
fPlay->SetState(1);
|
||||
fCurrentTrack->SetHighColor(fPlayColor);
|
||||
fCurrentTrack->Invalidate();
|
||||
}
|
||||
else
|
||||
if(playstate == kPaused)
|
||||
{
|
||||
} else if (playstate == kPaused) {
|
||||
fPlay->SetState(0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// If we got this far, then there must be a CD in the drive. The next order on the agenda
|
||||
// is to find out which CD it is
|
||||
int32 discid = fCDDrive.GetDiscID();
|
||||
bool update_track_gui=false;
|
||||
bool update_track_gui = false;
|
||||
|
||||
if(discid != fCDData.DiscID())
|
||||
{
|
||||
if (discid != fCDData.DiscID()) {
|
||||
update_track_gui = true;
|
||||
|
||||
// Apparently the disc has changed since we last looked.
|
||||
if(fCDQuery.CurrentDiscID()!=discid)
|
||||
{
|
||||
if (fCDQuery.CurrentDiscID() != discid)
|
||||
fCDQuery.SetToCD(fCDDrive.GetDrivePath());
|
||||
}
|
||||
|
||||
if(fCDQuery.Ready())
|
||||
{
|
||||
if (fCDQuery.Ready()) {
|
||||
// Note that we only update the CD title for now. We still need a track number
|
||||
// in order to update the display for the selected track
|
||||
if(fCDQuery.GetData(&fCDData, 1000000))
|
||||
{
|
||||
if (fCDQuery.GetData(&fCDData, 1000000)) {
|
||||
BString display(fCDData.Artist());
|
||||
display << " - " << fCDData.Album();
|
||||
fCDTitle->SetText(display.String());
|
||||
}
|
||||
else
|
||||
{
|
||||
fCDTitle->SetText("Audio CD");
|
||||
SetLabel(fCDTitle,display.String());
|
||||
} else {
|
||||
SetLabel(fCDTitle,"Audio CD");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Now that we know which CD it is, update the track info
|
||||
int16 drivecount = fCDDrive.CountTracks();
|
||||
int16 drivetrack = fCDDrive.GetTrack();
|
||||
@ -619,14 +504,11 @@ void CDPlayer::WatchCDState(void)
|
||||
int16 playlisttrack = fPlayList.GetCurrentTrack();
|
||||
int16 playlistcount = fPlayList.TrackCount();
|
||||
|
||||
if(playstate == kPlaying)
|
||||
{
|
||||
if(playlisttrack != drivetrack)
|
||||
{
|
||||
if (playstate == kPlaying) {
|
||||
if (playlisttrack != drivetrack) {
|
||||
playlisttrack = drivetrack;
|
||||
|
||||
if(!internal_track_change)
|
||||
{
|
||||
if (!internal_track_change) {
|
||||
// The main thing is that we need to make sure that the playlist and the drive's track
|
||||
// stay in sync. The CD's track may have been changed by an outside source, so if
|
||||
// the drive is playing, check for playlist sync.
|
||||
@ -634,75 +516,51 @@ void CDPlayer::WatchCDState(void)
|
||||
fPlayList.SetCurrentTrack(drivetrack);
|
||||
}
|
||||
}
|
||||
update_track_gui=true;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(playlistcount != drivecount)
|
||||
{
|
||||
update_track_gui = true;
|
||||
} else {
|
||||
if (playlistcount != drivecount) {
|
||||
// This happens only when CDs are changed
|
||||
if(drivecount<0)
|
||||
{
|
||||
if (drivecount < 0) {
|
||||
// There is no CD in the drive. The playlist needs to have its track
|
||||
// count set to 0 and it also needs to be rewound.
|
||||
fPlayList.SetStartingTrack(1);
|
||||
fPlayList.SetTrackCount(0);
|
||||
playlisttrack=1;
|
||||
playlistcount=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
playlisttrack = 1;
|
||||
playlistcount = 0;
|
||||
} else {
|
||||
// Two possible cases here: playlist is empty or playlist has a different
|
||||
// number of tracks. In either case, the playlist needs to be reinitialized
|
||||
// to the current track data
|
||||
fPlayList.SetStartingTrack(1);
|
||||
fPlayList.SetTrackCount(drivecount);
|
||||
playlisttrack=fPlayList.GetCurrentTrack();
|
||||
playlistcount=drivecount;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// CD has not changed, so check for change in tracks
|
||||
if(playlisttrack != drivetrack)
|
||||
{
|
||||
update_track_gui=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// do nothing. Everything is hunky-dory
|
||||
playlisttrack = fPlayList.GetCurrentTrack();
|
||||
playlistcount = drivecount;
|
||||
}
|
||||
} else {
|
||||
// update only with a track change
|
||||
if (playlisttrack != drivetrack)
|
||||
update_track_gui = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(update_track_gui)
|
||||
{
|
||||
if (update_track_gui) {
|
||||
BString currentTrackName;
|
||||
|
||||
if(playlisttrack >= 0)
|
||||
{
|
||||
if (playlisttrack >= 0) {
|
||||
int16 whichtrack = playlisttrack;
|
||||
|
||||
if(whichtrack == 0)
|
||||
if (whichtrack == 0)
|
||||
whichtrack++;
|
||||
|
||||
currentTrackName << "Track " << whichtrack << ": " << fCDData.TrackAt(whichtrack-1);
|
||||
|
||||
fCurrentTrack->SetText(currentTrackName.String());
|
||||
SetLabel(fCurrentTrack,currentTrackName.String());
|
||||
|
||||
fTrackMenu->SetItemCount(playlistcount);
|
||||
fTrackMenu->SetValue(playlisttrack-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
fCurrentTrack->SetText("");
|
||||
fTrackMenu->SetItemCount(0);
|
||||
fTrackMenu->SetValue(1);
|
||||
} else {
|
||||
SetLabel(fCurrentTrack,"");
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Now update the time info
|
||||
cdaudio_time tracktime;
|
||||
cdaudio_time disctime;
|
||||
@ -710,63 +568,54 @@ void CDPlayer::WatchCDState(void)
|
||||
cdaudio_time disctotal;
|
||||
char timestring[1024];
|
||||
|
||||
if(fCDDrive.GetTime(tracktime, disctime))
|
||||
{
|
||||
if (fCDDrive.GetTime(tracktime, disctime)) {
|
||||
fCDDrive.GetTimeForDisc(disctotal);
|
||||
sprintf(timestring,"Disc %ld:%.2ld / %ld:%.2ld",disctime.minutes,disctime.seconds,
|
||||
sprintf(timestring,"Disc: %ld:%.2ld / %ld:%.2ld",disctime.minutes,disctime.seconds,
|
||||
disctotal.minutes,disctotal.seconds);
|
||||
fDiscTime->SetText(timestring);
|
||||
SetLabel(fDiscTime,timestring);
|
||||
|
||||
fCDDrive.GetTimeForTrack(playlisttrack,tracktotal);
|
||||
sprintf(timestring,"Track %ld:%.2ld / %ld:%.2ld",tracktime.minutes,tracktime.seconds,
|
||||
sprintf(timestring,"Track: %ld:%.2ld / %ld:%.2ld",tracktime.minutes,tracktime.seconds,
|
||||
tracktotal.minutes,tracktotal.seconds);
|
||||
fTrackTime->SetText(timestring);
|
||||
}
|
||||
else
|
||||
{
|
||||
fTrackTime->SetText("Track --:-- / --:--");
|
||||
fDiscTime->SetText("Disc --:-- / --:--");
|
||||
SetLabel(fTrackTime,timestring);
|
||||
} else {
|
||||
SetLabel(fTrackTime,"Track: --:-- / --:--");
|
||||
SetLabel(fDiscTime,"Disc: --:-- / --:--");
|
||||
}
|
||||
}
|
||||
|
||||
class CDPlayerWindow : public BWindow
|
||||
{
|
||||
public:
|
||||
CDPlayerWindow(void);
|
||||
bool QuitRequested(void);
|
||||
};
|
||||
|
||||
CDPlayerWindow::CDPlayerWindow(void)
|
||||
: BWindow(BRect (100, 100, 610, 200), "CD Player", B_TITLED_WINDOW, B_NOT_V_RESIZABLE |
|
||||
B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS)
|
||||
: BWindow(BRect (100, 100, 405, 280), "CD Player", B_TITLED_WINDOW, B_NOT_RESIZABLE |
|
||||
B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS)
|
||||
{
|
||||
float wmin,wmax,hmin,hmax;
|
||||
|
||||
GetSizeLimits(&wmin,&wmax,&hmin,&hmax);
|
||||
wmin=510;
|
||||
hmin=100;
|
||||
SetSizeLimits(wmin,wmax,hmin,hmax);
|
||||
}
|
||||
|
||||
bool CDPlayerWindow::QuitRequested(void)
|
||||
|
||||
bool
|
||||
CDPlayerWindow::QuitRequested(void)
|
||||
{
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
CDPlayerApplication::CDPlayerApplication()
|
||||
: BApplication("application/x-vnd.Haiku-CDPlayer")
|
||||
: BApplication("application/x-vnd.Haiku-CDPlayer")
|
||||
{
|
||||
BWindow *window = new CDPlayerWindow();
|
||||
BView *button = new CDPlayer(window->Bounds(), "CD");
|
||||
window->AddChild(button);
|
||||
BView *view = new CDPlayer(window->Bounds(), "CD");
|
||||
window->ResizeTo(view->Bounds().Width(), view->Bounds().Height());
|
||||
window->AddChild(view);
|
||||
window->Show();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int, char **argv)
|
||||
{
|
||||
(new CDPlayerApplication())->Run();
|
||||
CDPlayerApplication app;
|
||||
app.Run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,14 +12,13 @@
|
||||
#include <Window.h>
|
||||
#include <View.h>
|
||||
#include <Button.h>
|
||||
#include <Slider.h>
|
||||
#include <TextControl.h>
|
||||
#include <StringView.h>
|
||||
|
||||
#include "TrackMenu.h"
|
||||
#include "CDAudioDevice.h"
|
||||
#include "CDDBSupport.h"
|
||||
#include "PlayList.h"
|
||||
#include "VolumeSlider.h"
|
||||
|
||||
class DrawButton;
|
||||
class DoubleShotDrawButton;
|
||||
@ -38,7 +37,6 @@ public:
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
virtual void Pulse();
|
||||
virtual void FrameResized(float new_width, float new_height);
|
||||
virtual void MessageReceived(BMessage *);
|
||||
|
||||
private:
|
||||
@ -47,8 +45,7 @@ private:
|
||||
DrawButton *fStop,
|
||||
*fNextTrack,
|
||||
*fPrevTrack,
|
||||
*fEject,
|
||||
*fSave;
|
||||
*fEject;
|
||||
|
||||
DoubleShotDrawButton
|
||||
*fFastFwd,
|
||||
@ -58,7 +55,7 @@ private:
|
||||
*fRepeat,
|
||||
*fPlay;
|
||||
|
||||
BSlider *fVolumeSlider;
|
||||
VolumeSlider *fVolumeSlider;
|
||||
|
||||
BStringView *fCDTitle,
|
||||
*fCurrentTrack,
|
||||
@ -68,8 +65,6 @@ private:
|
||||
BBox *fCDBox,
|
||||
*fTrackBox,
|
||||
*fTimeBox;
|
||||
|
||||
TrackMenu *fTrackMenu;
|
||||
|
||||
CDState fCDState;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author:
|
||||
* DarkWyrm <bpmagic@columbus.rr.com>
|
||||
*/
|
||||
#include "DoubleShotDrawButton.h"
|
||||
#include <stdio.h>
|
||||
|
||||
@ -12,6 +19,7 @@ DoubleShotDrawButton::DoubleShotDrawButton(BRect frame, const char *name, BBitma
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DoubleShotDrawButton::MouseDown(BPoint point)
|
||||
{
|
||||
|
@ -1,3 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author:
|
||||
* DarkWyrm <bpmagic@columbus.rr.com>
|
||||
*/
|
||||
#ifndef _DOUBLESHOT_DRAW_BUTTON_H
|
||||
#define _DOUBLESHOT_DRAW_BUTTON_H
|
||||
|
||||
@ -13,8 +20,8 @@ class DoubleShotDrawButton : public DrawButton
|
||||
{
|
||||
public:
|
||||
DoubleShotDrawButton(BRect frame, const char *name, BBitmap *up,
|
||||
BBitmap *down,BMessage *msg, int32 resize,
|
||||
int32 flags);
|
||||
BBitmap *down,BMessage *msg, int32 resize,
|
||||
int32 flags);
|
||||
|
||||
void MouseDown(BPoint point);
|
||||
};
|
||||
|
@ -1,14 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author:
|
||||
* DarkWyrm <bpmagic@columbus.rr.com>
|
||||
*/
|
||||
#include "DrawButton.h"
|
||||
|
||||
DrawButton::DrawButton(BRect frame, const char *name, BBitmap *up, BBitmap *down,
|
||||
BMessage *msg, int32 resize, int32 flags)
|
||||
: BButton(frame, name, "", msg, resize, flags)
|
||||
: BButton(frame, name, "", msg, resize, flags)
|
||||
{
|
||||
fUp=up;
|
||||
fDown=down;
|
||||
fDisabled=NULL;
|
||||
fUp = up;
|
||||
fDown = down;
|
||||
fDisabled = NULL;
|
||||
}
|
||||
|
||||
|
||||
DrawButton::~DrawButton(void)
|
||||
{
|
||||
delete fUp;
|
||||
@ -16,67 +24,65 @@ DrawButton::~DrawButton(void)
|
||||
delete fDisabled;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DrawButton::SetBitmaps(BBitmap *up, BBitmap *down)
|
||||
{
|
||||
delete fUp;
|
||||
delete fDown;
|
||||
|
||||
fUp=up;
|
||||
fDown=down;
|
||||
fUp = up;
|
||||
fDown = down;
|
||||
|
||||
if(IsEnabled())
|
||||
if (IsEnabled())
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DrawButton::SetDisabled(BBitmap *disabled)
|
||||
{
|
||||
delete fDisabled;
|
||||
|
||||
fDisabled=disabled;
|
||||
fDisabled = disabled;
|
||||
|
||||
if(!IsEnabled())
|
||||
if (!IsEnabled())
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DrawButton::Draw(BRect update)
|
||||
{
|
||||
if(!IsEnabled())
|
||||
{
|
||||
if(fDisabled)
|
||||
if (!IsEnabled()) {
|
||||
if (fDisabled)
|
||||
DrawBitmap(fDisabled, BPoint(0,0));
|
||||
else
|
||||
StrokeRect(Bounds());
|
||||
return;
|
||||
}
|
||||
|
||||
if(Value() == B_CONTROL_ON)
|
||||
{
|
||||
if(fDown)
|
||||
if (Value() == B_CONTROL_ON) {
|
||||
if (fDown)
|
||||
DrawBitmap(fDown, BPoint(0,0));
|
||||
else
|
||||
StrokeRect(Bounds());
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fUp)
|
||||
} else {
|
||||
if (fUp)
|
||||
DrawBitmap(fUp, BPoint(0,0));
|
||||
else
|
||||
StrokeRect(Bounds());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DrawButton::ResizeToPreferred(void)
|
||||
{
|
||||
if(fUp)
|
||||
if (fUp)
|
||||
ResizeTo(fUp->Bounds().Width(),fUp->Bounds().Height());
|
||||
else
|
||||
if(fDown)
|
||||
else if (fDown)
|
||||
ResizeTo(fDown->Bounds().Width(),fDown->Bounds().Height());
|
||||
else
|
||||
if(fDisabled)
|
||||
else if (fDisabled)
|
||||
ResizeTo(fDisabled->Bounds().Width(),fDisabled->Bounds().Height());
|
||||
}
|
||||
|
@ -1,3 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author:
|
||||
* DarkWyrm <bpmagic@columbus.rr.com>
|
||||
*/
|
||||
#ifndef _DRAW_BUTTON_H
|
||||
#define _DRAW_BUTTON_H
|
||||
|
||||
|
445
src/apps/cdplayer/DrawingTidbits.cpp
Normal file
445
src/apps/cdplayer/DrawingTidbits.cpp
Normal file
@ -0,0 +1,445 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
// TODO: remove this file again.... It originates from Be Sample code,
|
||||
// but was added to the VLC Media Player BeOS interface, I added some stuff
|
||||
// during my work on VLC, but I am not sure anymore if this file still
|
||||
// contains work done by Tony Castley, which would be GPL!
|
||||
|
||||
#include "DrawingTidbits.h"
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Debug.h>
|
||||
#include <Screen.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// ShiftComponent
|
||||
inline uchar
|
||||
ShiftComponent(uchar component, float percent)
|
||||
{
|
||||
// change the color by <percent>, make sure we aren't rounding
|
||||
// off significant bits
|
||||
if (percent >= 1)
|
||||
return (uchar)(component * (2 - percent));
|
||||
else
|
||||
return (uchar)(255 - percent * (255 - component));
|
||||
}
|
||||
|
||||
// ShiftColor
|
||||
rgb_color
|
||||
ShiftColor(rgb_color color, float percent)
|
||||
{
|
||||
rgb_color result = {
|
||||
ShiftComponent(color.red, percent),
|
||||
ShiftComponent(color.green, percent),
|
||||
ShiftComponent(color.blue, percent),
|
||||
0
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ReplaceColor
|
||||
void
|
||||
ReplaceColor(BBitmap *bitmap, rgb_color from, rgb_color to)
|
||||
{
|
||||
ASSERT(bitmap->ColorSpace() == B_COLOR_8_BIT); // other color spaces not implemented yet
|
||||
|
||||
BScreen screen(B_MAIN_SCREEN_ID);
|
||||
uint32 fromIndex = screen.IndexForColor(from);
|
||||
uint32 toIndex = screen.IndexForColor(to);
|
||||
|
||||
uchar *bits = (uchar *)bitmap->Bits();
|
||||
int32 bitsLength = bitmap->BitsLength();
|
||||
for (int32 index = 0; index < bitsLength; index++)
|
||||
if (bits[index] == fromIndex)
|
||||
bits[index] = toIndex;
|
||||
}
|
||||
|
||||
// ReplaceTransparentColor
|
||||
void
|
||||
ReplaceTransparentColor(BBitmap *bitmap, rgb_color with)
|
||||
{
|
||||
ASSERT(bitmap->ColorSpace() == B_COLOR_8_BIT); // other color spaces not implemented yet
|
||||
|
||||
BScreen screen(B_MAIN_SCREEN_ID);
|
||||
uint32 withIndex = screen.IndexForColor(with);
|
||||
|
||||
uchar *bits = (uchar *)bitmap->Bits();
|
||||
int32 bitsLength = bitmap->BitsLength();
|
||||
for (int32 index = 0; index < bitsLength; index++)
|
||||
if (bits[index] == B_TRANSPARENT_8_BIT)
|
||||
bits[index] = withIndex;
|
||||
}
|
||||
|
||||
// ycrcb_to_rgb
|
||||
inline void
|
||||
ycbcr_to_rgb( uint8 y, uint8 cb, uint8 cr,
|
||||
uint8& r, uint8& g, uint8& b)
|
||||
{
|
||||
r = (uint8)max_c( 0, min_c( 255, 1.164 * ( y - 16 ) + 1.596 * ( cr - 128 ) ) );
|
||||
g = (uint8)max_c( 0, min_c( 255, 1.164 * ( y - 16 ) - 0.813 * ( cr - 128 )
|
||||
- 0.391 * ( cb - 128 ) ) );
|
||||
b = (uint8)max_c( 0, min_c( 255, 1.164 * ( y - 16 ) + 2.018 * ( cb - 128 ) ) );
|
||||
}
|
||||
|
||||
// this function will not produce visually pleasing results!
|
||||
// we'd have to convert to Lab colorspace, do the mixing
|
||||
// and convert back to RGB - in an ideal world...
|
||||
//
|
||||
// mix_colors
|
||||
inline void
|
||||
mix_colors( uint8 ra, uint8 ga, uint8 ba,
|
||||
uint8 rb, uint8 gb, uint8 bb,
|
||||
uint8& r, uint8& g, uint8& b, float mixLevel )
|
||||
{
|
||||
float mixA = ( 1.0 - mixLevel );
|
||||
float mixB = mixLevel;
|
||||
r = (uint8)(mixA * ra + mixB * rb);
|
||||
g = (uint8)(mixA * ga + mixB * gb);
|
||||
b = (uint8)(mixA * ba + mixB * bb);
|
||||
}
|
||||
|
||||
// the algorithm used is probably pretty slow, but it should be easy
|
||||
// to understand what's going on...
|
||||
//
|
||||
// scale_bitmap
|
||||
status_t
|
||||
scale_bitmap( BBitmap* bitmap, uint32 fromWidth, uint32 fromHeight )
|
||||
{
|
||||
status_t status = B_BAD_VALUE;
|
||||
|
||||
if ( bitmap && bitmap->IsValid()
|
||||
&& ( bitmap->ColorSpace() == B_RGB32 || bitmap->ColorSpace() == B_RGBA32 ) )
|
||||
{
|
||||
status = B_MISMATCHED_VALUES;
|
||||
// we only support upscaling as of now
|
||||
uint32 destWidth = bitmap->Bounds().IntegerWidth() + 1;
|
||||
uint32 destHeight = bitmap->Bounds().IntegerHeight() + 1;
|
||||
if ( fromWidth <= destWidth && fromHeight <= destHeight )
|
||||
{
|
||||
status = B_OK;
|
||||
uint32 bpr = bitmap->BytesPerRow();
|
||||
if ( fromWidth < destWidth )
|
||||
{
|
||||
// scale horizontally
|
||||
uint8* src = (uint8*)bitmap->Bits();
|
||||
uint8* p = new uint8[fromWidth * 4]; // temp buffer
|
||||
for ( uint32 y = 0; y < fromHeight; y++ )
|
||||
{
|
||||
// copy valid pixels into temp buffer
|
||||
memcpy( p, src, fromWidth * 4 );
|
||||
for ( uint32 x = 0; x < destWidth; x++ )
|
||||
{
|
||||
// mix colors of left and right pixels and write it back
|
||||
// into the bitmap
|
||||
float xPos = ( (float)x / (float)destWidth ) * (float)fromWidth;
|
||||
uint32 leftIndex = (uint32)floorf( xPos ) * 4;
|
||||
uint32 rightIndex = (uint32)ceilf( xPos ) * 4;
|
||||
rgb_color left;
|
||||
left.red = p[leftIndex + 2];
|
||||
left.green = p[leftIndex + 1];
|
||||
left.blue = p[leftIndex + 0];
|
||||
rgb_color right;
|
||||
right.red = p[rightIndex + 2];
|
||||
right.green = p[rightIndex + 1];
|
||||
right.blue = p[rightIndex + 0];
|
||||
rgb_color mix;
|
||||
mix_colors( left.red, left.green, left.blue,
|
||||
right.red, right.green, right.blue,
|
||||
mix.red, mix.green, mix.blue, xPos - floorf( xPos ) );
|
||||
uint32 destIndex = x * 4;
|
||||
src[destIndex + 2] = mix.red;
|
||||
src[destIndex + 1] = mix.green;
|
||||
src[destIndex + 0] = mix.blue;
|
||||
}
|
||||
src += bpr;
|
||||
}
|
||||
delete[] p;
|
||||
}
|
||||
if ( fromHeight < destHeight )
|
||||
{
|
||||
// scale vertically
|
||||
uint8* src = (uint8*)bitmap->Bits();
|
||||
uint8* p = new uint8[fromHeight * 3]; // temp buffer
|
||||
for ( uint32 x = 0; x < destWidth; x++ )
|
||||
{
|
||||
// copy valid pixels into temp buffer
|
||||
for ( uint32 y = 0; y < fromHeight; y++ )
|
||||
{
|
||||
uint32 destIndex = y * 3;
|
||||
uint32 srcIndex = x * 4 + y * bpr;
|
||||
p[destIndex + 0] = src[srcIndex + 0];
|
||||
p[destIndex + 1] = src[srcIndex + 1];
|
||||
p[destIndex + 2] = src[srcIndex + 2];
|
||||
}
|
||||
// do the scaling
|
||||
for ( uint32 y = 0; y < destHeight; y++ )
|
||||
{
|
||||
// mix colors of upper and lower pixels and write it back
|
||||
// into the bitmap
|
||||
float yPos = ( (float)y / (float)destHeight ) * (float)fromHeight;
|
||||
uint32 upperIndex = (uint32)floorf( yPos ) * 3;
|
||||
uint32 lowerIndex = (uint32)ceilf( yPos ) * 3;
|
||||
rgb_color upper;
|
||||
upper.red = p[upperIndex + 2];
|
||||
upper.green = p[upperIndex + 1];
|
||||
upper.blue = p[upperIndex + 0];
|
||||
rgb_color lower;
|
||||
lower.red = p[lowerIndex + 2];
|
||||
lower.green = p[lowerIndex + 1];
|
||||
lower.blue = p[lowerIndex + 0];
|
||||
rgb_color mix;
|
||||
mix_colors( upper.red, upper.green, upper.blue,
|
||||
lower.red, lower.green, lower.blue,
|
||||
mix.red, mix.green, mix.blue, yPos - floorf( yPos ) );
|
||||
uint32 destIndex = x * 4 + y * bpr;
|
||||
src[destIndex + 2] = mix.red;
|
||||
src[destIndex + 1] = mix.green;
|
||||
src[destIndex + 0] = mix.blue;
|
||||
}
|
||||
}
|
||||
delete[] p;
|
||||
}
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// convert_bitmap
|
||||
status_t
|
||||
convert_bitmap( BBitmap* inBitmap, BBitmap* outBitmap )
|
||||
{
|
||||
status_t status = B_BAD_VALUE;
|
||||
// see that we got valid bitmaps
|
||||
if ( inBitmap && inBitmap->IsValid()
|
||||
&& outBitmap && outBitmap->IsValid() )
|
||||
{
|
||||
status = B_MISMATCHED_VALUES;
|
||||
// see that bitmaps are compatible and that we support the conversion
|
||||
if ( inBitmap->Bounds().Width() <= outBitmap->Bounds().Width()
|
||||
&& inBitmap->Bounds().Height() <= outBitmap->Bounds().Height()
|
||||
&& ( outBitmap->ColorSpace() == B_RGB32
|
||||
|| outBitmap->ColorSpace() == B_RGBA32) )
|
||||
{
|
||||
int32 width = inBitmap->Bounds().IntegerWidth() + 1;
|
||||
int32 height = inBitmap->Bounds().IntegerHeight() + 1;
|
||||
int32 srcBpr = inBitmap->BytesPerRow();
|
||||
int32 dstBpr = outBitmap->BytesPerRow();
|
||||
uint8* srcBits = (uint8*)inBitmap->Bits();
|
||||
uint8* dstBits = (uint8*)outBitmap->Bits();
|
||||
switch (inBitmap->ColorSpace())
|
||||
{
|
||||
case B_YCbCr422:
|
||||
// Y0[7:0] Cb0[7:0] Y1[7:0] Cr0[7:0]
|
||||
// Y2[7:0] Cb2[7:0] Y3[7:0] Cr2[7:0]
|
||||
for ( int32 y = 0; y < height; y++ )
|
||||
{
|
||||
for ( int32 x = 0; x < width; x += 2 )
|
||||
{
|
||||
int32 srcOffset = x * 2;
|
||||
int32 dstOffset = x * 4;
|
||||
ycbcr_to_rgb( srcBits[srcOffset + 0],
|
||||
srcBits[srcOffset + 1],
|
||||
srcBits[srcOffset + 3],
|
||||
dstBits[dstOffset + 2],
|
||||
dstBits[dstOffset + 1],
|
||||
dstBits[dstOffset + 0] );
|
||||
ycbcr_to_rgb( srcBits[srcOffset + 2],
|
||||
srcBits[srcOffset + 1],
|
||||
srcBits[srcOffset + 3],
|
||||
dstBits[dstOffset + 6],
|
||||
dstBits[dstOffset + 5],
|
||||
dstBits[dstOffset + 4] );
|
||||
// take care of alpha
|
||||
dstBits[x * 4 + 3] = 255;
|
||||
dstBits[x * 4 + 7] = 255;
|
||||
}
|
||||
srcBits += srcBpr;
|
||||
dstBits += dstBpr;
|
||||
}
|
||||
status = B_OK;
|
||||
break;
|
||||
case B_YCbCr420:
|
||||
// Non-interlaced only!
|
||||
// Cb0 Y0 Y1 Cb2 Y2 Y3 on even scan lines ...
|
||||
// Cr0 Y0 Y1 Cr2 Y2 Y3 on odd scan lines
|
||||
status = B_ERROR;
|
||||
break;
|
||||
case B_YUV422:
|
||||
// U0[7:0] Y0[7:0] V0[7:0] Y1[7:0]
|
||||
// U2[7:0] Y2[7:0] V2[7:0] Y3[7:0]
|
||||
status = B_ERROR;
|
||||
break;
|
||||
case B_RGB32:
|
||||
case B_RGBA32:
|
||||
memcpy( dstBits, srcBits, inBitmap->BitsLength() );
|
||||
status = B_OK;
|
||||
break;
|
||||
case B_RGB16:
|
||||
// G[2:0],B[4:0] R[4:0],G[5:3]
|
||||
for ( int32 y = 0; y < height; y ++ )
|
||||
{
|
||||
for ( int32 x = 0; x < width; x++ )
|
||||
{
|
||||
int32 srcOffset = x * 2;
|
||||
int32 dstOffset = x * 4;
|
||||
uint8 blue = srcBits[srcOffset + 0] & 0x1f;
|
||||
uint8 green = ( srcBits[srcOffset + 0] >> 5 )
|
||||
| ( ( srcBits[srcOffset + 1] & 0x07 ) << 3 );
|
||||
uint8 red = srcBits[srcOffset + 1] & 0xf8;
|
||||
// homogeneously scale each component to 8 bit
|
||||
dstBits[dstOffset + 0] = (blue << 3) | (blue >> 2);
|
||||
dstBits[dstOffset + 1] = (green << 2) | (green >> 4);
|
||||
dstBits[dstOffset + 2] = red | (red >> 5);
|
||||
}
|
||||
srcBits += srcBpr;
|
||||
dstBits += dstBpr;
|
||||
}
|
||||
status = B_OK;
|
||||
break;
|
||||
default:
|
||||
//printf("unkown colorspace: %ld\n", inBitmap->ColorSpace());
|
||||
status = B_MISMATCHED_VALUES;
|
||||
break;
|
||||
}
|
||||
if ( status == B_OK )
|
||||
{
|
||||
if ( width < outBitmap->Bounds().IntegerWidth() + 1
|
||||
|| height < outBitmap->Bounds().IntegerHeight() + 1 )
|
||||
{
|
||||
scale_bitmap( outBitmap, width, height );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// clip_float
|
||||
inline uint8
|
||||
clip_float(float value)
|
||||
{
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
if (value > 255)
|
||||
value = 255;
|
||||
return (uint8)value;
|
||||
}
|
||||
|
||||
// dim_bitmap
|
||||
status_t
|
||||
dim_bitmap(BBitmap* bitmap, rgb_color center, float dimLevel)
|
||||
{
|
||||
status_t status = B_BAD_VALUE;
|
||||
if (bitmap && bitmap->IsValid())
|
||||
{
|
||||
switch (bitmap->ColorSpace())
|
||||
{
|
||||
case B_CMAP8:
|
||||
{
|
||||
BScreen screen(B_MAIN_SCREEN_ID);
|
||||
if (screen.IsValid())
|
||||
{
|
||||
// iterate over each pixel, get the respective
|
||||
// color from the screen object, find the distance
|
||||
// to the "center" color and shorten the distance
|
||||
// by "dimLevel"
|
||||
int32 length = bitmap->BitsLength();
|
||||
uint8* bits = (uint8*)bitmap->Bits();
|
||||
for (int32 i = 0; i < length; i++)
|
||||
{
|
||||
// preserve transparent pixels
|
||||
if (bits[i] != B_TRANSPARENT_MAGIC_CMAP8)
|
||||
{
|
||||
// get color for this index
|
||||
rgb_color c = screen.ColorForIndex(bits[i]);
|
||||
// red
|
||||
float dist = (c.red - center.red) * dimLevel;
|
||||
c.red = clip_float(center.red + dist);
|
||||
// green
|
||||
dist = (c.green - center.green) * dimLevel;
|
||||
c.green = clip_float(center.green + dist);
|
||||
// blue
|
||||
dist = (c.blue - center.blue) * dimLevel;
|
||||
c.blue = clip_float(center.blue + dist);
|
||||
// write correct index of the dimmed color
|
||||
// back into bitmap (and hope the match is close...)
|
||||
bits[i] = screen.IndexForColor(c);
|
||||
}
|
||||
}
|
||||
status = B_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case B_RGB32:
|
||||
case B_RGBA32:
|
||||
{
|
||||
// iterate over each color component, find the distance
|
||||
// to the "center" color and shorten the distance
|
||||
// by "dimLevel"
|
||||
uint8* bits = (uint8*)bitmap->Bits();
|
||||
int32 bpr = bitmap->BytesPerRow();
|
||||
int32 pixels = bitmap->Bounds().IntegerWidth() + 1;
|
||||
int32 lines = bitmap->Bounds().IntegerHeight() + 1;
|
||||
// iterate over color components
|
||||
for (int32 y = 0; y < lines; y++) {
|
||||
for (int32 x = 0; x < pixels; x++) {
|
||||
int32 offset = 4 * x; // four bytes per pixel
|
||||
// blue
|
||||
float dist = (bits[offset + 0] - center.blue) * dimLevel;
|
||||
bits[offset + 0] = clip_float(center.blue + dist);
|
||||
// green
|
||||
dist = (bits[offset + 1] - center.green) * dimLevel;
|
||||
bits[offset + 1] = clip_float(center.green + dist);
|
||||
// red
|
||||
dist = (bits[offset + 2] - center.red) * dimLevel;
|
||||
bits[offset + 2] = clip_float(center.red + dist);
|
||||
// ignore alpha channel
|
||||
}
|
||||
// next line
|
||||
bits += bpr;
|
||||
}
|
||||
status = B_OK;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
status = B_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// dimmed_color_cmap8
|
||||
rgb_color
|
||||
dimmed_color_cmap8(rgb_color color, rgb_color center, float dimLevel)
|
||||
{
|
||||
BScreen screen(B_MAIN_SCREEN_ID);
|
||||
if (screen.IsValid())
|
||||
{
|
||||
// red
|
||||
float dist = (color.red - center.red) * dimLevel;
|
||||
color.red = clip_float(center.red + dist);
|
||||
// green
|
||||
dist = (color.green - center.green) * dimLevel;
|
||||
color.green = clip_float(center.green + dist);
|
||||
// blue
|
||||
dist = (color.blue - center.blue) * dimLevel;
|
||||
color.blue = clip_float(center.blue + dist);
|
||||
// get color index for dimmed color
|
||||
int32 index = screen.IndexForColor(color);
|
||||
// put color at index (closest match in palette
|
||||
// to dimmed result) into returned color
|
||||
color = screen.ColorForIndex(index);
|
||||
}
|
||||
return color;
|
||||
}
|
77
src/apps/cdplayer/DrawingTidbits.h
Normal file
77
src/apps/cdplayer/DrawingTidbits.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
// TODO: remove this file again.... It originates from Be Sample code,
|
||||
// but was added to the VLC Media Player BeOS interface, I added some stuff
|
||||
// during my work on VLC, but I am not sure anymore if this file still
|
||||
// contains work done by Tony Castley, which would be GPL!
|
||||
|
||||
#ifndef __DRAWING_TIBITS__
|
||||
#define __DRAWING_TIBITS__
|
||||
|
||||
#include <GraphicsDefs.h>
|
||||
|
||||
class BBitmap;
|
||||
|
||||
const rgb_color kBlack = { 0, 0, 0, 255 };
|
||||
const rgb_color kWhite = { 255, 255, 255, 255 };
|
||||
|
||||
rgb_color ShiftColor(rgb_color , float );
|
||||
|
||||
inline rgb_color
|
||||
Color(int32 r, int32 g, int32 b, int32 alpha = 255)
|
||||
{
|
||||
rgb_color result;
|
||||
result.red = r;
|
||||
result.green = g;
|
||||
result.blue = b;
|
||||
result.alpha = alpha;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const float kDarkness = 1.06;
|
||||
const float kDimLevel = 0.6;
|
||||
|
||||
void ReplaceColor(BBitmap *bitmap, rgb_color from, rgb_color to);
|
||||
void ReplaceTransparentColor(BBitmap *bitmap, rgb_color with);
|
||||
|
||||
// function can be used to scale the upper left part of
|
||||
// a bitmap to fill the entire bitmap, ie fromWidth
|
||||
// and fromHeight must be smaller or equal to the bitmaps size!
|
||||
// only supported colorspaces are B_RGB32 and B_RGBA32
|
||||
status_t scale_bitmap( BBitmap* bitmap,
|
||||
uint32 fromWidth, uint32 fromHeight );
|
||||
|
||||
// bitmaps need to be the same size, or this function will fail
|
||||
// currently supported conversions:
|
||||
// B_YCbCr422 -> B_RGB32
|
||||
// B_RGB32 -> B_RGB32
|
||||
// B_RGB16 -> B_RGB32
|
||||
// not yet implemented conversions:
|
||||
// B_YCbCr420 -> B_RGB32
|
||||
// B_YUV422 -> B_RGB32
|
||||
status_t convert_bitmap(BBitmap* inBitmap, BBitmap* outBitmap);
|
||||
|
||||
// dims bitmap (in place) by finding the distance of
|
||||
// the color at each pixel to the provided "center" color
|
||||
// and shortens that distance by dimLevel
|
||||
// (dimLevel < 1 -> less contrast)
|
||||
// (dimLevel > 1 -> more contrast)
|
||||
// (dimLevel < 0 -> inverted colors)
|
||||
// currently supported colorspaces:
|
||||
// B_RGB32
|
||||
// B_RGBA32
|
||||
// B_CMAP8
|
||||
status_t dim_bitmap(BBitmap* bitmap, rgb_color center,
|
||||
float dimLevel);
|
||||
|
||||
rgb_color dimmed_color_cmap8(rgb_color color, rgb_color center,
|
||||
float dimLevel);
|
||||
|
||||
#endif // __DRAWING_TIBITS__
|
@ -8,9 +8,10 @@ Application CDPlayer :
|
||||
CDPlayer.cpp
|
||||
DoubleShotDrawButton.cpp
|
||||
DrawButton.cpp
|
||||
DrawingTidbits.cpp
|
||||
PlayList.cpp
|
||||
TrackMenu.cpp
|
||||
TwoStateDrawButton.cpp
|
||||
VolumeSlider.cpp
|
||||
|
||||
: be $(SELECT_UNAME_ETC_LIB) $(NETAPI_LIB) translation textencoding
|
||||
: CDPlayer.rdef
|
||||
|
@ -1,10 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author:
|
||||
* DarkWyrm <bpmagic@columbus.rr.com>
|
||||
*/
|
||||
#include "TwoStateDrawButton.h"
|
||||
|
||||
TwoStateDrawButton::TwoStateDrawButton(BRect frame, const char *name, BBitmap *upone,
|
||||
BBitmap *downone, BBitmap *uptwo,
|
||||
BBitmap *downtwo, BMessage *msg,
|
||||
const int32 &resize, const int32 &flags)
|
||||
: BButton(frame, name, "", msg, resize, flags),
|
||||
: BButton(frame, name, "", msg, resize, flags),
|
||||
fUpOne(upone),
|
||||
fDownOne(downone),
|
||||
fUpTwo(uptwo),
|
||||
@ -14,9 +21,10 @@ TwoStateDrawButton::TwoStateDrawButton(BRect frame, const char *name, BBitmap *u
|
||||
fButtonState(true)
|
||||
|
||||
{
|
||||
fButtonState=false;
|
||||
fButtonState = false;
|
||||
}
|
||||
|
||||
|
||||
TwoStateDrawButton::~TwoStateDrawButton(void)
|
||||
{
|
||||
delete fUpOne;
|
||||
@ -27,6 +35,7 @@ TwoStateDrawButton::~TwoStateDrawButton(void)
|
||||
delete fDisabledTwo;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TwoStateDrawButton::ResizeToPreferred(void)
|
||||
{
|
||||
@ -49,9 +58,10 @@ TwoStateDrawButton::ResizeToPreferred(void)
|
||||
ResizeTo(fDisabledTwo->Bounds().Width(),fDisabledTwo->Bounds().Height());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TwoStateDrawButton::SetBitmaps(BBitmap *upone, BBitmap *downone, BBitmap *uptwo,
|
||||
BBitmap *downtwo)
|
||||
BBitmap *downtwo)
|
||||
{
|
||||
delete fUpOne;
|
||||
delete fDownOne;
|
||||
@ -64,7 +74,26 @@ TwoStateDrawButton::SetBitmaps(BBitmap *upone, BBitmap *downone, BBitmap *uptwo,
|
||||
fDownTwo = downtwo;
|
||||
}
|
||||
|
||||
void TwoStateDrawButton::SetDisabled(BBitmap *disabledone, BBitmap *disabledtwo)
|
||||
|
||||
void
|
||||
TwoStateDrawButton::SetBitmaps(const int32 state, BBitmap *up, BBitmap *down)
|
||||
{
|
||||
if (state == 0) {
|
||||
delete fUpOne;
|
||||
delete fDownOne;
|
||||
fUpOne = up;
|
||||
fDownOne = down;
|
||||
} else {
|
||||
delete fUpTwo;
|
||||
delete fDownTwo;
|
||||
fUpTwo = up;
|
||||
fDownTwo = down;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TwoStateDrawButton::SetDisabled(BBitmap *disabledone, BBitmap *disabledtwo)
|
||||
{
|
||||
delete fDisabledOne;
|
||||
delete fDisabledTwo;
|
||||
@ -73,32 +102,31 @@ void TwoStateDrawButton::SetDisabled(BBitmap *disabledone, BBitmap *disabledtwo)
|
||||
fDisabledTwo = disabledtwo;
|
||||
}
|
||||
|
||||
void TwoStateDrawButton::MouseUp(BPoint pt)
|
||||
|
||||
void
|
||||
TwoStateDrawButton::MouseUp(BPoint pt)
|
||||
{
|
||||
BButton::MouseUp(pt);
|
||||
fButtonState = fButtonState ? false : true;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TwoStateDrawButton::SetState(int32 value)
|
||||
{
|
||||
if(fButtonState!=value)
|
||||
{
|
||||
if(value==0)
|
||||
fButtonState = false;
|
||||
else
|
||||
fButtonState = true;
|
||||
if(fButtonState != value) {
|
||||
fButtonState = (value == 0) ? false : true;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void TwoStateDrawButton::Draw(BRect update)
|
||||
|
||||
void
|
||||
TwoStateDrawButton::Draw(BRect update)
|
||||
{
|
||||
if(fButtonState)
|
||||
{
|
||||
if(!IsEnabled())
|
||||
{
|
||||
if(fButtonState) {
|
||||
if(!IsEnabled()) {
|
||||
if(fDisabledTwo)
|
||||
DrawBitmap(fDisabledTwo, BPoint(0,0));
|
||||
else
|
||||
@ -106,25 +134,19 @@ void TwoStateDrawButton::Draw(BRect update)
|
||||
return;
|
||||
}
|
||||
|
||||
if(Value() == B_CONTROL_ON)
|
||||
{
|
||||
if(Value() == B_CONTROL_ON) {
|
||||
if(fDownTwo)
|
||||
DrawBitmap(fDownTwo, BPoint(0,0));
|
||||
else
|
||||
StrokeRect(Bounds());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if(fUpTwo)
|
||||
DrawBitmap(fUpTwo, BPoint(0,0));
|
||||
else
|
||||
StrokeRect(Bounds());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!IsEnabled())
|
||||
{
|
||||
} else {
|
||||
if(!IsEnabled()) {
|
||||
if(fDisabledOne)
|
||||
DrawBitmap(fDisabledOne, BPoint(0,0));
|
||||
else
|
||||
@ -132,15 +154,12 @@ void TwoStateDrawButton::Draw(BRect update)
|
||||
return;
|
||||
}
|
||||
|
||||
if(Value() == B_CONTROL_ON)
|
||||
{
|
||||
if(Value() == B_CONTROL_ON) {
|
||||
if(fDownOne)
|
||||
DrawBitmap(fDownOne, BPoint(0,0));
|
||||
else
|
||||
StrokeRect(Bounds());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if(fUpOne)
|
||||
DrawBitmap(fUpOne, BPoint(0,0));
|
||||
else
|
||||
|
@ -1,3 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2007, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author:
|
||||
* DarkWyrm <bpmagic@columbus.rr.com>
|
||||
*/
|
||||
#ifndef _TWOSTATE_DRAWBUTTON_H
|
||||
#define _TWOSTATE_DRAWBUTTON_H
|
||||
|
||||
@ -20,10 +27,10 @@ public:
|
||||
|
||||
void SetBitmaps(BBitmap *upone, BBitmap *downone, BBitmap *uptwo,
|
||||
BBitmap *downtwo);
|
||||
void SetBitmaps(const int32 state, BBitmap *up, BBitmap *down);
|
||||
void ResizeToPreferred(void);
|
||||
void SetDisabled(BBitmap *disabledone, BBitmap *disabledtwo);
|
||||
void MouseUp(BPoint pt);
|
||||
// void MessageReceived(BMessage *msg);
|
||||
|
||||
int32 GetState(void) { return fButtonState ? 1 : 0; };
|
||||
void SetState(int32 value);
|
||||
|
317
src/apps/cdplayer/VolumeSlider.cpp
Normal file
317
src/apps/cdplayer/VolumeSlider.cpp
Normal file
@ -0,0 +1,317 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
// NOTE: Based on my code in the BeOS interface for the VLC media player
|
||||
// that I did during the VLC 0.4.3 - 0.4.6 times. Code not done by me
|
||||
// removed. -Stephan Aßmus
|
||||
|
||||
#include "VolumeSlider.h"
|
||||
|
||||
#include "ButtonBitmaps.h"
|
||||
#include "DrawingTidbits.h"
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Screen.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// slider colors are hardcoded here, because that's just
|
||||
// what they currently are within those bitmaps
|
||||
const rgb_color kGreen = (rgb_color){ 152, 203, 152, 255 };
|
||||
const rgb_color kGreenShadow = (rgb_color){ 102, 152, 102, 255 };
|
||||
const rgb_color kBackground = (rgb_color){ 216, 216, 216, 255 };
|
||||
const rgb_color kSeekGreen = (rgb_color){ 171, 221, 161, 255 };
|
||||
const rgb_color kSeekGreenShadow = (rgb_color){ 144, 186, 136, 255 };
|
||||
const rgb_color kSeekRed = (rgb_color){ 255, 0, 0, 255 };
|
||||
const rgb_color kSeekRedLight = (rgb_color){ 255, 152, 152, 255 };
|
||||
const rgb_color kSeekRedShadow = (rgb_color){ 178, 0, 0, 255 };
|
||||
|
||||
#define DIM_LEVEL 0.4
|
||||
|
||||
// constructor
|
||||
VolumeSlider::VolumeSlider(BRect frame, const char* name,
|
||||
int32 minValue, int32 maxValue,
|
||||
BMessage* message, BHandler* target)
|
||||
: BControl(frame, name, NULL, message, B_FOLLOW_LEFT | B_FOLLOW_TOP,
|
||||
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
|
||||
fLeftSideBits(NULL),
|
||||
fRightSideBits(NULL),
|
||||
fKnobBits(NULL),
|
||||
fTracking(false),
|
||||
fMuted(false),
|
||||
fMinValue(minValue),
|
||||
fMaxValue(maxValue)
|
||||
{
|
||||
SetTarget(target);
|
||||
|
||||
// create bitmaps
|
||||
BRect r(0.0, 0.0,
|
||||
kVolumeSliderBitmapWidth - 1, kVolumeSliderBitmapHeight - 1);
|
||||
fLeftSideBits = new BBitmap(r, B_CMAP8);
|
||||
fRightSideBits = new BBitmap(r, B_CMAP8);
|
||||
r.Set(0.0, 0.0,
|
||||
kVolumeSliderKnobWidth - 1, kVolumeSliderKnobHeight - 1);
|
||||
fKnobBits = new BBitmap(r, B_CMAP8);
|
||||
|
||||
_MakeBitmaps();
|
||||
}
|
||||
|
||||
// destructor
|
||||
VolumeSlider::~VolumeSlider()
|
||||
{
|
||||
delete fLeftSideBits;
|
||||
delete fRightSideBits;
|
||||
delete fKnobBits;
|
||||
}
|
||||
|
||||
// AttachedToWindow
|
||||
void
|
||||
VolumeSlider::AttachedToWindow()
|
||||
{
|
||||
BControl::AttachedToWindow();
|
||||
SetViewColor(B_TRANSPARENT_COLOR);
|
||||
}
|
||||
|
||||
// SetValue
|
||||
void
|
||||
VolumeSlider::SetValue(int32 value)
|
||||
{
|
||||
if (value == Value())
|
||||
return;
|
||||
|
||||
BControl::SetValue(value);
|
||||
Invoke();
|
||||
}
|
||||
|
||||
// SetEnabled
|
||||
void
|
||||
VolumeSlider::SetEnabled(bool enable)
|
||||
{
|
||||
if (enable == IsEnabled())
|
||||
return;
|
||||
|
||||
BControl::SetEnabled(enable);
|
||||
|
||||
_MakeBitmaps();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
// Draw
|
||||
void
|
||||
VolumeSlider::Draw(BRect updateRect)
|
||||
{
|
||||
if (!IsValid()) {
|
||||
fprintf(stderr, "VolumeSlider::Draw() - Error: no valid bitmaps!");
|
||||
SetHighColor(255, 0, 0);
|
||||
FillRect(updateRect);
|
||||
return;
|
||||
}
|
||||
|
||||
BRect r(Bounds());
|
||||
float sliderSideWidth = kVolumeSliderBitmapWidth;
|
||||
float sliderStart = (r.left + sliderSideWidth);
|
||||
float sliderEnd = (r.right - sliderSideWidth);
|
||||
float knobPos = sliderStart
|
||||
+ (sliderEnd - sliderStart - 1.0) * (Value() - fMinValue)
|
||||
/ (fMaxValue - fMinValue);
|
||||
// draw both sides (the original from Be doesn't seem
|
||||
// to make a difference for enabled/disabled state)
|
||||
DrawBitmapAsync(fLeftSideBits, r.LeftTop());
|
||||
DrawBitmapAsync(fRightSideBits, BPoint(sliderEnd + 1.0, r.top));
|
||||
// colors for the slider area between the two bitmaps
|
||||
rgb_color background = kBackground;//ui_color(B_PANEL_BACKGROUND_COLOR);
|
||||
rgb_color shadow = tint_color(background, B_DARKEN_2_TINT);
|
||||
rgb_color softShadow = tint_color(background, B_DARKEN_1_TINT);
|
||||
rgb_color darkShadow = tint_color(background, B_DARKEN_4_TINT);
|
||||
rgb_color midShadow = tint_color(background, B_DARKEN_3_TINT);
|
||||
rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
|
||||
rgb_color softLight = tint_color(background, B_LIGHTEN_1_TINT);
|
||||
rgb_color green = kGreen;
|
||||
rgb_color greenShadow = kGreenShadow;
|
||||
rgb_color black = kBlack;
|
||||
rgb_color dotGrey = midShadow;
|
||||
rgb_color dotGreen = greenShadow;
|
||||
// make dimmed version of colors if we're disabled
|
||||
if (!IsEnabled()) {
|
||||
shadow = (rgb_color){ 200, 200, 200, 255 };
|
||||
softShadow = dimmed_color_cmap8(softShadow, background, DIM_LEVEL);
|
||||
darkShadow = dimmed_color_cmap8(darkShadow, background, DIM_LEVEL);
|
||||
midShadow = shadow;
|
||||
light = dimmed_color_cmap8(light, background, DIM_LEVEL);
|
||||
softLight = dimmed_color_cmap8(softLight, background, DIM_LEVEL);
|
||||
green = dimmed_color_cmap8(green, background, DIM_LEVEL);
|
||||
greenShadow = dimmed_color_cmap8(greenShadow, background, DIM_LEVEL);
|
||||
black = dimmed_color_cmap8(black, background, DIM_LEVEL);
|
||||
dotGreen = dotGrey;
|
||||
} else if (fMuted) {
|
||||
green = tint_color(kBackground, B_DARKEN_3_TINT);
|
||||
greenShadow = tint_color(kBackground, B_DARKEN_4_TINT);
|
||||
dotGreen = greenShadow;
|
||||
}
|
||||
// draw slider edges between bitmaps
|
||||
BeginLineArray(7);
|
||||
AddLine(BPoint(sliderStart, r.top),
|
||||
BPoint(sliderEnd, r.top), softShadow);
|
||||
AddLine(BPoint(sliderStart, r.bottom),
|
||||
BPoint(sliderEnd, r.bottom), softLight);
|
||||
r.InsetBy(0.0, 1.0);
|
||||
AddLine(BPoint(sliderStart, r.top),
|
||||
BPoint(sliderEnd, r.top), black);
|
||||
AddLine(BPoint(sliderStart, r.bottom),
|
||||
BPoint(sliderEnd, r.bottom), light);
|
||||
r.top++;
|
||||
AddLine(BPoint(sliderStart, r.top),
|
||||
BPoint(knobPos, r.top), greenShadow);
|
||||
AddLine(BPoint(knobPos, r.top),
|
||||
BPoint(sliderEnd, r.top), midShadow);
|
||||
r.top++;
|
||||
AddLine(BPoint(sliderStart, r.top),
|
||||
BPoint(knobPos, r.top), greenShadow);
|
||||
EndLineArray();
|
||||
// fill rest inside of slider
|
||||
r.InsetBy(0.0, 1.0);
|
||||
r.left = sliderStart;
|
||||
r.right = knobPos;
|
||||
SetHighColor(green);
|
||||
FillRect(r, B_SOLID_HIGH);
|
||||
r.left = knobPos + 1.0;
|
||||
r.right = sliderEnd;
|
||||
r.top -= 1.0;
|
||||
SetHighColor(shadow);
|
||||
FillRect(r, B_SOLID_HIGH);
|
||||
// draw little dots inside
|
||||
int32 dotCount = (int32)((sliderEnd - sliderStart) / 5.0);
|
||||
BPoint dotPos;
|
||||
dotPos.y = r.top + 4.0;
|
||||
for (int32 i = 0; i < dotCount; i++) {
|
||||
dotPos.x = sliderStart + i * 5.0 + 4.0;
|
||||
SetHighColor(dotPos.x < knobPos ? dotGreen : dotGrey);
|
||||
StrokeLine(dotPos, BPoint(dotPos.x, dotPos.y + 1.0));
|
||||
}
|
||||
// draw knob
|
||||
r.top -= 1.0;
|
||||
SetDrawingMode(B_OP_OVER); // part of knob is transparent
|
||||
DrawBitmapAsync(fKnobBits, BPoint(knobPos - kVolumeSliderKnobWidth / 2, r.top));
|
||||
}
|
||||
|
||||
// MouseDown
|
||||
void
|
||||
VolumeSlider::MouseDown(BPoint where)
|
||||
{
|
||||
if (Bounds().Contains(where) && IsEnabled()) {
|
||||
fTracking = true;
|
||||
SetValue(_ValueFor(where.x));
|
||||
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
|
||||
}
|
||||
}
|
||||
|
||||
// MouseMoved
|
||||
void
|
||||
VolumeSlider::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
|
||||
{
|
||||
if (fTracking)
|
||||
SetValue(_ValueFor(where.x));
|
||||
}
|
||||
|
||||
// MouseUp
|
||||
void
|
||||
VolumeSlider::MouseUp(BPoint where)
|
||||
{
|
||||
fTracking = false;
|
||||
}
|
||||
|
||||
// IsValid
|
||||
bool
|
||||
VolumeSlider::IsValid() const
|
||||
{
|
||||
return (fLeftSideBits && fLeftSideBits->IsValid()
|
||||
&& fRightSideBits && fRightSideBits->IsValid()
|
||||
&& fKnobBits && fKnobBits->IsValid());
|
||||
}
|
||||
|
||||
// SetMuted
|
||||
void
|
||||
VolumeSlider::SetMuted(bool mute)
|
||||
{
|
||||
if (mute == fMuted)
|
||||
return;
|
||||
|
||||
fMuted = mute;
|
||||
_MakeBitmaps();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
// _MakeBitmaps
|
||||
void
|
||||
VolumeSlider::_MakeBitmaps()
|
||||
{
|
||||
if (!IsValid())
|
||||
return;
|
||||
|
||||
// left side of slider
|
||||
memcpy(fLeftSideBits->Bits(), kVolumeSliderLeftBitmapBits,
|
||||
fLeftSideBits->BitsLength());
|
||||
// right side of slider
|
||||
memcpy(fRightSideBits->Bits(), kVolumeSliderRightBits,
|
||||
fRightSideBits->BitsLength());
|
||||
// slider knob
|
||||
int32 length = fKnobBits->BitsLength();
|
||||
memcpy(fKnobBits->Bits(), kVolumeSliderKnobBits, length);
|
||||
uint8* bits = (uint8*)fKnobBits->Bits();
|
||||
// black was used in the knob to represent transparency
|
||||
// use screen to get index for the "transarent" color used in the bitmap
|
||||
BScreen screen(B_MAIN_SCREEN_ID);
|
||||
uint8 blackIndex = screen.IndexForColor(kBlack);
|
||||
// replace black index with transparent index
|
||||
for (int32 i = 0; i < length; i++)
|
||||
if (bits[i] == blackIndex)
|
||||
bits[i] = B_TRANSPARENT_MAGIC_CMAP8;
|
||||
|
||||
if (!IsEnabled()) {
|
||||
// make ghosted versions of the bitmaps
|
||||
dim_bitmap(fLeftSideBits, kBackground, DIM_LEVEL);
|
||||
dim_bitmap(fRightSideBits, kBackground, DIM_LEVEL);
|
||||
dim_bitmap(fKnobBits, kBackground, DIM_LEVEL);
|
||||
} else if (fMuted) {
|
||||
// replace green color (and shadow) in left slider side
|
||||
bits = (uint8*)fLeftSideBits->Bits();
|
||||
length = fLeftSideBits->BitsLength();
|
||||
uint8 greenIndex = screen.IndexForColor(kGreen);
|
||||
uint8 greenShadowIndex = screen.IndexForColor(kGreenShadow);
|
||||
rgb_color shadow = tint_color(kBackground, B_DARKEN_3_TINT);
|
||||
rgb_color midShadow = tint_color(kBackground, B_DARKEN_4_TINT);
|
||||
uint8 replaceIndex = screen.IndexForColor(shadow);
|
||||
uint8 replaceShadowIndex = screen.IndexForColor(midShadow);
|
||||
for (int32 i = 0; i < length; i++) {
|
||||
if (bits[i] == greenIndex)
|
||||
bits[i] = replaceIndex;
|
||||
else if (bits[i] == greenShadowIndex)
|
||||
bits[i] = replaceShadowIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// _ValueFor
|
||||
int32
|
||||
VolumeSlider::_ValueFor(float xPos) const
|
||||
{
|
||||
BRect r(Bounds());
|
||||
float sliderStart = (r.left + kVolumeSliderBitmapWidth);
|
||||
float sliderEnd = (r.right - kVolumeSliderBitmapWidth);
|
||||
int32 value = fMinValue + (int32)(((xPos - sliderStart)
|
||||
* (fMaxValue - fMinValue))
|
||||
/ (sliderEnd - sliderStart - 1.0));
|
||||
if (value < fMinValue)
|
||||
value = fMinValue;
|
||||
if (value > fMaxValue)
|
||||
value = fMaxValue;
|
||||
return value;
|
||||
}
|
||||
|
55
src/apps/cdplayer/VolumeSlider.h
Normal file
55
src/apps/cdplayer/VolumeSlider.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
#ifndef VOLUME_SLIDER_H
|
||||
#define VOLUME_SLIDER_H
|
||||
|
||||
#include <Control.h>
|
||||
|
||||
class VolumeSlider : public BControl {
|
||||
public:
|
||||
VolumeSlider(BRect frame,
|
||||
const char* name,
|
||||
int32 minValue,
|
||||
int32 maxValue,
|
||||
BMessage* message = NULL,
|
||||
BHandler* target = NULL);
|
||||
|
||||
virtual ~VolumeSlider();
|
||||
|
||||
// BControl
|
||||
virtual void AttachedToWindow();
|
||||
virtual void SetValue(int32 value);
|
||||
virtual void SetEnabled(bool enable);
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual void MouseDown(BPoint where);
|
||||
virtual void MouseMoved(BPoint where, uint32 transit,
|
||||
const BMessage* dragMessage);
|
||||
virtual void MouseUp(BPoint where);
|
||||
|
||||
// VolumeSlider
|
||||
bool IsValid() const;
|
||||
void SetMuted(bool mute);
|
||||
bool IsMuted() const
|
||||
{ return fMuted; }
|
||||
|
||||
private:
|
||||
void _MakeBitmaps();
|
||||
void _DimBitmap(BBitmap* bitmap);
|
||||
int32 _ValueFor(float xPos) const;
|
||||
|
||||
BBitmap* fLeftSideBits;
|
||||
BBitmap* fRightSideBits;
|
||||
BBitmap* fKnobBits;
|
||||
bool fTracking;
|
||||
bool fMuted;
|
||||
int32 fMinValue;
|
||||
int32 fMaxValue;
|
||||
};
|
||||
|
||||
#endif // VOLUME_SLIDER_H
|
Loading…
Reference in New Issue
Block a user