[Implement an Outlook-style "New" dropdown button. It is basically

done but it needs pretty icons so I am leaving it disabled for now.]

* e-combo-button.c: Remove member `separator' from
`EComboButtonPrivate'.  New members `icon', `label'.
(init): There shall be no separator no more.  Init `icon' and
`label' to %NULL.
(e_combo_button_construct): Set no relief.
(e_combo_button_new): Don't get a @menu arg anymore.
(e_combo_button_construct): Likewise.
(e_combo_button_set_icon): New.
(e_combo_button_set_label): New.
(e_combo_button_set_menu): New.
(impl_clicked): New, overriding the "clicked" method for
GtkButton.
(class_init): Install.
(impl_button_release_event): Removed.
(class_init): No need to override ::release_event with this
anymore.
(impl_released): New, override for the GtkButton::released method.
(class_init): Install.

* e-shell-user-creatable-items-handler.c: New member `id' in
struct `Component'.  New member `icon' in struct `MenuItem'.
(component_free): Free ->id.
(component_new): Renamed from `component_new_from_client'.  Get an
@id arg and set ->id accordingly.
(e_shell_user_creatable_items_handler_add_component): New arg @id.
Pass it to `component_new'.
(e_shell_user_creatable_items_handler_setup_menus): New arg
@current_component_id.
(e_shell_user_creatable_items_handler_update_menus): New.
(set_current_component): New helper function.
(get_component_by_id): New helper function.
(add_verbs): Renamed from `add_verbs_to_ui_component()'.  Get a
@shell_view instead of a @ui_component.  Set the SHELL_VIEW_KEY on
the ui_component of the shell_view to point to the shell_view
itself.
(ensure_menu_items): Set item->icon to NULL.
(free_menu_items): Unref item->icon.
(ensure_menu_xml): Set the icon as well.
(get_default_action_for_view): New helper function.
(find_menu_item_for_verb): New helper function.
(shell_view_view_changed_callback): New callback, set up the label
on the "New" button depending on the current component.
(e_shell_user_creatable_items_handler_attach_menus): New.  For
now, do not display the toolbar button yet.
(execute_verb): New helper function, splitting out code from
`verb_fn'.
(verb_fn): Use `execute_verb'.
(combo_button_activate_default_callback): Callback for the
"activate_default" signal on the EComboButton.
(setup_toolbar_button): Connect.

* evolution-shell-component.c: New member `icon' in
`UserCreatableItemType'.
(impl__get_userCreatableItemTypes): Put the ->icon in the
corba_type as well.
(user_creatable_item_type_new): Get a new @icon argument.
(evolution_shell_component_add_user_creatable_item): New arg
@icon.

* Evolution-ShellComponent.idl: New member `icon' in struct
`UserCreatableItemType'.

* evolution-test-component.c (register_component): Pass a NULL
@icon to `evolution_shell_component_add_user_creatable_item()'.

* e-shell-view.c (class_init): Add the signal to the class.
(e_shell_view_display_uri): Emit "view_changed".
(e_shell_view_get_current_component_id): New.

* evolution-shell-component-client.c: New member `id' in
EvolutionShellComponentClientPrivate.
(init): Init to NULL.
(impl_destroy): Free.
(evolution_shell_component_client_new_for_objref): Removed.
(evolution_shell_component_client_construct): New arg @id.
Initialize ->id from it.
(evolution_shell_component_client_get_id): New.

* e-shell-view.h: New signal "view_changed".

* evolution-activity-client.c (create_icon_from_pixbuf): Removed.
(create_corba_animated_icon_from_pixbuf_array): Removed.
(evolution_activity_client_construct): Use
`e_new_corba_animated_icon_from_pixbuf_array()' instead.

svn path=/trunk/; revision=15438
This commit is contained in:
Ettore Perazzoli
2002-01-23 22:21:24 +00:00
parent 8cdf205496
commit 4eb4ae3be8
18 changed files with 749 additions and 306 deletions

View File

@ -1,3 +1,74 @@
2002-01-23 Ettore Perazzoli <ettore@ximian.com>
* e-shell-user-creatable-items-handler.c: New member `id' in
struct `Component'. New member `icon' in struct `MenuItem'.
(component_free): Free ->id.
(component_new): Renamed from `component_new_from_client'. Get an
@id arg and set ->id accordingly.
(e_shell_user_creatable_items_handler_add_component): New arg @id.
Pass it to `component_new'.
(e_shell_user_creatable_items_handler_setup_menus): New arg
@current_component_id.
(e_shell_user_creatable_items_handler_update_menus): New.
(set_current_component): New helper function.
(get_component_by_id): New helper function.
(add_verbs): Renamed from `add_verbs_to_ui_component()'. Get a
@shell_view instead of a @ui_component. Set the SHELL_VIEW_KEY on
the ui_component of the shell_view to point to the shell_view
itself.
(ensure_menu_items): Set item->icon to NULL.
(free_menu_items): Unref item->icon.
(ensure_menu_xml): Set the icon as well.
(get_default_action_for_view): New helper function.
(find_menu_item_for_verb): New helper function.
(shell_view_view_changed_callback): New callback, set up the label
on the "New" button depending on the current component.
(e_shell_user_creatable_items_handler_attach_menus): New. For
now, do not display the toolbar button yet.
(execute_verb): New helper function, splitting out code from
`verb_fn'.
(verb_fn): Use `execute_verb'.
(combo_button_activate_default_callback): Callback for the
"activate_default" signal on the EComboButton.
(setup_toolbar_button): Connect.
* evolution-shell-component.c: New member `icon' in
`UserCreatableItemType'.
(impl__get_userCreatableItemTypes): Put the ->icon in the
corba_type as well.
(user_creatable_item_type_new): Get a new @icon argument.
(evolution_shell_component_add_user_creatable_item): New arg
@icon.
* Evolution-ShellComponent.idl: New member `icon' in struct
`UserCreatableItemType'.
* evolution-test-component.c (register_component): Pass a NULL
@icon to `evolution_shell_component_add_user_creatable_item()'.
* e-shell-view.c (class_init): Add the signal to the class.
(e_shell_view_display_uri): Emit "view_changed".
(e_shell_view_get_current_component_id): New.
* evolution-shell-component-client.c: New member `id' in
EvolutionShellComponentClientPrivate.
(init): Init to NULL.
(impl_destroy): Free.
(evolution_shell_component_client_new_for_objref): Removed.
(evolution_shell_component_client_construct): New arg @id.
Initialize ->id from it.
(evolution_shell_component_client_get_id): New.
* e-shell-view.h: New signal "view_changed".
* evolution-activity-client.c (create_icon_from_pixbuf): Removed.
(create_corba_animated_icon_from_pixbuf_array): Removed.
(evolution_activity_client_construct): Use
`e_new_corba_animated_icon_from_pixbuf_array()' instead.
* e-shell-icon-utils.h: New.
* e-shell-icon-utils.c: New.
2002-01-23 Ettore Perazzoli <ettore@ximian.com>
[Patch by Michael Meeks <michael@ximian.com>.]

View File

@ -36,6 +36,7 @@ module Evolution {
string description;
string menuDescription;
char menuShortcut;
Icon icon;
};
typedef sequence<UserCreatableItemType> UserCreatableItemTypeList;

View File

@ -77,6 +77,8 @@ eshellinclude_HEADERS = \
libeshell_la_SOURCES = \
$(IDL_GENERATED) \
e-folder-tree.c \
e-shell-corba-icon-utils.c \
e-shell-corba-icon-utils.h \
evolution-activity-client.c \
evolution-session.c \
evolution-shell-client.c \

View File

@ -26,12 +26,18 @@
#include "e-shell-user-creatable-items-handler.h"
#include "widgets/misc/e-combo-button.h"
#include "e-util/e-corba-utils.h"
#include <gal/util/e-util.h>
#include <bonobo/bonobo-ui-util.h>
#include <libgnome/gnome-i18n.h>
#include <gtk/gtksignal.h>
#include <stdlib.h>
#include <ctype.h>
@ -41,7 +47,9 @@ static GtkObjectClass *parent_class = NULL;
#define VERB_PREFIX "ShellUserCreatableItemVerb"
#define SHELL_VIEW_DATA_KEY "EShellUserCreatableItemsHandler:shell_view"
#define SHELL_VIEW_KEY "EShellUserCreatableItemsHandler:shell_view"
#define COMBO_BUTTON_WIDGET_KEY "EShellUserCreatableItemsHandler:combo_button"
struct _Component {
EvolutionShellComponentClient *component_client;
@ -50,9 +58,18 @@ struct _Component {
};
typedef struct _Component Component;
struct _MenuItem {
const char *label;
char shortcut;
char *verb;
GdkPixbuf *icon;
};
typedef struct _MenuItem MenuItem;
struct _EShellUserCreatableItemsHandlerPrivate {
GSList *components; /* Component */
GSList *menu_items; /* MenuItem */
char *menu_xml;
};
@ -60,7 +77,8 @@ struct _EShellUserCreatableItemsHandlerPrivate {
/* Component struct handling. */
static Component *
component_new_from_client (EvolutionShellComponentClient *client)
component_new (const char *id,
EvolutionShellComponentClient *client)
{
CORBA_Environment ev;
Component *new;
@ -106,14 +124,8 @@ create_verb_from_component_number_and_type_id (int component_num,
}
/* Setting up the XML for the menus. */
struct _MenuItem {
const char *label;
char shortcut;
char *verb;
};
typedef struct _MenuItem MenuItem;
/* Setting up menu items for the "File -> New" submenu and the "New" toolbar
button. */
static int
item_types_sort_func (const void *a,
@ -156,51 +168,10 @@ item_types_sort_func (const void *a,
} else {
return +1;
}
}
static char *
create_xml_from_menu_items (GSList *items)
{
GString *xml;
GSList *p;
char *str;
xml = g_string_new ("");
g_string_append (xml, "<Root> <menu> <submenu name=\"File\"> <submenu name=\"New\"> <placeholder name=\"NewItems\">");
g_string_append (xml, "<separator/> ");
for (p = items; p != NULL; p = p->next) {
const MenuItem *item;
char *encoded_label;
item = (const MenuItem *) p->data;
encoded_label = bonobo_ui_util_encode_str (item->label);
g_string_sprintfa (xml, "<menuitem name=\"New:%s\" verb=\"%s\" label=\"%s\"",
item->verb, item->verb, encoded_label);
if (item->shortcut != '\0')
g_string_sprintfa (xml, " accel=\"*Control**Shift*%c\"", item->shortcut);
g_string_append (xml, "/> ");
g_free (encoded_label);
}
g_string_append (xml, "</placeholder> </submenu> </submenu> </menu> </Root>");
str = xml->str;
g_string_free (xml, FALSE);
return str;
}
static void
setup_menu_xml (EShellUserCreatableItemsHandler *handler)
ensure_menu_items (EShellUserCreatableItemsHandler *handler)
{
EShellUserCreatableItemsHandlerPrivate *priv;
GSList *menu_items;
@ -208,7 +179,8 @@ setup_menu_xml (EShellUserCreatableItemsHandler *handler)
int component_num;
priv = handler->priv;
g_assert (priv->menu_xml == NULL);
if (priv->menu_items != NULL)
return;
menu_items = NULL;
component_num = 0;
@ -228,6 +200,7 @@ setup_menu_xml (EShellUserCreatableItemsHandler *handler)
item->label = type->menuDescription;
item->shortcut = type->menuShortcut;
item->verb = create_verb_from_component_number_and_type_id (component_num, type->id);
item->icon = NULL;
menu_items = g_slist_prepend (menu_items, item);
}
@ -236,36 +209,154 @@ setup_menu_xml (EShellUserCreatableItemsHandler *handler)
component_num ++;
}
if (menu_items == NULL) {
priv->menu_xml = g_strdup ("");
if (menu_items == NULL)
priv->menu_items = NULL;
else
priv->menu_items = g_slist_sort (menu_items, item_types_sort_func);
}
static void
free_menu_items (GSList *menu_items)
{
GSList *p;
if (menu_items == NULL)
return;
}
menu_items = g_slist_sort (menu_items, item_types_sort_func);
priv->menu_xml = create_xml_from_menu_items (menu_items);
for (p = menu_items; p != NULL; p = p->next) {
MenuItem *item;
item = (MenuItem *) p->data;
g_free (item->verb);
if (item->icon != NULL)
gdk_pixbuf_unref (item->icon);
g_free (item);
}
g_slist_free (menu_items);
}
static const MenuItem *
find_menu_item_for_verb (EShellUserCreatableItemsHandler *handler,
const char *verb)
{
EShellUserCreatableItemsHandlerPrivate *priv;
GSList *p;
priv = handler->priv;
for (p = priv->menu_items; p != NULL; p = p->next) {
const MenuItem *item;
item = (const MenuItem *) p->data;
if (strcmp (item->verb, verb) == 0)
return item;
}
return NULL;
}
static const MenuItem *
get_default_action_for_view (EShellUserCreatableItemsHandler *handler,
EShellView *shell_view)
{
EShellUserCreatableItemsHandlerPrivate *priv;
const char *view_component_id;
const GSList *p;
int component_num;
priv = handler->priv;
/* FIXME-1.2: This should be based on the folder type not the component
that handles it. For this, we are going to have to make the IDL a
little more complex. Also, this is a pretty brutal and ugly hack. */
view_component_id = e_shell_view_get_current_component_id (shell_view);
for (p = priv->components, component_num = 0; p != NULL; p = p->next, component_num ++) {
const Component *component;
const GNOME_Evolution_UserCreatableItemType *type;
const char *component_id;
component = (const Component *) p->data;
type = & component->type_list->_buffer[0];
component_id = evolution_shell_component_client_get_id (component->component_client);
if (strcmp (component_id, view_component_id) == 0) {
const MenuItem *item;
char *verb;
verb = create_verb_from_component_number_and_type_id (component_num, type->id);
item = find_menu_item_for_verb (handler, verb);
g_free (verb);
return item;
}
}
return NULL;
}
/* The XML description for "File -> New". */
static void
ensure_menu_xml (EShellUserCreatableItemsHandler *handler)
{
EShellUserCreatableItemsHandlerPrivate *priv;
GString *xml;
GSList *p;
priv = handler->priv;
if (priv->menu_xml != NULL)
return;
ensure_menu_items (handler);
xml = g_string_new ("");
g_string_append (xml, "<placeholder name=\"NewItems\">");
for (p = priv->menu_items; p != NULL; p = p->next) {
const MenuItem *item;
char *encoded_label;
item = (const MenuItem *) p->data;
encoded_label = bonobo_ui_util_encode_str (item->label);
g_string_sprintfa (xml, "<menuitem name=\"New:%s\" verb=\"%s\" label=\"%s\"",
item->verb, item->verb, encoded_label);
if (item->shortcut != '\0')
g_string_sprintfa (xml, " accel=\"*Control**Shift*%c\"", item->shortcut);
if (item->icon != NULL)
g_string_sprintfa (xml, " pixtype=\"pixbuf\" pixname=\"%s\"",
bonobo_ui_util_pixbuf_to_xml (item->icon));
g_string_append (xml, "/> ");
g_free (encoded_label);
}
g_string_append (xml, "</placeholder>");
priv->menu_xml = xml->str;
g_string_free (xml, FALSE);
}
/* Verb handling. */
static void
verb_fn (BonoboUIComponent *ui_component,
void *data,
const char *verb_name)
execute_verb (EShellUserCreatableItemsHandler *handler,
EShellView *shell_view,
const char *verb_name)
{
EShellUserCreatableItemsHandler *handler;
EShellUserCreatableItemsHandlerPrivate *priv;
EShellView *shell_view;
const Component *component;
int component_number;
const char *p;
@ -273,10 +364,6 @@ verb_fn (BonoboUIComponent *ui_component,
GSList *component_list_item;
int i;
shell_view = gtk_object_get_data (GTK_OBJECT (ui_component), SHELL_VIEW_DATA_KEY);
g_assert (E_IS_SHELL_VIEW (shell_view));
handler = E_SHELL_USER_CREATABLE_ITEMS_HANDLER (data);
priv = handler->priv;
p = strchr (verb_name, ':');
@ -318,15 +405,35 @@ verb_fn (BonoboUIComponent *ui_component,
}
static void
add_verbs_to_ui_component (EShellUserCreatableItemsHandler *handler,
BonoboUIComponent *ui_component)
verb_fn (BonoboUIComponent *ui_component,
void *data,
const char *verb_name)
{
EShellUserCreatableItemsHandler *handler;
EShellView *shell_view;
shell_view = gtk_object_get_data (GTK_OBJECT (ui_component), SHELL_VIEW_KEY);
g_assert (E_IS_SHELL_VIEW (shell_view));
handler = E_SHELL_USER_CREATABLE_ITEMS_HANDLER (data);
execute_verb (handler, shell_view, verb_name);
}
static void
add_verbs (EShellUserCreatableItemsHandler *handler,
EShellView *shell_view)
{
EShellUserCreatableItemsHandlerPrivate *priv;
BonoboUIComponent *ui_component;
int component_num;
GSList *p;
priv = handler->priv;
ui_component = e_shell_view_get_bonobo_ui_component (shell_view);
gtk_object_set_data (GTK_OBJECT (ui_component), SHELL_VIEW_KEY, shell_view);
component_num = 0;
for (p = priv->components; p != NULL; p = p->next) {
const Component *component;
@ -351,6 +458,99 @@ add_verbs_to_ui_component (EShellUserCreatableItemsHandler *handler,
}
}
/* The "New" button in the toolbar. */
static void
combo_button_activate_default_callback (EComboButton *combo_button,
void *data)
{
EShellView *shell_view;
EShellUserCreatableItemsHandler *handler;
const MenuItem *menu_item;
shell_view = E_SHELL_VIEW (data);
handler = e_shell_get_user_creatable_items_handler (e_shell_view_get_shell (shell_view));
menu_item = get_default_action_for_view (handler, shell_view);
execute_verb (handler, shell_view, menu_item->verb);
}
static void
setup_toolbar_button (EShellUserCreatableItemsHandler *handler,
EShellView *shell_view)
{
EShellUserCreatableItemsHandlerPrivate *priv;
BonoboUIComponent *ui_component;
GtkWidget *combo_button;
GtkWidget *menu;
BonoboControl *control;
priv = handler->priv;
menu = gtk_menu_new ();
combo_button = e_combo_button_new ();
e_combo_button_set_menu (E_COMBO_BUTTON (combo_button), GTK_MENU (menu));
e_combo_button_set_label (E_COMBO_BUTTON (combo_button), _("New"));
gtk_widget_show (combo_button);
gtk_signal_connect (GTK_OBJECT (combo_button), "activate_default",
GTK_SIGNAL_FUNC (combo_button_activate_default_callback),
shell_view);
ui_component = e_shell_view_get_bonobo_ui_component (shell_view);
bonobo_window_add_popup (BONOBO_WINDOW (shell_view), GTK_MENU (menu), "/popups/NewPopup");
control = bonobo_control_new (combo_button);
bonobo_ui_component_object_set (ui_component, "/Toolbar/NewComboButton",
BONOBO_OBJREF (control), NULL);
gtk_object_set_data (GTK_OBJECT (shell_view), COMBO_BUTTON_WIDGET_KEY, combo_button);
}
/* This handles the menus for a given EShellView. We have to rebuild the menu
and set the toolbar button every time the view changes, and clean up when
the view is destroyed. */
static void
shell_view_view_changed_callback (EShellView *shell_view,
const char *evolution_path,
const char *physical_uri,
const char *folder_type,
const char *component_id,
void *data)
{
EShellUserCreatableItemsHandler *handler;
EShellUserCreatableItemsHandlerPrivate *priv;
GtkWidget *combo_button_widget;
const MenuItem *default_menu_item;
handler = E_SHELL_USER_CREATABLE_ITEMS_HANDLER (data);
priv = handler->priv;
combo_button_widget = gtk_object_get_data (GTK_OBJECT (shell_view), COMBO_BUTTON_WIDGET_KEY);
g_assert (E_IS_COMBO_BUTTON (combo_button_widget));
default_menu_item = get_default_action_for_view (handler, shell_view);
if (default_menu_item == NULL) {
gtk_widget_set_sensitive (combo_button_widget, FALSE);
e_combo_button_set_label (E_COMBO_BUTTON (combo_button_widget), _("New"));
e_combo_button_set_icon (E_COMBO_BUTTON (combo_button_widget), NULL);
return;
}
gtk_widget_set_sensitive (combo_button_widget, TRUE);
/* FIXME: This is temporary. We should just always say "New" once we
have the icons for all the actions. */
e_combo_button_set_label (E_COMBO_BUTTON (combo_button_widget), default_menu_item->label);
e_combo_button_set_icon (E_COMBO_BUTTON (combo_button_widget), default_menu_item->icon);
}
/* GtkObject methods. */
@ -371,6 +571,8 @@ impl_destroy (GtkObject *object)
g_free (priv->menu_xml);
free_menu_items (priv->menu_items);
g_free (priv);
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
@ -393,6 +595,7 @@ init (EShellUserCreatableItemsHandler *shell_user_creatable_items_handler)
priv = g_new (EShellUserCreatableItemsHandlerPrivate, 1);
priv->components = NULL;
priv->menu_xml = NULL;
priv->menu_items = NULL;
shell_user_creatable_items_handler->priv = priv;
}
@ -410,6 +613,7 @@ e_shell_user_creatable_items_handler_new (void)
void
e_shell_user_creatable_items_handler_add_component (EShellUserCreatableItemsHandler *handler,
const char *id,
EvolutionShellComponentClient *shell_component_client)
{
EShellUserCreatableItemsHandlerPrivate *priv;
@ -422,15 +626,25 @@ e_shell_user_creatable_items_handler_add_component (EShellUserCreatableItemsHan
priv = handler->priv;
g_return_if_fail (priv->menu_xml == NULL);
priv->components = g_slist_prepend (priv->components, component_new_from_client (shell_component_client));
priv->components = g_slist_prepend (priv->components, component_new (id, shell_component_client));
}
/**
* e_shell_user_creatable_items_handler_attach_menus:
* @handler:
* @shell_view:
*
* Set up the menus and toolbar items for @shell_view. When the shell changes
* view, the menu and the toolbar item will update automatically (i.e. the
* actions for the current folder will go on top etc.).
**/
void
e_shell_user_creatable_items_handler_setup_menus (EShellUserCreatableItemsHandler *handler,
EShellView *shell_view)
e_shell_user_creatable_items_handler_attach_menus (EShellUserCreatableItemsHandler *handler,
EShellView *shell_view)
{
EShellUserCreatableItemsHandlerPrivate *priv;
BonoboUIComponent *ui_component;
EShellUserCreatableItemsHandlerPrivate *priv;
g_return_if_fail (handler != NULL);
g_return_if_fail (E_IS_SHELL_USER_CREATABLE_ITEMS_HANDLER (handler));
@ -439,17 +653,20 @@ e_shell_user_creatable_items_handler_setup_menus (EShellUserCreatableItemsHandle
priv = handler->priv;
if (priv->menu_xml == NULL)
setup_menu_xml (handler);
/* FIXME: Re-enable this. */
if (0) {
setup_toolbar_button (handler, shell_view);
gtk_signal_connect (GTK_OBJECT (shell_view), "view_changed",
GTK_SIGNAL_FUNC (shell_view_view_changed_callback), handler);
}
ensure_menu_xml (handler);
add_verbs (handler, shell_view);
ui_component = e_shell_view_get_bonobo_ui_component (shell_view);
g_assert (ui_component);
add_verbs_to_ui_component (handler, ui_component);
gtk_object_set_data (GTK_OBJECT (ui_component), SHELL_VIEW_DATA_KEY, shell_view); /* Yuck. */
bonobo_ui_component_set (ui_component, "/", priv->menu_xml, NULL);
bonobo_ui_component_set (ui_component, "/menu/File/New/NewItems", priv->menu_xml, NULL);
bonobo_ui_component_set (ui_component, "/popups/NewPopup", priv->menu_xml, NULL);
}

View File

@ -61,10 +61,11 @@ GtkType e_shell_user_creatable_items_handler_get_type
EShellUserCreatableItemsHandler *e_shell_user_creatable_items_handler_new (void);
void e_shell_user_creatable_items_handler_add_component (EShellUserCreatableItemsHandler *handler,
const char *id,
EvolutionShellComponentClient *shell_component_client);
void e_shell_user_creatable_items_handler_setup_menus (EShellUserCreatableItemsHandler *handler,
EShellView *shell_view);
void e_shell_user_creatable_items_handler_attach_menus (EShellUserCreatableItemsHandler *handler,
EShellView *shell_view);
#ifdef __cplusplus
}

View File

@ -147,6 +147,7 @@ struct _EShellViewPrivate {
enum {
SHORTCUT_BAR_VISIBILITY_CHANGED,
FOLDER_BAR_VISIBILITY_CHANGED,
VIEW_CHANGED,
LAST_SIGNAL
};
@ -1167,6 +1168,18 @@ class_init (EShellViewClass *klass)
GTK_TYPE_NONE, 1,
GTK_TYPE_INT);
signals[VIEW_CHANGED]
= gtk_signal_new ("view_changed",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (EShellViewClass, view_changed),
e_marshal_NONE__POINTER_POINTER_POINTER_POINTER,
GTK_TYPE_NONE, 4,
GTK_TYPE_STRING,
GTK_TYPE_STRING,
GTK_TYPE_STRING,
GTK_TYPE_STRING);
gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
load_images ();
@ -1407,8 +1420,8 @@ e_shell_view_construct (EShellView *shell_view,
GTK_SIGNAL_FUNC (storage_set_removed_folder_callback), shell_view,
GTK_OBJECT (shell_view));
e_shell_user_creatable_items_handler_setup_menus (e_shell_get_user_creatable_items_handler (priv->shell),
shell_view);
e_shell_user_creatable_items_handler_attach_menus (e_shell_get_user_creatable_items_handler (priv->shell),
shell_view);
return view;
}
@ -2044,6 +2057,12 @@ e_shell_view_display_uri (EShellView *shell_view,
bonobo_window_thaw (BONOBO_WINDOW (shell_view));
gtk_signal_emit (GTK_OBJECT (shell_view), signals[VIEW_CHANGED],
e_shell_view_get_current_path (shell_view),
e_shell_view_get_current_uri (shell_view),
e_shell_view_get_current_folder_type (shell_view),
e_shell_view_get_current_component_id (shell_view));
return retval;
}
@ -2269,6 +2288,23 @@ e_shell_view_get_current_folder_type (EShellView *shell_view)
return get_type_for_folder (shell_view, current_path, NULL);
}
const char *
e_shell_view_get_current_component_id (EShellView *shell_view)
{
EShellViewPrivate *priv;
EFolderTypeRegistry *type_registry;
EvolutionShellComponentClient *component_client;
const char *current_folder_type;
priv = shell_view->priv;
type_registry = e_shell_get_folder_type_registry (priv->shell);
current_folder_type = e_shell_view_get_current_folder_type (shell_view);
component_client = e_folder_type_registry_get_handler_for_type (type_registry, current_folder_type);
return evolution_shell_component_client_get_id (component_client);
}
/**
* e_shell_view_save_settings:

View File

@ -57,8 +57,17 @@ struct _EShellViewClass {
BonoboWindowClass parent_class;
/* Signals. */
void (* shortcut_bar_visibility_changed) (EShellView *shell_view, gboolean visible);
void (* folder_bar_visibility_changed) (EShellView *shell_view, gboolean visible);
void (* shortcut_bar_visibility_changed) (EShellView *shell_view,
gboolean visible);
void (* folder_bar_visibility_changed) (EShellView *shell_view,
gboolean visible);
void (* view_changed) (EShellView *shell_view,
const char *evolution_path,
const char *physical_uri,
const char *folder_type,
const char *component_id);
};
@ -93,6 +102,7 @@ GtkWidget *e_shell_view_get_appbar (EShellView *shell_vi
const char *e_shell_view_get_current_uri (EShellView *shell_view);
const char *e_shell_view_get_current_physical_uri (EShellView *shell_view);
const char *e_shell_view_get_current_folder_type (EShellView *shell_view);
const char *e_shell_view_get_current_component_id (EShellView *shell_view);
const char *e_shell_view_get_current_path (EShellView *shell_view);
gboolean e_shell_view_save_settings (EShellView *shell_view,

View File

@ -742,6 +742,7 @@ setup_components (EShell *shell,
} else {
e_shell_user_creatable_items_handler_add_component
(priv->user_creatable_items_handler,
info->iid,
e_component_registry_get_component_by_id (priv->component_registry, info->iid));
}

View File

@ -31,6 +31,8 @@
#include "evolution-activity-client.h"
#include "e-shell-corba-icon-utils.h"
#include <gtk/gtksignal.h>
#include <gtk/gtkmain.h>
@ -78,76 +80,6 @@ struct _EvolutionActivityClientPrivate {
/* Utility functions. */
/* Create an icon from @pixbuf in @icon_return. */
static void
create_icon_from_pixbuf (GdkPixbuf *pixbuf,
GNOME_Evolution_Icon *icon_return)
{
const char *sp;
CORBA_octet *dp;
int width, height, total_width, rowstride;
int i, j;
gboolean has_alpha;
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
if (has_alpha)
total_width = 4 * width;
else
total_width = 3 * width;
icon_return->width = width;
icon_return->height = height;
icon_return->hasAlpha = has_alpha;
icon_return->rgbaData._length = icon_return->height * total_width;
icon_return->rgbaData._maximum = icon_return->rgbaData._length;
icon_return->rgbaData._buffer = CORBA_sequence_CORBA_octet_allocbuf (icon_return->rgbaData._maximum);
sp = gdk_pixbuf_get_pixels (pixbuf);
dp = icon_return->rgbaData._buffer;
for (i = 0; i < height; i ++) {
for (j = 0; j < total_width; j++)
*(dp ++) = sp[j];
sp += rowstride;
}
CORBA_sequence_set_release (& icon_return->rgbaData, TRUE);
}
/* Generate an AnimatedIcon from a NULL-terminated @pixbuf_array. */
static GNOME_Evolution_AnimatedIcon *
create_corba_animated_icon_from_pixbuf_array (GdkPixbuf **pixbuf_array)
{
GNOME_Evolution_AnimatedIcon *animated_icon;
GdkPixbuf **p;
int num_frames;
int i;
num_frames = 0;
for (p = pixbuf_array; *p != NULL; p++)
num_frames++;
if (num_frames == 0)
return NULL;
animated_icon = GNOME_Evolution_AnimatedIcon__alloc ();
animated_icon->_length = num_frames;
animated_icon->_maximum = num_frames;
animated_icon->_buffer = CORBA_sequence_GNOME_Evolution_Icon_allocbuf (animated_icon->_maximum);
for (i = 0; i < num_frames; i++)
create_icon_from_pixbuf (pixbuf_array[i], & animated_icon->_buffer[i]);
CORBA_sequence_set_release (animated_icon, TRUE);
return animated_icon;
}
static gboolean
corba_update_progress (EvolutionActivityClient *activity_client,
const char *information,
@ -350,7 +282,7 @@ evolution_activity_client_construct (EvolutionActivityClient *activity_client,
return FALSE;
}
corba_animated_icon = create_corba_animated_icon_from_pixbuf_array (animated_icon);
corba_animated_icon = e_new_corba_animated_icon_from_pixbuf_array (animated_icon);
GNOME_Evolution_Activity_operationStarted (activity_interface,
component_id,

View File

@ -44,6 +44,8 @@ char *evolution_debug_log;
static BonoboObjectClass *parent_class = NULL;
struct _EvolutionShellComponentClientPrivate {
char *id;
EvolutionShellComponentClientCallback callback;
void *callback_data;
@ -298,6 +300,8 @@ impl_destroy (GtkObject *object)
shell_component_client = EVOLUTION_SHELL_COMPONENT_CLIENT (object);
priv = shell_component_client->priv;
g_free (priv->id);
if (priv->callback != NULL)
dispatch_callback (shell_component_client, EVOLUTION_SHELL_COMPONENT_INTERRUPTED);
@ -347,6 +351,8 @@ init (EvolutionShellComponentClient *shell_component_client)
priv = g_new (EvolutionShellComponentClientPrivate, 1);
priv->id = NULL;
priv->listener_interface = CORBA_OBJECT_NIL;
priv->listener_servant = NULL;
@ -365,12 +371,18 @@ init (EvolutionShellComponentClient *shell_component_client)
void
evolution_shell_component_client_construct (EvolutionShellComponentClient *shell_component_client,
const char *id,
CORBA_Object corba_object)
{
EvolutionShellComponentClientPrivate *priv;
g_return_if_fail (shell_component_client != NULL);
g_return_if_fail (EVOLUTION_IS_SHELL_COMPONENT_CLIENT (shell_component_client));
g_return_if_fail (corba_object != CORBA_OBJECT_NIL);
priv = shell_component_client->priv;
priv->id = g_strdup (id);
bonobo_object_client_construct (BONOBO_OBJECT_CLIENT (shell_component_client),
corba_object);
}
@ -378,6 +390,7 @@ evolution_shell_component_client_construct (EvolutionShellComponentClient *shell
EvolutionShellComponentClient *
evolution_shell_component_client_new (const char *id)
{
EvolutionShellComponentClient *new;
CORBA_Environment ev;
CORBA_Object corba_object;
@ -392,12 +405,6 @@ evolution_shell_component_client_new (const char *id)
return NULL;
}
#if 0
ior = CORBA_ORB_object_to_string (bonobo_orb (), corba_object, &ev);
g_print ("--- %s %s\n", id, ior);
CORBA_free (ior);
#endif
CORBA_exception_free (&ev);
if (corba_object == CORBA_OBJECT_NIL) {
@ -406,22 +413,28 @@ evolution_shell_component_client_new (const char *id)
return NULL;
}
return evolution_shell_component_client_new_for_objref (corba_object);
}
EvolutionShellComponentClient *
evolution_shell_component_client_new_for_objref (const GNOME_Evolution_ShellComponent objref)
{
EvolutionShellComponentClient *new;
g_return_val_if_fail (objref != CORBA_OBJECT_NIL, NULL);
new = gtk_type_new (evolution_shell_component_client_get_type ());
evolution_shell_component_client_construct (new, objref);
evolution_shell_component_client_construct (new, id, corba_object);
return new;
}
/* Properties. */
const char *
evolution_shell_component_client_get_id (EvolutionShellComponentClient *shell_component_client)
{
EvolutionShellComponentClientPrivate *priv;
g_return_val_if_fail (shell_component_client != NULL, NULL);
g_return_val_if_fail (EVOLUTION_IS_SHELL_COMPONENT_CLIENT (shell_component_client), NULL);
priv = shell_component_client->priv;
return priv->id;
}
/* Querying DnD interfaces. */

View File

@ -61,11 +61,15 @@ typedef void (* EvolutionShellComponentClientCallback) (EvolutionShellComponentC
/* Construction. */
GtkType evolution_shell_component_client_get_type (void);
void evolution_shell_component_client_construct (EvolutionShellComponentClient *shell_component_client,
CORBA_Object corba_object);
EvolutionShellComponentClient *evolution_shell_component_client_new (const char *id);
EvolutionShellComponentClient *evolution_shell_component_client_new_for_objref (const GNOME_Evolution_ShellComponent objref);
GtkType evolution_shell_component_client_get_type (void);
void evolution_shell_component_client_construct (EvolutionShellComponentClient *shell_component_client,
const char *id,
CORBA_Object corba_object);
EvolutionShellComponentClient *evolution_shell_component_client_new (const char *id);
/* Properties. */
const char *evolution_shell_component_client_get_id (EvolutionShellComponentClient *shell_component_client);
/* Querying DnD interfaces. */

View File

@ -26,6 +26,8 @@
#include "evolution-shell-component.h"
#include "e-shell-corba-icon-utils.h"
#include <fcntl.h>
#include <glib.h>
@ -35,8 +37,6 @@
#include <gal/util/e-util.h>
#include "Evolution.h"
#define PING_DELAY 10000
@ -50,6 +50,7 @@ struct _UserCreatableItemType {
char *description;
char *menu_description;
char menu_shortcut;
GdkPixbuf *icon;
};
typedef struct _UserCreatableItemType UserCreatableItemType;
@ -93,7 +94,8 @@ static UserCreatableItemType *
user_creatable_item_type_new (const char *id,
const char *description,
const char *menu_description,
char menu_shortcut)
char menu_shortcut,
GdkPixbuf *icon)
{
UserCreatableItemType *type;
@ -103,6 +105,11 @@ user_creatable_item_type_new (const char *id,
type->menu_description = g_strdup (menu_description);
type->menu_shortcut = menu_shortcut;
if (icon == NULL)
type->icon = NULL;
else
type->icon = gdk_pixbuf_ref (icon);
return type;
}
@ -113,6 +120,9 @@ user_creatable_item_type_free (UserCreatableItemType *type)
g_free (type->description);
g_free (type->menu_description);
if (type->icon != NULL)
gdk_pixbuf_unref (type->icon);
g_free (type);
}
@ -350,6 +360,8 @@ impl__get_userCreatableItemTypes (PortableServer_Servant servant,
corba_type->description = CORBA_string_dup (type->description);
corba_type->menuDescription = CORBA_string_dup (type->menu_description);
corba_type->menuShortcut = type->menu_shortcut;
e_store_corba_icon_from_pixbuf (type->icon, & corba_type->icon);
}
CORBA_sequence_set_release (list, TRUE);
@ -978,7 +990,8 @@ evolution_shell_component_add_user_creatable_item (EvolutionShellComponent *she
const char *id,
const char *description,
const char *menu_description,
char menu_shortcut)
char menu_shortcut,
GdkPixbuf *icon)
{
EvolutionShellComponentPrivate *priv;
UserCreatableItemType *type;
@ -991,7 +1004,7 @@ evolution_shell_component_add_user_creatable_item (EvolutionShellComponent *she
priv = shell_component->priv;
type = user_creatable_item_type_new (id, description, menu_description, menu_shortcut);
type = user_creatable_item_type_new (id, description, menu_description, menu_shortcut, icon);
priv->user_creatable_item_types = g_slist_prepend (priv->user_creatable_item_types, type);
}

View File

@ -23,13 +23,15 @@
#ifndef EVOLUTION_SHELL_COMPONENT_H
#define EVOLUTION_SHELL_COMPONENT_H
#include <bonobo/bonobo-xobject.h>
#include <bonobo/bonobo-control.h>
#include "Evolution.h"
#include "evolution-shell-client.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <bonobo/bonobo-xobject.h>
#include <bonobo/bonobo-control.h>
#ifdef cplusplus
extern "C" {
#pragma }
@ -181,7 +183,8 @@ void evolution_shell_component_add_user_creatable_item (EvolutionShellComponen
const char *id,
const char *description,
const char *menu_description,
char menu_shortcut);
char menu_shortcut,
GdkPixbuf *icon);
const char *evolution_shell_component_result_to_string (EvolutionShellComponentResult result);

View File

@ -34,8 +34,8 @@ extern "C" {
#define EVOLUTION_TYPE_STORAGE_LISTENER (evolution_storage_listener_get_type ())
#define EVOLUTION_STORAGE_LISTENER(obj) (GTK_CHECK_CAST ((obj), EVOLUTION_TYPE_STORAGE_LISTENER, EvolutionStorageListener))
#define EVOLUTION_STORAGE_LISTENER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), EVOLUTION_TYPE_STORAGE_LISTENER, EvolutionStorageListenerClass))
#define EVOLUTION_IS_STORAGE_LISTENER(obj) (GTK_CHECK_TYPE ((obj), EVOLUTION_TYPE_STORAGE_LISTENER))
#define EVOLUTION_IS_STORAGE_LISTENER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), EVOLUTION_TYPE_STORAGE_LISTENER))
#define EVOLUTION_IS_STORAGE_LISTENER(obj) (GTK_CHECK_TYPE ((obj), EVOLUTION_TYPE_STORAGE_LISTENER))
#define EVOLUTION_IS_STORAGE_LISTENER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), EVOLUTION_TYPE_STORAGE_LISTENER))
typedef struct _EvolutionStorageListener EvolutionStorageListener;

View File

@ -312,8 +312,10 @@ register_component (void)
gtk_signal_connect (GTK_OBJECT (shell_component), "owner_unset",
GTK_SIGNAL_FUNC (owner_unset_callback), NULL);
evolution_shell_component_add_user_creatable_item (shell_component, "Stuff", "New Stuff", "New _Stuff", '\0');
evolution_shell_component_add_user_creatable_item (shell_component, "MoreStuff", "New More Stuff", "New _More Stuff", 'n');
evolution_shell_component_add_user_creatable_item (shell_component, "Stuff",
"New Stuff", "New _Stuff", '\0', NULL);
evolution_shell_component_add_user_creatable_item (shell_component, "MoreStuff",
"New More Stuff", "New _More Stuff", 'n', NULL);
gtk_signal_connect (GTK_OBJECT (shell_component), "user_create_new_item",
GTK_SIGNAL_FUNC (user_create_new_item_callback), NULL);

View File

@ -1,3 +1,24 @@
2002-01-23 Ettore Perazzoli <ettore@ximian.com>
* e-combo-button.c: Remove member `separator' from
`EComboButtonPrivate'. New members `icon', `label'.
(init): There shall be no separator no more. Init `icon' and
`label' to %NULL.
(e_combo_button_construct): Set no relief.
(e_combo_button_new): Don't get a @menu arg anymore.
(e_combo_button_construct): Likewise.
(e_combo_button_set_icon): New.
(e_combo_button_set_label): New.
(e_combo_button_set_menu): New.
(impl_clicked): New, overriding the "clicked" method for
GtkButton.
(class_init): Install.
(impl_button_release_event): Removed.
(class_init): No need to override ::release_event with this
anymore.
(impl_released): New, override for the GtkButton::released method.
(class_init): Install.
2002-01-04 Jeffrey Stedfast <fejj@ximian.com>
* e-charset-picker.c: Added iso-8859-8 (Hebrew; Visual) to the

View File

@ -26,7 +26,6 @@
#include "e-combo-button.h"
#include <gtk/gtkvseparator.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkmain.h>
@ -35,18 +34,14 @@
#include <gal/util/e-util.h>
enum {
ACTIVATE_DEFAULT,
LAST_SIGNAL
};
struct _EComboButtonPrivate {
GdkPixbuf *icon;
GtkWidget *icon_pixmap;
GtkWidget *label;
GtkWidget *arrow_pixmap;
GtkWidget *hbox;
GtkWidget *separator;
GtkWidget *label_hbox;
GtkMenu *menu;
@ -56,7 +51,7 @@ struct _EComboButtonPrivate {
#define SPACING 2
static char *arrow_xpm[] = {
static const char *arrow_xpm[] = {
"11 5 2 1",
" c none",
". c #000000000000",
@ -70,7 +65,82 @@ static char *arrow_xpm[] = {
#define PARENT_TYPE gtk_button_get_type ()
static GtkButtonClass *parent_class = NULL;
static guint combo_button_signals[LAST_SIGNAL] = { 0 };
enum {
ACTIVATE_DEFAULT,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
/* Utility functions. */
static GtkWidget *
create_pixmap_widget_from_pixbuf (GdkPixbuf *pixbuf)
{
GtkWidget *pixmap_widget;
GdkPixmap *pixmap;
GdkBitmap *mask;
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &mask, 128);
pixmap_widget = gtk_pixmap_new (pixmap, mask);
gdk_pixmap_unref (pixmap);
gdk_bitmap_unref (mask);
return pixmap_widget;
}
static GtkWidget *
create_empty_pixmap_widget (void)
{
GtkWidget *pixmap_widget;
GdkPixbuf *pixbuf;
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 1, 1);
pixmap_widget = create_pixmap_widget_from_pixbuf (pixbuf);
gdk_pixbuf_unref (pixbuf);
return pixmap_widget;
}
static GtkWidget *
create_arrow_pixmap_widget (void)
{
GtkWidget *pixmap_widget;
GdkPixbuf *pixbuf;
pixbuf = gdk_pixbuf_new_from_xpm_data (arrow_xpm);
pixmap_widget = create_pixmap_widget_from_pixbuf (pixbuf);
gdk_pixbuf_unref (pixbuf);
return pixmap_widget;
}
static void
set_icon (EComboButton *combo_button,
GdkPixbuf *pixbuf)
{
EComboButtonPrivate *priv;
GdkPixmap *pixmap;
GdkBitmap *mask;
priv = combo_button->priv;
priv->icon = gdk_pixbuf_ref (pixbuf);
gdk_pixbuf_render_pixmap_and_mask (pixbuf, &pixmap, &mask, 128);
gtk_pixmap_set (GTK_PIXMAP (priv->icon_pixmap), pixmap, mask);
gdk_pixmap_unref (pixmap);
gdk_pixmap_unref (mask);
}
/* Callbacks for the associated menu. */
@ -140,6 +210,11 @@ impl_destroy (GtkObject *object)
priv->arrow_pixmap = NULL;
}
if (priv->icon != NULL) {
gdk_pixbuf_unref (priv->icon);
priv->icon = NULL;
}
g_free (priv);
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
@ -148,48 +223,6 @@ impl_destroy (GtkObject *object)
/* GtkWidget methods. */
static void
impl_realize (GtkWidget *widget)
{
EComboButton *combo_button;
EComboButtonPrivate *priv;
GdkPixmap *arrow_gdk_pixmap;
GdkBitmap *arrow_gdk_mask;
combo_button = E_COMBO_BUTTON (widget);
priv = combo_button->priv;
(* GTK_WIDGET_CLASS (parent_class)->realize) (widget);
g_assert (priv->arrow_pixmap == NULL);
arrow_gdk_pixmap = gdk_pixmap_create_from_xpm_d (widget->window, &arrow_gdk_mask, NULL, arrow_xpm);
priv->arrow_pixmap = gtk_pixmap_new (arrow_gdk_pixmap, arrow_gdk_mask);
gtk_widget_show (priv->arrow_pixmap);
gtk_box_pack_start (GTK_BOX (priv->hbox), priv->arrow_pixmap, FALSE, TRUE, SPACING);
gdk_pixmap_unref (arrow_gdk_pixmap);
gdk_bitmap_unref (arrow_gdk_mask);
}
static void
impl_unrealize (GtkWidget *widget)
{
EComboButton *combo_button;
EComboButtonPrivate *priv;
combo_button = E_COMBO_BUTTON (widget);
priv = combo_button->priv;
(* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
if (priv->arrow_pixmap != NULL) {
gtk_widget_destroy (priv->arrow_pixmap);
priv->arrow_pixmap = NULL;
}
}
static int
impl_button_press_event (GtkWidget *widget,
GdkEventButton *event)
@ -203,7 +236,7 @@ impl_button_press_event (GtkWidget *widget,
if (event->type == GDK_BUTTON_PRESS && event->button == 1) {
GTK_BUTTON (widget)->button_down = TRUE;
if (event->x >= priv->separator->allocation.x) {
if (event->x >= priv->arrow_pixmap->allocation.x) {
/* User clicked on the right side: pop up the menu. */
gtk_button_pressed (GTK_BUTTON (widget));
@ -222,18 +255,6 @@ impl_button_press_event (GtkWidget *widget,
return TRUE;
}
static int
impl_button_release_event (GtkWidget *widget,
GdkEventButton *event)
{
if (event->button == 1) {
gtk_grab_remove (widget);
gtk_button_released (GTK_BUTTON (widget));
}
return TRUE;
}
static int
impl_leave_notify_event (GtkWidget *widget,
GdkEventCrossing *event)
@ -254,39 +275,78 @@ impl_leave_notify_event (GtkWidget *widget,
return FALSE;
}
/* GtkButton methods. */
static void
impl_released (GtkButton *button)
{
EComboButton *combo_button;
EComboButtonPrivate *priv;
combo_button = E_COMBO_BUTTON (button);
priv = combo_button->priv;
/* Massive cut & paste from GtkButton here... The only change in
behavior here is that we want to emit ::activate_default when not
the menu hasn't been popped up. */
if (button->button_down) {
int new_state;
button->button_down = FALSE;
if (button->in_button) {
gtk_button_clicked (button);
if (! priv->menu_popped_up)
gtk_signal_emit (GTK_OBJECT (button), signals[ACTIVATE_DEFAULT]);
}
new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);
if (GTK_WIDGET_STATE (button) != new_state) {
gtk_widget_set_state (GTK_WIDGET (button), new_state);
/* We _draw () instead of queue_draw so that if the
operation blocks, the label doesn't vanish. */
gtk_widget_draw (GTK_WIDGET (button), NULL);
}
}
}
static void
class_init (GtkObjectClass *object_class)
{
GtkWidgetClass *widget_class;
GtkButtonClass *button_class;
parent_class = gtk_type_class (PARENT_TYPE);
object_class->destroy = impl_destroy;
widget_class = GTK_WIDGET_CLASS (object_class);
widget_class->realize = impl_realize;
widget_class->unrealize = impl_unrealize;
widget_class->button_press_event = impl_button_press_event;
widget_class->button_release_event = impl_button_release_event;
widget_class->leave_notify_event = impl_leave_notify_event;
widget_class->button_press_event = impl_button_press_event;
widget_class->leave_notify_event = impl_leave_notify_event;
combo_button_signals[ACTIVATE_DEFAULT] =
gtk_signal_new ("activate_default",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (EComboButtonClass, activate_default),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
button_class = GTK_BUTTON_CLASS (object_class);
button_class->released = impl_released;
gtk_object_class_add_signals (object_class, combo_button_signals, LAST_SIGNAL);
signals[ACTIVATE_DEFAULT] = gtk_signal_new ("activate_default",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (EComboButtonClass, activate_default),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
}
static void
init (EComboButton *combo_button)
{
EComboButtonPrivate *priv;
GtkWidget *label;
priv = g_new (EComboButtonPrivate, 1);
combo_button->priv = priv;
@ -295,27 +355,84 @@ init (EComboButton *combo_button)
gtk_container_add (GTK_CONTAINER (combo_button), priv->hbox);
gtk_widget_show (priv->hbox);
priv->label_hbox = gtk_hbox_new (FALSE, SPACING);
gtk_box_pack_start (GTK_BOX (priv->hbox), priv->label_hbox, TRUE, TRUE, 0);
gtk_widget_show (priv->label_hbox);
priv->icon_pixmap = create_empty_pixmap_widget ();
gtk_box_pack_start (GTK_BOX (priv->hbox), priv->icon_pixmap, TRUE, TRUE, 0);
gtk_widget_show (priv->icon_pixmap);
priv->separator = gtk_vseparator_new ();
gtk_box_pack_start (GTK_BOX (priv->hbox), priv->separator, FALSE, TRUE, SPACING);
gtk_widget_show (priv->separator);
priv->label = gtk_label_new ("");
gtk_box_pack_start (GTK_BOX (priv->hbox), priv->label, TRUE, TRUE, 0);
gtk_widget_show (priv->label);
label = gtk_label_new ("TEST!!!");
gtk_container_add (GTK_CONTAINER (priv->label_hbox), label);
gtk_widget_show (label);
priv->arrow_pixmap = create_arrow_pixmap_widget ();
gtk_box_pack_start (GTK_BOX (priv->hbox), priv->arrow_pixmap, TRUE, TRUE, 0);
gtk_widget_show (priv->arrow_pixmap);
priv->arrow_pixmap = NULL;
priv->icon = NULL;
priv->menu = NULL;
priv->menu_popped_up = FALSE;
}
void
e_combo_button_construct (EComboButton *combo_button,
GtkMenu *menu)
e_combo_button_construct (EComboButton *combo_button)
{
EComboButtonPrivate *priv;
g_return_if_fail (combo_button != NULL);
g_return_if_fail (E_IS_COMBO_BUTTON (combo_button));
priv = combo_button->priv;
g_return_if_fail (priv->menu == NULL);
GTK_WIDGET_UNSET_FLAGS (combo_button, GTK_CAN_FOCUS);
gtk_button_set_relief (GTK_BUTTON (combo_button), GTK_RELIEF_NONE);
}
GtkWidget *
e_combo_button_new (void)
{
EComboButton *new;
new = gtk_type_new (e_combo_button_get_type ());
e_combo_button_construct (new);
return GTK_WIDGET (new);
}
void
e_combo_button_set_icon (EComboButton *combo_button,
GdkPixbuf *pixbuf)
{
g_return_if_fail (combo_button != NULL);
g_return_if_fail (E_IS_COMBO_BUTTON (combo_button));
g_return_if_fail (pixbuf != NULL);
set_icon (combo_button, pixbuf);
}
void
e_combo_button_set_label (EComboButton *combo_button,
const char *label)
{
EComboButtonPrivate *priv;
g_return_if_fail (combo_button != NULL);
g_return_if_fail (E_IS_COMBO_BUTTON (combo_button));
g_return_if_fail (label != NULL);
priv = combo_button->priv;
if (label == NULL)
label = "";
gtk_label_parse_uline (GTK_LABEL (priv->label), label);
}
void
e_combo_button_set_menu (EComboButton *combo_button,
GtkMenu *menu)
{
EComboButtonPrivate *priv;
@ -325,28 +442,19 @@ e_combo_button_construct (EComboButton *combo_button,
g_return_if_fail (GTK_IS_MENU (menu));
priv = combo_button->priv;
g_return_if_fail (priv->menu == NULL);
if (priv->menu != NULL)
gtk_menu_detach (priv->menu);
priv->menu = menu;
if (menu == NULL)
return;
gtk_menu_attach_to_widget (menu, GTK_WIDGET (combo_button), menu_detacher);
gtk_signal_connect (GTK_OBJECT (menu), "deactivate",
GTK_SIGNAL_FUNC (menu_deactivate_callback),
combo_button);
GTK_WIDGET_UNSET_FLAGS (combo_button, GTK_CAN_FOCUS);
}
GtkWidget *
e_combo_button_new (GtkMenu *menu)
{
GtkWidget *new;
new = gtk_type_new (e_combo_button_get_type ());
e_combo_button_construct (E_COMBO_BUTTON (new), menu);
return new;
}

View File

@ -30,6 +30,8 @@
#include <gtk/gtkbutton.h>
#include <gtk/gtkmenu.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#ifdef __cplusplus
extern "C" {
#pragma }
@ -60,10 +62,16 @@ struct _EComboButtonClass {
};
GtkType e_combo_button_get_type (void);
void e_combo_button_construct (EComboButton *combo_button,
GtkType e_combo_button_get_type (void);
void e_combo_button_construct (EComboButton *combo_button);
GtkWidget *e_combo_button_new (void);
void e_combo_button_set_icon (EComboButton *combo_button,
GdkPixbuf *pixbuf);
void e_combo_button_set_label (EComboButton *combo_button,
const char *label);
void e_combo_button_set_menu (EComboButton *combo_button,
GtkMenu *menu);
GtkWidget *e_combo_button_new (GtkMenu *menu);
#ifdef __cplusplus
}