static void
gstyle_color_widget_rgba_notify_cb (GstyleColorWidget *self,
                                    GParamSpec        *pspec,
                                    GstyleColor       *color)
{
  GdkRGBA rgba;

  g_assert (GSTYLE_IS_COLOR_WIDGET (self));
  g_assert (G_IS_PARAM_SPEC (pspec));
  g_assert (GSTYLE_IS_COLOR (color));

  if (self->filter_func != NULL && GSTYLE_IS_COLOR (self->filtered_color))
    {
      gstyle_color_fill_rgba (color, &rgba);
      self->filter_func (&rgba, &rgba, self->filter_user_data);
      gstyle_color_set_rgba (self->filtered_color, &rgba);
    }

  update_label_visibility (self);

  if (self->filter_func != NULL && GSTYLE_IS_COLOR (self->filtered_color))
    match_label_color (self, self->filtered_color);
  else
    match_label_color (self, color);

  gtk_widget_queue_draw (GTK_WIDGET (self));
}
/**
 * gstyle_color_widget_set_color:
 * @self: A #GstyleColorWidget
 * @color: (nullable): A #GstyleColor or %NULL
 *
 * Set the #GstyleColor for the #GstyleColorWidget.
 *
 */
void
gstyle_color_widget_set_color (GstyleColorWidget *self,
                               GstyleColor       *color)
{
  GdkRGBA rgba;

  g_return_if_fail (GSTYLE_IS_COLOR_WIDGET (self));
  g_return_if_fail (GSTYLE_IS_COLOR (color) || color == NULL);

  if (self->color != color)
    {
      if (self->color != NULL)
        {
          gstyle_color_widget_disconnect_color (self);
          g_clear_object (&self->color);
        }

      if (color != NULL)
        {
          self->color = g_object_ref (color);
          if (self->filter_func != NULL)
            {
              gstyle_color_fill_rgba (color, &rgba);
              self->filter_func (&rgba, &rgba, self->filter_user_data);

              g_clear_object (&self->filtered_color);
              self->filtered_color = gstyle_color_copy (color);
              gstyle_color_set_rgba (self->filtered_color, &rgba);
            }

          g_signal_connect_object (self->color,
                                   "notify::rgba",
                                   G_CALLBACK (gstyle_color_widget_rgba_notify_cb),
                                   self,
                                   G_CONNECT_SWAPPED);

          g_signal_connect_object (self->color,
                                   "notify::name",
                                   G_CALLBACK (gstyle_color_widget_name_notify_cb),
                                   self,
                                   G_CONNECT_SWAPPED);

          if (self->filter_func != NULL && GSTYLE_IS_COLOR (self->filtered_color))
            match_label_color (self, self->filtered_color);
          else
            match_label_color (self, color);
        }

      update_label_visibility (self);
      g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COLOR]);
    }
}
Example #3
0
/**
 * gstyle_palette_remove:
 * @self: a #GstylePalette
 * @color: A #GstyleColor
 *
 * Try to remove a #GstyleColor from the palette.
 *
 * Returns: %TRUE on succes, %FALSE otherwise.
 */
gboolean
gstyle_palette_remove (GstylePalette  *self,
                       GstyleColor    *color)
{
  GPtrArray *array;

  g_return_val_if_fail (GSTYLE_IS_PALETTE (self), FALSE);
  g_return_val_if_fail (GSTYLE_IS_COLOR (color), FALSE);

  array = self->colors;
  for (gint i = 0; i < array->len; ++i)
    {
      if (array->pdata[i] == color)
        {
          remove_color_to_names_sets (self, color);
          g_ptr_array_remove_index (array, i);
          g_list_model_items_changed (G_LIST_MODEL (self), i, 1, 0);
          gstyle_palette_set_changed (self, TRUE);

          return TRUE;
        }
    }

  return FALSE;
}
Example #4
0
static gboolean
remove_color_to_names_sets (GstylePalette *self,
                            GstyleColor   *color)
{
  const gchar *name;
  GPtrArray *set;
  gboolean ret = FALSE;

  g_assert (GSTYLE_IS_PALETTE (self));
  g_assert (GSTYLE_IS_COLOR (color));

  name = gstyle_color_get_name (color);
  if (gstyle_str_empty0 (name))
    return FALSE;

  set = g_hash_table_lookup (self->color_names, name);
  if (set == NULL)
    return FALSE;

  ret = g_ptr_array_remove (set, color);
  if (set->len == 0)
    {
      g_ptr_array_unref (set);
      g_hash_table_remove (self->color_names, name);
    }

  return ret;
}
static void
match_label_color (GstyleColorWidget *self,
                   GstyleColor       *color)
{
  PangoLayout *layout;
  PangoAttrList *attr_list;
  PangoAttribute *attr;
  GdkRGBA rgba;
  GdkRGBA dst_rgba;

  g_assert (GSTYLE_IS_COLOR_WIDGET (self));
  g_assert (GSTYLE_IS_COLOR (color));

  layout = gtk_label_get_layout (self->label);
  attr_list = pango_layout_get_attributes (layout);
  if (attr_list == NULL)
    {
      attr_list = pango_attr_list_new ();
      gtk_label_set_attributes (self->label, attr_list);
      pango_attr_list_unref (attr_list);
    }

  gstyle_color_fill_rgba (color, &rgba);
  gstyle_utils_get_contrasted_rgba (rgba, &dst_rgba);
  attr = pango_attr_foreground_new (dst_rgba.red * 0xffff, dst_rgba.green * 0xffff, dst_rgba.blue * 0xffff);
  pango_attr_list_change (attr_list, attr);
  attr = pango_attr_background_new (rgba.red * 0xffff, rgba.green * 0xffff, rgba.blue * 0xffff);
  pango_attr_list_change (attr_list, attr);
}
static void
update_label_visibility (GstyleColorWidget *self)
{
  const gchar *color_name;
  g_autofree gchar *fallback_name = NULL;

  g_assert (GSTYLE_IS_COLOR_WIDGET (self));

  if (self->color == NULL)
    {
      if (gtk_widget_is_visible (GTK_WIDGET (self->label)))
        gtk_widget_hide (GTK_WIDGET (self->label));

      return;
    }

  if (self->is_name_visible)
    {
      if (self->filter_func != NULL && GSTYLE_IS_COLOR (self->filtered_color))
        color_name = gstyle_color_get_name (self->filtered_color);
      else
        color_name = gstyle_color_get_name (self->color);

      if (color_name != NULL)
        {
          gtk_label_set_text (self->label, color_name);
          if (!gtk_widget_is_visible (GTK_WIDGET (self->label)))
            gtk_widget_show (GTK_WIDGET (self->label));

          return;
        }
    }

  if (self->is_fallback_name_visible)
    {
      if (self->filter_func != NULL && GSTYLE_IS_COLOR (self->filtered_color))
        fallback_name = gstyle_color_to_string (self->filtered_color, self->fallback_name_kind);
      else
        fallback_name = gstyle_color_to_string (self->color, self->fallback_name_kind);

      gtk_label_set_text (self->label, fallback_name);
      if (!gtk_widget_is_visible (GTK_WIDGET (self->label)))
        gtk_widget_show (GTK_WIDGET (self->label));
    }
  else
    gtk_widget_hide (GTK_WIDGET (self->label));
}
/**
 * gstyle_color_widget_new_with_color:
 * @color: A #GstyleColor
 *
 * Returns: A new #GstyleColorWidget.with @color affected.
 *
 */
GstyleColorWidget *
gstyle_color_widget_new_with_color (GstyleColor *color)
{
  g_return_val_if_fail (GSTYLE_IS_COLOR (color), NULL);

  return g_object_new (GSTYLE_TYPE_COLOR_WIDGET,
                       "color", color,
                       NULL);
}
Example #8
0
/**
 * gstyle_palette_add:
 * @self: a #GstylePalette
 * @color: A #GstyleColor
 * @error: (nullable): a #GError location or %NULL
 *
 * Add a #GstyleColor to the palette.
 *
 * Returns: %TRUE on succes, %FALSE otherwise.
 */
gboolean
gstyle_palette_add (GstylePalette  *self,
                    GstyleColor    *color,
                    GError        **error)
{
  g_return_val_if_fail (GSTYLE_IS_PALETTE (self), FALSE);
  g_return_val_if_fail (GSTYLE_IS_COLOR (color), FALSE);

  return gstyle_palette_add_at_index (self, color, -1, error);
}
static void
gstyle_color_widget_name_notify_cb (GstyleColorWidget *self,
                                    GParamSpec        *pspec,
                                    GstyleColor       *color)
{
  g_assert (GSTYLE_IS_COLOR_WIDGET (self));
  g_assert (G_IS_PARAM_SPEC (pspec));
  g_assert (GSTYLE_IS_COLOR (color));

  update_label_visibility (self);
}
static void
gstyle_color_widget_disconnect_color (GstyleColorWidget *self)
{
  g_assert (GSTYLE_IS_COLOR_WIDGET (self));
  g_assert (GSTYLE_IS_COLOR (self->color));

  g_signal_handlers_disconnect_by_func (self->color,
                                        G_CALLBACK (gstyle_color_widget_rgba_notify_cb),
                                        self);

 g_signal_handlers_disconnect_by_func (self->color,
                                       G_CALLBACK (gstyle_color_widget_name_notify_cb),
                                       self);
}
static void
gstyle_color_widget_on_drag_data_get (GtkWidget        *widget,
                                      GdkDragContext   *context,
                                      GtkSelectionData *data,
                                      guint             info,
                                      guint             time)
{
  GstyleColorWidget *self = (GstyleColorWidget *)widget;
  GdkAtom target = gtk_selection_data_get_target (data);
  GstyleColor *color;
  guint16 data_rgba[4];
  GdkRGBA rgba;

  g_assert (GSTYLE_IS_COLOR_WIDGET (self));
  g_assert (GDK_IS_DRAG_CONTEXT (context));

  if (self->filter_func != NULL && GSTYLE_IS_COLOR (self->filtered_color))
    color = self->filtered_color;
  else
    color = self->color;

  if (target == gdk_atom_intern_static_string ("GSTYLE_COLOR_WIDGET"))
    gtk_selection_data_set (data, target, 8, (void*)&color, sizeof (gpointer));
  else if (target == gdk_atom_intern_static_string ("application/x-color"))
    {
      gstyle_color_fill_rgba (color, &rgba);
      data_rgba[0] = (guint16) (rgba.red * 65535);
      data_rgba[1] = (guint16) (rgba.green * 65535);
      data_rgba[2] = (guint16) (rgba.blue * 65535);
      data_rgba[3] = (guint16) (rgba.alpha * 65535);

      gtk_selection_data_set (data, target, 16, (void*)&data_rgba, 8);
    }
  else if (gtk_targets_include_text (&target, 1))
    {
      g_autofree gchar *name = NULL;

      name = gstyle_color_to_string (color, GSTYLE_COLOR_KIND_ORIGINAL);
      if (name == NULL)
        name = gstyle_color_to_string (color, GSTYLE_COLOR_KIND_RGB_HEX6);

      gtk_selection_data_set_text (data, name, -1);
    }
}
Example #12
0
gboolean
gstyle_utils_is_array_contains_same_color (GPtrArray   *ar,
                                           GstyleColor *color)
{
  GstyleColor *tmp_color;
  GdkRGBA color_rgba;
  GdkRGBA tmp_rgba;

  g_return_val_if_fail (GSTYLE_IS_COLOR (color), FALSE);
  g_return_val_if_fail (ar != NULL, FALSE);

  gstyle_color_fill_rgba (color, &color_rgba);

  for (gint i = 0; i < ar->len; ++i)
    {
      tmp_color = g_ptr_array_index (ar, i);
      gstyle_color_fill_rgba (tmp_color, &tmp_rgba);
      if (gdk_rgba_equal (&color_rgba, &tmp_rgba))
        return TRUE;
    }

  return FALSE;
}
Example #13
0
/**
 * gstyle_palette_add_at_index:
 * @self: a #GstylePalette
 * @color: A #GstyleColor
 * @position: Position to insert the new color, from 0 to gstyle_palette_get_len() -1,
 *   or -1 to append it
 * @error: (nullable): a #GError location or %NULL
 *
 * Add a #GstyleColor to the palette.
 *
 * Returns: %TRUE on succes, %FALSE otherwise.
 */
gboolean
gstyle_palette_add_at_index (GstylePalette  *self,
                             GstyleColor    *color,
                             gint            position,
                             GError        **error)
{
  g_return_val_if_fail (GSTYLE_IS_PALETTE (self), FALSE);
  g_return_val_if_fail (GSTYLE_IS_COLOR (color), FALSE);

  /* If we are just after the last position, we in fact do an append */
  if (position == self->colors->len)
    position = -1;

  if (position == -1 ||
      (position == 0 && self->colors->len == 0) ||
      (0 <= position && position < self->colors->len))
    {
      g_object_ref (color);
      g_ptr_array_insert (self->colors, position, color);
      add_color_to_names_sets (self, color);
      gstyle_palette_set_changed (self, TRUE);

      position = (position == -1) ? self->colors->len - 1 : position;
      g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);

      return TRUE;
    }
  else
    {
      g_warning ("Color inserted in palette '%s' at out-of-bounds position %i in (0, %i)\n",
                 gstyle_palette_get_name (self),
                 position, self->colors->len - 1);

      return FALSE;
     }
}
Example #14
0
/* TODO: add an unnamed category ? */
static gboolean
add_color_to_names_sets (GstylePalette *self,
                         GstyleColor   *color)
{
  const gchar *name;
  GPtrArray *set;

  g_assert (GSTYLE_IS_PALETTE (self));
  g_assert (GSTYLE_IS_COLOR (color));

  name = gstyle_color_get_name (color);
  if (gstyle_str_empty0 (name))
    return FALSE;

  set = g_hash_table_lookup (self->color_names, name);
  if (set == NULL)
    {
      set = g_ptr_array_new ();
      g_hash_table_insert (self->color_names, (gpointer)name, set);
    }

  g_ptr_array_add (set, color);
  return TRUE;
}
void
gb_color_picker_document_monitor_set_color_tag_at_cursor (GbColorPickerDocumentMonitor *self,
                                                          GstyleColor                  *color)
{
  GtkTextMark *insert;
  GtkTextIter cursor;

  g_return_if_fail (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
  g_return_if_fail (GSTYLE_IS_COLOR (color));
  g_return_if_fail (self->buffer != NULL);

  insert = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER(self->buffer));
  gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER(self->buffer), &cursor, insert);

  if (!self->is_in_user_action)
    {
      gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (self->buffer));
      self->is_in_user_action = TRUE;
    }

  block_signals (self, self->buffer);
  gb_color_picker_helper_set_color_tag_at_iter (&cursor, color, TRUE);
  unblock_signals (self, self->buffer);
}
static void
gstyle_color_widget_drag_gesture_update (GtkGestureDrag    *gesture,
                                         gdouble            offset_x,
                                         gdouble            offset_y,
                                         GstyleColorWidget *self)
{
  GdkDragContext *context;
  GdkEventSequence *sequence;
  const GdkEvent *event;
  gdouble start_x, start_y;
  GtkAllocation allocation;
  GstylePaletteWidgetDndLockFlags dnd_lock;
  GtkWidget *container;
  GdkDragAction drag_action;
  gint button;

  g_assert (GTK_IS_GESTURE (gesture));
  g_assert (GSTYLE_IS_COLOR_WIDGET (self));

  dnd_lock = get_palette_widget_dnd_lock (self);
  if ((dnd_lock & GSTYLE_PALETTE_WIDGET_DND_LOCK_FLAGS_DRAG) != 0)
    return;

  button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
  if (!gtk_drag_check_threshold (GTK_WIDGET (self), 0, 0, offset_x, offset_y) ||
      button != GDK_BUTTON_PRIMARY)
    return;

  gtk_widget_get_allocation (GTK_WIDGET (self), &allocation);
  self->dnd_color_widget = gstyle_color_widget_copy (self);

  if (self->filter_func != NULL && GSTYLE_IS_COLOR (self->filtered_color))
    gstyle_color_widget_set_color (self->dnd_color_widget, self->filtered_color);

  self->dnd_window = gtk_window_new (GTK_WINDOW_POPUP);

  gtk_widget_set_size_request (self->dnd_window, allocation.width, allocation.height);
  gtk_window_set_screen (GTK_WINDOW (self->dnd_window), gtk_widget_get_screen (GTK_WIDGET (self)));

  gtk_container_add (GTK_CONTAINER (self->dnd_window), GTK_WIDGET (self->dnd_color_widget));
  gtk_widget_show_all (self->dnd_window);
  gtk_widget_set_opacity (self->dnd_window, GSTYLE_COLOR_WIDGET_DRAG_ICON_OPACITY);

  sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
  gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (gesture), &start_x, &start_y);
  event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);

  container = gtk_widget_get_ancestor (GTK_WIDGET (self), GSTYLE_TYPE_PALETTE_WIDGET);
  if (container != NULL && GSTYLE_IS_PALETTE_WIDGET (container))
    drag_action = (GDK_ACTION_MOVE | GDK_ACTION_COPY);
  else
    drag_action = GDK_ACTION_COPY;

  context = gtk_drag_begin_with_coordinates (GTK_WIDGET (self),
                                             self->target_list,
                                             drag_action,
                                             button,
                                             (GdkEvent*)event,
                                             start_x, start_y);

  gtk_drag_set_icon_widget (context, self->dnd_window, 0, 0);
}