Menu stuff update. Fixed some of the probably many bugs and made things a

bit more consistent.
This commit is contained in:
robijn
2002-07-09 22:56:05 +00:00
parent 012a4cb483
commit 1156c51062
8 changed files with 131 additions and 61 deletions
+5 -1
View File
@@ -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);
+20 -7
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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.
*/