<commit_before>/* nbtk-button.c: Plain button actor
 *
 * Copyright (C) 2007 OpenedHand
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Written by: <NAME> <<EMAIL>>
 *             <NAME> <<EMAIL>>
 */


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdlib.h>
#include <string.h>

#include <glib.h>

#include <clutter/clutter.h>
#include <clutter/clutter-container.h>

#include "nbtk-button.h"

#include "nbtk-marshal.h"
#include "nbtk-stylable.h"
#include "nbtk-texture-frame.h"
#include "nbtk-texture-cache.h"

enum
{
  PROP_0,

  PROP_LABEL
};

enum
{
  CLICKED,

  LAST_SIGNAL
};

#define NBTK_BUTTON_GET_PRIVATE(obj)    \
        (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NBTK_TYPE_BUTTON, NbtkButtonPrivate))

struct _NbtkButtonPrivate
{
  gchar *text;

  ClutterActor *label;
  ClutterTimeline *timeline;
  ClutterEffectTemplate *press_tmpl;

  guint8 old_opacity;

  guint is_pressed : 1;
  guint is_hover : 1;

  ClutterActor     *bg_image;
  ClutterActor     *old_bg;
  ClutterColor     *bg_color;
};

static guint button_signals[LAST_SIGNAL] = { 0, };


G_DEFINE_TYPE (NbtkButton, nbtk_button, NBTK_TYPE_WIDGET)

static void
style_changed_completed_effect (ClutterActor *actor, NbtkButton *button)
{
  NbtkButtonPrivate *priv = NBTK_BUTTON_GET_PRIVATE (button);

  if (priv->old_bg)
    g_object_unref (priv->old_bg);
  priv->old_bg = NULL;
}

static void
nbtk_button_style_changed (NbtkWidget *button)
{
  ClutterColor *real_color;
  gchar *bg_url = NULL;
  NbtkButtonPrivate *priv = NBTK_BUTTON_GET_PRIVATE (button);

  /* update the label styling */
  nbtk_stylable_get (NBTK_STYLABLE (button),
                     "color", &real_color,
                     NULL);
  g_object_set (G_OBJECT (priv->label),
                "color", real_color,
                NULL);
  clutter_color_free (real_color);

  if (priv->bg_color)
    {
      clutter_color_free (priv->bg_color);
      priv->bg_color = NULL;
    }

  /* cache these values for use in the paint function */
  nbtk_stylable_get (NBTK_STYLABLE (button),
                    "background-color", &priv->bg_color,
                    "background-image", &bg_url,
                    NULL);

  if (bg_url)
    {
      NbtkTextureCache *cache;
      ClutterActor *texture;

      if (priv->bg_image)
        priv->old_bg = priv->bg_image;

      cache = nbtk_texture_cache_get_default ();

      /* the TextureFrame doesn't work with texture clones as it only
       * references the texture data */
      texture = nbtk_texture_cache_get_texture (cache, bg_url, FALSE);

      priv->bg_image = nbtk_texture_frame_new (CLUTTER_TEXTURE (texture),
                                               0, 0, 0, 0);
      g_object_unref (texture);
      clutter_actor_set_opacity (CLUTTER_ACTOR (priv->bg_image), 0);
      clutter_actor_set_parent (CLUTTER_ACTOR (priv->bg_image),
                                CLUTTER_ACTOR (button));
      g_free (bg_url);

      if (G_UNLIKELY (!priv->press_tmpl))
        {
          priv->timeline = clutter_timeline_new_for_duration (100);
          priv->press_tmpl = clutter_effect_template_new (priv->timeline,
                                                          clutter_sine_inc_func);
          clutter_effect_template_set_timeline_clone (priv->press_tmpl, FALSE);
        }

      if (clutter_timeline_is_playing (priv->timeline))
        {
          clutter_timeline_stop (priv->timeline);
	  /* in case we stopped the timeline before old_bg was fully opaque */
	  clutter_actor_set_opacity (priv->old_bg, 0xff);
        }

      clutter_effect_fade (priv->press_tmpl, priv->bg_image,
                           0xff,
                           (ClutterEffectCompleteFunc) style_changed_completed_effect, button);

    }

  /* queue a relayout, which also calls redraw */
  clutter_actor_queue_relayout (CLUTTER_ACTOR (button));

 
  if (NBTK_WIDGET_CLASS (nbtk_button_parent_class)->style_changed)
    NBTK_WIDGET_CLASS (nbtk_button_parent_class)->style_changed (button);
}

static void
nbtk_button_paint (ClutterActor *actor)
{
  NbtkButton *button = NBTK_BUTTON (actor);
  NbtkButtonPrivate *priv = button->priv;

  if (priv->bg_image)
    {<commit_msg>Remove the background if the new style does not have background-image set<commit_after>/* nbtk-button.c: Plain button actor
 *
 * Copyright (C) 2007 OpenedHand
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Written by: <NAME> <<EMAIL>>
 *             <NAME> <<EMAIL>>
 */


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdlib.h>
#include <string.h>

#include <glib.h>

#include <clutter/clutter.h>
#include <clutter/clutter-container.h>

#include "nbtk-button.h"

#include "nbtk-marshal.h"
#include "nbtk-stylable.h"
#include "nbtk-texture-frame.h"
#include "nbtk-texture-cache.h"

enum
{
  PROP_0,

  PROP_LABEL
};

enum
{
  CLICKED,

  LAST_SIGNAL
};

#define NBTK_BUTTON_GET_PRIVATE(obj)    \
        (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NBTK_TYPE_BUTTON, NbtkButtonPrivate))

struct _NbtkButtonPrivate
{
  gchar *text;

  ClutterActor *label;
  ClutterTimeline *timeline;
  ClutterEffectTemplate *press_tmpl;

  guint8 old_opacity;

  guint is_pressed : 1;
  guint is_hover : 1;

  ClutterActor     *bg_image;
  ClutterActor     *old_bg;
  ClutterColor     *bg_color;
};

static guint button_signals[LAST_SIGNAL] = { 0, };


G_DEFINE_TYPE (NbtkButton, nbtk_button, NBTK_TYPE_WIDGET)

static void
style_changed_completed_effect (ClutterActor *actor, NbtkButton *button)
{
  NbtkButtonPrivate *priv = NBTK_BUTTON_GET_PRIVATE (button);

  if (priv->old_bg)
    g_object_unref (priv->old_bg);
  priv->old_bg = NULL;
}

static void
nbtk_button_style_changed (NbtkWidget *button)
{
  ClutterColor *real_color;
  gchar *bg_url = NULL;
  NbtkButtonPrivate *priv = NBTK_BUTTON_GET_PRIVATE (button);

  /* update the label styling */
  nbtk_stylable_get (NBTK_STYLABLE (button),
                     "color", &real_color,
                     NULL);
  g_object_set (G_OBJECT (priv->label),
                "color", real_color,
                NULL);
  clutter_color_free (real_color);

  if (priv->bg_color)
    {
      clutter_color_free (priv->bg_color);
      priv->bg_color = NULL;
    }

  /* cache these values for use in the paint function */
  nbtk_stylable_get (NBTK_STYLABLE (button),
                    "background-color", &priv->bg_color,
                    "background-image", &bg_url,
                    NULL);

  if (bg_url)
    {
      NbtkTextureCache *cache;
      ClutterActor *texture;

      if (priv->bg_image)
        priv->old_bg = priv->bg_image;

      cache = nbtk_texture_cache_get_default ();

      /* the TextureFrame doesn't work with texture clones as it only
       * references the texture data */
      texture = nbtk_texture_cache_get_texture (cache, bg_url, FALSE);

      priv->bg_image = nbtk_texture_frame_new (CLUTTER_TEXTURE (texture),
                                               0, 0, 0, 0);
      g_object_unref (texture);
      clutter_actor_set_opacity (CLUTTER_ACTOR (priv->bg_image), 0);
      clutter_actor_set_parent (CLUTTER_ACTOR (priv->bg_image),
                                CLUTTER_ACTOR (button));
      g_free (bg_url);

      if (G_UNLIKELY (!priv->press_tmpl))
        {
          priv->timeline = clutter_timeline_new_for_duration (100);
          priv->press_tmpl = clutter_effect_template_new (priv->timeline,
                                                          clutter_sine_inc_func);
          clutter_effect_template_set_timeline_clone (priv->press_tmpl, FALSE);
        }

      if (clutter_timeline_is_playing (priv->timeline))
        {
          clutter_timeline_stop (priv->timeline);
	  /* in case we stopped the timeline before old_bg was fully opaque */
	  clutter_actor_set_opacity (priv->old_bg, 0xff);
        }

      clutter_effect_fade (priv->press_tmpl, priv->bg_image,
                           0xff,
                           (ClutterEffectCompleteFunc) style_changed_completed_effect, button);

    }
  else
    {
      if (priv->bg_image)
        {
          g_object_unref (priv->bg_image);
          priv->bg_image = NULL;
        }
    }

  /* queue a relayout, which also calls redraw */
  clutter_actor_queue_relayout (CLUTTER_ACTOR (button));

 
  if (NBTK_WIDGET_CLASS (nbtk_button_parent_class)->style_changed)
    NBTK_WIDGET_CLASS (nbtk_button_parent_class)->style_changed (button);
}

static void
nbtk_button_paint (ClutterActor *actor)
{
  NbtkButton *button = NBTK_BUTTON (actor);
  NbtkButtonPrivate *priv = button->priv;

  if (priv->bg_image)
    {
{'fraction_non_alphanumeric': 0.09490298582487182, 'fraction_numerical': 0.006836232029757716, 'mean_word_length': 2.8648018648018647, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 84, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1412230', 'n_tokens_mistral': 3412, 'n_tokens_neox': 3263, 'n_words': 804}