[prev in list] [next in list] [prev in thread] [next in thread] 

List:       dia-list
Subject:    =?UTF-8?Q?Re:_Bug_60331_=EF=BF=BD_Object_propertie?=
From:       "Sameer Sahasrabuddhe" <sameerds () gmail ! com>
Date:       2008-11-29 18:48:18
Message-ID: 4cc31ad30811291036p3e8161abn88e28f917f807c5f () mail ! gmail ! com
[Download RAW message or body]

Hello,

Attaching the code for a new Selection object derived from a
DiaObject. It is of course not yet ready to be included ... as you can
see from the last three functions in the file, some other changes need
to be made first. Also, if we do replace the GList in DiagramData with
this Selection object, then all the code that accesses that list will
have to be replaced by functions defined for the Selection object.

I think this new object is the right approach to take. Causes no
changes to any established API, and promotes the notion of a set of
selected objects to a first class object in itself. That is likely to
expose places where the same code is repeated, which could instead be
defined as a function.

Sameer.
-- 
http://www.it.iitb.ac.in/~sameerds/

["selection.c" (text/x-csrc)]

/* Dia -- an diagram creation/manipulation program
 * Copyright(C) 1998 Alexander Larsson
 *
 * selection.c: container object to represent the current selection
 * Copyright(C) 2008 Sameer D. Sahasrabuddhe
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 *(at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "selection.h"
#include "object.h"

typedef struct _SelectionPropChange SelectionPropChange;

struct _Selection
{
  DiaObject object;		/* parent class */
  GList *objects;		/* we don't own these */
};

static Selection* selection_create();
static void selection_destroy(Selection * sel);

static DiaObject *selection_copy(Selection * sel);

static void selection_select(Selection * sel,
			     Point * clicked_point,
			     DiaRenderer * interactive_renderer);

static SelectionPropChange *selection_move(Selection * sel, Point * delta);
static SelectionPropChange *selection_move_handle(Selection * sel,
						  Handle * handle,
						  Point * pos,
						  ConnectionPoint * cp,
						  HandleMoveReason reason,
						  ModifierKeys modifiers);

static SelectionPropChange *selection_apply_properties_list(Selection * sel,
							    GPtrArray * props);

static void selection_draw(Selection * sel, DiaRenderer * ddisp);
static real selection_distance_from(Selection * sel, Point * point);

static const PropDescription *selection_describe_props(Selection * sel);
static void selection_get_props(Selection * sel, GPtrArray * props);
static void selection_set_props(Selection * sel, GPtrArray * props);

static ObjectOps selection_ops = {
 (DestroyFunc) selection_destroy,
 (DrawFunc) selection_draw,
 (DistanceFunc) selection_distance_from,
 (SelectFunc) NULL,
 (CopyFunc) selection_copy,
 (MoveFunc) selection_move,
 (MoveHandleFunc) selection_move_handle,
 (GetPropertiesFunc) object_create_props_dialog,
 (ApplyPropertiesDialogFunc) object_apply_props_from_dialog,
 (ObjectMenuFunc) NULL,
 (DescribePropsFunc) selection_describe_props,
 (GetPropsFunc) selection_get_props,
 (SetPropsFunc) selection_set_props,
 (TextEditFunc) 0,
 (ApplyPropertiesListFunc) selection_apply_properties_list,
};

DiaObjectType selection_type = {
  "Selection",
  0,
  NULL
};

Selection *
selection_create()
{
  Selection *sel;
  DiaObject *obj;

  sel = g_new0(Selection, 1);
  obj = &sel->object;
  obj->type = &selection_type;
  obj->ops = &selection_ops;

  /* Note that the selection is always at the origin. */
  obj->position.x = 0.0;
  obj->position.y = 0.0;

  return sel;
}

static void
selection_destroy(Selection * sel)
{
  /* Don't actually destroy the objects. We don't own them. */
  g_list_free(sel->objects);
  sel->objects = NULL;
}

static DiaObject *
selection_copy(Selection * sel)
{
  DiaObject *obj, *newobj;
  Selection *newsel;

  newsel = g_new0(Selection, 1);

  obj = &sel->object;
  newobj = &newsel->object;
  object_copy(obj, newobj);

  /* Shallow copy. We don't own them, remember? */
  newsel->objects = g_list_copy(sel->objects);

  return(DiaObject *) newsel;
}

static void
selection_select(Selection * sel,
		 Point * clicked_point,
		 DiaRenderer * interactive_renderer)
{
  /* Since the selection is not a real object, it cannot be
     selected. */
  g_return_if_reached();
}

static SelectionPropChange *
selection_move(Selection * sel, Point * to)
{
  GList *i;
  DiaObject *selobj = (DiaObject*)sel;

  g_warn_if_fail(selobj->position.x == 0.0 && selobj->position.y == 0.0);
  
  /* In any code that ends up moving the selection, the call to "move"
     for each selected object first computes the destination using the
     current position of that object. That code now moves only the
     Selection object, which is at the origin. Hence the destination
     computed is actually the delta. We recalculate the destination of
     each selected object before calling "move" on that object. Ugly,
     but effective. */
  for (i = sel->objects; i != NULL; i = g_list_next(i)) {
    DiaObject *object = (DiaObject*)i->data;
    Point pos = object->position;
    point_add(&pos, to);
    object->ops->move(object, &pos);
  }
}

static SelectionPropChange*
selection_move_handle(Selection * sel,
		      Handle * handle,
		      Point * pos,
		      ConnectionPoint * cp,
		      HandleMoveReason reason,
		      ModifierKeys modifiers)
{
  /* Selections don't have handles. Not yet. */
  g_return_if_reached();
}

static void
selection_draw(Selection * sel, DiaRenderer * ddisp)
{
  /* Selections are not real objects in the diagram, and hence this
     function will be never called. */
  g_return_if_reached();
}

static real
selection_distance_from(Selection * sel, Point * point)
{
  /* This should not get called. If it does, then the selection is
     also wherever you are, not just the origin. */
  g_return_val_if_reached((real)0.0);
}
  
static const PropDescription*
selection_describe_props(Selection * sel)
{
  /* The code here is identical to group_describe_props. The body of
     that function should be extracted into a function called
     object_list_describe_props. It should take an additional argument
     that determines whether a union or intersection is desired. */
}

static void
selection_get_props(Selection * sel, GPtrArray * props)
{
  /* Again, the same as group_get_props, to be extracted into
     object_list_get_props. */
}

static void
selection_set_props(Selection * sel, GPtrArray * props)
{
  /* Same as above. */
}


_______________________________________________
dia-list mailing list
dia-list@gnome.org
http://mail.gnome.org/mailman/listinfo/dia-list
FAQ at http://live.gnome.org/Dia/Faq
Main page at http://live.gnome.org/Dia



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic