home *** CD-ROM | disk | FTP | other *** search
/ Freelog 65 / Freelog065.iso / BAS / Bureautique / Gnumeric / gnumeric-1.3.92-rc1.exe / appwindow.c < prev    next >
C/C++ Source or Header  |  2004-10-15  |  16KB  |  464 lines

  1. /* Application main window
  2.  *
  3.  * Demonstrates a typical application window, with menubar, toolbar, statusbar.
  4.  */
  5.  
  6. #include <config.h>
  7. #include <gtk/gtk.h>
  8. #include "demo-common.h"
  9.  
  10. static GtkWidget *window = NULL;
  11.  
  12. static void
  13. activate_action (GtkAction *action)
  14. {
  15.   const gchar *name = gtk_action_get_name (action);
  16.   const gchar *typename = G_OBJECT_TYPE_NAME (action);
  17.  
  18.   GtkWidget *dialog;
  19.   
  20.   dialog = gtk_message_dialog_new (GTK_WINDOW (window),
  21.                                    GTK_DIALOG_DESTROY_WITH_PARENT,
  22.                                    GTK_MESSAGE_INFO,
  23.                                    GTK_BUTTONS_CLOSE,
  24.                                    "You activated action: \"%s\" of type \"%s\"",
  25.                                     name, typename);
  26.  
  27.   /* Close dialog on user response */
  28.   g_signal_connect (dialog,
  29.                     "response",
  30.                     G_CALLBACK (gtk_widget_destroy),
  31.                     NULL);
  32.   
  33.   gtk_widget_show (dialog);
  34. }
  35.  
  36. static void
  37. activate_radio_action (GtkAction *action, GtkRadioAction *current)
  38. {
  39.   const gchar *name = gtk_action_get_name (GTK_ACTION (current));
  40.   const gchar *typename = G_OBJECT_TYPE_NAME (GTK_ACTION (current));
  41.   gboolean active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (current));
  42.   gint value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (current));
  43.  
  44.   if (active) 
  45.     {
  46.       GtkWidget *dialog;
  47.   
  48.       dialog = gtk_message_dialog_new (GTK_WINDOW (window),
  49.                        GTK_DIALOG_DESTROY_WITH_PARENT,
  50.                        GTK_MESSAGE_INFO,
  51.                        GTK_BUTTONS_CLOSE,
  52.                        "You activated radio action: \"%s\" of type \"%s\".\nCurrent value: %d",
  53.                        name, typename, value);
  54.  
  55.       /* Close dialog on user response */
  56.       g_signal_connect (dialog,
  57.             "response",
  58.             G_CALLBACK (gtk_widget_destroy),
  59.             NULL);
  60.       
  61.       gtk_widget_show (dialog);
  62.     }
  63. }
  64.  
  65.  
  66. static GtkActionEntry entries[] = {
  67.   { "FileMenu", NULL, "_File" },               /* name, stock id, label */
  68.   { "PreferencesMenu", NULL, "_Preferences" }, /* name, stock id, label */
  69.   { "ColorMenu", NULL, "_Color"  },            /* name, stock id, label */
  70.   { "ShapeMenu", NULL, "_Shape" },             /* name, stock id, label */
  71.   { "HelpMenu", NULL, "_Help" },               /* name, stock id, label */
  72.   { "New", GTK_STOCK_NEW,                      /* name, stock id */
  73.     "_New", "<control>N",                      /* label, accelerator */
  74.     "Create a new file",                       /* tooltip */ 
  75.     G_CALLBACK (activate_action) },      
  76.   { "Open", GTK_STOCK_OPEN,                    /* name, stock id */
  77.     "_Open","<control>O",                      /* label, accelerator */     
  78.     "Open a file",                             /* tooltip */
  79.     G_CALLBACK (activate_action) }, 
  80.   { "Save", GTK_STOCK_SAVE,                    /* name, stock id */
  81.     "_Save","<control>S",                      /* label, accelerator */     
  82.     "Save current file",                       /* tooltip */
  83.     G_CALLBACK (activate_action) },
  84.   { "SaveAs", GTK_STOCK_SAVE,                  /* name, stock id */
  85.     "Save _As...", NULL,                       /* label, accelerator */     
  86.     "Save to a file",                          /* tooltip */
  87.     G_CALLBACK (activate_action) },
  88.   { "Quit", GTK_STOCK_QUIT,                    /* name, stock id */
  89.     "_Quit", "<control>Q",                     /* label, accelerator */     
  90.     "Quit",                                    /* tooltip */
  91.     G_CALLBACK (activate_action) },
  92.   { "About", NULL,                             /* name, stock id */
  93.     "_About", "<control>A",                    /* label, accelerator */     
  94.     "About",                                   /* tooltip */  
  95.     G_CALLBACK (activate_action) },
  96.   { "Logo", "demo-gtk-logo",                   /* name, stock id */
  97.      NULL, NULL,                               /* label, accelerator */     
  98.     "GTK+",                                    /* tooltip */
  99.     G_CALLBACK (activate_action) },
  100. };
  101. static guint n_entries = G_N_ELEMENTS (entries);
  102.  
  103.  
  104. static GtkToggleActionEntry toggle_entries[] = {
  105.   { "Bold", GTK_STOCK_BOLD,                    /* name, stock id */
  106.      "_Bold", "<control>B",                    /* label, accelerator */     
  107.     "Bold",                                    /* tooltip */
  108.     G_CALLBACK (activate_action), 
  109.     TRUE },                                    /* is_active */
  110. };
  111. static guint n_toggle_entries = G_N_ELEMENTS (toggle_entries);
  112.  
  113. enum {
  114.   COLOR_RED,
  115.   COLOR_GREEN,
  116.   COLOR_BLUE
  117. };
  118.  
  119. static GtkRadioActionEntry color_entries[] = {
  120.   { "Red", NULL,                               /* name, stock id */
  121.     "_Red", "<control>R",                      /* label, accelerator */     
  122.     "Blood", COLOR_RED },                      /* tooltip, value */
  123.   { "Green", NULL,                             /* name, stock id */
  124.     "_Green", "<control>G",                    /* label, accelerator */     
  125.     "Grass", COLOR_GREEN },                    /* tooltip, value */
  126.   { "Blue", NULL,                              /* name, stock id */
  127.     "_Blue", "<control>B",                     /* label, accelerator */     
  128.     "Sky", COLOR_BLUE },                       /* tooltip, value */
  129. };
  130. static guint n_color_entries = G_N_ELEMENTS (color_entries);
  131.  
  132. enum {
  133.   SHAPE_SQUARE,
  134.   SHAPE_RECTANGLE,
  135.   SHAPE_OVAL
  136. };
  137.  
  138. static GtkRadioActionEntry shape_entries[] = {
  139.   { "Square", NULL,                            /* name, stock id */
  140.     "_Square", "<control>S",                   /* label, accelerator */     
  141.     "Square",  SHAPE_SQUARE },                 /* tooltip, value */
  142.   { "Rectangle", NULL,                         /* name, stock id */
  143.     "_Rectangle", "<control>R",                /* label, accelerator */     
  144.     "Rectangle", SHAPE_RECTANGLE },            /* tooltip, value */
  145.   { "Oval", NULL,                              /* name, stock id */
  146.     "_Oval", "<control>O",                     /* label, accelerator */     
  147.     "Egg", SHAPE_OVAL },                       /* tooltip, value */  
  148. };
  149. static guint n_shape_entries = G_N_ELEMENTS (shape_entries);
  150.  
  151. static const gchar *ui_info = 
  152. "<ui>"
  153. "  <menubar name='MenuBar'>"
  154. "    <menu action='FileMenu'>"
  155. "      <menuitem action='New'/>"
  156. "      <menuitem action='Open'/>"
  157. "      <menuitem action='Save'/>"
  158. "      <menuitem action='SaveAs'/>"
  159. "      <separator/>"
  160. "      <menuitem action='Quit'/>"
  161. "    </menu>"
  162. "    <menu action='PreferencesMenu'>"
  163. "      <menu action='ColorMenu'>"
  164. "    <menuitem action='Red'/>"
  165. "    <menuitem action='Green'/>"
  166. "    <menuitem action='Blue'/>"
  167. "      </menu>"
  168. "      <menu action='ShapeMenu'>"
  169. "        <menuitem action='Square'/>"
  170. "        <menuitem action='Rectangle'/>"
  171. "        <menuitem action='Oval'/>"
  172. "      </menu>"
  173. "      <menuitem action='Bold'/>"
  174. "    </menu>"
  175. "    <menu action='HelpMenu'>"
  176. "      <menuitem action='About'/>"
  177. "    </menu>"
  178. "  </menubar>"
  179. "  <toolbar  name='ToolBar'>"
  180. "    <toolitem action='Open'/>"
  181. "    <toolitem action='Quit'/>"
  182. "    <separator action='Sep1'/>"
  183. "    <toolitem action='Logo'/>"
  184. "  </toolbar>"
  185. "</ui>";
  186.  
  187.  
  188.  
  189. /* This function registers our custom toolbar icons, so they can be themed.
  190.  *
  191.  * It's totally optional to do this, you could just manually insert icons
  192.  * and have them not be themeable, especially if you never expect people
  193.  * to theme your app.
  194.  */
  195. static void
  196. register_stock_icons (void)
  197. {
  198.   static gboolean registered = FALSE;
  199.   
  200.   if (!registered)
  201.     {
  202.       GdkPixbuf *pixbuf;
  203.       GtkIconFactory *factory;
  204.       char *filename;
  205.  
  206.       static GtkStockItem items[] = {
  207.         { "demo-gtk-logo",
  208.           "_GTK!",
  209.           0, 0, NULL }
  210.       };
  211.       
  212.       registered = TRUE;
  213.  
  214.       /* Register our stock items */
  215.       gtk_stock_add (items, G_N_ELEMENTS (items));
  216.       
  217.       /* Add our custom icon factory to the list of defaults */
  218.       factory = gtk_icon_factory_new ();
  219.       gtk_icon_factory_add_default (factory);
  220.  
  221.       /* demo_find_file() looks in the the current directory first,
  222.        * so you can run gtk-demo without installing GTK, then looks
  223.        * in the location where the file is installed.
  224.        */
  225.       pixbuf = NULL;
  226.       filename = demo_find_file ("gtk-logo-rgb.gif", NULL);
  227.       if (filename)
  228.     {
  229.       pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
  230.       g_free (filename);
  231.     }
  232.  
  233.       /* Register icon to accompany stock item */
  234.       if (pixbuf != NULL)
  235.         {
  236.           GtkIconSet *icon_set;
  237.           GdkPixbuf *transparent;
  238.  
  239.           /* The gtk-logo-rgb icon has a white background, make it transparent */
  240.           transparent = gdk_pixbuf_add_alpha (pixbuf, TRUE, 0xff, 0xff, 0xff);
  241.           
  242.           icon_set = gtk_icon_set_new_from_pixbuf (transparent);
  243.           gtk_icon_factory_add (factory, "demo-gtk-logo", icon_set);
  244.           gtk_icon_set_unref (icon_set);
  245.           g_object_unref (pixbuf);
  246.           g_object_unref (transparent);
  247.         }
  248.       else
  249.         g_warning ("failed to load GTK logo for toolbar");
  250.       
  251.       /* Drop our reference to the factory, GTK will hold a reference. */
  252.       g_object_unref (factory);
  253.     }
  254. }
  255.  
  256. static void
  257. update_statusbar (GtkTextBuffer *buffer,
  258.                   GtkStatusbar  *statusbar)
  259. {
  260.   gchar *msg;
  261.   gint row, col;
  262.   gint count;
  263.   GtkTextIter iter;
  264.   
  265.   gtk_statusbar_pop (statusbar, 0); /* clear any previous message, underflow is allowed */
  266.  
  267.   count = gtk_text_buffer_get_char_count (buffer);
  268.  
  269.   gtk_text_buffer_get_iter_at_mark (buffer,
  270.                                     &iter,
  271.                                     gtk_text_buffer_get_insert (buffer));
  272.  
  273.   row = gtk_text_iter_get_line (&iter);
  274.   col = gtk_text_iter_get_line_offset (&iter);
  275.  
  276.   msg = g_strdup_printf ("Cursor at row %d column %d - %d chars in document",
  277.                          row, col, count);
  278.  
  279.   gtk_statusbar_push (statusbar, 0, msg);
  280.  
  281.   g_free (msg);
  282. }
  283.  
  284. static void
  285. mark_set_callback (GtkTextBuffer     *buffer,
  286.                    const GtkTextIter *new_location,
  287.                    GtkTextMark       *mark,
  288.                    gpointer           data)
  289. {
  290.   update_statusbar (buffer, GTK_STATUSBAR (data));
  291. }
  292.  
  293. static void
  294. update_resize_grip (GtkWidget           *widget,
  295.             GdkEventWindowState *event,
  296.             GtkStatusbar        *statusbar)
  297. {
  298.   if (event->changed_mask & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN))
  299.     gtk_statusbar_set_has_resize_grip (statusbar, !(event->new_window_state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)));
  300. }
  301.             
  302.  
  303. GtkWidget *
  304. do_appwindow (GtkWidget *do_widget)
  305. {  
  306.   if (!window)
  307.     {
  308.       GtkWidget *table;
  309.       GtkWidget *statusbar;
  310.       GtkWidget *contents;
  311.       GtkWidget *sw;
  312.       GtkWidget *bar;
  313.       GtkTextBuffer *buffer;
  314.       GtkActionGroup *action_group;
  315.       GtkUIManager *merge;
  316.       GError *error = NULL;
  317.  
  318.       register_stock_icons ();
  319.       
  320.       /* Create the toplevel window
  321.        */
  322.       
  323.       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  324.       gtk_window_set_screen (GTK_WINDOW (window),
  325.                  gtk_widget_get_screen (do_widget));
  326.       gtk_window_set_title (GTK_WINDOW (window), "Application Window");
  327.  
  328.       /* NULL window variable when window is closed */
  329.       g_signal_connect (window, "destroy",
  330.                         G_CALLBACK (gtk_widget_destroyed),
  331.                         &window);
  332.  
  333.       table = gtk_table_new (1, 4, FALSE);
  334.       
  335.       gtk_container_add (GTK_CONTAINER (window), table);
  336.       
  337.       /* Create the menubar and toolbar
  338.        */
  339.       
  340.       action_group = gtk_action_group_new ("AppWindowActions");
  341.       gtk_action_group_add_actions (action_group, 
  342.                     entries, n_entries, 
  343.                     NULL);
  344.       gtk_action_group_add_toggle_actions (action_group, 
  345.                        toggle_entries, n_toggle_entries, 
  346.                        NULL);
  347.       gtk_action_group_add_radio_actions (action_group, 
  348.                       color_entries, n_color_entries, 
  349.                       COLOR_RED,
  350.                       G_CALLBACK (activate_radio_action), 
  351.                       NULL);
  352.       gtk_action_group_add_radio_actions (action_group, 
  353.                       shape_entries, n_shape_entries, 
  354.                       SHAPE_SQUARE,
  355.                       G_CALLBACK (activate_radio_action), 
  356.                       NULL);
  357.  
  358.       merge = gtk_ui_manager_new ();
  359.       g_object_set_data_full (G_OBJECT (window), "ui-manager", merge, g_object_unref);
  360.       gtk_ui_manager_insert_action_group (merge, action_group, 0);
  361.       gtk_window_add_accel_group (GTK_WINDOW (window), 
  362.                   gtk_ui_manager_get_accel_group (merge));
  363.       
  364.       if (!gtk_ui_manager_add_ui_from_string (merge, ui_info, -1, &error))
  365.     {
  366.       g_message ("building menus failed: %s", error->message);
  367.       g_error_free (error);
  368.     }
  369.  
  370.       bar = gtk_ui_manager_get_widget (merge, "/MenuBar");
  371.       gtk_widget_show (bar);
  372.       gtk_table_attach (GTK_TABLE (table),
  373.             bar, 
  374.                         /* X direction */          /* Y direction */
  375.                         0, 1,                      0, 1,
  376.                         GTK_EXPAND | GTK_FILL,     0,
  377.                         0,                         0);
  378.  
  379.       bar = gtk_ui_manager_get_widget (merge, "/ToolBar");
  380.       gtk_toolbar_set_tooltips (GTK_TOOLBAR (bar), TRUE);
  381.       gtk_widget_show (bar);
  382.       gtk_table_attach (GTK_TABLE (table),
  383.             bar, 
  384.                         /* X direction */       /* Y direction */
  385.                         0, 1,                   1, 2,
  386.                         GTK_EXPAND | GTK_FILL,  0,
  387.                         0,                      0);
  388.  
  389.       /* Create document
  390.        */
  391.  
  392.       sw = gtk_scrolled_window_new (NULL, NULL);
  393.  
  394.       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
  395.                                       GTK_POLICY_AUTOMATIC,
  396.                                       GTK_POLICY_AUTOMATIC);
  397.  
  398.       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
  399.                                            GTK_SHADOW_IN);
  400.       
  401.       gtk_table_attach (GTK_TABLE (table),
  402.                         sw,
  403.                         /* X direction */       /* Y direction */
  404.                         0, 1,                   2, 3,
  405.                         GTK_EXPAND | GTK_FILL,  GTK_EXPAND | GTK_FILL,
  406.                         0,                      0);
  407.  
  408.       gtk_window_set_default_size (GTK_WINDOW (window),
  409.                                    200, 200);
  410.       
  411.       contents = gtk_text_view_new ();
  412.       gtk_widget_grab_focus (contents);
  413.       
  414.       gtk_container_add (GTK_CONTAINER (sw),
  415.                          contents);
  416.  
  417.       /* Create statusbar */
  418.  
  419.       statusbar = gtk_statusbar_new ();
  420.       gtk_table_attach (GTK_TABLE (table),
  421.                         statusbar,
  422.                         /* X direction */       /* Y direction */
  423.                         0, 1,                   3, 4,
  424.                         GTK_EXPAND | GTK_FILL,  0,
  425.                         0,                      0);
  426.  
  427.       /* Show text widget info in the statusbar */
  428.       buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (contents));
  429.       
  430.       g_signal_connect_object (buffer,
  431.                                "changed",
  432.                                G_CALLBACK (update_statusbar),
  433.                                statusbar,
  434.                                0);
  435.  
  436.       g_signal_connect_object (buffer,
  437.                                "mark_set", /* cursor moved */
  438.                                G_CALLBACK (mark_set_callback),
  439.                                statusbar,
  440.                                0);
  441.  
  442.       g_signal_connect_object (window, 
  443.                    "window_state_event", 
  444.                    G_CALLBACK (update_resize_grip),
  445.                    statusbar,
  446.                    0);
  447.       
  448.       update_statusbar (buffer, GTK_STATUSBAR (statusbar));
  449.     }
  450.  
  451.   if (!GTK_WIDGET_VISIBLE (window))
  452.     {
  453.       gtk_widget_show_all (window);
  454.     }
  455.   else
  456.     {    
  457.       gtk_widget_destroy (window);
  458.       window = NULL;
  459.     }
  460.  
  461.   return window;
  462. }
  463.  
  464.