diff options
Diffstat (limited to 'editor/gsteditorelement.c')
-rw-r--r-- | editor/gsteditorelement.c | 927 |
1 files changed, 927 insertions, 0 deletions
diff --git a/editor/gsteditorelement.c b/editor/gsteditorelement.c new file mode 100644 index 000000000..d13c40f4a --- /dev/null +++ b/editor/gsteditorelement.c @@ -0,0 +1,927 @@ +/* Gnome-Streamer + * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library 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. + */ + + +#include <gnome.h> + +#include <gst/gst.h> +#include <gst/gstutils.h> + +#include "gsteditor.h" + +/* class functions */ +static void gst_editor_element_class_init(GstEditorElementClass *klass); +static void gst_editor_element_init(GstEditorElement *element); +static void gst_editor_element_set_arg(GtkObject *object,GtkArg *arg,guint id); +static void gst_editor_element_get_arg(GtkObject *object,GtkArg *arg,guint id); +static void gst_editor_element_realize(GstEditorElement *element); +static gint gst_editor_element_event(GnomeCanvasItem *item, + GdkEvent *event, + GstEditorElement *element); + +/* events fired by items within self */ +static gint gst_editor_element_resizebox_event(GnomeCanvasItem *item, + GdkEvent *event, + GstEditorElement *element); +static gint gst_editor_element_group_event(GnomeCanvasItem *item, + GdkEvent *event, + GstEditorElement *element); +static gint gst_editor_element_state_event(GnomeCanvasItem *item, + GdkEvent *event, + gpointer data); + +/* external events (from GstElement) */ +static void gst_editor_element_state_change(GstElement *element, + gint state, + GstEditorElement *editorelement); + +/* utility functions */ +static void gst_editor_element_resize(GstEditorElement *element); +static void gst_editor_element_set_state(GstEditorElement *element, + gint id,gboolean set); +static void gst_editor_element_sync_state(GstEditorElement *element); +static void gst_editor_element_move(GstEditorElement *element, + gdouble dx,gdouble dy); + + +static gchar *_gst_editor_element_states[] = { "C","R","D","P" }; + + +enum { + ARG_0, + ARG_X, + ARG_Y, + ARG_WIDTH, + ARG_HEIGHT, + ARG_X1, + ARG_Y1, + ARG_X2, + ARG_Y2, + ARG_ELEMENT, +}; + +enum { + LAST_SIGNAL +}; + +static GtkObjectClass *parent_class; +static guint gst_editor_element_signals[LAST_SIGNAL] = { 0 }; + +GtkType gst_editor_element_get_type() { + static GtkType element_type = 0; + + if (!element_type) { + static const GtkTypeInfo element_info = { + "GstEditorElement", + sizeof(GstEditorElement), + sizeof(GstEditorElementClass), + (GtkClassInitFunc)gst_editor_element_class_init, + (GtkObjectInitFunc)gst_editor_element_init, + NULL, + NULL, + (GtkClassInitFunc)NULL, + }; + element_type = gtk_type_unique(gtk_object_get_type(),&element_info); + } + return element_type; +} + +static void gst_editor_element_class_init(GstEditorElementClass *klass) { + GtkObjectClass *object_class; + + object_class = (GtkObjectClass*)klass; + + parent_class = gtk_type_class(gtk_object_get_type()); + + gtk_object_add_arg_type("GstEditorElement::x",GTK_TYPE_DOUBLE, + GTK_ARG_READWRITE|GTK_ARG_CONSTRUCT_ONLY, + ARG_X); + gtk_object_add_arg_type("GstEditorElement::y",GTK_TYPE_DOUBLE, + GTK_ARG_READWRITE|GTK_ARG_CONSTRUCT_ONLY, + ARG_Y); + gtk_object_add_arg_type("GstEditorElement::width",GTK_TYPE_DOUBLE, + GTK_ARG_READWRITE|GTK_ARG_CONSTRUCT_ONLY, + ARG_WIDTH); + gtk_object_add_arg_type("GstEditorElement::height",GTK_TYPE_DOUBLE, + GTK_ARG_READWRITE|GTK_ARG_CONSTRUCT_ONLY, + ARG_HEIGHT); + gtk_object_add_arg_type("GstEditorElement::x1",GTK_TYPE_DOUBLE, + GTK_ARG_READWRITE,ARG_X1); + gtk_object_add_arg_type("GstEditorElement::y1",GTK_TYPE_DOUBLE, + GTK_ARG_READWRITE,ARG_Y1); + gtk_object_add_arg_type("GstEditorElement::x2",GTK_TYPE_DOUBLE, + GTK_ARG_READWRITE,ARG_X2); + gtk_object_add_arg_type("GstEditorElement::y2",GTK_TYPE_DOUBLE, + GTK_ARG_READWRITE,ARG_Y2); + gtk_object_add_arg_type("GstEditorElement::element",GTK_TYPE_POINTER, + GTK_ARG_READABLE,ARG_ELEMENT); + + klass->realize = gst_editor_element_realize; + klass->event = gst_editor_element_event; + + object_class->set_arg = gst_editor_element_set_arg; + object_class->get_arg = gst_editor_element_get_arg; +} + +static void gst_editor_element_init(GstEditorElement *element) { +} + +GstEditorElement *gst_editor_element_new(GstEditorBin *parent, + GstElement *element, + const gchar *first_arg_name, ...) { + GstEditorElement *editorelement; + va_list args; + + g_return_if_fail(parent != NULL); + g_return_if_fail(GST_IS_EDITOR_BIN(parent)); + g_return_if_fail(element != NULL); + g_return_if_fail(GST_IS_ELEMENT(element)); + + editorelement = GST_EDITOR_ELEMENT(gtk_type_new(GST_TYPE_EDITOR_ELEMENT)); + editorelement->element = element; + + va_start(args,first_arg_name); + gst_editor_element_construct(editorelement,parent,first_arg_name,args); + va_end(args); + + return editorelement; +} + +void gst_editor_element_construct(GstEditorElement *element, + GstEditorBin *parent, + const gchar *first_arg_name, + va_list args) { + GtkObject *obj = GTK_OBJECT(element); + GSList *arg_list = NULL, *info_list = NULL; + gchar *error; + GstEditorElementClass *elementclass; + +// g_print("in gst_editor_element_construct()\n"); + + error = gtk_object_args_collect(GTK_OBJECT_TYPE(obj),&arg_list, + &info_list,first_arg_name,args); + if (error) { + g_warning("gst_editor_element_construct(): %s",error); + g_free(error); + } else { + GSList *arg,*info; +// g_print("setting all the arguments on the element\n"); + for (arg=arg_list,info=info_list;arg;arg=arg->next,info=info->next) + gtk_object_arg_set(obj,arg->data,info->data); + gtk_args_collect_cleanup(arg_list,info_list); + } + + if (parent) + gst_editor_bin_add(parent,element); + else if (!GST_IS_EDITOR_BIN(element)) + g_warning("floating element...\n"); + + elementclass = GST_EDITOR_ELEMENT_CLASS(GTK_OBJECT(element)->klass); + if (elementclass->realize) + (elementclass->realize)(element); +} + +static void gst_editor_element_set_arg(GtkObject *object,GtkArg *arg,guint id) { + GstEditorElement *element; + gdouble dx,dy,newwidth,newheight; + + /* get the major types of this object */ + element = GST_EDITOR_ELEMENT(object); + + switch (id) { + case ARG_X: + element->x = GTK_VALUE_DOUBLE(*arg); + break; + case ARG_Y: + element->y = GTK_VALUE_DOUBLE(*arg); + break; + case ARG_WIDTH: + element->width = GTK_VALUE_DOUBLE(*arg); + element->resize = TRUE; + break; + case ARG_HEIGHT: + element->height = GTK_VALUE_DOUBLE(*arg); + element->resize = TRUE; + break; + case ARG_X1: + element->x = GTK_VALUE_DOUBLE(*arg); + element->resize = TRUE; + break; + case ARG_Y1: + element->y = GTK_VALUE_DOUBLE(*arg); + element->resize = TRUE; + break; + case ARG_X2: + // make sure it's big enough, grow if not + element->width = MAX(GTK_VALUE_DOUBLE(*arg),element->minwidth); + element->resize = TRUE; + break; + case ARG_Y2: + // make sure it's big enough, grow if not + element->height = MAX(GTK_VALUE_DOUBLE(*arg),element->minheight); + element->resize = TRUE; + break; + default: + g_warning("gsteditorelement: unknown arg!"); + break; + } +} + +static void gst_editor_element_get_arg(GtkObject *object,GtkArg *arg,guint id) { + GstEditorElement *element; + + /* get the major types of this object */ + element = GST_EDITOR_ELEMENT(object); + + switch (id) { + case ARG_X: + GTK_VALUE_INT(*arg) = element->x + (element->width / 2.0); + break; + case ARG_Y: + GTK_VALUE_INT(*arg) = element->y + (element->height / 2.0); + break; + case ARG_WIDTH: + GTK_VALUE_INT(*arg) = element->width; + break; + case ARG_HEIGHT: + GTK_VALUE_INT(*arg) = element->height; + break; + case ARG_X1: + GTK_VALUE_INT(*arg) = element->x; + break; + case ARG_Y1: + GTK_VALUE_INT(*arg) = element->y; + break; + case ARG_X2: + GTK_VALUE_INT(*arg) = element->x + element->width; + break; + case ARG_Y2: + GTK_VALUE_INT(*arg) = element->y + element->height; + break; + case ARG_ELEMENT: + GTK_VALUE_POINTER(*arg) = element->element; + break; + default: + arg->type = GTK_TYPE_INVALID; + break; + } +} + +static void gst_editor_element_realize(GstEditorElement *element) { + GnomeCanvasGroup *parentgroup; + gint i; + gdouble x1,y1,x2,y2; + GList *pads; + GstPad *pad; + +// g_print("realizing editor element %p\n",element); + + /* we have to have a parent by this point */ + g_return_if_fail(element->parent != NULL); + + // set the state signal of the actual element + gtk_signal_connect(GTK_OBJECT(element->element),"state_change", + GTK_SIGNAL_FUNC(gst_editor_element_state_change), + element); + + // create the bounds if we haven't had them set +// g_print("centering element at %.2fx%.2f (%.2fx%.2f)\n", +// element->x,element->y,element->width,element->height); + + /* create the group holding all the stuff for this element */ + parentgroup = GST_EDITOR_ELEMENT(element->parent)->group; + element->group = GNOME_CANVAS_GROUP(gnome_canvas_item_new(parentgroup, + gnome_canvas_group_get_type(), + "x",element->x - (element->width / 2.0), + "y",element->y - (element->height / 2.0),NULL)); +// g_print("origin of group is %.2fx%.2f\n", +// element->x - (element->width / 2.0), +// element->y - (element->height / 2.0)); + g_return_if_fail(element->group != NULL); + GST_EDITOR_SET_OBJECT(element->group,element); + gtk_signal_connect(GTK_OBJECT(element->group),"event", + GTK_SIGNAL_FUNC(gst_editor_element_group_event),element); + + // calculate the inter-group coords (x1,y1,x2,y2 are convenience vars) + x1 = 0.0;y1 = 0.0; + x2 = element->width;y2 = element->height; + + /* create bordering box */ + element->border = gnome_canvas_item_new(element->group, + gnome_canvas_rect_get_type(), + "width_units",2.0,"fill_color","white","outline_color","black", + "x1",x1,"y1",y1,"x2",x2,"y2",y2,NULL); + g_return_if_fail(element->border != NULL); + GST_EDITOR_SET_OBJECT(element->border,element); + + /* create resizing box */ + element->resizebox = gnome_canvas_item_new(element->group, + gnome_canvas_rect_get_type(), + "width_units",1.0,"fill_color","white","outline_color","black", + "x1",x2-4.0,"y1",y2-4.0,"x2",x2,"y2",y2,NULL); + g_return_if_fail(element->resizebox != NULL); + GST_EDITOR_SET_OBJECT(element->resizebox,element); + gtk_signal_connect(GTK_OBJECT(element->resizebox),"event", + GTK_SIGNAL_FUNC(gst_editor_element_resizebox_event),element); + + /* create the title */ + element->title = gnome_canvas_item_new(element->group, + gnome_canvas_text_get_type(), + "text",gst_element_get_name(GST_OBJECT(element->element)), + "x",x1+1.0,"y",y1+1.0,"anchor",GTK_ANCHOR_NORTH_WEST, + "font_gdk",gtk_widget_get_default_style()->font, + NULL); + g_return_if_fail(element->title != NULL); + GST_EDITOR_SET_OBJECT(element->title,element); + + /* create the state boxen */ + for (i=0;i<4;i++) { + element->statebox[i] = gnome_canvas_item_new(element->group, + gnome_canvas_rect_get_type(), + "width_units",1.0,"fill_color","white","outline_color","black", + "x1",0.0,"y1",0.0,"x2",0.0,"y2",0.0, + NULL); + g_return_if_fail(element->statebox[i] != NULL); + GST_EDITOR_SET_OBJECT(element->statebox[i],element); + gtk_signal_connect(GTK_OBJECT(element->statebox[i]),"event", + GTK_SIGNAL_FUNC(gst_editor_element_state_event), + GINT_TO_POINTER(i)); + element->statetext[i] = gnome_canvas_item_new(element->group, + gnome_canvas_text_get_type(), + "text",_gst_editor_element_states[i], + "x",0.0,"y",0.0,"anchor",GTK_ANCHOR_NORTH_WEST, + "font","-*-*-*-*-*-*-6-*-*-*-*-*-*-*", + NULL); + g_return_if_fail(element->statetext[i] != NULL); + GST_EDITOR_SET_OBJECT(element->statetext[i],element); + gtk_signal_connect(GTK_OBJECT(element->statetext[i]),"event", + GTK_SIGNAL_FUNC(gst_editor_element_state_event), + GINT_TO_POINTER(i)); + } + /* and the play box (FIXME: should be icons, not text */ + element->playbox = gnome_canvas_item_new(element->group, + gnome_canvas_rect_get_type(), + "width_units",1.0,"fill_color","white","outline_color","black", + "x1",0.0,"y1",0.0,"x2",0.0,"y2",0.0, + NULL); + g_return_if_fail(element->playbox != NULL); + GST_EDITOR_SET_OBJECT(element->playbox,element); + gtk_signal_connect(GTK_OBJECT(element->playbox),"event", + GTK_SIGNAL_FUNC(gst_editor_element_state_event), + GINT_TO_POINTER(4)); + element->playtext = gnome_canvas_item_new(element->group, + gnome_canvas_text_get_type(), + "text","P", + "x",0.0,"y",0.0,"anchor",GTK_ANCHOR_NORTH_WEST, + "font","-*-*-*-*-*-*-6-*-*-*-*-*-*-*", + NULL); + g_return_if_fail(element->playtext != NULL); + GST_EDITOR_SET_OBJECT(element->playtext,element); + gtk_signal_connect(GTK_OBJECT(element->playtext),"event", + GTK_SIGNAL_FUNC(gst_editor_element_state_event), + GINT_TO_POINTER(4)); + + // get all the pads + pads = gst_element_get_pad_list(element->element); + while (pads) { + pad = GST_PAD(pads->data); + gst_editor_element_add_pad(element,pad); + pads = g_list_next(pads); + } + + element->realized = TRUE; + + // force a resize + element->resize = TRUE; + gst_editor_element_resize(element); + + // recenter things on the supposed center +// g_print("recentering element at %.2fx%.2f (%.2fx%.2f)\n", +// element->x,element->y,element->width,element->height); + element->x -= (element->width / 2.0); + element->y -= (element->height / 2.0); + gnome_canvas_item_set(GNOME_CANVAS_ITEM(element->group), + "x",element->x,"y",element->y,NULL); +// g_print("origin of group is %.2fx%.2f\n",element->x,element->y); + + gst_editor_element_repack(element); +} + + +static void gst_editor_element_resize(GstEditorElement *element) { + gdouble itemwidth,itemheight; + gdouble groupwidth,groupheight; + GList *pads; + GstEditorPad *editorpad; + gint i; + + if (element->resize != TRUE) return; + element->resize = FALSE; + +// g_print("resizing element\n"); + + element->minwidth = element->insidewidth; + element->minheight = element->insideheight; + + // get the text size and add it into minsize + g_return_if_fail(element->title != NULL); + itemwidth = gst_util_get_double_arg(GTK_OBJECT(element->title), + "text_width") + 2.0; + itemheight = gst_util_get_double_arg(GTK_OBJECT(element->title), + "text_height") + 2.0; + element->titlewidth = itemwidth; + element->titleheight = itemheight; + element->minwidth = MAX(element->minwidth,itemwidth); + element->minheight += itemheight; + + // now do the bottom bar + // find the biggest of the state chars + element->statewidth = 0.0;element->stateheight = 0.0; + for (i=0;i<4;i++) { + g_return_if_fail(element->statetext[i] != NULL); + itemwidth = gst_util_get_double_arg(GTK_OBJECT(element->statetext[i]), + "text_width") - 2.0; + itemwidth = gst_util_get_double_arg(GTK_OBJECT(element->statetext[i]), + "text_height"); + element->statewidth = MAX(element->statewidth,itemwidth); + element->stateheight = MAX(element->stateheight,itemheight); + } + // calculate the size of the primary group + groupwidth = element->statewidth * 5; // 4 states plus playstate + groupheight = element->stateheight; + // add in the resize box + groupwidth += 7.0; // 2.0 for buffer, 5.0 for actual size + groupheight = MAX(groupheight,5.0); + // update the minsize + element->minwidth = MAX(element->minwidth,groupwidth); + element->minheight += groupheight; + + // now go and try to calculate necessary space for the pads + element->sinkwidth = 10.0;element->sinkheight = 0.0;element->sinks = 0; + pads = element->sinkpads; + while (pads) { + editorpad = GST_EDITOR_PAD(pads->data); + element->sinkwidth = MAX(element->sinkwidth,editorpad->width); + element->sinkheight = MAX(element->sinkheight,editorpad->height); + element->sinks++; + pads = g_list_next(pads); + } + element->srcwidth = 10.0;element->srcheight = 0.0;element->srcs = 0; + pads = element->srcpads; + while (pads) { + editorpad = GST_EDITOR_PAD(pads->data); + element->srcwidth = MAX(element->srcwidth,editorpad->width); + element->srcheight = MAX(element->srcheight,editorpad->height); + element->srcs++; + pads = g_list_next(pads); + } + // add in the needed space + element->minheight += MAX((element->sinkheight*element->sinks), + (element->srcheight*element->srcs)) + 4.0; + element->minwidth = MAX(element->minwidth, + ((element->sinkwidth*element->sinks) + + (element->srcwidth*element->srcs) + 4.0)); +// g_print("have %d sinks (%.2fx%.2f) and %d srcs (%.2fx%.2f)\n", +// element->sinks,element->sinkwidth,element->sinkheight, +// element->srcs,element->srcwidth,element->srcheight); + + // grow the element to hold all the stuff +// g_print("minsize is %.2fx%.2f, +//",element->minwidth,element->minheight); +// g_print("size was %.2fx%.2f, ",element->width,element->height); + element->width = MAX(element->width,element->minwidth); + element->height = MAX(element->height,element->minheight); +// g_print("is now %.2fx%.2f\n",element->width,element->height); +} + +void gst_editor_element_repack(GstEditorElement *element) { + GList *pads; + GstPad *pad; + GstEditorPad *editorpad; + gdouble sinkwidth,sinkheight; + gint sinks; + gdouble srcwidth,srcheight; + gint srcs; + gdouble x1,y1,x2,y2; + gint i; + + if (!element->realized) return; + + gst_editor_element_resize(element); + + // still use x1,y1,x2,y2 so we can change around later + x1 = 0.0;y1 = 0.0; + x2 = element->width;y2 = element->height; + +// g_print("repacking element at %.2fx%.2f + %.2fx%.2f\n", +// element->x,element->y,x2,y2); + + // move the element group to match + gnome_canvas_item_set(GNOME_CANVAS_ITEM(element->group), + "x",element->x,"y",element->y,NULL); + + // start by resizing the bordering box + g_return_if_fail(element->border != NULL); + gtk_object_set(GTK_OBJECT(element->border), + "x1",x1,"y1",y1,"x2",x2,"y2",y2,NULL); + + // then move the text to the new top left + g_return_if_fail(element->title != NULL); + gtk_object_set(GTK_OBJECT(element->title), + "x",x1+1.0,"y",y1+1.0, + "anchor",GTK_ANCHOR_NORTH_WEST, + NULL); + + // and move the resize box + g_return_if_fail(element->resizebox != NULL); + gtk_object_set(GTK_OBJECT(element->resizebox), + "x1",x2-5.0,"y1",y2-5.0,"x2",x2,"y2",y2,NULL); + + // now place the state boxes + for (i=0;i<4;i++) { + g_return_if_fail(element->statebox[i] != NULL); + gtk_object_set(GTK_OBJECT(element->statebox[i]), + "x1",x1+(element->statewidth*i), + "y1",y2-element->stateheight, + "x2",x1+(element->statewidth*(i+1)),"y2",y2,NULL); + g_return_if_fail(element->statetext[i] != NULL); + gtk_object_set(GTK_OBJECT(element->statetext[i]), + "x",x1+(element->statewidth*i)+2.0, + "y",y2-element->stateheight+1.0, + "anchor",GTK_ANCHOR_NORTH_WEST,NULL); + } + // and the playstate box + g_return_if_fail(element->playbox != NULL); + gtk_object_set(GTK_OBJECT(element->playbox), + "x1",x1+(element->statewidth*4), + "y1",y2-element->stateheight, + "x2",x1+(element->statewidth*5),"y2",y2,NULL); + g_return_if_fail(element->playtext != NULL); + gtk_object_set(GTK_OBJECT(element->playtext), + "x",x1+(element->statewidth*4)+2.0, + "y",y2-element->stateheight+1.0, + "anchor",GTK_ANCHOR_NORTH_WEST,NULL); + + // now we try to place all the pads + sinks = element->sinks; + pads = element->sinkpads; + while (pads) { + editorpad = GST_EDITOR_PAD(pads->data); + gtk_object_set(GTK_OBJECT(editorpad), + "x",x1, + "y",y2 - 2.0 - element->stateheight - + (element->sinkheight * sinks), + NULL); + gst_editor_pad_repack(editorpad); + sinks--; + pads = g_list_next(pads); + } + + srcs = element->srcs; + pads = element->srcpads; + while (pads) { + editorpad = GST_EDITOR_PAD(pads->data); + gtk_object_set(GTK_OBJECT(editorpad), + "x",x2 - element->srcwidth, + "y",y2 - 2.0 - element->stateheight - + (element->srcheight * srcs), + NULL); + gst_editor_pad_repack(editorpad); + srcs--; + pads = g_list_next(pads); + } + +// g_print("done resizing element\n"); +} + + +GstEditorPad *gst_editor_element_add_pad(GstEditorElement *element, + GstPad *pad) { + GstEditorPad *editorpad; + + editorpad = gst_editor_pad_new(element,pad,NULL); + if (pad->direction == GST_PAD_SINK) { + element->sinkpads = g_list_prepend(element->sinkpads,editorpad); + element->sinks++; +// g_print("added 'new' pad to sink list\n"); + } else if (pad->direction == GST_PAD_SRC) { + element->srcpads = g_list_prepend(element->srcpads,editorpad); + element->srcs++; +// g_print("added 'new' pad to src list\n"); + } else + g_print("HUH?!? Don't know which direction this pad is...\n"); + + element->padlistchange = TRUE; + gst_editor_element_repack(element); + return editorpad; +} + + +static gint gst_editor_element_group_event(GnomeCanvasItem *item, + GdkEvent *event, + GstEditorElement *element) { +// g_print("in group_event, type %d\n",event->type); + if (GST_EDITOR_ELEMENT_CLASS(GTK_OBJECT(element)->klass)->event) + return (GST_EDITOR_ELEMENT_CLASS(GTK_OBJECT(element)->klass)->event)( + item,event,element); + return FALSE; +} + + +static gint gst_editor_element_event(GnomeCanvasItem *item,GdkEvent *event, + GstEditorElement *element) { + gdouble item_x,item_y,dx,dy; + GdkCursor *fleur; + +// g_print("element in event, type %d\n",event->type); + + switch(event->type) { + case GDK_ENTER_NOTIFY: + break; + case GDK_LEAVE_NOTIFY: + break; + case GDK_BUTTON_PRESS: + // dragxy coords are world coords of button press + element->dragx = event->button.x; + element->dragy = event->button.y; + // set some flags + element->dragging = TRUE; + element->moved = FALSE; + fleur = gdk_cursor_new(GDK_FLEUR); + gnome_canvas_item_grab(item, + GDK_POINTER_MOTION_MASK | +// GDK_ENTER_NOTIFY_MASK | +// GDK_LEAVE_NOTIFY_MASK | + GDK_BUTTON_RELEASE_MASK, + fleur,event->button.time); + return TRUE; + break; + case GDK_MOTION_NOTIFY: + if (element->dragging) { + dx = event->button.x - element->dragx; + dy = event->button.y - element->dragy; + gst_editor_element_move(element,dx,dy); + element->dragx = event->button.x; + element->dragy = event->button.y; + element->moved = TRUE; + } + return TRUE; + break; + case GDK_BUTTON_RELEASE: + if (element->dragging) { + element->dragging = FALSE; + gnome_canvas_item_ungrab(item,event->button.time); + } + if (!element->moved) { + GstEditorElementClass *elementclass; + elementclass = GST_EDITOR_ELEMENT_CLASS(GTK_OBJECT(element)->klass); + if (elementclass->button_event) + (elementclass->button_event)(item,event,element); + } +//g_print("in element group_event, setting inchild"); + element->canvas->inchild = TRUE; + return TRUE; + break; + + default: + break; + } + return FALSE; +} + + +static gint gst_editor_element_resizebox_event(GnomeCanvasItem *item, + GdkEvent *event, + GstEditorElement *element) { + GdkCursor *bottomright; + gdouble item_x,item_y; + +// g_print("in resizebox_event...\n"); + + // calculate coords relative to the group, not the box + item_x = event->button.x; + item_y = event->button.y; + gnome_canvas_item_w2i(item->parent,&item_x,&item_y); + + switch(event->type) { + case GDK_ENTER_NOTIFY: + break; + case GDK_LEAVE_NOTIFY: + element->hesitating = FALSE; + break; + case GDK_BUTTON_PRESS: + element->dragx = event->button.x; + element->dragy = event->button.y; + element->resizing = TRUE; + element->hesitating = TRUE; + bottomright = gdk_cursor_new(GDK_BOTTOM_RIGHT_CORNER); + gnome_canvas_item_grab(item, + GDK_POINTER_MOTION_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_BUTTON_RELEASE_MASK, + bottomright,event->button.time); + return TRUE; + break; + case GDK_MOTION_NOTIFY: + if (element->resizing) { + // doing a set because the code is in the arg set code +// g_print("resizing to x2,y2 of %.2f,%.2f\n",item_x,item_y); + gtk_object_set(GTK_OBJECT(element),"x2",item_x,"y2",item_y,NULL); + element->resize = TRUE; + gst_editor_element_repack(element); + return TRUE; + } + break; + case GDK_BUTTON_RELEASE: + if (element->resizing) { + element->resizing = FALSE; + gnome_canvas_item_ungrab(item,event->button.time); +//g_print("in element resizebox_event, setting inchild"); + element->canvas->inchild = TRUE; + return TRUE; + } + break; + default: + break; + } + return FALSE; +} + + +static gint gst_editor_element_state_event(GnomeCanvasItem *item, + GdkEvent *event, + gpointer data) { + GstEditorElement *element; + gint id = GPOINTER_TO_INT(data); + GdkCursor *uparrow; + + element = GST_EDTIOR_GET_OBJECT(item); + + switch (event->type) { + case GDK_ENTER_NOTIFY: + uparrow = gdk_cursor_new(GDK_SB_UP_ARROW); + gnome_canvas_item_grab(item, + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_LEAVE_NOTIFY_MASK, + uparrow,event->button.time); + /* NOTE: when grabbing canvas item, always get pointer_motion, + this will allow you to actually get all the other synth events */ + break; + case GDK_LEAVE_NOTIFY: + gnome_canvas_item_ungrab(item,event->button.time); + break; + case GDK_BUTTON_PRESS: + return TRUE; + break; + case GDK_BUTTON_RELEASE: + if (id < 5) { + element->states[id] = !element->states[id]; + gst_editor_element_set_state(element,id,TRUE); + } else + g_warning("Uh, shouldn't have gotten here, unknown state\n"); +//g_print("in element statebox_event, setting inchild"); + element->canvas->inchild = TRUE; + return TRUE; + break; + default: + break; + } + return FALSE; +} + + +static void gst_editor_element_set_state(GstEditorElement *element, + gint id,gboolean set) { + gboolean stateset = TRUE; /* if we have no element, set anyway */ + if (element->states[id]) { + /* set the object state */ + if (set && element->element) + stateset = gst_element_set_state(element->element,(1 << id)); + /* change the display */ + if (stateset) { + if (id < 4) { + gtk_object_set(GTK_OBJECT(element->statebox[id]), + "fill_color","black",NULL); + gtk_object_set(GTK_OBJECT(element->statetext[id]), + "fill_color","white",NULL); + } else if (id == 4) { + gtk_object_set(GTK_OBJECT(element->playbox), + "fill_color","black",NULL); + gtk_object_set(GTK_OBJECT(element->playtext), + "fill_color","white",NULL); + } + } else { + g_print("error setting state %d\n",id); + element->states[id] = !element->states[id]; + } + } else { + if (set && element->element) + stateset = gst_element_set_state(element->element,~(1 << id)); + if (stateset) { + if (id < 4) { + gtk_object_set(GTK_OBJECT(element->statebox[id]), + "fill_color","white",NULL); + gtk_object_set(GTK_OBJECT(element->statetext[id]), + "fill_color","black",NULL); + } else if (id == 4) { + gtk_object_set(GTK_OBJECT(element->playbox), + "fill_color","white",NULL); + gtk_object_set(GTK_OBJECT(element->playtext), + "fill_color","black",NULL); + } + } else { + g_print("error unsetting state %d\n",id); + element->states[id] = !element->states[id]; + } + } +} + + +static void gst_editor_element_state_change(GstElement *element, + gint state, + GstEditorElement *editorelement) { + gint id; + + g_return_if_fail(editorelement != NULL); + +// g_print("gst_editor_element_state_change got state 0x%08x\n",state); + // if it's an unset + if (state & GST_STATE_MAX) { + state = ~state; + for (id=0;id<(sizeof(state)*8)-1;id++) { + if (state & 1) { + editorelement->states[id] = FALSE; + break; + } + state /= 2; + } + } else { + for (id=0;id<(sizeof(state)*8)-1;id++) { + if (state & 1) { + editorelement->states[id] = TRUE; + break; + } + state /= 2; + } + } + gst_editor_element_set_state(editorelement,id,FALSE); +} + +static void gst_editor_element_sync_state(GstEditorElement *element) { + gint id; + +// g_print("syncronizing state\n"); + for (id=0;id<5;id++) { + element->states[id] = GST_FLAG_IS_SET(element->element,1<<id); + gst_editor_element_set_state(element,id,FALSE); + } +} + +static void gst_editor_element_move(GstEditorElement *element, + gdouble dx,gdouble dy) { + GList *pads; + GstEditorPad *pad; + + // this is a 'little' trick to keep from repacking the whole thing... + element->x += dx;element->y += dy; + gnome_canvas_item_move(GNOME_CANVAS_ITEM(element->group),dx,dy); + + pads = element->srcpads; + while (pads) { + pad = GST_EDITOR_PAD(pads->data); + if (pad->connection) { +// g_print("updating pad's connection\n"); + pad->connection->resize = TRUE; + gst_editor_connection_resize(pad->connection); + } + pads = g_list_next(pads); + } + pads = element->sinkpads; + while (pads) { + pad = GST_EDITOR_PAD(pads->data); + if (pad->connection) { +// g_print("updating pad's connection\n"); + pad->connection->resize = TRUE; + gst_editor_connection_resize(pad->connection); + } + pads = g_list_next(pads); + } +} |