In Media preflet:
* Refactor MediaListItem into four/five classes: * MediaListItem : abstract base class which provides an interface for MediaWindow and MediaListItem subclasses * NodeListItem : list item for media nodes * DeviceListItem : list item for audio/video settings (device selection) * MixerListItem : list item for the audio-mixer * MediaListItem::Renderer : does the drawing of MediaListItems, which supply render paramaters via a 'SetRenderParamaters()' method. * Comparison of MediaListItems (for sorting) is done via double-dispatch * MediaListItem provides a pure virtual AlterWindow() method, which removes the burden of distinguishing between different behaviours from MediaWindow. * Add methods to MediaWindow for the MediaListItems to call in their AlterWindow() implementation, eg. SelectNode() * Seperate code into these methods, as well as a few private utility methods. * Add a RAII-style 'SmartNode' nested class for MediaWindow, which handles watching/unwatching allocating/deallocating of media_nodes git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39433 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
Media::Media()
|
Media::Media()
|
||||||
:
|
:
|
||||||
BApplication("application/x-vnd.Haiku-Media"),
|
BApplication("application/x-vnd.Haiku-Media"),
|
||||||
|
fIcons(),
|
||||||
fWindow(NULL)
|
fWindow(NULL)
|
||||||
{
|
{
|
||||||
BRect rect(32, 64, 637, 462);
|
BRect rect(32, 64, 637, 462);
|
||||||
@@ -57,6 +58,7 @@ Media::Media()
|
|||||||
}
|
}
|
||||||
|
|
||||||
fWindow = new MediaWindow(rect);
|
fWindow = new MediaWindow(rect);
|
||||||
|
MediaListItem::SetIcons(&fIcons);
|
||||||
|
|
||||||
be_roster->StartWatching(BMessenger(this));
|
be_roster->StartWatching(BMessenger(this));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public:
|
|||||||
status_t InitCheck();
|
status_t InitCheck();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
MediaIcons fIcons;
|
||||||
MediaWindow* fWindow;
|
MediaWindow* fWindow;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,14 +15,20 @@
|
|||||||
|
|
||||||
const BRect MediaIcons::sBounds(0, 0, 15, 15);
|
const BRect MediaIcons::sBounds(0, 0, 15, 15);
|
||||||
|
|
||||||
|
|
||||||
|
MediaIcons::IconSet::IconSet()
|
||||||
|
:
|
||||||
|
inputIcon(MediaIcons::sBounds, B_CMAP8),
|
||||||
|
outputIcon(MediaIcons::sBounds, B_CMAP8)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MediaIcons::MediaIcons()
|
MediaIcons::MediaIcons()
|
||||||
:
|
:
|
||||||
devicesIcon(sBounds, B_CMAP8),
|
devicesIcon(sBounds, B_CMAP8),
|
||||||
mixerIcon(sBounds, B_CMAP8),
|
mixerIcon(sBounds, B_CMAP8)
|
||||||
tvIcon(sBounds, B_CMAP8),
|
|
||||||
camIcon(sBounds, B_CMAP8),
|
|
||||||
micIcon(sBounds, B_CMAP8),
|
|
||||||
speakerIcon(sBounds, B_CMAP8)
|
|
||||||
{
|
{
|
||||||
app_info info;
|
app_info info;
|
||||||
be_app->GetAppInfo(&info);
|
be_app->GetAppInfo(&info);
|
||||||
@@ -32,10 +38,10 @@ MediaIcons::MediaIcons()
|
|||||||
|
|
||||||
_LoadBitmap(&resources, devices_icon, &devicesIcon);
|
_LoadBitmap(&resources, devices_icon, &devicesIcon);
|
||||||
_LoadBitmap(&resources, mixer_icon, &mixerIcon);
|
_LoadBitmap(&resources, mixer_icon, &mixerIcon);
|
||||||
_LoadBitmap(&resources, tv_icon, &tvIcon);
|
_LoadBitmap(&resources, tv_icon, &videoIcons.outputIcon);
|
||||||
_LoadBitmap(&resources, cam_icon, &camIcon);
|
_LoadBitmap(&resources, cam_icon, &videoIcons.inputIcon);
|
||||||
_LoadBitmap(&resources, mic_icon, &micIcon);
|
_LoadBitmap(&resources, mic_icon, &audioIcons.inputIcon);
|
||||||
_LoadBitmap(&resources, speaker_icon, &speakerIcon);
|
_LoadBitmap(&resources, speaker_icon, &audioIcons.outputIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,18 +14,26 @@ class BResources;
|
|||||||
struct MediaIcons {
|
struct MediaIcons {
|
||||||
MediaIcons();
|
MediaIcons();
|
||||||
|
|
||||||
|
struct IconSet {
|
||||||
|
IconSet();
|
||||||
|
|
||||||
|
BBitmap inputIcon;
|
||||||
|
BBitmap outputIcon;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
BBitmap devicesIcon;
|
BBitmap devicesIcon;
|
||||||
BBitmap mixerIcon;
|
BBitmap mixerIcon;
|
||||||
BBitmap tvIcon;
|
|
||||||
BBitmap camIcon;
|
|
||||||
BBitmap micIcon;
|
|
||||||
BBitmap speakerIcon;
|
|
||||||
|
|
||||||
BRect IconRectAt(const BPoint& topLeft);
|
IconSet audioIcons;
|
||||||
private:
|
IconSet videoIcons;
|
||||||
|
|
||||||
|
static BRect IconRectAt(const BPoint& topLeft);
|
||||||
|
|
||||||
static const BRect sBounds;
|
static const BRect sBounds;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
void _LoadBitmap(BResources* resources, int32 id,
|
void _LoadBitmap(BResources* resources, int32 id,
|
||||||
BBitmap* bitmap);
|
BBitmap* bitmap);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,173 +12,384 @@
|
|||||||
// Created : June 25, 2003
|
// Created : June 25, 2003
|
||||||
//
|
//
|
||||||
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||||
|
|
||||||
|
|
||||||
#include "MediaListItem.h"
|
#include "MediaListItem.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <MediaAddOn.h>
|
||||||
#include <View.h>
|
#include <View.h>
|
||||||
|
|
||||||
#include "MediaIcons.h"
|
#include "MediaIcons.h"
|
||||||
|
#include "MediaWindow.h"
|
||||||
|
|
||||||
|
|
||||||
#define kITEM_MARGIN 1
|
#define kITEM_MARGIN 1
|
||||||
|
#define GREATER_THAN -1
|
||||||
|
#define LESS_THAN 1
|
||||||
|
|
||||||
|
|
||||||
MediaListItem::MediaListItem(dormant_node_info* info, uint32 level,
|
MediaIcons* MediaListItem::sIcons = NULL;
|
||||||
bool isVideo, MediaIcons* icons, uint32 modifiers)
|
|
||||||
|
|
||||||
|
struct MediaListItem::Renderer {
|
||||||
|
Renderer()
|
||||||
:
|
:
|
||||||
BListItem(level),
|
fTitle(NULL),
|
||||||
fInfo(info),
|
fPrimaryIcon(NULL),
|
||||||
fLabel(info->name),
|
fSecondaryIcon(NULL),
|
||||||
fIsAudioMixer(false),
|
fDoubleInsets(true),
|
||||||
fIsVideo(isVideo),
|
fSelected(false)
|
||||||
fIsDefaultInput(false),
|
|
||||||
fIsDefaultOutput(false),
|
|
||||||
fIcons(icons)
|
|
||||||
{
|
|
||||||
SetHeight(16 + kITEM_MARGIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MediaListItem::MediaListItem(const char* label, uint32 level,
|
|
||||||
bool isVideo, MediaIcons* icons, uint32 modifiers)
|
|
||||||
:
|
|
||||||
BListItem(level),
|
|
||||||
fInfo(NULL),
|
|
||||||
fLabel(label),
|
|
||||||
fIsAudioMixer(false),
|
|
||||||
fIsVideo(isVideo),
|
|
||||||
fIsDefaultInput(false),
|
|
||||||
fIsDefaultOutput(false),
|
|
||||||
fIcons(icons)
|
|
||||||
{
|
|
||||||
SetHeight(16 + kITEM_MARGIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MediaListItem::~MediaListItem()
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The first icon added is drawn next to the label,
|
||||||
//MediaListItem - DrawItem
|
// the second is drawn to the right of the label.
|
||||||
void
|
void AddIcon(BBitmap* icon)
|
||||||
MediaListItem::DrawItem(BView* owner, BRect frame, bool complete)
|
|
||||||
{
|
{
|
||||||
rgb_color kHighlight = { 140,140,140,0 };
|
if (!fPrimaryIcon)
|
||||||
rgb_color kBlack = { 0,0,0,0 };
|
fPrimaryIcon = icon;
|
||||||
|
else {
|
||||||
BRect r(frame);
|
fSecondaryIcon = fPrimaryIcon;
|
||||||
|
fPrimaryIcon = icon;
|
||||||
if (IsSelected() || complete) {
|
|
||||||
rgb_color color;
|
|
||||||
if (IsSelected()) {
|
|
||||||
color = kHighlight;
|
|
||||||
} else {
|
|
||||||
color = owner->ViewColor();
|
|
||||||
}
|
}
|
||||||
owner->SetHighColor(color);
|
}
|
||||||
owner->SetLowColor(color);
|
|
||||||
owner->FillRect(r);
|
void SetTitle(const char* title)
|
||||||
owner->SetHighColor(kBlack);
|
{
|
||||||
} else {
|
fTitle = title;
|
||||||
owner->SetLowColor(owner->ViewColor());
|
}
|
||||||
|
|
||||||
|
void SetSelected(bool selected)
|
||||||
|
{
|
||||||
|
fSelected = selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set whether or not to leave enough room for two icons,
|
||||||
|
// defaults to true.
|
||||||
|
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();
|
||||||
|
const rgb_color kBlack = {0, 0, 0, 255};
|
||||||
|
|
||||||
|
if (fSelected || complete) {
|
||||||
|
if (fSelected)
|
||||||
|
onto->SetLowColor(tint_color(lowColor, B_DARKEN_2_TINT));
|
||||||
|
onto->FillRect(frame, B_SOLID_LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame.left += 4;
|
frame.left += 4;
|
||||||
BRect iconFrame(fIcons->IconRectAt(BPoint(frame.left, frame.top + 1)));
|
frame.top += kITEM_MARGIN;
|
||||||
|
BRect iconFrame(MediaIcons::IconRectAt(frame.LeftTop() + BPoint(1, 0)));
|
||||||
|
|
||||||
BBitmap* icon = &fIcons->devicesIcon;
|
onto->SetDrawingMode(B_OP_OVER);
|
||||||
if (OutlineLevel() == 0 || (fIsDefaultInput && fIsDefaultOutput)) {
|
if (fPrimaryIcon && !fDoubleInsets) {
|
||||||
if (fIsDefaultInput && fIsVideo)
|
onto->DrawBitmap(fPrimaryIcon, iconFrame);
|
||||||
icon = &fIcons->camIcon;
|
frame.left = iconFrame.right + 1;
|
||||||
else if (fIsDefaultInput && !fIsVideo)
|
} else if (fSecondaryIcon) {
|
||||||
icon = &fIcons->micIcon;
|
onto->DrawBitmap(fSecondaryIcon, iconFrame);
|
||||||
|
}
|
||||||
|
iconFrame = MediaIcons::IconRectAt(iconFrame.RightTop() + BPoint(1, 0));
|
||||||
|
|
||||||
owner->SetDrawingMode(B_OP_OVER);
|
if (fDoubleInsets && fPrimaryIcon) {
|
||||||
owner->DrawBitmap(icon, iconFrame);
|
onto->DrawBitmap(fPrimaryIcon, iconFrame);
|
||||||
owner->SetDrawingMode(B_OP_COPY);
|
frame.left = iconFrame.right + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
iconFrame.OffsetBy(16, 0);
|
onto->SetDrawingMode(B_OP_COPY);
|
||||||
if (fIsDefaultInput || fIsDefaultOutput || fIsAudioMixer) {
|
onto->SetHighColor(kBlack);
|
||||||
if (fIsAudioMixer)
|
|
||||||
icon = &fIcons->mixerIcon;
|
|
||||||
else if (fIsDefaultOutput) {
|
|
||||||
if (fIsVideo)
|
|
||||||
icon = &fIcons->tvIcon;
|
|
||||||
else
|
|
||||||
icon = &fIcons->speakerIcon;
|
|
||||||
} else {
|
|
||||||
if (fIsVideo)
|
|
||||||
icon = &fIcons->camIcon;
|
|
||||||
else
|
|
||||||
icon = &fIcons->speakerIcon;
|
|
||||||
}
|
|
||||||
owner->SetDrawingMode(B_OP_OVER);
|
|
||||||
owner->DrawBitmap(icon, iconFrame);
|
|
||||||
owner->SetDrawingMode(B_OP_COPY);
|
|
||||||
}
|
|
||||||
|
|
||||||
frame.left += 16 * (OutlineLevel() + 1);
|
|
||||||
owner->SetHighColor(kBlack);
|
|
||||||
|
|
||||||
BFont font = be_plain_font;
|
BFont font = be_plain_font;
|
||||||
font_height fontInfo;
|
font_height fontInfo;
|
||||||
font.GetHeight(&fontInfo);
|
font.GetHeight(&fontInfo);
|
||||||
float lineHeight = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
|
float lineHeight = fontInfo.ascent + fontInfo.descent
|
||||||
owner->SetFont(&font);
|
+ fontInfo.leading;
|
||||||
owner->MovePenTo(frame.left + 8, frame.top
|
onto->SetFont(&font);
|
||||||
|
onto->MovePenTo(frame.left + 8, frame.top
|
||||||
+ ((frame.Height() - (lineHeight)) / 2)
|
+ ((frame.Height() - (lineHeight)) / 2)
|
||||||
+ (fontInfo.ascent + fontInfo.descent) - 1);
|
+ (fontInfo.ascent + fontInfo.descent) - 1);
|
||||||
owner->DrawString(fLabel);
|
onto->DrawString(fTitle);
|
||||||
|
|
||||||
|
onto->SetHighColor(highColor);
|
||||||
|
onto->SetLowColor(lowColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
const char* fTitle;
|
||||||
|
BBitmap* fPrimaryIcon;
|
||||||
|
BBitmap* fSecondaryIcon;
|
||||||
|
bool fDoubleInsets;
|
||||||
|
bool fSelected;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
MediaListItem::MediaListItem()
|
||||||
|
:
|
||||||
|
BListItem((uint32)0)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaListItem::SetDefault(bool isDefault, bool isInput)
|
MediaListItem::Update(BView* owner, const BFont* font)
|
||||||
|
{
|
||||||
|
// we need to override the update method so we can make sure our
|
||||||
|
// list item size doesn't change
|
||||||
|
BListItem::Update(owner, font);
|
||||||
|
|
||||||
|
float iconHeight = MediaIcons::sBounds.Height() + 1;
|
||||||
|
if ((Height() < iconHeight + kITEM_MARGIN * 2)) {
|
||||||
|
SetHeight(iconHeight + kITEM_MARGIN * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - NodeListItem
|
||||||
|
|
||||||
|
|
||||||
|
NodeListItem::NodeListItem(dormant_node_info* node, media_type type)
|
||||||
|
:
|
||||||
|
MediaListItem(),
|
||||||
|
fNodeInfo(node),
|
||||||
|
fIsAudioMixer(false),
|
||||||
|
fMediaType(type),
|
||||||
|
fIsDefaultInput(false),
|
||||||
|
fIsDefaultOutput(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NodeListItem::SetRenderParameters(MediaListItem::Renderer& renderer)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (fIsAudioMixer) {
|
||||||
|
renderer.AddIcon(&Icons()->mixerIcon);
|
||||||
|
} else {
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
if (isInput)
|
|
||||||
fIsDefaultInput = isDefault;
|
|
||||||
else
|
|
||||||
fIsDefaultOutput = isDefault;
|
fIsDefaultOutput = isDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaListItem::SetAudioMixer(bool isAudioMixer)
|
NodeListItem::SetDefaultInput(bool isDefault)
|
||||||
{
|
{
|
||||||
fIsAudioMixer = isAudioMixer;
|
fIsDefaultInput = isDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaListItem::Update(BView* owner, const BFont* finfo)
|
NodeListItem::AlterWindow(MediaWindow* window)
|
||||||
{
|
{
|
||||||
// we need to override the update method so we can make sure our
|
window->SelectNode(fNodeInfo);
|
||||||
// list item size doesn't change
|
|
||||||
BListItem::Update(owner, finfo);
|
|
||||||
if ((Height() < 16 + kITEM_MARGIN)) {
|
|
||||||
SetHeight(16 + kITEM_MARGIN);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
MediaListItem::Compare(const void* firstArg, const void* secondArg)
|
NodeListItem::CompareWith(MediaListItem* item)
|
||||||
{
|
{
|
||||||
const MediaListItem* item1
|
return item->CompareWith(this) * -1;
|
||||||
= *static_cast<const MediaListItem* const*>(firstArg);
|
}
|
||||||
const MediaListItem* item2
|
|
||||||
= *static_cast<const MediaListItem* const*>(secondArg);
|
|
||||||
|
int
|
||||||
if (item1->fIsVideo != item2->fIsVideo)
|
NodeListItem::CompareWith(NodeListItem* item)
|
||||||
return item1->fIsVideo ? 1 : -1;
|
{
|
||||||
if (item1->OutlineLevel() != item2->OutlineLevel())
|
if (fMediaType != item->fMediaType)
|
||||||
return item1->OutlineLevel() > item2->OutlineLevel() ? 1 : -1;
|
return fMediaType == AUDIO_TYPE ? GREATER_THAN : LESS_THAN;
|
||||||
if (item1->fIsAudioMixer != item2->fIsAudioMixer)
|
|
||||||
return item2->fIsAudioMixer ? 1 : -1;
|
if (fIsAudioMixer != item->fIsAudioMixer)
|
||||||
return strcmp(item1->fLabel, item2->fLabel);
|
return fIsAudioMixer ? GREATER_THAN : LESS_THAN;
|
||||||
|
|
||||||
|
return strcmp(Label(), item->Label());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
NodeListItem::CompareWith(DeviceListItem* deviceItem)
|
||||||
|
{
|
||||||
|
if (fMediaType != deviceItem->Type())
|
||||||
|
return fMediaType == AUDIO_TYPE ? GREATER_THAN : LESS_THAN;
|
||||||
|
else
|
||||||
|
return LESS_THAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
NodeListItem::CompareWith(AudioMixerListItem* item)
|
||||||
|
{
|
||||||
|
return LESS_THAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - DeviceListItem
|
||||||
|
|
||||||
|
|
||||||
|
DeviceListItem::DeviceListItem(const char* title,
|
||||||
|
MediaListItem::media_type type)
|
||||||
|
:
|
||||||
|
MediaListItem(),
|
||||||
|
fTitle(title),
|
||||||
|
fMediaType(type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
DeviceListItem::CompareWith(MediaListItem* item)
|
||||||
|
{
|
||||||
|
return item->CompareWith(this) * -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
DeviceListItem::CompareWith(NodeListItem* item)
|
||||||
|
{
|
||||||
|
// let NodeListItem do the work
|
||||||
|
return item->CompareWith(this) * -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
DeviceListItem::CompareWith(DeviceListItem* item)
|
||||||
|
{
|
||||||
|
if (fMediaType == MediaListItem::AUDIO_TYPE)
|
||||||
|
return GREATER_THAN;
|
||||||
|
return LESS_THAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
DeviceListItem::CompareWith(AudioMixerListItem* item)
|
||||||
|
{
|
||||||
|
// let AudioMixerListItem do the work too!
|
||||||
|
return item->CompareWith(this) * -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - AudioMixerListItem
|
||||||
|
|
||||||
|
|
||||||
|
AudioMixerListItem::AudioMixerListItem(const char* title)
|
||||||
|
:
|
||||||
|
MediaListItem(),
|
||||||
|
fTitle(title)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioMixerListItem::AlterWindow(MediaWindow* window)
|
||||||
|
{
|
||||||
|
window->SelectAudioMixer(fTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
AudioMixerListItem::CompareWith(MediaListItem* item)
|
||||||
|
{
|
||||||
|
return item->CompareWith(this) * -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
AudioMixerListItem::CompareWith(NodeListItem* item)
|
||||||
|
{
|
||||||
|
return GREATER_THAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
AudioMixerListItem::CompareWith(DeviceListItem* item)
|
||||||
|
{
|
||||||
|
if (item->Type() == AUDIO_TYPE)
|
||||||
|
return LESS_THAN;
|
||||||
|
return GREATER_THAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
AudioMixerListItem::CompareWith(AudioMixerListItem* item)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioMixerListItem::SetRenderParameters(Renderer& renderer)
|
||||||
|
{
|
||||||
|
renderer.AddIcon(&Icons()->mixerIcon);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,50 +20,150 @@
|
|||||||
#include <MediaAddOn.h>
|
#include <MediaAddOn.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct dormant_node_info;
|
||||||
|
|
||||||
class MediaIcons;
|
class MediaIcons;
|
||||||
|
class MediaWindow;
|
||||||
|
|
||||||
|
class AudioMixerListItem;
|
||||||
|
class DeviceListItem;
|
||||||
|
class NodeListItem;
|
||||||
|
|
||||||
|
|
||||||
class MediaListItem : public BListItem {
|
class MediaListItem : public BListItem {
|
||||||
public:
|
public:
|
||||||
MediaListItem(dormant_node_info* info,
|
MediaListItem();
|
||||||
uint32 level, bool isVideo,
|
|
||||||
MediaIcons* icons, uint32 modifiers = 0);
|
virtual void AlterWindow(MediaWindow* window) = 0;
|
||||||
MediaListItem(const char* label, uint32 level,
|
|
||||||
bool isVideo, MediaIcons* icons,
|
enum media_type {
|
||||||
uint32 modifiers=0);
|
AUDIO_TYPE,
|
||||||
virtual ~MediaListItem();
|
VIDEO_TYPE
|
||||||
|
};
|
||||||
|
|
||||||
virtual void Update(BView* owner, const BFont* font);
|
virtual void Update(BView* owner, const BFont* font);
|
||||||
virtual void DrawItem(BView* owner, BRect frame,
|
virtual void DrawItem(BView* owner, BRect frame,
|
||||||
bool complete = false);
|
bool complete = false);
|
||||||
|
|
||||||
void SetDefault(bool isDefaultInput, bool isInput);
|
// TODO: refactor and remove this:
|
||||||
void SetAudioMixer(bool isAudioMixer);
|
virtual dormant_node_info* NodeInfo() = 0;
|
||||||
|
|
||||||
|
virtual const char* Label() = 0;
|
||||||
|
|
||||||
|
|
||||||
bool IsDefault(bool isInput)
|
static MediaIcons* Icons() {return sIcons;}
|
||||||
{
|
static void SetIcons(MediaIcons* icons) {sIcons = icons;}
|
||||||
return isInput ? fIsDefaultInput : fIsDefaultOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsAudioMixer() { return fIsAudioMixer; }
|
static int Compare(const void* itemOne,
|
||||||
bool IsVideo() { return fIsVideo; }
|
const void* itemTwo);
|
||||||
const char* GetLabel() { return fLabel; }
|
|
||||||
|
|
||||||
|
// use double dispatch for comparison,
|
||||||
|
// returning item->CompareWith(this) * -1
|
||||||
|
// -1 : < item; 0 : == item; 1 : > item
|
||||||
|
virtual int CompareWith(MediaListItem* item) = 0;
|
||||||
|
virtual int CompareWith(NodeListItem* item) = 0;
|
||||||
|
virtual int CompareWith(DeviceListItem* item) = 0;
|
||||||
|
virtual int CompareWith(AudioMixerListItem* item) = 0;
|
||||||
|
|
||||||
dormant_node_info* fInfo;
|
protected:
|
||||||
|
struct Renderer;
|
||||||
|
|
||||||
static int Compare(const void* firstArg,
|
virtual void SetRenderParameters(Renderer& renderer) = 0;
|
||||||
const void* secondArg);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char* fLabel;
|
|
||||||
|
static MediaIcons* sIcons;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class NodeListItem : public MediaListItem {
|
||||||
|
public:
|
||||||
|
NodeListItem(dormant_node_info* node,
|
||||||
|
media_type type);
|
||||||
|
|
||||||
|
void SetMediaType(MediaListItem::media_type type);
|
||||||
|
void SetDefaultOutput(bool isDefault);
|
||||||
|
bool IsDefaultOutput() {return fIsDefaultOutput;}
|
||||||
|
void SetDefaultInput(bool isDefault);
|
||||||
|
bool IsDefaultInput() {return fIsDefaultInput;}
|
||||||
|
|
||||||
|
virtual void AlterWindow(MediaWindow* window);
|
||||||
|
|
||||||
|
// TODO: refactor and remove this:
|
||||||
|
virtual dormant_node_info* NodeInfo(){return fNodeInfo;}
|
||||||
|
|
||||||
|
virtual const char* Label();
|
||||||
|
media_type Type() {return fMediaType;}
|
||||||
|
|
||||||
|
virtual int CompareWith(MediaListItem* item);
|
||||||
|
|
||||||
|
// -1 : < item; 0 : == item; 1 : > item
|
||||||
|
virtual int CompareWith(NodeListItem* item);
|
||||||
|
virtual int CompareWith(DeviceListItem* item);
|
||||||
|
virtual int CompareWith(AudioMixerListItem* item);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
virtual void SetRenderParameters(Renderer& renderer);
|
||||||
|
|
||||||
|
dormant_node_info* fNodeInfo;
|
||||||
bool fIsAudioMixer;
|
bool fIsAudioMixer;
|
||||||
bool fIsVideo;
|
media_type fMediaType;
|
||||||
bool fIsDefaultInput;
|
bool fIsDefaultInput;
|
||||||
bool fIsDefaultOutput;
|
bool fIsDefaultOutput;
|
||||||
//dormant_node_info fNodeInfo;
|
};
|
||||||
MediaIcons* fIcons;
|
|
||||||
|
|
||||||
|
class DeviceListItem : public MediaListItem {
|
||||||
|
public:
|
||||||
|
DeviceListItem(const char* title,
|
||||||
|
MediaListItem::media_type type);
|
||||||
|
|
||||||
|
MediaListItem::media_type Type() {return fMediaType;}
|
||||||
|
|
||||||
|
// TODO: refactor and remove this:
|
||||||
|
virtual dormant_node_info* NodeInfo(){return NULL;}
|
||||||
|
virtual const char* Label() {return fTitle;}
|
||||||
|
|
||||||
|
virtual void AlterWindow(MediaWindow* window);
|
||||||
|
|
||||||
|
virtual int CompareWith(MediaListItem* item);
|
||||||
|
|
||||||
|
// -1 : < item; 0 : == item; 1 : > item
|
||||||
|
virtual int CompareWith(NodeListItem* item);
|
||||||
|
virtual int CompareWith(DeviceListItem* item);
|
||||||
|
virtual int CompareWith(AudioMixerListItem* item);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void SetRenderParameters(Renderer& renderer);
|
||||||
|
|
||||||
|
const char* fTitle;
|
||||||
|
media_type fMediaType;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class AudioMixerListItem : public MediaListItem {
|
||||||
|
public:
|
||||||
|
AudioMixerListItem(const char* title);
|
||||||
|
|
||||||
|
// TODO: refactor and remove this:
|
||||||
|
virtual dormant_node_info* NodeInfo(){return NULL;}
|
||||||
|
|
||||||
|
virtual const char* Label() {return fTitle;}
|
||||||
|
|
||||||
|
virtual void AlterWindow(MediaWindow* window);
|
||||||
|
|
||||||
|
virtual int CompareWith(MediaListItem* item);
|
||||||
|
|
||||||
|
// -1 : < item; 0 : == item; 1 : > item
|
||||||
|
virtual int CompareWith(NodeListItem* item);
|
||||||
|
virtual int CompareWith(DeviceListItem* item);
|
||||||
|
virtual int CompareWith(AudioMixerListItem* item);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void SetRenderParameters(Renderer& renderer);
|
||||||
|
|
||||||
|
const char* fTitle;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __MEDIALISTITEM_H__ */
|
#endif /* __MEDIALISTITEM_H__ */
|
||||||
|
|||||||
@@ -44,18 +44,92 @@ const uint32 ML_SELECTED_NODE = 'MlSN';
|
|||||||
const uint32 ML_INIT_MEDIA = 'MlIM';
|
const uint32 ML_INIT_MEDIA = 'MlIM';
|
||||||
|
|
||||||
|
|
||||||
|
MediaWindow::SmartNode::SmartNode(const BMessenger& notifyHandler)
|
||||||
|
:
|
||||||
|
fNode(NULL),
|
||||||
|
fMessenger(notifyHandler)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MediaWindow::SmartNode::~SmartNode()
|
||||||
|
{
|
||||||
|
_FreeNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaWindow::SmartNode::SetTo(dormant_node_info* info)
|
||||||
|
{
|
||||||
|
_FreeNode();
|
||||||
|
if (!info)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fNode = new media_node();
|
||||||
|
|
||||||
|
// TODO: check error codes
|
||||||
|
BMediaRoster* roster = BMediaRoster::Roster();
|
||||||
|
|
||||||
|
media_node_id node_id;
|
||||||
|
if (roster->GetInstancesFor(info->addon, info->flavor_id, &node_id) == B_OK)
|
||||||
|
roster->GetNodeFor(node_id, fNode);
|
||||||
|
else
|
||||||
|
roster->InstantiateDormantNode(*info, fNode, B_FLAVOR_IS_GLOBAL);
|
||||||
|
roster->StartWatching(fMessenger, *fNode, B_MEDIA_WILDCARD);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaWindow::SmartNode::SetTo(const media_node& node)
|
||||||
|
{
|
||||||
|
_FreeNode();
|
||||||
|
fNode = new media_node(node);
|
||||||
|
BMediaRoster* roster = BMediaRoster::Roster();
|
||||||
|
roster->StartWatching(fMessenger, *fNode, B_MEDIA_WILDCARD);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
MediaWindow::SmartNode::IsSet()
|
||||||
|
{
|
||||||
|
return fNode != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MediaWindow::SmartNode::operator media_node()
|
||||||
|
{
|
||||||
|
if (fNode)
|
||||||
|
return *fNode;
|
||||||
|
media_node node;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaWindow::SmartNode::_FreeNode()
|
||||||
|
{
|
||||||
|
if (!IsSet())
|
||||||
|
return;
|
||||||
|
// TODO: check error codes
|
||||||
|
BMediaRoster* roster = BMediaRoster::Roster();
|
||||||
|
roster->StopWatching(fMessenger, *fNode, B_MEDIA_WILDCARD);
|
||||||
|
roster->ReleaseNode(*fNode);
|
||||||
|
delete fNode;
|
||||||
|
fNode = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// MediaWindow - Constructor
|
// MediaWindow - Constructor
|
||||||
MediaWindow::MediaWindow(BRect frame)
|
MediaWindow::MediaWindow(BRect frame)
|
||||||
:
|
:
|
||||||
BWindow (frame, B_TRANSLATE("Media"), B_TITLED_WINDOW,
|
BWindow (frame, B_TRANSLATE("Media"), B_TITLED_WINDOW,
|
||||||
B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS),
|
B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS),
|
||||||
fCurrentNode(NULL),
|
fCurrentNode(BMessenger(this)),
|
||||||
fParamWeb(NULL),
|
fParamWeb(NULL),
|
||||||
fAudioInputs(5, true),
|
fAudioInputs(5, true),
|
||||||
fAudioOutputs(5, true),
|
fAudioOutputs(5, true),
|
||||||
fVideoInputs(5, true),
|
fVideoInputs(5, true),
|
||||||
fVideoOutputs(5, true),
|
fVideoOutputs(5, true),
|
||||||
fIcons(),
|
|
||||||
fAlert(NULL),
|
fAlert(NULL),
|
||||||
fInitCheck(B_OK)
|
fInitCheck(B_OK)
|
||||||
{
|
{
|
||||||
@@ -73,10 +147,9 @@ MediaWindow::InitCheck()
|
|||||||
MediaWindow::~MediaWindow()
|
MediaWindow::~MediaWindow()
|
||||||
{
|
{
|
||||||
_EmptyNodeLists();
|
_EmptyNodeLists();
|
||||||
|
_ClearParamView();
|
||||||
BMediaRoster* roster = BMediaRoster::Roster();
|
delete fVideoView;
|
||||||
if (roster && fCurrentNode)
|
delete fAudioView;
|
||||||
roster->ReleaseNode(*fCurrentNode);
|
|
||||||
|
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
BRect rect = Frame();
|
BRect rect = Frame();
|
||||||
@@ -95,6 +168,43 @@ MediaWindow::~MediaWindow()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaWindow::SelectNode(dormant_node_info* node)
|
||||||
|
{
|
||||||
|
fCurrentNode.SetTo(node);
|
||||||
|
_MakeParamView();
|
||||||
|
fTitleView->SetLabel(node->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaWindow::SelectAudioSettings(const char* title)
|
||||||
|
{
|
||||||
|
fContentView->AddChild(fAudioView);
|
||||||
|
fTitleView->SetLabel(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaWindow::SelectVideoSettings(const char* title)
|
||||||
|
{
|
||||||
|
fContentView->AddChild(fVideoView);
|
||||||
|
fTitleView->SetLabel(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaWindow::SelectAudioMixer(const char* title)
|
||||||
|
{
|
||||||
|
media_node mixerNode;
|
||||||
|
BMediaRoster* roster = BMediaRoster::Roster();
|
||||||
|
roster->GetAudioMixer(&mixerNode);
|
||||||
|
fCurrentNode.SetTo(mixerNode);
|
||||||
|
_MakeParamView();
|
||||||
|
fTitleView->SetLabel(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaWindow::_FindNodes()
|
MediaWindow::_FindNodes()
|
||||||
{
|
{
|
||||||
@@ -150,16 +260,16 @@ MediaWindow::_FindNodes(media_type type, uint64 kind, NodeList& into)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MediaListItem *
|
NodeListItem*
|
||||||
MediaWindow::FindMediaListItem(dormant_node_info* info)
|
MediaWindow::_FindNodeListItem(dormant_node_info* info)
|
||||||
{
|
{
|
||||||
for (int32 j = 0; j<fListView->CountItems(); j++) {
|
for (int32 i = 0; i < fListView->CountItems(); i++) {
|
||||||
MediaListItem* item
|
MediaListItem* item
|
||||||
= static_cast<MediaListItem *>(fListView->ItemAt(j));
|
= static_cast<MediaListItem*>(fListView->ItemAt(i));
|
||||||
if (item->fInfo && item->fInfo->addon == info->addon
|
dormant_node_info* itemInfo = item->NodeInfo();
|
||||||
&& item->fInfo->flavor_id == info->flavor_id) {
|
if (itemInfo && itemInfo->addon == info->addon
|
||||||
return item;
|
&& itemInfo->flavor_id == info->flavor_id) {
|
||||||
break;
|
return dynamic_cast<NodeListItem*>(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -167,13 +277,13 @@ MediaWindow::FindMediaListItem(dormant_node_info* info)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaWindow::_AddNodeItems(NodeList &list, bool isVideo)
|
MediaWindow::_AddNodeItems(NodeList &list, MediaListItem::media_type type)
|
||||||
{
|
{
|
||||||
int32 count = list.CountItems();
|
int32 count = list.CountItems();
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
dormant_node_info* info = list.ItemAt(i);
|
dormant_node_info* info = list.ItemAt(i);
|
||||||
if (!FindMediaListItem(info))
|
if (!_FindNodeListItem(info))
|
||||||
fListView->AddItem(new MediaListItem(info, 1, isVideo, &fIcons));
|
fListView->AddItem(new NodeListItem(info, type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,10 +407,10 @@ MediaWindow::InitMedia(bool first)
|
|||||||
|
|
||||||
// Add video nodes first. They might have an additional audio
|
// Add video nodes first. They might have an additional audio
|
||||||
// output or input, but still should be listed as video node.
|
// output or input, but still should be listed as video node.
|
||||||
_AddNodeItems(fVideoOutputs, true);
|
_AddNodeItems(fVideoOutputs, MediaListItem::VIDEO_TYPE);
|
||||||
_AddNodeItems(fVideoInputs, true);
|
_AddNodeItems(fVideoInputs, MediaListItem::VIDEO_TYPE);
|
||||||
_AddNodeItems(fAudioOutputs, false);
|
_AddNodeItems(fAudioOutputs, MediaListItem::AUDIO_TYPE);
|
||||||
_AddNodeItems(fAudioInputs, false);
|
_AddNodeItems(fAudioInputs, MediaListItem::AUDIO_TYPE);
|
||||||
|
|
||||||
fAudioView->AddNodes(fAudioOutputs, false);
|
fAudioView->AddNodes(fAudioOutputs, false);
|
||||||
fAudioView->AddNodes(fAudioInputs, true);
|
fAudioView->AddNodes(fAudioInputs, true);
|
||||||
@@ -308,18 +418,16 @@ MediaWindow::InitMedia(bool first)
|
|||||||
fVideoView->AddNodes(fVideoInputs, true);
|
fVideoView->AddNodes(fVideoInputs, true);
|
||||||
|
|
||||||
// build our list view
|
// build our list view
|
||||||
MediaListItem* audio = new MediaListItem(B_TRANSLATE("Audio settings"), 0,
|
DeviceListItem* audio = new DeviceListItem(B_TRANSLATE("Audio settings"),
|
||||||
false, &fIcons);
|
MediaListItem::AUDIO_TYPE);
|
||||||
fListView->AddItem(audio);
|
fListView->AddItem(audio);
|
||||||
|
|
||||||
MediaListItem* video = new MediaListItem(B_TRANSLATE("Video settings"), 0,
|
MediaListItem* video = new DeviceListItem(B_TRANSLATE("Video settings"),
|
||||||
true, &fIcons);
|
MediaListItem::VIDEO_TYPE);
|
||||||
fListView->AddItem(video);
|
fListView->AddItem(video);
|
||||||
|
|
||||||
MediaListItem* mixer = new MediaListItem(B_TRANSLATE("Audio mixer"),
|
MediaListItem* mixer = new AudioMixerListItem(B_TRANSLATE("Audio mixer"));
|
||||||
1, false, &fIcons);
|
|
||||||
fListView->AddItem(mixer);
|
fListView->AddItem(mixer);
|
||||||
mixer->SetAudioMixer(true);
|
|
||||||
|
|
||||||
fListView->SortItems(&MediaListItem::Compare);
|
fListView->SortItems(&MediaListItem::Compare);
|
||||||
|
|
||||||
@@ -331,33 +439,33 @@ MediaWindow::InitMedia(bool first)
|
|||||||
|
|
||||||
if (roster->GetAudioInput(&default_node) == B_OK) {
|
if (roster->GetAudioInput(&default_node) == B_OK) {
|
||||||
roster->GetDormantNodeFor(default_node, &node_info);
|
roster->GetDormantNodeFor(default_node, &node_info);
|
||||||
MediaListItem* item = FindMediaListItem(&node_info);
|
NodeListItem* item = _FindNodeListItem(&node_info);
|
||||||
if (item)
|
if (item)
|
||||||
item->SetDefault(true, true);
|
item->SetDefaultInput(true);
|
||||||
fAudioView->SetDefault(node_info, true);
|
fAudioView->SetDefault(node_info, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roster->GetAudioOutput(&default_node, &outputID, &outputName)==B_OK) {
|
if (roster->GetAudioOutput(&default_node, &outputID, &outputName)==B_OK) {
|
||||||
roster->GetDormantNodeFor(default_node, &node_info);
|
roster->GetDormantNodeFor(default_node, &node_info);
|
||||||
MediaListItem* item = FindMediaListItem(&node_info);
|
NodeListItem* item = _FindNodeListItem(&node_info);
|
||||||
if (item)
|
if (item)
|
||||||
item->SetDefault(true, false);
|
item->SetDefaultOutput(true);
|
||||||
fAudioView->SetDefault(node_info, false, outputID);
|
fAudioView->SetDefault(node_info, false, outputID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roster->GetVideoInput(&default_node)==B_OK) {
|
if (roster->GetVideoInput(&default_node)==B_OK) {
|
||||||
roster->GetDormantNodeFor(default_node, &node_info);
|
roster->GetDormantNodeFor(default_node, &node_info);
|
||||||
MediaListItem* item = FindMediaListItem(&node_info);
|
NodeListItem* item = _FindNodeListItem(&node_info);
|
||||||
if (item)
|
if (item)
|
||||||
item->SetDefault(true, true);
|
item->SetDefaultInput(true);
|
||||||
fVideoView->SetDefault(node_info, true);
|
fVideoView->SetDefault(node_info, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roster->GetVideoOutput(&default_node)==B_OK) {
|
if (roster->GetVideoOutput(&default_node)==B_OK) {
|
||||||
roster->GetDormantNodeFor(default_node, &node_info);
|
roster->GetDormantNodeFor(default_node, &node_info);
|
||||||
MediaListItem* item = FindMediaListItem(&node_info);
|
NodeListItem* item = _FindNodeListItem(&node_info);
|
||||||
if (item)
|
if (item)
|
||||||
item->SetDefault(true, false);
|
item->SetDefaultOutput(true);
|
||||||
fVideoView->SetDefault(node_info, false);
|
fVideoView->SetDefault(node_info, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,10 +499,7 @@ bool
|
|||||||
MediaWindow::QuitRequested()
|
MediaWindow::QuitRequested()
|
||||||
{
|
{
|
||||||
// stop watching the MediaRoster
|
// stop watching the MediaRoster
|
||||||
BMediaRoster* roster = BMediaRoster::CurrentRoster();
|
fCurrentNode.SetTo(NULL);
|
||||||
if (roster && fCurrentNode) {
|
|
||||||
roster->StopWatching(this, *fCurrentNode, B_MEDIA_WILDCARD);
|
|
||||||
}
|
|
||||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -480,24 +585,37 @@ MediaWindow::MessageReceived(BMessage* message)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaListItem* oldListItem = NULL;
|
NodeListItem* oldListItem = NULL;
|
||||||
|
MediaListItem::media_type mediaType = isVideo ?
|
||||||
|
MediaListItem::VIDEO_TYPE : MediaListItem::AUDIO_TYPE;
|
||||||
for (int32 j = 0; j < fListView->CountItems(); j++) {
|
for (int32 j = 0; j < fListView->CountItems(); j++) {
|
||||||
oldListItem = static_cast<MediaListItem*>(
|
NodeListItem* item = dynamic_cast<NodeListItem*>(
|
||||||
fListView->ItemAt(j));
|
fListView->ItemAt(j));
|
||||||
if (oldListItem->fInfo
|
if (!oldListItem)
|
||||||
&& oldListItem->IsVideo() == isVideo
|
continue;
|
||||||
&& oldListItem->IsDefault(isInput))
|
if (oldListItem->Type() != mediaType)
|
||||||
|
continue;
|
||||||
|
if (isInput && !oldListItem->IsDefaultInput()) {
|
||||||
|
oldListItem = item;
|
||||||
|
break;
|
||||||
|
} else if (!isInput && oldListItem->IsDefaultOutput()) {
|
||||||
|
oldListItem = item;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (oldListItem)
|
}
|
||||||
oldListItem->SetDefault(false, isInput);
|
if (oldListItem && isInput)
|
||||||
|
oldListItem->SetDefaultInput(false);
|
||||||
|
else if (oldListItem && !isInput)
|
||||||
|
oldListItem->SetDefaultOutput(false);
|
||||||
else
|
else
|
||||||
fprintf(stderr, "oldListItem not found\n");
|
fprintf(stderr, "oldListItem not found\n");
|
||||||
|
|
||||||
MediaListItem* listItem = FindMediaListItem(item->fInfo);
|
NodeListItem* listItem = _FindNodeListItem(item->fInfo);
|
||||||
if (listItem) {
|
if (listItem && isInput)
|
||||||
listItem->SetDefault(true, isInput);
|
listItem->SetDefaultInput(true);
|
||||||
} else
|
else if (listItem && !isInput)
|
||||||
|
listItem->SetDefaultOutput(true);
|
||||||
|
else
|
||||||
fprintf(stderr, "MediaListItem not found\n");
|
fprintf(stderr, "MediaListItem not found\n");
|
||||||
fListView->Invalidate();
|
fListView->Invalidate();
|
||||||
|
|
||||||
@@ -570,70 +688,10 @@ MediaWindow::MessageReceived(BMessage* message)
|
|||||||
fListView->ItemAt(fListView->CurrentSelection()));
|
fListView->ItemAt(fListView->CurrentSelection()));
|
||||||
if (!item)
|
if (!item)
|
||||||
break;
|
break;
|
||||||
BMediaRoster* roster = BMediaRoster::Roster();
|
|
||||||
if (fCurrentNode) {
|
|
||||||
// stop watching the MediaRoster
|
|
||||||
roster->StopWatching(this, *fCurrentNode, B_MEDIA_WILDCARD);
|
|
||||||
roster->ReleaseNode(*fCurrentNode);
|
|
||||||
}
|
|
||||||
fCurrentNode = NULL;
|
|
||||||
BView* paramView = fContentView->ChildAt(0);
|
|
||||||
if (paramView!=NULL) {
|
|
||||||
fContentView->RemoveChild(paramView);
|
|
||||||
}
|
|
||||||
paramView = NULL;
|
|
||||||
if (fParamWeb)
|
|
||||||
delete fParamWeb;
|
|
||||||
fParamWeb = NULL;
|
|
||||||
|
|
||||||
fTitleView->SetLabel(item->GetLabel());
|
fCurrentNode.SetTo(NULL);
|
||||||
|
_ClearParamView();
|
||||||
if (item->OutlineLevel() == 0) {
|
item->AlterWindow(this);
|
||||||
if (item->IsVideo())
|
|
||||||
fContentView->AddChild(fVideoView);
|
|
||||||
else
|
|
||||||
fContentView->AddChild(fAudioView);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (!fCurrentNode)
|
|
||||||
fCurrentNode = new media_node();
|
|
||||||
media_node_id node_id;
|
|
||||||
if (item->IsAudioMixer())
|
|
||||||
roster->GetAudioMixer(fCurrentNode);
|
|
||||||
else if (roster->GetInstancesFor(item->fInfo->addon, item->fInfo->flavor_id, &node_id)!=B_OK)
|
|
||||||
roster->InstantiateDormantNode(*(item->fInfo), fCurrentNode, B_FLAVOR_IS_GLOBAL);
|
|
||||||
else
|
|
||||||
roster->GetNodeFor(node_id, fCurrentNode);
|
|
||||||
|
|
||||||
if (roster->GetParameterWebFor(*fCurrentNode, &fParamWeb)==B_OK
|
|
||||||
&& (paramView = BMediaTheme::PreferredTheme()->ViewFor(fParamWeb)) != NULL) {
|
|
||||||
fContentView->AddChild(paramView);
|
|
||||||
paramView->ResizeTo(1, 1);
|
|
||||||
// make sure we don't get stuck with a very large
|
|
||||||
// paramView
|
|
||||||
roster->StartWatching(this, *fCurrentNode, B_MEDIA_WILDCARD);
|
|
||||||
} else {
|
|
||||||
delete fParamWeb;
|
|
||||||
fParamWeb = NULL;
|
|
||||||
|
|
||||||
BStringView* stringView = new BStringView("noControls",
|
|
||||||
B_TRANSLATE("This hardware has no controls."));
|
|
||||||
|
|
||||||
BSize unlimited(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED);
|
|
||||||
stringView->SetExplicitMaxSize(unlimited);
|
|
||||||
|
|
||||||
BAlignment centered(B_ALIGN_HORIZONTAL_CENTER,
|
|
||||||
B_ALIGN_VERTICAL_CENTER);
|
|
||||||
stringView->SetExplicitAlignment(centered);
|
|
||||||
stringView->SetAlignment(B_ALIGN_CENTER);
|
|
||||||
|
|
||||||
fContentView->AddChild(stringView);
|
|
||||||
|
|
||||||
rgb_color panel = stringView->LowColor();
|
|
||||||
stringView->SetHighColor(tint_color(panel,
|
|
||||||
B_DISABLED_LABEL_TINT));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case B_SOME_APP_LAUNCHED:
|
case B_SOME_APP_LAUNCHED:
|
||||||
@@ -729,3 +787,63 @@ MediaWindow::UpdateProgress(int stage, const char * message, void * cookie)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaWindow::_ClearParamView()
|
||||||
|
{
|
||||||
|
BView* child = fContentView->ChildAt(0);
|
||||||
|
if (child)
|
||||||
|
child->RemoveSelf();
|
||||||
|
if (child != fVideoView && child != fAudioView)
|
||||||
|
delete child;
|
||||||
|
delete fParamWeb;
|
||||||
|
fParamWeb = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaWindow::_MakeParamView()
|
||||||
|
{
|
||||||
|
if (!fCurrentNode.IsSet())
|
||||||
|
return;
|
||||||
|
|
||||||
|
fParamWeb = NULL;
|
||||||
|
BMediaRoster* roster = BMediaRoster::Roster();
|
||||||
|
if (roster->GetParameterWebFor(fCurrentNode, &fParamWeb) == B_OK) {
|
||||||
|
BView* paramView = BMediaTheme::ViewFor(fParamWeb);
|
||||||
|
if (paramView) {
|
||||||
|
fContentView->AddChild(paramView);
|
||||||
|
paramView->ResizeTo(1, 1);
|
||||||
|
// make sure we don't get stuck with a very large
|
||||||
|
// paramView
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_MakeEmptyParamView();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaWindow::_MakeEmptyParamView()
|
||||||
|
{
|
||||||
|
fParamWeb = NULL;
|
||||||
|
|
||||||
|
BStringView* stringView = new BStringView("noControls",
|
||||||
|
B_TRANSLATE("This hardware has no controls."));
|
||||||
|
|
||||||
|
BSize unlimited(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED);
|
||||||
|
stringView->SetExplicitMaxSize(unlimited);
|
||||||
|
|
||||||
|
BAlignment centered(B_ALIGN_HORIZONTAL_CENTER,
|
||||||
|
B_ALIGN_VERTICAL_CENTER);
|
||||||
|
stringView->SetExplicitAlignment(centered);
|
||||||
|
stringView->SetAlignment(B_ALIGN_CENTER);
|
||||||
|
|
||||||
|
fContentView->AddChild(stringView);
|
||||||
|
|
||||||
|
rgb_color panel = stringView->LowColor();
|
||||||
|
stringView->SetHighColor(tint_color(panel,
|
||||||
|
B_DISABLED_LABEL_TINT));
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,18 @@ class MediaWindow : public BWindow
|
|||||||
public:
|
public:
|
||||||
MediaWindow(BRect frame);
|
MediaWindow(BRect frame);
|
||||||
~MediaWindow();
|
~MediaWindow();
|
||||||
|
status_t InitCheck();
|
||||||
|
|
||||||
|
// methods to be called by MediaListItems...
|
||||||
|
void SelectNode(dormant_node_info* node);
|
||||||
|
void SelectAudioSettings(const char* title);
|
||||||
|
void SelectVideoSettings(const char* title);
|
||||||
|
void SelectAudioMixer(const char* title);
|
||||||
|
|
||||||
virtual bool QuitRequested();
|
virtual bool QuitRequested();
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
virtual void FrameResized(float width, float height);
|
virtual void FrameResized(float width, float height);
|
||||||
status_t InitCheck();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -57,16 +65,35 @@ private:
|
|||||||
void _FindNodes();
|
void _FindNodes();
|
||||||
void _FindNodes(media_type type, uint64 kind,
|
void _FindNodes(media_type type, uint64 kind,
|
||||||
NodeList& into);
|
NodeList& into);
|
||||||
void _AddNodeItems(NodeList& from, bool isVideo);
|
void _AddNodeItems(NodeList &from,
|
||||||
|
MediaListItem::media_type type);
|
||||||
void _EmptyNodeLists();
|
void _EmptyNodeLists();
|
||||||
|
|
||||||
MediaListItem* FindMediaListItem(dormant_node_info* info);
|
NodeListItem* _FindNodeListItem(dormant_node_info* info);
|
||||||
void InitWindow();
|
void InitWindow();
|
||||||
|
|
||||||
static status_t RestartMediaServices(void* data);
|
static status_t RestartMediaServices(void* data);
|
||||||
static bool UpdateProgress(int stage, const char * message,
|
static bool UpdateProgress(int stage, const char * message,
|
||||||
void * cookie);
|
void * cookie);
|
||||||
|
|
||||||
|
void _ClearParamView();
|
||||||
|
void _MakeParamView();
|
||||||
|
void _MakeEmptyParamView();
|
||||||
|
|
||||||
|
struct SmartNode {
|
||||||
|
SmartNode(const BMessenger& notifyHandler);
|
||||||
|
~SmartNode();
|
||||||
|
void SetTo(dormant_node_info* node);
|
||||||
|
void SetTo(const media_node& node);
|
||||||
|
bool IsSet();
|
||||||
|
operator media_node();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _FreeNode();
|
||||||
|
media_node* fNode;
|
||||||
|
BMessenger fMessenger;
|
||||||
|
};
|
||||||
|
|
||||||
BBox* fBox;
|
BBox* fBox;
|
||||||
BListView* fListView;
|
BListView* fListView;
|
||||||
BSeparatorView* fTitleView;
|
BSeparatorView* fTitleView;
|
||||||
@@ -74,7 +101,7 @@ private:
|
|||||||
SettingsView* fAudioView;
|
SettingsView* fAudioView;
|
||||||
SettingsView* fVideoView;
|
SettingsView* fVideoView;
|
||||||
|
|
||||||
media_node* fCurrentNode;
|
SmartNode fCurrentNode;
|
||||||
BParameterWeb* fParamWeb;
|
BParameterWeb* fParamWeb;
|
||||||
|
|
||||||
|
|
||||||
@@ -83,9 +110,6 @@ private:
|
|||||||
NodeList fVideoInputs;
|
NodeList fVideoInputs;
|
||||||
NodeList fVideoOutputs;
|
NodeList fVideoOutputs;
|
||||||
|
|
||||||
MediaIcons fIcons;
|
|
||||||
|
|
||||||
|
|
||||||
MediaAlert* fAlert;
|
MediaAlert* fAlert;
|
||||||
status_t fInitCheck;
|
status_t fInitCheck;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user