add clock screen (ported from ncmpc)

This commit is contained in:
Andrzej Rybczak
2009-01-17 20:40:28 +01:00
parent 351ddc8584
commit 542c121e0a
16 changed files with 290 additions and 23 deletions

View File

@@ -9,10 +9,15 @@ AC_LANG_CPLUSPLUS
AC_PROG_CXX AC_PROG_CXX
AM_PROG_LIBTOOL AM_PROG_LIBTOOL
AC_ARG_ENABLE(clock, AS_HELP_STRING([--enable-clock], [Enable clock screen]), [clock=$enableval], [clock=no])
AC_ARG_ENABLE(unicode, AS_HELP_STRING([--enable-unicode], [Enable utf8 support]), [unicode=$enableval], [unicode=yes]) AC_ARG_ENABLE(unicode, AS_HELP_STRING([--enable-unicode], [Enable utf8 support]), [unicode=$enableval], [unicode=yes])
AC_ARG_WITH(taglib, AS_HELP_STRING([--with-taglib], [Enable tag editor]), [taglib=$withval], [taglib=no]) AC_ARG_WITH(taglib, AS_HELP_STRING([--with-taglib], [Enable tag editor]), [taglib=$withval], [taglib=no])
AC_ARG_WITH(curl, AS_HELP_STRING([--with-curl], [Enable fetching lyrics from the Internet]), [curl=$withval], [curl=no]) AC_ARG_WITH(curl, AS_HELP_STRING([--with-curl], [Enable fetching lyrics from the Internet]), [curl=$withval], [curl=no])
if test "$clock" = "yes"; then
AC_DEFINE([ENABLE_CLOCK], [1], [enables clock screen])
fi
dnl ====================== dnl ======================
dnl = checking for iconv = dnl = checking for iconv =
dnl ====================== dnl ======================

View File

@@ -138,6 +138,8 @@
# #
#display_screens_numbers_on_start = "yes" #display_screens_numbers_on_start = "yes"
# #
#clock_display_seconds = "no"
#
#enable_window_title = "yes" #enable_window_title = "yes"
# #
##### colors definitions ##### ##### colors definitions #####

View File

@@ -54,6 +54,8 @@
# #
#key_tag_editor = '7' 271 #key_tag_editor = '7' 271
# #
#key_clock = '0' 274
#
#key_stop = 's' #key_stop = 's'
# #
#key_pause = 'P' #key_pause = 'P'

View File

@@ -1,13 +1,14 @@
bin_PROGRAMS = ncmpcpp bin_PROGRAMS = ncmpcpp
ncmpcpp_SOURCES = browser.cpp charset.cpp help.cpp helpers.cpp libmpdclient.c \ ncmpcpp_SOURCES = browser.cpp charset.cpp clock.cpp help.cpp helpers.cpp \
lyrics.cpp misc.cpp mpdpp.cpp ncmpcpp.cpp scrollpad.cpp search_engine.cpp \ libmpdclient.c lyrics.cpp misc.cpp mpdpp.cpp ncmpcpp.cpp scrollpad.cpp \
settings.cpp song.cpp status_checker.cpp str_pool.c tag_editor.cpp window.cpp search_engine.cpp settings.cpp song.cpp status_checker.cpp str_pool.c tag_editor.cpp \
window.cpp
# set the include path found by configure # set the include path found by configure
INCLUDES= $(all_includes) INCLUDES= $(all_includes)
# the library search path. # the library search path.
ncmpcpp_LDFLAGS = $(all_libraries) ncmpcpp_LDFLAGS = $(all_libraries)
noinst_HEADERS = browser.h charset.h help.h helpers.h lyrics.h menu.h mpdpp.h \ noinst_HEADERS = browser.h charset.h clock.h help.h helpers.h lyrics.h menu.h \
scrollpad.h search_engine.h settings.h song.h status_checker.h tag_editor.h \ mpdpp.h scrollpad.h search_engine.h settings.h song.h status_checker.h \
window.h tag_editor.h window.h

121
src/clock.cpp Normal file
View File

@@ -0,0 +1,121 @@
/***************************************************************************
* Copyright (C) 2008-2009 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
/// NOTICE: Major part of this code is ported from ncmpc's clock screen
#include "clock.h"
#ifdef ENABLE_CLOCK
#include <iomanip>
#include <sstream>
#include "settings.h"
namespace
{
short disp[11] =
{
075557, 011111, 071747, 071717,
055711, 074717, 074757, 071111,
075757, 075717, 002020
};
long older[6], next[6], newer[6], mask;
void set(int t, int n)
{
int m = 7 << n;
for (int i = 0; i < 5; i++)
{
next[i] |= ((disp[t] >> ((4 - i) * 3)) & 07) << n;
mask |= (next[i] ^ older[i]) & m;
}
if (mask & m)
mask |= m;
}
}
void InitClock()
{
for (int i = 0; i < 5; i++)
older[i] = newer[i] = next[i] = 0;
}
void DisplayClock(Window &w, const tm *time)
{
mask = 0;
set(time->tm_sec % 10, 0);
set(time->tm_sec / 10, 4);
set(time->tm_min % 10, 10);
set(time->tm_min / 10, 14);
set(time->tm_hour % 10, 20);
set(time->tm_hour / 10, 24);
set(10, 7);
set(10, 17);
char buf[54];
strftime(buf, 64, "%x", time);
attron(COLOR_PAIR(Config.main_color));
mvprintw(w.GetStartY()+w.GetHeight(), w.GetStartX()+(w.GetWidth()-strlen(buf))/2, "%s", buf);
attroff(COLOR_PAIR(Config.main_color));
refresh();
for (int k = 0; k < 6; k++)
{
newer[k] = (newer[k] & ~mask) | (next[k] & mask);
next[k] = 0;
for (int s = 1; s >= 0; s--)
{
w.Reverse(s);
for (int i = 0; i < 6; i++)
{
long a = (newer[i] ^ older[i]) & (s ? newer : older)[i];
if (a != 0)
{
long t = 1 << 26;
for (int j = 0; t; t >>= 1, j++)
{
if (a & t)
{
if (!(a & (t << 1)))
{
w.GotoXY(2*j+2, i);
}
if (Config.clock_display_seconds || j < 18)
w << " ";
}
}
}
if (!s)
{
older[i] = newer[i];
}
}
if (!s)
{
w.Refresh();
}
}
}
}
#endif // ENABLE_CLOCK

40
src/clock.h Normal file
View File

@@ -0,0 +1,40 @@
/***************************************************************************
* Copyright (C) 2008-2009 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef _CLOCK_H
#define _CLOCK_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef ENABLE_CLOCK
#include <ctime>
#include "window.h"
void InitClock();
void DisplayClock(Window &, const tm *);
#endif // ENABLE_CLOCK
#endif

View File

@@ -68,7 +68,7 @@ namespace
else if (key[i] >= 265 && key[i] <= 276) else if (key[i] >= 265 && key[i] <= 276)
{ {
result += "F"; result += "F";
result += key[i]-216; result += IntoStr(key[i]-264);
} }
else if ((key[i] == 263 || key[i] == 127) && !backspace); else if ((key[i] == 263 || key[i] == 127) && !backspace);
else if ((key[i] == 263 || key[i] == 127) && backspace) else if ((key[i] == 263 || key[i] == 127) && backspace)
@@ -106,10 +106,12 @@ void GetKeybindings(Scrollpad &help)
help << DisplayKeys(Key.MediaLibrary) << "Media library\n"; help << DisplayKeys(Key.MediaLibrary) << "Media library\n";
help << DisplayKeys(Key.PlaylistEditor) << "Playlist editor\n"; help << DisplayKeys(Key.PlaylistEditor) << "Playlist editor\n";
# ifdef HAVE_TAGLIB_H # ifdef HAVE_TAGLIB_H
help << DisplayKeys(Key.TagEditor) << "Tag editor\n\n\n"; help << DisplayKeys(Key.TagEditor) << "Tag editor\n";
# else
help << "\n\n";
# endif // HAVE_TAGLIB_H # endif // HAVE_TAGLIB_H
# ifdef ENABLE_CLOCK
help << DisplayKeys(Key.Clock) << "Clock screen\n";
# endif // ENABLE_CLOCK
help << "\n\n";
help << " " << fmtBold << "Keys - Global\n -----------------------------------------\n" << fmtBoldEnd; help << " " << fmtBold << "Keys - Global\n -----------------------------------------\n" << fmtBoldEnd;
help << DisplayKeys(Key.Stop) << "Stop\n"; help << DisplayKeys(Key.Stop) << "Stop\n";

View File

@@ -138,6 +138,9 @@ void Connection::UpdateStatus()
CheckForErrors(); CheckForErrors();
if (!itsConnection)
return;
if (itsOldStatus) if (itsOldStatus)
mpd_freeStatus(itsOldStatus); mpd_freeStatus(itsOldStatus);

View File

@@ -31,6 +31,7 @@
#include "browser.h" #include "browser.h"
#include "charset.h" #include "charset.h"
#include "clock.h"
#include "help.h" #include "help.h"
#include "helpers.h" #include "helpers.h"
#include "lyrics.h" #include "lyrics.h"
@@ -120,6 +121,9 @@ Scrollpad *sInfo;
Window *wHeader; Window *wHeader;
Window *wFooter; Window *wFooter;
#ifdef ENABLE_CLOCK
Window *wClock;
#endif
Connection *Mpd; Connection *Mpd;
@@ -308,6 +312,11 @@ int main(int argc, char *argv[])
mPlaylistEditor->SetItemDisplayer(DisplaySong); mPlaylistEditor->SetItemDisplayer(DisplaySong);
mPlaylistEditor->SetItemDisplayerUserData(&Config.song_list_format); mPlaylistEditor->SetItemDisplayerUserData(&Config.song_list_format);
# ifdef ENABLE_CLOCK
size_t clock_width = Config.clock_display_seconds ? 60 : 40;
size_t clock_height = 8;
# endif // ENABLE_CLOCK
sHelp = new Scrollpad(0, main_start_y, COLS, main_height, "", Config.main_color, brNone); sHelp = new Scrollpad(0, main_start_y, COLS, main_height, "", Config.main_color, brNone);
sHelp->SetTimeout(ncmpcpp_window_timeout); sHelp->SetTimeout(ncmpcpp_window_timeout);
GetKeybindings(*sHelp); GetKeybindings(*sHelp);
@@ -431,6 +440,9 @@ int main(int argc, char *argv[])
case csPlaylistEditor: case csPlaylistEditor:
screen_title = "Playlist editor"; screen_title = "Playlist editor";
break; break;
case csClock:
screen_title = "Clock";
break;
default: default:
break; break;
} }
@@ -461,10 +473,19 @@ int main(int argc, char *argv[])
} }
else else
{ {
*wHeader << XY(0, 0) << fmtBold << 1 << fmtBoldEnd << ":Help " << fmtBold << 2 << fmtBoldEnd << ":Playlist " << fmtBold << 3 << fmtBoldEnd << ":Browse " << fmtBold << 4 << fmtBoldEnd << ":Search " << fmtBold << 5 << fmtBoldEnd << ":Library " << fmtBold << 6 << fmtBoldEnd << ":Playlist editor"; *wHeader << XY(0, 0)
<< fmtBold << (char)Key.Help[0] << fmtBoldEnd << ":Help "
<< fmtBold << (char)Key.Playlist[0] << fmtBoldEnd << ":Playlist "
<< fmtBold << (char)Key.Browser[0] << fmtBoldEnd << ":Browse "
<< fmtBold << (char)Key.SearchEngine[0] << fmtBoldEnd << ":Search "
<< fmtBold << (char)Key.MediaLibrary[0] << fmtBoldEnd << ":Library "
<< fmtBold << (char)Key.PlaylistEditor[0] << fmtBoldEnd << ":Playlist editor";
# ifdef HAVE_TAGLIB_H # ifdef HAVE_TAGLIB_H
*wHeader << " " << fmtBold << 7 << fmtBoldEnd << ":Tag editor"; *wHeader << " " << fmtBold << (char)Key.TagEditor[0] << fmtBoldEnd << ":Tag editor";
# endif // HAVE_TAGLIB_H # endif // HAVE_TAGLIB_H
# ifdef ENABLE_CLOCK
*wHeader << " " << fmtBold << (char)Key.Clock[0] << fmtBoldEnd << ":Clock";
# endif // ENABLE_CLOCK
} }
wHeader->SetColor(Config.volume_color); wHeader->SetColor(Config.volume_color);
@@ -754,6 +775,25 @@ int main(int argc, char *argv[])
// album editor end // album editor end
else else
# endif // HAVE_TAGLIB_H # endif // HAVE_TAGLIB_H
# ifdef ENABLE_CLOCK
if (current_screen == csClock)
{
if (clock_width <= size_t(COLS) && clock_height <= main_height)
{
time_t rawtime;
time(&rawtime);
tm *t = localtime(&rawtime);
DisplayClock(*wClock, t);
}
else
{
delete wClock;
wClock = 0;
goto SWITCHER_PLAYLIST_REDIRECT;
}
}
else
# endif
// lyrics stuff // lyrics stuff
if (current_screen == csLyrics && reload_lyrics) if (current_screen == csLyrics && reload_lyrics)
{ {
@@ -820,7 +860,7 @@ int main(int argc, char *argv[])
// key mapping beginning // key mapping beginning
if (Keypressed(input, Key.Up)) if (current_screen != csClock && Keypressed(input, Key.Up))
{ {
if (!Config.fancy_scrolling && (wCurrent == mLibArtists || wCurrent == mPlaylistList || wCurrent == mEditorLeftCol)) if (!Config.fancy_scrolling && (wCurrent == mLibArtists || wCurrent == mPlaylistList || wCurrent == mEditorLeftCol))
{ {
@@ -836,7 +876,7 @@ int main(int argc, char *argv[])
else else
wCurrent->Scroll(wUp); wCurrent->Scroll(wUp);
} }
else if (Keypressed(input, Key.Down)) else if (current_screen != csClock && Keypressed(input, Key.Down))
{ {
if (!Config.fancy_scrolling && (wCurrent == mLibArtists || wCurrent == mPlaylistList || wCurrent == mEditorLeftCol)) if (!Config.fancy_scrolling && (wCurrent == mLibArtists || wCurrent == mPlaylistList || wCurrent == mEditorLeftCol))
{ {
@@ -852,11 +892,11 @@ int main(int argc, char *argv[])
else else
wCurrent->Scroll(wDown); wCurrent->Scroll(wDown);
} }
else if (Keypressed(input, Key.PageUp)) else if (current_screen != csClock && Keypressed(input, Key.PageUp))
{ {
wCurrent->Scroll(wPageUp); wCurrent->Scroll(wPageUp);
} }
else if (Keypressed(input, Key.PageDown)) else if (current_screen != csClock && Keypressed(input, Key.PageDown))
{ {
wCurrent->Scroll(wPageDown); wCurrent->Scroll(wPageDown);
} }
@@ -881,7 +921,7 @@ int main(int argc, char *argv[])
} }
main_height = LINES-4; main_height = LINES-4;
if (!Config.header_visibility) if (!Config.header_visibility)
main_height += 2; main_height += 2;
if (!Config.statusbar_visibility) if (!Config.statusbar_visibility)
@@ -927,6 +967,19 @@ int main(int argc, char *argv[])
mPlaylistEditor->MoveTo(middle_col_startx, main_start_y); mPlaylistEditor->MoveTo(middle_col_startx, main_start_y);
# endif // HAVE_TAGLIB_H # endif // HAVE_TAGLIB_H
# ifdef ENABLE_CLOCK
if (wClock)
{
wClock->MoveTo((COLS-clock_width)/2, (LINES-clock_height)/2);
if (current_screen == csClock)
{
mPlaylist->Hide();
InitClock();
wClock->Display();
}
}
# endif // ENABLE_CLOCK
if (Config.header_visibility) if (Config.header_visibility)
wHeader->Resize(COLS, wHeader->GetHeight()); wHeader->Resize(COLS, wHeader->GetHeight());
@@ -934,8 +987,6 @@ int main(int argc, char *argv[])
wFooter->MoveTo(0, footer_start_y); wFooter->MoveTo(0, footer_start_y);
wFooter->Resize(COLS, wFooter->GetHeight()); wFooter->Resize(COLS, wFooter->GetHeight());
wCurrent->Hide();
# ifdef HAVE_TAGLIB_H # ifdef HAVE_TAGLIB_H
if (current_screen == csLibrary) if (current_screen == csLibrary)
{ {
@@ -3673,6 +3724,33 @@ int main(int argc, char *argv[])
} }
} }
# endif // HAVE_TAGLIB_H # endif // HAVE_TAGLIB_H
# ifdef ENABLE_CLOCK
else if (Keypressed(input, Key.Clock))
{
if (clock_width > size_t(COLS) || clock_height > main_height)
{
ShowMessage("Screen is too small to display clock!");
}
else if (current_screen != csClock && current_screen != csTinyTagEditor)
{
if (!wClock)
{
wClock = new Window((COLS-clock_width)/2, (LINES-clock_height)/2, clock_width, clock_height-1, "", Config.main_color, Border(Config.main_color));
wClock->SetTimeout(ncmpcpp_window_timeout);
wClock->Reverse(1);
}
CLEAR_FIND_HISTORY;
wCurrent = wClock;
mPlaylist->Hide();
current_screen = csClock;
// redraw_screen = 1;
redraw_header = 1;
wCurrent->Display();
InitClock();
}
}
# endif // ENABLE_CLOCK
else if (Keypressed(input, Key.Quit)) else if (Keypressed(input, Key.Quit))
main_exit = 1; main_exit = 1;

View File

@@ -41,6 +41,7 @@ enum NcmpcppScreen
csLyrics, csLyrics,
csPlaylistEditor, csPlaylistEditor,
csTagEditor, csTagEditor,
csClock,
csOther csOther
}; };

View File

@@ -120,6 +120,7 @@ void DefaultKeys(ncmpcpp_keys &keys)
keys.MediaLibrary[0] = '5'; keys.MediaLibrary[0] = '5';
keys.PlaylistEditor[0] = '6'; keys.PlaylistEditor[0] = '6';
keys.TagEditor[0] = '7'; keys.TagEditor[0] = '7';
keys.Clock[0] = '0';
keys.Stop[0] = 's'; keys.Stop[0] = 's';
keys.Pause[0] = 'P'; keys.Pause[0] = 'P';
keys.Next[0] = '>'; keys.Next[0] = '>';
@@ -182,6 +183,7 @@ void DefaultKeys(ncmpcpp_keys &keys)
keys.MediaLibrary[1] = 269; keys.MediaLibrary[1] = 269;
keys.PlaylistEditor[1] = 270; keys.PlaylistEditor[1] = 270;
keys.TagEditor[1] = 271; keys.TagEditor[1] = 271;
keys.Clock[1] = 274;
keys.Stop[1] = null_key; keys.Stop[1] = null_key;
keys.Pause[1] = null_key; keys.Pause[1] = null_key;
keys.Next[1] = null_key; keys.Next[1] = null_key;
@@ -272,6 +274,7 @@ void DefaultConfiguration(ncmpcpp_config &conf)
conf.local_browser = false; conf.local_browser = false;
conf.search_in_db = true; conf.search_in_db = true;
conf.display_screens_numbers_on_start = true; conf.display_screens_numbers_on_start = true;
conf.clock_display_seconds = false;
conf.set_window_title = true; conf.set_window_title = true;
conf.mpd_port = 6600; conf.mpd_port = 6600;
conf.mpd_connection_timeout = 15; conf.mpd_connection_timeout = 15;
@@ -399,6 +402,8 @@ void ReadKeys(ncmpcpp_keys &keys)
GetKeys(key, keys.PlaylistEditor); GetKeys(key, keys.PlaylistEditor);
else if (key.find("key_tag_editor ") != string::npos) else if (key.find("key_tag_editor ") != string::npos)
GetKeys(key, keys.TagEditor); GetKeys(key, keys.TagEditor);
else if (key.find("key_clock ") != string::npos)
GetKeys(key, keys.Clock);
else if (key.find("key_stop ") != string::npos) else if (key.find("key_stop ") != string::npos)
GetKeys(key, keys.Stop); GetKeys(key, keys.Stop);
else if (key.find("key_pause ") != string::npos) else if (key.find("key_pause ") != string::npos)
@@ -671,6 +676,10 @@ void ReadConfiguration(ncmpcpp_config &conf)
{ {
conf.display_screens_numbers_on_start = v == "yes"; conf.display_screens_numbers_on_start = v == "yes";
} }
else if (cl.find("clock_display_seconds") != string::npos)
{
conf.clock_display_seconds = v == "yes";
}
else if (cl.find("enable_window_title") != string::npos) else if (cl.find("enable_window_title") != string::npos)
{ {
conf.set_window_title = v == "yes"; conf.set_window_title = v == "yes";

View File

@@ -48,6 +48,7 @@ struct ncmpcpp_keys
int MediaLibrary[2]; int MediaLibrary[2];
int PlaylistEditor[2]; int PlaylistEditor[2];
int TagEditor[2]; int TagEditor[2];
int Clock[2];
int Stop[2]; int Stop[2];
int Pause[2]; int Pause[2];
int Next[2]; int Next[2];
@@ -146,6 +147,7 @@ struct ncmpcpp_config
bool local_browser; bool local_browser;
bool search_in_db; bool search_in_db;
bool display_screens_numbers_on_start; bool display_screens_numbers_on_start;
bool clock_display_seconds;
int mpd_port; int mpd_port;
int mpd_connection_timeout; int mpd_connection_timeout;

View File

@@ -520,7 +520,7 @@ bool Song::operator==(const Song &s) const
&& itsSong->time == s.itsSong->time && itsSong->time == s.itsSong->time
&& itsSong->pos == s.itsSong->pos && itsSong->pos == s.itsSong->pos
&& itsSong->id == s.itsSong->id && itsSong->id == s.itsSong->id
&& itsHash == itsHash; && itsHash == s.itsHash;
} }
bool Song::operator!=(const Song &s) const bool Song::operator!=(const Song &s) const

View File

@@ -97,7 +97,8 @@ void UnlockStatusbar()
void TraceMpdStatus() void TraceMpdStatus()
{ {
Mpd->UpdateStatus(); if (Mpd->Connected())
Mpd->UpdateStatus();
time_t now = time(NULL); time_t now = time(NULL);
if (current_screen == csPlaylist && now == timer+Config.playlist_disable_highlight_delay) if (current_screen == csPlaylist && now == timer+Config.playlist_disable_highlight_delay)

View File

@@ -103,7 +103,7 @@ char *str_pool_dup(const char *value)
} }
} }
void str_pool_put(const char *value) void str_pool_put(char *value)
{ {
struct slot **slot_p, *slot; struct slot **slot_p, *slot;

View File

@@ -27,7 +27,7 @@ char *str_pool_get(const char *value);
char *str_pool_dup(const char *value); char *str_pool_dup(const char *value);
void str_pool_put(const char *value); void str_pool_put(char *value);
#ifdef __cplusplus #ifdef __cplusplus
} }