inLimbo
TUI Music Player that keeps you in Limbo.
 
Loading...
Searching...
No Matches
misc.hpp
Go to the documentation of this file.
1#ifndef MISC_HEADER
2#define MISC_HEADER
3
5#include "./colors.hpp"
7#include <cctype>
8#include <ftxui/component/captured_mouse.hpp>
9#include <ftxui/component/component.hpp>
10#include <ftxui/component/component_base.hpp>
11#include <ftxui/component/event.hpp>
12#include <ftxui/component/screen_interactive.hpp>
13#include <ftxui/dom/elements.hpp>
14#include <string>
15#include <vector>
16
18{
19 Component artists_list;
20 Component songs_list;
22 Component lyrics_scroller;
23 Component MainRenderer;
25};
26
27auto formatLyrics(const std::string& lyrics)
28{
29 std::vector<std::string> lines;
30 std::string currentLine;
31 bool insideSquareBrackets = false;
32 bool insideCurlBrackets = false;
33 bool lastWasUppercase = false;
34 bool lastWasSpecialChar = false; // Tracks special characters within words
35 char previousChar = '\0';
36
37 for (char c : lyrics)
38 {
39 if (c == '[' || c == '(')
40 {
41 if (!currentLine.empty())
42 {
43 lines.push_back(currentLine);
44 currentLine.clear();
45 }
46 if (c == '[')
47 insideSquareBrackets = true;
48 else
49 insideCurlBrackets = true;
50 currentLine += c;
51 continue;
52 }
53
54 if (insideSquareBrackets || insideCurlBrackets)
55 {
56 currentLine += c;
57 if (c == ']' && insideSquareBrackets)
58 {
59 lines.push_back(currentLine);
60 currentLine.clear();
61 insideSquareBrackets = false;
62 }
63
64 else if (c == ')' && insideCurlBrackets)
65 {
66 lines.push_back(currentLine);
67 currentLine.clear();
68 insideCurlBrackets = false;
69 }
70 continue;
71 }
72
73 if (c == '\'' || c == '-')
74 {
75 currentLine += c;
76 lastWasSpecialChar = true;
77 continue;
78 }
79
80 if (std::isupper(c) && !lastWasUppercase && !lastWasSpecialChar && !currentLine.empty() &&
81 previousChar != '\n' && previousChar != ' ')
82 {
83 lines.push_back(currentLine);
84 currentLine.clear();
85 }
86
87 currentLine += c;
88
89 if (c == '\n')
90 {
91 if (!currentLine.empty())
92 {
93 lines.push_back(currentLine);
94 currentLine.clear();
95 }
96 }
97
98 lastWasUppercase = std::isupper(c);
99 lastWasSpecialChar = false;
100 previousChar = c;
101 }
102
103 if (!currentLine.empty())
104 {
105 lines.push_back(currentLine);
106 }
107
108 // Trim empty lines (optional)
109 lines.erase(std::remove_if(lines.begin(), lines.end(),
110 [](const std::string& line) { return line.empty(); }),
111 lines.end());
112
113 return lines;
114}
115
116std::string charToStr(char ch)
117{
118 switch (ch)
119 {
120 case '\t':
121 return "Tab";
122 case ' ':
123 return "Space";
124 case '\n':
125 return "Enter";
126 case 27:
127 return "Escape"; // ASCII value for the Escape key
128 default:
129 return std::string(1, static_cast<char>(ch));
130 }
131}
132
133auto FormatTime(int seconds)
134{
135 int minutes = seconds / 60;
136 seconds = seconds % 60;
137 std::stringstream ss;
138 ss << std::setfill('0') << std::setw(2) << minutes << ":" << std::setfill('0') << std::setw(2)
139 << seconds << " ";
140 return ss.str();
141}
142
143auto getTrueColor(TrueColors::Color color) { return ftxui::color(TrueColors::GetColor(color)); }
144
145auto getTrueBGColor(TrueColors::Color color) { return ftxui::bgcolor(TrueColors::GetColor(color)); }
146
147auto renderAlbumName(const std::string& album_name, const int& year, ftxui::Color sel_color)
148{
149 return hbox({text(" "), text(album_name) | bold, filler(),
150 text(std::to_string(year)) | dim | align_right, text(" ")}) |
151 inverted | color(sel_color) | dim;
152}
153
154auto renderSongName(const std::string& disc_track_info, const std::string& song_name,
155 const int& duration)
156{
157 return hbox({text(disc_track_info) | dim, text(song_name) | bold | flex_grow,
158 filler(), // Spacer for dynamic layout
159 text(FormatTime(duration)) | align_right});
160}
161
162auto CreateMenu(const std::vector<std::string>* vecLines, int* currLine)
163{
164 MenuOption menu_options;
165 menu_options.on_change = [&]() {};
166 menu_options.focused_entry = currLine;
167
168 return Menu(vecLines, currLine, menu_options);
169}
170
171auto RenderSongMenu(const std::vector<Element>& items)
172{
173 Elements rendered_items;
174 for (int i = 0; i < items.size(); ++i)
175 {
176 rendered_items.push_back(items[i] | frame);
177 }
178
179 return vbox(std::move(rendered_items));
180}
181
182auto RenderThumbnail(const std::string& songFilePath, const std::string& cacheDirPath,
183 const std::string& songTitle, const std::string& artistName,
184 const std::string& albumName, const std::string& genre, unsigned int year,
185 unsigned int trackNumber, unsigned int discNumber,
186 float progress) // progress: a value between 0.0 (0%) and 1.0 (100%)
187{
188 auto thumbnailFilePath = cacheDirPath + "thumbnail.png";
189
190 if (extractThumbnail(songFilePath, thumbnailFilePath))
191 {
192 auto thumbnail = Renderer(
193 [&]
194 {
195 return vbox({image_view(thumbnailFilePath)}) |
196 center; // [TODO] Is not being centered properly
197 });
198
199 auto metadataView = vbox({
200 hbox({text(albumName) | bold | underlined}) | center,
201 hbox({text(songTitle) | bold, text(" by "), text(artistName) | bold, text(" ["),
202 text(std::to_string(year)), text("]"), text(" ("),
203 text(std::to_string(discNumber)) | bold, text("/"),
204 text(std::to_string(trackNumber)) | bold, text(")")}) |
205 center,
206 hbox({text("Seems like a "), text(genre) | bold, text(" type of song...")}) | center, // Genre
207 });
208
209 auto progressBar = hbox({
210 text("Progress: ") | bold,
211 gauge(progress) | flex, // Progress bar
212 text(" "),
213 text(std::to_string(static_cast<int>(progress * 100)) + "%"),
214 });
215
216 auto thumbNailEle = vbox({thumbnail->Render()});
217
218 auto modernUI = vbox({
219 thumbNailEle | flex_shrink, // Centered and scaled thumbnail
220 separator(),
221 metadataView | borderRounded, // Metadata in a rounded bordered box
222 separator(),
223 progressBar, // Progress bar below the metadata
224 }) |
225 borderRounded;
226
227 return modernUI;
228 }
229
230 // Fallback for when thumbnail extraction fails
231 auto errorView = vbox({
232 text("Error: Thumbnail not found!") | center | dim,
233 separator(),
234 text("Please ensure the file has embedded artwork.") | center,
235 });
236
237 return errorView;
238}
239
240#endif
auto getTrueBGColor(TrueColors::Color color)
Definition misc.hpp:145
auto getTrueColor(TrueColors::Color color)
Definition misc.hpp:143
std::string charToStr(char ch)
Definition misc.hpp:116
auto RenderThumbnail(const std::string &songFilePath, const std::string &cacheDirPath, const std::string &songTitle, const std::string &artistName, const std::string &albumName, const std::string &genre, unsigned int year, unsigned int trackNumber, unsigned int discNumber, float progress)
Definition misc.hpp:182
auto renderSongName(const std::string &disc_track_info, const std::string &song_name, const int &duration)
Definition misc.hpp:154
auto RenderSongMenu(const std::vector< Element > &items)
Definition misc.hpp:171
auto renderAlbumName(const std::string &album_name, const int &year, ftxui::Color sel_color)
Definition misc.hpp:147
auto CreateMenu(const std::vector< std::string > *vecLines, int *currLine)
Definition misc.hpp:162
auto FormatTime(int seconds)
Definition misc.hpp:133
auto formatLyrics(const std::string &lyrics)
Definition misc.hpp:27
ftxui::Color GetColor(Color color)
Maps a predefined color enum to its corresponding ftxui::Color::RGB value.
Definition colors.hpp:78
Color
Enumeration for predefined true colors.
Definition colors.hpp:26
Element image_view(std::string_view url)
Definition image_view.cpp:82
Definition misc.hpp:18
Component songs_queue_comp
Definition misc.hpp:21
Component lyrics_scroller
Definition misc.hpp:22
Component artists_list
Definition misc.hpp:19
Component MainRenderer
Definition misc.hpp:23
Component songs_list
Definition misc.hpp:20
Component ThumbnailRenderer
Definition misc.hpp:24
A header file for the TagLibParser class and Metadata structure, used to parse metadata from audio fi...
bool extractThumbnail(const std::string &audioFilePath, const std::string &outputImagePath)
Extracts the thumbnail (album art) from an audio file and saves it to an image file.
Definition taglib_parser.h:267