Logo Search packages:      
Sourcecode: vertex version File versions

tipofday.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h>

#include "guiutils.h"

#include "tipofday.h"


#include "images/icon_bulb_48x48.xpm"
#include "images/icon_bulb_32x32.xpm"
#include "images/icon_ok_20x20.xpm"
#include "images/icon_goto_20x20.xpm"


static gint TODWIN_TOTAL_TIPS_IN_LIST(const gchar **tips_list);
static void TODWinDestroyCB(GtkObject *object, gpointer data);
static gint TODWinCloseCB(
      GtkWidget *widget, GdkEvent *event, gpointer data
);
static void TODWinShowTipsNextTimeCheckCB(
      GtkWidget *widget, gpointer data
);
static void TODWinOKButtonCB(GtkWidget *widget, gpointer data);
static void TODWinNextTipButtonCB(GtkWidget *widget, gpointer data);

todwin_struct *TODWinNew(
        gpointer core_ptr,
        const gchar **tips_list,
      gbool show_tips_next_time,
        gpointer client_data,
        void (*show_tip_next_time_cb)(GtkWidget *, gpointer)
);
void TODWinMapTip(todwin_struct *tw, glong seed, gint i);
void TODWinMap(todwin_struct *tw);  
void TODWinUnmap(todwin_struct *tw); 
void TODWinDelete(todwin_struct *tw);


#define TODWIN_DEF_WIDTH      400
#define TODWIN_DEF_HEIGHT     220

#define TODWIN_BTN_WIDTH      (100 + (2 * 3))
#define TODWIN_BTN_HEIGHT     (30 + (2 * 3))

#define TODWIN_TITLE          "Tip Of The Day"
#define TODWIN_NOTIP_STRING   "Sorry, no tip available"
#define TODWIN_SHOW_TIPS_NEXT_TIME_CHECK_STRING "Show Tips Next Time"


/*
 *    Counts the number of `messages' in the given tips_list pointer
 *    array. Each `message' has two pointers, the first pointer being
 *    a parameter matching string and the second pointer is the
 *    actual message. The last two pointers in the array must be both
 *    NULL.
 */
static gint TODWIN_TOTAL_TIPS_IN_LIST(const gchar **tips_list)
{
      gint i;

      if(tips_list == NULL)
          return(0);

      for(i = 0; tips_list[i] != NULL; i++);

      /* Since messages come in pairs of pointers, divide by two. */
      i = i / 2;

      return(i);
}

/*
 *    Destroy callback.
 */
static void TODWinDestroyCB(GtkObject *object, gpointer data)
{
      return;
}

/*
 *      Close callback.
 */
static gint TODWinCloseCB(
      GtkWidget *widget, GdkEvent *event, gpointer data
)
{
        todwin_struct *tw = (todwin_struct *)data;
        if(tw == NULL)
            return(FALSE);

      TODWinUnmap(tw);

        return(TRUE);
}

/*
 *    Show tips next time check toggled callback.
 */
static void TODWinShowTipsNextTimeCheckCB(
        GtkWidget *widget, gpointer data
)
{
        todwin_struct *tw = (todwin_struct *)data;
        if((widget == NULL) || (tw == NULL))
            return;

      if(widget == tw->show_tips_next_time_check)
      {
          if(tw->show_tip_next_time_cb != NULL)
            tw->show_tip_next_time_cb(widget, data);
      }
}

/*
 *    OK button callback.
 */
static void TODWinOKButtonCB(GtkWidget *widget, gpointer data)
{
        todwin_struct *tw = (todwin_struct *)data;
        if(tw == NULL)
            return;

      TODWinUnmap(tw);
}

/*
 *    Next tip button callback.
 */
static void TODWinNextTipButtonCB(GtkWidget *widget, gpointer data)
{
      int i;
        todwin_struct *tw = (todwin_struct *)data;
        if(tw == NULL)
            return;

      i = tw->tip_index + 1;
      if(i >= tw->total_tips)
          i = 0;

      TODWinMapTip(tw, 0, i);
}

/*
 *    Creates a new tip of day window.
 */
todwin_struct *TODWinNew(
      gpointer core_ptr,
      const gchar **tips_list,
      gbool show_tips_next_time,
      gpointer client_data,
      void (*show_tip_next_time_cb)(GtkWidget *, gpointer)
)
{
      GtkAccelGroup *accelgrp;
      GtkWidget *w, *parent, *parent2, *parent3;
      GdkWindow *window;
      gint  border_major = 5,
            border_minor = 2;
      gint  bw = TODWIN_BTN_WIDTH,
            bh = TODWIN_BTN_HEIGHT;
const gchar *rcstr = "\n\
style \"todwin-tooltips-style\" { \n\
 bg[NORMAL] = \"#ffffc0\"\n\
 fg[NORMAL] = \"#000000\"\n\
}\n\
widget \"*todwin-tooltips\" style \"cdialog-tooltips-style\"\n\
";
      todwin_struct *tw = (todwin_struct *)calloc(
          1, sizeof(todwin_struct)
      );
      if(tw == NULL)
          return(tw);



      /* Reset values. */
      tw->initialized = TRUE;
      tw->map_state = FALSE;
      tw->core_ptr = core_ptr;
      tw->tips_list = tips_list;
      tw->tip_index = -1;
      tw->total_tips = TODWIN_TOTAL_TIPS_IN_LIST(tips_list);
      tw->client_data = client_data;
      tw->show_tip_next_time_cb = show_tip_next_time_cb;

      /* Parse rc string for help label style. */
        gtk_rc_parse_string(rcstr);

      /* Keyboard accelerator group. */
      tw->accelgrp = accelgrp = gtk_accel_group_new();

        /* Toplevel. */
        tw->toplevel = w = gtk_window_new(GTK_WINDOW_DIALOG);
        gtk_widget_realize(w);
        /* Set WM icon for toplevel. */
        window = w->window;
        if(window != NULL)
        {
            gdk_window_set_decorations(
                window,
                GDK_DECOR_TITLE | GDK_DECOR_MENU | GDK_DECOR_MINIMIZE
            );
            gdk_window_set_functions(
                window,
                GDK_FUNC_MOVE | GDK_FUNC_MINIMIZE | GDK_FUNC_CLOSE
            );
          GUISetWMIcon(window, (u_int8_t **)icon_bulb_48x48_xpm);
        }
        gtk_window_set_title(GTK_WINDOW(w), TODWIN_TITLE);
      gtk_widget_set_usize(w, TODWIN_DEF_WIDTH, TODWIN_DEF_HEIGHT);
        gtk_signal_connect(
            GTK_OBJECT(w), "delete_event",
            GTK_SIGNAL_FUNC(TODWinCloseCB),
            (gpointer)tw
        );
        gtk_signal_connect(
            GTK_OBJECT(w), "destroy",
            GTK_SIGNAL_FUNC(TODWinDestroyCB),
            (gpointer)tw
        );
        gtk_container_border_width(GTK_CONTAINER(w), 0);
        gtk_accel_group_attach(accelgrp, GTK_OBJECT(w));
        parent = w;


        /* Main vbox. */
        w = gtk_vbox_new(FALSE, 0);
        gtk_container_add(GTK_CONTAINER(parent), w);
      gtk_container_border_width(GTK_CONTAINER(w), 0);
        gtk_widget_show(w);
        parent = w;

        /* Hbox to hold icon and message label. */
        w = gtk_hbox_new(FALSE, border_minor);
        gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, border_major);
        gtk_widget_show(w);
        parent2 = w;

        /* Icon. */
        w = gtk_vbox_new(FALSE, 0);
        gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, border_major);
        gtk_widget_show(w);
        parent3 = w;

        w = GUICreateMenuItemIcon(
          (u_int8_t **)icon_bulb_32x32_xpm
      );
        gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, FALSE, 0);
        gtk_widget_set_usize(w, 32, 32);
        gtk_widget_show(w);


        /* Label frame. */
        w = gtk_frame_new(NULL);
        gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_IN);
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_major);
        gtk_widget_show(w);
        parent3 = w;

        w = gtk_fixed_new();
        gtk_widget_set_name(w, "todwin-tooltips");
        gtk_container_add(GTK_CONTAINER(parent3), w);
      gtk_container_set_border_width(GTK_CONTAINER(w), border_major);
        gtk_widget_show(w);
        parent3 = w;

      /* Label. */
        tw->label = w = gtk_label_new(TODWIN_NOTIP_STRING);
        gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
      gtk_fixed_put(GTK_FIXED(parent3), w, 0, 0);
        gtk_widget_show(w);

 
        /* Separator. */
        w = gtk_hseparator_new();
        gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
        gtk_widget_show(w);


      /* Buttons main hbox. */
      w = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
        gtk_widget_show(w);
      parent2 = w;

      /* Show tips next time check. */
      tw->show_tips_next_time_check = w = gtk_check_button_new_with_label(
          TODWIN_SHOW_TIPS_NEXT_TIME_CHECK_STRING
      );
        gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
      GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
      GTK_TOGGLE_BUTTON(w)->active = show_tips_next_time;
        gtk_signal_connect(
            GTK_OBJECT(w), "toggled",
            GTK_SIGNAL_FUNC(TODWinShowTipsNextTimeCheckCB),
          (gpointer)tw
        );
        gtk_widget_show(w);

      /* Empty label. */
      w = gtk_label_new("");
      gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_minor);
        gtk_widget_show(w);

        /* Buttons hbox. */
        w = gtk_hbox_new(TRUE, 0);
        gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
        gtk_widget_show(w);
        parent3 = w;


        /* OK button. */
        tw->ok_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_ok_20x20_xpm, "OK", NULL
        );
        gtk_widget_set_usize(w, bw, bh);
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, FALSE, 0);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(TODWinOKButtonCB),
            (gpointer)tw
        );
        gtk_accel_group_add(
            accelgrp, GDK_space, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_Return, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_3270_Enter, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_KP_Enter, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_ISO_Enter, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_accel_group_add(
            accelgrp, GDK_Escape, 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
      gtk_widget_show(w);

        /* Next tip button. */
        tw->next_tip_btn = w = GUIButtonPixmapLabelH(
            (u_int8_t **)icon_goto_20x20_xpm, "Next Tip", NULL
        );
        gtk_widget_set_usize(w, bw, bh);                               
        GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
        gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, FALSE, 0);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(TODWinNextTipButtonCB),
            (gpointer)tw
        );
        gtk_accel_group_add(
            accelgrp, 'n', 0, GTK_ACCEL_VISIBLE,
            GTK_OBJECT(w), "clicked"
        );
        gtk_widget_show(w);


      return(tw);
}

/*
 *    Maps the tip of day window with a random or set message.
 *
 *    A random message will be used if i is -1.
 *
 *    The given seed should be a random number.
 */
void TODWinMapTip(todwin_struct *tw, glong seed, gint i)
{
      if(tw == NULL)
          return;

      if(i < 0)
      {
          /* Get random tip. */
          if(tw->total_tips > 0)
          {
            srand(seed);
            tw->tip_index = rand() % (unsigned int)tw->total_tips;
          }
          else
          {
            tw->tip_index = 0;
          }
      }
      else
      {
          /* Use specific tip. */
          if(i < tw->total_tips)
          {
            tw->tip_index = i;
          }
          else
          {
            tw->tip_index = 0;
          }
      }

      /* Update label. */
      i = tw->tip_index;
      if((tw->tips_list != NULL) &&
         (i >= 0) && (i < tw->total_tips)
      )
      {
          const gchar *mesg_ptr = tw->tips_list[(i * 2) + 1];
          GtkWidget *w = tw->label;

          if((mesg_ptr != NULL) && (w != NULL))
          {
            gtk_label_set_text(GTK_LABEL(w), mesg_ptr);
            gtk_widget_queue_resize(tw->toplevel);
          }
      }

      TODWinMap(tw);
}


/*
 *    Maps the tip of day window.
 */
void TODWinMap(todwin_struct *tw)
{
      GtkWidget *w;

      if(tw == NULL)
          return;

        if(!tw->initialized)
            return;

      if(!tw->map_state)
      {
          GdkWindow *root, *window = NULL;

          w = tw->ok_btn;
          if(w != NULL)
          {
            gtk_widget_grab_focus(w);
            gtk_widget_grab_default(w);
          }

          w = tw->toplevel;
          if(w != NULL)
          {
            window = w->window;
            gtk_widget_show(w);
          }

          tw->map_state = TRUE;

          /* Center toplevel relative to root. */
          root = GDK_ROOT_PARENT();
          if((root != NULL) && (window != NULL))
          {
            gint rw, rh, cw, ch;

            gdk_window_get_size(root, &rw, &rh);
            gdk_window_get_size(window, &cw, &ch);

            gtk_widget_set_uposition(
                w,
                (rw / 2) - (cw / 2),
                (rh / 2) - (ch / 2)
            );

          }
      }
}

/*
 *    Unmaps the tip of day window.
 */
void TODWinUnmap(todwin_struct *tw)
{
        GtkWidget *w;

        if(tw == NULL)
            return;

      if(!tw->initialized)
          return;

        if(tw->map_state)
        {
          w = tw->toplevel;
          if(w != NULL)
            gtk_widget_hide(w);

          tw->map_state = FALSE;
      }
}

/*
 *    Deletes the given tip of day window.
 */
void TODWinDelete(todwin_struct *tw)
{
      GtkWidget **w;


      if(tw == NULL)
          return;

      if(tw->initialized)
      {
#define DO_DESTROY_WIDGET       \
{ \
 if((*w) != NULL) \
 { \
  GtkWidget *tmp_w = *w; \
  (*w) = NULL; \
  gtk_widget_destroy(tmp_w); \
 } \
}
          /* Begin destroying widgets. */
          w = &tw->show_tips_next_time_check;
          DO_DESTROY_WIDGET

            w = &tw->label;
            DO_DESTROY_WIDGET

          w = &tw->toplevel;
          DO_DESTROY_WIDGET

          if(tw->accelgrp != NULL)
          {
            gtk_accel_group_unref(tw->accelgrp);
            tw->accelgrp = NULL;
          }

#undef DO_DESTROY_WIDGET
      }

      /* Deallocate structure itself. */
      free(tw);
}

Generated by  Doxygen 1.6.0   Back to index