Menu stuff update. Fixed some of the probably many bugs and made things a
bit more consistent.
This commit is contained in:
+5
-1
@@ -20,6 +20,7 @@
|
||||
#include "screenlist.h"
|
||||
#include "render.h"
|
||||
#include "input.h"
|
||||
#include "menuscreens.h"
|
||||
#include "menuitem.h"
|
||||
#include "shared/report.h"
|
||||
#include "shared/LL.h"
|
||||
@@ -89,8 +90,11 @@ client_destroy (Client * c)
|
||||
LL_Destroy( c->screenlist);
|
||||
|
||||
/* Destroy the client's menu, if it exists */
|
||||
if (c->menu)
|
||||
if (c->menu) {
|
||||
menuscreen_inform_item_destruction (c->menu);
|
||||
menu_remove_item (c->menu->parent, c->menu);
|
||||
menuitem_destroy (c->menu);
|
||||
}
|
||||
|
||||
/* Forget client's key reservations */
|
||||
input_release_client_keys (c);
|
||||
|
||||
@@ -157,6 +157,7 @@ menu_add_item_func (Client * c, int argc, char **argv)
|
||||
break;
|
||||
}
|
||||
menu_add_item (menu, item);
|
||||
menuscreen_inform_item_modified (menu);
|
||||
sock_send_string(c->sock, "success\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -181,7 +182,7 @@ menu_del_item_func (Client * c, int argc, char **argv)
|
||||
if (!c->ack)
|
||||
return 1;
|
||||
|
||||
if ((argc < 4 )) {
|
||||
if ((argc < 3 )) {
|
||||
sock_send_string (c->sock, "huh? Usage: menu_del_item <menuid> <itemid>\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -189,6 +190,12 @@ menu_del_item_func (Client * c, int argc, char **argv)
|
||||
menu_id = argv[1];
|
||||
item_id = argv[2];
|
||||
|
||||
/* Does the client have a menu already ? */
|
||||
if (!c->menu) {
|
||||
sock_send_string (c->sock, "huh? Client has no menu\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( menu_id[0] == 0 ) {
|
||||
/* No menu specified = client's main menu */
|
||||
menu = c->menu;
|
||||
@@ -206,9 +213,19 @@ menu_del_item_func (Client * c, int argc, char **argv)
|
||||
sock_send_string (c->sock, "huh? Cannot find item\n");
|
||||
return 0;
|
||||
}
|
||||
menuscreen_inform_item_destruction (item);
|
||||
menu_remove_item (menu, item);
|
||||
menuscreen_inform_item_modified (item->parent);
|
||||
menuitem_destroy (item);
|
||||
|
||||
/* Was it the last item in the client's menu ? */
|
||||
if (menu_getfirst_item(c->menu) == NULL) {
|
||||
menuscreen_inform_item_destruction (c->menu);
|
||||
menu_remove_item (main_menu, c->menu);
|
||||
menuscreen_inform_item_modified (main_menu);
|
||||
menu_destroy (c->menu);
|
||||
c->menu = NULL;
|
||||
}
|
||||
sock_send_string(c->sock, "success\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -580,11 +597,7 @@ menu_set_item_func (Client * c, int argc, char **argv)
|
||||
argnr ++;
|
||||
continue; /* Skip current option and the invalid value */
|
||||
}
|
||||
if( active_menuitem && menuscreen ) {
|
||||
/* We need to rebuild the screen */
|
||||
menuitem_build_screen( active_menuitem, menuscreen );
|
||||
menuitem_update_screen( active_menuitem, menuscreen );
|
||||
}
|
||||
menuscreen_inform_item_modified (item);
|
||||
if( option_table[option_nr].attr_type != NOVALUE ) {
|
||||
/* Skip the now used argument */
|
||||
argnr ++;
|
||||
@@ -645,7 +658,7 @@ MenuEventFunc (menu_commands_handler)
|
||||
buf[sizeof(buf)-1] = 0;
|
||||
|
||||
/* Where should the message go to ? */
|
||||
for( i = item; i && i->parent != main_menu; i = item->parent );
|
||||
for( i = item; i && i->parent != main_menu; i = i->parent );
|
||||
c = (Client *) i->data.menu.association;
|
||||
if( !c ) {
|
||||
report( RPT_ERR, "%s: Could not find client of item \"%s\"", __FUNCTION__, item->id );
|
||||
|
||||
+3
-2
@@ -9,7 +9,8 @@
|
||||
* 2002, Joris Robijn
|
||||
*
|
||||
*
|
||||
* Handles a menu and all actions that can be performed on it.
|
||||
* Handles a menu and all actions that can be performed on it. Note that a
|
||||
* menu is itself also a menuitem.
|
||||
*
|
||||
* Menus are similar to "pull-down" menus, but have some extra features.
|
||||
* They can contain "normal" menu items, checkboxes, sliders, "movers",
|
||||
@@ -323,7 +324,7 @@ void menu_update_screen (MenuItem *menu, Screen *s)
|
||||
}
|
||||
}
|
||||
|
||||
MenuResult menu_handle_input (Menu *menu, MenuToken token, char * key)
|
||||
MenuResult menu_process_input (Menu *menu, MenuToken token, char * key)
|
||||
{
|
||||
MenuItem *subitem;
|
||||
|
||||
|
||||
+1
-1
@@ -103,7 +103,7 @@ void menu_update_screen (Menu *menu, Screen *s);
|
||||
* DO NOT CALL THIS FUNCTION, CALL menuitem_build_screen INSTEAD !
|
||||
*/
|
||||
|
||||
MenuResult menu_handle_input (Menu *menu, MenuToken token, char * key);
|
||||
MenuResult menu_process_input (Menu *menu, MenuToken token, char * key);
|
||||
/* Does something with the given input.
|
||||
* key is only used if token is MENUTOKEN_OTHER.
|
||||
* DO NOT CALL THIS FUNCTION, CALL menuitem_build_screen INSTEAD !
|
||||
|
||||
+14
-11
@@ -37,9 +37,9 @@ void menuitem_destroy_alpha (MenuItem *item);
|
||||
void menuitem_reset_numeric (MenuItem *item);
|
||||
void menuitem_reset_alpha (MenuItem *item);
|
||||
|
||||
void menuitem_build_screen_slider (MenuItem *item, Screen *s);
|
||||
void menuitem_build_screen_numeric (MenuItem *item, Screen *s);
|
||||
void menuitem_build_screen_alpha (MenuItem *item, Screen *s);
|
||||
void menuitem_rebuild_screen_slider (MenuItem *item, Screen *s);
|
||||
void menuitem_rebuild_screen_numeric (MenuItem *item, Screen *s);
|
||||
void menuitem_rebuild_screen_alpha (MenuItem *item, Screen *s);
|
||||
|
||||
void menuitem_update_screen_slider (MenuItem *item, Screen *s);
|
||||
void menuitem_update_screen_numeric (MenuItem *item, Screen *s);
|
||||
@@ -79,9 +79,9 @@ void (*build_screen_table[NUM_ITEMTYPES] ) (MenuItem *item, Screen *s) =
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
menuitem_build_screen_slider,
|
||||
menuitem_build_screen_numeric,
|
||||
menuitem_build_screen_alpha
|
||||
menuitem_rebuild_screen_slider,
|
||||
menuitem_rebuild_screen_numeric,
|
||||
menuitem_rebuild_screen_alpha
|
||||
};
|
||||
void (*update_screen_table[NUM_ITEMTYPES] ) (MenuItem *item, Screen *s) =
|
||||
{
|
||||
@@ -96,7 +96,7 @@ void (*update_screen_table[NUM_ITEMTYPES] ) (MenuItem *item, Screen *s) =
|
||||
|
||||
MenuResult (*process_input_table[NUM_ITEMTYPES] ) (MenuItem *item, MenuToken token, char *key) =
|
||||
{
|
||||
menu_handle_input,
|
||||
menu_process_input,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
@@ -351,7 +351,7 @@ void menuitem_reset_alpha (MenuItem *item)
|
||||
|
||||
/******** MENU SCREEN BUILD FUNCTIONS ********/
|
||||
|
||||
void menuitem_build_screen (MenuItem *item, Screen *s)
|
||||
void menuitem_rebuild_screen (MenuItem *item, Screen *s)
|
||||
{
|
||||
Widget * w;
|
||||
void (*build_screen) (MenuItem *item, Screen *s);
|
||||
@@ -381,9 +381,12 @@ void menuitem_build_screen (MenuItem *item, Screen *s)
|
||||
report (RPT_ERR, "%s: given menuitem cannot be active", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Also always call update_screen */
|
||||
menuitem_update_screen (item, s);
|
||||
}
|
||||
|
||||
void menuitem_build_screen_slider (MenuItem *item, Screen *s)
|
||||
void menuitem_rebuild_screen_slider (MenuItem *item, Screen *s)
|
||||
{
|
||||
Widget * w;
|
||||
|
||||
@@ -431,7 +434,7 @@ void menuitem_build_screen_slider (MenuItem *item, Screen *s)
|
||||
}
|
||||
}
|
||||
|
||||
void menuitem_build_screen_numeric (MenuItem *item, Screen *s)
|
||||
void menuitem_rebuild_screen_numeric (MenuItem *item, Screen *s)
|
||||
{
|
||||
Widget * w;
|
||||
|
||||
@@ -462,7 +465,7 @@ void menuitem_build_screen_numeric (MenuItem *item, Screen *s)
|
||||
}
|
||||
}
|
||||
|
||||
void menuitem_build_screen_alpha (MenuItem *item, Screen *s)
|
||||
void menuitem_rebuild_screen_alpha (MenuItem *item, Screen *s)
|
||||
{
|
||||
Widget * w;
|
||||
|
||||
|
||||
+2
-2
@@ -258,8 +258,8 @@ void menuitem_reset (MenuItem *item);
|
||||
* Those items do not keep temporary data.
|
||||
*/
|
||||
|
||||
void menuitem_build_screen (MenuItem *item, Screen *s);
|
||||
/* Builds the selected menuitem on screen using widgets.
|
||||
void menuitem_rebuild_screen (MenuItem *item, Screen *s);
|
||||
/* (Re)builds the selected menuitem on screen using widgets.
|
||||
* Should be re-called if menuitem data has been changed.
|
||||
* There are a few (logical) exceptions to this:
|
||||
* - the values
|
||||
|
||||
+75
-36
@@ -44,7 +44,8 @@ MenuItem * active_menuitem;
|
||||
Menu * main_menu;
|
||||
Menu * screens_menu;
|
||||
|
||||
|
||||
/* Local prototypes */
|
||||
void menuscreen_switch_item (MenuItem * new_menuitem);
|
||||
void menuscreen_create_menu ();
|
||||
MenuEventFunc (heartbeat_handler);
|
||||
MenuEventFunc (backlight_handler);
|
||||
@@ -78,6 +79,27 @@ int init_menu()
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void menuscreen_inform_item_destruction (MenuItem * item)
|
||||
{
|
||||
MenuItem * i;
|
||||
|
||||
/* Are we currently in (a subitem of) the given item ? */
|
||||
for( i = active_menuitem; i; i = i->parent ) {
|
||||
if( i == item ) {
|
||||
menuscreen_switch_item (item->parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void menuscreen_inform_item_modified (MenuItem * item)
|
||||
{
|
||||
/* Are we currently in the item or the parent of the item ? */
|
||||
if( active_menuitem == item || active_menuitem == item->parent ) {
|
||||
menuitem_rebuild_screen( active_menuitem, menuscreen );
|
||||
}
|
||||
}
|
||||
|
||||
bool is_menu_key (char * key)
|
||||
{
|
||||
if (strcmp (key, menu_key) == 0)
|
||||
@@ -86,6 +108,44 @@ bool is_menu_key (char * key)
|
||||
return false;
|
||||
}
|
||||
|
||||
void menuscreen_switch_item (MenuItem * new_menuitem)
|
||||
/* This function changes the menuitem to the given one, and does necesary
|
||||
* actions.
|
||||
* The item will not be reset when the new item is a child of the last one.
|
||||
*/
|
||||
{
|
||||
MenuItem * old_menuitem = active_menuitem;
|
||||
|
||||
/* First we do the switch */
|
||||
active_menuitem = new_menuitem;
|
||||
|
||||
/* What was the state change ? */
|
||||
if (old_menuitem && !new_menuitem) {
|
||||
/* Menu is being quit */
|
||||
|
||||
/* TODO: send menu to backgr */
|
||||
if (screenlist_remove (menuscreen) < 0) {
|
||||
report (RPT_ERR, "%s: Error unqueueing menu screen", __FUNCTION__);
|
||||
}
|
||||
} else if (!old_menuitem && new_menuitem) {
|
||||
/* Menu is becoming active */
|
||||
menuitem_reset (active_menuitem);
|
||||
menuitem_rebuild_screen (active_menuitem, menuscreen);
|
||||
|
||||
if (screenlist_add (menuscreen) < 0) {
|
||||
report (RPT_ERR, "%s: Error queueing menu screen", __FUNCTION__);
|
||||
}
|
||||
/* TODO: raise it ! */
|
||||
return;
|
||||
} else {
|
||||
/* We're left with the usual case: a menu level switch */
|
||||
if( old_menuitem->parent != new_menuitem) {
|
||||
menuitem_reset (new_menuitem);
|
||||
}
|
||||
menuitem_rebuild_screen (active_menuitem, menuscreen);
|
||||
}
|
||||
}
|
||||
|
||||
void menuscreen_key_handler (char *key)
|
||||
{
|
||||
char token = 0;
|
||||
@@ -112,16 +172,7 @@ void menuscreen_key_handler (char *key)
|
||||
/* Is the menu already active ? */
|
||||
if (!active_menuitem) {
|
||||
debug (RPT_DEBUG, "%s: Activating menu screen", __FUNCTION__);
|
||||
active_menuitem = main_menu;
|
||||
menuitem_build_screen (active_menuitem, menuscreen);
|
||||
menuitem_reset (active_menuitem);
|
||||
menuitem_update_screen (active_menuitem, menuscreen);
|
||||
|
||||
if (screenlist_add (menuscreen) < 0) {
|
||||
report (RPT_ERR, "%s: Error queueing menu screen", __FUNCTION__);
|
||||
}
|
||||
/* TODO: raise it ! */
|
||||
|
||||
menuscreen_switch_item (main_menu);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -132,42 +183,30 @@ void menuscreen_key_handler (char *key)
|
||||
report (RPT_ERR, "%s: Error from menu_handle_input", __FUNCTION__);
|
||||
break;
|
||||
case MENURESULT_NONE:
|
||||
if (active_menuitem) {
|
||||
menuitem_update_screen (active_menuitem, menuscreen);
|
||||
/* No rebuild needed, only value can be changed */
|
||||
}
|
||||
/* Nothing extra to be done */
|
||||
break;
|
||||
case MENURESULT_ENTER:
|
||||
/* Enter the selected menuitem
|
||||
* Note: this is not for checkboxes etc that don't have their
|
||||
* own screen. The menu_handle_input function should do
|
||||
* things like toggling checkboxes !
|
||||
*/
|
||||
/* Enter the selected menuitem
|
||||
* Note: this is not for checkboxes etc that don't have their
|
||||
* own screen. The menu_handle_input function should do
|
||||
* things like toggling checkboxes !
|
||||
*/
|
||||
debug (RPT_DEBUG, "%s: Entering subitem", __FUNCTION__);
|
||||
active_menuitem = menu_get_current_item (active_menuitem);
|
||||
menuitem_build_screen (active_menuitem, menuscreen);
|
||||
menuitem_reset (active_menuitem);
|
||||
menuscreen_switch_item (menu_get_current_item (active_menuitem));
|
||||
break;
|
||||
case MENURESULT_CLOSE:
|
||||
debug (RPT_DEBUG, "%s: Closing item", __FUNCTION__);
|
||||
active_menuitem = menuitem_get_parent (active_menuitem);
|
||||
if (active_menuitem) {
|
||||
/* We were in at least second level menu */
|
||||
menuitem_build_screen (active_menuitem, menuscreen);
|
||||
break;
|
||||
}
|
||||
/* If first level menu, quit menu now
|
||||
* Therefor no break; now.
|
||||
*/
|
||||
menuscreen_switch_item (active_menuitem->parent);
|
||||
break;
|
||||
case MENURESULT_QUIT:
|
||||
debug (RPT_DEBUG, "%s: Closing menu screen", __FUNCTION__);
|
||||
active_menuitem = NULL;
|
||||
/* TODO: send menu to backgr */
|
||||
if (screenlist_remove (menuscreen) < 0) {
|
||||
report (RPT_ERR, "%s: Error unqueueing menu screen", __FUNCTION__);
|
||||
}
|
||||
menuscreen_switch_item (NULL);
|
||||
break;
|
||||
}
|
||||
if (active_menuitem) {
|
||||
menuitem_update_screen (active_menuitem, menuscreen);
|
||||
}
|
||||
}
|
||||
|
||||
void menuscreen_create_menu ()
|
||||
|
||||
+11
-1
@@ -15,10 +15,10 @@
|
||||
#define MENUSCREENS_H
|
||||
|
||||
#include "menu.h"
|
||||
#include "menuitem.h"
|
||||
#include "screen.h"
|
||||
|
||||
extern Screen * menuscreen;
|
||||
extern MenuItem * active_menuitem;
|
||||
extern Menu * main_menu;
|
||||
|
||||
int init_menu();
|
||||
@@ -28,6 +28,16 @@ bool is_menu_key (char * key);
|
||||
* reserved menu key.
|
||||
*/
|
||||
|
||||
void menuscreen_inform_item_destruction (MenuItem * item);
|
||||
/* Meant for other parts of the program to inform the menuscreen that the
|
||||
* item is about to be removed.
|
||||
*/
|
||||
|
||||
void menuscreen_inform_item_modified (MenuItem * item);
|
||||
/* Meant for other parts of the program to inform the menuscreen that some
|
||||
* properties of the item have been modified.
|
||||
*/
|
||||
|
||||
void menuscreen_key_handler (char *key);
|
||||
/* This handler handles the keypresses for the menu.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user