Logo Search packages:      
Sourcecode: vertex version File versions

toolbar.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include "guiutils.h"
#include "toolbar.h"


static gint ToolbarEnterNotifyCB(
      GtkWidget *widget, GdkEventCrossing *crossing, gpointer data
);
static gint ToolbarLeaveNotifyCB(
        GtkWidget *widget, GdkEventCrossing *crossing, gpointer data
);
static void ToolbarClickedCB(GtkWidget *widget, gpointer data);

toolbar_item_struct *ToolBarItemNew(
        gint type,              /* One of TOOLBAR_ITEM_*. */
        const gchar *text,
        guint8 **icon_data,
        const gchar *tooltip,
        gint id,
        void (*func_cb)(gpointer),
      gpointer client_data,
        void (*enter_cb)(gpointer),
        gpointer enter_client_data,
        void (*leave_cb)(gpointer),
        gpointer leave_client_data
);
void ToolBarItemDelete(toolbar_item_struct *item);

toolbar_item_struct *ToolBarItemMatchByID(
      toolbar_item_struct **item, gint total_items,
      gint id
);

toolbar_struct *ToolBarNew(
      toolbar_item_struct **item, gint total_items,
      GtkWidget *parent,
      gint display,           /* One of TOOLBAR_DISPLAY_*. */
        gint relief,            /* One of TOOLBAR_RELIEF_*. */
      gbool vertical
);
void ToolBarSetDisplay(toolbar_struct *tb, gint display);
void ToolBarSetRelief(toolbar_struct *tb, gint relief);
void ToolBarItemUpdateByID(
        toolbar_struct *tb, gint id,
        const gchar *text,
        guint8 **icon_data,
        const gchar *tooltip
);
void ToolBarMap(toolbar_struct *tb);
void ToolBarUnmap(toolbar_struct *tb);
void ToolBarDelete(toolbar_struct *tb);

void ToolBarItemSetSensitiveID(
        toolbar_struct *tb, gint id, gbool sensitive
);
void ToolBarItemSetToggleID(
        toolbar_struct *tb, gint id, gbool toggled
);
gbool ToolBarItemGetToggleID(
        toolbar_struct *tb, gint id
);
void ToolBarItemMapID(toolbar_struct *tb, gint id);
void ToolBarItemUnmapID(toolbar_struct *tb, gint id);


#define STRDUP(s) (((s) != NULL) ? g_strdup(s) : NULL)

#define SET_BUTTON_LAYOUT                       \
{ if(w != NULL) { switch(display) {             \
   case TOOLBAR_DISPLAY_PICTURES_AND_TEXT:            \
    GUIButtonChangeLayout(w, 1, 1);             \
    gtk_widget_set_usize(                       \
     w,                                         \
     TOOLBAR_BUTTON_PICTURE_AND_TEXT_WIDTH,           \
     TOOLBAR_BUTTON_PICTURE_AND_TEXT_HEIGHT           \
    );                                          \
    break;                                \
   case TOOLBAR_DISPLAY_PICTURES:               \
    GUIButtonChangeLayout(w, 1, 0);             \
    gtk_widget_set_usize(                       \
     w,                                         \
     TOOLBAR_BUTTON_PICTURE_WIDTH,              \
     TOOLBAR_BUTTON_PICTURE_HEIGHT              \
    );                                          \
    break;                                \
   default: /* TOOLBAR_DISPLAY_TEXT */                \
    GUIButtonChangeLayout(w, 0, 1);             \
    gtk_widget_set_usize(                       \
     w,                                         \
     TOOLBAR_BUTTON_TEXT_WIDTH,                       \
     TOOLBAR_BUTTON_TEXT_HEIGHT                       \
    );                                          \
    break;                                \
} } }


/*
 *    "enter_notify_event" signal callback.
 */
static gint ToolbarEnterNotifyCB(
        GtkWidget *widget, GdkEventCrossing *crossing, gpointer data
)
{
      toolbar_item_struct *item = (toolbar_item_struct *)data;
      if(item == NULL)
          return(TRUE);

      if(item->enter_cb != NULL)
          item->enter_cb(item->enter_client_data);

      return(TRUE);
}

/*
 *      "leave_notify_event" signal callback.
 */
static gint ToolbarLeaveNotifyCB(
        GtkWidget *widget, GdkEventCrossing *crossing, gpointer data
)
{
        toolbar_item_struct *item = (toolbar_item_struct *)data;
        if(item == NULL)
            return(TRUE);

        if(item->leave_cb != NULL)
            item->leave_cb(item->leave_client_data);

        return(TRUE);
}

/*
 *    "clicked" or "toggled" signal callback.
 */
static void ToolbarClickedCB(GtkWidget *widget, gpointer data)
{
        toolbar_item_struct *item = (toolbar_item_struct *)data;
        if(item == NULL)
            return;

        if(item->func_cb != NULL)
            item->func_cb(item->client_data);
}


/*
 *    Creates a new tool bar item structure with the values initialized
 *    to the given inputs.
 *
 *    No widgets or other resources will be created.
 */
toolbar_item_struct *ToolBarItemNew(
        gint type,              /* One of TOOLBAR_ITEM_*. */
        const gchar *text,
        guint8 **icon_data,
        const gchar *tooltip,
        gint id,
        void (*func_cb)(gpointer),
        gpointer client_data,
        void (*enter_cb)(gpointer),
        gpointer enter_client_data,
        void (*leave_cb)(gpointer),
        gpointer leave_client_data
)
{
      toolbar_item_struct *item = (toolbar_item_struct *)g_malloc0(
          sizeof(toolbar_item_struct)
      );
      if(item == NULL)
          return(item);

      item->type = type;

      item->w = NULL;

      item->text = STRDUP(text);
      item->icon_data = icon_data;
      item->tooltip = STRDUP(tooltip);

      item->id = id;
      item->func_cb = func_cb;
        item->client_data = client_data;
      item->enter_cb = enter_cb;
      item->enter_client_data = enter_client_data;
        item->leave_cb = leave_cb;
        item->leave_client_data = leave_client_data;

      return(item);
}

/*
 *    Deallocates all resources of the given tool bar item and
 *    deallocates the item structure itself.
 */
void ToolBarItemDelete(toolbar_item_struct *item)
{
      GtkWidget *w;

      if(item == NULL)
          return;

      /* Destroy tool bar item toplevel widget. */
      w = item->w;
      if(w != NULL)
          gtk_widget_destroy(w);

      /* Deallocate memory. */
      g_free(item->text);

      /* item->icon_data = NULL; */ /* Shared. */

        g_free(item->tooltip);

      g_free(item);
}

/*
 *    Returns a tool bar item that matches the given id in the given
 *    items list.
 */
toolbar_item_struct *ToolBarItemMatchByID(
        toolbar_item_struct **item, gint total_items,
        gint id
)
{
      gint i;
      toolbar_item_struct *item_ptr;

      for(i = 0; i < total_items; i++)
      {
          item_ptr = item[i];
          if(item_ptr == NULL)
            continue;

          if(item_ptr->id == id)
            return(item_ptr);
      }

      return(NULL);
}


/*
 *    Creates a new tool bar with respect to the given list of items
 *    and parents it to the given parent widget.
 *
 *    The given list of items will not be modified.
 */
toolbar_struct *ToolBarNew(
        toolbar_item_struct **item, gint total_items,
        GtkWidget *parent,
        gint display,           /* One of TOOLBAR_DISPLAY_*. */
        gint relief,          /* One of TOOLBAR_RELIEF_*. */
        gbool vertical
)
{
      gint i, border_major = 5;
      GtkWidget *w, *parent2, *parent3;
      toolbar_item_struct *src_item_ptr, *item_ptr;
      toolbar_struct *tb = (toolbar_struct *)g_malloc0(
          sizeof(toolbar_struct)
      );
      if(tb == NULL)
          return(tb);

      /* Reset values. */
      tb->display = display;
      tb->relief = relief;
      tb->vertical = vertical;
      tb->map_state = FALSE;

      tb->item = NULL;
      tb->total_items = 0;

      /* Create toplevel. */
      if(vertical)
          w = gtk_vbox_new(FALSE, 0);
      else
          w = gtk_hbox_new(FALSE, 0);
      gtk_container_border_width(GTK_CONTAINER(w), 2);
      gtk_container_add(GTK_CONTAINER(parent), w);
      tb->toplevel = w;
      parent2 = w;


      /* Allocate pointer array for tool bar items. */
      tb->total_items = total_items;
      if(tb->total_items > 0)
      {
          tb->item = (toolbar_item_struct **)g_malloc0(
            tb->total_items * sizeof(toolbar_item_struct *)
          );
          if(tb->item == NULL)
          {
            tb->total_items = 0;
          }
      }

      /* Create tool bar items. */
      for(i = 0; i < tb->total_items; i++)
      {
          src_item_ptr = item[i];
          if(src_item_ptr == NULL)
            continue;

          /* Create a copy of the item. */
          tb->item[i] = item_ptr = ToolBarItemNew(
            src_item_ptr->type,
            src_item_ptr->text,
            src_item_ptr->icon_data,
            src_item_ptr->tooltip,
            src_item_ptr->id,
            src_item_ptr->func_cb,
            src_item_ptr->client_data,
                src_item_ptr->enter_cb,
            src_item_ptr->enter_client_data,
                src_item_ptr->leave_cb,
                src_item_ptr->leave_client_data
          );

          /* Create widgets based on new item. */
          if(item_ptr != NULL)
          {
            gpointer label_rtn;


            switch(item_ptr->type)
            {
              case TOOLBAR_ITEM_SEPARATOR:
                item_ptr->w = w = gtk_vbox_new(TRUE, 0);
                gtk_widget_set_usize(
                  w,
                  vertical ? -1 : 5,
                  vertical ? 5 : -1
                );
                gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
                gtk_widget_show(w);
                parent3 = w;

                if(vertical)
                  w = gtk_hseparator_new();
                else
                  w = gtk_vseparator_new();
                gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
                gtk_widget_show(w);
                break;

              case TOOLBAR_ITEM_BUTTON:
                item_ptr->w = w = (GtkWidget *)GUIButtonPixmapLabelV(
                  (u_int8_t **)item_ptr->icon_data,
                  item_ptr->text,
                  &label_rtn
                );
                switch(relief)
                {
                  case TOOLBAR_RELIEF_NONE:
                  gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NONE);
                  break;
                      case TOOLBAR_RELIEF_HALF:
                        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_HALF);
                        break;
                      default:
                        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NORMAL);
                        break;
                }
                gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
                if(item_ptr->func_cb != NULL)
                  gtk_signal_connect(
                      GTK_OBJECT(w), "clicked",
                      GTK_SIGNAL_FUNC(ToolbarClickedCB),
                      item_ptr
                        );
                if(item_ptr->enter_cb != NULL)
                        gtk_signal_connect(
                            GTK_OBJECT(w), "enter_notify_event",
                      GTK_SIGNAL_FUNC(ToolbarEnterNotifyCB),
                      item_ptr
                  );
                    if(item_ptr->leave_cb != NULL)
                        gtk_signal_connect(
                            GTK_OBJECT(w), "leave_notify_event",
                            GTK_SIGNAL_FUNC(ToolbarLeaveNotifyCB),
                            item_ptr
                        );
                if(item_ptr->tooltip != NULL)
                  GUISetWidgetTip(w, item_ptr->tooltip);
                SET_BUTTON_LAYOUT
                gtk_widget_show(w);
                break;

                  case TOOLBAR_ITEM_TOGGLE_BUTTON:
                    item_ptr->w = w = (GtkWidget *)GUIToggleButtonPixmapLabelV(
                        (u_int8_t **)item_ptr->icon_data,
                        item_ptr->text,
                        &label_rtn
                    );
                    switch(relief)
                    {
                      case TOOLBAR_RELIEF_NONE:
                        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NONE);
                        break;
                      case TOOLBAR_RELIEF_HALF:
                        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_HALF);
                        break;
                      default:
                        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NORMAL);
                        break;
                    }
                    gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
                    if(item_ptr->func_cb != NULL)
                        gtk_signal_connect(
                            GTK_OBJECT(w), "toggled",
                            GTK_SIGNAL_FUNC(ToolbarClickedCB),
                            item_ptr
                        );
                    if(item_ptr->enter_cb != NULL)
                        gtk_signal_connect(
                            GTK_OBJECT(w), "enter_notify_event",
                            GTK_SIGNAL_FUNC(ToolbarEnterNotifyCB),
                            item_ptr
                        );
                    if(item_ptr->leave_cb != NULL)
                        gtk_signal_connect(
                            GTK_OBJECT(w), "leave_notify_event",
                            GTK_SIGNAL_FUNC(ToolbarLeaveNotifyCB),
                            item_ptr
                        );
                    if(item_ptr->tooltip != NULL)
                        GUISetWidgetTip(w, item_ptr->tooltip);
                    SET_BUTTON_LAYOUT
                    gtk_widget_show(w);
                    break;

            }
          }
      }

      return(tb);
}

/*
 *    Changes the display of the given tool bar's widgets.
 */
void ToolBarSetDisplay(toolbar_struct *tb, gint display)
{
      gint i;
      GtkWidget *w;
      toolbar_item_struct *item_ptr;


      if(tb == NULL)
          return;

      /* Iterate through all tool bar items. */
      for(i = 0; i < tb->total_items; i++)
      {
          item_ptr = tb->item[i];
          if(item_ptr == NULL)
            continue;

          w = item_ptr->w;
          if(w == NULL)
            continue;

          switch(item_ptr->type)
          {
            case TOOLBAR_ITEM_SEPARATOR:
            break;

            case TOOLBAR_ITEM_BUTTON:
            SET_BUTTON_LAYOUT
            break;

              case TOOLBAR_ITEM_TOGGLE_BUTTON:
                SET_BUTTON_LAYOUT
                break;

          }
      }

      /* Remind tool bar that it needs to resize. */
/*
      w = tb->toplevel;
      if(w != NULL)
          gtk_widget_queue_resize(w);
 */
}

/*
 *      Changes the relief of the given tool bar's widgets.
 */
void ToolBarSetRelief(toolbar_struct *tb, gint relief)
{
        gint i;
        GtkWidget *w;
        toolbar_item_struct *item_ptr;


        if(tb == NULL)
            return;

        /* Iterate through all tool bar items. */
        for(i = 0; i < tb->total_items; i++)
        {
            item_ptr = tb->item[i];
            if(item_ptr == NULL)
                continue;

            w = item_ptr->w;
            if(w == NULL)
                continue;

            switch(item_ptr->type)
            {
              case TOOLBAR_ITEM_SEPARATOR:
                break;

              case TOOLBAR_ITEM_BUTTON:
                if(GTK_IS_BUTTON(w))
                {
                    switch(relief)
                    {
                      case TOOLBAR_RELIEF_NONE:
                        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NONE);
                        break;
                      case TOOLBAR_RELIEF_HALF:
                        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_HALF);
                        break;
                      default:
                        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NORMAL);
                        break;
                    }
                }
                break;

              case TOOLBAR_ITEM_TOGGLE_BUTTON:
            if(GTK_IS_BUTTON(w))
            {
                    switch(relief)
                    {
                      case TOOLBAR_RELIEF_NONE:
                        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NONE);
                        break;
                      case TOOLBAR_RELIEF_HALF:
                        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_HALF);
                        break;
                      default:
                        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NORMAL);
                        break;
                    }
            }
                break;
            }
        }

        /* Remind tool bar that it needs to resize. */
/*
        w = tb->toplevel;
        if(w != NULL)
            gtk_widget_queue_resize(w);
 */
}


/*
 *    Updates all items on the given tool bar that match the given id
 *    with the new text, icon, and tool tip message.
 *
 *    If any input is NULL then that value will not be chagned.
 */
void ToolBarItemUpdateByID(
        toolbar_struct *tb, gint id,
        const gchar *text,
        guint8 **icon_data,
        const gchar *tooltip
)
{
      gint i;
      toolbar_item_struct *item;


      if(tb == NULL)
          return;

      /* Iterate through all tool bar items. */
      for(i = 0; i < tb->total_items; i++)
      {
          item = tb->item[i];
          if(item == NULL)
            continue;

          /* Id of current item matches the given id? */
          if(item->id == id)
          {
            /* Update text, icon data, and tool tip message. */
            if(text != NULL)
            {
                g_free(item->text);
                item->text = STRDUP(text);
            }

            if(icon_data != NULL)
            {
                item->icon_data = icon_data;
            }

            if(tooltip != NULL)
            {
                g_free(item->tooltip);
                item->tooltip = STRDUP(tooltip);
            }

            /* Update widget, handle by item type. */
            switch(item->type)
            {
              case TOOLBAR_ITEM_BUTTON:
                if(item->w != NULL)
                {
                  GUIButtonPixmapUpdate(
                      item->w, icon_data, text
                  );
                }
                break;

                  case TOOLBAR_ITEM_TOGGLE_BUTTON:
                    if(item->w != NULL)
                    {
                        GUIButtonPixmapUpdate(
                            item->w, icon_data, text
                        );
                    }
                    break;
            }

          }
      }
}

/*
 *    Maps the given tool bar.
 */
void ToolBarMap(toolbar_struct *tb)
{
      GtkWidget *w;


      if(tb == NULL)
          return;

      w = tb->toplevel;
      if(w == NULL)
          return;

      if(!tb->map_state)
      {
          gtk_widget_show(w);
          tb->map_state = TRUE;
      }
}

/*
 *    Unmaps the given tool bar.
 */
void ToolBarUnmap(toolbar_struct *tb)
{
        GtkWidget *w;


        if(tb == NULL)
            return;

        w = tb->toplevel;
        if(w == NULL)
            return;

        if(tb->map_state)
        {
            gtk_widget_hide(w);
            tb->map_state = FALSE;
        }
}

/*
 *    Deallocates all resources on the given tool bar and deallocates 
 *    the tool bar structure itself.
 */
void ToolBarDelete(toolbar_struct *tb)
{
      gint i;
      GtkWidget *w;


        if(tb == NULL)
            return;

      /* Destroy all items and their widgets. */
      for(i = 0; i < tb->total_items; i++)
          ToolBarItemDelete(tb->item[i]);
      g_free(tb->item);
      tb->item = NULL;
      tb->total_items = 0;

      /* Destroy tool bar toplevel. */
      w = tb->toplevel;
      tb->toplevel = NULL;
      if(w != NULL)
          gtk_widget_destroy(w);


      /* Deallocate tool bar structure itself. */
      g_free(tb);
}


/*
 *    Sets the tool bar item that matches the given id sensitive or
 *    insensitive.
 */
void ToolBarItemSetSensitiveID(
        toolbar_struct *tb, gint id, gbool sensitive
)
{
      GtkWidget *w;
      toolbar_item_struct *item_ptr;


      if(tb == NULL)
          return;

      item_ptr = ToolBarItemMatchByID(
          tb->item, tb->total_items, id
      );
      if(item_ptr == NULL)
          return;

      w = item_ptr->w;
      if(w == NULL)
          return;

      gtk_widget_set_sensitive(w, sensitive);
}

/*
 *    Sets the tool bar item of type TOOLBAR_ITEM_TOGGLE_BUTTON that
 *    matches the given id toggled or untoggled.
 *
 *    No signal will be emitted.
 */
void ToolBarItemSetToggleID(
        toolbar_struct *tb, gint id, gbool toggled
)
{
        toolbar_item_struct *item_ptr;


        if(tb == NULL)
            return;

        item_ptr = ToolBarItemMatchByID(
            tb->item, tb->total_items, id
        );
        if(item_ptr == NULL)
            return;

      if(item_ptr->type == TOOLBAR_ITEM_TOGGLE_BUTTON)
      {
          GtkToggleButton *tb = (GtkToggleButton *)item_ptr->w;
          if(tb != NULL)
          {
            /* Check if toggle button state has changed by comparing
             * the current value with the given value. If there
             * is a change then first record the function callback
             * from the item structure and then set it NULL.
             * Next toggle the button, in which case the toggle
             * callback will be called but the func_cb will not be
             * called. After the callback is made we set the func_cb
             * back to its original value.
             */
            if((gbool)tb->active != (gbool)toggled)
            {
                void (*func_cb)(gpointer) = item_ptr->func_cb;
                item_ptr->func_cb = NULL;
                gtk_toggle_button_set_active(tb, toggled);
                item_ptr->func_cb = func_cb;
            }
          }
      }
}

/*
 *    Gets the toggle state of the tool bar item of type
 *    TOOLBAR_ITEM_TOGGLE_BUTTON that matches the given id
 */
gbool ToolBarItemGetToggleID(
        toolbar_struct *tb, gint id
)
{
        toolbar_item_struct *item_ptr;


        if(tb == NULL)
            return(FALSE);

        item_ptr = ToolBarItemMatchByID(
            tb->item, tb->total_items, id
        );
        if(item_ptr == NULL)
            return(FALSE);

        if(item_ptr->type == TOOLBAR_ITEM_TOGGLE_BUTTON)
        {
            GtkToggleButton *tb = (GtkToggleButton *)item_ptr->w;
            if(tb != NULL)
            return(tb->active);
          else
            return(FALSE);
      }

      return(FALSE);
}


/*
 *    Maps the tool bar item that matches the given id.
 */
void ToolBarItemMapID(toolbar_struct *tb, gint id)
{
        GtkWidget *w;
        toolbar_item_struct *item_ptr;


        if(tb == NULL)
            return;

        item_ptr = ToolBarItemMatchByID(
            tb->item, tb->total_items, id
        );
        if(item_ptr == NULL)
            return;

        w = item_ptr->w;
        if(w != NULL)
          gtk_widget_show(w);
}

/*
 *    Unmaps the tool bar item that matches the given id.
 */
void ToolBarItemUnmapID(toolbar_struct *tb, gint id)
{
        GtkWidget *w;
        toolbar_item_struct *item_ptr;


        if(tb == NULL)
            return;

        item_ptr = ToolBarItemMatchByID(
            tb->item, tb->total_items, id
        );
        if(item_ptr == NULL)
            return;

        w = item_ptr->w;
        if(w != NULL)
          gtk_widget_hide(w);
}


Generated by  Doxygen 1.6.0   Back to index