Replace hardcoded window index w window-targeting
For a replicant, the target-window can now be selected by either novelty, file-type, or an explicit index.
This commit is contained in:
parent
44eda8ab54
commit
f67161ff12
|
@ -11,9 +11,15 @@
|
||||||
#include "Song.h"
|
#include "Song.h"
|
||||||
|
|
||||||
|
|
||||||
MediaPlayer::MediaPlayer(int32 window)
|
// This seems a fair amount of Pulse()-es to wait before spam-checking windows.
|
||||||
|
const int32 kTargetHops = 20;
|
||||||
|
|
||||||
|
|
||||||
|
MediaPlayer::MediaPlayer(int32 window, target followType)
|
||||||
{
|
{
|
||||||
fWindowIndex = window;
|
fWindowIndex = window;
|
||||||
|
fWindowTarget = followType;
|
||||||
|
fWindowTargetHops = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +27,9 @@ MediaPlayer::MediaPlayer(BMessage* data)
|
||||||
:
|
:
|
||||||
BArchivable(data)
|
BArchivable(data)
|
||||||
{
|
{
|
||||||
fWindowIndex = data->GetInt32("_window", 0);
|
fWindowIndex = data->GetInt32("_window", -1);
|
||||||
|
fWindowTarget = (target)data->GetInt32("_windowtype", MP_BY_TYPE_AUDIO);
|
||||||
|
fWindowTargetHops = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +38,7 @@ MediaPlayer::Archive(BMessage* data, bool deep) const
|
||||||
{
|
{
|
||||||
status_t status = BArchivable::Archive(data, deep);
|
status_t status = BArchivable::Archive(data, deep);
|
||||||
data->AddInt32("_window", fWindowIndex);
|
data->AddInt32("_window", fWindowIndex);
|
||||||
|
data->AddInt32("_windowtype", fWindowTarget);
|
||||||
data->AddString("class", "MediaPlayer");
|
data->AddString("class", "MediaPlayer");
|
||||||
data->AddString("add_on", APP_SIGNATURE);
|
data->AddString("add_on", APP_SIGNATURE);
|
||||||
return status;
|
return status;
|
||||||
|
@ -45,6 +54,16 @@ MediaPlayer::Instantiate(BMessage* data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
MediaPlayer::IsValid()
|
||||||
|
{
|
||||||
|
BString type;
|
||||||
|
BMessage send, reply;
|
||||||
|
_ScriptingCall("Suites", &send, &reply, MP_NO_TRACK, true);
|
||||||
|
return reply.FindString("suites", &type) == B_OK && type == "suite/vnd.Haiku-MediaPlayer";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MediaPlayer::IsPlaying()
|
MediaPlayer::IsPlaying()
|
||||||
{
|
{
|
||||||
|
@ -113,6 +132,33 @@ MediaPlayer::PlaylistItem(Song* song, int32 index, bool duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
MediaPlayer::Window()
|
||||||
|
{
|
||||||
|
if (fWindowTarget == MP_BY_INDEX || fWindowTargetHops-- > 0)
|
||||||
|
return fWindowIndex;
|
||||||
|
|
||||||
|
fWindowTargetHops = kTargetHops;
|
||||||
|
|
||||||
|
for (int32 i = CountWindows() - 1; i >= 0; i--) {
|
||||||
|
MediaPlayer mp(i, MP_BY_INDEX);
|
||||||
|
if (mp.IsValid()) {
|
||||||
|
if (fWindowTarget == MP_BY_LATEST)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
Song current;
|
||||||
|
BString type;
|
||||||
|
if (CurrentItem(¤t, false)
|
||||||
|
&& BNode(current.Path().Path()).ReadAttrString("BEOS:TYPE", &type) == B_OK)
|
||||||
|
if ((type.StartsWith("audio") && fWindowTarget == MP_BY_TYPE_AUDIO)
|
||||||
|
|| (type.StartsWith("video") && fWindowTarget == MP_BY_TYPE_VIDEO))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fWindowIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
MediaPlayer::SetWindow(int32 index)
|
MediaPlayer::SetWindow(int32 index)
|
||||||
{
|
{
|
||||||
|
@ -127,7 +173,7 @@ int32
|
||||||
MediaPlayer::CountWindows()
|
MediaPlayer::CountWindows()
|
||||||
{
|
{
|
||||||
BMessage send(B_COUNT_PROPERTIES), reply;
|
BMessage send(B_COUNT_PROPERTIES), reply;
|
||||||
_ScriptingCall("Window", &send, &reply, MP_NO_TRACK);
|
_ScriptingCall("Window", &send, &reply, MP_NO_TRACK, false);
|
||||||
|
|
||||||
int32 count;
|
int32 count;
|
||||||
if (reply.FindInt32("result", &count) == B_OK)
|
if (reply.FindInt32("result", &count) == B_OK)
|
||||||
|
@ -136,8 +182,23 @@ MediaPlayer::CountWindows()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
target
|
||||||
|
MediaPlayer::Target()
|
||||||
|
{
|
||||||
|
return fWindowTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
target
|
||||||
|
MediaPlayer::SetTarget(target target)
|
||||||
|
{
|
||||||
|
fWindowTargetHops = 0;
|
||||||
|
return fWindowTarget = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MediaPlayer::_GetSong(Song* song, int32 trackIndex, bool durationRequired)
|
MediaPlayer::_GetSong(Song* song, int32 trackIndex, bool durationReq)
|
||||||
{
|
{
|
||||||
BMessage send, reply;
|
BMessage send, reply;
|
||||||
_ScriptingCall("URI", &send, &reply, trackIndex);
|
_ScriptingCall("URI", &send, &reply, trackIndex);
|
||||||
|
@ -146,19 +207,25 @@ MediaPlayer::_GetSong(Song* song, int32 trackIndex, bool durationRequired)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int64 duration = -1;
|
int64 duration = -1;
|
||||||
if (durationRequired) {
|
if (durationReq) {
|
||||||
_ScriptingCall("Duration", &send, &reply, trackIndex);
|
_ScriptingCall("Duration", &send, &reply, trackIndex);
|
||||||
if (reply.FindInt64("result", &duration) != B_OK)
|
if (reply.FindInt64("result", &duration) != B_OK)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trackIndex == MP_CURRENT_TRACK && fWindowTarget != MP_BY_INDEX
|
||||||
|
&& uriString != fLastItemPath) {
|
||||||
|
fLastItemPath.SetTo(uriString);
|
||||||
|
fWindowTargetHops = 0;
|
||||||
|
}
|
||||||
*song = Song(_UriToPath(uriString), duration);
|
*song = Song(_UriToPath(uriString), duration);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaPlayer::_ScriptingCall(const char* attribute, BMessage* send, BMessage* reply, int32 trackIndex)
|
MediaPlayer::_ScriptingCall(const char* attribute, BMessage* send, BMessage* reply, int32 trackIndex,
|
||||||
|
bool window)
|
||||||
{
|
{
|
||||||
if (send->what == 0)
|
if (send->what == 0)
|
||||||
send->what = B_GET_PROPERTY;
|
send->what = B_GET_PROPERTY;
|
||||||
|
@ -169,9 +236,14 @@ MediaPlayer::_ScriptingCall(const char* attribute, BMessage* send, BMessage* rep
|
||||||
else if (trackIndex == MP_CURRENT_TRACK)
|
else if (trackIndex == MP_CURRENT_TRACK)
|
||||||
send->AddSpecifier("CurrentTrack");
|
send->AddSpecifier("CurrentTrack");
|
||||||
|
|
||||||
send->AddSpecifier("Window", fWindowIndex);
|
if (window)
|
||||||
|
send->AddSpecifier("Window", Window());
|
||||||
|
|
||||||
BMessenger("application/x-vnd.Haiku-MediaPlayer").SendMessage(send, reply);
|
if (BMessenger("application/x-vnd.Haiku-MediaPlayer").SendMessage(send, reply) != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (reply != NULL && reply->what == B_MESSAGE_NOT_UNDERSTOOD)
|
||||||
|
fWindowTargetHops = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,14 +19,23 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum target {
|
||||||
|
MP_BY_INDEX,
|
||||||
|
MP_BY_TYPE_AUDIO,
|
||||||
|
MP_BY_TYPE_VIDEO,
|
||||||
|
MP_BY_LATEST
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class MediaPlayer : public BArchivable {
|
class MediaPlayer : public BArchivable {
|
||||||
public:
|
public:
|
||||||
MediaPlayer(int32 window = 0);
|
MediaPlayer(int32 window = 0, target followType = MP_BY_TYPE_AUDIO);
|
||||||
MediaPlayer(BMessage* archive);
|
MediaPlayer(BMessage* archive);
|
||||||
|
|
||||||
virtual status_t Archive(BMessage* data, bool deep = true) const;
|
virtual status_t Archive(BMessage* data, bool deep = true) const;
|
||||||
static MediaPlayer* Instantiate(BMessage* data);
|
static MediaPlayer* Instantiate(BMessage* data);
|
||||||
|
|
||||||
|
bool IsValid();
|
||||||
|
|
||||||
bool IsPlaying();
|
bool IsPlaying();
|
||||||
int64 Duration();
|
int64 Duration();
|
||||||
|
@ -38,16 +47,25 @@ public:
|
||||||
bool CurrentItem(Song* song, bool duration = true);
|
bool CurrentItem(Song* song, bool duration = true);
|
||||||
bool PlaylistItem(Song* song, int32 index, bool duration = true);
|
bool PlaylistItem(Song* song, int32 index, bool duration = true);
|
||||||
|
|
||||||
|
int32 Window();
|
||||||
int32 SetWindow(int32 index);
|
int32 SetWindow(int32 index);
|
||||||
int32 CountWindows();
|
int32 CountWindows();
|
||||||
|
|
||||||
|
target Target();
|
||||||
|
target SetTarget(target target);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _GetSong(Song* song, int32 trackIndex, bool durationRequired = true);
|
bool _GetSong(Song* song, int32 trackIndex, bool duration = true);
|
||||||
void _ScriptingCall(const char* attribute, BMessage* send, BMessage* reply,
|
void _ScriptingCall(const char* attribute, BMessage* send, BMessage* reply,
|
||||||
int32 trackIndex = MP_NO_TRACK);
|
int32 trackIndex = MP_NO_TRACK, bool window = true);
|
||||||
|
|
||||||
const char* _UriToPath(BString URI);
|
const char* _UriToPath(BString URI);
|
||||||
|
|
||||||
int32 fWindowIndex;
|
int32 fWindowIndex;
|
||||||
|
target fWindowTarget;
|
||||||
|
int32 fWindowTargetHops; // Amount of pulses to wait before re-checking windows
|
||||||
|
|
||||||
|
BString fLastItemPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MEDIAPLAYER_H
|
#endif // MEDIAPLAYER_H
|
||||||
|
|
|
@ -36,7 +36,7 @@ ReplicantView::ReplicantView(BRect frame, const char* name, uint32 draggerPlacem
|
||||||
fTransparentInactivity = false;
|
fTransparentInactivity = false;
|
||||||
fTransparentDragger = false;
|
fTransparentDragger = false;
|
||||||
|
|
||||||
fMediaPlayer = new MediaPlayer(0);
|
fMediaPlayer = new MediaPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,6 +89,25 @@ ReplicantView::MessageReceived(BMessage* msg)
|
||||||
{
|
{
|
||||||
switch (msg->what)
|
switch (msg->what)
|
||||||
{
|
{
|
||||||
|
case REPL_WIN_BY_AUDIO:
|
||||||
|
fMediaPlayer->SetTarget(MP_BY_TYPE_AUDIO);
|
||||||
|
break;
|
||||||
|
case REPL_WIN_BY_VIDEO:
|
||||||
|
fMediaPlayer->SetTarget(MP_BY_TYPE_VIDEO);
|
||||||
|
break;
|
||||||
|
case REPL_WIN_BY_LATEST:
|
||||||
|
fMediaPlayer->SetTarget(MP_BY_LATEST);
|
||||||
|
break;
|
||||||
|
case REPL_WIN_BY_INDEX:
|
||||||
|
{
|
||||||
|
int32 index = 0;
|
||||||
|
if (msg->FindInt32("index", &index) == B_OK) {
|
||||||
|
fMediaPlayer->SetTarget(MP_BY_INDEX);
|
||||||
|
fMediaPlayer->SetWindow(index);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case REPL_TRANSPARENTLY_INACTIVE:
|
case REPL_TRANSPARENTLY_INACTIVE:
|
||||||
case REPL_TRANSPARENTLY_DRAG: {
|
case REPL_TRANSPARENTLY_DRAG: {
|
||||||
if (msg->what == REPL_TRANSPARENTLY_INACTIVE)
|
if (msg->what == REPL_TRANSPARENTLY_INACTIVE)
|
||||||
|
@ -136,7 +155,6 @@ ReplicantView::RightClickPopUp(BPopUpMenu* menu)
|
||||||
|
|
||||||
BMenu* hideMenu = new BMenu("Hide when inactive");
|
BMenu* hideMenu = new BMenu("Hide when inactive");
|
||||||
menu->AddItem(hideMenu);
|
menu->AddItem(hideMenu);
|
||||||
|
|
||||||
BMenuItem* hideInactive = hideMenu->Superitem();
|
BMenuItem* hideInactive = hideMenu->Superitem();
|
||||||
hideInactive->SetMessage(new BMessage(REPL_TRANSPARENTLY_INACTIVE));
|
hideInactive->SetMessage(new BMessage(REPL_TRANSPARENTLY_INACTIVE));
|
||||||
hideInactive->SetMarked(fTransparentInactivity);
|
hideInactive->SetMarked(fTransparentInactivity);
|
||||||
|
@ -148,12 +166,29 @@ ReplicantView::RightClickPopUp(BPopUpMenu* menu)
|
||||||
hideDragger->SetTarget(this);
|
hideDragger->SetTarget(this);
|
||||||
hideMenu->AddItem(hideDragger);
|
hideMenu->AddItem(hideDragger);
|
||||||
|
|
||||||
|
BMenu* windowMenu = new BMenu("Target window…");
|
||||||
|
menu->AddItem(windowMenu);
|
||||||
|
|
||||||
|
BMenu* indexMenu = _WindowIndexMenu();
|
||||||
|
indexMenu->SetTargetForItems(this);
|
||||||
|
windowMenu->AddItem(indexMenu);
|
||||||
|
|
||||||
|
BMenu* typeMenu = new BMenu("By type…");
|
||||||
|
windowMenu->AddItem(typeMenu);
|
||||||
|
|
||||||
|
BMenuItem* audioItem = new BMenuItem("Audio", new BMessage(REPL_WIN_BY_AUDIO));
|
||||||
|
BMenuItem* videoItem = new BMenuItem("Video", new BMessage(REPL_WIN_BY_VIDEO));
|
||||||
|
audioItem->SetMarked(fMediaPlayer->Target() == MP_BY_TYPE_AUDIO);
|
||||||
|
videoItem->SetMarked(fMediaPlayer->Target() == MP_BY_TYPE_VIDEO);
|
||||||
|
typeMenu->AddItem(audioItem);
|
||||||
|
typeMenu->AddItem(videoItem);
|
||||||
|
typeMenu->SetTargetForItems(this);
|
||||||
|
|
||||||
menu->AddSeparatorItem();
|
menu->AddSeparatorItem();
|
||||||
|
|
||||||
BString aboutLabel = "About %replicant" B_UTF8_ELLIPSIS;
|
BString aboutLabel = "About %replicant" B_UTF8_ELLIPSIS;
|
||||||
aboutLabel.ReplaceAll("%replicant", Name());
|
aboutLabel.ReplaceAll("%replicant", Name());
|
||||||
BMenuItem* aboutItem = new BMenuItem(aboutLabel, new BMessage(B_ABOUT_REQUESTED));
|
BMenuItem* aboutItem = new BMenuItem(aboutLabel, new BMessage(B_ABOUT_REQUESTED));
|
||||||
aboutItem->SetTarget(this);
|
|
||||||
menu->AddItem(aboutItem);
|
menu->AddItem(aboutItem);
|
||||||
|
|
||||||
if (fReplicated) {
|
if (fReplicated) {
|
||||||
|
@ -182,3 +217,31 @@ ReplicantView::SetInactive(bool inactive)
|
||||||
|
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BMenu*
|
||||||
|
ReplicantView::_WindowIndexMenu()
|
||||||
|
{
|
||||||
|
BMenu* menu = new BMenu("By index…");
|
||||||
|
|
||||||
|
BMenuItem* latestItem = new BMenuItem("Latest", new BMessage(REPL_WIN_BY_LATEST));
|
||||||
|
latestItem->SetMarked(fMediaPlayer->Target() == MP_BY_LATEST);
|
||||||
|
menu->AddItem(latestItem);
|
||||||
|
|
||||||
|
int32 windowCount = fMediaPlayer->CountWindows();
|
||||||
|
for (int32 i = 0; i < windowCount; i++)
|
||||||
|
if (MediaPlayer(i, MP_BY_INDEX).IsValid()) {
|
||||||
|
BString label("");
|
||||||
|
label << i;
|
||||||
|
|
||||||
|
BMessage* msg = new BMessage(REPL_WIN_BY_INDEX);
|
||||||
|
msg->AddInt32("index", i);
|
||||||
|
|
||||||
|
BMenuItem* indexItem = new BMenuItem(label, msg);
|
||||||
|
indexItem->SetMarked(fMediaPlayer->Target() == MP_BY_INDEX
|
||||||
|
&& fMediaPlayer->Window() == i);
|
||||||
|
menu->AddItem(indexItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
|
@ -8,19 +8,18 @@
|
||||||
#include <View.h>
|
#include <View.h>
|
||||||
|
|
||||||
class BDragger;
|
class BDragger;
|
||||||
|
class BMenu;
|
||||||
class BPopUpMenu;
|
class BPopUpMenu;
|
||||||
class MediaPlayer;
|
class MediaPlayer;
|
||||||
|
|
||||||
|
|
||||||
enum {
|
|
||||||
MP_AUDIO_WINDOW = 'mpaw',
|
|
||||||
MP_VIDEO_WINDOW = 'mpvw',
|
|
||||||
MP_NEWEST_WINDOW = 'mpnw'
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
REPL_TRANSPARENTLY_INACTIVE = 'rtti',
|
REPL_TRANSPARENTLY_INACTIVE = 'rtti',
|
||||||
REPL_TRANSPARENTLY_DRAG = 'rttd'
|
REPL_TRANSPARENTLY_DRAG = 'rttd',
|
||||||
|
REPL_WIN_BY_INDEX = 'rwbi',
|
||||||
|
REPL_WIN_BY_LATEST = 'rwbl',
|
||||||
|
REPL_WIN_BY_AUDIO = 'rwba',
|
||||||
|
REPL_WIN_BY_VIDEO = 'rwbv'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,6 +52,9 @@ public:
|
||||||
// Set inactivity state, re-render accordingly
|
// Set inactivity state, re-render accordingly
|
||||||
virtual void SetInactive(bool inactive);
|
virtual void SetInactive(bool inactive);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BMenu* _WindowIndexMenu();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MediaPlayer* fMediaPlayer;
|
MediaPlayer* fMediaPlayer;
|
||||||
BDragger* fDragger;
|
BDragger* fDragger;
|
||||||
|
|
Ŝarĝante…
Reference in New Issue