Merge branch 'master' of github.com:clangen/musikcube

This commit is contained in:
casey langen 2017-07-26 22:30:58 -07:00
commit 7d6ac3d6b9
18 changed files with 71 additions and 53 deletions

View File

@ -63,6 +63,7 @@ set (musikcube_LINK_LIBS
${BOOST_LINK_LIBS}
dl
curl
pthread
)
include_directories (
@ -79,6 +80,10 @@ if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
include_directories("/usr/local/include")
endif ()
if (EXISTS "/etc/arch-release")
add_definitions (-DNO_NCURSESW)
endif()
add_subdirectory(src/core)
add_subdirectory(src/glue)
add_subdirectory(src/musikcube)

View File

@ -4,8 +4,6 @@ a cross-platform, terminal-based audio engine, library, player and server writte
musikcube compiles and runs easily on windows, macos and linux. it also runs well on a raspberry pi with raspbian, and can be setup as a streaming audio server.
if you'd like to check out a quick demo, you can view an [asciinema cast here](https://asciinema.org/a/129748).
[keyboard shortcuts are described in the user guide.](https://github.com/clangen/musikcube/wiki/user-guide)
# screenshots
@ -22,7 +20,7 @@ and on linux:
![linux screenshot](https://raw.githubusercontent.com/clangen/clangen-projects-static/master/musikcube/screenshots/linux.png)
here's a little demo:
here's a demo (made with asciinema):
[![asciicast](https://asciinema.org/a/129748.png)](https://asciinema.org/a/129748)

View File

@ -36,6 +36,7 @@
#include <core/debug.h>
#include <functional>
#include <string>
#include <queue>
#include <thread>

View File

@ -76,7 +76,7 @@ std::string musik::core::GetApplicationDirectory() {
result = result.substr(0, last); /* remove filename component */
#else
std::string pathToProc = boost::str(boost::format("/proc/%d/exe") % (int) getpid());
char pathbuf[PATH_MAX + 1];
char pathbuf[PATH_MAX + 1] = { 0 };
readlink(pathToProc.c_str(), pathbuf, PATH_MAX);
result.assign(pathbuf);
size_t last = result.find_last_of("/");
@ -266,4 +266,4 @@ close_and_return:
}
return success;
}
}

View File

@ -285,7 +285,7 @@ static size_t writePlayingFormat(
}
ON(w, attr);
wprintw(w, value.c_str());
checked_wprintw(w, value.c_str());
OFF(w, attr);
remaining -= cols;
@ -477,7 +477,7 @@ void TransportWindow::Update(TimeMode timeMode) {
if (stopped) {
ON(c, disabled);
wprintw(c, Strings.STOPPED.c_str());
checked_wprintw(c, Strings.STOPPED.c_str());
displayCache->Reset();
OFF(c, disabled);
}
@ -489,7 +489,7 @@ void TransportWindow::Update(TimeMode timeMode) {
wmove(c, 0, cx - shuffleLabelLen);
int64_t shuffleAttrs = this->playback.IsShuffled() ? gb : disabled;
ON(c, shuffleAttrs);
wprintw(c, shuffleLabel.c_str());
checked_wprintw(c, shuffleLabel.c_str());
OFF(c, shuffleAttrs);
/* volume slider */
@ -604,20 +604,20 @@ void TransportWindow::Update(TimeMode timeMode) {
wmove(c, 1, 0); /* move cursor to the second line */
ON(c, volumeAttrs);
wprintw(c, volume.c_str());
checked_wprintw(c, volume.c_str());
OFF(c, volumeAttrs);
ON(c, currentTimeAttrs); /* blink if paused */
wprintw(c, "%s ", currentTime.c_str());
checked_wprintw(c, "%s ", currentTime.c_str());
OFF(c, currentTimeAttrs);
ON(c, timerAttrs);
waddstr(c, timerTrack.c_str()); /* may be a very long string */
wprintw(c, " %s", displayCache->totalTime.c_str());
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);
wprintw(c, repeatModeLabel.c_str());
checked_wprintw(c, repeatModeLabel.c_str());
OFF(c, repeatAttrs);
this->Invalidate();

View File

@ -90,7 +90,7 @@ void Checkbox::OnRedraw() {
wattron(c, COLOR_PAIR(attrs));
}
wprintw(c, ellipsized.c_str());
checked_wprintw(c, ellipsized.c_str());
if (attrs != -1) {
wattroff(c, COLOR_PAIR(attrs));

View File

@ -169,7 +169,7 @@ void DialogOverlay::RecalculateSize() {
}
void DialogOverlay::Redraw() {
if (this->width <= 0 || this->height <= 0) {
if (!this->IsVisible() || this->width <= 0 || this->height <= 0) {
return;
}
@ -181,7 +181,7 @@ void DialogOverlay::Redraw() {
if (this->title.size()) {
wmove(c, currentY, currentX);
wattron(c, A_BOLD);
wprintw(c, text::Ellipsize(this->title, this->width - 4).c_str());
checked_wprintw(c, text::Ellipsize(this->title, this->width - 4).c_str());
wattroff(c, A_BOLD);
currentY += 2;
}
@ -189,8 +189,8 @@ void DialogOverlay::Redraw() {
if (this->message.size()) {
for (size_t i = 0; i < messageLines.size(); i++) {
wmove(c, currentY, currentX);
wprintw(c, this->messageLines.at(i).c_str());
checked_wprintw(c, this->messageLines.at(i).c_str());
++currentY;
}
}
}
}

View File

@ -172,7 +172,7 @@ void InputOverlay::RecalculateSize() {
}
void InputOverlay::Redraw() {
if (this->width <= 0 || this->height <= 0) {
if (!this->IsVisible() || this->width <= 0 || this->height <= 0) {
return;
}
@ -181,7 +181,7 @@ void InputOverlay::Redraw() {
if (this->title.size()) {
wmove(c, 0, 1);
wattron(c, A_BOLD);
wprintw(c, text::Ellipsize(this->title, this->width - 4).c_str());
checked_wprintw(c, text::Ellipsize(this->title, this->width - 4).c_str());
wattroff(c, A_BOLD);
}
}

View File

@ -213,7 +213,7 @@ void ListOverlay::RecalculateSize() {
}
void ListOverlay::Redraw() {
if (this->width <= 0 || this->height <= 0) {
if (!this->IsVisible() || this->width <= 0 || this->height <= 0) {
return;
}
@ -225,7 +225,7 @@ void ListOverlay::Redraw() {
if (this->title.size()) {
wmove(c, currentY, currentX);
wattron(c, A_BOLD);
wprintw(c, text::Ellipsize(this->title, this->width - 4).c_str());
checked_wprintw(c, text::Ellipsize(this->title, this->width - 4).c_str());
wattroff(c, A_BOLD);
currentY += 2;
}
@ -234,4 +234,4 @@ void ListOverlay::Redraw() {
void ListOverlay::RefreshAdapter() {
this->listWindow->OnAdapterChanged();
}
}

View File

@ -113,7 +113,7 @@ void ScrollAdapterBase::DrawPage(ScrollableWindow* scrollable, size_t index, Scr
WINDOW* window = scrollable->GetContent();
werase(window);
if (this->height == 0 || this->width == 0 || this->GetEntryCount() == 0) {
if (!scrollable->IsVisible() || !window || this->height == 0 || this->width == 0 || this->GetEntryCount() == 0) {
return;
}
@ -158,7 +158,7 @@ void ScrollAdapterBase::DrawPage(ScrollableWindow* scrollable, size_t index, Scr
/* string is padded above, we don't need a \n */
wprintw(window, "%s", line.c_str());
checked_wprintw(window, "%s", line.c_str());
if (attrs != -1) {
wattroff(window, attrs);

View File

@ -185,7 +185,7 @@ void ShortcutsWindow::OnRedraw() {
int64_t keyAttrs = (e->attrs == -1) ? normalAttrs : COLOR_PAIR(e->attrs);
keyAttrs = (e->key == this->activeKey) ? activeAttrs : keyAttrs;
wprintw(c, " ");
checked_wprintw(c, " ");
--remaining;
if (remaining == 0) {
@ -202,7 +202,7 @@ void ShortcutsWindow::OnRedraw() {
}
wattron(c, keyAttrs);
wprintw(c, key.c_str());
checked_wprintw(c, key.c_str());
wattroff(c, keyAttrs);
remaining -= len;
@ -217,7 +217,7 @@ void ShortcutsWindow::OnRedraw() {
len = remaining;
}
wprintw(c, value.c_str());
checked_wprintw(c, value.c_str());
remaining -= len;
}

View File

@ -102,7 +102,7 @@ void TextInput::OnRedraw() {
if (!this->IsFocused() && !columns && hintText.size()) {
/* draw the hint if we have one and there's no string yet */
waddstr(c, u8substr(hintText, 0, columns).c_str());
checked_waddstr(c, u8substr(hintText, 0, columns).c_str());
}
else {
/* mask the string if we're in password mode */
@ -121,7 +121,7 @@ void TextInput::OnRedraw() {
/* finally, draw the offset/trimmed, potentially masked, padded
string to the output */
waddstr(c, trimmed.c_str());
checked_waddstr(c, trimmed.c_str());
}
}

View File

@ -72,7 +72,7 @@ void TextLabel::OnRedraw() {
}
wmove(c, 0, 0);
waddstr(c, aligned.c_str());
checked_waddstr(c, aligned.c_str());
if (attrs != -1) {
wattroff(c, COLOR_PAIR(attrs));

View File

@ -100,7 +100,7 @@ void ToastOverlay::RecalculateSize() {
}
void ToastOverlay::OnRedraw() {
if (this->width <= 0 || this->height <= 0) {
if (!this->IsVisible() || this->width <= 0 || this->height <= 0) {
return;
}
@ -108,6 +108,6 @@ void ToastOverlay::OnRedraw() {
for (int i = 0; i < (int) this->titleLines.size(); i++) {
wmove(c, i, 1);
wprintw(c, text::Ellipsize(this->titleLines[i], this->width - 4).c_str());
checked_wprintw(c, text::Ellipsize(this->titleLines[i], this->width - 4).c_str());
}
}
}

View File

@ -389,18 +389,37 @@ void Window::SetFocusedFrameColor(int64_t color) {
this->RepaintBackground();
}
void Window::DrawFrameAndTitle() {
box(this->frame, 0, 0);
/* draw the title, if one is specified */
size_t titleLen = u8len(this->title);
if (titleLen > 0) {
int max = this->width - 4; /* 4 = corner + space + space + corner */
if (max > 3) { /* 3 = first character plus ellipse (e.g. 'F..')*/
std::string adjusted = " " + text::Ellipsize(this->title, (size_t) max - 2) + " ";
wmove(this->frame, 0, 2);
checked_waddstr(this->frame, adjusted.c_str());
}
}
}
void Window::RepaintBackground() {
bool focused = IsFocused();
if (this->drawFrame &&
this->frameColor != CURSESPP_DEFAULT_COLOR &&
this->frame &&
this->content != this->frame)
{
wbkgd(this->frame, COLOR_PAIR(IsFocused()
wbkgd(this->frame, COLOR_PAIR(focused
? this->focusedFrameColor : this->frameColor));
this->DrawFrameAndTitle();
}
if (this->content) {
wbkgd(this->content, COLOR_PAIR(IsFocused()
wbkgd(this->content, COLOR_PAIR(focused
? this->focusedContentColor : this->contentColor));
}
@ -621,8 +640,6 @@ void Window::Create() {
sub-window inside */
else {
box(this->frame, 0, 0);
this->content = newwin(
this->height - 2,
this->width - 2,
@ -646,16 +663,7 @@ void Window::Create() {
wbkgd(this->content, COLOR_PAIR(currentContentColor));
}
/* draw the title, if one is specified */
size_t titleLen = u8len(this->title);
if (titleLen > 0) {
int max = this->width - 4; /* 4 = corner + space + space + corner */
if (max > 3) { /* 3 = first character plus ellipse (e.g. 'F..')*/
std::string adjusted = " " + text::Ellipsize(this->title, (size_t) max - 2) + " ";
wmove(this->frame, 0, 2);
waddstr(this->frame, adjusted.c_str());
}
}
this->DrawFrameAndTitle();
}
this->Show();

View File

@ -136,6 +136,7 @@ namespace cursespp {
virtual void Destroy();
void Recreate();
void Clear();
void DrawFrameAndTitle();
void RepaintBackground();
void RecreateForUpdatedDimensions();
void DestroyIfBadBounds();

View File

@ -39,13 +39,18 @@
#undef MOUSE_MOVED
#endif
#ifdef WIN32
#include <curses.h>
#include <panel.h>
#elif defined __APPLE__
#if defined(WIN32) || defined(__APPLE__) || defined(NO_NCURSESW)
#include <curses.h>
#include <panel.h>
#else
#include <ncursesw/curses.h>
#include <ncursesw/panel.h>
#endif
#include <stdarg.h>
#define checked_wprintw(window, format, ...) \
if (window && format) { wprintw(window, format, ##__VA_ARGS__); }
#define checked_waddstr(window, str) \
if (window && str) { waddstr(window, str); }

View File

@ -226,7 +226,7 @@ bool TaglibMetadataReader::GetID3v2Tag(const char* uri, musik::core::sdk::ITrack
}
if (!allTags["TCOP"].isEmpty()) { /* ID3v2.3*/
this->SetTagValue("year", allTags["TDRC"].front()->toString().substr(0, 4), track);
this->SetTagValue("year", allTags["TCOP"].front()->toString().substr(0, 4), track);
}
/* TRCK is the track number (or "trackNum/totalTracks") */