Beispiel #1
0
static void
gimp_tag_popup_dispose (GObject *object)
{
  GimpTagPopup *popup = GIMP_TAG_POPUP (object);

  gimp_tag_popup_remove_scroll_timeout (popup);

  if (popup->combo_entry)
    {
      g_object_unref (popup->combo_entry);
      popup->combo_entry = NULL;
    }

  if (popup->layout)
    {
      g_object_unref (popup->layout);
      popup->layout = NULL;
    }

  if (popup->context)
    {
      g_object_unref (popup->context);
      popup->context = NULL;
    }

  if (popup->tag_data)
    {
      g_free (popup->tag_data);
      popup->tag_data = NULL;
    }

  G_OBJECT_CLASS (parent_class)->dispose (object);
}
Beispiel #2
0
static void
gimp_combo_tag_entry_icon_press (GtkWidget            *widget,
                                 GtkEntryIconPosition  icon_pos,
                                 GdkEvent             *event,
                                 gpointer              user_data)
{
  GimpComboTagEntry *entry = GIMP_COMBO_TAG_ENTRY (widget);

  if (! entry->popup)
    {
      GimpTaggedContainer *container = GIMP_TAG_ENTRY (entry)->container;
      gint                 tag_count;

      tag_count = gimp_tagged_container_get_tag_count (container);

      if (tag_count > 0 && ! GIMP_TAG_ENTRY (entry)->has_invalid_tags)
        {
          entry->popup = gimp_tag_popup_new (entry);
          g_signal_connect (entry->popup, "destroy",
                            G_CALLBACK (gimp_combo_tag_entry_popup_destroy),
                            entry);
          gimp_tag_popup_show (GIMP_TAG_POPUP (entry->popup));
        }
    }
  else
    {
      gtk_widget_destroy (entry->popup);
    }
}
Beispiel #3
0
static void
gimp_tag_popup_get_property (GObject    *object,
                             guint       property_id,
                             GValue     *value,
                             GParamSpec *pspec)
{
  GimpTagPopup *popup = GIMP_TAG_POPUP (object);

  switch (property_id)
    {
    case PROP_OWNER:
      g_value_set_object (value, popup->combo_entry);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}
Beispiel #4
0
static gboolean
gimp_tag_popup_border_event (GtkWidget *widget,
                             GdkEvent  *event)
{
  GimpTagPopup *popup = GIMP_TAG_POPUP (widget);

  if (event->type == GDK_BUTTON_PRESS)
    {
      GdkEventButton *button_event = (GdkEventButton *) event;
      GtkAllocation   allocation;
      gint            x;
      gint            y;

      if (button_event->window == gtk_widget_get_window (widget) &&
          gimp_tag_popup_button_scroll (popup, button_event))
        {
          return TRUE;
        }

      gtk_widget_get_allocation (widget, &allocation);

      gdk_window_get_pointer (gtk_widget_get_window (widget), &x, &y, NULL);

      if (button_event->window != gtk_widget_get_window (popup->tag_area) &&
          (x < allocation.y                    ||
           y < allocation.x                    ||
           x > allocation.x + allocation.width ||
           y > allocation.y + allocation.height))
        {
          /* user has clicked outside the popup area,
           * which means it should be hidden.
           */
          gtk_grab_remove (widget);
          gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
                                      GDK_CURRENT_TIME);
          gtk_widget_destroy (widget);
        }
    }
  else if (event->type == GDK_MOTION_NOTIFY)
    {
      GdkEventMotion *motion_event = (GdkEventMotion *) event;
      gint            x, y;

      gdk_window_get_pointer (gtk_widget_get_window (widget), &x, &y, NULL);

      gimp_tag_popup_handle_scrolling (popup, x, y,
                                       motion_event->window ==
                                       gtk_widget_get_window (widget),
                                       TRUE);
    }
  else if (event->type == GDK_BUTTON_RELEASE)
    {
      GdkEventButton *button_event = (GdkEventButton *) event;

      popup->single_select_disabled = TRUE;

      if (button_event->window == gtk_widget_get_window (widget) &&
          gimp_tag_popup_button_scroll (popup, button_event))
        {
          return TRUE;
        }
    }
  else if (event->type == GDK_GRAB_BROKEN)
    {
      gtk_grab_remove (widget);
      gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
                                  GDK_CURRENT_TIME);
      gtk_widget_destroy (widget);
    }
  else if (event->type == GDK_KEY_PRESS)
    {
      gtk_grab_remove (widget);
      gdk_display_pointer_ungrab (gtk_widget_get_display (widget),
                                  GDK_CURRENT_TIME);
      gtk_widget_destroy (widget);
    }
  else if (event->type == GDK_SCROLL)
    {
      GdkEventScroll *scroll_event = (GdkEventScroll *) event;

      switch (scroll_event->direction)
        {
        case GDK_SCROLL_RIGHT:
        case GDK_SCROLL_DOWN:
          gimp_tag_popup_scroll_by (popup, MENU_SCROLL_STEP2);
          return TRUE;

        case GDK_SCROLL_LEFT:
        case GDK_SCROLL_UP:
          gimp_tag_popup_scroll_by (popup, - MENU_SCROLL_STEP2);
          return TRUE;
        }
    }

  return FALSE;
}
Beispiel #5
0
static void
gimp_tag_popup_constructed (GObject *object)
{
  GimpTagPopup        *popup = GIMP_TAG_POPUP (object);
  GimpTaggedContainer *container;
  GtkWidget           *entry;
  GtkAllocation        entry_allocation;
  GtkStyle            *frame_style;
  gint                 x;
  gint                 y;
  gint                 width;
  gint                 height;
  gint                 popup_height;
  GHashTable          *tag_hash;
  GList               *tag_list;
  GList               *tag_iterator;
  gint                 i;
  gint                 max_height;
  gint                 screen_height;
  gchar              **current_tags;
  gint                 current_count;
  GdkRectangle         popup_rects[2]; /* variants of popup placement */
  GdkRectangle         popup_rect; /* best popup rect in screen coordinates */

  if (G_OBJECT_CLASS (parent_class)->constructed)
    G_OBJECT_CLASS (parent_class)->constructed (object);

  entry = GTK_WIDGET (popup->combo_entry);

  gtk_window_set_screen (GTK_WINDOW (popup), gtk_widget_get_screen (entry));

  popup->context = gtk_widget_create_pango_context (GTK_WIDGET (popup));
  popup->layout  = pango_layout_new (popup->context);

  gtk_widget_get_allocation (entry, &entry_allocation);

  gtk_widget_style_get (GTK_WIDGET (popup),
                        "scroll-arrow-vlength", &popup->scroll_arrow_height,
                        NULL);

  pango_layout_set_attributes (popup->layout,
                               popup->combo_entry->normal_item_attr);

  current_tags  = gimp_tag_entry_parse_tags (GIMP_TAG_ENTRY (popup->combo_entry));
  current_count = g_strv_length (current_tags);

  container = GIMP_TAG_ENTRY (popup->combo_entry)->container;

  tag_hash = container->tag_ref_counts;
  tag_list = g_hash_table_get_keys (tag_hash);
  tag_list = g_list_sort (tag_list, gimp_tag_compare_func);

  popup->tag_count = g_list_length (tag_list);
  popup->tag_data  = g_new0 (PopupTagData, popup->tag_count);

  for (i = 0, tag_iterator = tag_list;
       i < popup->tag_count;
       i++, tag_iterator = g_list_next (tag_iterator))
    {
      PopupTagData *tag_data = &popup->tag_data[i];
      gint          j;

      tag_data->tag   = tag_iterator->data;
      tag_data->state = GTK_STATE_NORMAL;

      for (j = 0; j < current_count; j++)
        {
          if (! gimp_tag_compare_with_string (tag_data->tag, current_tags[j]))
            {
              tag_data->state = GTK_STATE_SELECTED;
              break;
            }
        }
    }

  g_list_free (tag_list);
  g_strfreev (current_tags);

  if (GIMP_TAG_ENTRY (popup->combo_entry)->mode == GIMP_TAG_ENTRY_MODE_QUERY)
    {
      for (i = 0; i < popup->tag_count; i++)
        {
          if (popup->tag_data[i].state != GTK_STATE_SELECTED)
            {
              popup->tag_data[i].state = GTK_STATE_INSENSITIVE;
            }
        }

      gimp_container_foreach (GIMP_CONTAINER (container),
                              (GFunc) gimp_tag_popup_check_can_toggle,
                              popup);
    }

  frame_style = gtk_widget_get_style (popup->frame);

  width  = (entry_allocation.width -
            2 * frame_style->xthickness);
  height = (gimp_tag_popup_layout_tags (popup, width) +
            2 * frame_style->ythickness);

  gdk_window_get_origin (gtk_widget_get_window (entry), &x, &y);

  max_height = entry_allocation.height * 10;

  screen_height = gdk_screen_get_height (gtk_widget_get_screen (entry));

  popup_height = MIN (height, max_height);

  popup_rects[0].x      = x;
  popup_rects[0].y      = 0;
  popup_rects[0].width  = entry_allocation.width;
  popup_rects[0].height = y + entry_allocation.height;

  popup_rects[1].x      = x;
  popup_rects[1].y      = y;
  popup_rects[1].width  = popup_rects[0].width;
  popup_rects[1].height = screen_height - popup_rects[0].height;

  if (popup_rects[0].height >= popup_height)
    {
      popup_rect = popup_rects[0];
      popup_rect.y += popup_rects[0].height - popup_height;
      popup_rect.height = popup_height;
    }
  else if (popup_rects[1].height >= popup_height)
    {
      popup_rect = popup_rects[1];
      popup_rect.height = popup_height;
    }
  else
    {
      if (popup_rects[0].height >= popup_rects[1].height)
        {
          popup_rect = popup_rects[0];
          popup_rect.y += popup->scroll_arrow_height + frame_style->ythickness;
        }
      else
        {
          popup_rect = popup_rects[1];
          popup_rect.y -= popup->scroll_arrow_height + frame_style->ythickness;
        }

      popup_height = popup_rect.height;
    }

  if (popup_height < height)
    {
      popup->arrows_visible    = TRUE;
      popup->upper_arrow_state = GTK_STATE_INSENSITIVE;

      gtk_alignment_set_padding (GTK_ALIGNMENT (popup->alignment),
                                 popup->scroll_arrow_height + 2,
                                 popup->scroll_arrow_height + 2, 0, 0);

      popup_height -= 2 * popup->scroll_arrow_height + 4;

      popup->scroll_height = height - popup_rect.height;
      popup->scroll_y      = 0;
      popup->scroll_step   = 0;
    }

  gtk_widget_set_size_request (popup->tag_area, width, popup_height);

  gtk_window_move (GTK_WINDOW (popup), popup_rect.x, popup_rect.y);
  gtk_window_resize (GTK_WINDOW (popup), popup_rect.width, popup_rect.height);
}