In Media preflet:
* Modify MediaListItem to use the visitor pattern * Use the visitor pattern for comparison of MediaListItem subclassed objects * Use the visitor pattern in MediaWindow to propagate changes to NodeListItems. * Rename and/or remove some message constants * Rename SettingsItem class to NodeMenuItem * Rename Settings2Item class to ChannelMenuItem * Derive SettingsView from BGridView, and make it an abstract base class for two new classes, AudioSettingsView and VideoSettingsView. * Have the SettingsView subclasses handle messages originating from their children (for the most part). * Use a BCardLayout to hold our Audio/Video SettingsViews and our instantiated node view (when applicable). * small changes git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40127 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -57,8 +57,8 @@ Media::Media()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fWindow = new MediaWindow(rect);
|
|
||||||
MediaListItem::SetIcons(&fIcons);
|
MediaListItem::SetIcons(&fIcons);
|
||||||
|
fWindow = new MediaWindow(rect);
|
||||||
|
|
||||||
be_roster->StartWatching(BMessenger(this));
|
be_roster->StartWatching(BMessenger(this));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,11 +174,10 @@ MediaListItem::Compare(const void* itemOne, const void* itemTwo)
|
|||||||
// #pragma mark - NodeListItem
|
// #pragma mark - NodeListItem
|
||||||
|
|
||||||
|
|
||||||
NodeListItem::NodeListItem(dormant_node_info* node, media_type type)
|
NodeListItem::NodeListItem(const dormant_node_info* node, media_type type)
|
||||||
:
|
:
|
||||||
MediaListItem(),
|
MediaListItem(),
|
||||||
fNodeInfo(node),
|
fNodeInfo(node),
|
||||||
fIsAudioMixer(false),
|
|
||||||
fMediaType(type),
|
fMediaType(type),
|
||||||
fIsDefaultInput(false),
|
fIsDefaultInput(false),
|
||||||
fIsDefaultOutput(false)
|
fIsDefaultOutput(false)
|
||||||
@@ -189,10 +188,6 @@ NodeListItem::NodeListItem(dormant_node_info* node, media_type type)
|
|||||||
void
|
void
|
||||||
NodeListItem::SetRenderParameters(MediaListItem::Renderer& renderer)
|
NodeListItem::SetRenderParameters(MediaListItem::Renderer& renderer)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (fIsAudioMixer) {
|
|
||||||
renderer.AddIcon(&Icons()->mixerIcon);
|
|
||||||
} else {
|
|
||||||
MediaIcons::IconSet* iconSet = &Icons()->videoIcons;
|
MediaIcons::IconSet* iconSet = &Icons()->videoIcons;
|
||||||
if (fMediaType == MediaListItem::AUDIO_TYPE)
|
if (fMediaType == MediaListItem::AUDIO_TYPE)
|
||||||
iconSet = &Icons()->audioIcons;
|
iconSet = &Icons()->audioIcons;
|
||||||
@@ -201,7 +196,6 @@ NodeListItem::SetRenderParameters(MediaListItem::Renderer& renderer)
|
|||||||
renderer.AddIcon(&iconSet->inputIcon);
|
renderer.AddIcon(&iconSet->inputIcon);
|
||||||
if (fIsDefaultOutput)
|
if (fIsDefaultOutput)
|
||||||
renderer.AddIcon(&iconSet->outputIcon);
|
renderer.AddIcon(&iconSet->outputIcon);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -240,40 +234,55 @@ NodeListItem::AlterWindow(MediaWindow* window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NodeListItem::Accept(MediaListItem::Visitor& visitor)
|
||||||
|
{
|
||||||
|
visitor.Visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
NodeListItem::CompareWith(MediaListItem* item)
|
NodeListItem::CompareWith(MediaListItem* item)
|
||||||
{
|
{
|
||||||
return item->CompareWith(this) * -1;
|
Comparator comparator(this);
|
||||||
|
item->Accept(comparator);
|
||||||
|
return comparator.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
NodeListItem::Comparator::Comparator(NodeListItem* compareOthersTo)
|
||||||
NodeListItem::CompareWith(NodeListItem* item)
|
:
|
||||||
|
result(GREATER_THAN),
|
||||||
|
fTarget(compareOthersTo)
|
||||||
{
|
{
|
||||||
if (fMediaType != item->fMediaType)
|
|
||||||
return fMediaType == AUDIO_TYPE ? GREATER_THAN : LESS_THAN;
|
|
||||||
|
|
||||||
if (fIsAudioMixer != item->fIsAudioMixer)
|
|
||||||
return fIsAudioMixer ? GREATER_THAN : LESS_THAN;
|
|
||||||
|
|
||||||
return strcmp(Label(), item->Label());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
void
|
||||||
NodeListItem::CompareWith(DeviceListItem* deviceItem)
|
NodeListItem::Comparator::Visit(NodeListItem* item)
|
||||||
{
|
{
|
||||||
if (fMediaType != deviceItem->Type())
|
result = GREATER_THAN;
|
||||||
return fMediaType == AUDIO_TYPE ? GREATER_THAN : LESS_THAN;
|
|
||||||
|
if (fTarget->Type() != item->Type() && fTarget->Type() == VIDEO_TYPE)
|
||||||
|
result = LESS_THAN;
|
||||||
else
|
else
|
||||||
return LESS_THAN;
|
result = strcmp(fTarget->Label(), item->Label());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
void
|
||||||
NodeListItem::CompareWith(AudioMixerListItem* item)
|
NodeListItem::Comparator::Visit(DeviceListItem* item)
|
||||||
{
|
{
|
||||||
return LESS_THAN;
|
result = LESS_THAN;
|
||||||
|
if (fTarget->Type() != item->Type() && fTarget->Type() == AUDIO_TYPE)
|
||||||
|
result = GREATER_THAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NodeListItem::Comparator::Visit(AudioMixerListItem* item)
|
||||||
|
{
|
||||||
|
result = LESS_THAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -290,35 +299,54 @@ DeviceListItem::DeviceListItem(const char* title,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DeviceListItem::Accept(MediaListItem::Visitor& visitor)
|
||||||
|
{
|
||||||
|
visitor.Visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
DeviceListItem::CompareWith(MediaListItem* item)
|
DeviceListItem::CompareWith(MediaListItem* item)
|
||||||
{
|
{
|
||||||
return item->CompareWith(this) * -1;
|
Comparator comparator(this);
|
||||||
|
item->Accept(comparator);
|
||||||
|
return comparator.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
DeviceListItem::Comparator::Comparator(DeviceListItem* compareOthersTo)
|
||||||
DeviceListItem::CompareWith(NodeListItem* item)
|
:
|
||||||
|
result(GREATER_THAN),
|
||||||
|
fTarget(compareOthersTo)
|
||||||
{
|
{
|
||||||
// let NodeListItem do the work
|
|
||||||
return item->CompareWith(this) * -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
void
|
||||||
DeviceListItem::CompareWith(DeviceListItem* item)
|
DeviceListItem::Comparator::Visit(NodeListItem* item)
|
||||||
{
|
{
|
||||||
if (fMediaType == MediaListItem::AUDIO_TYPE)
|
result = GREATER_THAN;
|
||||||
return GREATER_THAN;
|
if (fTarget->Type() != item->Type() && fTarget->Type() == AUDIO_TYPE)
|
||||||
return LESS_THAN;
|
result = LESS_THAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
void
|
||||||
DeviceListItem::CompareWith(AudioMixerListItem* item)
|
DeviceListItem::Comparator::Visit(DeviceListItem* item)
|
||||||
{
|
{
|
||||||
// let AudioMixerListItem do the work too!
|
result = LESS_THAN;
|
||||||
return item->CompareWith(this) * -1;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -358,33 +386,50 @@ AudioMixerListItem::AlterWindow(MediaWindow* window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioMixerListItem::Accept(MediaListItem::Visitor& visitor)
|
||||||
|
{
|
||||||
|
visitor.Visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AudioMixerListItem::CompareWith(MediaListItem* item)
|
AudioMixerListItem::CompareWith(MediaListItem* item)
|
||||||
{
|
{
|
||||||
return item->CompareWith(this) * -1;
|
Comparator comparator(this);
|
||||||
|
item->Accept(comparator);
|
||||||
|
return comparator.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
AudioMixerListItem::Comparator::Comparator(AudioMixerListItem* compareOthersTo)
|
||||||
AudioMixerListItem::CompareWith(NodeListItem* item)
|
:
|
||||||
|
result(0),
|
||||||
|
fTarget(compareOthersTo)
|
||||||
{
|
{
|
||||||
return GREATER_THAN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
void
|
||||||
AudioMixerListItem::CompareWith(DeviceListItem* item)
|
AudioMixerListItem::Comparator::Visit(NodeListItem* item)
|
||||||
{
|
{
|
||||||
|
result = GREATER_THAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioMixerListItem::Comparator::Visit(DeviceListItem* item)
|
||||||
|
{
|
||||||
|
result = GREATER_THAN;
|
||||||
if (item->Type() == AUDIO_TYPE)
|
if (item->Type() == AUDIO_TYPE)
|
||||||
return LESS_THAN;
|
result = LESS_THAN;
|
||||||
return GREATER_THAN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
void
|
||||||
AudioMixerListItem::CompareWith(AudioMixerListItem* item)
|
AudioMixerListItem::Comparator::Visit(AudioMixerListItem* item)
|
||||||
{
|
{
|
||||||
return 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -45,25 +45,26 @@ public:
|
|||||||
virtual void DrawItem(BView* owner, BRect frame,
|
virtual void DrawItem(BView* owner, BRect frame,
|
||||||
bool complete = false);
|
bool complete = false);
|
||||||
|
|
||||||
// TODO: refactor and remove this:
|
|
||||||
virtual dormant_node_info* NodeInfo() = 0;
|
|
||||||
|
|
||||||
virtual const char* Label() = 0;
|
virtual const char* Label() = 0;
|
||||||
|
|
||||||
|
|
||||||
static MediaIcons* Icons() {return sIcons;}
|
static MediaIcons* Icons() {return sIcons;}
|
||||||
static void SetIcons(MediaIcons* icons) {sIcons = icons;}
|
static void SetIcons(MediaIcons* icons) {sIcons = icons;}
|
||||||
|
|
||||||
static int Compare(const void* itemOne,
|
struct Visitor {
|
||||||
const void* itemTwo);
|
virtual void Visit(AudioMixerListItem* item) = 0;
|
||||||
|
virtual void Visit(DeviceListItem* item) = 0;
|
||||||
|
virtual void Visit(NodeListItem* item) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
// use double dispatch for comparison,
|
virtual void Accept(Visitor& visitor) = 0;
|
||||||
// returning item->CompareWith(this) * -1
|
|
||||||
|
// use the visitor pattern for comparison,
|
||||||
// -1 : < item; 0 : == item; 1 : > item
|
// -1 : < item; 0 : == item; 1 : > item
|
||||||
virtual int CompareWith(MediaListItem* item) = 0;
|
virtual int CompareWith(MediaListItem* item) = 0;
|
||||||
virtual int CompareWith(NodeListItem* item) = 0;
|
|
||||||
virtual int CompareWith(DeviceListItem* item) = 0;
|
static int Compare(const void* itemOne,
|
||||||
virtual int CompareWith(AudioMixerListItem* item) = 0;
|
const void* itemTwo);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct Renderer;
|
struct Renderer;
|
||||||
@@ -78,7 +79,7 @@ private:
|
|||||||
|
|
||||||
class NodeListItem : public MediaListItem {
|
class NodeListItem : public MediaListItem {
|
||||||
public:
|
public:
|
||||||
NodeListItem(dormant_node_info* node,
|
NodeListItem(const dormant_node_info* node,
|
||||||
media_type type);
|
media_type type);
|
||||||
|
|
||||||
void SetMediaType(MediaListItem::media_type type);
|
void SetMediaType(MediaListItem::media_type type);
|
||||||
@@ -89,25 +90,32 @@ public:
|
|||||||
|
|
||||||
virtual void AlterWindow(MediaWindow* window);
|
virtual void AlterWindow(MediaWindow* window);
|
||||||
|
|
||||||
// TODO: refactor and remove this:
|
|
||||||
virtual dormant_node_info* NodeInfo(){return fNodeInfo;}
|
|
||||||
|
|
||||||
virtual const char* Label();
|
virtual const char* Label();
|
||||||
media_type Type() {return fMediaType;}
|
media_type Type() {return fMediaType;}
|
||||||
|
|
||||||
virtual int CompareWith(MediaListItem* item);
|
virtual void Accept(MediaListItem::Visitor& visitor);
|
||||||
|
|
||||||
|
struct Comparator : public MediaListItem::Visitor {
|
||||||
|
Comparator(NodeListItem* compareOthersTo);
|
||||||
|
virtual void Visit(NodeListItem* item);
|
||||||
|
virtual void Visit(DeviceListItem* item);
|
||||||
|
virtual void Visit(AudioMixerListItem* item);
|
||||||
|
|
||||||
|
int result;
|
||||||
|
// -1 : < item; 0 : == item; 1 : > item
|
||||||
|
private:
|
||||||
|
NodeListItem* fTarget;
|
||||||
|
};
|
||||||
|
|
||||||
// -1 : < item; 0 : == item; 1 : > item
|
// -1 : < item; 0 : == item; 1 : > item
|
||||||
virtual int CompareWith(NodeListItem* item);
|
virtual int CompareWith(MediaListItem* item);
|
||||||
virtual int CompareWith(DeviceListItem* item);
|
|
||||||
virtual int CompareWith(AudioMixerListItem* item);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
virtual void SetRenderParameters(Renderer& renderer);
|
virtual void SetRenderParameters(Renderer& renderer);
|
||||||
|
|
||||||
dormant_node_info* fNodeInfo;
|
const dormant_node_info* fNodeInfo;
|
||||||
bool fIsAudioMixer;
|
|
||||||
media_type fMediaType;
|
media_type fMediaType;
|
||||||
bool fIsDefaultInput;
|
bool fIsDefaultInput;
|
||||||
bool fIsDefaultOutput;
|
bool fIsDefaultOutput;
|
||||||
@@ -120,19 +128,24 @@ public:
|
|||||||
MediaListItem::media_type type);
|
MediaListItem::media_type type);
|
||||||
|
|
||||||
MediaListItem::media_type Type() {return fMediaType;}
|
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 const char* Label() {return fTitle;}
|
||||||
|
|
||||||
virtual void AlterWindow(MediaWindow* window);
|
virtual void AlterWindow(MediaWindow* window);
|
||||||
|
virtual void Accept(MediaListItem::Visitor& visitor);
|
||||||
|
|
||||||
virtual int CompareWith(MediaListItem* item);
|
struct Comparator : public MediaListItem::Visitor {
|
||||||
|
Comparator(DeviceListItem* compareOthersTo);
|
||||||
|
virtual void Visit(NodeListItem* item);
|
||||||
|
virtual void Visit(DeviceListItem* item);
|
||||||
|
virtual void Visit(AudioMixerListItem* item);
|
||||||
|
|
||||||
|
int result;
|
||||||
|
// -1 : < item; 0 : == item; 1 : > item
|
||||||
|
private:
|
||||||
|
DeviceListItem* fTarget;
|
||||||
|
};
|
||||||
|
|
||||||
// -1 : < item; 0 : == item; 1 : > item
|
// -1 : < item; 0 : == item; 1 : > item
|
||||||
virtual int CompareWith(NodeListItem* item);
|
virtual int CompareWith(MediaListItem* item);
|
||||||
virtual int CompareWith(DeviceListItem* item);
|
|
||||||
virtual int CompareWith(AudioMixerListItem* item);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void SetRenderParameters(Renderer& renderer);
|
virtual void SetRenderParameters(Renderer& renderer);
|
||||||
@@ -146,19 +159,25 @@ class AudioMixerListItem : public MediaListItem {
|
|||||||
public:
|
public:
|
||||||
AudioMixerListItem(const char* title);
|
AudioMixerListItem(const char* title);
|
||||||
|
|
||||||
// TODO: refactor and remove this:
|
|
||||||
virtual dormant_node_info* NodeInfo(){return NULL;}
|
|
||||||
|
|
||||||
virtual const char* Label() {return fTitle;}
|
virtual const char* Label() {return fTitle;}
|
||||||
|
|
||||||
virtual void AlterWindow(MediaWindow* window);
|
virtual void AlterWindow(MediaWindow* window);
|
||||||
|
virtual void Accept(MediaListItem::Visitor& visitor);
|
||||||
|
|
||||||
virtual int CompareWith(MediaListItem* item);
|
struct Comparator : public MediaListItem::Visitor {
|
||||||
|
Comparator(AudioMixerListItem* compareOthersTo);
|
||||||
|
virtual void Visit(NodeListItem* item);
|
||||||
|
virtual void Visit(DeviceListItem* item);
|
||||||
|
virtual void Visit(AudioMixerListItem* item);
|
||||||
|
|
||||||
|
int result;
|
||||||
|
// -1 : < item; 0 : == item; 1 : > item
|
||||||
|
private:
|
||||||
|
AudioMixerListItem* fTarget;
|
||||||
|
};
|
||||||
|
|
||||||
// -1 : < item; 0 : == item; 1 : > item
|
// -1 : < item; 0 : == item; 1 : > item
|
||||||
virtual int CompareWith(NodeListItem* item);
|
virtual int CompareWith(MediaListItem* item);
|
||||||
virtual int CompareWith(DeviceListItem* item);
|
|
||||||
virtual int CompareWith(AudioMixerListItem* item);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void SetRenderParameters(Renderer& renderer);
|
virtual void SetRenderParameters(Renderer& renderer);
|
||||||
|
|||||||
@@ -12,247 +12,286 @@
|
|||||||
// Created : June 25, 2003
|
// Created : June 25, 2003
|
||||||
//
|
//
|
||||||
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||||
|
|
||||||
|
|
||||||
#include "MediaViews.h"
|
#include "MediaViews.h"
|
||||||
|
|
||||||
|
#include <AutoDeleter.h>
|
||||||
#include <Box.h>
|
#include <Box.h>
|
||||||
#include <Button.h>
|
#include <Button.h>
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
|
#include <CheckBox.h>
|
||||||
#include <Deskbar.h>
|
#include <Deskbar.h>
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
#include <GridView.h>
|
#include <LayoutBuilder.h>
|
||||||
#include <GroupView.h>
|
|
||||||
#include <Locale.h>
|
#include <Locale.h>
|
||||||
#include <MediaAddOn.h>
|
#include <MediaAddOn.h>
|
||||||
#include <MediaRoster.h>
|
#include <MediaRoster.h>
|
||||||
#include <MenuField.h>
|
#include <MenuField.h>
|
||||||
#include <PopUpMenu.h>
|
#include <PopUpMenu.h>
|
||||||
#include <SpaceLayoutItem.h>
|
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
#include <StringView.h>
|
||||||
#include <TextView.h>
|
#include <TextView.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "MediaWindow.h"
|
||||||
|
|
||||||
|
|
||||||
#undef B_TRANSLATE_CONTEXT
|
#undef B_TRANSLATE_CONTEXT
|
||||||
#define B_TRANSLATE_CONTEXT "Media views"
|
#define B_TRANSLATE_CONTEXT "Media views"
|
||||||
|
|
||||||
|
#define MEDIA_DEFAULT_INPUT_CHANGE 'dich'
|
||||||
|
#define MEDIA_DEFAULT_OUTPUT_CHANGE 'doch'
|
||||||
|
#define MEDIA_SHOW_HIDE_VOLUME_CONTROL 'shvc'
|
||||||
|
|
||||||
SettingsView::SettingsView (bool isVideo)
|
|
||||||
|
SettingsView::SettingsView()
|
||||||
:
|
:
|
||||||
BView("SettingsView", B_WILL_DRAW | B_SUPPORTS_LAYOUT),
|
BGridView(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING),
|
||||||
fIsVideo(isVideo)
|
fRealtimeCheckBox(NULL),
|
||||||
|
fInputMenu(NULL),
|
||||||
|
fOutputMenu(NULL),
|
||||||
|
fRestartView(NULL)
|
||||||
{
|
{
|
||||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
|
||||||
|
|
||||||
// create the default box
|
|
||||||
|
|
||||||
// input menu
|
// input menu
|
||||||
fInputMenu = new BPopUpMenu(B_TRANSLATE("<none>"));
|
fInputMenu = new BPopUpMenu(B_TRANSLATE("<none>"));
|
||||||
fInputMenu->SetLabelFromMarked(true);
|
fInputMenu->SetLabelFromMarked(true);
|
||||||
BMenuField* inputMenuField = new BMenuField("inputMenuField",
|
|
||||||
fIsVideo ? B_TRANSLATE("Video input:")
|
|
||||||
: B_TRANSLATE("Audio input:"), fInputMenu, NULL);
|
|
||||||
|
|
||||||
// output menu
|
// input menu
|
||||||
fOutputMenu = new BPopUpMenu(B_TRANSLATE("<none>"));
|
fOutputMenu = new BPopUpMenu(B_TRANSLATE("<none>"));
|
||||||
fOutputMenu->SetLabelFromMarked(true);
|
fOutputMenu->SetLabelFromMarked(true);
|
||||||
BMenuField* outputMenuField = new BMenuField("outputMenuField",
|
}
|
||||||
fIsVideo ? B_TRANSLATE("Video output:")
|
|
||||||
: B_TRANSLATE("Audio output:"), fOutputMenu, NULL);
|
|
||||||
|
|
||||||
// channel menu (audio only)
|
|
||||||
BMenuField* channelMenuField = NULL;
|
|
||||||
if (!fIsVideo) {
|
|
||||||
fChannelMenu = new BPopUpMenu(B_TRANSLATE("<none>"));
|
|
||||||
fChannelMenu->SetLabelFromMarked(true);
|
|
||||||
channelMenuField = new BMenuField("channelMenuField",
|
|
||||||
B_TRANSLATE("Channel:"), fChannelMenu, NULL);
|
|
||||||
channelMenuField->SetDivider(StringWidth(B_TRANSLATE("Channel:"))+5);
|
|
||||||
}
|
|
||||||
|
|
||||||
BBox* defaultsBox = new BBox("defaults");
|
|
||||||
defaultsBox->SetLabel(fIsVideo ? B_TRANSLATE("Default nodes")
|
|
||||||
: B_TRANSLATE("Defaults"));
|
|
||||||
|
|
||||||
// put our menus in a BGridView in our BBox, this way, the BBox makes sure
|
|
||||||
// we have are not blocking the label.
|
|
||||||
BGridView* defaultsGridView = new BGridView();
|
|
||||||
defaultsBox->AddChild(defaultsGridView);
|
|
||||||
|
|
||||||
BGridLayout* defaultsGrid = defaultsGridView->GridLayout();
|
|
||||||
defaultsGrid->SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING,
|
|
||||||
B_USE_DEFAULT_SPACING);
|
|
||||||
|
|
||||||
BLayoutItem* labelItem = inputMenuField->CreateLabelLayoutItem();
|
|
||||||
BLayoutItem* menuItem = inputMenuField->CreateMenuBarLayoutItem();
|
|
||||||
defaultsGrid->AddItem(labelItem, 0, 0, 1, 1);
|
|
||||||
defaultsGrid->AddItem(menuItem, 1, 0, 3, 1);
|
|
||||||
|
|
||||||
int32 outputMenuWidth = 3;
|
|
||||||
if (channelMenuField) {
|
|
||||||
outputMenuWidth = 1;
|
|
||||||
labelItem = channelMenuField->CreateLabelLayoutItem();
|
|
||||||
menuItem = channelMenuField->CreateMenuBarLayoutItem();
|
|
||||||
defaultsGrid->AddItem(labelItem, 2, 1, 1, 1);
|
|
||||||
defaultsGrid->AddItem(menuItem, 3, 1, 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
labelItem = outputMenuField->CreateLabelLayoutItem();
|
|
||||||
menuItem = outputMenuField->CreateMenuBarLayoutItem();
|
|
||||||
defaultsGrid->AddItem(labelItem, 0, 1, 1, 1);
|
|
||||||
defaultsGrid->AddItem(menuItem, 1, 1, outputMenuWidth, 1);
|
|
||||||
|
|
||||||
|
|
||||||
rgb_color red_color = {222, 32, 33};
|
BBox*
|
||||||
fRestartView = new BStringView("restartStringView",
|
SettingsView::MakeRealtimeBox(const char* info, uint32 realtimeMask,
|
||||||
B_TRANSLATE("Restart the media server to apply changes."));
|
const char* checkBoxLabel)
|
||||||
fRestartView->SetHighColor(red_color);
|
{
|
||||||
defaultsBox->AddChild(fRestartView);
|
|
||||||
fRestartView->Hide();
|
|
||||||
|
|
||||||
// create the realtime box
|
// create the realtime box
|
||||||
BBox* realtimeBox = new BBox("realtime");
|
BBox* realtimeBox = new BBox("realtime");
|
||||||
realtimeBox->SetLabel(B_TRANSLATE("Real-time"));
|
realtimeBox->SetLabel(B_TRANSLATE("Real-time"));
|
||||||
|
|
||||||
BMessage* message = new BMessage(ML_ENABLE_REAL_TIME);
|
BMessage* checkBoxMessage = new BMessage(ML_ENABLE_REAL_TIME);
|
||||||
message->AddBool("isVideo", fIsVideo);
|
checkBoxMessage->AddUInt32("flags", realtimeMask);
|
||||||
fRealtimeCheckBox = new BCheckBox("realtimeCheckBox",
|
fRealtimeCheckBox = new BCheckBox("realtimeCheckBox", checkBoxLabel,
|
||||||
fIsVideo ? B_TRANSLATE("Enable real-time video")
|
checkBoxMessage);
|
||||||
: B_TRANSLATE("Enable real-time audio"),
|
|
||||||
message);
|
|
||||||
|
|
||||||
uint32 flags;
|
uint32 flags = 0;
|
||||||
BMediaRoster::Roster()->GetRealtimeFlags(&flags);
|
BMediaRoster::Roster()->GetRealtimeFlags(&flags);
|
||||||
if (flags & (fIsVideo ? B_MEDIA_REALTIME_VIDEO : B_MEDIA_REALTIME_AUDIO))
|
if (flags & realtimeMask)
|
||||||
fRealtimeCheckBox->SetValue(B_CONTROL_ON);
|
fRealtimeCheckBox->SetValue(B_CONTROL_ON);
|
||||||
|
|
||||||
BTextView* textView = new BTextView("stringView");
|
BTextView* textView = new BTextView("stringView");
|
||||||
textView->Insert(fIsVideo ? B_TRANSLATE(
|
textView->Insert(info);
|
||||||
"Enabling real-time video allows system to "
|
|
||||||
"perform video operations as fast and smoothly as possible. It "
|
|
||||||
"achieves optimum performance by using more RAM."
|
|
||||||
"\n\nOnly enable this feature if you need the lowest latency possible.")
|
|
||||||
: B_TRANSLATE(
|
|
||||||
"Enabling real-time audio allows system to record and play audio "
|
|
||||||
"as fast as possible. It achieves this performance by using more"
|
|
||||||
" CPU and RAM.\n\nOnly enable this feature if you need the lowest"
|
|
||||||
" latency possible."));
|
|
||||||
|
|
||||||
textView->MakeEditable(false);
|
textView->MakeEditable(false);
|
||||||
textView->MakeSelectable(false);
|
textView->MakeSelectable(false);
|
||||||
textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
|
||||||
BGroupLayout* realtimeBoxLayout = new BGroupLayout(B_VERTICAL, 5);
|
BGroupView* realtimeGroup = new BGroupView(B_VERTICAL);
|
||||||
realtimeBoxLayout->SetInsets(10,10,10,10);
|
BLayoutBuilder::Group<>(realtimeGroup)
|
||||||
realtimeBox->SetLayout(realtimeBoxLayout);
|
.SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING,
|
||||||
|
B_USE_DEFAULT_SPACING)
|
||||||
|
.Add(fRealtimeCheckBox)
|
||||||
|
.Add(textView);
|
||||||
|
|
||||||
realtimeBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5));
|
realtimeBox->AddChild(realtimeGroup);
|
||||||
realtimeBoxLayout->AddView(fRealtimeCheckBox);
|
return realtimeBox;
|
||||||
realtimeBoxLayout->AddView(textView);
|
}
|
||||||
|
|
||||||
// create the bottom line: volume in deskbar checkbox and restart button
|
|
||||||
BGroupView* bottomView = new BGroupView(B_HORIZONTAL);
|
BStringView*
|
||||||
BButton* restartButton = new BButton("restartButton",
|
SettingsView::MakeRestartMessageView()
|
||||||
|
{
|
||||||
|
// note: this ought to display at the bottom of the default box...
|
||||||
|
fRestartView = new BStringView("restartStringView",
|
||||||
|
B_TRANSLATE("Restart the media server to apply changes."));
|
||||||
|
fRestartView->SetHighColor(ui_color(B_FAILURE_COLOR));
|
||||||
|
// not exactly failure, but sort of.
|
||||||
|
fRestartView->Hide();
|
||||||
|
fRestartView->SetExplicitAlignment(BAlignment(B_ALIGN_HORIZONTAL_CENTER,
|
||||||
|
B_ALIGN_VERTICAL_CENTER));
|
||||||
|
fRestartView->SetAlignment(B_ALIGN_HORIZONTAL_CENTER);
|
||||||
|
fRestartView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
|
||||||
|
return fRestartView;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BButton*
|
||||||
|
SettingsView::MakeRestartButton()
|
||||||
|
{
|
||||||
|
return new BButton("restartButton",
|
||||||
B_TRANSLATE("Restart media services"),
|
B_TRANSLATE("Restart media services"),
|
||||||
new BMessage(ML_RESTART_MEDIA_SERVER));
|
new BMessage(ML_RESTART_MEDIA_SERVER));
|
||||||
|
}
|
||||||
|
|
||||||
if (!fIsVideo) {
|
|
||||||
fVolumeCheckBox = new BCheckBox("volumeCheckBox",
|
|
||||||
B_TRANSLATE("Show volume control on Deskbar"),
|
|
||||||
new BMessage(ML_SHOW_VOLUME_CONTROL));
|
|
||||||
bottomView->GroupLayout()->AddView(fVolumeCheckBox);
|
|
||||||
if (BDeskbar().HasItem("MediaReplicant"))
|
|
||||||
fVolumeCheckBox->SetValue(B_CONTROL_ON);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
bottomView->GroupLayout()->AddItem(BSpaceLayoutItem::CreateGlue());
|
|
||||||
}
|
|
||||||
bottomView->GroupLayout()->AddView(restartButton);
|
|
||||||
|
|
||||||
// compose all stuff
|
|
||||||
BGroupLayout* rootlayout = new BGroupLayout(B_VERTICAL, 5);
|
|
||||||
SetLayout(rootlayout);
|
|
||||||
|
|
||||||
rootlayout->AddView(defaultsBox);
|
void
|
||||||
rootlayout->AddView(realtimeBox);
|
SettingsView::AddInputNodes(NodeList& list)
|
||||||
rootlayout->AddView(bottomView);
|
{
|
||||||
|
_EmptyMenu(fInputMenu);
|
||||||
|
|
||||||
|
BMessage message(MEDIA_DEFAULT_INPUT_CHANGE);
|
||||||
|
_PopulateMenu(fInputMenu, list, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SettingsView::AddNodes(NodeList& list, bool isInput)
|
SettingsView::AddOutputNodes(NodeList& list)
|
||||||
{
|
{
|
||||||
BMenu* menu = isInput ? fInputMenu : fOutputMenu;
|
_EmptyMenu(fOutputMenu);
|
||||||
|
|
||||||
for (BMenuItem* item; (item = menu->RemoveItem((int32)0)) != NULL;)
|
BMessage message(MEDIA_DEFAULT_OUTPUT_CHANGE);
|
||||||
delete item;
|
_PopulateMenu(fOutputMenu, list, message);
|
||||||
|
|
||||||
BMessage message(ML_DEFAULT_CHANGE);
|
|
||||||
message.AddBool("isVideo", fIsVideo);
|
|
||||||
message.AddBool("isInput", isInput);
|
|
||||||
|
|
||||||
for (int32 i = 0; i < list.CountItems(); i++) {
|
|
||||||
dormant_node_info* info = list.ItemAt(i);
|
|
||||||
menu->AddItem(new SettingsItem(info, new BMessage(message)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SettingsView::SetDefault(dormant_node_info &info, bool isInput, int32 outputID)
|
SettingsView::SetDefaultInput(const dormant_node_info* info)
|
||||||
{
|
{
|
||||||
BMenu* menu = isInput ? fInputMenu : fOutputMenu;
|
_ClearMenuSelection(fInputMenu);
|
||||||
|
NodeMenuItem* item = _FindNodeItem(fInputMenu, info);
|
||||||
for (int32 i = 0; i < menu->CountItems(); i++) {
|
if (item)
|
||||||
SettingsItem* item = static_cast<SettingsItem*>(menu->ItemAt(i));
|
|
||||||
if (item->fInfo && item->fInfo->addon == info.addon
|
|
||||||
&& item->fInfo->flavor_id == info.flavor_id) {
|
|
||||||
item->SetMarked(true);
|
item->SetMarked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SettingsView::SetDefaultOutput(const dormant_node_info* info)
|
||||||
|
{
|
||||||
|
_ClearMenuSelection(fOutputMenu);
|
||||||
|
NodeMenuItem* item = _FindNodeItem(fOutputMenu, info);
|
||||||
|
if (item)
|
||||||
|
item->SetMarked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SettingsView::MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case MEDIA_DEFAULT_INPUT_CHANGE:
|
||||||
|
{
|
||||||
|
int32 index;
|
||||||
|
if (message->FindInt32("index", &index)!=B_OK)
|
||||||
|
break;
|
||||||
|
NodeMenuItem* item
|
||||||
|
= static_cast<NodeMenuItem*>(fInputMenu->ItemAt(index));
|
||||||
|
SetDefaultInput(item->NodeInfo());
|
||||||
|
RestartRequired(true);
|
||||||
|
}
|
||||||
|
case MEDIA_DEFAULT_OUTPUT_CHANGE:
|
||||||
|
{
|
||||||
|
int32 index;
|
||||||
|
if (message->FindInt32("index", &index)!=B_OK)
|
||||||
|
break;
|
||||||
|
NodeMenuItem* item
|
||||||
|
= static_cast<NodeMenuItem*>(fOutputMenu->ItemAt(index));
|
||||||
|
SetDefaultOutput(item->NodeInfo());
|
||||||
|
RestartRequired(true);
|
||||||
|
}
|
||||||
|
case ML_ENABLE_REAL_TIME:
|
||||||
|
{
|
||||||
|
uint32 flags = 0;
|
||||||
|
if (message->FindUInt32("flags", &flags) == B_OK)
|
||||||
|
_FlipRealtimeFlag(flags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BGridView::MessageReceived(message);
|
||||||
|
}
|
||||||
|
|
||||||
if (!fIsVideo && !isInput && outputID >= 0) {
|
|
||||||
BMenuItem* item;
|
|
||||||
while ((item = fChannelMenu->RemoveItem((int32)0)) != NULL)
|
|
||||||
delete item;
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SettingsView::AttachedToWindow()
|
||||||
|
{
|
||||||
|
BMessenger thisMessenger(this);
|
||||||
|
fInputMenu->SetTargetForItems(thisMessenger);
|
||||||
|
fOutputMenu->SetTargetForItems(thisMessenger);
|
||||||
|
fRealtimeCheckBox->SetTarget(thisMessenger);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SettingsView::RestartRequired(bool required)
|
||||||
|
{
|
||||||
|
if (required)
|
||||||
|
fRestartView->Show();
|
||||||
|
else
|
||||||
|
fRestartView->Hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MediaWindow*
|
||||||
|
SettingsView::_MediaWindow() const
|
||||||
|
{
|
||||||
|
return static_cast<MediaWindow*>(Window());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SettingsView::_FlipRealtimeFlag(uint32 mask)
|
||||||
|
{
|
||||||
|
// TODO: error codes
|
||||||
|
uint32 flags = 0;
|
||||||
BMediaRoster* roster = BMediaRoster::Roster();
|
BMediaRoster* roster = BMediaRoster::Roster();
|
||||||
media_node node;
|
roster->GetRealtimeFlags(&flags);
|
||||||
media_node_id node_id;
|
if (flags & mask)
|
||||||
status_t err;
|
flags &= ~mask;
|
||||||
if (roster->GetInstancesFor(info.addon, info.flavor_id,
|
else
|
||||||
&node_id) != B_OK) {
|
flags |= mask;
|
||||||
err = roster->InstantiateDormantNode(info, &node,
|
roster->SetRealtimeFlags(flags);
|
||||||
B_FLAVOR_IS_GLOBAL);
|
}
|
||||||
} else {
|
|
||||||
err = roster->GetNodeFor(node_id, &node);
|
|
||||||
|
void
|
||||||
|
SettingsView::_EmptyMenu(BMenu* menu)
|
||||||
|
{
|
||||||
|
while (menu->CountItems() > 0)
|
||||||
|
delete menu->RemoveItem((int32)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SettingsView::_PopulateMenu(BMenu* menu, NodeList& nodes,
|
||||||
|
const BMessage& message)
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i < nodes.CountItems(); i++) {
|
||||||
|
dormant_node_info* info = nodes.ItemAt(i);
|
||||||
|
menu->AddItem(new NodeMenuItem(info, new BMessage(message)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == B_OK) {
|
if (Window() != NULL)
|
||||||
media_input inputs[16];
|
menu->SetTargetForItems(BMessenger(this));
|
||||||
int32 inputCount = 16;
|
}
|
||||||
if (roster->GetAllInputsFor(node, inputs, 16, &inputCount)==B_OK) {
|
|
||||||
BMessage message(ML_DEFAULTOUTPUT_CHANGE);
|
|
||||||
|
|
||||||
for (int32 i = 0; i < inputCount; i++) {
|
|
||||||
media_input* input = new media_input();
|
NodeMenuItem*
|
||||||
memcpy(input, &inputs[i], sizeof(*input));
|
SettingsView::_FindNodeItem(BMenu* menu, const dormant_node_info* nodeInfo)
|
||||||
item = new Settings2Item(&info, input,
|
{
|
||||||
new BMessage(message));
|
for (int32 i = 0; i < menu->CountItems(); i++) {
|
||||||
fChannelMenu->AddItem(item);
|
NodeMenuItem* item = static_cast<NodeMenuItem*>(menu->ItemAt(i));
|
||||||
if (inputs[i].destination.id == outputID)
|
const dormant_node_info* itemInfo = item->NodeInfo();
|
||||||
item->SetMarked(true);
|
if (itemInfo && itemInfo->addon == nodeInfo->addon
|
||||||
}
|
&& itemInfo->flavor_id == nodeInfo->flavor_id) {
|
||||||
|
return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SettingsView::_ClearMenuSelection(BMenu* menu)
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i < menu->CountItems(); i++) {
|
||||||
|
BMenuItem* item = menu->ItemAt(i);
|
||||||
|
item->SetMarked(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SettingsItem::SettingsItem(dormant_node_info* info, BMessage* message,
|
NodeMenuItem::NodeMenuItem(const dormant_node_info* info, BMessage* message,
|
||||||
char shortcut, uint32 modifiers)
|
char shortcut, uint32 modifiers)
|
||||||
:
|
:
|
||||||
BMenuItem(info->name, message, shortcut, modifiers),
|
BMenuItem(info->name, message, shortcut, modifiers),
|
||||||
@@ -263,7 +302,7 @@ SettingsItem::SettingsItem(dormant_node_info* info, BMessage* message,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
SettingsItem::Invoke(BMessage* message)
|
NodeMenuItem::Invoke(BMessage* message)
|
||||||
{
|
{
|
||||||
if (IsMarked())
|
if (IsMarked())
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -271,27 +310,330 @@ SettingsItem::Invoke(BMessage* message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Settings2Item::Settings2Item(dormant_node_info* info, media_input* input,
|
ChannelMenuItem::ChannelMenuItem(media_input* input, BMessage* message,
|
||||||
BMessage* message, char shortcut, uint32 modifiers)
|
char shortcut, uint32 modifiers)
|
||||||
:
|
:
|
||||||
BMenuItem(input->name, message, shortcut, modifiers),
|
BMenuItem(input->name, message, shortcut, modifiers),
|
||||||
fInfo(info),
|
|
||||||
fInput(input)
|
fInput(input)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Settings2Item::~Settings2Item()
|
ChannelMenuItem::~ChannelMenuItem()
|
||||||
{
|
{
|
||||||
delete fInput;
|
delete fInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
ChannelMenuItem::DestinationID()
|
||||||
|
{
|
||||||
|
return fInput->destination.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
media_input*
|
||||||
|
ChannelMenuItem::Input()
|
||||||
|
{
|
||||||
|
return fInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Settings2Item::Invoke(BMessage* message)
|
ChannelMenuItem::Invoke(BMessage* message)
|
||||||
{
|
{
|
||||||
if (IsMarked())
|
if (IsMarked())
|
||||||
return B_OK;
|
return B_OK;
|
||||||
return BMenuItem::Invoke(message);
|
return BMenuItem::Invoke(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AudioSettingsView::AudioSettingsView()
|
||||||
|
{
|
||||||
|
BBox* defaultsBox = new BBox("defaults");
|
||||||
|
defaultsBox->SetLabel(B_TRANSLATE("Defaults"));
|
||||||
|
BGridView* defaultsGridView = new BGridView();
|
||||||
|
|
||||||
|
BMenuField* inputMenuField = new BMenuField("inputMenuField",
|
||||||
|
B_TRANSLATE("Audio input:"), InputMenu(), NULL);
|
||||||
|
|
||||||
|
BMenuField* outputMenuField = new BMenuField("outputMenuField",
|
||||||
|
B_TRANSLATE("Audio output:"), OutputMenu(), NULL);
|
||||||
|
|
||||||
|
BLayoutBuilder::Grid<>(defaultsGridView)
|
||||||
|
.SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING, 0)
|
||||||
|
.AddMenuField(inputMenuField, 0, 0, B_ALIGN_HORIZONTAL_UNSET, 1, 3, 1)
|
||||||
|
.AddMenuField(outputMenuField, 0, 1)
|
||||||
|
.AddMenuField(_MakeChannelMenu(), 2, 1)
|
||||||
|
.Add(MakeRestartMessageView(), 0, 2, 4, 1);
|
||||||
|
|
||||||
|
defaultsBox->AddChild(defaultsGridView);
|
||||||
|
|
||||||
|
const char* realtimeLabel = B_TRANSLATE("Enable real-time audio");
|
||||||
|
const char* realtimeInfo = B_TRANSLATE(
|
||||||
|
"Enabling real-time audio allows system to record and play audio "
|
||||||
|
"as fast as possible. It achieves this performance by using more"
|
||||||
|
" CPU and RAM.\n\nOnly enable this feature if you need the lowest"
|
||||||
|
" latency possible.");
|
||||||
|
|
||||||
|
|
||||||
|
BLayoutBuilder::Grid<>(this)
|
||||||
|
.SetInsets(0, 0, 0, 0)
|
||||||
|
.Add(defaultsBox, 0, 0, 2, 1)
|
||||||
|
.Add(MakeRealtimeBox(realtimeInfo, B_MEDIA_REALTIME_AUDIO,
|
||||||
|
realtimeLabel), 0, 1, 2, 1)
|
||||||
|
.Add(_MakeVolumeCheckBox(),0, 2, 1, 1)
|
||||||
|
.Add(MakeRestartButton(), 1, 2, 1, 1)
|
||||||
|
.SetRowWeight(1, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioSettingsView::SetDefaultChannel(int32 channelID)
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i < fChannelMenu->CountItems(); i++) {
|
||||||
|
ChannelMenuItem* item = _ChannelMenuItemAt(i);
|
||||||
|
item->SetMarked(item->DestinationID() == channelID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioSettingsView::AttachedToWindow()
|
||||||
|
{
|
||||||
|
SettingsView::AttachedToWindow();
|
||||||
|
|
||||||
|
BMessenger thisMessenger(this);
|
||||||
|
fChannelMenu->SetTargetForItems(thisMessenger);
|
||||||
|
fVolumeCheckBox->SetTarget(thisMessenger);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioSettingsView::MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case ML_DEFAULT_CHANNEL_CHANGED:
|
||||||
|
{
|
||||||
|
int32 index;
|
||||||
|
if (message->FindInt32("index", &index) != B_OK)
|
||||||
|
break;
|
||||||
|
ChannelMenuItem* item = _ChannelMenuItemAt(index);
|
||||||
|
|
||||||
|
if (item) {
|
||||||
|
BMediaRoster* roster = BMediaRoster::Roster();
|
||||||
|
roster->SetAudioOutput(*item->Input());
|
||||||
|
RestartRequired(true);
|
||||||
|
} else
|
||||||
|
fprintf(stderr, "ChannelMenuItem not found\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MEDIA_SHOW_HIDE_VOLUME_CONTROL:
|
||||||
|
{
|
||||||
|
if (fVolumeCheckBox->Value() == B_CONTROL_ON)
|
||||||
|
_ShowDeskbarVolumeControl();
|
||||||
|
else
|
||||||
|
_HideDeskbarVolumeControl();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
SettingsView::MessageReceived(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioSettingsView::SetDefaultInput(const dormant_node_info* info)
|
||||||
|
{
|
||||||
|
SettingsView::SetDefaultInput(info);
|
||||||
|
_MediaWindow()->UpdateInputListItem(MediaListItem::AUDIO_TYPE, info);
|
||||||
|
BMediaRoster::Roster()->SetAudioInput(*info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioSettingsView::SetDefaultOutput(const dormant_node_info* info)
|
||||||
|
{
|
||||||
|
SettingsView::SetDefaultOutput(info);
|
||||||
|
_MediaWindow()->UpdateOutputListItem(MediaListItem::AUDIO_TYPE, info);
|
||||||
|
_FillChannelMenu(info);
|
||||||
|
BMediaRoster::Roster()->SetAudioOutput(*info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BMenuField*
|
||||||
|
AudioSettingsView::_MakeChannelMenu()
|
||||||
|
{
|
||||||
|
fChannelMenu = new BPopUpMenu(B_TRANSLATE("<none>"));
|
||||||
|
fChannelMenu->SetLabelFromMarked(true);
|
||||||
|
BMenuField* channelMenuField = new BMenuField("channelMenuField",
|
||||||
|
B_TRANSLATE("Channel:"), fChannelMenu, NULL);
|
||||||
|
return channelMenuField;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BCheckBox*
|
||||||
|
AudioSettingsView::_MakeVolumeCheckBox()
|
||||||
|
{
|
||||||
|
fVolumeCheckBox = new BCheckBox("volumeCheckBox",
|
||||||
|
B_TRANSLATE("Show volume control on Deskbar"),
|
||||||
|
new BMessage(MEDIA_SHOW_HIDE_VOLUME_CONTROL));
|
||||||
|
|
||||||
|
if (BDeskbar().HasItem("MediaReplicant"))
|
||||||
|
fVolumeCheckBox->SetValue(B_CONTROL_ON);
|
||||||
|
|
||||||
|
return fVolumeCheckBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioSettingsView::_FillChannelMenu(const dormant_node_info* nodeInfo)
|
||||||
|
{
|
||||||
|
_EmptyMenu(fChannelMenu);
|
||||||
|
|
||||||
|
BMediaRoster* roster = BMediaRoster::Roster();
|
||||||
|
media_node node;
|
||||||
|
media_node_id node_id;
|
||||||
|
|
||||||
|
status_t err = roster->GetInstancesFor(nodeInfo->addon,
|
||||||
|
nodeInfo->flavor_id, &node_id);
|
||||||
|
if (err != B_OK) {
|
||||||
|
err = roster->InstantiateDormantNode(*nodeInfo, &node,
|
||||||
|
B_FLAVOR_IS_GLOBAL);
|
||||||
|
} else {
|
||||||
|
err = roster->GetNodeFor(node_id, &node);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == B_OK) {
|
||||||
|
int32 inputCount = 4;
|
||||||
|
media_input* inputs = new media_input[inputCount];
|
||||||
|
BPrivate::ArrayDeleter<media_input> inputDeleter(inputs);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int32 realInputCount = 0;
|
||||||
|
err = roster->GetAllInputsFor(node, inputs,
|
||||||
|
inputCount, &realInputCount);
|
||||||
|
if (realInputCount > inputCount) {
|
||||||
|
inputCount *= 2;
|
||||||
|
inputs = new media_input[inputCount];
|
||||||
|
inputDeleter.SetTo(inputs);
|
||||||
|
} else {
|
||||||
|
inputCount = realInputCount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == B_OK) {
|
||||||
|
BMessage message(ML_DEFAULT_CHANNEL_CHANGED);
|
||||||
|
|
||||||
|
for (int32 i = 0; i < inputCount; i++) {
|
||||||
|
media_input* input = new media_input();
|
||||||
|
memcpy(input, &inputs[i], sizeof(*input));
|
||||||
|
ChannelMenuItem* channelItem = new ChannelMenuItem(input,
|
||||||
|
new BMessage(message));
|
||||||
|
fChannelMenu->AddItem(channelItem);
|
||||||
|
|
||||||
|
if (channelItem->DestinationID() == 0)
|
||||||
|
channelItem->SetMarked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Window())
|
||||||
|
fChannelMenu->SetTargetForItems(BMessenger(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioSettingsView::_ShowDeskbarVolumeControl()
|
||||||
|
{
|
||||||
|
BDeskbar deskbar;
|
||||||
|
BEntry entry("/bin/desklink", true);
|
||||||
|
int32 id;
|
||||||
|
entry_ref ref;
|
||||||
|
status_t status = entry.GetRef(&ref);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = deskbar.AddItem(&ref, &id);
|
||||||
|
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, B_TRANSLATE(
|
||||||
|
"Couldn't add volume control in Deskbar: %s\n"),
|
||||||
|
strerror(status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioSettingsView::_HideDeskbarVolumeControl()
|
||||||
|
{
|
||||||
|
BDeskbar deskbar;
|
||||||
|
status_t status = deskbar.RemoveItem("MediaReplicant");
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, B_TRANSLATE(
|
||||||
|
"Couldn't remove volume control in Deskbar: %s\n"),
|
||||||
|
strerror(status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ChannelMenuItem*
|
||||||
|
AudioSettingsView::_ChannelMenuItemAt(int32 index)
|
||||||
|
{
|
||||||
|
return static_cast<ChannelMenuItem*>(fChannelMenu->ItemAt(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VideoSettingsView::VideoSettingsView()
|
||||||
|
{
|
||||||
|
BBox* defaultsBox = new BBox("defaults");
|
||||||
|
defaultsBox->SetLabel(B_TRANSLATE("Defaults"));
|
||||||
|
BGridView* defaultsGridView = new BGridView();
|
||||||
|
|
||||||
|
BMenuField* inputMenuField = new BMenuField("inputMenuField",
|
||||||
|
B_TRANSLATE("Video input:"), InputMenu(), NULL);
|
||||||
|
|
||||||
|
BMenuField* outputMenuField = new BMenuField("outputMenuField",
|
||||||
|
B_TRANSLATE("Video output:"), OutputMenu(), NULL);
|
||||||
|
|
||||||
|
BLayoutBuilder::Grid<>(defaultsGridView)
|
||||||
|
.SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING, 0)
|
||||||
|
.AddMenuField(inputMenuField, 0, 0)
|
||||||
|
.AddMenuField(outputMenuField, 0, 1)
|
||||||
|
.Add(MakeRestartMessageView(), 0, 2, 2, 1);
|
||||||
|
|
||||||
|
defaultsBox->AddChild(defaultsGridView);
|
||||||
|
|
||||||
|
const char* realtimeLabel = B_TRANSLATE("Enable real-time video");
|
||||||
|
const char* realtimeInfo = B_TRANSLATE(
|
||||||
|
"Enabling real-time video allows system to "
|
||||||
|
"perform video operations as fast and smoothly as possible. It "
|
||||||
|
"achieves optimum performance by using more RAM.\n\n"
|
||||||
|
"Only enable this feature if you need the lowest latency possible.");
|
||||||
|
|
||||||
|
BLayoutBuilder::Grid<>(this)
|
||||||
|
.SetInsets(0, 0, 0, 0)
|
||||||
|
.Add(defaultsBox, 0, 0, 2, 1)
|
||||||
|
.Add(MakeRealtimeBox(realtimeInfo, B_MEDIA_REALTIME_VIDEO,
|
||||||
|
realtimeLabel), 0, 1, 2, 1)
|
||||||
|
.Add(MakeRestartButton(), 1, 2, 1, 1)
|
||||||
|
.SetRowWeight(1, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
VideoSettingsView::SetDefaultInput(const dormant_node_info* info)
|
||||||
|
{
|
||||||
|
SettingsView::SetDefaultInput(info);
|
||||||
|
_MediaWindow()->UpdateInputListItem(MediaListItem::VIDEO_TYPE, info);
|
||||||
|
BMediaRoster::Roster()->SetVideoInput(*info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
VideoSettingsView::SetDefaultOutput(const dormant_node_info* info)
|
||||||
|
{
|
||||||
|
SettingsView::SetDefaultOutput(info);
|
||||||
|
_MediaWindow()->UpdateOutputListItem(MediaListItem::VIDEO_TYPE, info);
|
||||||
|
BMediaRoster::Roster()->SetVideoOutput(*info);
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,69 +14,145 @@
|
|||||||
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
||||||
#ifndef __MEDIAVIEWS_H__
|
#ifndef __MEDIAVIEWS_H__
|
||||||
#define __MEDIAVIEWS_H__
|
#define __MEDIAVIEWS_H__
|
||||||
#include <CheckBox.h>
|
#include <GridView.h>
|
||||||
#include <MediaAddOn.h>
|
#include <MediaAddOn.h>
|
||||||
#include <MenuItem.h>
|
#include <MenuItem.h>
|
||||||
#include <StringView.h>
|
|
||||||
#include <View.h>
|
|
||||||
|
|
||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
|
|
||||||
|
|
||||||
|
class BBox;
|
||||||
|
class BButton;
|
||||||
|
class BCheckBox;
|
||||||
|
class BMenu;
|
||||||
|
class BMenuField;
|
||||||
|
class BStringView;
|
||||||
|
|
||||||
|
class MediaWindow;
|
||||||
|
|
||||||
|
|
||||||
const uint32 ML_RESTART_MEDIA_SERVER = 'resr';
|
const uint32 ML_RESTART_MEDIA_SERVER = 'resr';
|
||||||
const uint32 ML_SHOW_VOLUME_CONTROL = 'shvc';
|
|
||||||
const uint32 ML_ENABLE_REAL_TIME = 'enrt';
|
const uint32 ML_ENABLE_REAL_TIME = 'enrt';
|
||||||
const uint32 ML_DEFAULT_CHANGE = 'dech';
|
const uint32 ML_DEFAULT_CHANNEL_CHANGED = 'chch';
|
||||||
const uint32 ML_DEFAULTOUTPUT_CHANGE = 'doch';
|
|
||||||
|
|
||||||
|
|
||||||
class SettingsItem : public BMenuItem
|
class NodeMenuItem : public BMenuItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SettingsItem(dormant_node_info* info,
|
NodeMenuItem(const dormant_node_info* info,
|
||||||
BMessage* message, char shortcut = 0,
|
BMessage* message, char shortcut = 0,
|
||||||
uint32 modifiers = 0);
|
uint32 modifiers = 0);
|
||||||
virtual status_t Invoke(BMessage* message = NULL);
|
virtual status_t Invoke(BMessage* message = NULL);
|
||||||
|
|
||||||
dormant_node_info* fInfo;
|
const dormant_node_info* NodeInfo() const {return fInfo;}
|
||||||
|
private:
|
||||||
|
|
||||||
|
const dormant_node_info* fInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Settings2Item : public BMenuItem
|
class ChannelMenuItem : public BMenuItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Settings2Item(dormant_node_info* info,
|
ChannelMenuItem(media_input* input,
|
||||||
media_input* input, BMessage* message,
|
BMessage* message, char shortcut = 0,
|
||||||
char shortcut = 0, uint32 modifiers = 0);
|
uint32 modifiers = 0);
|
||||||
virtual ~Settings2Item();
|
virtual ~ChannelMenuItem();
|
||||||
|
|
||||||
|
int32 DestinationID();
|
||||||
|
media_input* Input();
|
||||||
|
|
||||||
virtual status_t Invoke(BMessage* message = NULL);
|
virtual status_t Invoke(BMessage* message = NULL);
|
||||||
|
|
||||||
dormant_node_info* fInfo;
|
private:
|
||||||
media_input* fInput;
|
media_input* fInput;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class SettingsView : public BView
|
class SettingsView : public BGridView
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef BObjectList<dormant_node_info> NodeList;
|
typedef BObjectList<dormant_node_info> NodeList;
|
||||||
|
|
||||||
SettingsView(bool isVideo);
|
SettingsView();
|
||||||
void AddNodes(NodeList &nodes, bool isInput);
|
void AddInputNodes(NodeList& nodes);
|
||||||
void SetDefault(dormant_node_info &info,
|
void AddOutputNodes(NodeList& nodes);
|
||||||
bool isInput, int32 outputID = -1);
|
|
||||||
|
virtual void SetDefaultInput(const dormant_node_info* info);
|
||||||
|
virtual void SetDefaultOutput(const dormant_node_info* info);
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
|
||||||
|
void RestartRequired(bool required);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
BMenu* InputMenu() {return fInputMenu;}
|
||||||
|
BMenu* OutputMenu() {return fOutputMenu;}
|
||||||
|
|
||||||
|
BBox* MakeRealtimeBox(const char* info,
|
||||||
|
uint32 realtimeMask,
|
||||||
|
const char* checkboxLabel);
|
||||||
|
BStringView* MakeRestartMessageView();
|
||||||
|
BButton* MakeRestartButton();
|
||||||
|
|
||||||
|
void _EmptyMenu(BMenu* menu);
|
||||||
|
MediaWindow* _MediaWindow() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _FlipRealtimeFlag(uint32 mask);
|
||||||
|
|
||||||
|
void _PopulateMenu(BMenu* menu, NodeList& nodes,
|
||||||
|
const BMessage& message);
|
||||||
|
NodeMenuItem* _FindNodeItem(BMenu* menu,
|
||||||
|
const dormant_node_info* nodeInfo);
|
||||||
|
void _ClearMenuSelection(BMenu* menu);
|
||||||
|
|
||||||
BCheckBox* fRealtimeCheckBox;
|
BCheckBox* fRealtimeCheckBox;
|
||||||
BCheckBox* fVolumeCheckBox;
|
|
||||||
|
|
||||||
BMenu* fInputMenu;
|
BMenu* fInputMenu;
|
||||||
BMenu* fOutputMenu;
|
BMenu* fOutputMenu;
|
||||||
BMenu* fChannelMenu;
|
|
||||||
// (audio only)
|
|
||||||
BStringView* fRestartView;
|
BStringView* fRestartView;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class AudioSettingsView : public SettingsView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AudioSettingsView();
|
||||||
|
|
||||||
|
void SetDefaultChannel(int32 channelID);
|
||||||
|
|
||||||
|
virtual void SetDefaultInput(const dormant_node_info* info);
|
||||||
|
virtual void SetDefaultOutput(const dormant_node_info* info);
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool fIsVideo;
|
BMenuField* _MakeChannelMenu();
|
||||||
|
BCheckBox* _MakeVolumeCheckBox();
|
||||||
|
void _FillChannelMenu(const dormant_node_info* info);
|
||||||
|
|
||||||
|
void _ShowDeskbarVolumeControl();
|
||||||
|
void _HideDeskbarVolumeControl();
|
||||||
|
|
||||||
|
ChannelMenuItem* _ChannelMenuItemAt(int32 index);
|
||||||
|
|
||||||
|
BMenu* fChannelMenu;
|
||||||
|
BCheckBox* fVolumeCheckBox;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class VideoSettingsView : public SettingsView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VideoSettingsView();
|
||||||
|
|
||||||
|
virtual void SetDefaultInput(const dormant_node_info* info);
|
||||||
|
virtual void SetDefaultOutput(const dormant_node_info* info);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2005, Haiku, Inc.
|
* Copyright (c) 2003-2010, Haiku, Inc.
|
||||||
* Distributed under the terms of the MIT license.
|
* Distributed under the terms of the MIT license.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Sikosis, Jérôme Duval
|
* Sikosis, Jérôme Duval
|
||||||
|
* yourpalal, Alex Wilson
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -16,10 +17,11 @@
|
|||||||
#include <Autolock.h>
|
#include <Autolock.h>
|
||||||
#include <Bitmap.h>
|
#include <Bitmap.h>
|
||||||
#include <Button.h>
|
#include <Button.h>
|
||||||
|
#include <CardLayout.h>
|
||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
#include <Debug.h>
|
#include <Debug.h>
|
||||||
#include <Deskbar.h>
|
#include <Deskbar.h>
|
||||||
#include <GroupView.h>
|
#include <LayoutBuilder.h>
|
||||||
#include <Locale.h>
|
#include <Locale.h>
|
||||||
#include <MediaRoster.h>
|
#include <MediaRoster.h>
|
||||||
#include <MediaTheme.h>
|
#include <MediaTheme.h>
|
||||||
@@ -44,6 +46,34 @@ const uint32 ML_SELECTED_NODE = 'MlSN';
|
|||||||
const uint32 ML_INIT_MEDIA = 'MlIM';
|
const uint32 ML_INIT_MEDIA = 'MlIM';
|
||||||
|
|
||||||
|
|
||||||
|
class NodeListItemUpdater : public MediaListItem::Visitor {
|
||||||
|
public:
|
||||||
|
typedef void (NodeListItem::*UpdateMethod)(bool);
|
||||||
|
|
||||||
|
NodeListItemUpdater(NodeListItem* target, UpdateMethod action)
|
||||||
|
:
|
||||||
|
fComparator(target),
|
||||||
|
fAction(action)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void Visit(AudioMixerListItem*){}
|
||||||
|
virtual void Visit(DeviceListItem*){}
|
||||||
|
|
||||||
|
virtual void Visit(NodeListItem* item)
|
||||||
|
{
|
||||||
|
item->Accept(fComparator);
|
||||||
|
(item->*(fAction))(fComparator.result == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
NodeListItem::Comparator fComparator;
|
||||||
|
UpdateMethod fAction;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
MediaWindow::SmartNode::SmartNode(const BMessenger& notifyHandler)
|
MediaWindow::SmartNode::SmartNode(const BMessenger& notifyHandler)
|
||||||
:
|
:
|
||||||
fNode(NULL),
|
fNode(NULL),
|
||||||
@@ -59,17 +89,16 @@ MediaWindow::SmartNode::~SmartNode()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaWindow::SmartNode::SetTo(dormant_node_info* info)
|
MediaWindow::SmartNode::SetTo(const dormant_node_info* info)
|
||||||
{
|
{
|
||||||
_FreeNode();
|
_FreeNode();
|
||||||
if (!info)
|
if (!info)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fNode = new media_node();
|
fNode = new media_node();
|
||||||
|
|
||||||
// TODO: check error codes
|
|
||||||
BMediaRoster* roster = BMediaRoster::Roster();
|
BMediaRoster* roster = BMediaRoster::Roster();
|
||||||
|
|
||||||
|
// TODO: error codes
|
||||||
media_node_id node_id;
|
media_node_id node_id;
|
||||||
if (roster->GetInstancesFor(info->addon, info->flavor_id, &node_id) == B_OK)
|
if (roster->GetInstancesFor(info->addon, info->flavor_id, &node_id) == B_OK)
|
||||||
roster->GetNodeFor(node_id, fNode);
|
roster->GetNodeFor(node_id, fNode);
|
||||||
@@ -122,7 +151,7 @@ MediaWindow::SmartNode::_FreeNode()
|
|||||||
// 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(BMessenger(this)),
|
fCurrentNode(BMessenger(this)),
|
||||||
fParamWeb(NULL),
|
fParamWeb(NULL),
|
||||||
@@ -148,8 +177,6 @@ MediaWindow::~MediaWindow()
|
|||||||
{
|
{
|
||||||
_EmptyNodeLists();
|
_EmptyNodeLists();
|
||||||
_ClearParamView();
|
_ClearParamView();
|
||||||
delete fVideoView;
|
|
||||||
delete fAudioView;
|
|
||||||
|
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
BRect rect = Frame();
|
BRect rect = Frame();
|
||||||
@@ -169,7 +196,7 @@ MediaWindow::~MediaWindow()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaWindow::SelectNode(dormant_node_info* node)
|
MediaWindow::SelectNode(const dormant_node_info* node)
|
||||||
{
|
{
|
||||||
fCurrentNode.SetTo(node);
|
fCurrentNode.SetTo(node);
|
||||||
_MakeParamView();
|
_MakeParamView();
|
||||||
@@ -180,7 +207,7 @@ MediaWindow::SelectNode(dormant_node_info* node)
|
|||||||
void
|
void
|
||||||
MediaWindow::SelectAudioSettings(const char* title)
|
MediaWindow::SelectAudioSettings(const char* title)
|
||||||
{
|
{
|
||||||
fContentView->AddChild(fAudioView);
|
fContentLayout->SetVisibleItem(fContentLayout->IndexOfView(fAudioView));
|
||||||
fTitleView->SetLabel(title);
|
fTitleView->SetLabel(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +215,7 @@ MediaWindow::SelectAudioSettings(const char* title)
|
|||||||
void
|
void
|
||||||
MediaWindow::SelectVideoSettings(const char* title)
|
MediaWindow::SelectVideoSettings(const char* title)
|
||||||
{
|
{
|
||||||
fContentView->AddChild(fVideoView);
|
fContentLayout->SetVisibleItem(fContentLayout->IndexOfView(fVideoView));
|
||||||
fTitleView->SetLabel(title);
|
fTitleView->SetLabel(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,6 +232,34 @@ MediaWindow::SelectAudioMixer(const char* title)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaWindow::UpdateInputListItem(MediaListItem::media_type type,
|
||||||
|
const dormant_node_info* node)
|
||||||
|
{
|
||||||
|
NodeListItem compareTo(node, type);
|
||||||
|
NodeListItemUpdater updater(&compareTo, &NodeListItem::SetDefaultInput);
|
||||||
|
for (int32 i = 0; i < fListView->CountItems(); i++) {
|
||||||
|
MediaListItem* item = static_cast<MediaListItem*>(fListView->ItemAt(i));
|
||||||
|
item->Accept(updater);
|
||||||
|
}
|
||||||
|
fListView->Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaWindow::UpdateOutputListItem(MediaListItem::media_type type,
|
||||||
|
const dormant_node_info* node)
|
||||||
|
{
|
||||||
|
NodeListItem compareTo(node, type);
|
||||||
|
NodeListItemUpdater updater(&compareTo, &NodeListItem::SetDefaultOutput);
|
||||||
|
for (int32 i = 0; i < fListView->CountItems(); i++) {
|
||||||
|
MediaListItem* item = static_cast<MediaListItem*>(fListView->ItemAt(i));
|
||||||
|
item->Accept(updater);
|
||||||
|
}
|
||||||
|
fListView->Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaWindow::_FindNodes()
|
MediaWindow::_FindNodes()
|
||||||
{
|
{
|
||||||
@@ -249,7 +304,8 @@ MediaWindow::_FindNodes(media_type type, uint64 kind, NodeList& into)
|
|||||||
|
|
||||||
for (int32 i = 0; i < node_info_count; i++) {
|
for (int32 i = 0; i < node_info_count; i++) {
|
||||||
PRINT(("node : %s, media_addon %i, flavor_id %i\n",
|
PRINT(("node : %s, media_addon %i, flavor_id %i\n",
|
||||||
node_info[i].name, node_info[i].addon, node_info[i].flavor_id));
|
node_info[i].name, (int)node_info[i].addon,
|
||||||
|
(int)node_info[i].flavor_id));
|
||||||
|
|
||||||
dormant_node_info* info = new dormant_node_info();
|
dormant_node_info* info = new dormant_node_info();
|
||||||
strncpy(info->name, node_info[i].name, B_MEDIA_NAME_LENGTH);
|
strncpy(info->name, node_info[i].name, B_MEDIA_NAME_LENGTH);
|
||||||
@@ -263,14 +319,22 @@ MediaWindow::_FindNodes(media_type type, uint64 kind, NodeList& into)
|
|||||||
NodeListItem*
|
NodeListItem*
|
||||||
MediaWindow::_FindNodeListItem(dormant_node_info* info)
|
MediaWindow::_FindNodeListItem(dormant_node_info* info)
|
||||||
{
|
{
|
||||||
|
NodeListItem audioItem(info, MediaListItem::AUDIO_TYPE);
|
||||||
|
NodeListItem videoItem(info, MediaListItem::VIDEO_TYPE);
|
||||||
|
|
||||||
|
NodeListItem::Comparator audioComparator(&audioItem);
|
||||||
|
NodeListItem::Comparator videoComparator(&videoItem);
|
||||||
|
|
||||||
for (int32 i = 0; i < fListView->CountItems(); i++) {
|
for (int32 i = 0; i < fListView->CountItems(); i++) {
|
||||||
MediaListItem* item
|
MediaListItem* item
|
||||||
= static_cast<MediaListItem*>(fListView->ItemAt(i));
|
= static_cast<MediaListItem*>(fListView->ItemAt(i));
|
||||||
dormant_node_info* itemInfo = item->NodeInfo();
|
item->Accept(audioComparator);
|
||||||
if (itemInfo && itemInfo->addon == info->addon
|
if (audioComparator.result == 0)
|
||||||
&& itemInfo->flavor_id == info->flavor_id) {
|
return static_cast<NodeListItem*>(item);
|
||||||
return dynamic_cast<NodeListItem*>(item);
|
|
||||||
}
|
item->Accept(videoComparator);
|
||||||
|
if (videoComparator.result == 0)
|
||||||
|
return static_cast<NodeListItem*>(item);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -313,43 +377,35 @@ MediaWindow::InitWindow()
|
|||||||
scrollView->SetExplicitMaxSize(BSize(scrollWidth, B_SIZE_UNSET));
|
scrollView->SetExplicitMaxSize(BSize(scrollWidth, B_SIZE_UNSET));
|
||||||
|
|
||||||
// Create the Views
|
// Create the Views
|
||||||
fBox = new BBox("background", B_WILL_DRAW | B_FRAME_EVENTS,
|
|
||||||
B_PLAIN_BORDER);
|
|
||||||
SetLayout(new BGroupLayout(B_HORIZONTAL));
|
|
||||||
GetLayout()->AddView(fBox);
|
|
||||||
|
|
||||||
// StringViews
|
|
||||||
fTitleView = new BSeparatorView(B_HORIZONTAL, B_FANCY_BORDER);
|
fTitleView = new BSeparatorView(B_HORIZONTAL, B_FANCY_BORDER);
|
||||||
fTitleView->SetLabel(B_TRANSLATE("Audio settings"));
|
fTitleView->SetLabel(B_TRANSLATE("Audio settings"));
|
||||||
fTitleView->SetFont(be_bold_font);
|
fTitleView->SetFont(be_bold_font);
|
||||||
|
|
||||||
fContentView = new BBox("contentView", B_WILL_DRAW | B_FRAME_EVENTS,
|
fContentLayout = new BCardLayout();
|
||||||
B_NO_BORDER);
|
new BView("content view", 0, fContentLayout);
|
||||||
|
fContentLayout->Owner()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
|
||||||
fAudioView = new SettingsView(false);
|
fAudioView = new AudioSettingsView();
|
||||||
fVideoView = new SettingsView(true);
|
fContentLayout->AddView(fAudioView);
|
||||||
|
|
||||||
|
fVideoView = new VideoSettingsView();
|
||||||
|
fContentLayout->AddView(fVideoView);
|
||||||
|
|
||||||
|
|
||||||
// Layout all views
|
// Layout all views
|
||||||
BGroupView* rightView = new BGroupView(B_VERTICAL, 5);
|
BLayoutBuilder::Group<>(this, B_HORIZONTAL)
|
||||||
rightView->GroupLayout()->SetInsets(14, 0, 0, 0);
|
.SetInsets(14, 14, 14, 14)
|
||||||
rightView->GroupLayout()->AddView(fTitleView);
|
.Add(scrollView)
|
||||||
rightView->GroupLayout()->AddView(fContentView);
|
.AddGroup(B_VERTICAL)
|
||||||
|
.SetInsets(14, 0, 0, 0)
|
||||||
BGroupLayout* rootLayout = new BGroupLayout(B_HORIZONTAL);
|
.Add(fTitleView)
|
||||||
rootLayout->SetInsets(14, 14, 14, 14);
|
.Add(fContentLayout);
|
||||||
fBox->SetLayout(rootLayout);
|
|
||||||
|
|
||||||
rootLayout->AddView(scrollView);
|
|
||||||
|
|
||||||
rootLayout->AddView(rightView);
|
|
||||||
|
|
||||||
// Start the window
|
// Start the window
|
||||||
fInitCheck = InitMedia(true);
|
fInitCheck = InitMedia(true);
|
||||||
if (fInitCheck != B_OK) {
|
if (fInitCheck != B_OK) {
|
||||||
PostMessage(B_QUIT_REQUESTED);
|
PostMessage(B_QUIT_REQUESTED);
|
||||||
} else {
|
} else if (IsHidden()) {
|
||||||
if (IsHidden())
|
|
||||||
Show();
|
Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -412,10 +468,10 @@ MediaWindow::InitMedia(bool first)
|
|||||||
_AddNodeItems(fAudioOutputs, MediaListItem::AUDIO_TYPE);
|
_AddNodeItems(fAudioOutputs, MediaListItem::AUDIO_TYPE);
|
||||||
_AddNodeItems(fAudioInputs, MediaListItem::AUDIO_TYPE);
|
_AddNodeItems(fAudioInputs, MediaListItem::AUDIO_TYPE);
|
||||||
|
|
||||||
fAudioView->AddNodes(fAudioOutputs, false);
|
fAudioView->AddOutputNodes(fAudioOutputs);
|
||||||
fAudioView->AddNodes(fAudioInputs, true);
|
fAudioView->AddInputNodes(fAudioInputs);
|
||||||
fVideoView->AddNodes(fVideoOutputs, false);
|
fVideoView->AddOutputNodes(fVideoOutputs);
|
||||||
fVideoView->AddNodes(fVideoInputs, true);
|
fVideoView->AddInputNodes(fVideoInputs);
|
||||||
|
|
||||||
// build our list view
|
// build our list view
|
||||||
DeviceListItem* audio = new DeviceListItem(B_TRANSLATE("Audio settings"),
|
DeviceListItem* audio = new DeviceListItem(B_TRANSLATE("Audio settings"),
|
||||||
@@ -439,43 +495,34 @@ 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);
|
||||||
NodeListItem* item = _FindNodeListItem(&node_info);
|
fAudioView->SetDefaultInput(&node_info);
|
||||||
if (item)
|
// this causes our listview to be updated as well
|
||||||
item->SetDefaultInput(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);
|
||||||
NodeListItem* item = _FindNodeListItem(&node_info);
|
fAudioView->SetDefaultOutput(&node_info);
|
||||||
if (item)
|
fAudioView->SetDefaultChannel(outputID);
|
||||||
item->SetDefaultOutput(true);
|
// this causes our listview to be updated as well
|
||||||
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);
|
||||||
NodeListItem* item = _FindNodeListItem(&node_info);
|
fVideoView->SetDefaultInput(&node_info);
|
||||||
if (item)
|
// this causes our listview to be updated as well
|
||||||
item->SetDefaultInput(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);
|
||||||
NodeListItem* item = _FindNodeListItem(&node_info);
|
fVideoView->SetDefaultOutput(&node_info);
|
||||||
if (item)
|
// this causes our listview to be updated as well
|
||||||
item->SetDefaultOutput(true);
|
|
||||||
fVideoView->SetDefault(node_info, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
fListView->Select(fListView->IndexOf(mixer));
|
fListView->Select(fListView->IndexOf(mixer));
|
||||||
} else {
|
} else {
|
||||||
if (!fAudioView->fRestartView->IsHidden())
|
fAudioView->RestartRequired(false);
|
||||||
fAudioView->fRestartView->Hide();
|
fVideoView->RestartRequired(false);
|
||||||
if (!fVideoView->fRestartView->IsHidden())
|
|
||||||
fVideoView->fRestartView->Hide();
|
|
||||||
|
|
||||||
if (isVideoSelected)
|
if (isVideoSelected)
|
||||||
fListView->Select(fListView->IndexOf(video));
|
fListView->Select(fListView->IndexOf(video));
|
||||||
@@ -505,15 +552,6 @@ MediaWindow::QuitRequested()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
MediaWindow::FrameResized (float width, float height)
|
|
||||||
{
|
|
||||||
// This makes sure our SideBar colours down to the bottom when resized
|
|
||||||
BRect r;
|
|
||||||
r = Bounds();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ErrorAlert -- Displays a BAlert Box with a Custom Error or Debug Message
|
// ErrorAlert -- Displays a BAlert Box with a Custom Error or Debug Message
|
||||||
void
|
void
|
||||||
ErrorAlert(char* errorMessage) {
|
ErrorAlert(char* errorMessage) {
|
||||||
@@ -533,98 +571,6 @@ MediaWindow::MessageReceived(BMessage* message)
|
|||||||
case ML_INIT_MEDIA:
|
case ML_INIT_MEDIA:
|
||||||
InitMedia(false);
|
InitMedia(false);
|
||||||
break;
|
break;
|
||||||
case ML_DEFAULTOUTPUT_CHANGE:
|
|
||||||
{
|
|
||||||
int32 index;
|
|
||||||
if (message->FindInt32("index", &index)!=B_OK)
|
|
||||||
break;
|
|
||||||
Settings2Item* item = static_cast<Settings2Item*>(
|
|
||||||
fAudioView->fChannelMenu->ItemAt(index));
|
|
||||||
|
|
||||||
if (item) {
|
|
||||||
BMediaRoster* roster = BMediaRoster::Roster();
|
|
||||||
roster->SetAudioOutput(*item->fInput);
|
|
||||||
|
|
||||||
if (fAudioView->fRestartView->IsHidden())
|
|
||||||
fAudioView->fRestartView->Show();
|
|
||||||
} else
|
|
||||||
fprintf(stderr, "Settings2Item not found\n");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ML_DEFAULT_CHANGE:
|
|
||||||
{
|
|
||||||
bool isVideo = true;
|
|
||||||
bool isInput = true;
|
|
||||||
if (message->FindBool("isVideo", &isVideo)!=B_OK)
|
|
||||||
break;
|
|
||||||
if (message->FindBool("isInput", &isInput)!=B_OK)
|
|
||||||
break;
|
|
||||||
int32 index;
|
|
||||||
if (message->FindInt32("index", &index)!=B_OK)
|
|
||||||
break;
|
|
||||||
SettingsView* settingsView = isVideo ? fVideoView : fAudioView;
|
|
||||||
BMenu* menu = isInput ? settingsView->fInputMenu
|
|
||||||
: settingsView->fOutputMenu;
|
|
||||||
SettingsItem* item = static_cast<SettingsItem*>(
|
|
||||||
menu->ItemAt(index));
|
|
||||||
|
|
||||||
if (item) {
|
|
||||||
PRINT(("isVideo %i isInput %i\n", isVideo, isInput));
|
|
||||||
BMediaRoster* roster = BMediaRoster::Roster();
|
|
||||||
if (isVideo) {
|
|
||||||
if (isInput)
|
|
||||||
roster->SetVideoInput(*item->fInfo);
|
|
||||||
else
|
|
||||||
roster->SetVideoOutput(*item->fInfo);
|
|
||||||
} else {
|
|
||||||
if (isInput)
|
|
||||||
roster->SetAudioInput(*item->fInfo);
|
|
||||||
else {
|
|
||||||
roster->SetAudioOutput(*item->fInfo);
|
|
||||||
fAudioView->SetDefault(*item->fInfo, false, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeListItem* oldListItem = NULL;
|
|
||||||
MediaListItem::media_type mediaType = isVideo ?
|
|
||||||
MediaListItem::VIDEO_TYPE : MediaListItem::AUDIO_TYPE;
|
|
||||||
for (int32 j = 0; j < fListView->CountItems(); j++) {
|
|
||||||
NodeListItem* item = dynamic_cast<NodeListItem*>(
|
|
||||||
fListView->ItemAt(j));
|
|
||||||
if (!oldListItem)
|
|
||||||
continue;
|
|
||||||
if (oldListItem->Type() != mediaType)
|
|
||||||
continue;
|
|
||||||
if (isInput && !oldListItem->IsDefaultInput()) {
|
|
||||||
oldListItem = item;
|
|
||||||
break;
|
|
||||||
} else if (!isInput && oldListItem->IsDefaultOutput()) {
|
|
||||||
oldListItem = item;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (oldListItem && isInput)
|
|
||||||
oldListItem->SetDefaultInput(false);
|
|
||||||
else if (oldListItem && !isInput)
|
|
||||||
oldListItem->SetDefaultOutput(false);
|
|
||||||
else
|
|
||||||
fprintf(stderr, "oldListItem not found\n");
|
|
||||||
|
|
||||||
NodeListItem* listItem = _FindNodeListItem(item->fInfo);
|
|
||||||
if (listItem && isInput)
|
|
||||||
listItem->SetDefaultInput(true);
|
|
||||||
else if (listItem && !isInput)
|
|
||||||
listItem->SetDefaultOutput(true);
|
|
||||||
else
|
|
||||||
fprintf(stderr, "MediaListItem not found\n");
|
|
||||||
fListView->Invalidate();
|
|
||||||
|
|
||||||
if (settingsView->fRestartView->IsHidden())
|
|
||||||
settingsView->fRestartView->Show();
|
|
||||||
} else
|
|
||||||
fprintf(stderr, "SettingsItem not found\n");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ML_RESTART_MEDIA_SERVER:
|
case ML_RESTART_MEDIA_SERVER:
|
||||||
{
|
{
|
||||||
thread_id thread = spawn_thread(&MediaWindow::RestartMediaServices,
|
thread_id thread = spawn_thread(&MediaWindow::RestartMediaServices,
|
||||||
@@ -635,50 +581,6 @@ MediaWindow::MessageReceived(BMessage* message)
|
|||||||
resume_thread(thread);
|
resume_thread(thread);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ML_SHOW_VOLUME_CONTROL:
|
|
||||||
{
|
|
||||||
BDeskbar deskbar;
|
|
||||||
if (fAudioView->fVolumeCheckBox->Value() == B_CONTROL_ON) {
|
|
||||||
BEntry entry("/bin/desklink", true);
|
|
||||||
int32 id;
|
|
||||||
entry_ref ref;
|
|
||||||
status_t status = entry.GetRef(&ref);
|
|
||||||
if (status == B_OK)
|
|
||||||
status = deskbar.AddItem(&ref, &id);
|
|
||||||
|
|
||||||
if (status != B_OK) {
|
|
||||||
fprintf(stderr, B_TRANSLATE(
|
|
||||||
"Couldn't add volume control in Deskbar: %s\n"),
|
|
||||||
strerror(status));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
status_t status = deskbar.RemoveItem("MediaReplicant");
|
|
||||||
if (status != B_OK) {
|
|
||||||
fprintf(stderr, B_TRANSLATE(
|
|
||||||
"Couldn't remove volume control in Deskbar: %s\n"),
|
|
||||||
strerror(status));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ML_ENABLE_REAL_TIME:
|
|
||||||
{
|
|
||||||
bool isVideo = true;
|
|
||||||
if (message->FindBool("isVideo", &isVideo) != B_OK)
|
|
||||||
break;
|
|
||||||
SettingsView* settingsView = isVideo ? fVideoView : fAudioView;
|
|
||||||
uint32 flags;
|
|
||||||
uint32 realtimeFlag = isVideo
|
|
||||||
? B_MEDIA_REALTIME_VIDEO : B_MEDIA_REALTIME_AUDIO;
|
|
||||||
BMediaRoster* roster = BMediaRoster::Roster();
|
|
||||||
roster->GetRealtimeFlags(&flags);
|
|
||||||
if (settingsView->fRealtimeCheckBox->Value() == B_CONTROL_ON)
|
|
||||||
flags |= realtimeFlag;
|
|
||||||
else
|
|
||||||
flags &= ~realtimeFlag;
|
|
||||||
roster->SetRealtimeFlags(flags);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case B_MEDIA_WEB_CHANGED:
|
case B_MEDIA_WEB_CHANGED:
|
||||||
case ML_SELECTED_NODE:
|
case ML_SELECTED_NODE:
|
||||||
{
|
{
|
||||||
@@ -692,8 +594,8 @@ MediaWindow::MessageReceived(BMessage* message)
|
|||||||
fCurrentNode.SetTo(NULL);
|
fCurrentNode.SetTo(NULL);
|
||||||
_ClearParamView();
|
_ClearParamView();
|
||||||
item->AlterWindow(this);
|
item->AlterWindow(this);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case B_SOME_APP_LAUNCHED:
|
case B_SOME_APP_LAUNCHED:
|
||||||
{
|
{
|
||||||
PRINT_OBJECT(*message);
|
PRINT_OBJECT(*message);
|
||||||
@@ -791,13 +693,18 @@ MediaWindow::UpdateProgress(int stage, const char * message, void * cookie)
|
|||||||
void
|
void
|
||||||
MediaWindow::_ClearParamView()
|
MediaWindow::_ClearParamView()
|
||||||
{
|
{
|
||||||
BView* child = fContentView->ChildAt(0);
|
BLayoutItem* item = fContentLayout->VisibleItem();
|
||||||
if (child)
|
if (!item)
|
||||||
child->RemoveSelf();
|
return;
|
||||||
if (child != fVideoView && child != fAudioView)
|
|
||||||
delete child;
|
BView* view = item->View();
|
||||||
|
if (view != fVideoView && view != fAudioView) {
|
||||||
|
fContentLayout->RemoveItem(item);
|
||||||
|
delete item;
|
||||||
|
delete view;
|
||||||
delete fParamWeb;
|
delete fParamWeb;
|
||||||
fParamWeb = NULL;
|
fParamWeb = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -810,17 +717,16 @@ MediaWindow::_MakeParamView()
|
|||||||
fParamWeb = NULL;
|
fParamWeb = NULL;
|
||||||
BMediaRoster* roster = BMediaRoster::Roster();
|
BMediaRoster* roster = BMediaRoster::Roster();
|
||||||
if (roster->GetParameterWebFor(fCurrentNode, &fParamWeb) == B_OK) {
|
if (roster->GetParameterWebFor(fCurrentNode, &fParamWeb) == B_OK) {
|
||||||
BView* paramView = BMediaTheme::ViewFor(fParamWeb);
|
BRect hint(fContentLayout->Frame());
|
||||||
|
BView* paramView = BMediaTheme::ViewFor(fParamWeb, &hint);
|
||||||
if (paramView) {
|
if (paramView) {
|
||||||
fContentView->AddChild(paramView);
|
fContentLayout->AddView(paramView);
|
||||||
paramView->ResizeTo(1, 1);
|
fContentLayout->SetVisibleItem(fContentLayout->CountItems() - 1);
|
||||||
// make sure we don't get stuck with a very large
|
|
||||||
// paramView
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_MakeEmptyParamView();
|
|
||||||
|
|
||||||
|
_MakeEmptyParamView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -840,7 +746,8 @@ MediaWindow::_MakeEmptyParamView()
|
|||||||
stringView->SetExplicitAlignment(centered);
|
stringView->SetExplicitAlignment(centered);
|
||||||
stringView->SetAlignment(B_ALIGN_CENTER);
|
stringView->SetAlignment(B_ALIGN_CENTER);
|
||||||
|
|
||||||
fContentView->AddChild(stringView);
|
fContentLayout->AddView(stringView);
|
||||||
|
fContentLayout->SetVisibleItem(fContentLayout->CountItems() - 1);
|
||||||
|
|
||||||
rgb_color panel = stringView->LowColor();
|
rgb_color panel = stringView->LowColor();
|
||||||
stringView->SetHighColor(tint_color(panel,
|
stringView->SetHighColor(tint_color(panel,
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
#define __MEDIAWINDOWS_H__
|
#define __MEDIAWINDOWS_H__
|
||||||
|
|
||||||
|
|
||||||
#include <Box.h>
|
|
||||||
#include <ListView.h>
|
#include <ListView.h>
|
||||||
#include <MediaAddOn.h>
|
#include <MediaAddOn.h>
|
||||||
#include <ParameterWeb.h>
|
#include <ParameterWeb.h>
|
||||||
@@ -34,6 +33,7 @@
|
|||||||
#define SETTINGS_FILE "MediaPrefs Settings"
|
#define SETTINGS_FILE "MediaPrefs Settings"
|
||||||
|
|
||||||
|
|
||||||
|
class BCardLayout;
|
||||||
class BSeparatorView;
|
class BSeparatorView;
|
||||||
// struct dormant_node_info;
|
// struct dormant_node_info;
|
||||||
|
|
||||||
@@ -46,15 +46,21 @@ public:
|
|||||||
status_t InitCheck();
|
status_t InitCheck();
|
||||||
|
|
||||||
// methods to be called by MediaListItems...
|
// methods to be called by MediaListItems...
|
||||||
void SelectNode(dormant_node_info* node);
|
void SelectNode(const dormant_node_info* node);
|
||||||
void SelectAudioSettings(const char* title);
|
void SelectAudioSettings(const char* title);
|
||||||
void SelectVideoSettings(const char* title);
|
void SelectVideoSettings(const char* title);
|
||||||
void SelectAudioMixer(const char* title);
|
void SelectAudioMixer(const char* title);
|
||||||
|
|
||||||
|
// methods to be called by SettingsViews...
|
||||||
|
void UpdateInputListItem(
|
||||||
|
MediaListItem::media_type type,
|
||||||
|
const dormant_node_info* node);
|
||||||
|
void UpdateOutputListItem(
|
||||||
|
MediaListItem::media_type type,
|
||||||
|
const dormant_node_info* node);
|
||||||
|
|
||||||
virtual bool QuitRequested();
|
virtual bool QuitRequested();
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
virtual void FrameResized(float width, float height);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -83,7 +89,7 @@ private:
|
|||||||
struct SmartNode {
|
struct SmartNode {
|
||||||
SmartNode(const BMessenger& notifyHandler);
|
SmartNode(const BMessenger& notifyHandler);
|
||||||
~SmartNode();
|
~SmartNode();
|
||||||
void SetTo(dormant_node_info* node);
|
void SetTo(const dormant_node_info* node);
|
||||||
void SetTo(const media_node& node);
|
void SetTo(const media_node& node);
|
||||||
bool IsSet();
|
bool IsSet();
|
||||||
operator media_node();
|
operator media_node();
|
||||||
@@ -94,12 +100,11 @@ private:
|
|||||||
BMessenger fMessenger;
|
BMessenger fMessenger;
|
||||||
};
|
};
|
||||||
|
|
||||||
BBox* fBox;
|
|
||||||
BListView* fListView;
|
BListView* fListView;
|
||||||
BSeparatorView* fTitleView;
|
BSeparatorView* fTitleView;
|
||||||
BView* fContentView;
|
BCardLayout* fContentLayout;
|
||||||
SettingsView* fAudioView;
|
AudioSettingsView* fAudioView;
|
||||||
SettingsView* fVideoView;
|
VideoSettingsView* fVideoView;
|
||||||
|
|
||||||
SmartNode fCurrentNode;
|
SmartNode fCurrentNode;
|
||||||
BParameterWeb* fParamWeb;
|
BParameterWeb* fParamWeb;
|
||||||
|
|||||||
Reference in New Issue
Block a user