20e9d56ba5
It changes pluginlib actions to contain only a single and simple context (and other one for remote directional buttons), consisting of 7(9) buttons: up/down/left/right, select OR short select and long select, exit and cancel (plus 2 for scrollwheel targets). This ensures contexts don't clash with other contexts and simplifies them, at the expense of reduced versatility. However, the versatility made it largely unusable due to the great number of targets. This should allow for using pluginlib actions safely for the most simple plugins (e.g. almost all demos). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26202 a1c6a512-1295-4272-9138-f99709370657
180 lines
5.6 KiB
C
180 lines
5.6 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2010 Clément Pit-Claudel
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "plugin.h"
|
|
#include "lib/pluginlib_actions.h"
|
|
|
|
PLUGIN_HEADER
|
|
|
|
const struct button_mapping *plugin_contexts[] = { pla_main_ctx };
|
|
|
|
static int current = 0;
|
|
static bool tomorrow = false;
|
|
static int alarm[2] = {0, 0}, maxval[2] = {24, 60}, prev_tick = 3600 * 24;
|
|
static bool quit = false, usb = false, waiting = false, done = false;
|
|
|
|
static inline int get_button(void) {
|
|
return pluginlib_getaction(HZ/2, plugin_contexts,
|
|
ARRAYLEN(plugin_contexts));
|
|
}
|
|
|
|
int rem_seconds(void) {
|
|
int seconds = (((alarm[0] - rb->get_time()->tm_hour) * 3600)
|
|
+((alarm[1] - rb->get_time()->tm_min) * 60)
|
|
-(rb->get_time()->tm_sec));
|
|
|
|
/* The tomorrow flag means that the alarm should ring on the next day */
|
|
if (seconds > prev_tick) tomorrow = false;
|
|
prev_tick = seconds;
|
|
|
|
return seconds + (tomorrow ? 24 * 3600 : 0);
|
|
}
|
|
|
|
void draw_centered_string(struct screen * display, char * string) {
|
|
int w, h;
|
|
display->getstringsize(string, &w, &h);
|
|
|
|
if (w > display->lcdwidth || h > display->lcdheight) {
|
|
rb->splash(0, string);
|
|
} else {
|
|
display->putsxy((display->lcdwidth - w) / 2,
|
|
(display->lcdheight - h) / 2,
|
|
string);
|
|
display->update();
|
|
}
|
|
}
|
|
|
|
void draw(struct screen * display) {
|
|
char info[128];
|
|
display->clear_display();
|
|
|
|
int secs = rem_seconds();
|
|
|
|
if (waiting)
|
|
rb->snprintf(info, sizeof(info), "Next alarm in %02dh,"
|
|
" %02dmn, and %02ds.",
|
|
secs / 3600, (secs / 60) % 60, secs % 60);
|
|
else {
|
|
if (current == 0)
|
|
rb->snprintf(info, sizeof(info), "Set alarm at [%02d]:%02d.",
|
|
alarm[0],
|
|
alarm[1]);
|
|
else
|
|
rb->snprintf(info, sizeof(info), "Set alarm at %02d:[%02d].",
|
|
alarm[0],
|
|
alarm[1]);
|
|
}
|
|
draw_centered_string(display, info);
|
|
}
|
|
|
|
bool can_play(void) {
|
|
int audio_status = rb->audio_status();
|
|
if ((!audio_status && rb->global_status->resume_index != -1)
|
|
&& (rb->playlist_resume() != -1)) {
|
|
return true;
|
|
}
|
|
else if (audio_status & AUDIO_STATUS_PAUSE)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
void play(void) {
|
|
int audio_status = rb->audio_status();
|
|
if (!audio_status && rb->global_status->resume_index != -1) {
|
|
if (rb->playlist_resume() != -1) {
|
|
rb->playlist_start(rb->global_status->resume_index,
|
|
rb->global_status->resume_offset);
|
|
}
|
|
}
|
|
else if (audio_status & AUDIO_STATUS_PAUSE)
|
|
rb->audio_resume();
|
|
}
|
|
|
|
enum plugin_status plugin_start(const void* parameter)
|
|
{
|
|
int button;
|
|
int i;
|
|
(void)parameter;
|
|
|
|
if (!can_play()) {
|
|
rb->splash(4*HZ, "No track to resume! This plugin will resume a track "
|
|
"at a specific time. Therefore, you need to first play"
|
|
" one, and then pause it and start the plugin again.");
|
|
quit = true;
|
|
}
|
|
|
|
while(!quit) {
|
|
button = get_button();
|
|
|
|
if (button == PLA_EXIT || PLA_CANCEL)
|
|
quit = true;
|
|
|
|
FOR_NB_SCREENS(i) {
|
|
draw(rb->screens[i]);
|
|
}
|
|
if (waiting) {
|
|
if (rem_seconds() <= 0) {
|
|
quit = done = true;
|
|
play();
|
|
}
|
|
}
|
|
else {
|
|
switch (button) {
|
|
case PLA_UP:
|
|
case PLA_UP_REPEAT:
|
|
alarm[current] = (alarm[current] + 1) % maxval[current];
|
|
break;
|
|
|
|
case PLA_DOWN:
|
|
case PLA_DOWN_REPEAT:
|
|
alarm[current] = (alarm[current] + maxval[current] - 1)
|
|
% maxval[current];
|
|
break;
|
|
|
|
case PLA_LEFT:
|
|
case PLA_LEFT_REPEAT:
|
|
case PLA_RIGHT:
|
|
case PLA_RIGHT_REPEAT:
|
|
current = (current + 1) % 2;
|
|
break;
|
|
|
|
case PLA_SELECT:
|
|
case PLA_SELECT_REPEAT: {
|
|
if (rem_seconds() < 0)
|
|
tomorrow = true;
|
|
|
|
waiting = true;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
|
|
quit = usb = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return (usb) ? PLUGIN_USB_CONNECTED
|
|
: (done ? PLUGIN_GOTO_WPS : PLUGIN_OK);
|
|
}
|
|
|