ekiga r6897 - in trunk: . lib/engine/gui/gtk-frontend lib/gui
- From: jschamp svn gnome org
- To: svn-commits-list gnome org
- Subject: ekiga r6897 - in trunk: . lib/engine/gui/gtk-frontend lib/gui
- Date: Tue, 9 Sep 2008 19:13:58 +0000 (UTC)
Author: jschamp
Date: Tue Sep 9 19:13:57 2008
New Revision: 6897
URL: http://svn.gnome.org/viewvc/ekiga?rev=6897&view=rev
Log:
Use a C99 capable compiler, add a new button type to select a smiley in the chat area.
Added:
trunk/lib/gui/gm-smiley-chooser-button.c
trunk/lib/gui/gm-smiley-chooser-button.h
Modified:
trunk/configure.ac
trunk/lib/engine/gui/gtk-frontend/chat-area.cpp
trunk/lib/gui/Makefile.am
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Tue Sep 9 19:13:57 2008
@@ -39,7 +39,7 @@
AM_PROG_LIBTOOL
-AC_PROG_CC
+AC_PROG_CC_C99
AC_PROG_CXX
AC_ISC_POSIX
AC_HEADER_STDC
Modified: trunk/lib/engine/gui/gtk-frontend/chat-area.cpp
==============================================================================
--- trunk/lib/engine/gui/gtk-frontend/chat-area.cpp (original)
+++ trunk/lib/engine/gui/gtk-frontend/chat-area.cpp Tue Sep 9 19:13:57 2008
@@ -43,6 +43,7 @@
#include "gm-text-anchored-tag.h"
#include "gm-text-smiley.h"
#include "gm-text-extlink.h"
+#include "gm-smiley-chooser-button.h"
#include "gm-smileys.h"
#include "toolbox/toolbox.h"
@@ -142,11 +143,9 @@
GtkTextIter* iter,
gpointer data);
-static void on_smiley_activated (GtkMenuItem *item,
- gpointer data);
-
-static void on_smiley_clicked (GtkButton* button,
- gpointer data);
+static void on_smiley_selected (GmSmileyChooserButton*,
+ gpointer,
+ gpointer);
static void on_font_changed (GtkButton* button,
gpointer data);
@@ -441,8 +440,9 @@
}
static void
-on_smiley_activated (GtkMenuItem *item,
- gpointer data)
+on_smiley_selected (G_GNUC_UNUSED GmSmileyChooserButton* smiley_chooser_button,
+ gpointer characters,
+ gpointer data)
{
const gchar* text = NULL;
ChatArea* self = NULL;
@@ -451,8 +451,7 @@
self = (ChatArea*)data;
- /* FIXME: that will break when gtk+ will change... */
- text = gtk_label_get_text (GTK_LABEL(GTK_BIN(GTK_MENU_ITEM (item))->child));
+ text = g_strdup ((gchar*) characters);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->priv->message));
gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
@@ -461,18 +460,6 @@
}
static void
-on_smiley_clicked (G_GNUC_UNUSED GtkButton* button,
- gpointer data)
-{
- ChatArea* self = NULL;
-
- self = (ChatArea*)data;
-
- gtk_menu_popup (GTK_MENU (self->priv->smiley_menu),
- NULL, NULL, NULL, NULL, 0, 0);
-}
-
-static void
on_font_changed (GtkButton* button,
gpointer data)
{
@@ -892,34 +879,8 @@
GtkWidget* vbox = NULL;
GtkWidget* bbox = NULL;
GtkWidget* button = NULL;
- const gchar** smileys = gm_get_smileys ();
- gint smiley;
- GdkPixbuf* pixbuf = NULL;
- GtkWidget* image = NULL;
- GtkWidget* smiley_item = NULL;
- GtkWidget* smiley_button = NULL;
-
- /* we need to build a nice menu for smileys */
- self->priv->smiley_menu = gtk_menu_new ();
- g_object_ref (self->priv->smiley_menu);
- for (smiley = 0;
- smileys[smiley] != NULL;
- smiley = smiley + 2) {
-
- smiley_item = gtk_image_menu_item_new_with_label (smileys[smiley]);
- pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
- smileys[smiley + 1], 16,
- (GtkIconLookupFlags)0, NULL);
- image = gtk_image_new_from_pixbuf (pixbuf);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (smiley_item),
- image);
- gtk_widget_show_all (smiley_item);
- gtk_menu_shell_append (GTK_MENU_SHELL (self->priv->smiley_menu),
- smiley_item);
-
- g_signal_connect (G_OBJECT (smiley_item), "activate",
- G_CALLBACK (on_smiley_activated), self);
- }
+ GtkWidget* smiley_button;
+ GtkWidget* smiley_chooser_button = NULL;
frame = gtk_frame_new (NULL);
vbox = gtk_vbox_new (FALSE, 2);
@@ -938,16 +899,17 @@
FALSE, FALSE, 2);
gtk_widget_show (bbox);
- button = gtk_button_new_with_mnemonic (_("_Smile..."));
- gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
smiley_button = gtk_image_new_from_icon_name ("face-smile", GTK_ICON_SIZE_BUTTON);
- gtk_button_set_image (GTK_BUTTON(button), smiley_button);
- gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
- g_signal_connect (G_OBJECT (button), "clicked",
- G_CALLBACK (on_smiley_clicked), self);
- gtk_box_pack_start (GTK_BOX (bbox), button,
+
+ smiley_chooser_button = gm_smiley_chooser_button_new ();
+ gtk_button_set_label (GTK_BUTTON(smiley_chooser_button), _("Smile..."));
+ gtk_button_set_image (GTK_BUTTON(smiley_chooser_button), smiley_button);
+ gtk_button_set_relief (GTK_BUTTON(smiley_chooser_button), GTK_RELIEF_NONE);
+ gtk_button_set_focus_on_click (GTK_BUTTON (smiley_chooser_button), FALSE);
+ g_signal_connect (G_OBJECT (smiley_chooser_button), "smiley_selected",
+ G_CALLBACK (on_smiley_selected), self);
+ gtk_box_pack_start (GTK_BOX (bbox), smiley_chooser_button,
FALSE, TRUE, 2);
- gtk_widget_show (button);
/* the BOLD button */
button = gtk_button_new_from_stock (GTK_STOCK_BOLD);
Modified: trunk/lib/gui/Makefile.am
==============================================================================
--- trunk/lib/gui/Makefile.am (original)
+++ trunk/lib/gui/Makefile.am Tue Sep 9 19:13:57 2008
@@ -42,7 +42,9 @@
gm-text-extlink.c \
gm-text-extlink.h \
gm-text-buffer-enhancer.c \
- gm-text-buffer-enhancer.h
+ gm-text-buffer-enhancer.h \
+ gm-smiley-chooser-button.c \
+ gm-smiley-chooser-button.h
if !WIN32
@@ -76,7 +78,7 @@
endif
AM_CXXFLAGS = $(GTK_CFLAGS) $(GLIB_CFLAGS) $(OPAL_CFLAGS) $(PTLIB_CFLAGS) $(XV_CFLAGS) $(DX_CFLAGS) $(SIGC_CFLAGS) -I ../../lib/engine/protocol/skel/ -I ../../lib/engine/framework/
-AM_CFLAGS = $(GTK_CFLAGS) $(GLIB_CFLAGS) $(GNOME_CFLAGS)
+AM_CFLAGS = $(GTK_CFLAGS) $(GLIB_CFLAGS) $(GNOME_CFLAGS)
AM_LIBS = $(GTK_LIBS) $(GLIB_LIBS) $(OPAL_LIBS) $(PTLIB_LIBS) $(XV_LIBS) $(DX_LIBS) $(GNOME_LIBS) $(SIGC_LIBS)
libgmwidgets_la_LDFLAGS = -export-dynamic
Added: trunk/lib/gui/gm-smiley-chooser-button.c
==============================================================================
--- (empty file)
+++ trunk/lib/gui/gm-smiley-chooser-button.c Tue Sep 9 19:13:57 2008
@@ -0,0 +1,806 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ * gm-smiley-chooser-button.c - description
+ * ------------------------------------------
+ * begin : August 2008 by Jan Schampera
+ * copyright : (C) 2008 by Jan Schampera
+ * description : Implementation of a popup window to choose a smiley
+ *
+ */
+
+/*
+ * Thanks to (alphabetical):
+ * Alphonso, Fabrice
+ * Defais, Yannick
+ * Puydt, Julien
+ * Sandras, Damien
+ */
+
+/* #include "config.h" */
+#define _(x) x
+
+#include "gm-smiley-chooser-button.h"
+#include "gm-smileys.h"
+
+#include <math.h>
+
+enum {
+ SIG_SMILEY_SELECTED,
+ SIG_LAST
+};
+
+/* these are used for readability */
+enum {
+ HANDLER_CONFIGURE,
+ HANDLER_SCREEN_CHANGED,
+ HANDLER_HIDE,
+ HANDLER_DELETE_EVENT,
+ HANDLER_NUM
+};
+
+static guint signals[SIG_LAST] = { 0 };
+
+struct _GmSmileyChooserButtonPrivate {
+ gulong toplevel_window_handler[HANDLER_NUM];
+ gchar** smiley_set;
+
+ gboolean popped_up;
+
+ GtkWidget* popup_window;
+ GtkWidget* frame;
+ GtkWidget* table;
+};
+
+/* a permanent pointer to the parent class,
+ * saves typing and hassle.
+ * set in gm_smiley_chooser_button_class_init()
+ */
+static GObjectClass *parent_class = NULL;
+
+/* Prototyping of the internal API */
+
+/* GObjecting */
+static void gm_smiley_chooser_button_class_init (gpointer,
+ gpointer);
+
+static void gm_smiley_chooser_button_init (GTypeInstance*,
+ gpointer);
+
+static void gm_smiley_chooser_button_dispose (GObject*);
+
+static void gm_smiley_chooser_button_finalize (GObject*);
+
+/* internal callbacks */
+
+static void on_smiley_chooser_button_toggled (GtkToggleButton*,
+ gpointer);
+
+static void on_button_hierarchy_changed (GtkWidget*,
+ GtkWidget*,
+ gpointer);
+
+static gboolean on_toplevel_configure_event (GtkWidget*,
+ GdkEventConfigure*,
+ gpointer);
+
+static void on_toplevel_screen_changed (GtkWidget*,
+ GdkScreen*,
+ gpointer);
+
+static void on_toplevel_hide (GtkWidget*,
+ gpointer);
+
+static gboolean on_toplevel_delete_event (GtkWidget*,
+ GdkEvent*,
+ gpointer);
+
+static void on_smiley_image_clicked (GtkButton*,
+ gpointer);
+
+static gboolean on_popup_button_press_event (GtkWidget*,
+ GdkEventButton*,
+ gpointer);
+
+
+/* real internal API */
+static void gm_smiley_chooser_button_reposition_popup (GmSmileyChooserButton*,
+ gint,
+ gint);
+
+static void gm_smiley_chooser_button_set_smiley_set (GmSmileyChooserButton*,
+ const gchar**);
+
+static void gm_smiley_chooser_button_reload_smiley_set (GmSmileyChooserButton*);
+
+static void gm_smiley_chooser_button_destroy_view (GmSmileyChooserButton*);
+
+static void gm_smiley_chooser_build_view (GmSmileyChooserButton*);
+
+static void gm_smiley_chooser_button_popup (GmSmileyChooserButton*);
+
+static void gm_smiley_chooser_button_popdown (GmSmileyChooserButton*);
+
+
+/* Implementation of the internal API */
+
+static void
+gm_smiley_chooser_button_class_init (gpointer g_class,
+ G_GNUC_UNUSED gpointer class_data)
+{
+ GObjectClass* gobject_class = NULL;
+ GtkWidgetClass* widget_class = NULL;
+
+ parent_class = (GObjectClass *) g_type_class_peek_parent (g_class);
+ g_type_class_add_private (g_class, sizeof (GmSmileyChooserButtonPrivate));
+
+ gobject_class = (GObjectClass*) g_class;
+ widget_class = GTK_WIDGET_CLASS (g_class);
+
+ gobject_class->dispose = gm_smiley_chooser_button_dispose;
+ gobject_class->finalize = gm_smiley_chooser_button_finalize;
+
+ /* the "smiley_selected" signal */
+ signals[SIG_SMILEY_SELECTED] =
+ g_signal_new ("smiley_selected",
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GmSmileyChooserButtonClass, smiley_selected),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+}
+
+static void
+gm_smiley_chooser_button_init (GTypeInstance* instance,
+ G_GNUC_UNUSED gpointer g_class)
+{
+ GmSmileyChooserButton* self = NULL;
+ GmSmileyChooserButtonPrivate* priv = NULL;
+
+ self = (GM_SMILEY_CHOOSER_BUTTON (instance));
+
+ self->priv = g_new (GmSmileyChooserButtonPrivate, 1);
+ priv = self->priv;
+
+ priv->popped_up = FALSE;
+ priv->toplevel_window_handler[HANDLER_CONFIGURE] = 0;
+ priv->toplevel_window_handler[HANDLER_SCREEN_CHANGED] = 0;
+ priv->toplevel_window_handler[HANDLER_HIDE] = 0;
+ priv->toplevel_window_handler[HANDLER_DELETE_EVENT] = 0;
+ priv->smiley_set = NULL;
+ priv->popup_window = NULL;
+ priv->frame = NULL;
+ priv->table = NULL;
+
+ g_signal_connect (G_OBJECT (self), "toggled",
+ G_CALLBACK (on_smiley_chooser_button_toggled), NULL);
+}
+
+static void
+gm_smiley_chooser_button_dispose (GObject* object)
+{
+ GmSmileyChooserButton* self = NULL;
+ GmSmileyChooserButtonPrivate* priv = NULL;
+
+ self = GM_SMILEY_CHOOSER_BUTTON (object);
+ priv = self->priv;
+
+ if (priv->popped_up)
+ gm_smiley_chooser_button_popdown (self);
+
+ gm_smiley_chooser_button_destroy_view (self);
+}
+
+static void
+gm_smiley_chooser_button_finalize (GObject* object)
+{
+ GmSmileyChooserButton* self = NULL;
+ GmSmileyChooserButtonPrivate* priv = NULL;
+
+ self = GM_SMILEY_CHOOSER_BUTTON (object);
+ priv = self->priv;
+
+ if (priv->smiley_set)
+ {
+ g_strfreev (priv->smiley_set);
+ priv->smiley_set = NULL;
+ }
+}
+
+/* internal callbacks */
+
+static void on_smiley_chooser_button_toggled (GtkToggleButton* toggle_button,
+ G_GNUC_UNUSED gpointer data)
+{
+ GmSmileyChooserButton* self = NULL;
+
+ self = GM_SMILEY_CHOOSER_BUTTON (toggle_button);
+ g_return_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self));
+
+ if (gtk_toggle_button_get_active (toggle_button))
+ {
+ /* popup */
+ gm_smiley_chooser_button_popup (self);
+ }
+ else
+ {
+ /* popdown */
+ gm_smiley_chooser_button_popdown (self);
+ }
+}
+
+static void
+on_button_hierarchy_changed (GtkWidget* widget,
+ GtkWidget* old_toplevel,
+ gpointer data)
+{
+ GmSmileyChooserButton* self = NULL;
+ GmSmileyChooserButtonPrivate* priv = NULL;
+ GtkWidget* new_toplevel = NULL;
+
+ g_return_if_fail (data != NULL);
+ self = GM_SMILEY_CHOOSER_BUTTON (data);
+ g_return_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self));
+
+ priv = self->priv;
+
+ if (old_toplevel &&
+ priv->toplevel_window_handler[HANDLER_CONFIGURE])
+ {
+ g_signal_handler_disconnect (G_OBJECT (old_toplevel),
+ priv->toplevel_window_handler[HANDLER_CONFIGURE]);
+ priv->toplevel_window_handler[HANDLER_CONFIGURE] = 0;
+ }
+
+ if (old_toplevel &&
+ priv->toplevel_window_handler[HANDLER_SCREEN_CHANGED])
+ {
+ g_signal_handler_disconnect (G_OBJECT (old_toplevel),
+ priv->toplevel_window_handler[HANDLER_SCREEN_CHANGED]);
+ priv->toplevel_window_handler[HANDLER_SCREEN_CHANGED] = 0;
+ }
+
+ if (old_toplevel &&
+ priv->toplevel_window_handler[HANDLER_HIDE])
+ {
+ g_signal_handler_disconnect (G_OBJECT (old_toplevel),
+ priv->toplevel_window_handler[HANDLER_HIDE]);
+ priv->toplevel_window_handler[HANDLER_HIDE] = 0;
+ }
+
+ if (old_toplevel &&
+ priv->toplevel_window_handler[HANDLER_DELETE_EVENT])
+ {
+ g_signal_handler_disconnect (G_OBJECT (old_toplevel),
+ priv->toplevel_window_handler[HANDLER_DELETE_EVENT]);
+ priv->toplevel_window_handler[HANDLER_DELETE_EVENT] = 0;
+ }
+
+ if (old_toplevel)
+ {
+ gtk_window_set_transient_for (GTK_WINDOW (priv->popup_window), NULL);
+ g_object_unref (G_OBJECT (old_toplevel));
+ }
+
+ new_toplevel = gtk_widget_get_toplevel (widget);
+
+ if (new_toplevel &&
+ GTK_IS_WINDOW (new_toplevel))
+ {
+ g_object_ref_sink (G_OBJECT (new_toplevel));
+ priv->toplevel_window_handler[HANDLER_CONFIGURE] =
+ g_signal_connect (G_OBJECT (new_toplevel), "configure-event",
+ G_CALLBACK (on_toplevel_configure_event), self);
+ priv->toplevel_window_handler[HANDLER_SCREEN_CHANGED] =
+ g_signal_connect (G_OBJECT (new_toplevel), "screen-changed",
+ G_CALLBACK (on_toplevel_screen_changed), self);
+ priv->toplevel_window_handler[HANDLER_HIDE] =
+ g_signal_connect (G_OBJECT (new_toplevel), "hide",
+ G_CALLBACK (on_toplevel_hide), self);
+ priv->toplevel_window_handler[HANDLER_DELETE_EVENT] =
+ g_signal_connect (G_OBJECT (new_toplevel), "delete-event",
+ G_CALLBACK (on_toplevel_delete_event), self);
+ gtk_window_set_transient_for (GTK_WINDOW (priv->popup_window),
+ GTK_WINDOW (new_toplevel));
+ }
+}
+
+
+static gboolean
+on_toplevel_configure_event (G_GNUC_UNUSED GtkWidget* widget,
+ GdkEventConfigure* event,
+ gpointer data)
+{
+ GmSmileyChooserButton* self = NULL;
+
+ g_return_val_if_fail (data != NULL, FALSE);
+ self = GM_SMILEY_CHOOSER_BUTTON (data);
+ g_return_val_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self), FALSE);
+
+ /* reposition, if we show our popup */
+ if (self->priv->popped_up &&
+ event->type == GDK_CONFIGURE)
+ gm_smiley_chooser_button_reposition_popup (self,
+ event->x, event->y);
+
+ return FALSE;
+}
+
+static void on_toplevel_screen_changed (G_GNUC_UNUSED GtkWidget* widget,
+ G_GNUC_UNUSED GdkScreen* old_screen,
+ gpointer data)
+{
+ GmSmileyChooserButton* self = NULL;
+
+ g_return_if_fail (data != NULL);
+ self = GM_SMILEY_CHOOSER_BUTTON (data);
+ g_return_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self));
+
+ if (self->priv->popped_up)
+ {
+ gm_smiley_chooser_button_popdown (self);
+ gm_smiley_chooser_button_popup (self);
+ }
+}
+
+static void on_toplevel_hide (G_GNUC_UNUSED GtkWidget* window,
+ gpointer data)
+{
+ GmSmileyChooserButton* self = NULL;
+
+ g_return_if_fail (data != NULL);
+ self = GM_SMILEY_CHOOSER_BUTTON (data);
+ g_return_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self));
+
+ gm_smiley_chooser_button_popdown (self);
+}
+
+static gboolean on_toplevel_delete_event (G_GNUC_UNUSED GtkWidget* window,
+ G_GNUC_UNUSED GdkEvent* event,
+ gpointer data)
+{
+ GmSmileyChooserButton* self = NULL;
+ g_return_val_if_fail (data != NULL, FALSE);
+ self = GM_SMILEY_CHOOSER_BUTTON (data);
+ g_return_val_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self), FALSE);
+
+ gm_smiley_chooser_button_popdown (self);
+ /* FIXME - delete us! */
+
+ return FALSE;
+}
+
+static void on_smiley_image_clicked (GtkButton* button,
+ gpointer data)
+{
+ GmSmileyChooserButton* self = NULL;
+ gchar* smiley_characters = NULL;
+
+ g_return_if_fail (data != NULL);
+ self = GM_SMILEY_CHOOSER_BUTTON (data);
+ g_return_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self));
+
+ smiley_characters = (gchar*) g_object_get_data (G_OBJECT (button),
+ "smiley_characters");
+
+ gm_smiley_chooser_button_popdown (self);
+
+ g_signal_emit_by_name (self, "smiley_selected",
+ g_strdup (smiley_characters));
+}
+
+static gboolean on_popup_button_press_event (G_GNUC_UNUSED GtkWidget* widget,
+ GdkEventButton* event,
+ gpointer data)
+{
+ GmSmileyChooserButton* self = NULL;
+
+ g_return_val_if_fail (data != NULL, FALSE);
+ self = GM_SMILEY_CHOOSER_BUTTON (data);
+ g_return_val_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self), FALSE);
+
+ switch (event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ gm_smiley_chooser_button_popdown (self);
+ return FALSE;
+ break;
+ /* FIXME is that neccesary? Compiler warnings and so... */
+ case GDK_NOTHING:
+ case GDK_DELETE:
+ case GDK_DESTROY:
+ case GDK_EXPOSE:
+ case GDK_MOTION_NOTIFY:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ case GDK_KEY_PRESS:
+ case GDK_KEY_RELEASE:
+ case GDK_ENTER_NOTIFY:
+ case GDK_LEAVE_NOTIFY:
+ case GDK_FOCUS_CHANGE:
+ case GDK_CONFIGURE:
+ case GDK_MAP:
+ case GDK_UNMAP:
+ case GDK_PROPERTY_NOTIFY:
+ case GDK_SELECTION_CLEAR:
+ case GDK_SELECTION_REQUEST:
+ case GDK_SELECTION_NOTIFY:
+ case GDK_PROXIMITY_IN:
+ case GDK_PROXIMITY_OUT:
+ case GDK_DRAG_ENTER:
+ case GDK_DRAG_LEAVE:
+ case GDK_DRAG_MOTION:
+ case GDK_DRAG_STATUS:
+ case GDK_DROP_START:
+ case GDK_DROP_FINISHED:
+ case GDK_CLIENT_EVENT:
+ case GDK_VISIBILITY_NOTIFY:
+ case GDK_NO_EXPOSE:
+ case GDK_SCROLL:
+ case GDK_WINDOW_STATE:
+ case GDK_SETTING:
+ case GDK_OWNER_CHANGE:
+ case GDK_GRAB_BROKEN:
+ default:
+ return FALSE;
+ }
+
+ return FALSE;
+}
+
+
+/* real internal API */
+static void gm_smiley_chooser_button_reposition_popup (GmSmileyChooserButton* self,
+ gint ref_x,
+ gint ref_y)
+{
+ gint final_x = 0;
+ gint final_y = 0;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self));
+
+ /* return if nothing useful to do */
+ if (!self->priv->popped_up)
+ return;
+ if (!self->priv->popup_window)
+ return;
+
+ /* calculate the new position out of the button's
+ * and the smiley's sizes */
+ final_x = ref_x +
+ GTK_WIDGET (self)->allocation.x;
+ final_y = ref_y +
+ GTK_WIDGET (self)->allocation.y -
+ GTK_WIDGET (self->priv->popup_window)->allocation.height;
+
+ /* move its ass */
+ gtk_window_move (GTK_WINDOW (self->priv->popup_window),
+ final_x, final_y);
+}
+
+
+static void
+gm_smiley_chooser_button_set_smiley_set (GmSmileyChooserButton* self,
+ const gchar** smiley_set)
+{
+ GmSmileyChooserButtonPrivate* priv = NULL;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (smiley_set != NULL);
+ g_return_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self));
+
+ priv = self->priv;
+
+ if (priv->smiley_set)
+ g_strfreev (priv->smiley_set);
+
+ priv->smiley_set = g_strdupv ((gchar**) smiley_set);
+}
+
+
+static void
+gm_smiley_chooser_button_reload_smiley_set (GmSmileyChooserButton* self)
+{
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self));
+
+ /* nothing but kill and rebuild our view */
+ gm_smiley_chooser_button_destroy_view (self);
+ gm_smiley_chooser_build_view (self);
+}
+
+static void
+gm_smiley_chooser_button_popup (GmSmileyChooserButton* self)
+{
+ GmSmileyChooserButtonPrivate* priv = NULL;
+ gint my_x = 0;
+ gint my_y = 0;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self));
+
+ priv = self->priv;
+
+ /* get my position data and position the popup */
+ (void) gdk_window_get_origin (GTK_WIDGET (self)->window,
+ &my_x, &my_y);
+
+ gtk_window_move (GTK_WINDOW (priv->popup_window),
+ my_x, my_y);
+
+ gtk_widget_show_all (priv->popup_window);
+ gtk_window_present (GTK_WINDOW (priv->popup_window));
+
+ priv->popped_up = TRUE;
+
+ gm_smiley_chooser_button_reposition_popup (self, my_x, my_y);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self), TRUE);
+}
+
+static void
+gm_smiley_chooser_button_popdown (GmSmileyChooserButton* self)
+{
+ GmSmileyChooserButtonPrivate* priv = NULL;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self));
+
+ priv = self->priv;
+
+ gtk_widget_hide_all (GTK_WIDGET (priv->popup_window));
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self), FALSE);
+
+ priv->popped_up = FALSE;
+}
+
+static void
+gm_smiley_chooser_button_destroy_view (GmSmileyChooserButton* self)
+{
+ GmSmileyChooserButtonPrivate* priv = NULL;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self));
+
+ priv = self->priv;
+
+ if (priv->popped_up)
+ gm_smiley_chooser_button_popdown (self);
+
+ if (priv->table)
+ {
+ g_object_unref (G_OBJECT (priv->table));
+ gtk_widget_destroy (priv->table);
+ priv->table = NULL;
+ }
+
+ if (priv->frame)
+ {
+ g_object_unref (G_OBJECT (priv->frame));
+ gtk_widget_destroy (priv->frame);
+ priv->frame = NULL;
+ }
+
+ if (priv->popup_window)
+ {
+ g_object_unref (G_OBJECT (priv->popup_window));
+ gtk_widget_destroy (priv->popup_window);
+ priv->popup_window = NULL;
+ }
+}
+
+
+static void gm_smiley_chooser_build_view (GmSmileyChooserButton* self)
+{
+ GmSmileyChooserButtonPrivate* priv = NULL;
+
+ GtkWidget* button = NULL;
+ GtkWidget* image = NULL;
+ GdkPixbuf* pixbuf = NULL;
+
+ gchar** smiley_set = NULL;
+ const gfloat golden_ratio = 1.6180339887;
+ guint smiley = 0;
+ guint num_smileys = 0;
+
+ guint table_width = 0;
+ guint table_height = 0;
+ guint iter_x = 0;
+ guint iter_y = 0;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (GM_IS_SMILEY_CHOOSER_BUTTON (self));
+
+ priv = self->priv;
+
+ g_return_if_fail (priv->smiley_set != NULL);
+ smiley_set = priv->smiley_set;
+ g_return_if_fail (smiley_set[0] != NULL);
+
+ /* the popup window */
+ priv->popup_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_object_ref_sink (G_OBJECT (priv->popup_window));
+ g_signal_connect (G_OBJECT (priv->popup_window), "button-press-event",
+ G_CALLBACK (on_popup_button_press_event), self);
+ gtk_window_set_title (GTK_WINDOW (priv->popup_window), _("Smile!"));
+ gtk_window_set_type_hint (GTK_WINDOW (priv->popup_window),
+ GDK_WINDOW_TYPE_HINT_UTILITY);
+ gtk_window_set_skip_taskbar_hint (GTK_WINDOW (priv->popup_window), TRUE);
+ gtk_window_set_resizable (GTK_WINDOW (priv->popup_window), FALSE);
+ gtk_window_set_decorated (GTK_WINDOW (priv->popup_window), FALSE);
+
+ /* the frame */
+ priv->frame = gtk_frame_new (_("Smile!"));
+ g_object_ref_sink (G_OBJECT (priv->frame));
+
+ /* compute the number of available smileys */
+ for (smiley = 0;
+ smiley_set[smiley] != NULL;
+ smiley = smiley + 2) {}
+ num_smileys = smiley / 2;
+
+ /* calculate the dimensions out of the number of smileys */
+ /* FIXME calc the height/width of the table */
+ if (num_smileys == 1)
+ /* 1 smiley - special case, or fix the calculation below
+ * if possible */
+ table_width = table_height = 1;
+ else {
+ table_height = round (sqrt (num_smileys / golden_ratio));
+ table_width = ceil (sqrt (num_smileys / golden_ratio) * golden_ratio);
+ /* the following is needed to catch bordercases where the
+ * rounding/ceiling fails to quantize to the wanted value.
+ * No matter how you do the columns (round/ceil), you sometimes
+ * have either one row too much or too less - that's why */
+ if ( (table_height * table_width) < num_smileys)
+ {
+ if ( ((table_height + 1) * table_width) > (table_height * (table_width + 1)))
+ table_width++;
+ else
+ table_height++;
+ }
+ }
+
+ /* the table */
+ priv->table = gtk_table_new (table_height, table_width, TRUE);
+ g_object_ref (G_OBJECT (priv->table));
+
+ /* populate the table with the smiley buttons */
+ smiley = 0;
+ for (iter_y = 0;
+ iter_y < table_height && (smiley / 2) < num_smileys;
+ iter_y++) {
+ for (iter_x = 0;
+ iter_x < table_width && (smiley / 2) < num_smileys;
+ iter_x++) {
+ button = gtk_button_new ();
+ gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+ pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+ smiley_set[smiley + 1], 16,
+ (GtkIconLookupFlags)0, NULL);
+ image = gtk_image_new_from_pixbuf (pixbuf);
+ gtk_container_add (GTK_CONTAINER (button), image);
+ g_object_set_data_full (G_OBJECT (button),
+ "smiley_characters",
+ (gpointer) g_strdup (smiley_set[smiley]),
+ g_free);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (on_smiley_image_clicked), self);
+
+ gtk_table_attach_defaults (GTK_TABLE (priv->table),
+ button,
+ iter_x, iter_x + 1,
+ iter_y, iter_y + 1);
+ smiley += 2;
+ } /* for (iter_x) */
+ } /* for (iter_y) */
+
+ /* glue it all together */
+ gtk_container_add (GTK_CONTAINER (priv->popup_window), priv->frame);
+ gtk_container_add (GTK_CONTAINER (priv->frame), priv->table);
+ gtk_widget_show (priv->frame);
+ gtk_widget_show_all (priv->table);
+}
+
+
+/* Implementation of the public API */
+
+GType
+gm_smiley_chooser_button_get_type (void)
+{
+ static GType result = 0;
+
+ if (!result) {
+
+ static const GTypeInfo info = {
+ sizeof (GmSmileyChooserButtonClass),
+ NULL,
+ NULL,
+ gm_smiley_chooser_button_class_init,
+ NULL,
+ NULL,
+ sizeof (GmSmileyChooserButton),
+ 0,
+ gm_smiley_chooser_button_init,
+ NULL
+ };
+
+ result = g_type_register_static (GTK_TYPE_TOGGLE_BUTTON,
+ "GmSmileyChooserButton",
+ &info, (GTypeFlags) 0);
+ }
+
+ return result;
+}
+
+GtkWidget*
+gm_smiley_chooser_button_new (void)
+{
+ GmSmileyChooserButton* self = NULL;
+ GtkWidget* widget = NULL;
+
+ self =
+ (GmSmileyChooserButton*) g_object_new (GM_SMILEY_CHOOSER_BUTTON_TYPE, NULL);
+
+ /* if already possible (unlikely), initially set the toplevel reference */
+ widget = gtk_widget_get_toplevel (GTK_WIDGET (self));
+ if (widget &&
+ GTK_WIDGET_TOPLEVEL (widget) &&
+ GTK_IS_WINDOW (widget))
+ {
+ g_object_ref_sink (G_OBJECT (widget));
+ self->priv->toplevel_window_handler[HANDLER_CONFIGURE] =
+ g_signal_connect (G_OBJECT (widget), "configure-event",
+ G_CALLBACK (on_toplevel_configure_event), self);
+ self->priv->toplevel_window_handler[HANDLER_SCREEN_CHANGED] =
+ g_signal_connect (G_OBJECT (widget), "screen-changed",
+ G_CALLBACK (on_toplevel_screen_changed), self);
+ self->priv->toplevel_window_handler[HANDLER_HIDE] =
+ g_signal_connect (G_OBJECT (widget), "hide",
+ G_CALLBACK (on_toplevel_hide), self);
+ self->priv->toplevel_window_handler[HANDLER_DELETE_EVENT] =
+ g_signal_connect (G_OBJECT (widget), "delete-event",
+ G_CALLBACK (on_toplevel_delete_event), self);
+ }
+
+ g_signal_connect (G_OBJECT (self), "hierarchy-changed",
+ G_CALLBACK (on_button_hierarchy_changed), self);
+
+ gm_smiley_chooser_button_set_smiley_set (self, gm_get_smileys());
+ gm_smiley_chooser_button_reload_smiley_set (self);
+
+ return GTK_WIDGET (self);
+}
+
Added: trunk/lib/gui/gm-smiley-chooser-button.h
==============================================================================
--- (empty file)
+++ trunk/lib/gui/gm-smiley-chooser-button.h Tue Sep 9 19:13:57 2008
@@ -0,0 +1,101 @@
+
+/* Ekiga -- A VoIP and Video-Conferencing application
+ * Copyright (C) 2000-2008 Damien Sandras
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * Ekiga is licensed under the GPL license and as a special exception,
+ * you have permission to link or otherwise combine this program with the
+ * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
+ * without applying the requirements of the GNU GPL to the OPAL, OpenH323
+ * and PWLIB programs, as long as you do follow the requirements of the
+ * GNU GPL for all the rest of the software thus combined.
+ */
+
+
+/*
+ * gm-smiley-chooser-button.h - description
+ * ------------------------------------------
+ * begin : August 2008 by Jan Schampera
+ * copyright : (C) 2008 by Jan Schampera
+ * description : Declaration of a popup window to choose a smiley
+ *
+ */
+
+/*
+ * Thanks to (alphabetical):
+ * Alphonso, Fabrice
+ * Defais, Yannick
+ * Puydt, Julien
+ * Sandras, Damien
+ */
+
+#ifndef __GM_SMILEY_CHOOSER_BUTTON_H__
+#define __GM_SMILEY_CHOOSER_BUTTON_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GmSmileyChooserButton GmSmileyChooserButton;
+typedef struct _GmSmileyChooserButtonPrivate GmSmileyChooserButtonPrivate;
+typedef struct _GmSmileyChooserButtonClass GmSmileyChooserButtonClass;
+
+struct _GmSmileyChooserButton {
+ GtkToggleButton parent;
+
+ GmSmileyChooserButtonPrivate* priv;
+};
+
+struct _GmSmileyChooserButtonClass {
+ GtkToggleButtonClass parent;
+
+ /* the "smiley_selected" signal */
+ void (*smiley_selected) (GmSmileyChooserButton* self,
+ gpointer characters);
+};
+
+#define GM_SMILEY_CHOOSER_BUTTON_TYPE \
+ (gm_smiley_chooser_button_get_type ())
+#define GM_SMILEY_CHOOSER_BUTTON(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GM_SMILEY_CHOOSER_BUTTON_TYPE, GmSmileyChooserButton))
+#define GM_IS_SMILEY_CHOOSER_BUTTON(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GM_SMILEY_CHOOSER_BUTTON_TYPE))
+#define GM_SMILEY_CHOOSER_BUTTON_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GM_SMILEY_CHOOSER_BUTTON_TYPE, GmSmileyChooserButtonClass))
+#define GM_IS_SMILEY_CHOOSER_BUTTON_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GM_SMILEY_CHOOSER_BUTTON_TYPE))
+#define GM_SMILEY_CHOOSER_BUTTON_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GM_SMILEY_CHOOSER_BUTTON_TYPE, GmSmileyChooserButtonClass))
+
+
+/**
+ * The GTyping function for GmSmileyChooserButton
+ * @return The GType of the GmSmileyChooserButton
+ */
+GType gm_smiley_chooser_button_get_type (void);
+
+
+/**
+ * Create a new GmSmileyChooserButton
+ * @return a new GmSmileyChooserButton
+ */
+GtkWidget* gm_smiley_chooser_button_new (void);
+
+G_END_DECLS
+
+#endif /* __GM_SMILEY_CHOOSER_BUTTON_H__ */
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]