~ubuntu-branches/debian/sid/cheese/sid

« back to all changes in this revision

Viewing changes to src/cheese-effect-chooser.c

  • Committer: Bazaar Package Importer
  • Author(s): Laurent Bigonville
  • Date: 2011-07-17 21:04:16 UTC
  • mfrom: (15.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20110717210416-nt5qi659qei7a2yy
Tags: 3.0.1-2
* debian/control.in:
  - Change gir1.2-cheese-3.0 Section to libs
  - Make library packages depend against cheese-common package
  - Make cheese package recommends against hicolor-icon-theme
  - Move gst Dependency to libcheese package
* debian/patches/0002-fix-linking.patch: Add missing library to fix linking
* debian/watch:
  - Switch to .bz2 tarballs.
  - Bump version to 3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright © 2007-2009 daniel g. siegel <dgsiegel@gnome.org>
3
 
 * Copyright © 2007,2008 Jaap Haitsma <jaap@haitsma.org>
4
 
 *
5
 
 * Licensed under the GNU General Public License Version 2
6
 
 *
7
 
 * This program is free software; you can redistribute it and/or modify
8
 
 * it under the terms of the GNU General Public License as published by
9
 
 * the Free Software Foundation; either version 2 of the License, or
10
 
 * (at your option) any later version.
11
 
 *
12
 
 * This program is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
 * GNU General Public License for more details.
16
 
 *
17
 
 * You should have received a copy of the GNU General Public License
18
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 
 */
20
 
 
21
 
#ifdef HAVE_CONFIG_H
22
 
  #include <cheese-config.h>
23
 
#endif
24
 
 
25
 
#include <string.h>
26
 
#include <glib.h>
27
 
#include <glib/gi18n.h>
28
 
#include <gtk/gtk.h>
29
 
#include <cairo.h>
30
 
 
31
 
#include <cheese-camera.h>
32
 
#include "cheese-effect-chooser.h"
33
 
 
34
 
#define BOARD_COLS  4
35
 
#define BOARD_ROWS  3
36
 
#define NUM_EFFECTS (BOARD_ROWS * BOARD_COLS)
37
 
 
38
 
#define SHRINK(cr, x) cairo_translate (cr, (1 - (x)) / 2.0, (1 - (x)) / 2.0); cairo_scale (cr, (x), (x))
39
 
 
40
 
#define CHEESE_EFFECT_CHOOSER_GET_PRIVATE(o) \
41
 
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), CHEESE_TYPE_EFFECT_CHOOSER, CheeseEffectChooserPrivate))
42
 
 
43
 
G_DEFINE_TYPE (CheeseEffectChooser, cheese_effect_chooser, GTK_TYPE_DRAWING_AREA);
44
 
 
45
 
typedef struct
46
 
{
47
 
  gboolean selected[NUM_EFFECTS];
48
 
} CheeseEffectChooserPrivate;
49
 
 
50
 
 
51
 
typedef struct
52
 
{
53
 
  CheeseCameraEffect effect;
54
 
  char *name;
55
 
  char *filename;
56
 
  gboolean is_black;
57
 
} GstEffect;
58
 
 
59
 
static const GstEffect GST_EFFECT[] = {
60
 
  {CHEESE_CAMERA_EFFECT_NO_EFFECT,       N_("No Effect"),
61
 
   PACKAGE_DATADIR "/effects/identity.png", FALSE},
62
 
  {CHEESE_CAMERA_EFFECT_MAUVE,           N_("Mauve"),
63
 
   PACKAGE_DATADIR "/effects/Mauve.png", FALSE},
64
 
  {CHEESE_CAMERA_EFFECT_NOIR_BLANC,      N_("Noir/Blanc"),
65
 
   PACKAGE_DATADIR "/effects/NoirBlanc.png", FALSE},
66
 
  {CHEESE_CAMERA_EFFECT_SATURATION,      N_("Saturation"),
67
 
   PACKAGE_DATADIR "/effects/Saturation.png", FALSE},
68
 
  {CHEESE_CAMERA_EFFECT_HULK,            N_("Hulk"),
69
 
   PACKAGE_DATADIR "/effects/Hulk.png", FALSE},
70
 
  {CHEESE_CAMERA_EFFECT_VERTICAL_FLIP,   N_("Vertical Flip"),
71
 
   PACKAGE_DATADIR "/effects/videoflip_v.png", FALSE},
72
 
  {CHEESE_CAMERA_EFFECT_HORIZONTAL_FLIP, N_("Horizontal Flip"),
73
 
   PACKAGE_DATADIR "/effects/videoflip_h.png", FALSE},
74
 
  {CHEESE_CAMERA_EFFECT_SHAGADELIC,      N_("Shagadelic"),
75
 
   PACKAGE_DATADIR "/effects/shagadelictv.png", FALSE},
76
 
  {CHEESE_CAMERA_EFFECT_VERTIGO,         N_("Vertigo"),
77
 
   PACKAGE_DATADIR "/effects/vertigotv.png", FALSE},
78
 
  {CHEESE_CAMERA_EFFECT_EDGE,            N_("Edge"),
79
 
   PACKAGE_DATADIR "/effects/edgetv.png", TRUE},
80
 
  {CHEESE_CAMERA_EFFECT_DICE,            N_("Dice"),
81
 
   PACKAGE_DATADIR "/effects/dicetv.png", FALSE},
82
 
  {CHEESE_CAMERA_EFFECT_WARP,            N_("Warp"),
83
 
   PACKAGE_DATADIR "/effects/warptv.png", FALSE}
84
 
};
85
 
 
86
 
 
87
 
static void
88
 
cheese_cairo_rectangle_round (cairo_t *cr,
89
 
                              double x0, double y0,
90
 
                              double width, double height, double radius)
91
 
{
92
 
  double x1, y1;
93
 
 
94
 
  x1 = x0 + width;
95
 
  y1 = y0 + height;
96
 
 
97
 
  if (!width || !height)
98
 
    return;
99
 
  if (width / 2 < radius)
100
 
  {
101
 
    if (height / 2 < radius)
102
 
    {
103
 
      cairo_move_to (cr, x0, (y0 + y1) / 2);
104
 
      cairo_curve_to (cr, x0, y0, x0, y0, (x0 + x1) / 2, y0);
105
 
      cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1) / 2);
106
 
      cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0) / 2, y1);
107
 
      cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1) / 2);
108
 
    }
109
 
    else
110
 
    {
111
 
      cairo_move_to (cr, x0, y0 + radius);
112
 
      cairo_curve_to (cr, x0, y0, x0, y0, (x0 + x1) / 2, y0);
113
 
      cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
114
 
      cairo_line_to (cr, x1, y1 - radius);
115
 
      cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0) / 2, y1);
116
 
      cairo_curve_to (cr, x0, y1, x0, y1, x0, y1 - radius);
117
 
    }
118
 
  }
119
 
  else
120
 
  {
121
 
    if (height / 2 < radius)
122
 
    {
123
 
      cairo_move_to (cr, x0, (y0 + y1) / 2);
124
 
      cairo_curve_to (cr, x0, y0, x0, y0, x0 + radius, y0);
125
 
      cairo_line_to (cr, x1 - radius, y0);
126
 
      cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1) / 2);
127
 
      cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
128
 
      cairo_line_to (cr, x0 + radius, y1);
129
 
      cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1) / 2);
130
 
    }
131
 
    else
132
 
    {
133
 
      cairo_move_to (cr, x0, y0 + radius);
134
 
      cairo_curve_to (cr, x0, y0, x0, y0, x0 + radius, y0);
135
 
      cairo_line_to (cr, x1 - radius, y0);
136
 
      cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
137
 
      cairo_line_to (cr, x1, y1 - radius);
138
 
      cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
139
 
      cairo_line_to (cr, x0 + radius, y1);
140
 
      cairo_curve_to (cr, x0, y1, x0, y1, x0, y1 - radius);
141
 
    }
142
 
  }
143
 
  cairo_close_path (cr);
144
 
}
145
 
 
146
 
static void
147
 
cheese_cairo_draw_card (cairo_t *cr, const GstEffect *card, gboolean highlight)
148
 
{
149
 
  int              w, h;
150
 
  cairo_surface_t *image;
151
 
 
152
 
  cairo_save (cr);
153
 
 
154
 
  SHRINK (cr, .9);
155
 
 
156
 
  cheese_cairo_rectangle_round (cr, 0, 0, 1.0, 1.0, 0.1);
157
 
  cairo_set_source_rgb (cr, 0, 0, 0);
158
 
 
159
 
  cairo_save (cr);
160
 
 
161
 
  cheese_cairo_rectangle_round (cr, 0, 0, 1.0, 1.0, 0.1);
162
 
  cairo_clip (cr);
163
 
  cairo_new_path (cr);
164
 
 
165
 
  image = cairo_image_surface_create_from_png (card->filename);
166
 
  w     = cairo_image_surface_get_width (image);
167
 
  h     = cairo_image_surface_get_height (image);
168
 
 
169
 
  cairo_scale (cr, 1.0 / w, 1.0 / h);
170
 
 
171
 
  cairo_set_source_surface (cr, image, 0, 0);
172
 
  cairo_paint (cr);
173
 
 
174
 
  cairo_surface_destroy (image);
175
 
  cairo_restore (cr);
176
 
 
177
 
  if (card->is_black)
178
 
    cairo_set_source_rgb (cr, 1, 1, 1);
179
 
 
180
 
  PangoLayout *layout = pango_cairo_create_layout (cr);
181
 
  gchar *name = gettext (card->name);
182
 
  pango_layout_set_text (layout, name, -1);
183
 
  PangoFontDescription *desc = pango_font_description_from_string ("Sans 0.09");
184
 
  pango_layout_set_font_description (layout, desc);
185
 
  pango_font_description_free (desc);
186
 
  int width, height;
187
 
  pango_layout_get_size (layout, &width, &height);
188
 
  double x, y;
189
 
  x = 0.5 - ((double)width / PANGO_SCALE) / 2;
190
 
  y = 0.92 - ((double)height / PANGO_SCALE) / 2;
191
 
  cairo_move_to (cr, x, y);
192
 
  pango_cairo_show_layout (cr, layout);
193
 
  g_object_unref (layout);
194
 
 
195
 
  if (highlight)
196
 
  {
197
 
    cheese_cairo_rectangle_round (cr, 0, 0, 1.0, 1.0, 0.1);
198
 
    cairo_set_source_rgba (cr, 0, 0, 1, 0.25);
199
 
    cairo_fill (cr);
200
 
  }
201
 
  cairo_restore (cr);
202
 
}
203
 
 
204
 
static void
205
 
cheese_effect_chooser_expose_cb (GtkWidget *widget, GdkEventExpose *expose_event, gpointer data)
206
 
{
207
 
  CheeseEffectChooserPrivate *priv = CHEESE_EFFECT_CHOOSER_GET_PRIVATE (widget);
208
 
 
209
 
  GtkAllocation  allocation;
210
 
  int            width, height;
211
 
  int            i;
212
 
  cairo_t       *cr;
213
 
 
214
 
  gtk_widget_get_allocation (widget, &allocation);
215
 
  width  = allocation.width;
216
 
  height = allocation.height;
217
 
 
218
 
  cr = gdk_cairo_create (gtk_widget_get_window (widget));
219
 
 
220
 
  cairo_save (cr);
221
 
  cairo_scale (cr, width, height);
222
 
 
223
 
  for (i = 0; i < NUM_EFFECTS; i++)
224
 
  {
225
 
    cairo_save (cr);
226
 
    cairo_translate (cr, 1.0 / BOARD_COLS * (i % BOARD_COLS),
227
 
                     1.0 / BOARD_ROWS * (i / BOARD_COLS));
228
 
    cairo_scale (cr, 1.0 / BOARD_COLS, 1.0 / BOARD_ROWS);
229
 
    cheese_cairo_draw_card (cr, &(GST_EFFECT[i]), priv->selected[i]);
230
 
    cairo_restore (cr);
231
 
  }
232
 
 
233
 
  cairo_restore (cr);
234
 
}
235
 
 
236
 
static gboolean
237
 
cheese_effect_chooser_button_press_event_cb (GtkWidget *widget, GdkEventButton *button_event, gpointer data)
238
 
{
239
 
  CheeseEffectChooserPrivate *priv = CHEESE_EFFECT_CHOOSER_GET_PRIVATE (widget);
240
 
  GtkAllocation allocation;
241
 
  int i;
242
 
  int col, row;
243
 
  int slot;
244
 
 
245
 
  gtk_widget_get_allocation (widget, &allocation);
246
 
  col  = (int) (button_event->x / allocation.width * BOARD_COLS);
247
 
  row  = (int) (button_event->y / allocation.height * BOARD_ROWS);
248
 
  slot = (row * BOARD_COLS + col);
249
 
 
250
 
  priv->selected[slot] = !priv->selected[slot];
251
 
 
252
 
  if (priv->selected[0] == TRUE)
253
 
  {
254
 
    for (i = 0; i < NUM_EFFECTS; i++)
255
 
      priv->selected[i] = FALSE;
256
 
  }
257
 
 
258
 
  gtk_widget_queue_draw (widget);
259
 
 
260
 
  return TRUE;
261
 
}
262
 
 
263
 
CheeseCameraEffect
264
 
cheese_effect_chooser_get_selection (CheeseEffectChooser *effect_chooser)
265
 
{
266
 
  CheeseEffectChooserPrivate *priv = CHEESE_EFFECT_CHOOSER_GET_PRIVATE (effect_chooser);
267
 
 
268
 
  int                i;
269
 
  CheeseCameraEffect effect = 0;
270
 
 
271
 
  for (i = 0; i < NUM_EFFECTS; i++)
272
 
  {
273
 
    if (priv->selected[i])
274
 
    {
275
 
      effect |= GST_EFFECT[i].effect;
276
 
    }
277
 
  }
278
 
  return effect;
279
 
}
280
 
 
281
 
char *
282
 
cheese_effect_chooser_get_selection_string (CheeseEffectChooser *effect_chooser)
283
 
{
284
 
  CheeseEffectChooserPrivate *priv = CHEESE_EFFECT_CHOOSER_GET_PRIVATE (effect_chooser);
285
 
 
286
 
  int   i;
287
 
  char *effects = NULL;
288
 
 
289
 
  for (i = 0; i < NUM_EFFECTS; i++)
290
 
  {
291
 
    if (priv->selected[i])
292
 
    {
293
 
      if (effects == NULL)
294
 
        effects = GST_EFFECT[i].name;
295
 
      else
296
 
        effects = g_strjoin (",", effects, GST_EFFECT[i].name, NULL);
297
 
    }
298
 
  }
299
 
  return effects;
300
 
}
301
 
 
302
 
static void
303
 
cheese_effect_chooser_finalize (GObject *object)
304
 
{
305
 
  G_OBJECT_CLASS (cheese_effect_chooser_parent_class)->finalize (object);
306
 
}
307
 
 
308
 
static void
309
 
cheese_effect_chooser_class_init (CheeseEffectChooserClass *klass)
310
 
{
311
 
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
312
 
 
313
 
  object_class->finalize = cheese_effect_chooser_finalize;
314
 
 
315
 
  g_type_class_add_private (klass, sizeof (CheeseEffectChooserPrivate));
316
 
}
317
 
 
318
 
static void
319
 
cheese_effect_chooser_init (CheeseEffectChooser *effect_chooser)
320
 
{
321
 
  gtk_widget_add_events (GTK_WIDGET (effect_chooser), GDK_BUTTON_PRESS_MASK);
322
 
 
323
 
  g_signal_connect (G_OBJECT (effect_chooser), "button_press_event",
324
 
                    G_CALLBACK (cheese_effect_chooser_button_press_event_cb), NULL);
325
 
  g_signal_connect (G_OBJECT (effect_chooser), "expose-event",
326
 
                    G_CALLBACK (cheese_effect_chooser_expose_cb), NULL);
327
 
}
328
 
 
329
 
GtkWidget *
330
 
cheese_effect_chooser_new (char *selected_effects)
331
 
{
332
 
  CheeseEffectChooser *effect_chooser;
333
 
  int                  i;
334
 
 
335
 
  effect_chooser = g_object_new (CHEESE_TYPE_EFFECT_CHOOSER, NULL);
336
 
 
337
 
  CheeseEffectChooserPrivate *priv = CHEESE_EFFECT_CHOOSER_GET_PRIVATE (effect_chooser);
338
 
 
339
 
  if (selected_effects != NULL)
340
 
  {
341
 
    for (i = 1; i < NUM_EFFECTS; i++)
342
 
    {
343
 
      if (strstr (selected_effects, GST_EFFECT[i].name) != NULL)
344
 
        priv->selected[i] = TRUE;
345
 
    }
346
 
  }
347
 
 
348
 
  return GTK_WIDGET (effect_chooser);
349
 
}