[Goodies-commits] r3789 - xfce4-places-plugin/trunk/panel-plugin

Diego Ongaro ongardie at xfce.org
Tue Jan 8 15:31:24 CET 2008


Author: ongardie
Date: 2008-01-08 14:31:23 +0000 (Tue, 08 Jan 2008)
New Revision: 3789

Added:
   xfce4-places-plugin/trunk/panel-plugin/button.c
   xfce4-places-plugin/trunk/panel-plugin/button.h
Log:
I left these out of the last commit, oops


Added: xfce4-places-plugin/trunk/panel-plugin/button.c
===================================================================
--- xfce4-places-plugin/trunk/panel-plugin/button.c	                        (rev 0)
+++ xfce4-places-plugin/trunk/panel-plugin/button.c	2008-01-08 14:31:23 UTC (rev 3789)
@@ -0,0 +1,497 @@
+/*  xfce4-places-plugin
+ *
+ *  Provides the widget that sits on the panel
+ *
+ *  Note that, while this extends GtkToggleButton, much of the gtk_button_*()
+ *  functions shouldn't be used.
+ *
+ *  Copyright (c) 2007-2008 Diego Ongaro <ongardie at gmail.com>
+ *  
+ *  Some code adapted from libxfce4panel for the togglebutton configuration
+ *    (xfce-panel-convenience.c)
+ *    Copyright (c) 2006-2007 Jasper Huijsmans <jasper at xfce.org>
+ *
+ *  Some code adapted from gtk+ for the properties
+ *    (gtkbutton.c)
+ *    Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *    Modified by the GTK+ Team and others 1997-2001
+ *
+ *  May also contain code adapted from:
+ *   - notes plugin
+ *     panel-plugin.c - (xfce4-panel plugin for temporary notes)
+ *     Copyright (c) 2006 Mike Massonnet <mmassonnet at gmail.com>
+ *
+ *   - xfdesktop menu plugin
+ *     desktop-menu-plugin.c - xfce4-panel plugin that displays the desktop menu
+ *     Copyright (C) 2004 Brian Tarricone, <bjt23 at cornell.edu>
+ *  
+ *   - launcher plugin
+ *     launcher.c - (xfce4-panel plugin that opens programs)
+ *     Copyright (c) 2005-2007 Jasper Huijsmans <jasper at xfce.org>
+ *     Copyright (c) 2006-2007 Nick Schermer <nick at xfce.org>
+ *
+ *  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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <libxfce4panel/xfce-panel-plugin.h>
+#include <libxfce4panel/xfce-hvbox.h>
+#include <string.h>
+
+#define EXO_API_SUBJECT_TO_CHANGE
+#include <exo/exo.h>
+
+#include "button.h"
+
+#define BOX_SPACING 4
+
+enum
+{
+    PROP_0,
+    PROP_PIXBUF_FACTORY,
+    PROP_LABEL
+};
+
+static void
+places_button_dispose(GObject*);
+
+static void
+places_button_resize(PlacesButton*);
+
+static void
+places_button_orientation_changed(XfcePanelPlugin*, GtkOrientation, PlacesButton*);
+
+static gboolean
+places_button_size_changed(XfcePanelPlugin*, gint size, PlacesButton*);
+
+static void
+places_button_theme_changed(PlacesButton*);
+
+G_DEFINE_TYPE(PlacesButton, places_button, GTK_TYPE_TOGGLE_BUTTON);
+
+void
+places_button_set_label(PlacesButton *self, const gchar *label)
+{
+    g_assert(PLACES_IS_BUTTON(self));
+
+    if (label == NULL && self->label_text == NULL)
+        return;
+
+    if (label != NULL && self->label_text != NULL &&
+        strcmp(label, self->label_text) == 0) {
+        return;
+    }
+
+    DBG("new label text: %s", label);
+
+    if (self->label_text != NULL)
+        g_free(self->label_text);
+    
+    self->label_text = g_strdup(label);
+
+    places_button_resize(self);
+}
+
+void
+places_button_set_pixbuf_factory(PlacesButton *self,
+                                 places_button_image_pixbuf_factory *factory)
+{
+    g_assert(PLACES_IS_BUTTON(self));
+
+    if (self->pixbuf_factory == factory)
+        return;
+
+    DBG("new pixbuf factory: %p", factory);
+    self->pixbuf_factory = factory;
+
+    places_button_resize(self);
+}
+
+static void
+places_button_set_property(GObject      *object,
+                           guint         property_id,
+                           const GValue *value,
+                           GParamSpec   *pspec)
+{
+    PlacesButton *self;
+
+    self = PLACES_BUTTON(object);
+
+    switch (property_id) {
+
+        case PROP_PIXBUF_FACTORY:
+            places_button_set_pixbuf_factory(self, g_value_get_pointer(value));
+            break;
+        case PROP_LABEL:
+            places_button_set_label(self, g_value_get_string(value));
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+            break;
+    }
+}
+
+places_button_image_pixbuf_factory*
+places_button_get_pixbuf_factory(PlacesButton *self)
+{
+    g_assert(PLACES_IS_BUTTON(self));
+
+    DBG("returning %p", self->pixbuf_factory);
+    return self->pixbuf_factory;
+}
+
+
+const gchar*
+places_button_get_label(PlacesButton *self)
+{
+    g_assert(PLACES_IS_BUTTON(self));
+
+    DBG("returning %s", self->label_text);
+    return self->label_text;
+}
+
+static void
+places_button_get_property(GObject      *object,
+                           guint         property_id,
+                           GValue       *value,
+                           GParamSpec   *pspec)
+{
+    PlacesButton *self;
+
+    self = PLACES_BUTTON(object);
+
+    switch (property_id) {
+
+        case PROP_PIXBUF_FACTORY:
+            g_value_set_pointer(value, places_button_get_pixbuf_factory(self));
+            break;
+
+        case PROP_LABEL:
+            g_value_set_string(value, places_button_get_label(self));
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+            break;
+    }
+}
+
+
+
+static void
+places_button_class_init(PlacesButtonClass *klass)
+{
+    GObjectClass *gobject_class;
+    
+    gobject_class = G_OBJECT_CLASS(klass);
+
+    gobject_class->dispose = places_button_dispose;
+  
+    gobject_class->set_property = places_button_set_property;
+    gobject_class->get_property = places_button_get_property;
+
+    g_object_class_install_property(gobject_class,
+        PROP_LABEL,
+        g_param_spec_string("label",
+            "Label",
+            "Button text",
+            NULL,
+            EXO_PARAM_READWRITE));
+
+    g_object_class_install_property(gobject_class,
+        PROP_PIXBUF_FACTORY,
+        g_param_spec_object("pixbuf-factory",
+            "Pixbuf factory",
+            "Factory to create icons for image to appear next to button text",
+            GTK_TYPE_WIDGET,
+            EXO_PARAM_READWRITE));
+}
+
+static void
+places_button_init(PlacesButton *self)
+{
+    self->plugin = NULL;
+    self->box = NULL;
+    self->label = NULL;
+    self->image = NULL;
+    self->plugin_size = -1;
+}
+
+static void
+places_button_construct(PlacesButton *self, XfcePanelPlugin *plugin)
+{
+    GtkOrientation orientation;
+
+    g_assert(XFCE_IS_PANEL_PLUGIN(plugin));
+
+    g_object_ref(plugin);
+    self->plugin = plugin;
+
+    /* from libxfce4panel */
+    GTK_WIDGET_UNSET_FLAGS(self, GTK_CAN_DEFAULT|GTK_CAN_FOCUS);
+    gtk_button_set_relief(GTK_BUTTON(self), GTK_RELIEF_NONE);
+    gtk_button_set_focus_on_click(GTK_BUTTON(self), FALSE);
+
+    orientation = xfce_panel_plugin_get_orientation(self->plugin);
+    self->box = xfce_hvbox_new(orientation, FALSE, BOX_SPACING);
+    gtk_container_set_border_width(GTK_CONTAINER(self->box), 0);
+    gtk_container_add(GTK_CONTAINER(self), self->box);
+    gtk_widget_show(self->box);
+
+    places_button_resize(self);
+
+    g_signal_connect(G_OBJECT(plugin), "orientation-changed",
+                     G_CALLBACK(places_button_orientation_changed), self);
+    g_signal_connect(G_OBJECT(plugin), "size-changed",
+                     G_CALLBACK(places_button_size_changed), self);
+
+    g_signal_connect(G_OBJECT(self), "style-set",
+                     G_CALLBACK(places_button_theme_changed), NULL);
+    g_signal_connect(G_OBJECT(self), "screen-changed",
+                     G_CALLBACK(places_button_theme_changed), NULL);
+
+}
+
+
+GtkWidget*
+places_button_new(XfcePanelPlugin *plugin)
+{
+    PlacesButton *button;
+
+    g_assert(XFCE_IS_PANEL_PLUGIN(plugin));
+
+    button = (PlacesButton*) g_object_new(PLACES_TYPE_BUTTON, NULL);
+    places_button_construct(button, plugin);
+
+    return (GtkWidget*) button;
+}
+
+static void
+places_button_dispose(GObject *object)
+{
+    PlacesButton *self = PLACES_BUTTON(object);
+
+    if (self->plugin != NULL) {
+        g_object_unref(self->plugin);
+        self->plugin = NULL;
+    }
+
+    (*G_OBJECT_CLASS(places_button_parent_class)->dispose) (object);
+}
+
+static void
+places_button_destroy_image(PlacesButton *self)
+{
+    if (self->image != NULL) {
+        gtk_widget_destroy(self->image);
+        g_object_unref(self->image);
+        self->image = NULL;
+    }
+}
+static void
+places_button_resize_image(PlacesButton *self, gint new_size, gint *width, gint *height)
+{
+    GdkPixbuf *icon;
+
+    *width = 0;
+    *height = 0;
+
+    if (self->pixbuf_factory == NULL) {
+        places_button_destroy_image(self);
+        return;
+    }
+
+    icon = self->pixbuf_factory(new_size);
+    
+    if (G_UNLIKELY(icon == NULL)) {
+        DBG("Could not load icon for button");
+        places_button_destroy_image(self);
+        return;
+    }
+
+    *width  = gdk_pixbuf_get_width(icon);
+    *height = gdk_pixbuf_get_height(icon);
+     
+    if (self->image == NULL) {
+            self->image = g_object_ref(gtk_image_new_from_pixbuf(icon));
+            gtk_box_pack_start_defaults(GTK_BOX(self->box), self->image);
+            gtk_widget_show(self->image);
+    }
+    else
+            gtk_image_set_from_pixbuf(GTK_IMAGE(self->image), icon);
+
+    g_object_unref(G_OBJECT(icon));
+}
+
+static void
+places_button_destroy_label(PlacesButton *self)
+{
+    if (self->label != NULL) {
+        gtk_widget_destroy(self->label);
+        g_object_unref(self->label);
+        self->label = NULL;
+    }
+}
+
+static void
+places_button_resize_label(PlacesButton *self, gint *width, gint *height)
+{
+    GtkRequisition req;
+
+    *width = 0;
+    *height = 0;
+
+    if (self->label_text == NULL) {
+        places_button_destroy_label(self);
+        return;
+    }
+
+    if (self->label == NULL) {
+        self->label = g_object_ref(gtk_label_new(self->label_text));
+        gtk_box_pack_end_defaults(GTK_BOX(self->box), 
+                                  self->label);
+        gtk_widget_show(self->label);
+    }
+    else
+        gtk_label_set_text(GTK_LABEL(self->label), self->label_text);
+
+
+    gtk_widget_size_request(self->label, &req);
+    *width = req.width;
+    *height = req.height;
+
+}
+
+
+static void
+places_button_resize(PlacesButton *self)
+{
+    gboolean show_image, show_label;
+    gint new_size, image_size;
+    GtkOrientation orientation;
+
+    gint total_width,  total_height;
+    gint image_width,  image_height;
+    gint label_width,  label_height;
+    gint button_width, button_height;
+    gint box_width,    box_height;
+
+    new_size = xfce_panel_plugin_get_size(self->plugin);
+    self->plugin_size = new_size;
+    DBG("Panel size: %d", new_size);
+    
+    orientation = xfce_panel_plugin_get_orientation(self->plugin);
+
+    show_image = self->pixbuf_factory != NULL;
+    show_label = self->label_text != NULL;
+
+    total_width  = 0;
+    total_height = 0;
+
+    /* these will be added into totals later */
+    button_width  = 2 + 2 * ((GtkWidget*) self)->style->xthickness;
+    button_height = 2 + 2 * ((GtkWidget*) self)->style->ythickness;
+    
+    /* image */
+    image_size = new_size - MAX(button_width, button_height);
+    /* TODO: could check if anything changed
+     * (though it's hard to know if the icon theme changed) */
+    places_button_resize_image(self,
+                               image_size,
+                               &image_width, &image_height);
+    show_image = self->image != NULL;
+    if (show_image) {
+        image_width  = MAX(image_width,  image_size);
+        image_height = MAX(image_height, image_size);
+        total_width  += image_width;
+        total_height += image_height;
+    }
+
+    /* label */
+    /* TODO: could check if anything changed */
+    places_button_resize_label(self,
+                               &label_width, &label_height);
+    show_label = self->label != NULL;
+
+    if (show_label) {
+        if (orientation == GTK_ORIENTATION_HORIZONTAL) {
+            total_width += label_width;
+            total_height = MAX(total_height, label_height);
+        }
+        else {
+            total_width = MAX(total_width, label_width);
+            total_height += label_height;
+        }
+    }
+
+    /* at this point, total width and height reflect just image and label */
+    /* now, add on the button and box overhead */
+    total_width  += button_width;
+    total_height += button_height;
+
+    box_width  = 0;
+    box_height = 0;
+    if (show_image && show_label) {
+    
+        if (orientation == GTK_ORIENTATION_HORIZONTAL)
+            box_width  = BOX_SPACING;
+        else
+            box_height = BOX_SPACING;
+            
+        total_width  += box_width;
+        total_height += box_height;
+    }
+    
+    if (orientation == GTK_ORIENTATION_HORIZONTAL)
+        total_height = MAX(total_height, new_size);
+    else
+        total_width  = MAX(total_width,  new_size);
+
+    DBG("width=%d, height=%d", total_width, total_height);
+    gtk_widget_set_size_request((GtkWidget*) self, total_width, total_height);
+}
+
+static void
+places_button_orientation_changed(XfcePanelPlugin *plugin, GtkOrientation orientation, PlacesButton *self)
+{
+    DBG("orientation changed");
+    xfce_hvbox_set_orientation(XFCE_HVBOX(self->box), orientation);
+    places_button_resize(self);
+}
+
+static gboolean
+places_button_size_changed(XfcePanelPlugin *plugin, gint size, PlacesButton *self)
+{
+    if (self->plugin_size == size)
+        return TRUE;
+
+    DBG("size changed");
+    places_button_resize(self);
+    return TRUE;
+}
+
+static void
+places_button_theme_changed(PlacesButton *self)
+{
+    DBG("theme changed");
+    places_button_resize(self);
+}
+
+/* vim: set ai et tabstop=4: */

Added: xfce4-places-plugin/trunk/panel-plugin/button.h
===================================================================
--- xfce4-places-plugin/trunk/panel-plugin/button.h	                        (rev 0)
+++ xfce4-places-plugin/trunk/panel-plugin/button.h	2008-01-08 14:31:23 UTC (rev 3789)
@@ -0,0 +1,78 @@
+/*  xfce4-places-plugin
+ *
+ *  Provides the widget that sits on the panel
+ *
+ *  Note that, while this extends GtkToggleButton, much of the gtk_button_*()
+ *  functions shouldn't be used.
+ *
+ *  Copyright (c) 2007-2008 Diego Ongaro <ongardie at gmail.com>
+ *
+ *  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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _XFCE_PANEL_PLACES_BUTTON_H
+#define _XFCE_PANEL_PLACES_BUTTON_H
+
+#include <gtk/gtk.h>
+
+#define PLACES_TYPE_BUTTON             (places_button_get_type ())
+#define PLACES_BUTTON(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), PLACES_TYPE_BUTTON, PlacesButton))
+#define PLACES_BUTTON_CLASS(obj)       (G_TYPE_CHECK_CLASS_CAST ((obj), PLACES_TYPE_BUTTON,  PlacesButtonClass))
+#define PLACES_IS_BUTTON(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PLACES_TYPE_BUTTON))
+#define PLACES_IS_BUTTON_CLASS(obj)    (G_TYPE_CHECK_CLASS_TYPE ((obj), PLACES_TYPE_BUTTON))
+#define PLACES_BUTTON_GET_CLASS        (G_TYPE_INSTANCE_GET_CLASS ((obj), PLACES_TYPE_BUTTON, PlacesButtonClass))
+
+typedef struct _PlacesButton            PlacesButton;
+typedef struct _PlacesButtonClass       PlacesButtonClass;
+
+typedef GdkPixbuf* (places_button_image_pixbuf_factory) (int size);
+
+struct _PlacesButton
+{
+    GtkToggleButton parent;
+
+    /* private */
+    XfcePanelPlugin *plugin;
+    GtkWidget *box;
+    GtkWidget *image;
+    GtkWidget *label;
+    gchar *label_text;
+    places_button_image_pixbuf_factory *pixbuf_factory;
+    gint plugin_size;
+};
+
+struct _PlacesButtonClass
+{
+    GtkToggleButtonClass parent_class;
+};
+
+GtkWidget*
+places_button_new();
+
+void
+places_button_set_label(PlacesButton*, const gchar *label);
+
+const gchar*
+places_button_get_label(PlacesButton*);
+
+void
+places_button_set_pixbuf_factory(PlacesButton*, places_button_image_pixbuf_factory*);
+
+places_button_image_pixbuf_factory*
+places_button_get_pixbuf_factory(PlacesButton*);
+
+
+#endif
+/* vim: set ai et tabstop=4: */




More information about the Goodies-commits mailing list