[haiku-commits] r40127 - haiku/trunk/src/preferences/media

  • From: yourpalal2@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 5 Jan 2011 21:47:17 +0100 (CET)

Author: yourpalal
Date: 2011-01-05 21:47:17 +0100 (Wed, 05 Jan 2011)
New Revision: 40127
Changeset: http://dev.haiku-os.org/changeset/40127

Modified:
   haiku/trunk/src/preferences/media/Media.cpp
   haiku/trunk/src/preferences/media/MediaListItem.cpp
   haiku/trunk/src/preferences/media/MediaListItem.h
   haiku/trunk/src/preferences/media/MediaViews.cpp
   haiku/trunk/src/preferences/media/MediaViews.h
   haiku/trunk/src/preferences/media/MediaWindow.cpp
   haiku/trunk/src/preferences/media/MediaWindow.h
Log:
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


Modified: haiku/trunk/src/preferences/media/Media.cpp
===================================================================
--- haiku/trunk/src/preferences/media/Media.cpp 2011-01-05 20:05:09 UTC (rev 
40126)
+++ haiku/trunk/src/preferences/media/Media.cpp 2011-01-05 20:47:17 UTC (rev 
40127)
@@ -57,8 +57,8 @@
                }
        }
 
+       MediaListItem::SetIcons(&fIcons);
        fWindow = new MediaWindow(rect);
-       MediaListItem::SetIcons(&fIcons);
 
        be_roster->StartWatching(BMessenger(this));
 }

Modified: haiku/trunk/src/preferences/media/MediaListItem.cpp
===================================================================
--- haiku/trunk/src/preferences/media/MediaListItem.cpp 2011-01-05 20:05:09 UTC 
(rev 40126)
+++ haiku/trunk/src/preferences/media/MediaListItem.cpp 2011-01-05 20:47:17 UTC 
(rev 40127)
@@ -174,11 +174,10 @@
 // #pragma mark - NodeListItem
 
 
-NodeListItem::NodeListItem(dormant_node_info* node, media_type type)
+NodeListItem::NodeListItem(const dormant_node_info* node, media_type type)
        :
        MediaListItem(),
        fNodeInfo(node),
-       fIsAudioMixer(false),
        fMediaType(type),
        fIsDefaultInput(false),
        fIsDefaultOutput(false)
@@ -189,19 +188,14 @@
 void
 NodeListItem::SetRenderParameters(MediaListItem::Renderer& renderer)
 {
+       MediaIcons::IconSet* iconSet = &Icons()->videoIcons;
+       if (fMediaType == MediaListItem::AUDIO_TYPE)
+               iconSet = &Icons()->audioIcons;
 
-       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);
-       }
+       if (fIsDefaultInput)
+               renderer.AddIcon(&iconSet->inputIcon);
+       if (fIsDefaultOutput)
+               renderer.AddIcon(&iconSet->outputIcon);
 }
 
 
@@ -240,43 +234,58 @@
 }
 
 
-int
-NodeListItem::CompareWith(MediaListItem* item)
+void
+NodeListItem::Accept(MediaListItem::Visitor& visitor)
 {
-       return item->CompareWith(this) * -1;
+       visitor.Visit(this);
 }
 
 
 int
-NodeListItem::CompareWith(NodeListItem* item)
+NodeListItem::CompareWith(MediaListItem* item)
 {
-       if (fMediaType != item->fMediaType)
-               return fMediaType == AUDIO_TYPE ? GREATER_THAN : LESS_THAN;
+       Comparator comparator(this);
+       item->Accept(comparator);
+       return comparator.result;
+}
 
-       if (fIsAudioMixer != item->fIsAudioMixer)
-               return fIsAudioMixer ? GREATER_THAN : LESS_THAN;
 
-       return strcmp(Label(), item->Label());
+NodeListItem::Comparator::Comparator(NodeListItem* compareOthersTo)
+       :
+       result(GREATER_THAN),
+       fTarget(compareOthersTo)
+{
 }
 
 
-int
-NodeListItem::CompareWith(DeviceListItem* deviceItem)
+void
+NodeListItem::Comparator::Visit(NodeListItem* item)
 {
-       if (fMediaType != deviceItem->Type())
-               return fMediaType == AUDIO_TYPE ? GREATER_THAN : LESS_THAN;
+       result = GREATER_THAN;
+
+       if (fTarget->Type() != item->Type() && fTarget->Type() == VIDEO_TYPE)
+               result = LESS_THAN;
        else
-               return LESS_THAN;
+               result = strcmp(fTarget->Label(), item->Label());
 }
 
 
-int
-NodeListItem::CompareWith(AudioMixerListItem* item)
+void
+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;
+}
+
+
 // #pragma mark - DeviceListItem
 
 
@@ -290,39 +299,58 @@
 }
 
 
+void
+DeviceListItem::Accept(MediaListItem::Visitor& visitor)
+{
+       visitor.Visit(this);
+}
+
+
 int
 DeviceListItem::CompareWith(MediaListItem* item)
 {
-       return item->CompareWith(this) * -1;
+       Comparator comparator(this);
+       item->Accept(comparator);
+       return comparator.result;
 }
 
 
-int
-DeviceListItem::CompareWith(NodeListItem* item)
+DeviceListItem::Comparator::Comparator(DeviceListItem* compareOthersTo)
+       :
+       result(GREATER_THAN),
+       fTarget(compareOthersTo)
 {
-       // let NodeListItem do the work
-       return item->CompareWith(this) * -1;
 }
 
 
-int
-DeviceListItem::CompareWith(DeviceListItem* item)
+void
+DeviceListItem::Comparator::Visit(NodeListItem* item)
 {
-       if (fMediaType == MediaListItem::AUDIO_TYPE)
-               return GREATER_THAN;
-       return LESS_THAN;
+       result = GREATER_THAN;
+       if (fTarget->Type() != item->Type() && fTarget->Type() == AUDIO_TYPE)
+               result = LESS_THAN;
 }
 
 
-int
-DeviceListItem::CompareWith(AudioMixerListItem* item)
+void
+DeviceListItem::Comparator::Visit(DeviceListItem* item)
 {
-       // let AudioMixerListItem do the work too!
-       return item->CompareWith(this) * -1;
+       result = LESS_THAN;
+       if (fTarget->Type() == AUDIO_TYPE)
+               result = GREATER_THAN;
 }
 
 
 void
+DeviceListItem::Comparator::Visit(AudioMixerListItem* item)
+{
+       result = LESS_THAN;
+       if (fTarget->Type() == AUDIO_TYPE)
+               result = GREATER_THAN;
+}
+
+
+void
 DeviceListItem::SetRenderParameters(Renderer& renderer)
 {
        renderer.AddIcon(&Icons()->devicesIcon);
@@ -358,33 +386,50 @@
 }
 
 
+void
+AudioMixerListItem::Accept(MediaListItem::Visitor& visitor)
+{
+       visitor.Visit(this);
+}
+
+
 int
 AudioMixerListItem::CompareWith(MediaListItem* item)
 {
-       return item->CompareWith(this) * -1;
+       Comparator comparator(this);
+       item->Accept(comparator);
+       return comparator.result;
 }
 
 
-int
-AudioMixerListItem::CompareWith(NodeListItem* item)
+AudioMixerListItem::Comparator::Comparator(AudioMixerListItem* compareOthersTo)
+       :
+       result(0),
+       fTarget(compareOthersTo)
 {
-       return GREATER_THAN;
 }
 
 
-int
-AudioMixerListItem::CompareWith(DeviceListItem* item)
+void
+AudioMixerListItem::Comparator::Visit(NodeListItem* item)
 {
+       result = GREATER_THAN;
+}
+
+
+void
+AudioMixerListItem::Comparator::Visit(DeviceListItem* item)
+{
+       result = GREATER_THAN;
        if (item->Type() == AUDIO_TYPE)
-               return LESS_THAN;
-       return GREATER_THAN;
+               result = LESS_THAN;
 }
 
 
-int
-AudioMixerListItem::CompareWith(AudioMixerListItem* item)
+void
+AudioMixerListItem::Comparator::Visit(AudioMixerListItem* item)
 {
-       return 0;
+       result = 0;
 }
 
 

Modified: haiku/trunk/src/preferences/media/MediaListItem.h
===================================================================
--- haiku/trunk/src/preferences/media/MediaListItem.h   2011-01-05 20:05:09 UTC 
(rev 40126)
+++ haiku/trunk/src/preferences/media/MediaListItem.h   2011-01-05 20:47:17 UTC 
(rev 40127)
@@ -44,9 +44,6 @@
        virtual void                            Update(BView* owner, const 
BFont* font);
        virtual void                            DrawItem(BView* owner, BRect 
frame,
                                                                        bool 
complete = false);
-
-       // TODO: refactor and remove this:
-       virtual dormant_node_info*      NodeInfo() = 0;
        
        virtual const char*                     Label() = 0;
 
@@ -54,17 +51,21 @@
        static  MediaIcons*                     Icons() {return sIcons;}
        static  void                            SetIcons(MediaIcons* icons) 
{sIcons = icons;}
 
-       static  int                                     Compare(const void* 
itemOne,
-                                                                       const 
void* itemTwo);
+       struct Visitor {
+               virtual void                    Visit(AudioMixerListItem* item) 
= 0;
+               virtual void                    Visit(DeviceListItem* item) = 0;
+               virtual void                    Visit(NodeListItem* item) = 0;
+       };
 
-       // use double dispatch for comparison,
-       // returning item->CompareWith(this) * -1
+       virtual void                            Accept(Visitor& visitor) = 0;
+
+       // use the visitor pattern for comparison,
        // -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;
 
+       static  int                                     Compare(const void* 
itemOne,
+                                                                       const 
void* itemTwo);
+
 protected:
                        struct Renderer;
 
@@ -78,7 +79,7 @@
 
 class NodeListItem : public MediaListItem {
 public:
-                                                               
NodeListItem(dormant_node_info* node,
+                                                               
NodeListItem(const dormant_node_info* node,
                                                                        
media_type type);
 
                        void                            
SetMediaType(MediaListItem::media_type type);
@@ -89,25 +90,32 @@
 
        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);
+       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
-       virtual int                                     
CompareWith(NodeListItem* item);
-       virtual int                                     
CompareWith(DeviceListItem* item);
-       virtual int                                     
CompareWith(AudioMixerListItem* item);
+       virtual int                                     
CompareWith(MediaListItem* item);
 
 private:
 
        virtual void                            SetRenderParameters(Renderer& 
renderer);
 
-                       dormant_node_info*      fNodeInfo;
-                       bool                            fIsAudioMixer;
+                       const dormant_node_info* fNodeInfo;
+
                        media_type                      fMediaType;
                        bool                            fIsDefaultInput;
                        bool                            fIsDefaultOutput;
@@ -120,19 +128,24 @@
                                                                        
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 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
-       virtual int                                     
CompareWith(NodeListItem* item);
-       virtual int                                     
CompareWith(DeviceListItem* item);
-       virtual int                                     
CompareWith(AudioMixerListItem* item);
+       virtual int                                     
CompareWith(MediaListItem* item);
 
 private:
        virtual void                            SetRenderParameters(Renderer& 
renderer);
@@ -146,19 +159,25 @@
 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 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
-       virtual int                                     
CompareWith(NodeListItem* item);
-       virtual int                                     
CompareWith(DeviceListItem* item);
-       virtual int                                     
CompareWith(AudioMixerListItem* item);
+       virtual int                                     
CompareWith(MediaListItem* item);
 
 private:
        virtual void                            SetRenderParameters(Renderer& 
renderer);

Modified: haiku/trunk/src/preferences/media/MediaViews.cpp
===================================================================
--- haiku/trunk/src/preferences/media/MediaViews.cpp    2011-01-05 20:05:09 UTC 
(rev 40126)
+++ haiku/trunk/src/preferences/media/MediaViews.cpp    2011-01-05 20:47:17 UTC 
(rev 40127)
@@ -12,248 +12,287 @@
 //  Created :    June 25, 2003
 //
 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-
 #include "MediaViews.h"
 
+#include <AutoDeleter.h>
 #include <Box.h>
 #include <Button.h>
 #include <Catalog.h>
+#include <CheckBox.h>
 #include <Deskbar.h>
 #include <Entry.h>
-#include <GridView.h>
-#include <GroupView.h>
+#include <LayoutBuilder.h>
 #include <Locale.h>
 #include <MediaAddOn.h>
 #include <MediaRoster.h>
 #include <MenuField.h>
 #include <PopUpMenu.h>
-#include <SpaceLayoutItem.h>
 #include <String.h>
+#include <StringView.h>
 #include <TextView.h>
 
+#include <assert.h>
 #include <stdio.h>
 
+#include "MediaWindow.h"
 
+
 #undef B_TRANSLATE_CONTEXT
 #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),
-       fIsVideo(isVideo)
+       BGridView(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING),
+       fRealtimeCheckBox(NULL),
+       fInputMenu(NULL),
+       fOutputMenu(NULL),
+       fRestartView(NULL)
 {
-       SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
-
-       // create the default box
-
        // input menu
        fInputMenu = new BPopUpMenu(B_TRANSLATE("<none>"));
        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->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};
-       fRestartView = new BStringView("restartStringView",
-               B_TRANSLATE("Restart the media server to apply changes."));
-       fRestartView->SetHighColor(red_color);
-       defaultsBox->AddChild(fRestartView);
-       fRestartView->Hide();
-
+BBox*
+SettingsView::MakeRealtimeBox(const char* info, uint32 realtimeMask,
+       const char* checkBoxLabel)
+{
        // create the realtime box
        BBox* realtimeBox = new BBox("realtime");
        realtimeBox->SetLabel(B_TRANSLATE("Real-time"));
 
-       BMessage* message = new BMessage(ML_ENABLE_REAL_TIME);
-       message->AddBool("isVideo", fIsVideo);
-       fRealtimeCheckBox = new BCheckBox("realtimeCheckBox",
-               fIsVideo ? B_TRANSLATE("Enable real-time video")
-                       : B_TRANSLATE("Enable real-time audio"),
-               message);
+       BMessage* checkBoxMessage = new BMessage(ML_ENABLE_REAL_TIME);
+       checkBoxMessage->AddUInt32("flags", realtimeMask);
+       fRealtimeCheckBox = new BCheckBox("realtimeCheckBox", checkBoxLabel,
+               checkBoxMessage);
 
-       uint32 flags;
+       uint32 flags = 0;
        BMediaRoster::Roster()->GetRealtimeFlags(&flags);
-       if (flags & (fIsVideo ? B_MEDIA_REALTIME_VIDEO : 
B_MEDIA_REALTIME_AUDIO))
+       if (flags & realtimeMask)
                fRealtimeCheckBox->SetValue(B_CONTROL_ON);
 
        BTextView* textView = new BTextView("stringView");
-       textView->Insert(fIsVideo ? 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\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->Insert(info);
        textView->MakeEditable(false);
        textView->MakeSelectable(false);
        textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
 
-       BGroupLayout* realtimeBoxLayout = new BGroupLayout(B_VERTICAL, 5);
-       realtimeBoxLayout->SetInsets(10,10,10,10);
-       realtimeBox->SetLayout(realtimeBoxLayout);
+       BGroupView* realtimeGroup = new BGroupView(B_VERTICAL);
+       BLayoutBuilder::Group<>(realtimeGroup)
+               .SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING,
+                       B_USE_DEFAULT_SPACING)
+               .Add(fRealtimeCheckBox)
+               .Add(textView);
 
-       realtimeBoxLayout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(5));
-       realtimeBoxLayout->AddView(fRealtimeCheckBox);
-       realtimeBoxLayout->AddView(textView);
+       realtimeBox->AddChild(realtimeGroup);
+       return realtimeBox;
+}
 
-       // create the bottom line: volume in deskbar checkbox and restart button
-       BGroupView* bottomView = new BGroupView(B_HORIZONTAL);
-       BButton* restartButton = new BButton("restartButton",
+
+BStringView*
+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"),
                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);
-       rootlayout->AddView(realtimeBox);
-       rootlayout->AddView(bottomView);
+void
+SettingsView::AddInputNodes(NodeList& list)
+{
+       _EmptyMenu(fInputMenu);
+
+       BMessage message(MEDIA_DEFAULT_INPUT_CHANGE);
+       _PopulateMenu(fInputMenu, list, message);
 }
 
 
 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;)
-               delete item;
+       BMessage message(MEDIA_DEFAULT_OUTPUT_CHANGE);
+       _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
+SettingsView::SetDefaultInput(const dormant_node_info* info)
+{
+       _ClearMenuSelection(fInputMenu);
+       NodeMenuItem* item = _FindNodeItem(fInputMenu, info);
+       if (item)
+               item->SetMarked(true);
 }
 
 
 void
-SettingsView::SetDefault(dormant_node_info &info, bool isInput, int32 outputID)
+SettingsView::SetDefaultOutput(const dormant_node_info* info)
 {
-       BMenu* menu = isInput ? fInputMenu : fOutputMenu;
+       _ClearMenuSelection(fOutputMenu);
+       NodeMenuItem* item = _FindNodeItem(fOutputMenu, info);
+       if (item)
+               item->SetMarked(true);
+}
 
-       for (int32 i = 0; i < menu->CountItems(); i++) {
-               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);
+
+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;
                }
        }
+       BGridView::MessageReceived(message);
+}
 
-       if (!fIsVideo && !isInput && outputID >= 0) {
-               BMenuItem* item;
-               while ((item = fChannelMenu->RemoveItem((int32)0)) != NULL)
-                       delete item;
 
-               BMediaRoster* roster = BMediaRoster::Roster();
-               media_node node;
-               media_node_id node_id;
-               status_t err;
-               if (roster->GetInstancesFor(info.addon, info.flavor_id,
-                       &node_id) != B_OK) {
-                       err = roster->InstantiateDormantNode(info, &node, 
-                               B_FLAVOR_IS_GLOBAL);
-               } else {
-                       err = roster->GetNodeFor(node_id, &node);
-               }
+void
+SettingsView::AttachedToWindow()
+{
+       BMessenger thisMessenger(this);
+       fInputMenu->SetTargetForItems(thisMessenger);
+       fOutputMenu->SetTargetForItems(thisMessenger);
+       fRealtimeCheckBox->SetTarget(thisMessenger);
+}
 
-               if (err == B_OK) {
-                       media_input inputs[16];
-                       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();
-                                       memcpy(input, &inputs[i], 
sizeof(*input));
-                                       item = new Settings2Item(&info, input,
-                                               new BMessage(message));
-                                       fChannelMenu->AddItem(item);
-                                       if (inputs[i].destination.id == 
outputID)
-                                               item->SetMarked(true);
-                               }
-                       }
+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();
+       roster->GetRealtimeFlags(&flags);
+       if (flags & mask)
+               flags &= ~mask;
+       else
+               flags |= mask;
+       roster->SetRealtimeFlags(flags);
+}
+
+
+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 (Window() != NULL)
+               menu->SetTargetForItems(BMessenger(this));
+}
+
+
+NodeMenuItem*
+SettingsView::_FindNodeItem(BMenu* menu, const dormant_node_info* nodeInfo)
+{
+       for (int32 i = 0; i < menu->CountItems(); i++) {
+               NodeMenuItem* item = 
static_cast<NodeMenuItem*>(menu->ItemAt(i));
+               const dormant_node_info* itemInfo = item->NodeInfo();
+               if (itemInfo && itemInfo->addon == nodeInfo->addon
+                       && itemInfo->flavor_id == nodeInfo->flavor_id) {
+                       return item;
                }
        }
+       return NULL;
 }
 
 
-SettingsItem::SettingsItem(dormant_node_info* info, BMessage* message,
-               char shortcut, uint32 modifiers)
+void
+SettingsView::_ClearMenuSelection(BMenu* menu)
+{
+       for (int32 i = 0; i < menu->CountItems(); i++) {
+               BMenuItem* item = menu->ItemAt(i);
+               item->SetMarked(false);
+       }
+}
+
+
+NodeMenuItem::NodeMenuItem(const dormant_node_info* info, BMessage* message,
+       char shortcut, uint32 modifiers)
        :
        BMenuItem(info->name, message, shortcut, modifiers),
        fInfo(info)
@@ -263,7 +302,7 @@
 
 
 status_t
-SettingsItem::Invoke(BMessage* message)
+NodeMenuItem::Invoke(BMessage* message)
 {
        if (IsMarked())
                return B_OK;
@@ -271,27 +310,330 @@
 }
 
 
-Settings2Item::Settings2Item(dormant_node_info* info, media_input* input,
-               BMessage* message, char shortcut, uint32 modifiers)
+ChannelMenuItem::ChannelMenuItem(media_input* input, BMessage* message,
+       char shortcut, uint32 modifiers)
        :
        BMenuItem(input->name, message, shortcut, modifiers),
-       fInfo(info),
        fInput(input)
 {
 }
 
 
-Settings2Item::~Settings2Item()
+ChannelMenuItem::~ChannelMenuItem()
 {
        delete fInput;
 }
 
 
+int32
+ChannelMenuItem::DestinationID()
+{
+       return fInput->destination.id;
+}
+
+
+media_input*
+ChannelMenuItem::Input()
+{
+       return fInput;
+}
+
+
 status_t
-Settings2Item::Invoke(BMessage* message)
+ChannelMenuItem::Invoke(BMessage* message)
 {
        if (IsMarked())
                return B_OK;
        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);

[... truncated: 1065 lines follow ...]

Other related posts:

  • » [haiku-commits] r40127 - haiku/trunk/src/preferences/media - yourpalal2