2 * This file is part of TBO, a gnome comic editor
3 * Copyright (C) 2010 Daniel Garcia Moreno <dani@danigm.net>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <glib/gi18n.h>
22 #include <gdk/gdkkeysyms.h>
27 #include "tbo-ui-utils.h"
28 #include "tbo-tool-selector.h"
29 #include "tbo-drawing.h"
30 #include "tbo-object-group.h"
32 #include "tbo-tooltip.h"
34 G_DEFINE_TYPE (TboToolSelector, tbo_tool_selector, TBO_TYPE_TOOL_BASE);
37 static void on_move (TboToolBase *tool, GtkWidget *widget, GdkEventMotion *event);
38 static void on_click (TboToolBase *tool, GtkWidget *widget, GdkEventButton *event);
39 static void on_release (TboToolBase *tool, GtkWidget *widget, GdkEventButton *event);
40 static void on_key (TboToolBase *tool, GtkWidget *widget, GdkEventKey *event);
41 static void drawing (TboToolBase *tool, cairo_t *cr);
43 static void frame_view_on_move (TboToolBase *tool, GtkWidget *widget, GdkEventMotion *event);
44 static void page_view_on_move (TboToolBase *tool, GtkWidget *widget, GdkEventMotion *event);
45 static void frame_view_on_click (TboToolBase *tool, GtkWidget *widget, GdkEventButton *event);
46 static void page_view_on_click (TboToolBase *tool, GtkWidget *widget, GdkEventButton *event);
47 static void frame_view_drawing (TboToolBase *tool, cairo_t *cr);
48 static void page_view_drawing (TboToolBase *tool, cairo_t *cr);
49 static void frame_view_on_key (TboToolBase *tool, GtkWidget *widget, GdkEventKey *event);
55 update_selected_cb (GtkSpinButton *widget, TboToolSelector *tool)
57 TboDrawing *drawing = TBO_DRAWING (TBO_TOOL_BASE (tool)->tbo->drawing);
58 if (tool->resizing || tool->clicked || tool->selected_frame == NULL || tool->spin_x == NULL)
61 tool->selected_frame->x = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (tool->spin_x));
62 tool->selected_frame->y = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (tool->spin_y));
63 tool->selected_frame->width = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (tool->spin_w));
64 tool->selected_frame->height = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (tool->spin_h));
66 tbo_drawing_update (drawing);
71 update_color_cb (GtkColorButton *button, TboToolSelector *tool)
73 TboDrawing *drawing = TBO_DRAWING (TBO_TOOL_BASE (tool)->tbo->drawing);
74 if (tool->resizing || tool->clicked || tool->selected_frame == NULL)
77 GdkColor color = { 0, 0, 0, 0 };
78 gtk_color_button_get_color (button, &color);
79 tbo_frame_set_color (tool->selected_frame, &color);
80 tbo_drawing_update (drawing);
85 update_border_cb (GtkToggleButton *button, TboToolSelector *tool)
87 TboDrawing *drawing = TBO_DRAWING (TBO_TOOL_BASE (tool)->tbo->drawing);
88 if (tool->resizing || tool->clicked || tool->selected_frame == NULL)
91 tool->selected_frame->border = !tool->selected_frame->border;
92 tbo_drawing_update (drawing);
97 empty_tool_area (TboToolSelector *self)
99 tbo_empty_tool_area (TBO_TOOL_BASE (self)->tbo);
107 update_tool_area (TboToolSelector *self)
109 TboWindow *tbo = TBO_TOOL_BASE (self)->tbo;
110 GtkWidget *toolarea = tbo->toolarea;
115 GdkColor gdk_color = { 0, 0, 0, 0 };
119 empty_tool_area (self);
120 self->spin_x = add_spin_with_label (toolarea, "x: ", self->selected_frame->x);
121 self->spin_y = add_spin_with_label (toolarea, "y: ", self->selected_frame->y);
122 self->spin_w = add_spin_with_label (toolarea, "w: ", self->selected_frame->width);
123 self->spin_h = add_spin_with_label (toolarea, "h: ", self->selected_frame->height);
125 g_signal_connect (self->spin_x, "value-changed", G_CALLBACK (update_selected_cb), self);
126 g_signal_connect (self->spin_y, "value-changed", G_CALLBACK (update_selected_cb), self);
127 g_signal_connect (self->spin_w, "value-changed", G_CALLBACK (update_selected_cb), self);
128 g_signal_connect (self->spin_h, "value-changed", G_CALLBACK (update_selected_cb), self);
130 hpanel = gtk_hbox_new (FALSE, 0);
131 label = gtk_label_new (_("Background color: "));
132 gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
133 color = gtk_color_button_new ();
134 gdk_color.red = self->selected_frame->color->r * 65535;
135 gdk_color.green = self->selected_frame->color->g * 65535;
136 gdk_color.blue = self->selected_frame->color->b * 65535;
137 gtk_color_button_set_color (GTK_COLOR_BUTTON (color), &gdk_color);
139 gtk_box_pack_start (GTK_BOX (hpanel), label, TRUE, TRUE, 5);
140 gtk_box_pack_start (GTK_BOX (hpanel), color, TRUE, TRUE, 5);
141 gtk_box_pack_start (GTK_BOX (toolarea), hpanel, FALSE, FALSE, 5);
142 g_signal_connect (color, "color-set", G_CALLBACK (update_color_cb), self);
144 border = gtk_check_button_new_with_label (_("border"));
145 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (border), self->selected_frame->border);
146 gtk_box_pack_start (GTK_BOX (toolarea), border, FALSE, FALSE, 5);
147 g_signal_connect (border, "toggled", G_CALLBACK (update_border_cb), self);
149 gtk_widget_show_all (toolarea);
152 gtk_spin_button_set_value (GTK_SPIN_BUTTON (self->spin_x), self->selected_frame->x);
153 gtk_spin_button_set_value (GTK_SPIN_BUTTON (self->spin_y), self->selected_frame->y);
154 gtk_spin_button_set_value (GTK_SPIN_BUTTON (self->spin_w), self->selected_frame->width);
155 gtk_spin_button_set_value (GTK_SPIN_BUTTON (self->spin_h), self->selected_frame->height);
159 over_resizer (TboToolSelector *self, Frame *frame, int x, int y)
162 rx = frame->x + frame->width;
163 ry = frame->y + frame->height;
166 r_size = R_SIZE / tbo_drawing_get_zoom (TBO_DRAWING (TBO_TOOL_BASE (self)->tbo->drawing));
168 if (((rx-r_size) < x) &&
182 over_resizer_obj (TboToolSelector *self, TboObjectBase *obj, int x, int y)
186 tbo_frame_get_obj_relative (obj, &ox, &oy, &ow, &oh);
187 rx = ox + (ow * cos(obj->angle) - oh * sin(obj->angle));
188 ry = oy + (oh * cos(obj->angle) + ow * sin(obj->angle));
191 r_size = R_SIZE / tbo_drawing_get_zoom (TBO_DRAWING (TBO_TOOL_BASE (self)->tbo->drawing));
193 if (((rx-r_size) < x) &&
207 over_rotater_obj (TboToolSelector *self, TboObjectBase *obj, int x, int y)
211 tbo_frame_get_obj_relative (obj, &ox, &oy, &ow, &oh);
216 r_size = R_SIZE / tbo_drawing_get_zoom (TBO_DRAWING (TBO_TOOL_BASE (self)->tbo->drawing));
218 if (((rx-r_size/2.0) < x) &&
219 ((rx+r_size/2.0) > x) &&
220 ((ry-r_size/2.0) < y) &&
221 ((ry+r_size/2.0) > y))
233 on_move (TboToolBase *tool, GtkWidget *widget, GdkEventMotion *event)
235 TboDrawing *drawing = TBO_DRAWING (tool->tbo->drawing);
236 Frame *frame = tbo_drawing_get_current_frame (drawing);
238 frame_view_on_move (tool, widget, event);
240 page_view_on_move (tool, widget, event);
242 tbo_drawing_update (drawing);
246 on_click (TboToolBase *tool, GtkWidget *widget, GdkEventButton *event)
248 TboDrawing *drawing = TBO_DRAWING (tool->tbo->drawing);
249 Frame *frame = tbo_drawing_get_current_frame (drawing);
251 frame_view_on_click (tool, widget, event);
253 page_view_on_click (tool, widget, event);
255 tbo_drawing_update (drawing);
259 on_release (TboToolBase *tool, GtkWidget *widget, GdkEventButton *event)
261 TboToolSelector *self = TBO_TOOL_SELECTOR (tool);
264 self->clicked = FALSE;
265 self->resizing = FALSE;
266 self->rotating = FALSE;
270 on_key (TboToolBase *tool, GtkWidget *widget, GdkEventKey *event)
272 TboDrawing *drawing = TBO_DRAWING (tool->tbo->drawing);
273 Frame *frame = tbo_drawing_get_current_frame (drawing);
275 frame_view_on_key (tool, widget, event);
279 drawing (TboToolBase *tool, cairo_t *cr)
281 TboDrawing *drawing = TBO_DRAWING (tool->tbo->drawing);
282 Frame *frame = tbo_drawing_get_current_frame (drawing);
284 frame_view_drawing (tool, cr);
286 page_view_drawing (tool, cr);
291 frame_view_on_move (TboToolBase *tool, GtkWidget *widget, GdkEventMotion *event)
293 int x, y, offset_x, offset_y;
294 TboToolSelector *self = TBO_TOOL_SELECTOR (tool);
302 if (self->selected_object != NULL)
306 offset_x = (self->start_x - x) / tbo_frame_get_scale_factor ();
307 offset_y = (self->start_y - y) / tbo_frame_get_scale_factor ();
312 self->selected_object->width = self->start_m_w - offset_x;
313 self->selected_object->height = self->start_m_h - offset_y;
315 else if (self->rotating)
317 self->selected_object->angle = atan2 (offset_y, offset_x);
322 self->selected_object->x = self->start_m_x - offset_x;
323 self->selected_object->y = self->start_m_y - offset_y;
327 // updating group object
328 if (TBO_IS_OBJECT_GROUP (self->selected_object))
330 tbo_object_group_update_status (TBO_OBJECT_GROUP (self->selected_object));
334 self->start_m_x = self->selected_object->x;
335 self->start_m_y = self->selected_object->y;
336 self->start_m_w = self->selected_object->width;
337 self->start_m_h = self->selected_object->height;
340 tbo_object_group_set_vars (self->selected_object);
342 if (over_resizer_obj (self, self->selected_object, x, y))
344 self->over_resizer = TRUE;
348 self->over_resizer = FALSE;
351 if (over_rotater_obj (self, self->selected_object, x, y))
353 self->over_rotater = TRUE;
357 self->over_rotater = FALSE;
359 tbo_object_group_unset_vars (self->selected_object);
365 frame_view_on_click (TboToolBase *tool, GtkWidget *widget, GdkEventButton *event)
367 TboToolSelector *self = TBO_TOOL_SELECTOR (tool);
371 TboObjectBase *obj, *obj2;
372 TboObjectGroup *group;
373 TboDrawing *drawing = TBO_DRAWING (tool->tbo->drawing);
374 gboolean found = FALSE;
380 tbo_object_group_set_vars (self->selected_object);
381 if (self->selected_object && over_resizer_obj (self, self->selected_object, x, y))
383 self->resizing = TRUE;
385 else if (self->selected_object && over_rotater_obj (self, self->selected_object, x, y))
387 self->rotating = TRUE;
391 frame = tbo_drawing_get_current_frame (drawing);
393 for (obj_list = g_list_first (frame->objects); obj_list; obj_list = obj_list->next)
395 obj = TBO_OBJECT_BASE (obj_list->data);
396 tbo_object_group_set_vars (obj);
397 if (tbo_frame_point_inside_obj (obj, x, y))
399 // Selecting last occurrence.
403 tbo_object_group_unset_vars (obj);
407 tbo_tool_selector_set_selected_obj (self, NULL);
410 if ((event->state & GDK_SHIFT_MASK) && self->selected_object) {
411 if (!TBO_IS_OBJECT_GROUP (self->selected_object))
413 group = TBO_OBJECT_GROUP (tbo_object_group_new ());
414 tbo_frame_add_obj (frame, TBO_OBJECT_BASE (group));
415 tbo_object_group_add (group, self->selected_object);
418 group = TBO_OBJECT_GROUP (self->selected_object);
420 tbo_object_group_add (group, obj2);
421 obj2 = TBO_OBJECT_BASE (group);
423 tbo_tool_selector_set_selected_obj (self, obj2);
426 tbo_object_group_unset_vars (self->selected_object);
431 if (self->selected_object)
433 self->start_m_x = self->selected_object->x;
434 self->start_m_y = self->selected_object->y;
435 self->start_m_w = self->selected_object->width;
436 self->start_m_h = self->selected_object->height;
438 self->clicked = TRUE;
442 frame_view_drawing (TboToolBase *tool, cairo_t *cr)
444 const double dashes[] = {5, 5};
445 Color border = {0.9, 0.9, 0};
446 Color white = {1, 1, 1};
447 Color black = {0, 0, 0};
448 Color *resizer_border;
450 Color *rotater_border;
454 TboToolSelector *self = TBO_TOOL_SELECTOR (tool);
455 TboObjectBase *current_obj = self->selected_object;
456 TboDrawing *drawing = TBO_DRAWING (tool->tbo->drawing);
458 if (current_obj != NULL)
460 if (TBO_IS_OBJECT_GROUP (current_obj))
461 tbo_object_group_set_vars (current_obj);
463 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
464 cairo_set_line_width (cr, 1);
465 cairo_set_dash (cr, dashes, G_N_ELEMENTS (dashes), 0);
466 cairo_set_source_rgb (cr, border.r, border.g, border.b);
468 tbo_frame_get_obj_relative (current_obj, &ox, &oy, &ow, &oh);
470 cairo_translate (cr, ox, oy);
471 cairo_rotate (cr, current_obj->angle);
472 cairo_rectangle (cr, 0, 0, ow, oh);
476 if (self->over_resizer)
478 resizer_fill = &black;
479 resizer_border = &white;
483 resizer_fill = &white;
484 resizer_border = &black;
488 if (self->over_rotater)
490 rotater_fill = &black;
491 rotater_border = &white;
495 rotater_fill = &white;
496 rotater_border = &black;
499 cairo_set_line_width (cr, 1);
500 cairo_set_dash (cr, dashes, 0, 0);
505 r_size = R_SIZE / tbo_drawing_get_zoom (drawing);
506 cairo_set_line_width (cr, 1/tbo_drawing_get_zoom (drawing));
508 cairo_rectangle (cr, x, y, r_size, r_size);
509 cairo_set_source_rgb(cr, resizer_fill->r, resizer_fill->g, resizer_fill->b);
512 cairo_set_source_rgb(cr, resizer_border->r, resizer_border->g, resizer_border->b);
513 cairo_rectangle (cr, x, y, r_size, r_size);
516 // object rotate zone
517 cairo_set_source_rgb(cr, rotater_fill->r, rotater_fill->g, rotater_fill->b);
518 cairo_arc (cr, 0, 0, r_size / 2., 0, 2 * M_PI);
520 cairo_set_source_rgb(cr, rotater_border->r, rotater_border->g, rotater_border->b);
521 cairo_arc (cr, 0, 0, r_size / 2., 0, 2 * M_PI);
523 cairo_set_line_width (cr, tbo_drawing_get_zoom (drawing));
525 cairo_rotate (cr, -current_obj->angle);
526 cairo_translate (cr, -ox, -oy);
528 cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT);
532 cairo_set_source_rgb(cr, 1, 0, 0);
533 cairo_move_to (cr, ox, oy);
534 cairo_line_to (cr, self->x, self->y);
538 if (TBO_IS_OBJECT_GROUP (current_obj))
539 tbo_object_group_unset_vars (current_obj);
544 frame_view_on_key (TboToolBase *tool, GtkWidget *widget, GdkEventKey *event)
546 TboToolSelector *self = TBO_TOOL_SELECTOR (tool);
547 TboObjectBase *current_obj = self->selected_object;
548 TboDrawing *drawing = TBO_DRAWING (tool->tbo->drawing);
550 if (self->selected_frame != NULL && event->keyval == GDK_KEY_Escape)
552 tbo_tool_selector_set_selected (self, NULL);
553 tbo_drawing_set_current_frame (drawing, NULL);
554 update_menubar (tool->tbo);
555 tbo_toolbar_update (tool->tbo->toolbar);
558 if (current_obj != NULL)
560 switch (event->keyval)
563 tbo_object_base_resize (current_obj, RESIZE_LESS);
565 case GDK_KEY_greater:
566 tbo_object_base_resize (current_obj, RESIZE_GREATER);
569 tbo_object_base_move (current_obj, MOVE_UP);
572 tbo_object_base_move (current_obj, MOVE_DOWN);
575 tbo_object_base_move (current_obj, MOVE_LEFT);
578 tbo_object_base_move (current_obj, MOVE_RIGHT);
584 tbo_drawing_update (drawing);
588 page_view_drawing (TboToolBase *tool, cairo_t *cr)
590 const double dashes[] = {5, 5};
591 Color border = {0.9, 0.9, 0};
592 Color white = {1, 1, 1};
593 Color black = {0, 0, 0};
594 Color *resizer_border;
599 TboToolSelector *self = TBO_TOOL_SELECTOR (tool);
600 Frame *selected = self->selected_frame;
601 TboDrawing *drawing = TBO_DRAWING (tool->tbo->drawing);
603 if (selected != NULL)
605 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
606 cairo_set_line_width (cr, 1);
607 cairo_set_dash (cr, dashes, G_N_ELEMENTS (dashes), 0);
608 cairo_set_source_rgb (cr, border.r, border.g, border.b);
609 cairo_rectangle (cr, selected->x, selected->y,
610 selected->width, selected->height);
614 if (self->over_resizer)
616 resizer_fill = &black;
617 resizer_border = &white;
621 resizer_fill = &white;
622 resizer_border = &black;
625 cairo_set_line_width (cr, 1);
626 cairo_set_dash (cr, dashes, 0, 0);
628 x = selected->x + selected->width;
629 y = selected->y + selected->height;
631 r_size = R_SIZE / tbo_drawing_get_zoom (drawing);
632 cairo_set_line_width (cr, 1 / tbo_drawing_get_zoom (drawing));
633 cairo_rectangle (cr, x, y, r_size, r_size);
634 cairo_set_source_rgb(cr, resizer_fill->r, resizer_fill->g, resizer_fill->b);
637 cairo_set_source_rgb(cr, resizer_border->r, resizer_border->g, resizer_border->b);
638 cairo_rectangle (cr, x, y, r_size, r_size);
640 cairo_set_line_width (cr, tbo_drawing_get_zoom (drawing));
642 cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT);
647 page_view_on_click (TboToolBase *tool, GtkWidget *widget, GdkEventButton *event)
653 gboolean found = FALSE;
655 TboWindow *tbo = tool->tbo;
656 TboToolSelector *self = TBO_TOOL_SELECTOR (tool);
658 TboDrawing *drawing = TBO_DRAWING (tool->tbo->drawing);
664 page = tbo_comic_get_current_page (tbo->comic);
665 for (frame_list = tbo_page_get_frames (page); frame_list; frame_list = frame_list->next)
667 frame = (Frame *)frame_list->data;
668 if (tbo_frame_point_inside (frame, x, y))
670 // Selecting last occurrence.
671 tbo_tool_selector_set_selected (self, frame);
675 selected = self->selected_frame;
678 if (selected && over_resizer (self, selected, x, y))
680 self->resizing = TRUE;
683 tbo_tool_selector_set_selected (self, NULL);
685 // double click, frame view
686 if (selected && event->type == GDK_2BUTTON_PRESS)
688 tbo_drawing_set_current_frame (drawing, selected);
689 empty_tool_area (self);
690 tbo_tooltip_set (NULL, 0, 0, tbo);
691 // TODO add tooltip_notify
692 tbo_tooltip_set_center_timeout (_("press esc to go back"), 3000, tbo);
693 update_menubar (tbo);
694 tbo_toolbar_update (tbo->toolbar);
702 self->start_m_x = selected->x;
703 self->start_m_y = selected->y;
704 self->start_m_w = selected->width;
705 self->start_m_h = selected->height;
706 tbo_page_set_current_frame (page, selected);
708 self->clicked = TRUE;
712 page_view_on_move (TboToolBase *tool, GtkWidget *widget, GdkEventMotion *event)
714 int x, y, offset_x, offset_y;
715 TboWindow *tbo = tool->tbo;
716 TboToolSelector *self = TBO_TOOL_SELECTOR (tool);
717 Frame *selected = self->selected_frame;
722 if (selected != NULL)
726 offset_x = (self->start_x - x);
727 offset_y = (self->start_y - y);
732 selected->width = abs (self->start_m_w - offset_x);
733 selected->height = abs (self->start_m_h - offset_y);
735 update_tool_area (self);
740 selected->x = self->start_m_x - offset_x;
741 selected->y = self->start_m_y - offset_y;
743 update_tool_area (self);
748 if (over_resizer (self, selected, x, y))
750 self->over_resizer = TRUE;
754 self->over_resizer = FALSE;
760 Page *page = tbo_comic_get_current_page (tbo->comic);
761 gboolean found = FALSE;
764 for (frame_list = tbo_page_get_frames (page); frame_list && !found; frame_list = frame_list->next)
766 if (tbo_frame_point_inside ((Frame*)frame_list->data, x, y))
768 frame = (Frame*)frame_list->data;
769 x1 = frame->x + (frame->width / 2);
770 y1 = frame->y + (frame->height / 2);
771 tbo_tooltip_set (_("double click here"), x1, y1, tbo);
776 tbo_tooltip_set(NULL, 0, 0, tbo);
782 tbo_tool_selector_init (TboToolSelector *self)
792 self->clicked = FALSE;
793 self->over_resizer = FALSE;
794 self->over_rotater = FALSE;
795 self->resizing = FALSE;
796 self->rotating = FALSE;
802 self->parent_instance.on_move = on_move;
803 self->parent_instance.on_click = on_click;
804 self->parent_instance.on_release = on_release;
805 self->parent_instance.on_key = on_key;
806 self->parent_instance.drawing = drawing;
810 tbo_tool_selector_class_init (TboToolSelectorClass *klass)
814 /* object functions */
817 tbo_tool_selector_new ()
820 tbo_tool = g_object_new (TBO_TYPE_TOOL_SELECTOR, NULL);
825 tbo_tool_selector_new_with_params (TboWindow *tbo)
828 TboToolBase *tbo_tool_base;
829 tbo_tool = g_object_new (TBO_TYPE_TOOL_SELECTOR, NULL);
830 tbo_tool_base = TBO_TOOL_BASE (tbo_tool);
831 tbo_tool_base->tbo = tbo;
836 tbo_tool_selector_get_selected_frame (TboToolSelector *self)
838 return self->selected_frame;
842 tbo_tool_selector_get_selected_obj (TboToolSelector *self)
844 return self->selected_object;
848 tbo_tool_selector_set_selected (TboToolSelector *self, Frame *frame)
850 self->selected_frame = frame;
851 empty_tool_area (self);
852 if (self->selected_frame != NULL)
853 update_tool_area (self);
854 update_menubar (TBO_TOOL_BASE (self)->tbo);
858 tbo_tool_selector_set_selected_obj (TboToolSelector *self, TboObjectBase *obj)
860 if (!obj && TBO_IS_OBJECT_GROUP (self->selected_object))
862 TboDrawing *drawing = TBO_DRAWING (TBO_TOOL_BASE (self)->tbo->drawing);
863 Frame *frame = tbo_drawing_get_current_frame (drawing);
864 tbo_frame_del_obj (frame, self->selected_object);
866 self->selected_object = obj;
867 update_menubar (TBO_TOOL_BASE (self)->tbo);