Blame demos/gtk-demo/search_entry.c

Packit 98cdb6
/* Entry/Search Entry
Packit 98cdb6
 *
Packit 98cdb6
 * GtkEntry allows to display icons and progress information.
Packit 98cdb6
 * This demo shows how to use these features in a search entry.
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#include <gtk/gtk.h>
Packit 98cdb6
Packit 98cdb6
static GtkWidget *window = NULL;
Packit 98cdb6
static GtkWidget *menu = NULL;
Packit 98cdb6
static GtkWidget *notebook = NULL;
Packit 98cdb6
Packit 98cdb6
static guint search_progress_id = 0;
Packit 98cdb6
static guint finish_search_id = 0;
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
show_find_button (void)
Packit 98cdb6
{
Packit 98cdb6
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 0);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
show_cancel_button (void)
Packit 98cdb6
{
Packit 98cdb6
  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 1);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
search_progress (gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  gtk_entry_progress_pulse (GTK_ENTRY (data));
Packit 98cdb6
Packit 98cdb6
  return TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
search_progress_done (GtkEntry *entry)
Packit 98cdb6
{
Packit 98cdb6
  gtk_entry_set_progress_fraction (entry, 0.0);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
finish_search (GtkButton *button)
Packit 98cdb6
{
Packit 98cdb6
  show_find_button ();
Packit 98cdb6
  g_source_remove (search_progress_id);
Packit 98cdb6
  search_progress_id = 0;
Packit 98cdb6
Packit 98cdb6
  return FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
start_search_feedback (gpointer data)
Packit 98cdb6
{
Packit 98cdb6
  search_progress_id = g_timeout_add_full (G_PRIORITY_DEFAULT, 100,
Packit 98cdb6
                                           (GSourceFunc)search_progress, data,
Packit 98cdb6
                                           (GDestroyNotify)search_progress_done);
Packit 98cdb6
  return FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
start_search (GtkButton *button,
Packit 98cdb6
              GtkEntry  *entry)
Packit 98cdb6
{
Packit 98cdb6
  show_cancel_button ();
Packit 98cdb6
  search_progress_id = g_timeout_add_seconds (1, (GSourceFunc)start_search_feedback, entry);
Packit 98cdb6
  finish_search_id = g_timeout_add_seconds (15, (GSourceFunc)finish_search, button);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
stop_search (GtkButton *button,
Packit 98cdb6
             gpointer   data)
Packit 98cdb6
{
Packit 98cdb6
  g_source_remove (finish_search_id);
Packit 98cdb6
  finish_search (button);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
clear_entry (GtkEntry *entry)
Packit 98cdb6
{
Packit 98cdb6
  gtk_entry_set_text (entry, "");
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
search_by_name (GtkWidget *item,
Packit 98cdb6
                GtkEntry  *entry)
Packit 98cdb6
{
Packit 98cdb6
  gtk_entry_set_icon_from_stock (entry,
Packit 98cdb6
                                 GTK_ENTRY_ICON_PRIMARY,
Packit 98cdb6
                                 GTK_STOCK_FIND);
Packit 98cdb6
  gtk_entry_set_icon_tooltip_text (entry,
Packit 98cdb6
                                   GTK_ENTRY_ICON_PRIMARY,
Packit 98cdb6
                                   "Search by name\n"
Packit 98cdb6
                                   "Click here to change the search type");
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
search_by_description (GtkWidget *item,
Packit 98cdb6
                       GtkEntry  *entry)
Packit 98cdb6
{
Packit 98cdb6
  gtk_entry_set_icon_from_stock (entry,
Packit 98cdb6
                                 GTK_ENTRY_ICON_PRIMARY,
Packit 98cdb6
                                 GTK_STOCK_EDIT);
Packit 98cdb6
  gtk_entry_set_icon_tooltip_text (entry,
Packit 98cdb6
                                   GTK_ENTRY_ICON_PRIMARY,
Packit 98cdb6
                                   "Search by description\n"
Packit 98cdb6
                                   "Click here to change the search type");
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
search_by_file (GtkWidget *item,
Packit 98cdb6
                GtkEntry  *entry)
Packit 98cdb6
{
Packit 98cdb6
  gtk_entry_set_icon_from_stock (entry,
Packit 98cdb6
                                 GTK_ENTRY_ICON_PRIMARY,
Packit 98cdb6
                                 GTK_STOCK_OPEN);
Packit 98cdb6
  gtk_entry_set_icon_tooltip_text (entry,
Packit 98cdb6
                                   GTK_ENTRY_ICON_PRIMARY,
Packit 98cdb6
                                   "Search by file name\n"
Packit 98cdb6
                                   "Click here to change the search type");
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GtkWidget *
Packit 98cdb6
create_search_menu (GtkWidget *entry)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidget *menu;
Packit 98cdb6
  GtkWidget *item;
Packit 98cdb6
  GtkWidget *image;
Packit 98cdb6
Packit 98cdb6
  menu = gtk_menu_new ();
Packit 98cdb6
Packit 98cdb6
  item = gtk_image_menu_item_new_with_mnemonic ("Search by _name");
Packit 98cdb6
  image = gtk_image_new_from_stock (GTK_STOCK_FIND, GTK_ICON_SIZE_MENU);
Packit 98cdb6
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
Packit 98cdb6
  gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (item), TRUE);
Packit 98cdb6
  g_signal_connect (item, "activate",
Packit 98cdb6
                    G_CALLBACK (search_by_name), entry);
Packit 98cdb6
  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
Packit 98cdb6
Packit 98cdb6
  item = gtk_image_menu_item_new_with_mnemonic ("Search by _description");
Packit 98cdb6
  image = gtk_image_new_from_stock (GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU);
Packit 98cdb6
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
Packit 98cdb6
  gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (item), TRUE);
Packit 98cdb6
  g_signal_connect (item, "activate",
Packit 98cdb6
                    G_CALLBACK (search_by_description), entry);
Packit 98cdb6
  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
Packit 98cdb6
Packit 98cdb6
  item = gtk_image_menu_item_new_with_mnemonic ("Search by _file name");
Packit 98cdb6
  image = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
Packit 98cdb6
  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
Packit 98cdb6
  gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (item), TRUE);
Packit 98cdb6
  g_signal_connect (item, "activate",
Packit 98cdb6
                    G_CALLBACK (search_by_file), entry);
Packit 98cdb6
  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
Packit 98cdb6
Packit 98cdb6
  gtk_widget_show_all (menu);
Packit 98cdb6
Packit 98cdb6
  return menu;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
icon_press_cb (GtkEntry       *entry,
Packit 98cdb6
               gint            position,
Packit 98cdb6
               GdkEventButton *event,
Packit 98cdb6
               gpointer        data)
Packit 98cdb6
{
Packit 98cdb6
  if (position == GTK_ENTRY_ICON_PRIMARY)
Packit 98cdb6
    gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
Packit 98cdb6
                    event->button, event->time);
Packit 98cdb6
  else
Packit 98cdb6
    clear_entry (entry);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
text_changed_cb (GtkEntry   *entry,
Packit 98cdb6
                 GParamSpec *pspec,
Packit 98cdb6
                 GtkWidget  *button)
Packit 98cdb6
{
Packit 98cdb6
  gboolean has_text;
Packit 98cdb6
Packit 98cdb6
  has_text = gtk_entry_get_text_length (entry) > 0;
Packit 98cdb6
  gtk_entry_set_icon_sensitive (entry,
Packit 98cdb6
                                GTK_ENTRY_ICON_SECONDARY,
Packit 98cdb6
                                has_text);
Packit 98cdb6
  gtk_widget_set_sensitive (button, has_text);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
activate_cb (GtkEntry  *entry,
Packit 98cdb6
             GtkButton *button)
Packit 98cdb6
{
Packit 98cdb6
  if (search_progress_id != 0)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  start_search (button, entry);
Packit 98cdb6
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
search_entry_destroyed (GtkWidget  *widget)
Packit 98cdb6
{
Packit 98cdb6
  if (finish_search_id != 0)
Packit 98cdb6
    g_source_remove (finish_search_id);
Packit 98cdb6
Packit 98cdb6
  if (search_progress_id != 0)
Packit 98cdb6
    g_source_remove (search_progress_id);
Packit 98cdb6
Packit 98cdb6
  window = NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
entry_populate_popup (GtkEntry *entry,
Packit 98cdb6
                      GtkMenu  *menu,
Packit 98cdb6
                      gpointer user_data)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidget *item;
Packit 98cdb6
  GtkWidget *search_menu;
Packit 98cdb6
  gboolean has_text;
Packit 98cdb6
Packit 98cdb6
  has_text = gtk_entry_get_text_length (entry) > 0;
Packit 98cdb6
Packit 98cdb6
  item = gtk_separator_menu_item_new ();
Packit 98cdb6
  gtk_widget_show (item);
Packit 98cdb6
  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
Packit 98cdb6
Packit 98cdb6
  item = gtk_menu_item_new_with_mnemonic ("C_lear");
Packit 98cdb6
  gtk_widget_show (item);
Packit 98cdb6
  g_signal_connect_swapped (item, "activate",
Packit 98cdb6
                            G_CALLBACK (clear_entry), entry);
Packit 98cdb6
  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
Packit 98cdb6
  gtk_widget_set_sensitive (item, has_text);
Packit 98cdb6
Packit 98cdb6
  search_menu = create_search_menu (GTK_WIDGET (entry));
Packit 98cdb6
  item = gtk_menu_item_new_with_label ("Search by");
Packit 98cdb6
  gtk_widget_show (item);
Packit 98cdb6
  gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), search_menu);
Packit 98cdb6
  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GtkWidget *
Packit 98cdb6
do_search_entry (GtkWidget *do_widget)
Packit 98cdb6
{
Packit 98cdb6
  GtkWidget *vbox;
Packit 98cdb6
  GtkWidget *hbox;
Packit 98cdb6
  GtkWidget *label;
Packit 98cdb6
  GtkWidget *entry;
Packit 98cdb6
  GtkWidget *find_button;
Packit 98cdb6
  GtkWidget *cancel_button;
Packit 98cdb6
Packit 98cdb6
  if (!window)
Packit 98cdb6
    {
Packit 98cdb6
      window = gtk_dialog_new_with_buttons ("Search Entry",
Packit 98cdb6
                                            GTK_WINDOW (do_widget),
Packit 98cdb6
                                            0,
Packit 98cdb6
                                            GTK_STOCK_CLOSE,
Packit 98cdb6
                                            GTK_RESPONSE_NONE,
Packit 98cdb6
                                            NULL);
Packit 98cdb6
      gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
Packit 98cdb6
Packit 98cdb6
      g_signal_connect (window, "response",
Packit 98cdb6
                        G_CALLBACK (gtk_widget_destroy), NULL);
Packit 98cdb6
      g_signal_connect (window, "destroy",
Packit 98cdb6
                        G_CALLBACK (search_entry_destroyed), &window);
Packit 98cdb6
Packit 98cdb6
      vbox = gtk_vbox_new (FALSE, 5);
Packit 98cdb6
      gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (window))), vbox, TRUE, TRUE, 0);
Packit 98cdb6
      gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
Packit 98cdb6
Packit 98cdb6
      label = gtk_label_new (NULL);
Packit 98cdb6
      gtk_label_set_markup (GTK_LABEL (label), "Search entry demo");
Packit 98cdb6
      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
Packit 98cdb6
Packit 98cdb6
      hbox = gtk_hbox_new (FALSE, 10);
Packit 98cdb6
      gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
Packit 98cdb6
      gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
Packit 98cdb6
Packit 98cdb6
      /* Create our entry */
Packit 98cdb6
      entry = gtk_entry_new ();
Packit 98cdb6
      gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
Packit 98cdb6
Packit 98cdb6
      /* Create the find and cancel buttons */
Packit 98cdb6
      notebook = gtk_notebook_new ();
Packit 98cdb6
      gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
Packit 98cdb6
      gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
Packit 98cdb6
      gtk_box_pack_start (GTK_BOX (hbox), notebook, FALSE, FALSE, 0);
Packit 98cdb6
Packit 98cdb6
      find_button = gtk_button_new_with_label ("Find");
Packit 98cdb6
      g_signal_connect (find_button, "clicked",
Packit 98cdb6
                        G_CALLBACK (start_search), entry);
Packit 98cdb6
      gtk_notebook_append_page (GTK_NOTEBOOK (notebook), find_button, NULL);
Packit 98cdb6
      gtk_widget_show (find_button);
Packit 98cdb6
Packit 98cdb6
      cancel_button = gtk_button_new_with_label ("Cancel");
Packit 98cdb6
      g_signal_connect (cancel_button, "clicked",
Packit 98cdb6
                        G_CALLBACK (stop_search), NULL);
Packit 98cdb6
      gtk_notebook_append_page (GTK_NOTEBOOK (notebook), cancel_button, NULL);
Packit 98cdb6
      gtk_widget_show (cancel_button);
Packit 98cdb6
Packit 98cdb6
      /* Set up the search icon */
Packit 98cdb6
      search_by_name (NULL, GTK_ENTRY (entry));
Packit 98cdb6
Packit 98cdb6
      /* Set up the clear icon */
Packit 98cdb6
      gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
Packit 98cdb6
                                     GTK_ENTRY_ICON_SECONDARY,
Packit 98cdb6
                                     GTK_STOCK_CLEAR);
Packit 98cdb6
      text_changed_cb (GTK_ENTRY (entry), NULL, find_button);
Packit 98cdb6
Packit 98cdb6
      g_signal_connect (entry, "icon-press",
Packit 98cdb6
                        G_CALLBACK (icon_press_cb), NULL);
Packit 98cdb6
      g_signal_connect (entry, "notify::text",
Packit 98cdb6
                        G_CALLBACK (text_changed_cb), find_button);
Packit 98cdb6
      g_signal_connect (entry, "activate",
Packit 98cdb6
                        G_CALLBACK (activate_cb), NULL);
Packit 98cdb6
Packit 98cdb6
      /* Create the menu */
Packit 98cdb6
      menu = create_search_menu (entry);
Packit 98cdb6
      gtk_menu_attach_to_widget (GTK_MENU (menu), entry, NULL);
Packit 98cdb6
Packit 98cdb6
      /* add accessible alternatives for icon functionality */
Packit 98cdb6
      g_signal_connect (entry, "populate-popup",
Packit 98cdb6
                        G_CALLBACK (entry_populate_popup), NULL);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (!gtk_widget_get_visible (window))
Packit 98cdb6
    gtk_widget_show_all (window);
Packit 98cdb6
  else
Packit 98cdb6
    {
Packit 98cdb6
      gtk_widget_destroy (menu);
Packit 98cdb6
      gtk_widget_destroy (window);
Packit 98cdb6
      window = NULL;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return window;
Packit 98cdb6
}