[tbo] Group selection to move and resize.
- From: Daniel Garcia Moreno <danigm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tbo] Group selection to move and resize.
- Date: Sun, 21 Nov 2010 10:17:45 +0000 (UTC)
commit b420034838fd32e46d2481220ea2b8e22fdfa093
Author: danigm <dani danigm net>
Date: Sun Nov 7 19:46:38 2010 +0100
Group selection to move and resize.
src/Makefile.am | 2 +
src/tbo-object-base.c | 81 +++++++++++-------
src/tbo-object-base.h | 30 ++++---
src/tbo-object-group.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++
src/tbo-object-group.h | 68 +++++++++++++++
src/tbo-tool-selector.c | 62 +++++++++++++-
6 files changed, 405 insertions(+), 51 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index e004c7c..b0ddf4b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -50,6 +50,8 @@ SOURCES = \
tbo-object-text.c \
tbo-object-pixmap.h \
tbo-object-pixmap.c \
+ tbo-object-group.h \
+ tbo-object-group.c \
tbo-tool-base.h \
tbo-tool-base.c \
tbo-tool-selector.h \
diff --git a/src/tbo-object-base.c b/src/tbo-object-base.c
index b8e3d27..90dd37e 100644
--- a/src/tbo-object-base.c
+++ b/src/tbo-object-base.c
@@ -39,6 +39,49 @@ save (TboObjectBase *self, FILE *file)
{
}
+static void
+move (TboObjectBase *self, enum MOVE_OPT type)
+{
+ switch (type)
+ {
+ case MOVE_UP:
+ self->y -= MOVING_OFFSET;
+ break;
+ case MOVE_DOWN:
+ self->y += MOVING_OFFSET;
+ break;
+ case MOVE_LEFT:
+ self->x -= MOVING_OFFSET;
+ break;
+ case MOVE_RIGHT:
+ self->x += MOVING_OFFSET;
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+resize (TboObjectBase *self, enum RESIZE_OPT type)
+{
+ switch (type)
+ {
+ case RESIZE_LESS:
+ if (self->width > 10 && self->height > 10)
+ {
+ self->width *= 0.95;
+ self->height *= 0.95;
+ }
+ break;
+ case RESIZE_GREATER:
+ self->width *= 1.05;
+ self->height *= 1.05;
+ break;
+ default:
+ break;
+ }
+}
+
static TboObjectBase *
clone (TboObjectBase *self)
{
@@ -61,6 +104,9 @@ tbo_object_base_init (TboObjectBase *self)
self->draw = draw;
self->save = save;
self->clone = clone;
+
+ self->move = move;
+ self->resize = resize;
}
static void
@@ -145,42 +191,11 @@ tbo_object_base_order_up (TboObjectBase *self, Frame *frame)
void
tbo_object_base_move (TboObjectBase *self, enum MOVE_OPT type)
{
- switch (type)
- {
- case MOVE_UP:
- self->y -= MOVING_OFFSET;
- break;
- case MOVE_DOWN:
- self->y += MOVING_OFFSET;
- break;
- case MOVE_LEFT:
- self->x -= MOVING_OFFSET;
- break;
- case MOVE_RIGHT:
- self->x += MOVING_OFFSET;
- break;
- default:
- break;
- }
+ self->move (self, type);
}
void
tbo_object_base_resize (TboObjectBase *self, enum RESIZE_OPT type)
{
- switch (type)
- {
- case RESIZE_LESS:
- if (self->width > 10 && self->height > 10)
- {
- self->width *= 0.95;
- self->height *= 0.95;
- }
- break;
- case RESIZE_GREATER:
- self->width *= 1.05;
- self->height *= 1.05;
- break;
- default:
- break;
- }
+ self->resize (self, type);
}
diff --git a/src/tbo-object-base.h b/src/tbo-object-base.h
index c877cef..d643114 100644
--- a/src/tbo-object-base.h
+++ b/src/tbo-object-base.h
@@ -37,6 +37,20 @@
typedef struct _TboObjectBase TboObjectBase;
typedef struct _TboObjectBaseClass TboObjectBaseClass;
+enum MOVE_OPT
+{
+ MOVE_UP,
+ MOVE_DOWN,
+ MOVE_LEFT,
+ MOVE_RIGHT,
+};
+
+enum RESIZE_OPT
+{
+ RESIZE_LESS,
+ RESIZE_GREATER,
+};
+
struct _TboObjectBase
{
GObject parent_instance;
@@ -53,6 +67,8 @@ struct _TboObjectBase
void (*draw) (TboObjectBase *, Frame *, cairo_t *);
void (*save) (TboObjectBase *, FILE *);
TboObjectBase * (*clone) (TboObjectBase *);
+ void (*move) (TboObjectBase *, enum MOVE_OPT type);
+ void (*resize) (TboObjectBase *, enum RESIZE_OPT type);
};
struct _TboObjectBaseClass
@@ -69,20 +85,6 @@ GType tbo_object_base_get_type (void);
* Method definitions.
*/
-enum MOVE_OPT
-{
- MOVE_UP,
- MOVE_DOWN,
- MOVE_LEFT,
- MOVE_RIGHT,
-};
-
-enum RESIZE_OPT
-{
- RESIZE_LESS,
- RESIZE_GREATER,
-};
-
GObject * tbo_object_base_new ();
void tbo_object_base_flipv (TboObjectBase *self);
void tbo_object_base_fliph (TboObjectBase *self);
diff --git a/src/tbo-object-group.c b/src/tbo-object-group.c
new file mode 100644
index 0000000..0f871b1
--- /dev/null
+++ b/src/tbo-object-group.c
@@ -0,0 +1,213 @@
+/*
+ * This file is part of TBO, a gnome comic editor
+ * Copyright (C) 2010 Daniel Garcia Moreno <dani danigm net>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <glib.h>
+#include <cairo.h>
+#include <stdio.h>
+#include "tbo-types.h"
+#include "tbo-object-group.h"
+
+G_DEFINE_TYPE (TboObjectGroup, tbo_object_group, TBO_TYPE_OBJECT_BASE);
+
+static TboObjectBase * clone (TboObjectBase *);
+
+static TboObjectBase *
+clone (TboObjectBase *self)
+{
+}
+
+static void tbo_object_group_get_base (TboObjectGroup *self, gint *minx, gint *miny, gint *maxx, gint *maxy);
+
+static void
+resize (TboObjectBase *self, enum RESIZE_OPT type)
+{
+ GList *o;
+ TboObjectBase *obj;
+ gdouble scale = 1.0;
+ gint minx=-1, miny=-1, maxx=0, maxy=0;
+ tbo_object_group_get_base (TBO_OBJECT_GROUP (self), &minx, &miny, &maxx, &maxy);
+
+ switch (type)
+ {
+ case RESIZE_LESS:
+ scale -= 0.05;
+ break;
+ case RESIZE_GREATER:
+ scale += 0.05;
+ break;
+ default:
+ break;
+ }
+
+ for (o=g_list_first (TBO_OBJECT_GROUP (self)->objs); o; o=g_list_next(o))
+ {
+ obj = TBO_OBJECT_BASE (o->data);
+
+ if ((obj->width < 10 || obj->height < 10) && scale < 1)
+ break;
+
+ obj->width *= scale;
+ obj->x = minx + (obj->x - minx) * scale;
+ obj->height *= scale;
+ obj->y = miny + (obj->y - miny) * scale;
+ }
+}
+
+static void
+move (TboObjectBase *self, enum MOVE_OPT type)
+{
+ TBO_OBJECT_GROUP (self)->parent_move (self, type);
+ tbo_object_group_update_status (TBO_OBJECT_GROUP (self));
+}
+
+/* init methods */
+
+static void
+tbo_object_group_init (TboObjectGroup *self)
+{
+ self->objs = NULL;
+ self->parent_move = self->parent_instance.move;
+
+ self->parent_instance.clone = clone;
+ self->parent_instance.resize = resize;
+ self->parent_instance.move = move;
+}
+
+static void
+tbo_object_group_finalize (GObject *self)
+{
+ if (TBO_IS_OBJECT_GROUP (self))
+ {
+ if ((TBO_OBJECT_GROUP (self)->objs))
+ g_list_free (TBO_OBJECT_GROUP (self)->objs);
+ }
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (tbo_object_group_parent_class)->finalize (self);
+}
+
+static void
+tbo_object_group_class_init (TboObjectGroupClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = tbo_object_group_finalize;
+}
+
+/* object functions */
+
+GObject *
+tbo_object_group_new ()
+{
+ GObject *tbo_object;
+ tbo_object = g_object_new (TBO_TYPE_OBJECT_GROUP, NULL);
+
+ return tbo_object;
+}
+
+void
+tbo_object_group_add (TboObjectGroup *self, TboObjectBase *obj)
+{
+ if (TBO_IS_OBJECT_GROUP (obj))
+ return;
+ if (!g_list_find (self->objs, obj))
+ self->objs = g_list_append (self->objs, obj);
+}
+
+void
+tbo_object_group_del (TboObjectGroup *self, TboObjectBase *obj)
+{
+ self->objs = g_list_remove (g_list_first (self->objs), obj);
+}
+
+void
+tbo_object_group_get_base (TboObjectGroup *self,
+ gint *minx, gint *miny,
+ gint *maxx, gint *maxy)
+{
+ GList *o;
+ TboObjectBase *obj;
+
+ for (o=g_list_first (self->objs); o; o=g_list_next(o))
+ {
+ obj = TBO_OBJECT_BASE (o->data);
+ if (*minx < 0 || obj->x < *minx)
+ *minx = obj->x;
+ if (*miny < 0 || obj->y < *miny)
+ *miny = obj->y;
+ if ((obj->x + obj->width) > *maxx)
+ *maxx = (obj->x + obj->width);
+ if ((obj->y + obj->height) > *maxy)
+ *maxy = (obj->y + obj->height);
+ }
+}
+
+void
+tbo_object_group_set_vars (TboObjectBase *obj)
+{
+ if (!TBO_IS_OBJECT_GROUP (obj))
+ return;
+
+ gint minx=-1, miny=-1, maxx=0, maxy=0;
+ tbo_object_group_get_base (TBO_OBJECT_GROUP (obj), &minx, &miny, &maxx, &maxy);
+
+ obj->x = minx;
+ obj->y = miny;
+ obj->width = maxx - minx;
+ obj->height = maxy - miny;
+}
+
+void
+tbo_object_group_unset_vars (TboObjectBase *obj)
+{
+ if (!TBO_IS_OBJECT_GROUP (obj))
+ return;
+
+ obj->x = 0;
+ obj->y = 0;
+ obj->width = 0;
+ obj->height = 0;
+}
+
+void
+tbo_object_group_update_status (TboObjectGroup *self)
+{
+ GList *o;
+ gdouble scale = 1.0;
+ TboObjectBase *obj, *tbo_object;
+ gint minx=-1, miny=-1, maxx=0, maxy=0;
+
+ tbo_object = TBO_OBJECT_BASE (self);
+ tbo_object_group_get_base (self, &minx, &miny, &maxx, &maxy);
+
+ for (o=g_list_first (self->objs); o; o=g_list_next(o))
+ {
+ obj = TBO_OBJECT_BASE (o->data);
+ obj->x += tbo_object->x;
+ obj->y += tbo_object->y;
+ // resizing
+ scale = (obj->width + tbo_object->width) / (double) obj->width;
+ obj->width += tbo_object->width;
+ obj->x = minx + (obj->x - minx) * scale;
+ scale = (obj->height + tbo_object->height) / (double) obj->height;
+ obj->height += tbo_object->height;
+ obj->y = miny + (obj->y - miny) * scale;
+ }
+
+ tbo_object_group_unset_vars (tbo_object);
+}
+
diff --git a/src/tbo-object-group.h b/src/tbo-object-group.h
new file mode 100644
index 0000000..779302f
--- /dev/null
+++ b/src/tbo-object-group.h
@@ -0,0 +1,68 @@
+/*
+ * This file is part of TBO, a gnome comic editor
+ * Copyright (C) 2010 Daniel Garcia Moreno <dani danigm net>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __TBO_OBJECT_GROUP_H__
+#define __TBO_OBJECT_GROUP_H__
+
+#include <glib.h>
+#include "tbo-object-base.h"
+#include "tbo-object-group.h"
+
+#define TBO_TYPE_OBJECT_GROUP (tbo_object_group_get_type ())
+#define TBO_OBJECT_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TBO_TYPE_OBJECT_GROUP, TboObjectGroup))
+#define TBO_IS_OBJECT_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TBO_TYPE_OBJECT_GROUP))
+#define TBO_OBJECT_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TBO_TYPE_OBJECT_GROUP, TboObjectGroupClass))
+#define TBO_IS_OBJECT_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TBO_TYPE_OBJECT_GROUP))
+#define TBO_OBJECT_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TBO_TYPE_OBJECT_GROUP, TboObjectGroupClass))
+
+typedef struct _TboObjectGroup TboObjectGroup;
+typedef struct _TboObjectGroupClass TboObjectGroupClass;
+
+struct _TboObjectGroup
+{
+ TboObjectBase parent_instance;
+
+ /* instance members */
+ GList *objs;
+ void (*parent_move) (TboObjectBase *, enum MOVE_OPT type);
+};
+
+struct _TboObjectGroupClass
+{
+ TboObjectBaseClass parent_class;
+
+ /* class members */
+};
+
+/* used by TBO_TYPE_OBJECT_GROUP */
+GType tbo_object_group_get_type (void);
+
+/*
+ * Method definitions.
+ */
+
+GObject * tbo_object_group_new ();
+void tbo_object_group_add (TboObjectGroup *self, TboObjectBase *obj);
+void tbo_object_group_del (TboObjectGroup *self, TboObjectBase *obj);
+void tbo_object_group_set_vars (TboObjectBase *self);
+void tbo_object_group_unset_vars (TboObjectBase *self);
+void tbo_object_group_update_status (TboObjectGroup *self);
+
+#endif /* __TBO_OBJECT_GROUP_H__ */
+
diff --git a/src/tbo-tool-selector.c b/src/tbo-tool-selector.c
index a33d3f6..ce14e91 100644
--- a/src/tbo-tool-selector.c
+++ b/src/tbo-tool-selector.c
@@ -26,6 +26,7 @@
#include "tbo-ui-utils.h"
#include "tbo-tool-selector.h"
#include "tbo-drawing.h"
+#include "tbo-object-group.h"
G_DEFINE_TYPE (TboToolSelector, tbo_tool_selector, TBO_TYPE_TOOL_BASE);
@@ -305,8 +306,8 @@ frame_view_on_move (TboToolBase *tool, GtkWidget *widget, GdkEventMotion *event)
// resizing object
if (self->resizing)
{
- self->selected_object->width = abs (self->start_m_w - offset_x);
- self->selected_object->height = abs (self->start_m_h - offset_y);
+ self->selected_object->width = self->start_m_w - offset_x;
+ self->selected_object->height = self->start_m_h - offset_y;
}
else if (self->rotating)
{
@@ -320,6 +321,20 @@ frame_view_on_move (TboToolBase *tool, GtkWidget *widget, GdkEventMotion *event)
}
}
+ // updating group object
+ if (TBO_IS_OBJECT_GROUP (self->selected_object))
+ {
+ tbo_object_group_update_status (TBO_OBJECT_GROUP (self->selected_object));
+
+ self->start_x = x;
+ self->start_y = y;
+ self->start_m_x = self->selected_object->x;
+ self->start_m_y = self->selected_object->y;
+ self->start_m_w = self->selected_object->width;
+ self->start_m_h = self->selected_object->height;
+ }
+
+ tbo_object_group_set_vars (self->selected_object);
// over resizer
if (over_resizer_obj (self, self->selected_object, x, y))
{
@@ -338,6 +353,8 @@ frame_view_on_move (TboToolBase *tool, GtkWidget *widget, GdkEventMotion *event)
{
self->over_rotater = FALSE;
}
+ tbo_object_group_unset_vars (self->selected_object);
+
}
}
@@ -348,7 +365,8 @@ frame_view_on_click (TboToolBase *tool, GtkWidget *widget, GdkEventButton *event
int x, y;
GList *obj_list;
Frame *frame;
- TboObjectBase *obj;
+ TboObjectBase *obj, *obj2;
+ TboObjectGroup *group;
TboDrawing *drawing = TBO_DRAWING (tool->tbo->drawing);
gboolean found = FALSE;
@@ -356,6 +374,7 @@ frame_view_on_click (TboToolBase *tool, GtkWidget *widget, GdkEventButton *event
y = (int)event->y;
// resizing
+ tbo_object_group_set_vars (self->selected_object);
if (self->selected_object && over_resizer_obj (self, self->selected_object, x, y))
{
self->resizing = TRUE;
@@ -367,19 +386,41 @@ frame_view_on_click (TboToolBase *tool, GtkWidget *widget, GdkEventButton *event
else
{
frame = tbo_drawing_get_current_frame (drawing);
+
for (obj_list = g_list_first (frame->objects); obj_list; obj_list = obj_list->next)
{
obj = TBO_OBJECT_BASE (obj_list->data);
+ tbo_object_group_set_vars (obj);
if (tbo_frame_point_inside_obj (obj, x, y))
{
// Selecting last occurrence.
- tbo_tool_selector_set_selected_obj (self, obj);
+ obj2 = obj;
found = TRUE;
}
+ tbo_object_group_unset_vars (obj);
}
+
if (!found)
tbo_tool_selector_set_selected_obj (self, NULL);
+ else
+ {
+ if ((event->state & GDK_SHIFT_MASK) && self->selected_object) {
+ if (!TBO_IS_OBJECT_GROUP (self->selected_object))
+ {
+ group = TBO_OBJECT_GROUP (tbo_object_group_new ());
+ tbo_frame_add_obj (frame, TBO_OBJECT_BASE (group));
+ tbo_object_group_add (group, self->selected_object);
+ }
+ else
+ group = TBO_OBJECT_GROUP (self->selected_object);
+
+ tbo_object_group_add (group, obj2);
+ obj2 = TBO_OBJECT_BASE (group);
+ }
+ tbo_tool_selector_set_selected_obj (self, obj2);
+ }
}
+ tbo_object_group_unset_vars (self->selected_object);
self->start_x = x;
self->start_y = y;
@@ -407,12 +448,16 @@ frame_view_drawing (TboToolBase *tool, cairo_t *cr)
Color *rotater_fill;
int x, y;
float r_size;
+ gboolean group = FALSE;
TboToolSelector *self = TBO_TOOL_SELECTOR (tool);
TboObjectBase *current_obj = self->selected_object;
TboDrawing *drawing = TBO_DRAWING (tool->tbo->drawing);
if (current_obj != NULL)
{
+ if (TBO_IS_OBJECT_GROUP (current_obj))
+ tbo_object_group_set_vars (current_obj);
+
cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
cairo_set_line_width (cr, 1);
cairo_set_dash (cr, dashes, G_N_ELEMENTS (dashes), 0);
@@ -487,6 +532,9 @@ frame_view_drawing (TboToolBase *tool, cairo_t *cr)
cairo_line_to (cr, self->x, self->y);
cairo_stroke (cr);
}
+
+ if (TBO_IS_OBJECT_GROUP (current_obj))
+ tbo_object_group_unset_vars (current_obj);
}
}
@@ -810,6 +858,12 @@ tbo_tool_selector_set_selected (TboToolSelector *self, Frame *frame)
void
tbo_tool_selector_set_selected_obj (TboToolSelector *self, TboObjectBase *obj)
{
+ if (!obj && TBO_IS_OBJECT_GROUP (self->selected_object))
+ {
+ TboDrawing *drawing = TBO_DRAWING (TBO_TOOL_BASE (self)->tbo->drawing);
+ Frame *frame = tbo_drawing_get_current_frame (drawing);
+ tbo_frame_del_obj (frame, self->selected_object);
+ }
self->selected_object = obj;
update_menubar (TBO_TOOL_BASE (self)->tbo);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]