pidgin/pidgin
Clone
Summary
Browse
Changes
Graph
merge of 'b98e72d4089afb8a1879e5fe9627cfb132ee88de'
gaim
2007-05-20, William Ehlhardt
77693555855f
merge of 'b98e72d4089afb8a1879e5fe9627cfb132ee88de'
and 'b2836a24d81e7a1bd1d21b3aea8794b094391344'
#include
"gntmenu.h"
#include
"gntmenuitemcheck.h"
#include
<string.h>
enum
{
SIGS
=
1
,
};
static
GntTreeClass
*
parent_class
=
NULL
;
static
void
(
*
org_draw
)(
GntWidget
*
wid
);
static
void
(
*
org_destroy
)(
GntWidget
*
wid
);
static
void
(
*
org_map
)(
GntWidget
*
wid
);
static
gboolean
(
*
org_key_pressed
)(
GntWidget
*
w
,
const
char
*
t
);
static
void
gnt_menu_draw
(
GntWidget
*
widget
)
{
GntMenu
*
menu
=
GNT_MENU
(
widget
);
GList
*
iter
;
chtype
type
;
int
i
;
if
(
menu
->
type
==
GNT_MENU_TOPLEVEL
)
{
wbkgdset
(
widget
->
window
,
'\0'
|
COLOR_PAIR
(
GNT_COLOR_HIGHLIGHT
));
werase
(
widget
->
window
);
for
(
i
=
0
,
iter
=
menu
->
list
;
iter
;
iter
=
iter
->
next
,
i
++
)
{
GntMenuItem
*
item
=
GNT_MENUITEM
(
iter
->
data
);
type
=
' '
|
COLOR_PAIR
(
GNT_COLOR_HIGHLIGHT
);
if
(
i
==
menu
->
selected
)
type
|=
A_REVERSE
;
item
->
priv
.
x
=
getcurx
(
widget
->
window
)
+
widget
->
priv
.
x
;
item
->
priv
.
y
=
getcury
(
widget
->
window
)
+
widget
->
priv
.
y
+
1
;
wbkgdset
(
widget
->
window
,
type
);
wprintw
(
widget
->
window
,
" %s "
,
item
->
text
);
}
}
else
{
org_draw
(
widget
);
}
GNTDEBUG
;
}
static
void
gnt_menu_size_request
(
GntWidget
*
widget
)
{
GntMenu
*
menu
=
GNT_MENU
(
widget
);
if
(
menu
->
type
==
GNT_MENU_TOPLEVEL
)
{
widget
->
priv
.
height
=
1
;
widget
->
priv
.
width
=
getmaxx
(
stdscr
);
}
else
{
widget
->
priv
.
height
=
g_list_length
(
menu
->
list
)
+
2
;
widget
->
priv
.
width
=
25
;
/* XXX: */
}
}
static
void
menu_tree_add
(
GntMenu
*
menu
,
GntMenuItem
*
item
,
GntMenuItem
*
parent
)
{
if
(
GNT_IS_MENUITEM_CHECK
(
item
))
{
gnt_tree_add_choice
(
GNT_TREE
(
menu
),
item
,
gnt_tree_create_row
(
GNT_TREE
(
menu
),
item
->
text
,
" "
),
parent
,
NULL
);
gnt_tree_set_choice
(
GNT_TREE
(
menu
),
item
,
gnt_menuitem_check_get_checked
(
GNT_MENUITEM_CHECK
(
item
)));
}
else
gnt_tree_add_row_last
(
GNT_TREE
(
menu
),
item
,
gnt_tree_create_row
(
GNT_TREE
(
menu
),
item
->
text
,
item
->
submenu
?
">"
:
" "
),
parent
);
if
(
0
&&
item
->
submenu
)
{
GntMenu
*
sub
=
GNT_MENU
(
item
->
submenu
);
GList
*
iter
;
for
(
iter
=
sub
->
list
;
iter
;
iter
=
iter
->
next
)
{
GntMenuItem
*
it
=
GNT_MENUITEM
(
iter
->
data
);
menu_tree_add
(
menu
,
it
,
item
);
}
}
}
static
void
gnt_menu_map
(
GntWidget
*
widget
)
{
GntMenu
*
menu
=
GNT_MENU
(
widget
);
if
(
menu
->
type
==
GNT_MENU_TOPLEVEL
)
{
gnt_widget_size_request
(
widget
);
}
else
{
/* Populate the tree */
GList
*
iter
;
gnt_tree_remove_all
(
GNT_TREE
(
widget
));
for
(
iter
=
menu
->
list
;
iter
;
iter
=
iter
->
next
)
{
GntMenuItem
*
item
=
GNT_MENUITEM
(
iter
->
data
);
menu_tree_add
(
menu
,
item
,
NULL
);
}
org_map
(
widget
);
gnt_tree_adjust_columns
(
GNT_TREE
(
widget
));
}
GNTDEBUG
;
}
static
void
menuitem_activate
(
GntMenu
*
menu
,
GntMenuItem
*
item
)
{
if
(
item
)
{
if
(
item
->
submenu
)
{
GntMenu
*
sub
=
GNT_MENU
(
item
->
submenu
);
menu
->
submenu
=
sub
;
sub
->
type
=
GNT_MENU_POPUP
;
/* Submenus are *never* toplevel */
sub
->
parentmenu
=
menu
;
if
(
menu
->
type
!=
GNT_MENU_TOPLEVEL
)
{
GntWidget
*
widget
=
GNT_WIDGET
(
menu
);
item
->
priv
.
x
=
widget
->
priv
.
x
+
widget
->
priv
.
width
-
1
;
item
->
priv
.
y
=
widget
->
priv
.
y
+
gnt_tree_get_selection_visible_line
(
GNT_TREE
(
menu
));
}
gnt_widget_set_position
(
GNT_WIDGET
(
sub
),
item
->
priv
.
x
,
item
->
priv
.
y
);
GNT_WIDGET_UNSET_FLAGS
(
GNT_WIDGET
(
sub
),
GNT_WIDGET_INVISIBLE
);
gnt_widget_draw
(
GNT_WIDGET
(
sub
));
}
else
if
(
item
->
callback
)
{
item
->
callback
(
item
,
item
->
callbackdata
);
while
(
menu
)
{
gnt_widget_hide
(
GNT_WIDGET
(
menu
));
menu
=
menu
->
parentmenu
;
}
}
}
}
static
gboolean
gnt_menu_key_pressed
(
GntWidget
*
widget
,
const
char
*
text
)
{
GntMenu
*
menu
=
GNT_MENU
(
widget
);
int
current
=
menu
->
selected
;
if
(
menu
->
submenu
)
{
return
(
gnt_widget_key_pressed
(
GNT_WIDGET
(
menu
->
submenu
),
text
));
}
if
(
text
[
0
]
==
27
&&
text
[
1
]
==
0
)
{
/* Escape closes menu */
GntMenu
*
par
=
menu
->
parentmenu
;
if
(
par
!=
NULL
)
{
par
->
submenu
=
NULL
;
gnt_widget_hide
(
widget
);
}
else
gnt_widget_hide
(
widget
);
return
TRUE
;
}
if
(
menu
->
type
==
GNT_MENU_TOPLEVEL
)
{
if
(
strcmp
(
text
,
GNT_KEY_LEFT
)
==
0
)
{
menu
->
selected
--
;
if
(
menu
->
selected
<
0
)
menu
->
selected
=
g_list_length
(
menu
->
list
)
-
1
;
}
else
if
(
strcmp
(
text
,
GNT_KEY_RIGHT
)
==
0
)
{
menu
->
selected
++
;
if
(
menu
->
selected
>=
g_list_length
(
menu
->
list
))
menu
->
selected
=
0
;
}
else
if
(
strcmp
(
text
,
GNT_KEY_ENTER
)
==
0
)
{
gnt_widget_activate
(
widget
);
}
if
(
current
!=
menu
->
selected
)
{
gnt_widget_draw
(
widget
);
return
TRUE
;
}
}
else
{
return
org_key_pressed
(
widget
,
text
);
}
return
FALSE
;
}
static
void
gnt_menu_destroy
(
GntWidget
*
widget
)
{
GntMenu
*
menu
=
GNT_MENU
(
widget
);
g_list_foreach
(
menu
->
list
,
(
GFunc
)
g_object_unref
,
NULL
);
g_list_free
(
menu
->
list
);
org_destroy
(
widget
);
}
static
void
gnt_menu_toggled
(
GntTree
*
tree
,
gpointer
key
)
{
GntMenuItem
*
item
=
GNT_MENUITEM
(
key
);
GntMenu
*
menu
=
GNT_MENU
(
tree
);
gboolean
check
=
gnt_menuitem_check_get_checked
(
GNT_MENUITEM_CHECK
(
item
));
gnt_menuitem_check_set_checked
(
GNT_MENUITEM_CHECK
(
item
),
!
check
);
if
(
item
->
callback
)
item
->
callback
(
item
,
item
->
callbackdata
);
while
(
menu
)
{
gnt_widget_hide
(
GNT_WIDGET
(
menu
));
menu
=
menu
->
parentmenu
;
}
}
static
void
gnt_menu_activate
(
GntWidget
*
widget
)
{
GntMenu
*
menu
=
GNT_MENU
(
widget
);
GntMenuItem
*
item
;
if
(
menu
->
type
==
GNT_MENU_TOPLEVEL
)
{
item
=
g_list_nth_data
(
menu
->
list
,
menu
->
selected
);
}
else
{
item
=
gnt_tree_get_selection_data
(
GNT_TREE
(
menu
));
}
if
(
item
)
{
if
(
GNT_IS_MENUITEM_CHECK
(
item
))
gnt_menu_toggled
(
GNT_TREE
(
widget
),
item
);
else
menuitem_activate
(
menu
,
item
);
}
}
static
void
gnt_menu_hide
(
GntWidget
*
widget
)
{
GntMenu
*
menu
=
GNT_MENU
(
widget
);
if
(
menu
->
parentmenu
)
menu
->
parentmenu
->
submenu
=
NULL
;
}
static
void
gnt_menu_class_init
(
GntMenuClass
*
klass
)
{
GntWidgetClass
*
wid_class
=
GNT_WIDGET_CLASS
(
klass
);
parent_class
=
GNT_TREE_CLASS
(
klass
);
org_destroy
=
wid_class
->
destroy
;
org_map
=
wid_class
->
map
;
org_draw
=
wid_class
->
draw
;
org_key_pressed
=
wid_class
->
key_pressed
;
wid_class
->
destroy
=
gnt_menu_destroy
;
wid_class
->
draw
=
gnt_menu_draw
;
wid_class
->
map
=
gnt_menu_map
;
wid_class
->
size_request
=
gnt_menu_size_request
;
wid_class
->
key_pressed
=
gnt_menu_key_pressed
;
wid_class
->
activate
=
gnt_menu_activate
;
wid_class
->
hide
=
gnt_menu_hide
;
parent_class
->
toggled
=
gnt_menu_toggled
;
GNTDEBUG
;
}
static
void
gnt_menu_init
(
GTypeInstance
*
instance
,
gpointer
class
)
{
GntWidget
*
widget
=
GNT_WIDGET
(
instance
);
GNT_WIDGET_SET_FLAGS
(
widget
,
GNT_WIDGET_NO_SHADOW
|
GNT_WIDGET_NO_BORDER
|
GNT_WIDGET_CAN_TAKE_FOCUS
|
GNT_WIDGET_TRANSIENT
);
GNTDEBUG
;
}
/******************************************************************************
* GntMenu API
*****************************************************************************/
GType
gnt_menu_get_gtype
(
void
)
{
static
GType
type
=
0
;
if
(
type
==
0
)
{
static
const
GTypeInfo
info
=
{
sizeof
(
GntMenuClass
),
NULL
,
/* base_init */
NULL
,
/* base_finalize */
(
GClassInitFunc
)
gnt_menu_class_init
,
NULL
,
/* class_finalize */
NULL
,
/* class_data */
sizeof
(
GntMenu
),
0
,
/* n_preallocs */
gnt_menu_init
,
/* instance_init */
};
type
=
g_type_register_static
(
GNT_TYPE_TREE
,
"GntMenu"
,
&
info
,
0
);
}
return
type
;
}
GntWidget
*
gnt_menu_new
(
GntMenuType
type
)
{
GntWidget
*
widget
=
g_object_new
(
GNT_TYPE_MENU
,
NULL
);
GntMenu
*
menu
=
GNT_MENU
(
widget
);
menu
->
list
=
NULL
;
menu
->
selected
=
0
;
menu
->
type
=
type
;
if
(
type
==
GNT_MENU_TOPLEVEL
)
{
widget
->
priv
.
x
=
0
;
widget
->
priv
.
y
=
0
;
}
else
{
GNT_TREE
(
widget
)
->
show_separator
=
FALSE
;
_gnt_tree_init_internals
(
GNT_TREE
(
widget
),
2
);
gnt_tree_set_col_width
(
GNT_TREE
(
widget
),
1
,
1
);
/* The second column is to indicate that it has a submenu */
GNT_WIDGET_UNSET_FLAGS
(
widget
,
GNT_WIDGET_NO_BORDER
);
}
return
widget
;
}
void
gnt_menu_add_item
(
GntMenu
*
menu
,
GntMenuItem
*
item
)
{
menu
->
list
=
g_list_append
(
menu
->
list
,
item
);
}