2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
24 #include <gst/gstutils.h>
26 #include "gsteditor.h"
29 static void gst_editor_element_class_init(GstEditorElementClass *klass);
30 static void gst_editor_element_init(GstEditorElement *element);
31 static void gst_editor_element_set_arg(GtkObject *object,GtkArg *arg,guint id);
32 static void gst_editor_element_get_arg(GtkObject *object,GtkArg *arg,guint id);
33 static void gst_editor_element_realize(GstEditorElement *element);
34 static gint gst_editor_element_event(GnomeCanvasItem *item,
36 GstEditorElement *element);
38 /* events fired by items within self */
39 static gint gst_editor_element_resizebox_event(GnomeCanvasItem *item,
41 GstEditorElement *element);
42 static gint gst_editor_element_group_event(GnomeCanvasItem *item,
44 GstEditorElement *element);
45 static gint gst_editor_element_state_event(GnomeCanvasItem *item,
49 /* external events (from GstElement) */
50 static void gst_editor_element_state_change(GstElement *element,
52 GstEditorElement *editorelement);
54 /* utility functions */
55 static void gst_editor_element_resize(GstEditorElement *element);
56 static void gst_editor_element_set_state(GstEditorElement *element,
57 gint id,gboolean set);
58 static void gst_editor_element_sync_state(GstEditorElement *element);
59 static void gst_editor_element_move(GstEditorElement *element,
60 gdouble dx,gdouble dy);
63 static gchar *_gst_editor_element_states[] = { "C","R","D","P" };
83 static GtkObjectClass *parent_class;
84 static guint gst_editor_element_signals[LAST_SIGNAL] = { 0 };
86 GtkType gst_editor_element_get_type() {
87 static GtkType element_type = 0;
90 static const GtkTypeInfo element_info = {
92 sizeof(GstEditorElement),
93 sizeof(GstEditorElementClass),
94 (GtkClassInitFunc)gst_editor_element_class_init,
95 (GtkObjectInitFunc)gst_editor_element_init,
98 (GtkClassInitFunc)NULL,
100 element_type = gtk_type_unique(gtk_object_get_type(),&element_info);
105 static void gst_editor_element_class_init(GstEditorElementClass *klass) {
106 GtkObjectClass *object_class;
108 object_class = (GtkObjectClass*)klass;
110 parent_class = gtk_type_class(gtk_object_get_type());
112 gtk_object_add_arg_type("GstEditorElement::x",GTK_TYPE_DOUBLE,
113 GTK_ARG_READWRITE|GTK_ARG_CONSTRUCT_ONLY,
115 gtk_object_add_arg_type("GstEditorElement::y",GTK_TYPE_DOUBLE,
116 GTK_ARG_READWRITE|GTK_ARG_CONSTRUCT_ONLY,
118 gtk_object_add_arg_type("GstEditorElement::width",GTK_TYPE_DOUBLE,
119 GTK_ARG_READWRITE|GTK_ARG_CONSTRUCT_ONLY,
121 gtk_object_add_arg_type("GstEditorElement::height",GTK_TYPE_DOUBLE,
122 GTK_ARG_READWRITE|GTK_ARG_CONSTRUCT_ONLY,
124 gtk_object_add_arg_type("GstEditorElement::x1",GTK_TYPE_DOUBLE,
125 GTK_ARG_READWRITE,ARG_X1);
126 gtk_object_add_arg_type("GstEditorElement::y1",GTK_TYPE_DOUBLE,
127 GTK_ARG_READWRITE,ARG_Y1);
128 gtk_object_add_arg_type("GstEditorElement::x2",GTK_TYPE_DOUBLE,
129 GTK_ARG_READWRITE,ARG_X2);
130 gtk_object_add_arg_type("GstEditorElement::y2",GTK_TYPE_DOUBLE,
131 GTK_ARG_READWRITE,ARG_Y2);
132 gtk_object_add_arg_type("GstEditorElement::element",GTK_TYPE_POINTER,
133 GTK_ARG_READABLE,ARG_ELEMENT);
135 klass->realize = gst_editor_element_realize;
136 klass->event = gst_editor_element_event;
138 object_class->set_arg = gst_editor_element_set_arg;
139 object_class->get_arg = gst_editor_element_get_arg;
142 static void gst_editor_element_init(GstEditorElement *element) {
145 GstEditorElement *gst_editor_element_new(GstEditorBin *parent,
147 const gchar *first_arg_name, ...) {
148 GstEditorElement *editorelement;
151 g_return_if_fail(parent != NULL);
152 g_return_if_fail(GST_IS_EDITOR_BIN(parent));
153 g_return_if_fail(element != NULL);
154 g_return_if_fail(GST_IS_ELEMENT(element));
156 editorelement = GST_EDITOR_ELEMENT(gtk_type_new(GST_TYPE_EDITOR_ELEMENT));
157 editorelement->element = element;
159 va_start(args,first_arg_name);
160 gst_editor_element_construct(editorelement,parent,first_arg_name,args);
163 return editorelement;
166 void gst_editor_element_construct(GstEditorElement *element,
167 GstEditorBin *parent,
168 const gchar *first_arg_name,
170 GtkObject *obj = GTK_OBJECT(element);
171 GSList *arg_list = NULL, *info_list = NULL;
173 GstEditorElementClass *elementclass;
175 // g_print("in gst_editor_element_construct()\n");
177 error = gtk_object_args_collect(GTK_OBJECT_TYPE(obj),&arg_list,
178 &info_list,first_arg_name,args);
180 g_warning("gst_editor_element_construct(): %s",error);
184 // g_print("setting all the arguments on the element\n");
185 for (arg=arg_list,info=info_list;arg;arg=arg->next,info=info->next)
186 gtk_object_arg_set(obj,arg->data,info->data);
187 gtk_args_collect_cleanup(arg_list,info_list);
191 gst_editor_bin_add(parent,element);
192 else if (!GST_IS_EDITOR_BIN(element))
193 g_warning("floating element...\n");
195 elementclass = GST_EDITOR_ELEMENT_CLASS(GTK_OBJECT(element)->klass);
196 if (elementclass->realize)
197 (elementclass->realize)(element);
200 static void gst_editor_element_set_arg(GtkObject *object,GtkArg *arg,guint id) {
201 GstEditorElement *element;
202 gdouble dx,dy,newwidth,newheight;
204 /* get the major types of this object */
205 element = GST_EDITOR_ELEMENT(object);
209 element->x = GTK_VALUE_DOUBLE(*arg);
212 element->y = GTK_VALUE_DOUBLE(*arg);
215 element->width = GTK_VALUE_DOUBLE(*arg);
216 element->resize = TRUE;
219 element->height = GTK_VALUE_DOUBLE(*arg);
220 element->resize = TRUE;
223 element->x = GTK_VALUE_DOUBLE(*arg);
224 element->resize = TRUE;
227 element->y = GTK_VALUE_DOUBLE(*arg);
228 element->resize = TRUE;
231 // make sure it's big enough, grow if not
232 element->width = MAX(GTK_VALUE_DOUBLE(*arg),element->minwidth);
233 element->resize = TRUE;
236 // make sure it's big enough, grow if not
237 element->height = MAX(GTK_VALUE_DOUBLE(*arg),element->minheight);
238 element->resize = TRUE;
241 g_warning("gsteditorelement: unknown arg!");
246 static void gst_editor_element_get_arg(GtkObject *object,GtkArg *arg,guint id) {
247 GstEditorElement *element;
249 /* get the major types of this object */
250 element = GST_EDITOR_ELEMENT(object);
254 GTK_VALUE_INT(*arg) = element->x + (element->width / 2.0);
257 GTK_VALUE_INT(*arg) = element->y + (element->height / 2.0);
260 GTK_VALUE_INT(*arg) = element->width;
263 GTK_VALUE_INT(*arg) = element->height;
266 GTK_VALUE_INT(*arg) = element->x;
269 GTK_VALUE_INT(*arg) = element->y;
272 GTK_VALUE_INT(*arg) = element->x + element->width;
275 GTK_VALUE_INT(*arg) = element->y + element->height;
278 GTK_VALUE_POINTER(*arg) = element->element;
281 arg->type = GTK_TYPE_INVALID;
286 static void gst_editor_element_realize(GstEditorElement *element) {
287 GnomeCanvasGroup *parentgroup;
293 // g_print("realizing editor element %p\n",element);
295 /* we have to have a parent by this point */
296 g_return_if_fail(element->parent != NULL);
298 // set the state signal of the actual element
299 gtk_signal_connect(GTK_OBJECT(element->element),"state_change",
300 GTK_SIGNAL_FUNC(gst_editor_element_state_change),
303 // create the bounds if we haven't had them set
304 // g_print("centering element at %.2fx%.2f (%.2fx%.2f)\n",
305 // element->x,element->y,element->width,element->height);
307 /* create the group holding all the stuff for this element */
308 parentgroup = GST_EDITOR_ELEMENT(element->parent)->group;
309 element->group = GNOME_CANVAS_GROUP(gnome_canvas_item_new(parentgroup,
310 gnome_canvas_group_get_type(),
311 "x",element->x - (element->width / 2.0),
312 "y",element->y - (element->height / 2.0),NULL));
313 // g_print("origin of group is %.2fx%.2f\n",
314 // element->x - (element->width / 2.0),
315 // element->y - (element->height / 2.0));
316 g_return_if_fail(element->group != NULL);
317 GST_EDITOR_SET_OBJECT(element->group,element);
318 gtk_signal_connect(GTK_OBJECT(element->group),"event",
319 GTK_SIGNAL_FUNC(gst_editor_element_group_event),element);
321 // calculate the inter-group coords (x1,y1,x2,y2 are convenience vars)
323 x2 = element->width;y2 = element->height;
325 /* create bordering box */
326 element->border = gnome_canvas_item_new(element->group,
327 gnome_canvas_rect_get_type(),
328 "width_units",2.0,"fill_color","white","outline_color","black",
329 "x1",x1,"y1",y1,"x2",x2,"y2",y2,NULL);
330 g_return_if_fail(element->border != NULL);
331 GST_EDITOR_SET_OBJECT(element->border,element);
333 /* create resizing box */
334 element->resizebox = gnome_canvas_item_new(element->group,
335 gnome_canvas_rect_get_type(),
336 "width_units",1.0,"fill_color","white","outline_color","black",
337 "x1",x2-4.0,"y1",y2-4.0,"x2",x2,"y2",y2,NULL);
338 g_return_if_fail(element->resizebox != NULL);
339 GST_EDITOR_SET_OBJECT(element->resizebox,element);
340 gtk_signal_connect(GTK_OBJECT(element->resizebox),"event",
341 GTK_SIGNAL_FUNC(gst_editor_element_resizebox_event),element);
343 /* create the title */
344 element->title = gnome_canvas_item_new(element->group,
345 gnome_canvas_text_get_type(),
346 "text",gst_element_get_name(GST_OBJECT(element->element)),
347 "x",x1+1.0,"y",y1+1.0,"anchor",GTK_ANCHOR_NORTH_WEST,
348 "font_gdk",gtk_widget_get_default_style()->font,
350 g_return_if_fail(element->title != NULL);
351 GST_EDITOR_SET_OBJECT(element->title,element);
353 /* create the state boxen */
355 element->statebox[i] = gnome_canvas_item_new(element->group,
356 gnome_canvas_rect_get_type(),
357 "width_units",1.0,"fill_color","white","outline_color","black",
358 "x1",0.0,"y1",0.0,"x2",0.0,"y2",0.0,
360 g_return_if_fail(element->statebox[i] != NULL);
361 GST_EDITOR_SET_OBJECT(element->statebox[i],element);
362 gtk_signal_connect(GTK_OBJECT(element->statebox[i]),"event",
363 GTK_SIGNAL_FUNC(gst_editor_element_state_event),
365 element->statetext[i] = gnome_canvas_item_new(element->group,
366 gnome_canvas_text_get_type(),
367 "text",_gst_editor_element_states[i],
368 "x",0.0,"y",0.0,"anchor",GTK_ANCHOR_NORTH_WEST,
369 "font","-*-*-*-*-*-*-6-*-*-*-*-*-*-*",
371 g_return_if_fail(element->statetext[i] != NULL);
372 GST_EDITOR_SET_OBJECT(element->statetext[i],element);
373 gtk_signal_connect(GTK_OBJECT(element->statetext[i]),"event",
374 GTK_SIGNAL_FUNC(gst_editor_element_state_event),
377 /* and the play box (FIXME: should be icons, not text */
378 element->playbox = gnome_canvas_item_new(element->group,
379 gnome_canvas_rect_get_type(),
380 "width_units",1.0,"fill_color","white","outline_color","black",
381 "x1",0.0,"y1",0.0,"x2",0.0,"y2",0.0,
383 g_return_if_fail(element->playbox != NULL);
384 GST_EDITOR_SET_OBJECT(element->playbox,element);
385 gtk_signal_connect(GTK_OBJECT(element->playbox),"event",
386 GTK_SIGNAL_FUNC(gst_editor_element_state_event),
388 element->playtext = gnome_canvas_item_new(element->group,
389 gnome_canvas_text_get_type(),
391 "x",0.0,"y",0.0,"anchor",GTK_ANCHOR_NORTH_WEST,
392 "font","-*-*-*-*-*-*-6-*-*-*-*-*-*-*",
394 g_return_if_fail(element->playtext != NULL);
395 GST_EDITOR_SET_OBJECT(element->playtext,element);
396 gtk_signal_connect(GTK_OBJECT(element->playtext),"event",
397 GTK_SIGNAL_FUNC(gst_editor_element_state_event),
401 pads = gst_element_get_pad_list(element->element);
403 pad = GST_PAD(pads->data);
404 gst_editor_element_add_pad(element,pad);
405 pads = g_list_next(pads);
408 element->realized = TRUE;
411 element->resize = TRUE;
412 gst_editor_element_resize(element);
414 // recenter things on the supposed center
415 // g_print("recentering element at %.2fx%.2f (%.2fx%.2f)\n",
416 // element->x,element->y,element->width,element->height);
417 element->x -= (element->width / 2.0);
418 element->y -= (element->height / 2.0);
419 gnome_canvas_item_set(GNOME_CANVAS_ITEM(element->group),
420 "x",element->x,"y",element->y,NULL);
421 // g_print("origin of group is %.2fx%.2f\n",element->x,element->y);
423 gst_editor_element_repack(element);
427 static void gst_editor_element_resize(GstEditorElement *element) {
428 gdouble itemwidth,itemheight;
429 gdouble groupwidth,groupheight;
431 GstEditorPad *editorpad;
434 if (element->resize != TRUE) return;
435 element->resize = FALSE;
437 // g_print("resizing element\n");
439 element->minwidth = element->insidewidth;
440 element->minheight = element->insideheight;
442 // get the text size and add it into minsize
443 g_return_if_fail(element->title != NULL);
444 itemwidth = gst_util_get_double_arg(GTK_OBJECT(element->title),
446 itemheight = gst_util_get_double_arg(GTK_OBJECT(element->title),
447 "text_height") + 2.0;
448 element->titlewidth = itemwidth;
449 element->titleheight = itemheight;
450 element->minwidth = MAX(element->minwidth,itemwidth);
451 element->minheight += itemheight;
453 // now do the bottom bar
454 // find the biggest of the state chars
455 element->statewidth = 0.0;element->stateheight = 0.0;
457 g_return_if_fail(element->statetext[i] != NULL);
458 itemwidth = gst_util_get_double_arg(GTK_OBJECT(element->statetext[i]),
460 itemwidth = gst_util_get_double_arg(GTK_OBJECT(element->statetext[i]),
462 element->statewidth = MAX(element->statewidth,itemwidth);
463 element->stateheight = MAX(element->stateheight,itemheight);
465 // calculate the size of the primary group
466 groupwidth = element->statewidth * 5; // 4 states plus playstate
467 groupheight = element->stateheight;
468 // add in the resize box
469 groupwidth += 7.0; // 2.0 for buffer, 5.0 for actual size
470 groupheight = MAX(groupheight,5.0);
471 // update the minsize
472 element->minwidth = MAX(element->minwidth,groupwidth);
473 element->minheight += groupheight;
475 // now go and try to calculate necessary space for the pads
476 element->sinkwidth = 10.0;element->sinkheight = 0.0;element->sinks = 0;
477 pads = element->sinkpads;
479 editorpad = GST_EDITOR_PAD(pads->data);
480 element->sinkwidth = MAX(element->sinkwidth,editorpad->width);
481 element->sinkheight = MAX(element->sinkheight,editorpad->height);
483 pads = g_list_next(pads);
485 element->srcwidth = 10.0;element->srcheight = 0.0;element->srcs = 0;
486 pads = element->srcpads;
488 editorpad = GST_EDITOR_PAD(pads->data);
489 element->srcwidth = MAX(element->srcwidth,editorpad->width);
490 element->srcheight = MAX(element->srcheight,editorpad->height);
492 pads = g_list_next(pads);
494 // add in the needed space
495 element->minheight += MAX((element->sinkheight*element->sinks),
496 (element->srcheight*element->srcs)) + 4.0;
497 element->minwidth = MAX(element->minwidth,
498 ((element->sinkwidth*element->sinks) +
499 (element->srcwidth*element->srcs) + 4.0));
500 // g_print("have %d sinks (%.2fx%.2f) and %d srcs (%.2fx%.2f)\n",
501 // element->sinks,element->sinkwidth,element->sinkheight,
502 // element->srcs,element->srcwidth,element->srcheight);
504 // grow the element to hold all the stuff
505 // g_print("minsize is %.2fx%.2f,
506 //",element->minwidth,element->minheight);
507 // g_print("size was %.2fx%.2f, ",element->width,element->height);
508 element->width = MAX(element->width,element->minwidth);
509 element->height = MAX(element->height,element->minheight);
510 // g_print("is now %.2fx%.2f\n",element->width,element->height);
513 void gst_editor_element_repack(GstEditorElement *element) {
516 GstEditorPad *editorpad;
517 gdouble sinkwidth,sinkheight;
519 gdouble srcwidth,srcheight;
524 if (!element->realized) return;
526 gst_editor_element_resize(element);
528 // still use x1,y1,x2,y2 so we can change around later
530 x2 = element->width;y2 = element->height;
532 // g_print("repacking element at %.2fx%.2f + %.2fx%.2f\n",
533 // element->x,element->y,x2,y2);
535 // move the element group to match
536 gnome_canvas_item_set(GNOME_CANVAS_ITEM(element->group),
537 "x",element->x,"y",element->y,NULL);
539 // start by resizing the bordering box
540 g_return_if_fail(element->border != NULL);
541 gtk_object_set(GTK_OBJECT(element->border),
542 "x1",x1,"y1",y1,"x2",x2,"y2",y2,NULL);
544 // then move the text to the new top left
545 g_return_if_fail(element->title != NULL);
546 gtk_object_set(GTK_OBJECT(element->title),
547 "x",x1+1.0,"y",y1+1.0,
548 "anchor",GTK_ANCHOR_NORTH_WEST,
551 // and move the resize box
552 g_return_if_fail(element->resizebox != NULL);
553 gtk_object_set(GTK_OBJECT(element->resizebox),
554 "x1",x2-5.0,"y1",y2-5.0,"x2",x2,"y2",y2,NULL);
556 // now place the state boxes
558 g_return_if_fail(element->statebox[i] != NULL);
559 gtk_object_set(GTK_OBJECT(element->statebox[i]),
560 "x1",x1+(element->statewidth*i),
561 "y1",y2-element->stateheight,
562 "x2",x1+(element->statewidth*(i+1)),"y2",y2,NULL);
563 g_return_if_fail(element->statetext[i] != NULL);
564 gtk_object_set(GTK_OBJECT(element->statetext[i]),
565 "x",x1+(element->statewidth*i)+2.0,
566 "y",y2-element->stateheight+1.0,
567 "anchor",GTK_ANCHOR_NORTH_WEST,NULL);
569 // and the playstate box
570 g_return_if_fail(element->playbox != NULL);
571 gtk_object_set(GTK_OBJECT(element->playbox),
572 "x1",x1+(element->statewidth*4),
573 "y1",y2-element->stateheight,
574 "x2",x1+(element->statewidth*5),"y2",y2,NULL);
575 g_return_if_fail(element->playtext != NULL);
576 gtk_object_set(GTK_OBJECT(element->playtext),
577 "x",x1+(element->statewidth*4)+2.0,
578 "y",y2-element->stateheight+1.0,
579 "anchor",GTK_ANCHOR_NORTH_WEST,NULL);
581 // now we try to place all the pads
582 sinks = element->sinks;
583 pads = element->sinkpads;
585 editorpad = GST_EDITOR_PAD(pads->data);
586 gtk_object_set(GTK_OBJECT(editorpad),
588 "y",y2 - 2.0 - element->stateheight -
589 (element->sinkheight * sinks),
591 gst_editor_pad_repack(editorpad);
593 pads = g_list_next(pads);
596 srcs = element->srcs;
597 pads = element->srcpads;
599 editorpad = GST_EDITOR_PAD(pads->data);
600 gtk_object_set(GTK_OBJECT(editorpad),
601 "x",x2 - element->srcwidth,
602 "y",y2 - 2.0 - element->stateheight -
603 (element->srcheight * srcs),
605 gst_editor_pad_repack(editorpad);
607 pads = g_list_next(pads);
610 // g_print("done resizing element\n");
614 GstEditorPad *gst_editor_element_add_pad(GstEditorElement *element,
616 GstEditorPad *editorpad;
618 editorpad = gst_editor_pad_new(element,pad,NULL);
619 if (pad->direction == GST_PAD_SINK) {
620 element->sinkpads = g_list_prepend(element->sinkpads,editorpad);
622 // g_print("added 'new' pad to sink list\n");
623 } else if (pad->direction == GST_PAD_SRC) {
624 element->srcpads = g_list_prepend(element->srcpads,editorpad);
626 // g_print("added 'new' pad to src list\n");
628 g_print("HUH?!? Don't know which direction this pad is...\n");
630 element->padlistchange = TRUE;
631 gst_editor_element_repack(element);
636 static gint gst_editor_element_group_event(GnomeCanvasItem *item,
638 GstEditorElement *element) {
639 // g_print("in group_event, type %d\n",event->type);
640 if (GST_EDITOR_ELEMENT_CLASS(GTK_OBJECT(element)->klass)->event)
641 return (GST_EDITOR_ELEMENT_CLASS(GTK_OBJECT(element)->klass)->event)(
647 static gint gst_editor_element_event(GnomeCanvasItem *item,GdkEvent *event,
648 GstEditorElement *element) {
649 gdouble item_x,item_y,dx,dy;
652 // g_print("element in event, type %d\n",event->type);
654 switch(event->type) {
655 case GDK_ENTER_NOTIFY:
657 case GDK_LEAVE_NOTIFY:
659 case GDK_BUTTON_PRESS:
660 // dragxy coords are world coords of button press
661 element->dragx = event->button.x;
662 element->dragy = event->button.y;
664 element->dragging = TRUE;
665 element->moved = FALSE;
666 fleur = gdk_cursor_new(GDK_FLEUR);
667 gnome_canvas_item_grab(item,
668 GDK_POINTER_MOTION_MASK |
669 // GDK_ENTER_NOTIFY_MASK |
670 // GDK_LEAVE_NOTIFY_MASK |
671 GDK_BUTTON_RELEASE_MASK,
672 fleur,event->button.time);
675 case GDK_MOTION_NOTIFY:
676 if (element->dragging) {
677 dx = event->button.x - element->dragx;
678 dy = event->button.y - element->dragy;
679 gst_editor_element_move(element,dx,dy);
680 element->dragx = event->button.x;
681 element->dragy = event->button.y;
682 element->moved = TRUE;
686 case GDK_BUTTON_RELEASE:
687 if (element->dragging) {
688 element->dragging = FALSE;
689 gnome_canvas_item_ungrab(item,event->button.time);
691 if (!element->moved) {
692 GstEditorElementClass *elementclass;
693 elementclass = GST_EDITOR_ELEMENT_CLASS(GTK_OBJECT(element)->klass);
694 if (elementclass->button_event)
695 (elementclass->button_event)(item,event,element);
697 //g_print("in element group_event, setting inchild");
698 element->canvas->inchild = TRUE;
709 static gint gst_editor_element_resizebox_event(GnomeCanvasItem *item,
711 GstEditorElement *element) {
712 GdkCursor *bottomright;
713 gdouble item_x,item_y;
715 // g_print("in resizebox_event...\n");
717 // calculate coords relative to the group, not the box
718 item_x = event->button.x;
719 item_y = event->button.y;
720 gnome_canvas_item_w2i(item->parent,&item_x,&item_y);
722 switch(event->type) {
723 case GDK_ENTER_NOTIFY:
725 case GDK_LEAVE_NOTIFY:
726 element->hesitating = FALSE;
728 case GDK_BUTTON_PRESS:
729 element->dragx = event->button.x;
730 element->dragy = event->button.y;
731 element->resizing = TRUE;
732 element->hesitating = TRUE;
733 bottomright = gdk_cursor_new(GDK_BOTTOM_RIGHT_CORNER);
734 gnome_canvas_item_grab(item,
735 GDK_POINTER_MOTION_MASK |
736 GDK_ENTER_NOTIFY_MASK |
737 GDK_LEAVE_NOTIFY_MASK |
738 GDK_BUTTON_RELEASE_MASK,
739 bottomright,event->button.time);
742 case GDK_MOTION_NOTIFY:
743 if (element->resizing) {
744 // doing a set because the code is in the arg set code
745 // g_print("resizing to x2,y2 of %.2f,%.2f\n",item_x,item_y);
746 gtk_object_set(GTK_OBJECT(element),"x2",item_x,"y2",item_y,NULL);
747 element->resize = TRUE;
748 gst_editor_element_repack(element);
752 case GDK_BUTTON_RELEASE:
753 if (element->resizing) {
754 element->resizing = FALSE;
755 gnome_canvas_item_ungrab(item,event->button.time);
756 //g_print("in element resizebox_event, setting inchild");
757 element->canvas->inchild = TRUE;
768 static gint gst_editor_element_state_event(GnomeCanvasItem *item,
771 GstEditorElement *element;
772 gint id = GPOINTER_TO_INT(data);
775 element = GST_EDTIOR_GET_OBJECT(item);
777 switch (event->type) {
778 case GDK_ENTER_NOTIFY:
779 uparrow = gdk_cursor_new(GDK_SB_UP_ARROW);
780 gnome_canvas_item_grab(item,
781 GDK_POINTER_MOTION_MASK |
782 GDK_BUTTON_RELEASE_MASK |
783 GDK_LEAVE_NOTIFY_MASK,
784 uparrow,event->button.time);
785 /* NOTE: when grabbing canvas item, always get pointer_motion,
786 this will allow you to actually get all the other synth events */
788 case GDK_LEAVE_NOTIFY:
789 gnome_canvas_item_ungrab(item,event->button.time);
791 case GDK_BUTTON_PRESS:
794 case GDK_BUTTON_RELEASE:
796 element->states[id] = !element->states[id];
797 gst_editor_element_set_state(element,id,TRUE);
799 g_warning("Uh, shouldn't have gotten here, unknown state\n");
800 //g_print("in element statebox_event, setting inchild");
801 element->canvas->inchild = TRUE;
811 static void gst_editor_element_set_state(GstEditorElement *element,
812 gint id,gboolean set) {
813 gboolean stateset = TRUE; /* if we have no element, set anyway */
814 if (element->states[id]) {
815 /* set the object state */
816 if (set && element->element)
817 stateset = gst_element_set_state(element->element,(1 << id));
818 /* change the display */
821 gtk_object_set(GTK_OBJECT(element->statebox[id]),
822 "fill_color","black",NULL);
823 gtk_object_set(GTK_OBJECT(element->statetext[id]),
824 "fill_color","white",NULL);
825 } else if (id == 4) {
826 gtk_object_set(GTK_OBJECT(element->playbox),
827 "fill_color","black",NULL);
828 gtk_object_set(GTK_OBJECT(element->playtext),
829 "fill_color","white",NULL);
832 g_print("error setting state %d\n",id);
833 element->states[id] = !element->states[id];
836 if (set && element->element)
837 stateset = gst_element_set_state(element->element,~(1 << id));
840 gtk_object_set(GTK_OBJECT(element->statebox[id]),
841 "fill_color","white",NULL);
842 gtk_object_set(GTK_OBJECT(element->statetext[id]),
843 "fill_color","black",NULL);
844 } else if (id == 4) {
845 gtk_object_set(GTK_OBJECT(element->playbox),
846 "fill_color","white",NULL);
847 gtk_object_set(GTK_OBJECT(element->playtext),
848 "fill_color","black",NULL);
851 g_print("error unsetting state %d\n",id);
852 element->states[id] = !element->states[id];
858 static void gst_editor_element_state_change(GstElement *element,
860 GstEditorElement *editorelement) {
863 g_return_if_fail(editorelement != NULL);
865 // g_print("gst_editor_element_state_change got state 0x%08x\n",state);
867 if (state & GST_STATE_MAX) {
869 for (id=0;id<(sizeof(state)*8)-1;id++) {
871 editorelement->states[id] = FALSE;
877 for (id=0;id<(sizeof(state)*8)-1;id++) {
879 editorelement->states[id] = TRUE;
885 gst_editor_element_set_state(editorelement,id,FALSE);
888 static void gst_editor_element_sync_state(GstEditorElement *element) {
891 // g_print("syncronizing state\n");
892 for (id=0;id<5;id++) {
893 element->states[id] = GST_FLAG_IS_SET(element->element,1<<id);
894 gst_editor_element_set_state(element,id,FALSE);
898 static void gst_editor_element_move(GstEditorElement *element,
899 gdouble dx,gdouble dy) {
903 // this is a 'little' trick to keep from repacking the whole thing...
904 element->x += dx;element->y += dy;
905 gnome_canvas_item_move(GNOME_CANVAS_ITEM(element->group),dx,dy);
907 pads = element->srcpads;
909 pad = GST_EDITOR_PAD(pads->data);
910 if (pad->connection) {
911 // g_print("updating pad's connection\n");
912 pad->connection->resize = TRUE;
913 gst_editor_connection_resize(pad->connection);
915 pads = g_list_next(pads);
917 pads = element->sinkpads;
919 pad = GST_EDITOR_PAD(pads->data);
920 if (pad->connection) {
921 // g_print("updating pad's connection\n");
922 pad->connection->resize = TRUE;
923 gst_editor_connection_resize(pad->connection);
925 pads = g_list_next(pads);