diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 27 | ||||
| -rw-r--r-- | src/settings.c | 25 | ||||
| -rw-r--r-- | src/settings.h | 3 | ||||
| -rw-r--r-- | src/ui_act.c | 258 | ||||
| -rw-r--r-- | src/ui_act.h | 7 | ||||
| -rw-r--r-- | src/ui_dispatch.c | 71 | ||||
| -rw-r--r-- | src/ui_dispatch.h | 105 | 
7 files changed, 293 insertions, 203 deletions
| @@ -50,11 +50,9 @@ THE SOFTWARE.  #include "terminal.h"  #include "config.h"  #include "ui.h" -#include "ui_act.h" +#include "ui_dispatch.h"  #include "ui_readline.h" -typedef void (*BarKeyShortcutFunc_t) (BarApp_t *app); -  /*	copy proxy settings to waitress handle   */  static void BarMainLoadProxy (const BarSettings_t *settings, @@ -154,26 +152,9 @@ static void BarMainHandleUserInput (BarApp_t *app) {  	char buf[2];  	if (BarReadline (buf, sizeof (buf), NULL, &app->input,  			BAR_RL_FULLRETURN | BAR_RL_NOECHO, 1) > 0) { -		for (size_t i = 0; i < BAR_KS_COUNT; i++) { -			if (app->settings.keys[i] != BAR_KS_DISABLED && -					app->settings.keys[i] == buf[0]) { -				static const BarKeyShortcutFunc_t idToF[] = {BarUiActHelp, -						BarUiActLoveSong, BarUiActBanSong, -						BarUiActAddMusic, BarUiActCreateStation, -						BarUiActDeleteStation, BarUiActExplain, -						BarUiActStationFromGenre, BarUiActHistory, -						BarUiActSongInfo, BarUiActAddSharedStation, -						BarUiActMoveSong, BarUiActSkipSong, BarUiActPause, -						BarUiActQuit, BarUiActRenameStation, -						BarUiActSelectStation, BarUiActTempBanSong, -						BarUiActPrintUpcoming, BarUiActSelectQuickMix, -						BarUiActDebug, BarUiActBookmark, BarUiActVolDown, -						BarUiActVolUp}; -				idToF[i] (app); -				break; -			} -		} /* end for */ -	} /* end if */ +		BarUiDispatch (app, buf[0], app->curStation, app->playlist, true, +				BAR_DC_GLOBAL); +	}  }  /*	append current song to history list and move to the next song diff --git a/src/settings.c b/src/settings.c index a7a26a6..dddc05c 100644 --- a/src/settings.c +++ b/src/settings.c @@ -30,9 +30,11 @@ THE SOFTWARE.  #include <stdlib.h>  #include <stdio.h>  #include <limits.h> +#include <assert.h>  #include "settings.h"  #include "config.h" +#include "ui_dispatch.h"  #define streq(a, b) (strcmp (a, b) == 0) @@ -93,20 +95,9 @@ void BarSettingsDestroy (BarSettings_t *settings) {  void BarSettingsRead (BarSettings_t *settings) {  	char configfile[PATH_MAX], key[256], val[256];  	FILE *configfd; -	/* _must_ have same order as in BarKeyShortcutId_t */ -	static const char defaultKeys[] = {'?', '+', '-', 'a', 'c', 'd', 'e', 'g', -			'h', 'i', 'j', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'x', '$', -			'b', '(', ')', -			}; -	static const char *shortcutFileKeys[] = { -			"act_help", "act_songlove", "act_songban", "act_stationaddmusic", -			"act_stationcreate", "act_stationdelete", "act_songexplain", -			"act_stationaddbygenre", "act_history", "act_songinfo", -			"act_addshared", "act_songmove", "act_songnext", "act_songpause", -			"act_quit", "act_stationrename", "act_stationchange", -			"act_songtired", "act_upcoming", "act_stationselectquickmix", -			"act_debug", "act_bookmark", "act_voldown", "act_volup", -			}; + +	assert (sizeof (settings->keys) / sizeof (*settings->keys) == +			sizeof (dispatchActions) / sizeof (*dispatchActions));  	/* apply defaults */  	#ifdef ENABLE_FAAD @@ -119,9 +110,11 @@ void BarSettingsRead (BarSettings_t *settings) {  	settings->history = 5;  	settings->volume = 0;  	settings->sortOrder = BAR_SORT_NAME_AZ; -	memcpy (settings->keys, defaultKeys, sizeof (defaultKeys));  	settings->loveIcon = strdup ("<3");  	settings->banIcon = strdup ("</3"); +	for (size_t i = 0; i < BAR_KS_COUNT; i++) { +		settings->keys[i] = dispatchActions[i].defaultKey; +	}  	BarGetXdgConfigDir (PACKAGE "/config", configfile, sizeof (configfile));  	if ((configfd = fopen (configfile, "r")) == NULL) { @@ -149,7 +142,7 @@ void BarSettingsRead (BarSettings_t *settings) {  			size_t i;  			/* keyboard shortcuts */  			for (i = 0; i < BAR_KS_COUNT; i++) { -				if (streq (shortcutFileKeys[i], key)) { +				if (streq (dispatchActions[i].configKey, key)) {  					if (streq (val, "disabled")) {  						settings->keys[i] = BAR_KS_DISABLED;  					} else { diff --git a/src/settings.h b/src/settings.h index f529a81..58ff3d1 100644 --- a/src/settings.h +++ b/src/settings.h @@ -27,8 +27,7 @@ THE SOFTWARE.  #include <piano.h>  #include <waitress.h> -/* keep in mind that you have to update several arrays in main.c/ui_act.c too, - * if you're adding new shortcuts */ +/* update structure in ui_dispatch.h if you add shortcuts here */  typedef enum {  	BAR_KS_HELP = 0,  	BAR_KS_LOVE = 1, diff --git a/src/ui_act.c b/src/ui_act.c index f8c9879..a57cb01 100644 --- a/src/ui_act.c +++ b/src/ui_act.c @@ -26,18 +26,11 @@ THE SOFTWARE.  #include <string.h>  #include <unistd.h>  #include <pthread.h> +#include <assert.h>  #include "ui.h" -#include "ui_act.h"  #include "ui_readline.h" - -#define RETURN_IF_NO_STATION if (app->curStation == NULL) { \ -		BarUiMsg (MSG_ERR, "No station selected.\n"); \ -		return; } - -#define RETURN_IF_NO_SONG if (app->curStation == NULL || app->playlist == NULL) { \ -		BarUiMsg (MSG_ERR, "No song playing.\n"); \ -		return; } +#include "ui_dispatch.h"  /*	standard eventcmd call   */ @@ -54,6 +47,8 @@ THE SOFTWARE.   *	@param player handle   */  static inline void BarUiDoSkipSong (struct audioPlayer *player) { +	assert (player != NULL); +  	player->doQuit = 1;  	pthread_mutex_unlock (&player->pauseMutex);  } @@ -67,6 +62,8 @@ static int BarTransformIfShared (BarApp_t *app, PianoStation_t *station) {  	PianoReturn_t pRet;  	WaitressReturn_t wRet; +	assert (station != NULL); +  	/* shared stations must be transformed */  	if (!station->isCreator) {  		BarUiMsg (MSG_INFO, "Transforming station... "); @@ -81,38 +78,13 @@ static int BarTransformIfShared (BarApp_t *app, PianoStation_t *station) {  /*	print current shortcut configuration   */  BarUiActCallback(BarUiActHelp) { -	static const char *idToDesc[] = { -			NULL, -			"love current song", -			"ban current song", -			"add music to current station", -			"create new station", -			"delete current station", -			"explain why this song is played", -			"add genre station", -			"song history", -			"print information about current song/station", -			"add shared station", -			"move song to different station", -			"next song", -			"pause/continue", -			"quit", -			"rename current station", -			"change station", -			"tired (ban song for 1 month)", -			"upcoming songs", -			"select quickmix stations", -			NULL, -			"bookmark song/artist", -			"decrease volume", -			"increase volume", -			}; -	size_t i; -  	BarUiMsg (MSG_NONE, "\r"); -	for (i = 0; i < BAR_KS_COUNT; i++) { -		if (idToDesc[i] != NULL && app->settings.keys[i] != BAR_KS_DISABLED) { -			BarUiMsg (MSG_LIST, "%c    %s\n", app->settings.keys[i], idToDesc[i]); +	for (size_t i = 0; i < BAR_KS_COUNT; i++) { +		if (dispatchActions[i].helpText != NULL && +				(context & dispatchActions[i].context) == dispatchActions[i].context && +				app->settings.keys[i] != BAR_KS_DISABLED) { +			BarUiMsg (MSG_LIST, "%c    %s\n", app->settings.keys[i], +					dispatchActions[i].helpText);  		}  	}  } @@ -124,14 +96,14 @@ BarUiActCallback(BarUiActAddMusic) {  	WaitressReturn_t wRet;  	PianoRequestDataAddSeed_t reqData; -	RETURN_IF_NO_STATION; +	assert (selStation != NULL);  	reqData.musicId = BarUiSelectMusicId (app, app->playlist->musicId);  	if (reqData.musicId != NULL) { -		if (!BarTransformIfShared (app, app->curStation)) { +		if (!BarTransformIfShared (app, selStation)) {  			return;  		} -		reqData.station = app->curStation; +		reqData.station = selStation;  		BarUiMsg (MSG_INFO, "Adding music to station... ");  		BarUiActDefaultPianoCall (PIANO_REQUEST_ADD_SEED, &reqData); @@ -148,18 +120,20 @@ BarUiActCallback(BarUiActBanSong) {  	PianoReturn_t pRet;  	WaitressReturn_t wRet; -	RETURN_IF_NO_SONG; +	assert (selStation != NULL); +	assert (selSong != NULL); -	if (!BarTransformIfShared (app, app->curStation)) { +	if (!BarTransformIfShared (app, selStation)) {  		return;  	}  	PianoRequestDataRateSong_t reqData; -	reqData.song = app->playlist; +	reqData.song = selSong;  	reqData.rating = PIANO_RATE_BAN;  	BarUiMsg (MSG_INFO, "Banning song... "); -	if (BarUiActDefaultPianoCall (PIANO_REQUEST_RATE_SONG, &reqData)) { +	if (BarUiActDefaultPianoCall (PIANO_REQUEST_RATE_SONG, &reqData) && +			selSong == app->playlist) {  		BarUiDoSkipSong (&app->player);  	}  	BarUiActDefaultEventcmd ("songban"); @@ -207,14 +181,14 @@ BarUiActCallback(BarUiActDeleteStation) {  	PianoReturn_t pRet;  	WaitressReturn_t wRet; -	RETURN_IF_NO_STATION; +	assert (selStation != NULL);  	BarUiMsg (MSG_QUESTION, "Really delete \"%s\"? [yN] ",  			app->curStation->name);  	if (BarReadlineYesNo (false, &app->input)) {  		BarUiMsg (MSG_INFO, "Deleting station... ");  		if (BarUiActDefaultPianoCall (PIANO_REQUEST_DELETE_STATION, -				app->curStation)) { +				selStation) && selStation == app->curStation) {  			BarUiDoSkipSong (&app->player);  			PianoDestroyPlaylist (app->playlist);  			app->playlist = NULL; @@ -231,9 +205,9 @@ BarUiActCallback(BarUiActExplain) {  	WaitressReturn_t wRet;  	PianoRequestDataExplain_t reqData; -	RETURN_IF_NO_STATION; +	assert (selSong != NULL); -	reqData.song = app->playlist; +	reqData.song = selSong;  	BarUiMsg (MSG_INFO, "Receiving explanation... ");  	if (BarUiActDefaultPianoCall (PIANO_REQUEST_EXPLAIN, &reqData)) { @@ -253,20 +227,21 @@ BarUiActCallback(BarUiActStationFromGenre) {  /*	print verbose song information   */  BarUiActCallback(BarUiActSongInfo) { -	RETURN_IF_NO_SONG; +	assert (selStation != NULL); +	assert (selSong != NULL); -	BarUiPrintStation (app->curStation); +	BarUiPrintStation (selStation);  	/* print real station if quickmix */ -	BarUiPrintSong (&app->settings, app->playlist, -			app->curStation->isQuickMix ? -			PianoFindStationById (app->ph.stations, app->playlist->stationId) : +	BarUiPrintSong (&app->settings, selSong, +			selStation->isQuickMix ? +			PianoFindStationById (app->ph.stations, selSong->stationId) :  			NULL);  }  /*	print some debugging information   */  BarUiActCallback(BarUiActDebug) { -	RETURN_IF_NO_SONG; +	assert (selSong != NULL);  	/* print debug-alike infos */  	BarUiMsg (MSG_NONE, @@ -283,15 +258,19 @@ BarUiActCallback(BarUiActDebug) {  			"testStrategy:\t%i\n"  			"title:\t%s\n"  			"userSeed:\t%s\n", -			app->playlist->album, app->playlist->artist, -			app->playlist->audioFormat, -			app->playlist->audioUrl, -			app->playlist->coverArt, -			app->playlist->fileGain, -			app->playlist->musicId, app->playlist->rating, -			app->playlist->songType, app->playlist->stationId, -			app->playlist->testStrategy, app->playlist->title, -			app->playlist->userSeed); +			selSong->album, +			selSong->artist, +			selSong->audioFormat, +			selSong->audioUrl, +			selSong->coverArt, +			selSong->fileGain, +			selSong->musicId, +			selSong->rating, +			selSong->songType, +			selSong->stationId, +			selSong->testStrategy, +			selSong->title, +			selSong->userSeed);  }  /*	rate current song @@ -300,14 +279,15 @@ BarUiActCallback(BarUiActLoveSong) {  	PianoReturn_t pRet;  	WaitressReturn_t wRet; -	RETURN_IF_NO_SONG; +	assert (selStation != NULL); +	assert (selSong != NULL); -	if (!BarTransformIfShared (app, app->curStation)) { +	if (!BarTransformIfShared (app, selStation)) {  		return;  	}  	PianoRequestDataRateSong_t reqData; -	reqData.song = app->playlist; +	reqData.song = selSong;  	reqData.rating = PIANO_RATE_LOVE;  	BarUiMsg (MSG_INFO, "Loving song... "); @@ -328,9 +308,9 @@ BarUiActCallback(BarUiActMoveSong) {  	WaitressReturn_t wRet;  	PianoRequestDataMoveSong_t reqData; -	reqData.step = 0; +	assert (selSong != NULL); -	RETURN_IF_NO_SONG; +	reqData.step = 0;  	reqData.to = BarUiSelectStation (&app->ph, "Move song to station: ",  			app->settings.sortOrder, &app->input); @@ -338,7 +318,7 @@ BarUiActCallback(BarUiActMoveSong) {  		/* find original station (just is case we're playing a quickmix  		 * station) */  		reqData.from = PianoFindStationById (app->ph.stations, -				app->playlist->stationId); +				selSong->stationId);  		if (reqData.from == NULL) {  			BarUiMsg (MSG_ERR, "Station not found\n");  			return; @@ -349,8 +329,9 @@ BarUiActCallback(BarUiActMoveSong) {  			return;  		}  		BarUiMsg (MSG_INFO, "Moving song to \"%s\"... ", reqData.to->name); -		reqData.song = app->playlist; -		if (BarUiActDefaultPianoCall (PIANO_REQUEST_MOVE_SONG, &reqData)) { +		reqData.song = selSong; +		if (BarUiActDefaultPianoCall (PIANO_REQUEST_MOVE_SONG, &reqData) && +				selSong == app->playlist) {  			BarUiDoSkipSong (&app->player);  		}  		BarUiActDefaultEventcmd ("songmove"); @@ -373,16 +354,16 @@ BarUiActCallback(BarUiActRenameStation) {  	WaitressReturn_t wRet;  	char lineBuf[100]; -	RETURN_IF_NO_STATION; +	assert (selStation != NULL);  	BarUiMsg (MSG_QUESTION, "New name: ");  	if (BarReadlineStr (lineBuf, sizeof (lineBuf), &app->input, BAR_RL_DEFAULT) > 0) {  		PianoRequestDataRenameStation_t reqData; -		if (!BarTransformIfShared (app, app->curStation)) { +		if (!BarTransformIfShared (app, selStation)) {  			return;  		} -		reqData.station = app->curStation; +		reqData.station = selStation;  		reqData.newName = lineBuf;  		BarUiMsg (MSG_INFO, "Renaming station... "); @@ -411,10 +392,11 @@ BarUiActCallback(BarUiActTempBanSong) {  	PianoReturn_t pRet;  	WaitressReturn_t wRet; -	RETURN_IF_NO_SONG; +	assert (selSong != NULL);  	BarUiMsg (MSG_INFO, "Putting song on shelf... "); -	if (BarUiActDefaultPianoCall (PIANO_REQUEST_ADD_TIRED_SONG, app->playlist)) { +	if (BarUiActDefaultPianoCall (PIANO_REQUEST_ADD_TIRED_SONG, selSong) && +			selSong == app->playlist) {  		BarUiDoSkipSong (&app->player);  	}  	BarUiActDefaultEventcmd ("songshelf"); @@ -423,9 +405,9 @@ BarUiActCallback(BarUiActTempBanSong) {  /*	print upcoming songs   */  BarUiActCallback(BarUiActPrintUpcoming) { -	RETURN_IF_NO_SONG; +	assert (selSong != NULL); -	PianoSong_t *nextSong = app->playlist->next; +	PianoSong_t *nextSong = selSong->next;  	if (nextSong != NULL) {  		BarUiListSongs (&app->settings, nextSong);  	} else { @@ -440,14 +422,14 @@ BarUiActCallback(BarUiActSelectQuickMix) {  	PianoReturn_t pRet;  	WaitressReturn_t wRet; -	RETURN_IF_NO_STATION; +	assert (selStation != NULL); -	if (app->curStation->isQuickMix) { -		PianoStation_t *selStation; -		while ((selStation = BarUiSelectStation (&app->ph, +	if (selStation->isQuickMix) { +		PianoStation_t *toggleStation; +		while ((toggleStation = BarUiSelectStation (&app->ph,  				"Toggle quickmix for station: ", app->settings.sortOrder,  				&app->input)) != NULL) { -			selStation->useQuickMix = !selStation->useQuickMix; +			toggleStation->useQuickMix = !toggleStation->useQuickMix;  		}  		BarUiMsg (MSG_INFO, "Setting quickmix stations... ");  		BarUiActDefaultPianoCall (PIANO_REQUEST_SET_QUICKMIX, NULL); @@ -467,81 +449,36 @@ BarUiActCallback(BarUiActQuit) {  /*	song history   */  BarUiActCallback(BarUiActHistory) { -	PianoReturn_t pRet; -	WaitressReturn_t wRet; -	char selectBuf[2], allowedBuf[4]; -	PianoSong_t *selectedSong; +	char buf[2]; +	PianoSong_t *histSong;  	if (app->songHistory != NULL) { -		selectedSong = BarUiSelectSong (&app->settings, app->songHistory, +		histSong = BarUiSelectSong (&app->settings, app->songHistory,  				&app->input); -		if (selectedSong != NULL) { -			/* use user-defined keybindings */ -			allowedBuf[0] = app->settings.keys[BAR_KS_LOVE]; -			allowedBuf[1] = app->settings.keys[BAR_KS_BAN]; -			allowedBuf[2] = app->settings.keys[BAR_KS_TIRED]; -			allowedBuf[3] = '\0'; - -			BarUiMsg (MSG_QUESTION, "%s - %s: love[%c], ban[%c] or tired[%c]? ", -					selectedSong->artist, selectedSong->title, -					app->settings.keys[BAR_KS_LOVE], -					app->settings.keys[BAR_KS_BAN], -					app->settings.keys[BAR_KS_TIRED]); -			BarReadline (selectBuf, sizeof (selectBuf), allowedBuf, -					&app->input, BAR_RL_FULLRETURN, -1); - -			if (selectBuf[0] == app->settings.keys[BAR_KS_LOVE] || -					selectBuf[0] == app->settings.keys[BAR_KS_BAN] || -					selectBuf[0] == app->settings.keys[BAR_KS_TIRED]) { -				/* make sure we're transforming the _original_ station (not -				 * curStation) */ -				PianoStation_t *songStation = -						PianoFindStationById (app->ph.stations, -								selectedSong->stationId); - -				if (songStation == NULL) { -					BarUiMsg (MSG_ERR, "Station does not exist any more.\n"); -					return; +		if (histSong != NULL) { +			BarKeyShortcutId_t action; +			PianoStation_t *songStation = PianoFindStationById (app->ph.stations, +					histSong->stationId); + +			if (songStation == NULL) { +				BarUiMsg (MSG_ERR, "Station does not exist any more.\n"); +				return; +			} + +			do { +				action = BAR_KS_COUNT; + +				BarUiMsg (MSG_QUESTION, "What to do with this song? "); + +				if (BarReadline (buf, sizeof (buf), NULL, &app->input, +						BAR_RL_FULLRETURN, -1) > 0) { +					/* actions assume that selStation is the song's original +					 * station */ +					action = BarUiDispatch (app, buf[0], songStation, histSong, +							false, BAR_DC_UNDEFINED);  				} - -				if (!BarTransformIfShared (app, songStation)) { -					return; -				} - -				if (selectBuf[0] == app->settings.keys[BAR_KS_LOVE]) { -					/* FIXME: copy&waste */ -					PianoRequestDataRateSong_t reqData; -					reqData.song = selectedSong; -					reqData.rating = PIANO_RATE_LOVE; - -					BarUiMsg (MSG_INFO, "Loving song... "); -					BarUiActDefaultPianoCall (PIANO_REQUEST_RATE_SONG, -							&reqData); - -					BarUiStartEventCmd (&app->settings, "songlove", songStation, -							selectedSong, &app->player, app->ph.stations, -							pRet, wRet); -				} else if (selectBuf[0] == app->settings.keys[BAR_KS_BAN]) { -					PianoRequestDataRateSong_t reqData; -					reqData.song = selectedSong; -					reqData.rating = PIANO_RATE_BAN; - -					BarUiMsg (MSG_INFO, "Banning song... "); -					BarUiActDefaultPianoCall (PIANO_REQUEST_RATE_SONG, -							&reqData); -					BarUiStartEventCmd (&app->settings, "songban", songStation, -							selectedSong, &app->player, app->ph.stations, -							pRet, wRet); -				} else if (selectBuf[0] == app->settings.keys[BAR_KS_TIRED]) { -					BarUiMsg (MSG_INFO, "Putting song on shelf... "); -					BarUiActDefaultPianoCall (PIANO_REQUEST_ADD_TIRED_SONG, selectedSong); - -					BarUiStartEventCmd (&app->settings, "songshelf", songStation, -							selectedSong, &app->player, app->ph.stations, -							pRet, wRet); -				} /* end if */ -			} /* end if selectBuf[0] */ -		} /* end if selectedSong != NULL */ +			} while (action == BAR_KS_HELP); +		} /* end if histSong != NULL */  	} else {  		BarUiMsg (MSG_INFO, (app->settings.history == 0) ? "History disabled.\n" :  				"No history yet.\n"); @@ -555,19 +492,18 @@ BarUiActCallback(BarUiActBookmark) {  	WaitressReturn_t wRet;  	char selectBuf[2]; -	RETURN_IF_NO_SONG; +	assert (selSong != NULL);  	BarUiMsg (MSG_QUESTION, "Bookmark [s]ong or [a]rtist? ");  	BarReadline (selectBuf, sizeof (selectBuf), "sa", &app->input,  			BAR_RL_FULLRETURN, -1);  	if (selectBuf[0] == 's') {  		BarUiMsg (MSG_INFO, "Bookmarking song... "); -		BarUiActDefaultPianoCall (PIANO_REQUEST_BOOKMARK_SONG, app->playlist); +		BarUiActDefaultPianoCall (PIANO_REQUEST_BOOKMARK_SONG, selSong);  		BarUiActDefaultEventcmd ("songbookmark");  	} else if (selectBuf[0] == 'a') {  		BarUiMsg (MSG_INFO, "Bookmarking artist... "); -		BarUiActDefaultPianoCall (PIANO_REQUEST_BOOKMARK_ARTIST, -				app->playlist); +		BarUiActDefaultPianoCall (PIANO_REQUEST_BOOKMARK_ARTIST, selSong);  		BarUiActDefaultEventcmd ("artistbookmark");  	}  } diff --git a/src/ui_act.h b/src/ui_act.h index b1dce62..ca67c63 100644 --- a/src/ui_act.h +++ b/src/ui_act.h @@ -24,9 +24,14 @@ THE SOFTWARE.  #ifndef _UI_ACT_H  #define _UI_ACT_H +#include <piano.h> +  #include "main.h" +#include "ui_dispatch.h" -#define BarUiActCallback(name) void name (BarApp_t *app) +#define BarUiActCallback(name) void name (BarApp_t *app, \ +		PianoStation_t *selStation, PianoSong_t *selSong, \ +		BarUiDispatchContext_t context)  BarUiActCallback(BarUiActHelp);  BarUiActCallback(BarUiActAddMusic); diff --git a/src/ui_dispatch.c b/src/ui_dispatch.c new file mode 100644 index 0000000..ddcf60c --- /dev/null +++ b/src/ui_dispatch.c @@ -0,0 +1,71 @@ +/* +Copyright (c) 2010-2011 +	Lars-Dominik Braun <lars@6xq.net> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include <assert.h> + +#include "ui_dispatch.h" +#include "settings.h" +#include "ui.h" + +/*	handle global keyboard shortcuts + *	@return BAR_KS_* if action was performed or BAR_KS_COUNT on error/if no + *			action was performed + */ +BarKeyShortcutId_t BarUiDispatch (BarApp_t *app, const char key, PianoStation_t *selStation, +		PianoSong_t *selSong, const bool verbose, +		BarUiDispatchContext_t context) { +	assert (app != NULL); +	assert (sizeof (app->settings.keys) / sizeof (*app->settings.keys) == +			sizeof (dispatchActions) / sizeof (*dispatchActions)); + +	if (selStation != NULL) { +		context |= BAR_DC_STATION; +	} +	if (selSong != NULL) { +		context |= BAR_DC_SONG; +	} + +	for (size_t i = 0; i < BAR_KS_COUNT; i++) { +		if (app->settings.keys[i] != BAR_KS_DISABLED && +				app->settings.keys[i] == key) { +			if ((dispatchActions[i].context & context) == dispatchActions[i].context) { +				assert (dispatchActions[i].function != NULL); + +				dispatchActions[i].function (app, selStation, selSong, +						context); +				return i; +			} else if (verbose) { +				if (dispatchActions[i].context & BAR_DC_SONG) { +					BarUiMsg (MSG_ERR, "No song playing.\n"); +				} else if (dispatchActions[i].context & BAR_DC_STATION) { +					BarUiMsg (MSG_ERR, "No station selected.\n"); +				} else { +					assert (0); +				} +				return BAR_KS_COUNT; +			} +		} +	} +	return BAR_KS_COUNT; +} + diff --git a/src/ui_dispatch.h b/src/ui_dispatch.h new file mode 100644 index 0000000..c5aecc5 --- /dev/null +++ b/src/ui_dispatch.h @@ -0,0 +1,105 @@ +/* +Copyright (c) 2010-2011 +	Lars-Dominik Braun <lars@6xq.net> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef _UI_DISPATCH_H +#define _UI_DISPATCH_H + +/* bit-mask */ +typedef enum { +	BAR_DC_UNDEFINED = 0, +	BAR_DC_GLOBAL = 1, /* top-level action */ +	BAR_DC_STATION = 2, /* station selected */ +	BAR_DC_SONG = 4, /* song selected */ +} BarUiDispatchContext_t; + +#include "settings.h" +#include "main.h" + +typedef void (*BarKeyShortcutFunc_t) (BarApp_t *, PianoStation_t *, +		PianoSong_t *, BarUiDispatchContext_t); + +typedef struct { +	BarUiDispatchContext_t context; +	BarKeyShortcutFunc_t function; +	char *helpText; +	char defaultKey; +	char *configKey; +} BarUiDispatchAction_t; + +#include "ui_act.h" + +/* see settings.h */ +static const BarUiDispatchAction_t dispatchActions[BAR_KS_COUNT] = { +		{BAR_DC_UNDEFINED, BarUiActHelp, NULL, '?', "act_help"}, +		{BAR_DC_SONG, BarUiActLoveSong, "love song", '+', +				"act_songlove"}, +		{BAR_DC_SONG, BarUiActBanSong, "ban song", '-', "act_songban"}, +		{BAR_DC_STATION, BarUiActAddMusic, "add music to station", 'a', +				"act_stationaddmusic"}, +		{BAR_DC_GLOBAL, BarUiActCreateStation, "create new station", 'c', +				"act_stationcreate"}, +		{BAR_DC_STATION, BarUiActDeleteStation, "delete station", 'd', +				"act_stationdelete"}, +		{BAR_DC_SONG, BarUiActExplain, "explain why this song is played", 'e', +				"act_songexplain"}, +		{BAR_DC_GLOBAL, BarUiActStationFromGenre, "add genre station", 'g', +				"act_stationaddbygenre"}, +		{BAR_DC_GLOBAL, BarUiActHistory, "song history", 'h', "act_history"}, +		{BAR_DC_GLOBAL | BAR_DC_STATION | BAR_DC_SONG, BarUiActSongInfo, +				"print information about song/station", 'i', +				"act_songinfo"}, +		{BAR_DC_GLOBAL, BarUiActAddSharedStation, "add shared station", 'j', +				"act_addshared"}, +		{BAR_DC_SONG, BarUiActMoveSong, "move song to different station", 'm', +				"act_songmove"}, +		{BAR_DC_GLOBAL | BAR_DC_STATION, BarUiActSkipSong, "next song", 'n', "act_songnext"}, +		{BAR_DC_GLOBAL | BAR_DC_STATION, BarUiActPause, "pause/continue", 'p', "act_songpause"}, +		{BAR_DC_GLOBAL, BarUiActQuit, "quit", 'q', "act_quit"}, +		{BAR_DC_STATION, BarUiActRenameStation, "rename station", 'r', +				"act_stationrename"}, +		{BAR_DC_GLOBAL, BarUiActSelectStation, "change station", 's', +				"act_stationchange"}, +		{BAR_DC_SONG, BarUiActTempBanSong, "tired (ban song for 1 month)", 't', +				"act_songtired"}, +		{BAR_DC_GLOBAL | BAR_DC_STATION, BarUiActPrintUpcoming, "upcoming songs", 'u', +				"act_upcoming"}, +		{BAR_DC_STATION, BarUiActSelectQuickMix, "select quickmix stations", +				'x', "act_stationselectquickmix"}, +		{BAR_DC_GLOBAL, BarUiActDebug, NULL, '$', "act_debug"}, +		{BAR_DC_SONG, BarUiActBookmark, "bookmark song/artist", 'b', +				"act_bookmark"}, +		{BAR_DC_GLOBAL, BarUiActVolDown, "decrease volume", '(', +				"act_voldown"}, +		{BAR_DC_GLOBAL, BarUiActVolUp, "increase volume", ')', +				"act_volup"}, +		}; + +#include <piano.h> +#include <stdbool.h> +#include <stdio.h> + +BarKeyShortcutId_t BarUiDispatch (BarApp_t *, const char, PianoStation_t *, PianoSong_t *, +		const bool, BarUiDispatchContext_t); + +#endif /* _UI_DISPATCH_H */ + | 
