Extended mouse support to ListOverlay, PreampOverlay and

TransportWindow.
This commit is contained in:
casey langen 2018-05-28 21:48:15 -07:00
parent 9e410eb739
commit 56209e84ff
5 changed files with 107 additions and 17 deletions

View File

@ -156,6 +156,10 @@ void PreampOverlay::InitViews() {
this->shortcuts->AddShortcut("ESC", _TSTR("button_cancel"));
this->shortcuts->AddShortcut("M-s", _TSTR("button_save"));
this->shortcuts->SetChangedCallback([this](std::string key) {
this->KeyPress(key);
});
/* preamp gain */
this->preampLabel.reset(new TextLabel());
this->preampLabel->SetText(_TSTR("settings_preamp_label"), text::AlignLeft);
@ -252,7 +256,7 @@ bool PreampOverlay::Save() {
}
bool PreampOverlay::KeyPress(const std::string& key) {
if (key == "^[") { /* esc closes */
if (key == "^[" || key == "ESC") { /* esc closes */
this->Dismiss();
return true;
}

View File

@ -325,6 +325,10 @@ TransportWindow::TransportWindow(
this->playback.TimeChanged.connect(this, &TransportWindow::OnTransportTimeChanged);
this->paused = false;
this->lastTime = DEFAULT_TIME;
this->shufflePos.y = 0;
this->repeatPos.y = 1;
this->volumePos.y = 1;
this->timePos.y = 1;
this->UpdateReplayGainState();
}
@ -381,6 +385,44 @@ bool TransportWindow::KeyPress(const std::string& kn) {
return false;
}
bool TransportWindow::MouseEvent(const IMouseHandler::Event& event) {
if (event.Button1Clicked()) {
if (this->shufflePos.Contains(event)) {
this->playback.ToggleShuffle();
return true;
}
else if (this->repeatPos.Contains(event)) {
this->playback.ToggleRepeatMode();
return true;
}
else if (this->volumePos.Contains(event)) {
if (playback.IsMuted()) {
playback.ToggleMute();
}
else {
playback.SetVolume(this->volumePos.Percent(event.x));
}
return true;
}
else if (this->timePos.Contains(event)) {
if (playback.GetPlaybackState() != PlaybackStopped) {
double duration = playback.GetDuration();
double percent = this->timePos.Percent(event.x);
playback.SetPosition(duration * percent);
}
return true;
}
}
else if (event.Button3Clicked()) {
if (this->volumePos.Contains(event)) {
if (!playback.IsMuted()) {
playback.ToggleMute();
}
}
}
return false;
}
bool TransportWindow::FocusNext() {
this->SetFocus((FocusTarget)(((int) this->focus + 1) % 3));
return (this->focus != FocusNone);
@ -508,7 +550,7 @@ void TransportWindow::Update(TimeMode timeMode) {
/* prepare the "shuffle" label */
std::string shuffleLabel = Strings.SHUFFLE;
size_t shuffleLabelLen = displayCache->Columns(shuffleLabel);
size_t shuffleWidth = displayCache->Columns(shuffleLabel);
/* playing SONG TITLE from ALBUM NAME */
@ -520,14 +562,17 @@ void TransportWindow::Update(TimeMode timeMode) {
}
else {
displayCache->Update(transport, this->currentTrack);
writePlayingFormat(c, *this->displayCache, cx - shuffleLabelLen);
writePlayingFormat(c, *this->displayCache, cx - shuffleWidth);
}
wmove(c, 0, cx - shuffleLabelLen);
/* draw the "shuffle" label */
const int shuffleOffset = cx - shuffleWidth;
wmove(c, 0, shuffleOffset);
int64_t shuffleAttrs = this->playback.IsShuffled() ? gb : disabled;
ON(c, shuffleAttrs);
checked_wprintw(c, shuffleLabel.c_str());
OFF(c, shuffleAttrs);
this->shufflePos.Set(shuffleOffset, shuffleWidth);
/* volume slider */
@ -538,9 +583,11 @@ void TransportWindow::Update(TimeMode timeMode) {
if (muted) {
volume = Strings.MUTED;
this->volumePos.Set(0, u8cols(Strings.MUTED));
}
else {
volume = Strings.VOLUME;
this->volumePos.Set(u8cols(Strings.VOLUME), 10);
for (int i = 0; i < 10; i++) {
volume += (i == thumbOffset) ? "" : "";
@ -659,13 +706,15 @@ void TransportWindow::Update(TimeMode timeMode) {
OFF(c, currentTimeAttrs);
ON(c, timerAttrs);
this->timePos.Set(getcurx(c), u8cols(timerTrack));
checked_waddstr(c, timerTrack.c_str()); /* may be a very long string */
checked_wprintw(c, " %s", displayCache->totalTime.c_str());
OFF(c, timerAttrs);
ON(c, repeatAttrs);
this->repeatPos.Set(getcurx(c), u8cols(repeatModeLabel));
checked_wprintw(c, repeatModeLabel.c_str());
OFF(c, repeatAttrs);
this->Invalidate();
}
}

View File

@ -71,6 +71,7 @@ namespace musik {
virtual void OnFocusChanged(bool focused);
virtual void OnRedraw();
virtual bool KeyPress(const std::string& key);
virtual bool MouseEvent(const IMouseHandler::Event& mouseEvent);
void SetFocus(FocusTarget target);
FocusTarget GetFocus() const;
@ -87,6 +88,33 @@ namespace musik {
TimeSync = 2
};
/* a little structure used to make mouse event handling a bit
less verbose. */
struct Position {
Position() {
this->x = this->y = this->width = 0;
}
Position(int x, int y, int width) {
this->x = x;
this->y = y;
this->width = width;
}
void Set(int x, int width) {
this->x = x;
this->width = width;
}
double Percent(int x) {
return std::max(0.0, std::min(1.0,
double(x - this->x) / double(this->width - 1)));
}
bool Contains(const IMouseHandler::Event& event) {
return event.y == this->y &&
event.x >= this->x &&
event.x < this->x + this->width;
}
int x, y, width;
};
void Update(TimeMode mode = TimeSmooth);
void OnPlaybackServiceTrackChanged(size_t index, musik::core::TrackPtr track);
@ -98,6 +126,7 @@ namespace musik {
bool paused;
bool hasReplayGain;
Position shufflePos, repeatPos, volumePos, timePos;
musik::core::sdk::ReplayGainMode replayGainMode;
musik::core::ILibraryPtr library;
musik::core::audio::ITransport& transport;

View File

@ -99,13 +99,15 @@ ListOverlay::ListOverlay() {
this->scrollbar.reset(new Window());
this->scrollbar->SetFrameVisible(false);
this->scrollbar->SetContentColor(CURSESPP_OVERLAY_CONTENT);
this->AddWindow(this->scrollbar);
this->listWindow.reset(new CustomListWindow(decorator, adapterChanged));
this->listWindow->SetContentColor(CURSESPP_OVERLAY_CONTENT);
this->listWindow->SetFocusedContentColor(CURSESPP_OVERLAY_CONTENT);
this->listWindow->SetFrameVisible(false);
this->listWindow->EntryActivated.connect(this, &ListOverlay::OnListEntryActivated);
this->listWindow->SetFocusOrder(0);
this->AddWindow(this->scrollbar);
this->AddWindow(this->listWindow);
}
@ -222,21 +224,24 @@ ListOverlay& ListOverlay::SetDeleteKeyCallback(DeleteKeyCallback cb) {
return *this;
}
void ListOverlay::OnListEntryActivated(cursespp::ListWindow* sender, size_t index) {
if (itemSelectedCallback) {
itemSelectedCallback(this, this->adapter, index);
}
if (this->autoDismiss) {
this->Dismiss();
}
}
bool ListOverlay::KeyPress(const std::string& key) {
if (key == "^[") { /* esc closes */
this->Dismiss();
return true;
}
else if (key == "KEY_ENTER" || key == " ") {
if (itemSelectedCallback) {
itemSelectedCallback(
this,
this->adapter,
listWindow->GetSelectedIndex());
}
if (this->autoDismiss) {
this->Dismiss();
}
else if (key == " ") { /* space bar also toggles activation */
this->OnListEntryActivated(
this->listWindow.get(),
this->listWindow->GetSelectedIndex());
return true;
}
else if (key == "KEY_BACKSPACE" || key == "KEY_DC") {

View File

@ -42,7 +42,8 @@
namespace cursespp {
class ListOverlay :
public OverlayBase
public OverlayBase,
public sigslot::has_slots<>
#if (__clang_major__ == 7 && __clang_minor__ == 3)
, public std::enable_shared_from_this<ListOverlay>
#endif
@ -72,6 +73,8 @@ namespace cursespp {
virtual void OnVisibilityChanged(bool visible);
private:
void OnListEntryActivated(cursespp::ListWindow* sender, size_t index);
class CustomListWindow;
void Redraw();