new feature: mouse support

This commit is contained in:
Andrzej Rybczak
2009-05-25 21:46:36 +02:00
parent dd266b0103
commit d965f4e517
22 changed files with 370 additions and 1 deletions

View File

@@ -259,6 +259,47 @@ void Browser::SpacePressed()
w->Scroll(wDown);
}
void Browser::MouseButtonPressed(MEVENT me)
{
if (w->Empty() || !w->hasCoords(me.x, me.y) || size_t(me.y) >= w->Size())
return;
if (me.bstate & BUTTON1_PRESSED || me.bstate & BUTTON3_PRESSED)
{
w->Goto(me.y);
switch (w->Current().type)
{
case itDirectory:
if (me.bstate & BUTTON1_PRESSED)
{
GetDirectory(w->Current().name);
RedrawHeader = 1;
}
else
{
size_t pos = w->GetPosition();
SpacePressed();
if (pos < w->Size()-1)
w->Scroll(wUp);
}
break;
case itPlaylist:
case itSong:
if (me.bstate & BUTTON1_PRESSED)
{
size_t pos = w->GetPosition();
SpacePressed();
if (pos < w->Size()-1)
w->Scroll(wUp);
}
else
EnterPressed();
break;
}
}
else
Screen< Menu<MPD::Item> >::MouseButtonPressed(me);
}
MPD::Song *Browser::CurrentSong()
{
return !w->Empty() && w->Current().type == itSong ? w->Current().song : 0;

View File

@@ -37,6 +37,7 @@ class Browser : public Screen< Menu<MPD::Item> >
virtual void EnterPressed();
virtual void SpacePressed();
virtual void MouseButtonPressed(MEVENT);
virtual MPD::Song *CurrentSong();

View File

@@ -44,6 +44,7 @@ class Clock : public Screen<Window>
virtual void EnterPressed() { }
virtual void SpacePressed() { }
virtual void MouseButtonPressed(MEVENT) { }
virtual bool allowsSelection() { return false; }

View File

@@ -327,6 +327,65 @@ void MediaLibrary::SpacePressed()
AddToPlaylist(0);
}
void MediaLibrary::MouseButtonPressed(MEVENT me)
{
if (!Artists->Empty() && Artists->hasCoords(me.x, me.y))
{
if (w != Artists)
{
PrevColumn();
PrevColumn();
}
if (size_t(me.y) < Artists->Size() && (me.bstate & BUTTON1_PRESSED || me.bstate & BUTTON3_PRESSED))
{
Artists->Goto(me.y);
if (me.bstate & BUTTON3_PRESSED)
EnterPressed();
}
else
Screen<Window>::MouseButtonPressed(me);
Albums->Clear(0);
Songs->Clear(0);
}
else if (!Albums->Empty() && Albums->hasCoords(me.x, me.y))
{
if (w != Albums)
w == Artists ? NextColumn() : PrevColumn();
if (size_t(me.y) < Albums->Size() && (me.bstate & BUTTON1_PRESSED || me.bstate & BUTTON3_PRESSED))
{
Albums->Goto(me.y);
if (me.bstate & BUTTON3_PRESSED)
EnterPressed();
}
else
Screen<Window>::MouseButtonPressed(me);
Songs->Clear(0);
}
else if (!Songs->Empty() && Songs->hasCoords(me.x, me.y))
{
if (w != Songs)
{
NextColumn();
NextColumn();
}
if (size_t(me.y) < Songs->Size() && (me.bstate & BUTTON1_PRESSED || me.bstate & BUTTON3_PRESSED))
{
Songs->Goto(me.y);
if (me.bstate & BUTTON1_PRESSED)
{
size_t pos = Songs->GetPosition();
SpacePressed();
if (pos < Songs->Size()-1)
Songs->Scroll(wUp);
}
else
EnterPressed();
}
else
Screen<Window>::MouseButtonPressed(me);
}
}
MPD::Song *MediaLibrary::CurrentSong()
{
return w == Songs && !Songs->Empty() ? &Songs->Current() : 0;

View File

@@ -48,6 +48,7 @@ class MediaLibrary : public Screen<Window>
virtual void EnterPressed() { AddToPlaylist(1); }
virtual void SpacePressed();
virtual void MouseButtonPressed(MEVENT);
virtual MPD::Song *CurrentSong();

View File

@@ -118,6 +118,9 @@ namespace NCurses
void IntoSeparator(size_t pos);
void Swap(size_t one, size_t two);
void Move(size_t from, size_t to);
bool Goto(size_t y);
size_t GetPosition() const { return itsHighlight; }
bool isBold(int id = -1);
void BoldOption(int index, bool bold);
@@ -358,6 +361,19 @@ template <typename T> void NCurses::Menu<T>::Move(size_t from, size_t to)
}
}
template <typename T> bool NCurses::Menu<T>::Goto(size_t y)
{
if (!itsOptionsPtr->at(itsBeginning+y) || itsOptionsPtr->at(itsBeginning+y)->isStatic)
return false;
size_t cur_pos = itsHighlight-itsBeginning;
while (itsHighlight-itsBeginning != int(y) && (y < cur_pos || size_t(itsHighlight) < itsOptions.size()-1))
{
Scroll(y < cur_pos ? wUp : wDown);
y < cur_pos ? cur_pos-- : cur_pos++;
}
return true;
}
template <typename T> void NCurses::Menu<T>::Refresh()
{
if (itsOptionsPtr->empty())

View File

@@ -190,6 +190,13 @@ int main(int argc, char *argv[])
gettimeofday(&now, 0);
MEVENT mouse_event;
if (Config.mouse_support)
{
mousemask(ALL_MOUSE_EVENTS, 0);
mouseinterval(0);
}
while (!main_exit)
{
if (!Mpd->Connected())
@@ -333,6 +340,45 @@ int main(int argc, char *argv[])
{
myScreen->Scroll(wEnd);
}
else if (Config.mouse_support && input == KEY_MOUSE)
{
# ifdef USE_PDCURSES
nc_getmouse(&mouse_event);
# else
getmouse(&mouse_event);
# endif // USE_PDCURSES
if (mouse_event.bstate & BUTTON1_PRESSED
&& mouse_event.y == LINES-(Config.statusbar_visibility ? 2 : 1)
) // progressbar
{
const Song *s = myPlaylist->NowPlayingSong();
if (!s)
continue;
Mpd->Seek(s->GetTotalLength()*mouse_event.x/double(COLS));
UpdateStatusImmediately = 1;
}
else if (mouse_event.bstate & BUTTON1_PRESSED
&& Config.statusbar_visibility
&& Mpd->GetState() > psStop
&& mouse_event.y == LINES-1 && mouse_event.x < 9
) // playing/paused
{
Mpd->Pause();
UpdateStatusImmediately = 1;
}
else if ((mouse_event.bstate & BUTTON2_PRESSED || mouse_event.bstate & BUTTON4_PRESSED)
&& Config.header_visibility
&& mouse_event.y == 0 && size_t(mouse_event.x) > COLS-VolumeState.length()
) // volume
{
if (mouse_event.bstate & BUTTON2_PRESSED)
Mpd->SetVolume(Mpd->GetVolume()-2);
else
Mpd->SetVolume(Mpd->GetVolume()+2);
}
else
myScreen->MouseButtonPressed(mouse_event);
}
else if (input == KEY_RESIZE)
{
# ifdef USE_PDCURSES

View File

@@ -133,6 +133,20 @@ void Playlist::SpacePressed()
w->Scroll(wDown);
}
void Playlist::MouseButtonPressed(MEVENT me)
{
if (w->Empty() || !w->hasCoords(me.x, me.y) || size_t(me.y) >= w->Size())
return;
if (me.bstate & BUTTON1_PRESSED)
{
w->Goto(me.y);
Mpd->Play(w->Current().GetPosition());
UpdateStatusImmediately = 1;
}
else
Screen< Menu<MPD::Song> >::MouseButtonPressed(me);
}
MPD::Song *Playlist::CurrentSong()
{
return !w->Empty() ? &w->Current() : 0;

View File

@@ -41,6 +41,7 @@ class Playlist : public Screen< Menu<MPD::Song> >
virtual void EnterPressed();
virtual void SpacePressed();
virtual void MouseButtonPressed(MEVENT);
virtual MPD::Song *CurrentSong();

View File

@@ -281,6 +281,44 @@ void PlaylistEditor::SpacePressed()
AddToPlaylist(0);
}
void PlaylistEditor::MouseButtonPressed(MEVENT me)
{
if (!Playlists->Empty() && Playlists->hasCoords(me.x, me.y))
{
if (w != Playlists)
PrevColumn();
if (size_t(me.y) < Playlists->Size() && (me.bstate & BUTTON1_PRESSED || me.bstate & BUTTON3_PRESSED))
{
Playlists->Goto(me.y);
if (me.bstate & BUTTON3_PRESSED)
EnterPressed();
}
else
Screen<Window>::MouseButtonPressed(me);
Content->Clear(0);
}
else if (!Content->Empty() && Content->hasCoords(me.x, me.y))
{
if (w != Content)
NextColumn();
if (size_t(me.y) < Content->Size() && (me.bstate & BUTTON1_PRESSED || me.bstate & BUTTON3_PRESSED))
{
Content->Goto(me.y);
if (me.bstate & BUTTON1_PRESSED)
{
size_t pos = Content->GetPosition();
SpacePressed();
if (pos < Content->Size()-1)
Content->Scroll(wUp);
}
else
EnterPressed();
}
else
Screen<Window>::MouseButtonPressed(me);
}
}
MPD::Song *PlaylistEditor::CurrentSong()
{
return w == Content && !Content->Empty() ? &Content->Current() : 0;

View File

@@ -37,6 +37,7 @@ class PlaylistEditor : public Screen<Window>
virtual void EnterPressed() { AddToPlaylist(1); }
virtual void SpacePressed();
virtual void MouseButtonPressed(MEVENT);
virtual MPD::Song *CurrentSong();

View File

@@ -49,6 +49,7 @@ class BasicScreen
virtual void EnterPressed() = 0;
virtual void SpacePressed() = 0;
virtual void MouseButtonPressed(MEVENT) { }
virtual MPD::Song *CurrentSong() { return 0; }
@@ -76,7 +77,9 @@ template <typename WindowType> class Screen : public BasicScreen
virtual void Refresh();
virtual void RefreshWindow();
virtual void ReadKey(int &input);
virtual void Scroll(Where where, const int *);
virtual void Scroll(Where where, const int * = 0);
virtual void MouseButtonPressed(MEVENT me);
protected:
WindowType *w;
@@ -126,5 +129,31 @@ template <typename WindowType> void Screen<WindowType>::Scroll(Where where, cons
w->Scroll(where);
}
template <typename WindowType> void Screen<WindowType>::MouseButtonPressed(MEVENT me)
{
if (me.bstate & BUTTON2_PRESSED)
{
Scroll(wPageDown);
}
else if (me.bstate & BUTTON4_PRESSED)
{
Scroll(wPageUp);
}
}
template <> inline void Screen<Scrollpad>::MouseButtonPressed(MEVENT me)
{
if (me.bstate & BUTTON2_PRESSED)
{
for (size_t i = 0; i < 2; i++)
Scroll(wDown);
}
else if (me.bstate & BUTTON4_PRESSED)
{
for (size_t i = 0; i < 2; i++)
Scroll(wUp);
}
}
#endif

View File

@@ -295,6 +295,34 @@ void SearchEngine::SpacePressed()
w->Scroll(wDown);
}
void SearchEngine::MouseButtonPressed(MEVENT me)
{
if (w->Empty() || !w->hasCoords(me.x, me.y) || size_t(me.y) >= w->Size())
return;
if (me.bstate & BUTTON1_PRESSED || me.bstate & BUTTON3_PRESSED)
{
if (!w->Goto(me.y))
return;
w->Refresh();
if ((me.bstate & BUTTON3_PRESSED || w->GetPosition() > 10) && w->GetPosition() < StaticOptions)
EnterPressed();
else if (w->GetPosition() >= StaticOptions)
{
if (me.bstate & BUTTON1_PRESSED)
{
size_t pos = w->GetPosition();
SpacePressed();
if (pos < w->Size()-1)
w->Scroll(wUp);
}
else
EnterPressed();
}
}
else
Screen< Menu< std::pair<Buffer *, MPD::Song *> > >::MouseButtonPressed(me);
}
MPD::Song *SearchEngine::CurrentSong()
{
return !w->Empty() ? w->Current().second : 0;

View File

@@ -48,6 +48,7 @@ class SearchEngine : public Screen< Menu< std::pair<Buffer *, MPD::Song *> > >
virtual void EnterPressed();
virtual void SpacePressed();
virtual void MouseButtonPressed(MEVENT);
virtual MPD::Song *CurrentSong();

View File

@@ -280,6 +280,7 @@ void DefaultConfiguration(ncmpcpp_config &conf)
conf.use_cyclic_scrolling = false;
conf.allow_physical_files_deletion = false;
conf.allow_physical_directories_deletion = false;
conf.mouse_support = true;
conf.set_window_title = true;
conf.mpd_port = 6600;
conf.mpd_connection_timeout = 15;
@@ -679,6 +680,10 @@ void ReadConfiguration(ncmpcpp_config &conf)
{
conf.allow_physical_directories_deletion = v == "yes";
}
else if (cl.find("mouse_support") != string::npos)
{
conf.mouse_support = v == "yes";
}
else if (cl.find("enable_window_title") != string::npos)
{
conf.set_window_title = v == "yes";

View File

@@ -172,6 +172,7 @@ struct ncmpcpp_config
bool use_cyclic_scrolling;
bool allow_physical_files_deletion;
bool allow_physical_directories_deletion;
bool mouse_support;
int mpd_port;
int mpd_connection_timeout;

View File

@@ -216,6 +216,21 @@ void TinyTagEditor::EnterPressed()
UnlockStatusbar();
}
void TinyTagEditor::MouseButtonPressed(MEVENT me)
{
if (w->Empty() || !w->hasCoords(me.x, me.y) || size_t(me.y) >= w->Size())
return;
if (me.bstate & BUTTON1_PRESSED)
{
if (!w->Goto(me.y))
return;
w->Refresh();
EnterPressed();
}
else
Screen< Menu<Buffer> >::MouseButtonPressed(me);
}
bool TinyTagEditor::SetEdited(MPD::Song *s)
{
if (!s)
@@ -728,6 +743,62 @@ void TagEditor::SpacePressed()
Tags->Clear(0);
}
void TagEditor::MouseButtonPressed(MEVENT me)
{
if (!LeftColumn->Empty() && LeftColumn->hasCoords(me.x, me.y))
{
if (w != LeftColumn)
{
PrevColumn();
PrevColumn();
}
if (size_t(me.y) < LeftColumn->Size() && (me.bstate & BUTTON1_PRESSED || me.bstate & BUTTON3_PRESSED))
{
LeftColumn->Goto(me.y);
if (me.bstate & BUTTON1_PRESSED)
EnterPressed();
else
SpacePressed();
}
else
Screen<Window>::MouseButtonPressed(me);
Tags->Clear(0);
}
else if (!TagTypes->Empty() && TagTypes->hasCoords(me.x, me.y))
{
if (w != TagTypes)
w == LeftColumn ? NextColumn() : PrevColumn();
if (size_t(me.y) < TagTypes->Size() && (me.bstate & BUTTON1_PRESSED || me.bstate & BUTTON3_PRESSED))
{
if (!TagTypes->Goto(me.y))
return;
TagTypes->Refresh();
Tags->Refresh();
if (me.bstate & BUTTON3_PRESSED)
EnterPressed();
}
else
Screen<Window>::MouseButtonPressed(me);
}
else if (!Tags->Empty() && Tags->hasCoords(me.x, me.y))
{
if (w != Tags)
{
NextColumn();
NextColumn();
}
if (size_t(me.y) < Tags->Size() && (me.bstate & BUTTON1_PRESSED || me.bstate & BUTTON3_PRESSED))
{
Tags->Goto(me.y);
Tags->Refresh();
if (me.bstate & BUTTON3_PRESSED)
EnterPressed();
}
else
Screen<Window>::MouseButtonPressed(me);
}
}
MPD::Song *TagEditor::CurrentSong()
{
return w == Tags && !Tags->Empty() ? &Tags->Current() : 0;

View File

@@ -44,6 +44,7 @@ class TinyTagEditor : public Screen< Menu<Buffer> >
virtual void EnterPressed();
virtual void SpacePressed() { }
virtual void MouseButtonPressed(MEVENT);
virtual bool allowsSelection() { return false; }
@@ -74,6 +75,7 @@ class TagEditor : public Screen<Window>
virtual void EnterPressed();
virtual void SpacePressed();
virtual void MouseButtonPressed(MEVENT);
virtual MPD::Song *CurrentSong();

View File

@@ -468,6 +468,8 @@ string Window::GetString(const string &base, size_t length, size_t width, bool e
switch (input)
{
case ERR:
case KEY_MOUSE:
break;
case KEY_UP:
if (itsHistory && !encrypted && history_offset > 0)
{
@@ -634,6 +636,11 @@ int Window::Y() const
return itsY;
}
bool Window::hasCoords(int &x, int &y)
{
return wmouse_trafo(itsWindow, &y, &x, 0);
}
void Window::Scrollable(bool scrollable) const
{
scrollok(itsWindow, scrollable);

View File

@@ -107,6 +107,7 @@ namespace NCurses
void GotoXY(int, int);
int X() const;
int Y() const;
bool hasCoords(int &, int &);
void SetGetStringHelper(GetStringHelper helper) { itsGetStringHelper = helper; }
void SetColor(Color, Color = clDefault);