mostly working
This commit is contained in:
parent
1e2eed03de
commit
71ae0385ee
8 changed files with 470 additions and 205 deletions
|
|
@ -4,6 +4,7 @@ setup_project(mauplay ${CMAKE_INSTALL_BINDIR})
|
|||
|
||||
pkg_config_add(mauplay sqlite3)
|
||||
pkg_config_add(mauplay samplerate)
|
||||
pkg_config_add(mauplay inih)
|
||||
|
||||
target_link_libraries(
|
||||
mauplay
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ pthread_mutex_t audio_mutex;
|
|||
queue_t* queue = NULL;
|
||||
int queue_seek = -1;
|
||||
int paused = 0;
|
||||
int repeated = 0;
|
||||
|
||||
static void handler(MDEAudio handle, void* user, void* data, int frames) {
|
||||
memset(data, 0, frames * 2 * 2);
|
||||
|
|
@ -35,9 +36,14 @@ static void handler(MDEAudio handle, void* user, void* data, int frames) {
|
|||
free(to);
|
||||
|
||||
if(f < from_frames) {
|
||||
queue_seek++;
|
||||
if(queue_seek >= arrlen(queue)) {
|
||||
queue_seek = -1;
|
||||
if(repeated) {
|
||||
queue[queue_seek].frames = 0;
|
||||
MDESoundSeek(queue[queue_seek].sound, 0);
|
||||
} else {
|
||||
queue_seek++;
|
||||
if(queue_seek >= arrlen(queue)) {
|
||||
queue_seek = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
32
mauplay/db.c
32
mauplay/db.c
|
|
@ -52,7 +52,7 @@ int db_init(void) {
|
|||
|
||||
free(path);
|
||||
|
||||
if((st = db_exec("CREATE TABLE IF NOT EXISTS cache (path TEXT PRIMARY KEY, title TEXT, artist TEXT, album TEXT, genre TEXT, length INTEGER, mtime INTEGER)")) != 0) {
|
||||
if((st = db_exec("CREATE TABLE IF NOT EXISTS cache (path TEXT PRIMARY KEY, title TEXT, artist TEXT, album TEXT, genre TEXT, length INTEGER, track INTEGER, mtime INTEGER)")) != 0) {
|
||||
sqlite3_close(db);
|
||||
return st;
|
||||
}
|
||||
|
|
@ -68,6 +68,7 @@ static int db_bind(sqlite3_stmt* stmt, const char* path) {
|
|||
const char* s_album;
|
||||
const char* s_genre;
|
||||
int s_length;
|
||||
int s_track = 0;
|
||||
struct stat s;
|
||||
if(sound == NULL) return 1;
|
||||
|
||||
|
|
@ -75,6 +76,7 @@ static int db_bind(sqlite3_stmt* stmt, const char* path) {
|
|||
s_artist = sound->context->artist;
|
||||
s_album = sound->context->album;
|
||||
s_genre = sound->context->genre;
|
||||
s_track = sound->context->track;
|
||||
s_length = sound->context->frames / sound->context->sample_rate;
|
||||
|
||||
if(s_title == NULL) s_title = path;
|
||||
|
|
@ -92,7 +94,8 @@ static int db_bind(sqlite3_stmt* stmt, const char* path) {
|
|||
sqlite3_bind_text(stmt, 4, s_album, -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 5, s_genre, -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(stmt, 6, s_length);
|
||||
sqlite3_bind_int64(stmt, 7, s.st_mtime);
|
||||
sqlite3_bind_int64(stmt, 7, s_track);
|
||||
sqlite3_bind_int64(stmt, 8, s.st_mtime);
|
||||
|
||||
MDESoundClose(sound);
|
||||
|
||||
|
|
@ -104,7 +107,7 @@ static int db_bind(sqlite3_stmt* stmt, const char* path) {
|
|||
void db_add(const char* path) {
|
||||
sqlite3_stmt* stmt;
|
||||
|
||||
if(sqlite3_prepare_v2(db, "INSERT OR REPLACE INTO cache VALUES(?,?,?,?,?,?,?)", -1, &stmt, NULL) != SQLITE_OK) {
|
||||
if(sqlite3_prepare_v2(db, "INSERT OR REPLACE INTO cache VALUES(?,?,?,?,?,?,?,?)", -1, &stmt, NULL) != SQLITE_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -196,3 +199,26 @@ void db_scan(void) {
|
|||
|
||||
MwDispatchUserHandler(tree, MwNactivateHandler, ui_last);
|
||||
}
|
||||
|
||||
char** db_find(const char* query, const char* param, const char* additional) {
|
||||
char** r = NULL;
|
||||
sqlite3_stmt* stmt;
|
||||
char q[128];
|
||||
|
||||
sprintf(q, "SELECT * FROM cache WHERE %s = ? ORDER BY %s ASC", query, additional == NULL ? query : additional);
|
||||
|
||||
if(sqlite3_prepare_v2(db, q, -1, &stmt, NULL) != SQLITE_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sqlite3_bind_text(stmt, 1, param, -1, SQLITE_TRANSIENT);
|
||||
|
||||
while(sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
char* p = MDEStringDuplicate(sqlite3_column_text(stmt, 0));
|
||||
arrput(r, p);
|
||||
}
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
|||
176
mauplay/main.c
176
mauplay/main.c
|
|
@ -7,15 +7,16 @@
|
|||
#include "skipfwd.xpm"
|
||||
|
||||
#include "repeat.xpm"
|
||||
#include "repeatsong.xpm"
|
||||
#include "shuffle.xpm"
|
||||
|
||||
MwWidget window;
|
||||
MwWidget menu, album, infoframe, info, infosep, bskipback, bplay, bpause, bstop, bskipfwd, modesep, brepeat, bshuffle;
|
||||
MwWidget menu, albumframe, album, infoframe, info, timelabel, infosep, bskipback, bplay, bpause, bstop, bskipfwd, modesep, brepeat, bshuffle;
|
||||
MwWidget mainsep;
|
||||
MwWidget eltime, seekbar, rmtime;
|
||||
MwWidget seekbar;
|
||||
MwWidget tree, list;
|
||||
MwLLPixmap pxalbum, pxskipback, pxplay, pxpause, pxstop, pxskipfwd, pxrepeat, pxshuffle;
|
||||
MwLLPixmap pxoptical;
|
||||
MwLLPixmap pxalbum, pxskipback, pxplay, pxpause, pxstop, pxskipfwd, pxrepeat, pxrepeatsong, pxshuffle;
|
||||
MwLLPixmap pxoptical, pxfoldermusic, pxgenre, pxartist;
|
||||
unsigned char* pxalbumdata;
|
||||
|
||||
static void resize(MwWidget handle, void* user, void* client) {
|
||||
|
|
@ -23,13 +24,20 @@ static void resize(MwWidget handle, void* user, void* client) {
|
|||
int wh = MwGetInteger(window, MwNheight) - MwGetInteger(menu, MwNheight);
|
||||
int y = MwGetInteger(menu, MwNheight);
|
||||
|
||||
MwVaApply(album,
|
||||
MwVaApply(albumframe,
|
||||
MwNx, 5,
|
||||
MwNy, y + 5,
|
||||
MwNwidth, 32,
|
||||
MwNheight, 32,
|
||||
NULL);
|
||||
|
||||
MwVaApply(album,
|
||||
MwNx, MwDefaultBorderWidth(album),
|
||||
MwNy, MwDefaultBorderWidth(album),
|
||||
MwNwidth, 32 - MwDefaultBorderWidth(album) * 2,
|
||||
MwNheight, 32 - MwDefaultBorderWidth(album) * 2,
|
||||
NULL);
|
||||
|
||||
MwVaApply(infoframe,
|
||||
MwNx, 5 + 32 + 5,
|
||||
MwNy, y + 5,
|
||||
|
|
@ -44,6 +52,13 @@ static void resize(MwWidget handle, void* user, void* client) {
|
|||
MwNheight, MwGetInteger(infoframe, MwNheight) - MwDefaultBorderWidth(infoframe) * 2,
|
||||
NULL);
|
||||
|
||||
MwVaApply(timelabel,
|
||||
MwNx, MwGetInteger(info, MwNwidth) * 2 / 3,
|
||||
MwNy, MwDefaultBorderWidth(infoframe) + MwGetInteger(info, MwNheight) / 2,
|
||||
MwNwidth, MwGetInteger(info, MwNwidth) / 3,
|
||||
MwNheight, MwGetInteger(info, MwNheight) / 2,
|
||||
NULL);
|
||||
|
||||
MwVaApply(infosep,
|
||||
MwNx, 5 + 32 + 5 + MwGetInteger(infoframe, MwNwidth),
|
||||
MwNy, y + 5,
|
||||
|
|
@ -114,24 +129,10 @@ static void resize(MwWidget handle, void* user, void* client) {
|
|||
MwNheight, 10,
|
||||
NULL);
|
||||
|
||||
MwVaApply(eltime,
|
||||
MwVaApply(seekbar,
|
||||
MwNx, 5,
|
||||
MwNy, y + 5 + 32 + 10,
|
||||
MwNwidth, MwTextWidth(window, "000:00"),
|
||||
MwNheight, 16,
|
||||
NULL);
|
||||
|
||||
MwVaApply(seekbar,
|
||||
MwNx, 5 + MwTextWidth(window, "000:00") + 5,
|
||||
MwNy, y + 5 + 32 + 10,
|
||||
MwNwidth, ww - (5 + MwTextWidth(window, "000:00") + 5) * 2,
|
||||
MwNheight, 16,
|
||||
NULL);
|
||||
|
||||
MwVaApply(rmtime,
|
||||
MwNx, ww - 5 - MwTextWidth(window, "000:00"),
|
||||
MwNy, y + 5 + 32 + 10,
|
||||
MwNwidth, MwTextWidth(window, "000:00"),
|
||||
MwNwidth, ww - 5 * 2,
|
||||
MwNheight, 16,
|
||||
NULL);
|
||||
|
||||
|
|
@ -157,68 +158,67 @@ int main() {
|
|||
|
||||
MwLibraryInit();
|
||||
|
||||
window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 600, 400,
|
||||
MwNtitle, "mauplay",
|
||||
NULL);
|
||||
menu = MwCreateWidget(MwMenuClass, "menu", window, 0, 0, 0, 0);
|
||||
album = MwCreateWidget(MwImageClass, "album", window, 0, 0, 0, 0);
|
||||
infoframe = MwVaCreateWidget(MwFrameClass, "infoframe", window, 0, 0, 0, 0,
|
||||
MwNbackground, "#000",
|
||||
MwNforeground, "#0f0",
|
||||
MwNhasBorder, 1,
|
||||
MwNinverted, 1,
|
||||
NULL);
|
||||
info = MwVaCreateWidget(MwLabelClass, "info", infoframe, 0, 0, 0, 0,
|
||||
MwNalignment, MwALIGNMENT_BEGINNING,
|
||||
NULL);
|
||||
infosep = MwVaCreateWidget(MwSeparatorClass, "infosep", window, 0, 0, 0, 0,
|
||||
MwNorientation, MwVERTICAL,
|
||||
NULL);
|
||||
bskipback = MwVaCreateWidget(MwButtonClass, "skipback", window, 0, 0, 0, 0,
|
||||
MwNflat, 1,
|
||||
NULL);
|
||||
bplay = MwVaCreateWidget(MwButtonClass, "play", window, 0, 0, 0, 0,
|
||||
MwNflat, 1,
|
||||
NULL);
|
||||
bpause = MwVaCreateWidget(MwButtonClass, "pause", window, 0, 0, 0, 0,
|
||||
MwNflat, 1,
|
||||
NULL);
|
||||
bstop = MwVaCreateWidget(MwButtonClass, "stop", window, 0, 0, 0, 0,
|
||||
MwNflat, 1,
|
||||
NULL);
|
||||
bskipfwd = MwVaCreateWidget(MwButtonClass, "skipfwd", window, 0, 0, 0, 0,
|
||||
MwNflat, 1,
|
||||
NULL);
|
||||
modesep = MwVaCreateWidget(MwSeparatorClass, "modesep", window, 0, 0, 0, 0,
|
||||
MwNorientation, MwVERTICAL,
|
||||
NULL);
|
||||
brepeat = MwVaCreateWidget(MwButtonClass, "repeat", window, 0, 0, 0, 0,
|
||||
MwNflat, 1,
|
||||
NULL);
|
||||
bshuffle = MwVaCreateWidget(MwButtonClass, "shuffle", window, 0, 0, 0, 0,
|
||||
MwNflat, 1,
|
||||
NULL);
|
||||
mainsep = MwVaCreateWidget(MwSeparatorClass, "mainsep", window, 0, 0, 0, 0,
|
||||
MwNorientation, MwHORIZONTAL,
|
||||
NULL);
|
||||
eltime = MwVaCreateWidget(MwLabelClass, "eltime", window, 0, 0, 0, 0,
|
||||
MwNalignment, MwALIGNMENT_END,
|
||||
MwNtext, "000:00",
|
||||
NULL);
|
||||
seekbar = MwVaCreateWidget(MwScrollBarClass, "seekbar", window, 0, 0, 0, 0,
|
||||
MwNorientation, MwHORIZONTAL,
|
||||
MwNareaShown, 15,
|
||||
MwNshowArrows, 0,
|
||||
NULL);
|
||||
rmtime = MwVaCreateWidget(MwLabelClass, "rmtime", window, 0, 0, 0, 0,
|
||||
MwNalignment, MwALIGNMENT_END,
|
||||
MwNtext, "000:00",
|
||||
NULL);
|
||||
tree = MwCreateWidget(MwTreeViewClass, "tree", window, 0, 0, 0, 0);
|
||||
list = MwVaCreateWidget(MwListBoxClass, "list", window, 0, 0, 0, 0,
|
||||
MwNhasHeading, 1,
|
||||
MwNleftPadding, 16,
|
||||
NULL);
|
||||
window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 600, 400,
|
||||
MwNtitle, "mauplay",
|
||||
NULL);
|
||||
menu = MwCreateWidget(MwMenuClass, "menu", window, 0, 0, 0, 0);
|
||||
albumframe = MwVaCreateWidget(MwFrameClass, "albumframe", window, 0, 0, 0, 0,
|
||||
MwNhasBorder, 1,
|
||||
MwNinverted, 1,
|
||||
NULL);
|
||||
album = MwCreateWidget(MwImageClass, "album", albumframe, 0, 0, 0, 0);
|
||||
infoframe = MwVaCreateWidget(MwFrameClass, "infoframe", window, 0, 0, 0, 0,
|
||||
MwNbackground, "#000",
|
||||
MwNforeground, "#0f0",
|
||||
MwNhasBorder, 1,
|
||||
MwNinverted, 1,
|
||||
NULL);
|
||||
info = MwVaCreateWidget(MwLabelClass, "info", infoframe, 0, 0, 0, 0,
|
||||
MwNalignment, MwALIGNMENT_BEGINNING,
|
||||
NULL);
|
||||
timelabel = MwVaCreateWidget(MwLabelClass, "timelabel", infoframe, 0, 0, 0, 0,
|
||||
MwNalignment, MwALIGNMENT_END,
|
||||
NULL);
|
||||
infosep = MwVaCreateWidget(MwSeparatorClass, "infosep", window, 0, 0, 0, 0,
|
||||
MwNorientation, MwVERTICAL,
|
||||
NULL);
|
||||
bskipback = MwVaCreateWidget(MwButtonClass, "skipback", window, 0, 0, 0, 0,
|
||||
MwNflat, 1,
|
||||
NULL);
|
||||
bplay = MwVaCreateWidget(MwButtonClass, "play", window, 0, 0, 0, 0,
|
||||
MwNflat, 1,
|
||||
NULL);
|
||||
bpause = MwVaCreateWidget(MwButtonClass, "pause", window, 0, 0, 0, 0,
|
||||
MwNflat, 1,
|
||||
NULL);
|
||||
bstop = MwVaCreateWidget(MwButtonClass, "stop", window, 0, 0, 0, 0,
|
||||
MwNflat, 1,
|
||||
NULL);
|
||||
bskipfwd = MwVaCreateWidget(MwButtonClass, "skipfwd", window, 0, 0, 0, 0,
|
||||
MwNflat, 1,
|
||||
NULL);
|
||||
modesep = MwVaCreateWidget(MwSeparatorClass, "modesep", window, 0, 0, 0, 0,
|
||||
MwNorientation, MwVERTICAL,
|
||||
NULL);
|
||||
brepeat = MwVaCreateWidget(MwButtonClass, "repeat", window, 0, 0, 0, 0,
|
||||
MwNflat, 1,
|
||||
NULL);
|
||||
bshuffle = MwVaCreateWidget(MwButtonClass, "shuffle", window, 0, 0, 0, 0,
|
||||
MwNflat, 1,
|
||||
NULL);
|
||||
mainsep = MwVaCreateWidget(MwSeparatorClass, "mainsep", window, 0, 0, 0, 0,
|
||||
MwNorientation, MwHORIZONTAL,
|
||||
NULL);
|
||||
seekbar = MwVaCreateWidget(MwScrollBarClass, "seekbar", window, 0, 0, 0, 0,
|
||||
MwNorientation, MwHORIZONTAL,
|
||||
MwNareaShown, 15,
|
||||
MwNshowArrows, 0,
|
||||
NULL);
|
||||
tree = MwCreateWidget(MwTreeViewClass, "tree", window, 0, 0, 0, 0);
|
||||
list = MwVaCreateWidget(MwListBoxClass, "list", window, 0, 0, 0, 0,
|
||||
MwNhasHeading, 1,
|
||||
MwNleftPadding, 16,
|
||||
NULL);
|
||||
|
||||
pxalbumdata = malloc(ALBUMWIDTH * ALBUMWIDTH * 4);
|
||||
memset(pxalbumdata, 0, ALBUMWIDTH * ALBUMWIDTH * 4);
|
||||
|
|
@ -232,10 +232,14 @@ int main() {
|
|||
|
||||
free(pxalbumdata);
|
||||
|
||||
pxrepeat = MwLoadXPM(window, repeat_xpm);
|
||||
pxshuffle = MwLoadXPM(window, shuffle_xpm);
|
||||
pxrepeat = MwLoadXPM(window, repeat_xpm);
|
||||
pxrepeatsong = MwLoadXPM(window, repeatsong_xpm);
|
||||
pxshuffle = MwLoadXPM(window, shuffle_xpm);
|
||||
|
||||
pxoptical = MwLoadImage(window, ICON128DIR "/optical.png");
|
||||
pxoptical = MwLoadImage(window, ICON16DIR "/optical.png");
|
||||
pxfoldermusic = MwLoadImage(window, ICON16DIR "/folder-music.png");
|
||||
pxartist = MwLoadImage(window, ICON16DIR "/artist.png");
|
||||
pxgenre = MwLoadImage(window, ICON16DIR "/genre.png");
|
||||
|
||||
MwSetVoid(album, MwNpixmap, pxalbum);
|
||||
|
||||
|
|
|
|||
|
|
@ -37,14 +37,14 @@ typedef struct queue {
|
|||
} queue_t;
|
||||
|
||||
/* main.c */
|
||||
extern MwWidget window;
|
||||
extern MwWidget album, info;
|
||||
extern MwWidget window, menu;
|
||||
extern MwWidget album, info, timelabel;
|
||||
extern MwWidget bskipback, bplay, bpause, bstop, bskipfwd, brepeat, bshuffle;
|
||||
extern MwWidget eltime, seekbar, rmtime;
|
||||
extern MwWidget seekbar;
|
||||
extern MwWidget tree, list;
|
||||
extern unsigned char* pxalbumdata;
|
||||
extern MwLLPixmap pxalbum;
|
||||
extern MwLLPixmap pxoptical;
|
||||
extern MwLLPixmap pxalbum, pxrepeat, pxrepeatsong;
|
||||
extern MwLLPixmap pxoptical, pxfoldermusic, pxartist, pxgenre;
|
||||
|
||||
/* db.c */
|
||||
extern numkv_t* db_musics;
|
||||
|
|
@ -52,10 +52,11 @@ extern numkv_t* db_albums;
|
|||
extern numkv_t* db_artists;
|
||||
extern numkv_t* db_genres;
|
||||
|
||||
int db_exec(const char* s);
|
||||
int db_init(void);
|
||||
void db_add(const char* path);
|
||||
void db_scan(void);
|
||||
int db_exec(const char* s);
|
||||
int db_init(void);
|
||||
void db_add(const char* path);
|
||||
void db_scan(void);
|
||||
char** db_find(const char* query, const char* param, const char* additional);
|
||||
|
||||
/* ui.c */
|
||||
extern void* ui_last;
|
||||
|
|
@ -74,6 +75,7 @@ extern pthread_mutex_t audio_mutex;
|
|||
extern queue_t* queue;
|
||||
extern int queue_seek;
|
||||
extern int paused;
|
||||
extern int repeated;
|
||||
|
||||
void audio_init(void);
|
||||
void audio_queue(const char* path);
|
||||
|
|
@ -81,4 +83,7 @@ void audio_queue(const char* path);
|
|||
/* id3.c */
|
||||
unsigned char* id3_findimage(const char* path, size_t* size);
|
||||
|
||||
/* playlist.c */
|
||||
void playlist_add(const char* path);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
44
mauplay/playlist.c
Normal file
44
mauplay/playlist.c
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#include "mauplay.h"
|
||||
|
||||
#include <stb_ds.h>
|
||||
#include <ini.h>
|
||||
|
||||
typedef struct song {
|
||||
int key;
|
||||
char* value;
|
||||
} song_t;
|
||||
|
||||
song_t* songs = NULL;
|
||||
int count = 0;
|
||||
|
||||
static int dumper(void* user, const char* section, const char* key, const char* value) {
|
||||
if(strcmp(section, "playlist") != 0) return 1;
|
||||
if(strcmp(key, "NumberOfEntries") == 0) {
|
||||
count = atoi(value);
|
||||
}
|
||||
if(strlen(key) > 4 && memcmp(key, "File", 4) == 0) {
|
||||
song_t s;
|
||||
s.key = atoi(key + 4);
|
||||
s.value = MDEStringDuplicate(value);
|
||||
hmputs(songs, s);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void playlist_add(const char* path) {
|
||||
int i;
|
||||
ini_parse(path, dumper, NULL);
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
int ind = hmgeti(songs, i + 1);
|
||||
if(ind == -1) continue;
|
||||
|
||||
db_add(songs[ind].value);
|
||||
}
|
||||
for(i = 0; i < hmlen(songs); i++) {
|
||||
free(songs[i].value);
|
||||
}
|
||||
hmfree(songs);
|
||||
db_scan();
|
||||
}
|
||||
36
mauplay/repeatsong.xpm
Normal file
36
mauplay/repeatsong.xpm
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* XPM */
|
||||
static char *repeatsong_xpm[] = {
|
||||
/* columns rows colors chars-per-pixel */
|
||||
"28 28 2 1 ",
|
||||
" c None",
|
||||
". c black",
|
||||
/* pixels */
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" .......... ",
|
||||
" . . ",
|
||||
" . . . ",
|
||||
" . .. . ",
|
||||
" . . . ",
|
||||
" . . . ",
|
||||
" . . . . ",
|
||||
" . .. . ",
|
||||
" .. ....... ",
|
||||
" .. ",
|
||||
" . ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
};
|
||||
327
mauplay/ui.c
327
mauplay/ui.c
|
|
@ -11,6 +11,10 @@ static void* genres;
|
|||
void* ui_last;
|
||||
static int changed = 0;
|
||||
|
||||
static void* file_add_file;
|
||||
static void* file_add_directory;
|
||||
static void* file_add_playlist;
|
||||
|
||||
void ui_list_reset(const char* merge) {
|
||||
void* p;
|
||||
|
||||
|
|
@ -90,102 +94,109 @@ void ui_set_genres(int v) {
|
|||
MwTreeViewSetLabel(tree, genres, buf);
|
||||
}
|
||||
|
||||
static void tree_activate(MwWidget handle, void* user, void* client) {
|
||||
if(client == play_queue || client == all_music || client == albums || client == artists || client == genres) {
|
||||
void* p = MwListBoxCreatePacket();
|
||||
int i;
|
||||
if(client == play_queue) {
|
||||
pthread_mutex_lock(&audio_mutex);
|
||||
for(i = 0; i < arrlen(queue); i++) {
|
||||
char buf[64];
|
||||
int ind = shgeti(db_musics, queue[i].path);
|
||||
int index = MwListBoxPacketInsert(p, -1);
|
||||
sprintf(buf, "%d", i + 1);
|
||||
static char* current = NULL;
|
||||
static char** current_list = NULL;
|
||||
static void tree_activate(MwWidget handle, void* user, void* client) {
|
||||
if(client == play_queue || client == all_music || client == albums || client == artists || client == genres) {
|
||||
void* p = MwListBoxCreatePacket();
|
||||
int i;
|
||||
if(current != NULL) free(current);
|
||||
current = NULL;
|
||||
if(client == play_queue) {
|
||||
pthread_mutex_lock(&audio_mutex);
|
||||
for(i = 0; i < arrlen(queue); i++) {
|
||||
char buf[64];
|
||||
int ind = shgeti(db_musics, queue[i].path);
|
||||
int index = MwListBoxPacketInsert(p, -1);
|
||||
sprintf(buf, "%d", i + 1);
|
||||
|
||||
MwListBoxPacketSetIcon(p, index, pxoptical);
|
||||
MwListBoxPacketSet(p, index, 0, buf);
|
||||
MwListBoxPacketSet(p, index, 1, db_musics[ind].title);
|
||||
MwListBoxPacketSet(p, index, 2, db_musics[ind].artist);
|
||||
MwListBoxPacketSetIcon(p, index, pxoptical);
|
||||
MwListBoxPacketSet(p, index, 0, buf);
|
||||
MwListBoxPacketSet(p, index, 1, db_musics[ind].title);
|
||||
MwListBoxPacketSet(p, index, 2, db_musics[ind].artist);
|
||||
|
||||
sprintf(buf, "%d:%02d", db_musics[ind].length / 60, db_musics[ind].length % 60);
|
||||
sprintf(buf, "%d:%02d", db_musics[ind].length / 60, db_musics[ind].length % 60);
|
||||
|
||||
MwListBoxPacketSet(p, index, 3, buf);
|
||||
}
|
||||
pthread_mutex_unlock(&audio_mutex);
|
||||
}
|
||||
if(client == all_music) {
|
||||
for(i = 0; i < shlen(db_musics); i++) {
|
||||
char buf[64];
|
||||
int index = MwListBoxPacketInsert(p, -1);
|
||||
sprintf(buf, "%d", i + 1);
|
||||
MwListBoxPacketSet(p, index, 3, buf);
|
||||
}
|
||||
pthread_mutex_unlock(&audio_mutex);
|
||||
}
|
||||
if(client == all_music) {
|
||||
for(i = 0; i < shlen(db_musics); i++) {
|
||||
char buf[64];
|
||||
int index = MwListBoxPacketInsert(p, -1);
|
||||
sprintf(buf, "%d", i + 1);
|
||||
|
||||
MwListBoxPacketSetIcon(p, index, pxoptical);
|
||||
MwListBoxPacketSet(p, index, 0, buf);
|
||||
MwListBoxPacketSet(p, index, 1, db_musics[i].title);
|
||||
MwListBoxPacketSet(p, index, 2, db_musics[i].artist);
|
||||
MwListBoxPacketSetIcon(p, index, pxoptical);
|
||||
MwListBoxPacketSet(p, index, 0, buf);
|
||||
MwListBoxPacketSet(p, index, 1, db_musics[i].title);
|
||||
MwListBoxPacketSet(p, index, 2, db_musics[i].artist);
|
||||
|
||||
sprintf(buf, "%d:%02d", db_musics[i].length / 60, db_musics[i].length % 60);
|
||||
sprintf(buf, "%d:%02d", db_musics[i].length / 60, db_musics[i].length % 60);
|
||||
|
||||
MwListBoxPacketSet(p, index, 3, buf);
|
||||
}
|
||||
}
|
||||
if(client == albums) {
|
||||
for(i = 0; i < shlen(db_albums); i++) {
|
||||
char buf[64];
|
||||
int index = MwListBoxPacketInsert(p, -1);
|
||||
sprintf(buf, "%d", i + 1);
|
||||
MwListBoxPacketSet(p, index, 3, buf);
|
||||
}
|
||||
}
|
||||
if(client == albums) {
|
||||
for(i = 0; i < shlen(db_albums); i++) {
|
||||
char buf[64];
|
||||
int index = MwListBoxPacketInsert(p, -1);
|
||||
sprintf(buf, "%d", i + 1);
|
||||
|
||||
MwListBoxPacketSet(p, index, 0, buf);
|
||||
MwListBoxPacketSet(p, index, 1, db_albums[i].key);
|
||||
MwListBoxPacketSetIcon(p, index, pxfoldermusic);
|
||||
MwListBoxPacketSet(p, index, 0, buf);
|
||||
MwListBoxPacketSet(p, index, 1, db_albums[i].key);
|
||||
|
||||
sprintf(buf, "%d:%02d", db_musics[i].length / 60, db_albums[i].length % 60);
|
||||
sprintf(buf, "%d:%02d", db_albums[i].length / 60, db_albums[i].length % 60);
|
||||
|
||||
MwListBoxPacketSet(p, index, 2, buf);
|
||||
}
|
||||
}
|
||||
if(client == artists) {
|
||||
for(i = 0; i < shlen(db_artists); i++) {
|
||||
char buf[64];
|
||||
int index = MwListBoxPacketInsert(p, -1);
|
||||
sprintf(buf, "%d", i + 1);
|
||||
MwListBoxPacketSet(p, index, 2, buf);
|
||||
}
|
||||
}
|
||||
if(client == artists) {
|
||||
for(i = 0; i < shlen(db_artists); i++) {
|
||||
char buf[64];
|
||||
int index = MwListBoxPacketInsert(p, -1);
|
||||
sprintf(buf, "%d", i + 1);
|
||||
|
||||
MwListBoxPacketSet(p, index, 0, buf);
|
||||
MwListBoxPacketSet(p, index, 1, db_artists[i].key);
|
||||
MwListBoxPacketSetIcon(p, index, pxartist);
|
||||
MwListBoxPacketSet(p, index, 0, buf);
|
||||
MwListBoxPacketSet(p, index, 1, db_artists[i].key);
|
||||
|
||||
sprintf(buf, "%d:%02d", db_artists[i].length / 60, db_artists[i].length % 60);
|
||||
sprintf(buf, "%d:%02d", db_artists[i].length / 60, db_artists[i].length % 60);
|
||||
|
||||
MwListBoxPacketSet(p, index, 2, buf);
|
||||
}
|
||||
}
|
||||
if(client == genres) {
|
||||
for(i = 0; i < shlen(db_genres); i++) {
|
||||
char buf[64];
|
||||
int index = MwListBoxPacketInsert(p, -1);
|
||||
sprintf(buf, "%d", i + 1);
|
||||
MwListBoxPacketSet(p, index, 2, buf);
|
||||
}
|
||||
}
|
||||
if(client == genres) {
|
||||
for(i = 0; i < shlen(db_genres); i++) {
|
||||
char buf[64];
|
||||
int index = MwListBoxPacketInsert(p, -1);
|
||||
sprintf(buf, "%d", i + 1);
|
||||
|
||||
MwListBoxPacketSet(p, index, 0, buf);
|
||||
MwListBoxPacketSet(p, index, 1, db_genres[i].key);
|
||||
MwListBoxPacketSetIcon(p, index, pxgenre);
|
||||
MwListBoxPacketSet(p, index, 0, buf);
|
||||
MwListBoxPacketSet(p, index, 1, db_genres[i].key);
|
||||
|
||||
sprintf(buf, "%d:%02d", db_genres[i].length / 60, db_genres[i].length % 60);
|
||||
sprintf(buf, "%d:%02d", db_genres[i].length / 60, db_genres[i].length % 60);
|
||||
|
||||
MwListBoxPacketSet(p, index, 2, buf);
|
||||
}
|
||||
}
|
||||
MwListBoxPacketSet(p, index, 2, buf);
|
||||
}
|
||||
}
|
||||
|
||||
if(client == albums) {
|
||||
ui_list_reset("Album");
|
||||
} else if(client == artists) {
|
||||
ui_list_reset("Artist");
|
||||
} else if(client == genres) {
|
||||
ui_list_reset("Genre");
|
||||
} else {
|
||||
ui_list_reset(NULL);
|
||||
}
|
||||
MwListBoxInsert(list, -1, p);
|
||||
MwListBoxDestroyPacket(p);
|
||||
if(client == albums) {
|
||||
ui_list_reset("Album");
|
||||
} else if(client == artists) {
|
||||
ui_list_reset("Artist");
|
||||
} else if(client == genres) {
|
||||
ui_list_reset("Genre");
|
||||
} else {
|
||||
ui_list_reset(NULL);
|
||||
}
|
||||
MwListBoxInsert(list, -1, p);
|
||||
MwListBoxDestroyPacket(p);
|
||||
|
||||
ui_last = client;
|
||||
}
|
||||
ui_last = client;
|
||||
}
|
||||
}
|
||||
|
||||
static void list_activate(MwWidget handle, void* user, void* client) {
|
||||
|
|
@ -201,6 +212,70 @@ static void list_activate(MwWidget handle, void* user, void* client) {
|
|||
pthread_mutex_unlock(&audio_mutex);
|
||||
} else if(ui_last == all_music) {
|
||||
audio_queue(db_musics[(*(int*)client) - 1].key);
|
||||
} else if(ui_last == albums || ui_last == artists || ui_last == genres) {
|
||||
numkv_t* kv = NULL;
|
||||
const char* n;
|
||||
if(ui_last == albums) {
|
||||
kv = db_albums;
|
||||
n = "album";
|
||||
}
|
||||
if(ui_last == artists) {
|
||||
kv = db_artists;
|
||||
n = "artist";
|
||||
}
|
||||
if(ui_last == genres) {
|
||||
kv = db_genres;
|
||||
n = "genre";
|
||||
}
|
||||
|
||||
if(current == NULL) {
|
||||
void* p = MwListBoxCreatePacket();
|
||||
int i;
|
||||
int index;
|
||||
|
||||
current = MDEStringDuplicate(kv[(*(int*)client) - 1].key);
|
||||
|
||||
for(i = 0; i < arrlen(current_list); i++) {
|
||||
free(current_list[i]);
|
||||
}
|
||||
arrfree(current_list);
|
||||
|
||||
index = MwListBoxPacketInsert(p, -1);
|
||||
|
||||
MwListBoxPacketSetIcon(p, index, pxfoldermusic);
|
||||
MwListBoxPacketSet(p, index, 0, "");
|
||||
MwListBoxPacketSet(p, index, 1, "..");
|
||||
|
||||
current_list = db_find(n, current, ui_last == albums ? "track" : NULL);
|
||||
for(i = 0; i < arrlen(current_list); i++) {
|
||||
char buf[128];
|
||||
numkv_t kv = shgets(db_musics, current_list[i]);
|
||||
|
||||
index = MwListBoxPacketInsert(p, -1);
|
||||
|
||||
sprintf(buf, "%d", i + 1);
|
||||
|
||||
MwListBoxPacketSetIcon(p, index, pxoptical);
|
||||
MwListBoxPacketSet(p, index, 0, buf);
|
||||
MwListBoxPacketSet(p, index, 1, kv.title);
|
||||
MwListBoxPacketSet(p, index, 2, kv.artist);
|
||||
|
||||
sprintf(buf, "%d:%02d", kv.length / 60, kv.length % 60);
|
||||
|
||||
MwListBoxPacketSet(p, index, 3, buf);
|
||||
}
|
||||
|
||||
ui_list_reset(NULL);
|
||||
MwListBoxInsert(handle, -1, p);
|
||||
MwListBoxDestroyPacket(p);
|
||||
} else {
|
||||
int index = *(int*)client;
|
||||
if(index == 1) {
|
||||
MwDispatchUserHandler(tree, MwNactivateHandler, ui_last);
|
||||
} else {
|
||||
audio_queue(current_list[index - 2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -271,16 +346,11 @@ static void window_tick(MwWidget handle, void* user, void* client) {
|
|||
}
|
||||
if(arrlen(queue) > 0 && queue_seek != -1) {
|
||||
int elsec = queue[queue_seek].frames / queue[queue_seek].sound->context->sample_rate;
|
||||
int rmsec = (queue[queue_seek].sound->context->frames / queue[queue_seek].sound->context->sample_rate) - elsec;
|
||||
int ttsec = queue[queue_seek].sound->context->frames / queue[queue_seek].sound->context->sample_rate;
|
||||
char buf[64];
|
||||
|
||||
sprintf(buf, "%d:%02d", elsec / 60, elsec % 60);
|
||||
MwVaApply(eltime,
|
||||
MwNtext, buf,
|
||||
NULL);
|
||||
|
||||
sprintf(buf, "%d:%02d", rmsec / 60, rmsec % 60);
|
||||
MwVaApply(rmtime,
|
||||
sprintf(buf, "%d:%02d | %d:%02d", elsec / 60, elsec % 60, ttsec / 60, ttsec % 60);
|
||||
MwVaApply(timelabel,
|
||||
MwNtext, buf,
|
||||
NULL);
|
||||
|
||||
|
|
@ -293,12 +363,12 @@ static void window_tick(MwWidget handle, void* user, void* client) {
|
|||
NULL);
|
||||
}
|
||||
} else {
|
||||
MwVaApply(eltime,
|
||||
MwNtext, "0:00",
|
||||
NULL);
|
||||
MwVaApply(rmtime,
|
||||
MwNtext, "0:00",
|
||||
MwVaApply(timelabel,
|
||||
MwNtext, "",
|
||||
NULL);
|
||||
memset(((MwLLCommonPixmap)pxalbum)->raw, 0, ALBUMWIDTH * ALBUMWIDTH * 4);
|
||||
MwLLPixmapUpdate(pxalbum);
|
||||
MwForceRender(album);
|
||||
}
|
||||
queue_last = queue_seek;
|
||||
pthread_mutex_unlock(&audio_mutex);
|
||||
|
|
@ -362,7 +432,71 @@ static void bskipfwd_activate(MwWidget handle, void* user, void* client) {
|
|||
pthread_mutex_unlock(&audio_mutex);
|
||||
}
|
||||
|
||||
static void brepeat_activate(MwWidget handle, void* user, void* client) {
|
||||
pthread_mutex_lock(&audio_mutex);
|
||||
repeated = repeated ? 0 : 1;
|
||||
MwVaApply(brepeat,
|
||||
MwNpixmap, repeated ? pxrepeatsong : pxrepeat,
|
||||
NULL);
|
||||
pthread_mutex_unlock(&audio_mutex);
|
||||
}
|
||||
|
||||
static void file_fc_chosen(MwWidget handle, void* user, void* client) {
|
||||
db_add(client);
|
||||
db_scan();
|
||||
}
|
||||
|
||||
static void playlist_fc_chosen(MwWidget handle, void* user, void* client) {
|
||||
playlist_add(client);
|
||||
}
|
||||
|
||||
static void menu_menu(MwWidget handle, void* user, void* client) {
|
||||
if(client == file_add_file) {
|
||||
MwWidget fc = MwFileChooser(window, "Choose a file to add");
|
||||
MwAddUserHandler(fc, MwNfileChosenHandler, file_fc_chosen, NULL);
|
||||
} else if(client == file_add_playlist) {
|
||||
MwWidget fc = MwFileChooser(window, "Choose a playlist to add");
|
||||
MwAddUserHandler(fc, MwNfileChosenHandler, playlist_fc_chosen, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void list_mouseup(MwWidget handle, void* user, void* client) {
|
||||
MwLLMouse* m = client;
|
||||
int s;
|
||||
if(ui_last != play_queue) return;
|
||||
if(m->button != MwLLMouseRight) return;
|
||||
if((s = MwGetInteger(list, MwNvalue)) == -1) return;
|
||||
|
||||
pthread_mutex_lock(&audio_mutex);
|
||||
MwListBoxDelete(list, s);
|
||||
arrdel(queue, s - 1);
|
||||
ui_set_play_queue(arrlen(queue));
|
||||
|
||||
if(queue_last == (s - 1)) {
|
||||
queue_last = -1;
|
||||
} else if(queue_last > (s - 1)) {
|
||||
queue_last--;
|
||||
queue_seek--;
|
||||
}
|
||||
if(arrlen(queue) <= queue_seek) {
|
||||
queue_seek = arrlen(queue) - 1;
|
||||
}
|
||||
pthread_mutex_unlock(&audio_mutex);
|
||||
}
|
||||
|
||||
void ui_init(void) {
|
||||
MwMenu m;
|
||||
int i;
|
||||
MwWidget* l;
|
||||
|
||||
m = MwMenuAdd(menu, NULL, "File");
|
||||
file_add_file = MwMenuAdd(menu, m, "Add File");
|
||||
file_add_directory = MwMenuAdd(menu, m, "Add Directory");
|
||||
file_add_playlist = MwMenuAdd(menu, m, "Add Playlist");
|
||||
|
||||
m = MwMenuAdd(menu, NULL, "?Help");
|
||||
MwMenuAdd(menu, m, "About");
|
||||
|
||||
ui_list_reset(NULL);
|
||||
ui_tree_reset();
|
||||
|
||||
|
|
@ -372,7 +506,14 @@ void ui_init(void) {
|
|||
ui_set_artists(0);
|
||||
ui_set_genres(0);
|
||||
|
||||
MwAddUserHandler(menu, MwNmenuHandler, menu_menu, NULL);
|
||||
|
||||
ui_last = all_music;
|
||||
l = MwGetChildren(list);
|
||||
for(i = 0; l[i] != NULL; i++) {
|
||||
if(MwGetClass(l[i]) == MwFrameClass) MwAddUserHandler(l[i], MwNmouseUpHandler, list_mouseup, NULL);
|
||||
}
|
||||
free(l);
|
||||
MwAddUserHandler(list, MwNactivateHandler, list_activate, NULL);
|
||||
MwAddUserHandler(tree, MwNactivateHandler, tree_activate, NULL);
|
||||
MwAddUserHandler(window, MwNtickHandler, window_tick, NULL);
|
||||
|
|
@ -383,4 +524,6 @@ void ui_init(void) {
|
|||
MwAddUserHandler(bpause, MwNactivateHandler, bpause_activate, NULL);
|
||||
MwAddUserHandler(bstop, MwNactivateHandler, bstop_activate, NULL);
|
||||
MwAddUserHandler(bskipfwd, MwNactivateHandler, bskipfwd_activate, NULL);
|
||||
|
||||
MwAddUserHandler(brepeat, MwNactivateHandler, brepeat_activate, NULL);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue