Add auto-scrolling; Right-click menu with settings

Now three settings can be toggled through the right-click menu―
whether or not the view should be transparent when no lyrics are
available (or no music is playing); whether or not the dragger should
be, as well; and whether or not auto-scroll should be toggled.

Auto-scroll, when enabled, will scroll through the text automatically,
in proportion with current position in the song.
This commit is contained in:
Jaidyn Ann 2022-05-01 11:38:29 -05:00
parent 2316c1bf5f
commit 78dec2ec7e
2 changed files with 156 additions and 35 deletions

View File

@ -58,44 +58,22 @@ LyricsTextView::MouseDown(BPoint where)
Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons); Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons);
if (buttons & B_SECONDARY_MOUSE_BUTTON) if (buttons & B_SECONDARY_MOUSE_BUTTON)
_RightClickPopUp(where)->Go(ConvertToScreen(where), true, false); ((LyricsView*)Parent()->Parent())->MouseDown(
Parent()->ConvertToParent(ConvertToParent(where)));
else else
BTextView::MouseDown(where); BTextView::MouseDown(where);
} }
BPopUpMenu*
LyricsTextView::_RightClickPopUp(BPoint where)
{
BPopUpMenu* menu = new BPopUpMenu("rightClickPopUp");
BMenuItem* copy =
new BMenuItem("Copy", new BMessage(B_COPY), 'C', B_COMMAND_KEY);
BMenuItem* selectAll = new BMenuItem("Select all",
new BMessage(B_SELECT_ALL), 'A', B_COMMAND_KEY);
int32 start = -1, end = -1;
GetSelection(&start, &end);
copy->SetEnabled(start >= 0 && end > 0);
copy->SetTarget(this);
menu->AddItem(copy);
selectAll->SetTarget(this);
menu->AddItem(selectAll);
return menu;
}
LyricsView::LyricsView(BRect frame) LyricsView::LyricsView(BRect frame)
: :
BView(frame, "Lyrics", B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_TRANSPARENT_BACKGROUND | B_PULSE_NEEDED) BView(frame, "Lyrics", B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_TRANSPARENT_BACKGROUND | B_PULSE_NEEDED)
{ {
BRect dragRect(0, 0, 10, frame.Height()); BRect dragRect(0, 0, 10, frame.Height());
BDragger* airdrag = new BDragger(dragRect, this, fDragger = new BDragger(dragRect, this,
B_FOLLOW_LEFT | B_FOLLOW_BOTTOM, B_WILL_DRAW); B_FOLLOW_LEFT | B_FOLLOW_BOTTOM, B_WILL_DRAW);
airdrag->SetViewColor(B_TRANSPARENT_COLOR); fDragger->SetViewColor(B_TRANSPARENT_COLOR);
AddChild(airdrag); AddChild(fDragger);
BRect textRect(0, 0, Bounds().Width(), Bounds().Height() - 10); BRect textRect(0, 0, Bounds().Width(), Bounds().Height() - 10);
fTextView = new LyricsTextView(textRect, "lyricsText", textRect, fTextView = new LyricsTextView(textRect, "lyricsText", textRect,
@ -108,7 +86,10 @@ LyricsView::LyricsView(BRect frame)
fScrollView->ScrollBar(B_VERTICAL)->Hide(); fScrollView->ScrollBar(B_VERTICAL)->Hide();
AddChild(fScrollView); AddChild(fScrollView);
fTransparentInactivity = false; fAutoScroll = false;
fTransparentInactivity = true;
fTransparentDragger = false;
fFgColor = ui_color(B_PANEL_TEXT_COLOR); fFgColor = ui_color(B_PANEL_TEXT_COLOR);
fBgColor = ui_color(B_PANEL_BACKGROUND_COLOR); fBgColor = ui_color(B_PANEL_BACKGROUND_COLOR);
@ -120,15 +101,21 @@ LyricsView::LyricsView(BMessage* data)
: :
BView(data) BView(data)
{ {
fTransparentInactivity = false; fAutoScroll = false;
fTransparentInactivity = true;
fTransparentDragger = false;
fFgColor = ui_color(B_PANEL_TEXT_COLOR); fFgColor = ui_color(B_PANEL_TEXT_COLOR);
fBgColor = ui_color(B_PANEL_BACKGROUND_COLOR); fBgColor = ui_color(B_PANEL_BACKGROUND_COLOR);
fTextView = dynamic_cast<LyricsTextView*>(FindView("lyricsText")); fTextView = dynamic_cast<LyricsTextView*>(FindView("lyricsText"));
fScrollView = dynamic_cast<BScrollView*>(FindView("scrollView")); fScrollView = dynamic_cast<BScrollView*>(FindView("scrollView"));
fDragger = dynamic_cast<BDragger*>(FindView("_dragger_"));
data->FindColor("background_color", &fBgColor); data->FindColor("background_color", &fBgColor);
data->FindColor("foreground_color", &fFgColor); data->FindColor("foreground_color", &fFgColor);
data->FindBool("autoscroll", &fAutoScroll);
data->FindBool("transparent_inactivity", &fTransparentInactivity); data->FindBool("transparent_inactivity", &fTransparentInactivity);
data->FindBool("transparent_dragger", &fTransparentDragger);
_Init(Frame()); _Init(Frame());
} }
@ -140,10 +127,13 @@ LyricsView::Archive(BMessage* data, bool deep) const
status_t status = BView::Archive(data, deep); status_t status = BView::Archive(data, deep);
data->AddColor("background_color", fBgColor); data->AddColor("background_color", fBgColor);
data->AddColor("foreground_color", fFgColor); data->AddColor("foreground_color", fFgColor);
data->AddBool("autoscroll", fAutoScroll);
data->AddBool("transparent_inactivity", fTransparentInactivity); data->AddBool("transparent_inactivity", fTransparentInactivity);
data->AddBool("transparent_dragger", fTransparentDragger);
data->AddString("class", "LyricsView"); data->AddString("class", "LyricsView");
data->AddString("add_on", "application/x-vnd.mediamonitor"); data->AddString("add_on", "application/x-vnd.mediamonitor");
data->PrintToStream();
return status; return status;
} }
@ -178,8 +168,24 @@ LyricsView::MessageReceived(BMessage* msg)
_UpdateColors(); _UpdateColors();
break; break;
} }
case LYRICS_AUTO_SCROLL:
fAutoScroll = !fAutoScroll;
break;
case LYRICS_TRANSPARENTLY_INACTIVE:
case LYRICS_TRANSPARENTLY_DRAG: {
if (msg->what == LYRICS_TRANSPARENTLY_INACTIVE)
fTransparentInactivity = !fTransparentInactivity;
if (msg->what == LYRICS_TRANSPARENTLY_DRAG)
fTransparentDragger = !fTransparentDragger;
if (fCurrentPath.IsEmpty() == true)
_ClearText();
break;
}
default:
BView::MessageReceived(msg);
break;
} }
BView::MessageReceived(msg);
} }
@ -197,6 +203,23 @@ LyricsView::Pulse()
fCurrentPath = path; fCurrentPath = path;
_ClearText(); _ClearText();
} }
if (fAutoScroll == true) {
float position = _GetPositionProportion();
if (position > 0)
fTextView->ScrollToOffset(fTextView->TextLength() * position);
}
}
void
LyricsView::MouseDown(BPoint where)
{
uint32 buttons = 0;
Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons);
if (buttons & B_SECONDARY_MOUSE_BUTTON)
_RightClickPopUp()->Go(ConvertToScreen(where), true, false, true);
} }
@ -214,6 +237,8 @@ LyricsView::_SetText(const char* text)
{ {
if (fScrollView->IsHidden() == true) if (fScrollView->IsHidden() == true)
fScrollView->Show(); fScrollView->Show();
if (fDragger->IsHidden() == true)
fDragger->Show();
fTextView->SetText(text); fTextView->SetText(text);
fTextView->SetAlignment(B_ALIGN_LEFT); fTextView->SetAlignment(B_ALIGN_LEFT);
@ -223,8 +248,17 @@ LyricsView::_SetText(const char* text)
void void
LyricsView::_ClearText() LyricsView::_ClearText()
{ {
if (fScrollView->IsHidden() == false && fTransparentInactivity == true) if (fTransparentInactivity == true) {
fScrollView->Hide(); if (fScrollView->IsHidden() == false)
fScrollView->Hide();
if (fDragger->IsHidden() == false && fTransparentDragger == true)
fDragger->Hide();
} else {
if (fScrollView->IsHidden() == true)
fScrollView->Show();
if (fDragger->IsHidden() == true)
fDragger->Show();
}
fTextView->SetText("No lyrics to display!"); fTextView->SetText("No lyrics to display!");
fTextView->SetAlignment(B_ALIGN_CENTER); fTextView->SetAlignment(B_ALIGN_CENTER);
@ -253,6 +287,53 @@ LyricsView::_UpdateColors()
} }
BPopUpMenu*
LyricsView::_RightClickPopUp()
{
BPopUpMenu* menu = new BPopUpMenu("rightClickPopUp");
menu->SetRadioMode(false);
BMenuItem* copy =
new BMenuItem("Copy", new BMessage(B_COPY), 'C', B_COMMAND_KEY);
int32 start = -1, end = -1;
fTextView->GetSelection(&start, &end);
copy->SetEnabled(start >= 0 && end > 0);
copy->SetTarget(fTextView);
menu->AddItem(copy);
BMenuItem* selectAll = new BMenuItem("Select all",
new BMessage(B_SELECT_ALL), 'A', B_COMMAND_KEY);
selectAll->SetTarget(fTextView);
menu->AddItem(selectAll);
menu->AddSeparatorItem();
BMenuItem* autoScroll = new BMenuItem("Auto-scroll",
new BMessage(LYRICS_AUTO_SCROLL));
autoScroll->SetMarked(fAutoScroll);
autoScroll->SetTarget(this);
menu->AddItem(autoScroll);
BMenu* hideMenu = new BMenu("Hide when inactive");
menu->AddItem(hideMenu);
BMenuItem* hideInactive = hideMenu->Superitem();
hideInactive->SetMessage(new BMessage(LYRICS_TRANSPARENTLY_INACTIVE));
hideInactive->SetMarked(fTransparentInactivity);
hideInactive->SetTarget(this);
BMenuItem* hideDragger = new BMenuItem("… including the dragger",
new BMessage(LYRICS_TRANSPARENTLY_DRAG));
hideDragger->SetMarked(fTransparentDragger);
hideDragger->SetTarget(this);
hideMenu->AddItem(hideDragger);
return menu;
}
BString BString
LyricsView::_GetCurrentPath() LyricsView::_GetCurrentPath()
{ {
@ -266,3 +347,29 @@ LyricsView::_GetCurrentPath()
reply.FindString("result", &result); reply.FindString("result", &result);
return result.ReplaceAll("file://", ""); return result.ReplaceAll("file://", "");
} }
float
LyricsView::_GetPositionProportion()
{
int64 position = _GetIntProperty("Position");
int64 duration = _GetIntProperty("Duration");
if (position >= 0 && duration > 0)
return (float)position / (float)duration;
return -1.0;
}
int64
LyricsView::_GetIntProperty(const char* specifier)
{
BMessage message, reply;
message.what = B_GET_PROPERTY;
message.AddSpecifier(specifier);
message.AddSpecifier("Window", 0);
BMessenger("application/x-vnd.Haiku-MediaPlayer").SendMessage(&message, &reply);
int64 result = -1;
reply.FindInt64("result", &result);
return result;
}

View File

@ -7,10 +7,18 @@
#include <TextView.h> #include <TextView.h>
class BDragger;
class BPopUpMenu; class BPopUpMenu;
class BScrollView; class BScrollView;
enum {
LYRICS_AUTO_SCROLL = 'lvas',
LYRICS_TRANSPARENTLY_INACTIVE = 'lvti',
LYRICS_TRANSPARENTLY_DRAG = 'lvtd'
};
class LyricsTextView : public BTextView { class LyricsTextView : public BTextView {
public: public:
LyricsTextView(BRect frame, const char* name, BRect textFrame, LyricsTextView(BRect frame, const char* name, BRect textFrame,
@ -21,9 +29,6 @@ public:
static LyricsTextView* Instantiate(BMessage* data); static LyricsTextView* Instantiate(BMessage* data);
virtual void MouseDown(BPoint where); virtual void MouseDown(BPoint where);
private:
BPopUpMenu* _RightClickPopUp(BPoint where);
}; };
@ -38,6 +43,8 @@ public:
virtual void MessageReceived(BMessage* msg); virtual void MessageReceived(BMessage* msg);
virtual void Pulse(); virtual void Pulse();
virtual void MouseDown(BPoint where);
private: private:
void _Init(BRect frame); void _Init(BRect frame);
@ -46,12 +53,19 @@ private:
void _UpdateColors(); void _UpdateColors();
BPopUpMenu* _RightClickPopUp();
BString _GetCurrentPath(); BString _GetCurrentPath();
float _GetPositionProportion();
int64 _GetIntProperty(const char* specifier);
LyricsTextView* fTextView; LyricsTextView* fTextView;
BScrollView* fScrollView; BScrollView* fScrollView;
BDragger* fDragger;
bool fAutoScroll;
bool fTransparentInactivity; bool fTransparentInactivity;
bool fTransparentDragger;
rgb_color fBgColor; rgb_color fBgColor;
rgb_color fFgColor; rgb_color fFgColor;