#include "MediaListItem.h"
#include <string.h>
#include <MediaAddOn.h>
#include <View.h>
#include "MediaIcons.h"
#include "MediaWindow.h"
#include "MidiSettingsView.h"
#define kITEM_MARGIN 1
#define GREATER_THAN -1
#define LESS_THAN 1
MediaIcons* MediaListItem::sIcons = NULL;
struct MediaListItem::Renderer {
Renderer()
:
fTitle(NULL),
fPrimaryIcon(NULL),
fSecondaryIcon(NULL),
fDoubleInsets(true),
fSelected(false)
{
}
void AddIcon(BBitmap* icon)
{
if (!fPrimaryIcon)
fPrimaryIcon = icon;
else {
fSecondaryIcon = fPrimaryIcon;
fPrimaryIcon = icon;
}
}
void SetTitle(const char* title)
{
fTitle = title;
}
void SetSelected(bool selected)
{
fSelected = selected;
}
void UseDoubleInset(bool doubleInset)
{
fDoubleInsets = doubleInset;
}
void Render(BView* onto, BRect frame, bool complete = false)
{
const rgb_color lowColor = onto->LowColor();
const rgb_color highColor = onto->HighColor();
if (fSelected || complete) {
if (fSelected)
onto->SetLowColor(ui_color(B_LIST_SELECTED_BACKGROUND_COLOR));
onto->FillRect(frame, B_SOLID_LOW);
}
BPoint point(frame.left + 4.0f,
frame.top + (frame.Height() - MediaIcons::sBounds.Height()) / 2.0f);
BRect iconFrame(MediaIcons::IconRectAt(point + BPoint(1, 0)));
onto->SetDrawingMode(B_OP_OVER);
if (fPrimaryIcon && !fDoubleInsets) {
onto->DrawBitmap(fPrimaryIcon, iconFrame);
point.x = iconFrame.right + 1;
} else if (fSecondaryIcon) {
onto->DrawBitmap(fSecondaryIcon, iconFrame);
}
iconFrame = MediaIcons::IconRectAt(iconFrame.RightTop() + BPoint(1, 0));
if (fDoubleInsets) {
if (fPrimaryIcon != NULL)
onto->DrawBitmap(fPrimaryIcon, iconFrame);
point.x = iconFrame.right + 1;
}
onto->SetDrawingMode(B_OP_COPY);
BFont font = be_plain_font;
font_height fontInfo;
font.GetHeight(&fontInfo);
onto->SetFont(&font);
onto->MovePenTo(point.x + 8, frame.top
+ fontInfo.ascent + (frame.Height()
- ceilf(fontInfo.ascent + fontInfo.descent)) / 2.0f);
onto->DrawString(fTitle);
onto->SetHighColor(highColor);
onto->SetLowColor(lowColor);
}
float ItemWidth()
{
float width = 4.0f;
float iconSpace = MediaIcons::sBounds.Width() + 1.0f;
if (fDoubleInsets)
iconSpace *= 2.0f;
width += iconSpace;
width += 8.0f;
width += be_plain_font->StringWidth(fTitle) + 16.0f;
return width;
}
private:
const char* fTitle;
BBitmap* fPrimaryIcon;
BBitmap* fSecondaryIcon;
bool fDoubleInsets;
bool fSelected;
};
MediaListItem::MediaListItem()
:
BListItem((uint32)0)
{
}
void
MediaListItem::Update(BView* owner, const BFont* font)
{
BListItem::Update(owner, font);
float iconHeight = MediaIcons::sBounds.Height() + 1;
if ((Height() < iconHeight + kITEM_MARGIN * 2)) {
SetHeight(iconHeight + kITEM_MARGIN * 2);
}
Renderer renderer;
renderer.SetTitle(Label());
SetRenderParameters(renderer);
SetWidth(renderer.ItemWidth());
}
void
MediaListItem::DrawItem(BView* owner, BRect frame, bool complete)
{
Renderer renderer;
renderer.SetSelected(IsSelected());
renderer.SetTitle(Label());
SetRenderParameters(renderer);
renderer.Render(owner, frame, complete);
}
int
MediaListItem::Compare(const void* itemOne, const void* itemTwo)
{
MediaListItem* firstItem = *(MediaListItem**)itemOne;
MediaListItem* secondItem = *(MediaListItem**)itemTwo;
return firstItem->CompareWith(secondItem);
}
NodeListItem::NodeListItem(const dormant_node_info* node, media_type type)
:
MediaListItem(),
fNodeInfo(node),
fMediaType(type),
fIsDefaultInput(false),
fIsDefaultOutput(false)
{
}
void
NodeListItem::SetRenderParameters(MediaListItem::Renderer& renderer)
{
MediaIcons::IconSet* iconSet = &Icons()->videoIcons;
if (fMediaType == MediaListItem::AUDIO_TYPE)
iconSet = &Icons()->audioIcons;
if (fIsDefaultInput)
renderer.AddIcon(&iconSet->inputIcon);
if (fIsDefaultOutput)
renderer.AddIcon(&iconSet->outputIcon);
}
const char*
NodeListItem::Label()
{
return fNodeInfo->name;
}
void
NodeListItem::SetMediaType(media_type type)
{
fMediaType = type;
}
void
NodeListItem::SetDefaultOutput(bool isDefault)
{
fIsDefaultOutput = isDefault;
}
void
NodeListItem::SetDefaultInput(bool isDefault)
{
fIsDefaultInput = isDefault;
}
void
NodeListItem::AlterWindow(MediaWindow* window)
{
window->SelectNode(fNodeInfo);
}
void
NodeListItem::Accept(MediaListItem::Visitor& visitor)
{
visitor.Visit(this);
}
int
NodeListItem::CompareWith(MediaListItem* item)
{
Comparator comparator(this);
item->Accept(comparator);
return comparator.result;
}
NodeListItem::Comparator::Comparator(NodeListItem* compareOthersTo)
:
result(GREATER_THAN),
fTarget(compareOthersTo)
{
}
void
NodeListItem::Comparator::Visit(NodeListItem* item)
{
result = GREATER_THAN;
if (fTarget->Type() != item->Type() && fTarget->Type() == VIDEO_TYPE)
result = LESS_THAN;
else
result = strcmp(fTarget->Label(), item->Label());
}
void
NodeListItem::Comparator::Visit(DeviceListItem* item)
{
result = LESS_THAN;
if (fTarget->Type() != item->Type() && fTarget->Type() == AUDIO_TYPE)
result = GREATER_THAN;
}
void
NodeListItem::Comparator::Visit(AudioMixerListItem* item)
{
result = LESS_THAN;
}
void
NodeListItem::Comparator::Visit(MidiListItem* item)
{
result = GREATER_THAN;
}
DeviceListItem::DeviceListItem(const char* title,
MediaListItem::media_type type)
:
MediaListItem(),
fTitle(title),
fMediaType(type)
{
}
void
DeviceListItem::Accept(MediaListItem::Visitor& visitor)
{
visitor.Visit(this);
}
int
DeviceListItem::CompareWith(MediaListItem* item)
{
Comparator comparator(this);
item->Accept(comparator);
return comparator.result;
}
DeviceListItem::Comparator::Comparator(DeviceListItem* compareOthersTo)
:
result(GREATER_THAN),
fTarget(compareOthersTo)
{
}
void
DeviceListItem::Comparator::Visit(NodeListItem* item)
{
result = GREATER_THAN;
if (fTarget->Type() != item->Type() && fTarget->Type() == AUDIO_TYPE)
result = LESS_THAN;
}
void
DeviceListItem::Comparator::Visit(DeviceListItem* item)
{
result = LESS_THAN;
if (fTarget->Type() == AUDIO_TYPE)
result = GREATER_THAN;
}
void
DeviceListItem::Comparator::Visit(AudioMixerListItem* item)
{
result = LESS_THAN;
if (fTarget->Type() == AUDIO_TYPE)
result = GREATER_THAN;
}
void
DeviceListItem::Comparator::Visit(MidiListItem* item)
{
result = LESS_THAN;
}
void
DeviceListItem::SetRenderParameters(Renderer& renderer)
{
renderer.AddIcon(&Icons()->devicesIcon);
renderer.UseDoubleInset(false);
}
void
DeviceListItem::AlterWindow(MediaWindow* window)
{
if (fMediaType == MediaListItem::AUDIO_TYPE)
window->SelectAudioSettings(fTitle);
else
window->SelectVideoSettings(fTitle);
}
AudioMixerListItem::AudioMixerListItem(const char* title)
:
MediaListItem(),
fTitle(title)
{
}
void
AudioMixerListItem::AlterWindow(MediaWindow* window)
{
window->SelectAudioMixer(fTitle);
}
void
AudioMixerListItem::Accept(MediaListItem::Visitor& visitor)
{
visitor.Visit(this);
}
int
AudioMixerListItem::CompareWith(MediaListItem* item)
{
Comparator comparator(this);
item->Accept(comparator);
return comparator.result;
}
AudioMixerListItem::Comparator::Comparator(AudioMixerListItem* compareOthersTo)
:
result(0),
fTarget(compareOthersTo)
{
}
void
AudioMixerListItem::Comparator::Visit(NodeListItem* item)
{
result = GREATER_THAN;
}
void
AudioMixerListItem::Comparator::Visit(DeviceListItem* item)
{
result = GREATER_THAN;
if (item->Type() == AUDIO_TYPE)
result = LESS_THAN;
}
void
AudioMixerListItem::Comparator::Visit(AudioMixerListItem* item)
{
result = 0;
}
void
AudioMixerListItem::Comparator::Visit(MidiListItem* item)
{
result = GREATER_THAN;
}
void
AudioMixerListItem::SetRenderParameters(Renderer& renderer)
{
renderer.AddIcon(&Icons()->mixerIcon);
}
MidiListItem::MidiListItem(const char* title)
:
MediaListItem(),
fTitle(title)
{
}
void
MidiListItem::AlterWindow(MediaWindow* window)
{
window->SelectMidiSettings(fTitle);
}
const char*
MidiListItem::Label()
{
return "MIDI";
}
void
MidiListItem::Accept(MediaListItem::Visitor& visitor)
{
visitor.Visit(this);
}
int
MidiListItem::CompareWith(MediaListItem* item)
{
Comparator comparator(this);
item->Accept(comparator);
return comparator.result;
}
MidiListItem::Comparator::Comparator(MidiListItem* compareOthersTo)
:
result(0),
fTarget(compareOthersTo)
{
}
void
MidiListItem::Comparator::Visit(NodeListItem* item)
{
result = GREATER_THAN;
}
void
MidiListItem::Comparator::Visit(DeviceListItem* item)
{
result = GREATER_THAN;
if (item->Type() == AUDIO_TYPE)
result = LESS_THAN;
}
void
MidiListItem::Comparator::Visit(AudioMixerListItem* item)
{
result = LESS_THAN;
}
void
MidiListItem::Comparator::Visit(MidiListItem* item)
{
result = 0;
}
void
MidiListItem::SetRenderParameters(Renderer& renderer)
{
renderer.AddIcon(&Icons()->mixerIcon);
}