mirror of
https://github.com/clangen/musikcube.git
synced 2024-12-28 15:16:43 +00:00
Fixed column alignment in TrackListView with respect to multi-byte
characters.
This commit is contained in:
parent
2b1a924165
commit
b3a189b240
@ -144,13 +144,13 @@ int64 IndexerLayout::ListItemDecorator(
|
||||
|
||||
void IndexerLayout::InitializeWindows() {
|
||||
this->title.reset(new TextLabel());
|
||||
this->title->SetText("settings", TextLabel::AlignCenter);
|
||||
this->title->SetText("settings", text::AlignCenter);
|
||||
|
||||
this->browseLabel.reset(new TextLabel());
|
||||
this->browseLabel->SetText("browse (SPACE to add)", TextLabel::AlignLeft);
|
||||
this->browseLabel->SetText("browse (SPACE to add)", text::AlignLeft);
|
||||
|
||||
this->addedPathsLabel.reset(new TextLabel());
|
||||
this->addedPathsLabel->SetText("indexed paths (BACKSPACE to remove)", TextLabel::AlignLeft);
|
||||
this->addedPathsLabel->SetText("indexed paths (BACKSPACE to remove)", text::AlignLeft);
|
||||
|
||||
this->addedPathsList.reset(new cursespp::ListWindow(&this->addedPathsAdapter));
|
||||
this->browseList.reset(new cursespp::ListWindow(&this->browseAdapter));
|
||||
|
@ -148,42 +148,41 @@ bool NowPlayingLayout::KeyPress(const std::string& key) {
|
||||
#define ALBUM_COL_WIDTH 14
|
||||
#define DURATION_COL_WIDTH 5 /* 00:00 */
|
||||
|
||||
/* see TrackListView.cpp for more info */
|
||||
#define DISPLAY_WIDTH(chars, str) \
|
||||
chars + (str.size() - u8len(str))
|
||||
|
||||
static std::string formatWithAlbum(TrackPtr track, size_t width) {
|
||||
std::string trackNum = track->GetValue(constants::Track::TRACK_NUM);
|
||||
std::string artist = track->GetValue(constants::Track::ARTIST);
|
||||
std::string album = track->GetValue(constants::Track::ALBUM);
|
||||
std::string title = track->GetValue(constants::Track::TITLE);
|
||||
std::string duration = track->GetValue(constants::Track::DURATION);
|
||||
std::string trackNum = text::Align(
|
||||
track->GetValue(constants::Track::TRACK_NUM),
|
||||
text::AlignLeft,
|
||||
TRACK_COL_WIDTH);
|
||||
|
||||
int column0Width = DISPLAY_WIDTH(TRACK_COL_WIDTH, trackNum);
|
||||
int column2Width = DISPLAY_WIDTH(DURATION_COL_WIDTH, duration);
|
||||
int column3Width = DISPLAY_WIDTH(ARTIST_COL_WIDTH, artist);
|
||||
int column4Width = DISPLAY_WIDTH(ALBUM_COL_WIDTH, album);
|
||||
std::string duration = text::Align(
|
||||
duration::Duration(track->GetValue(constants::Track::DURATION)),
|
||||
text::AlignRight,
|
||||
DURATION_COL_WIDTH);
|
||||
|
||||
size_t column1CharacterCount =
|
||||
std::string album = text::Align(
|
||||
track->GetValue(constants::Track::ALBUM),
|
||||
text::AlignLeft,
|
||||
ALBUM_COL_WIDTH);
|
||||
|
||||
std::string artist = text::Align(
|
||||
track->GetValue(constants::Track::ARTIST),
|
||||
text::AlignLeft,
|
||||
ARTIST_COL_WIDTH);
|
||||
|
||||
size_t titleWidth =
|
||||
width -
|
||||
column0Width -
|
||||
column2Width -
|
||||
column3Width -
|
||||
column4Width -
|
||||
(3 * 4); /* 3 = spacing */
|
||||
TRACK_COL_WIDTH -
|
||||
DURATION_COL_WIDTH -
|
||||
ALBUM_COL_WIDTH -
|
||||
ARTIST_COL_WIDTH -
|
||||
(4 * 3); /* 3 = spacing */
|
||||
|
||||
int column1Width = DISPLAY_WIDTH(column1CharacterCount, title);
|
||||
|
||||
text::Ellipsize(artist, ARTIST_COL_WIDTH);
|
||||
text::Ellipsize(album, ALBUM_COL_WIDTH);
|
||||
text::Ellipsize(title, column1CharacterCount);
|
||||
duration = duration::Duration(duration);
|
||||
std::string title = text::Align(
|
||||
track->GetValue(constants::Track::TITLE),
|
||||
text::AlignLeft,
|
||||
titleWidth);
|
||||
|
||||
return boost::str(
|
||||
boost::format("%s %s %s %s %s")
|
||||
% group(setw(column0Width), setfill(' '), trackNum)
|
||||
% group(setw(column1Width), setiosflags(std::ios::left), setfill(' '), title)
|
||||
% group(setw(column2Width), setiosflags(std::ios::right), setfill(' '), duration)
|
||||
% group(setw(column3Width), setiosflags(std::ios::left), setfill(' '), artist)
|
||||
% group(setw(column4Width), setiosflags(std::ios::left), setfill(' '), album));
|
||||
% trackNum % title % duration % album % artist);
|
||||
}
|
@ -36,6 +36,7 @@
|
||||
|
||||
#include <cursespp/Colors.h>
|
||||
#include <cursespp/Screen.h>
|
||||
#include <cursespp/Text.h>
|
||||
#include <core/library/LocalLibraryConstants.h>
|
||||
#include <app/query/CategoryTrackListQuery.h>
|
||||
#include "SearchLayout.h"
|
||||
@ -97,9 +98,9 @@ void SearchLayout::Layout() {
|
||||
this->AddWindow(view); \
|
||||
view->SetFocusOrder(order);
|
||||
|
||||
#define CREATE_LABEL(view, text) \
|
||||
#define CREATE_LABEL(view, value) \
|
||||
view.reset(new cursespp::TextLabel()); \
|
||||
view->SetText(text, cursespp::TextLabel::AlignCenter); \
|
||||
view->SetText(value, cursespp::text::AlignCenter); \
|
||||
this->AddWindow(view);
|
||||
|
||||
void SearchLayout::InitializeWindows(PlaybackService& playback) {
|
||||
|
@ -56,7 +56,7 @@ bool GlobalHotkeys::Handle(const std::string& kn) {
|
||||
playback::PauseOrResume(this->transport);
|
||||
return true;
|
||||
}
|
||||
if (kn == "M-i") {
|
||||
else if (kn == "M-i") {
|
||||
this->transport.SetVolume(this->transport.Volume() + 0.05); /* 5% */
|
||||
return true;
|
||||
}
|
||||
|
@ -169,42 +169,37 @@ size_t TrackListView::Adapter::GetEntryCount() {
|
||||
#define ARTIST_COL_WIDTH 17
|
||||
#define DURATION_COL_WIDTH 5 /* 00:00 */
|
||||
|
||||
/* so this part is a bit tricky... we draw multiple columns, but we use
|
||||
standard std::setw() stuff, which is not aware of multi-byte characters.
|
||||
so we have to manually adjust the widths (i.e. we can't just use simple
|
||||
constants) */
|
||||
#define DISPLAY_WIDTH(chars, str) \
|
||||
chars + (str.size() - u8len(str))
|
||||
|
||||
static std::string formatWithoutAlbum(TrackPtr track, size_t width) {
|
||||
std::string trackNum = track->GetValue(constants::Track::TRACK_NUM);
|
||||
std::string artist = track->GetValue(constants::Track::ARTIST);
|
||||
std::string title = track->GetValue(constants::Track::TITLE);
|
||||
std::string duration = track->GetValue(constants::Track::DURATION);
|
||||
std::string trackNum = text::Align(
|
||||
track->GetValue(constants::Track::TRACK_NUM),
|
||||
text::AlignLeft,
|
||||
TRACK_COL_WIDTH);
|
||||
|
||||
int column0Width = DISPLAY_WIDTH(TRACK_COL_WIDTH, trackNum);
|
||||
int column2Width = DISPLAY_WIDTH(DURATION_COL_WIDTH, duration);
|
||||
int column3Width = DISPLAY_WIDTH(ARTIST_COL_WIDTH, artist);
|
||||
std::string duration = text::Align(
|
||||
duration::Duration(track->GetValue(constants::Track::DURATION)),
|
||||
text::AlignRight,
|
||||
DURATION_COL_WIDTH);
|
||||
|
||||
size_t column1CharacterCount =
|
||||
std::string artist = text::Align(
|
||||
track->GetValue(constants::Track::ARTIST),
|
||||
text::AlignLeft,
|
||||
ARTIST_COL_WIDTH);
|
||||
|
||||
size_t titleWidth =
|
||||
width -
|
||||
column0Width -
|
||||
column2Width -
|
||||
column3Width -
|
||||
TRACK_COL_WIDTH -
|
||||
DURATION_COL_WIDTH -
|
||||
ARTIST_COL_WIDTH -
|
||||
(3 * 3); /* 3 = spacing */
|
||||
|
||||
int column1Width = DISPLAY_WIDTH(column1CharacterCount, title);
|
||||
|
||||
text::Ellipsize(artist, ARTIST_COL_WIDTH);
|
||||
text::Ellipsize(title, column1CharacterCount);
|
||||
duration = duration::Duration(duration);
|
||||
std::string title = text::Align(
|
||||
track->GetValue(constants::Track::TITLE),
|
||||
text::AlignLeft,
|
||||
titleWidth);
|
||||
|
||||
return boost::str(
|
||||
boost::format("%s %s %s %s")
|
||||
% group(setw(column0Width), setfill(' '), trackNum)
|
||||
% group(setw(column1Width), setiosflags(std::ios::left), setfill(' '), title)
|
||||
% group(setw(column2Width), setiosflags(std::ios::right), setfill(' '), duration)
|
||||
% group(setw(column3Width), setiosflags(std::ios::left), setfill(' '), artist));
|
||||
% trackNum % title % duration % artist);
|
||||
}
|
||||
|
||||
IScrollAdapter::EntryPtr TrackListView::Adapter::GetEntry(size_t index) {
|
||||
|
@ -37,6 +37,8 @@
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#define PAD(str, count) for (size_t i = 0; i < count; i++) { str += " "; }
|
||||
|
||||
namespace cursespp {
|
||||
namespace text {
|
||||
void Truncate(std::string& str, size_t len) {
|
||||
@ -69,5 +71,34 @@ namespace cursespp {
|
||||
str += "..";
|
||||
}
|
||||
}
|
||||
|
||||
std::string Align(const std::string& str, TextAlign align, size_t cx) {
|
||||
size_t len = u8len(str);
|
||||
|
||||
if (len > cx) {
|
||||
std::string ellipsized = str;
|
||||
Ellipsize(ellipsized, cx);
|
||||
return ellipsized;
|
||||
}
|
||||
else if (align == AlignLeft) {
|
||||
size_t pad = cx - len;
|
||||
std::string left = str;
|
||||
PAD(left, pad);
|
||||
return left;
|
||||
}
|
||||
else {
|
||||
size_t leftPad = (align == AlignRight)
|
||||
? (cx - len)
|
||||
: (cx - len) / 2;
|
||||
|
||||
size_t rightPad = cx - (leftPad + len);
|
||||
|
||||
std::string padded;
|
||||
PAD(padded, leftPad);
|
||||
padded += str;
|
||||
PAD(padded, rightPad);
|
||||
return padded;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,14 @@
|
||||
|
||||
namespace cursespp {
|
||||
namespace text {
|
||||
enum TextAlign {
|
||||
AlignLeft,
|
||||
AlignCenter,
|
||||
AlignRight
|
||||
};
|
||||
|
||||
void Truncate(std::string& str, size_t len);
|
||||
void Ellipsize(std::string& str, size_t len);
|
||||
std::string Align(const std::string& str, TextAlign align, size_t len);
|
||||
}
|
||||
}
|
||||
|
@ -46,44 +46,22 @@ using namespace cursespp;
|
||||
|
||||
inline static void redrawContents(
|
||||
IWindow &window,
|
||||
const TextLabel::Alignment alignment,
|
||||
const text::TextAlign alignment,
|
||||
const std::string& text)
|
||||
{
|
||||
std::string aligned = text::Align(
|
||||
text, alignment, window.GetContentWidth());
|
||||
|
||||
WINDOW* c = window.GetContent();
|
||||
werase(c);
|
||||
|
||||
int len = (int) u8len(text);
|
||||
int cx = window.GetContentWidth();
|
||||
|
||||
if (len > cx) {
|
||||
std::string ellipsized = text;
|
||||
text::Ellipsize(ellipsized, cx);
|
||||
wprintw(c, ellipsized.c_str());
|
||||
}
|
||||
else if (alignment == TextLabel::AlignLeft) {
|
||||
wprintw(c, text.c_str());
|
||||
}
|
||||
else { /* center */
|
||||
int leftPad =
|
||||
(alignment == TextLabel::AlignRight)
|
||||
? (cx - len)
|
||||
: (cx - len) / 2;
|
||||
|
||||
std::string padded;
|
||||
for (int i = 0; i < leftPad; i++) {
|
||||
padded += " ";
|
||||
}
|
||||
|
||||
padded += text;
|
||||
wprintw(c, padded.c_str());
|
||||
}
|
||||
wprintw(c, aligned.c_str());
|
||||
|
||||
window.Repaint();
|
||||
}
|
||||
|
||||
TextLabel::TextLabel()
|
||||
: Window()
|
||||
, alignment(AlignLeft) {
|
||||
, alignment(text::AlignLeft) {
|
||||
this->SetFrameVisible(false);
|
||||
}
|
||||
|
||||
@ -95,7 +73,7 @@ void TextLabel::Show() {
|
||||
redrawContents(*this, this->alignment, this->buffer);
|
||||
}
|
||||
|
||||
void TextLabel::SetText(const std::string& value, const Alignment alignment) {
|
||||
void TextLabel::SetText(const std::string& value, const text::TextAlign alignment) {
|
||||
if (value != this->buffer || alignment != this->alignment) {
|
||||
this->buffer = value;
|
||||
this->alignment = alignment;
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <cursespp/curses_config.h>
|
||||
#include <cursespp/Window.h>
|
||||
#include <cursespp/IInput.h>
|
||||
#include <cursespp/Text.h>
|
||||
#include <sigslot/sigslot.h>
|
||||
|
||||
namespace cursespp {
|
||||
@ -48,18 +49,12 @@ namespace cursespp {
|
||||
public cursespp::Window {
|
||||
#endif
|
||||
public:
|
||||
enum Alignment {
|
||||
AlignLeft,
|
||||
AlignCenter,
|
||||
AlignRight
|
||||
};
|
||||
|
||||
TextLabel();
|
||||
virtual ~TextLabel();
|
||||
|
||||
virtual void SetText(
|
||||
const std::string& value,
|
||||
const Alignment alignment = AlignLeft);
|
||||
const text::TextAlign alignment = text::AlignLeft);
|
||||
|
||||
virtual std::string GetText() { return this->buffer; }
|
||||
|
||||
@ -67,6 +62,6 @@ namespace cursespp {
|
||||
|
||||
private:
|
||||
std::string buffer;
|
||||
Alignment alignment;
|
||||
text::TextAlign alignment;
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user