1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program 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
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #include "interface.h"
37 #include "handle_ops.h"
38 #include "connectionpoint_ops.h"
40 #include "cut_n_paste.h"
42 #include "preferences.h"
43 #include "app_procs.h"
44 #include "layer_dialog.h"
45 #include "load_save.h"
46 #include "dia-props.h"
48 #ifdef THIS_IS_PROBABLY_DEAD_CODE
49 #include "pixmaps/snap-to-grid.xpm"
50 #include "pixmaps/snap-to-grid-mask.xpm"
53 static GHashTable
*display_ht
= NULL
;
54 static GdkCursor
*current_cursor
= NULL
;
56 GdkCursor
*default_cursor
= NULL
;
58 static DDisplay
*active_display
= NULL
;
61 typedef struct _IRectangle
{
66 static guint
display_hash(DDisplay
*ddisp
);
68 static GtkPixmap
*snapping
;
69 #ifdef THIS_IS_PROBABLY_DEAD_CODE
70 static GtkPixmap
*not_snapping
;
74 snap_status_load_images(GdkWindow
*window
)
76 #ifdef THIS_IS_PROBABLY_DEAD_CODE
78 GdkBitmap
*mask
= NULL
;
80 dpix = gdk_pixmap_create_from_xpm_d(window, &mask, NULL, snap_to_grid_xpm);
81 g_assert(dpix != NULL);
83 snapping = gtk_pixmap_new(dpix, mask);
84 g_assert(snapping != NULL);
86 gdk_pixmap_unref(dpix);
87 gdk_pixmap_unref(mask);
89 dpix = gdk_pixmap_create_from_data(window, data, width, height);
90 mask = gdk_pixmap_create_from_data(window, mask, width, height);
91 g_assert(dpix != NULL && mask != NULL);
93 snapping = gdk_image_new(dpix, mask);
94 g_assert(snapping != NULL);
96 gdk_pixmap_unref(dpix);
97 gdk_pixmap_unref(mask);
104 update_snap_status(DDisplay
*ddisp
)
106 #ifdef THIS_IS_PROBABLY_DEAD_CODE
107 GtkButton
*zoomimage
= GTK_BUTTON(ddisp
->snap_status
);
109 if (ddisp
->grid
.snap
) {
117 update_zoom_status(DDisplay
*ddisp
)
119 #ifndef WITHOUT_ZOOM_COMBO
123 zoomcombo
= GTK_COMBO(ddisp
->zoom_status
);
124 sprintf (zoom_text
, "%.1f%%",
125 ddisp
->zoom_factor
* 100.0 / DDISPLAY_NORMAL_ZOOM
);
126 gtk_entry_set_text(GTK_ENTRY(zoomcombo
->entry
), zoom_text
);
129 /* HB: if the combo above ever get's the focus, the window
130 * hotkeys won't work anymore; plus IHMO it clutters the UI
131 * and isn't the useful anyway ...
133 GtkStatusbar
*statusbar
;
137 statusbar
= GTK_STATUSBAR (ddisp
->zoom_status
);
138 context_id
= gtk_statusbar_get_context_id (statusbar
, "Zoom");
140 gtk_statusbar_pop (statusbar
, context_id
);
141 zoom_text
= g_malloc (sizeof (guchar
) * (strlen (_("Zoom")) + 1 + 8 + 1));
142 sprintf (zoom_text
, "%s % 7.1f%c", _("Zoom"),
143 ddisp
->zoom_factor
* 100.0 / DDISPLAY_NORMAL_ZOOM
, '%');
144 gtk_statusbar_push (statusbar
, context_id
, zoom_text
);
151 update_modified_status(DDisplay
*ddisp
)
153 GtkStatusbar
*statusbar
;
156 if (ddisp
->diagram
->modified
)
158 statusbar
= GTK_STATUSBAR (ddisp
->modified_status
);
159 context_id
= gtk_statusbar_get_context_id (statusbar
, "Changed");
161 gtk_statusbar_pop (statusbar
, context_id
);
162 gtk_statusbar_push (statusbar
, context_id
, _("Diagram modified!"));
166 statusbar
= GTK_STATUSBAR (ddisp
->modified_status
);
167 context_id
= gtk_statusbar_get_context_id (statusbar
, "Changed");
169 gtk_statusbar_pop (statusbar
, context_id
);
174 new_display(Diagram
*dia
)
178 int embedded
= app_is_embedded();
181 ddisp
= g_new0(DDisplay
,1);
183 ddisp
->menu_bar
= NULL
;
184 ddisp
->mbar_item_factory
= NULL
;
186 ddisp
->rulers
= NULL
;
187 ddisp
->visible_grid
= NULL
;
188 ddisp
->snap_to_grid
= NULL
;
189 ddisp
->show_cx_pts_mitem
= NULL
;
191 ddisp
->antialiased
= NULL
;
193 /* initialize the whole struct to 0 so that we are sure to catch errors.*/
194 memset (&ddisp
->updatable_menu_items
, 0, sizeof (UpdatableMenuItems
));
196 ddisp
->diagram
= dia
;
198 ddisp
->grid
.visible
= prefs
.grid
.visible
;
199 ddisp
->grid
.snap
= prefs
.grid
.snap
;
201 ddisp
->show_cx_pts
= prefs
.show_cx_pts
;
203 ddisp
->autoscroll
= TRUE
;
205 ddisp
->aa_renderer
= 0;
206 ddisp
->renderer
= (Renderer
*)new_gdk_renderer(ddisp
);
208 ddisp
->update_areas
= NULL
;
209 ddisp
->display_areas
= NULL
;
210 ddisp
->update_id
= 0;
212 filename
= strrchr(dia
->filename
, G_DIR_SEPARATOR
);
213 if (filename
==NULL
) {
214 filename
= dia
->filename
;
219 diagram_add_ddisplay(dia
, ddisp
);
221 ddisp
->origo
.x
= 0.0;
222 ddisp
->origo
.y
= 0.0;
223 ddisp
->zoom_factor
= prefs
.new_view
.zoom
/100.0*DDISPLAY_NORMAL_ZOOM
;
224 if ((ddisp
->diagram
) && (ddisp
->diagram
->data
)) {
225 Rectangle
*extents
= &ddisp
->diagram
->data
->extents
;
227 visible
.left
= extents
->left
;
228 visible
.top
= extents
->top
;
233 visible
.right
= visible
.left
+ prefs
.new_view
.width
/ddisp
->zoom_factor
;
234 visible
.bottom
= visible
.top
+ prefs
.new_view
.height
/ddisp
->zoom_factor
;
236 ddisp
->visible
= visible
;
238 create_display_shell(ddisp
, prefs
.new_view
.width
, prefs
.new_view
.height
,
239 filename
, prefs
.new_view
.use_menu_bar
, !embedded
);
242 ddisplay_update_statusbar (ddisp
);
244 ddisplay_set_origo(ddisp
, visible
.left
, visible
.top
);
245 ddisp
->visible
= visible
; /* force the visible area extents */
246 ddisplay_update_scrollbars(ddisp
);
247 ddisplay_add_update_all(ddisp
);
250 display_ht
= g_hash_table_new ((GHashFunc
) display_hash
, NULL
);
253 ddisplay_set_cursor(ddisp
, current_cursor
);
255 g_hash_table_insert (display_ht
, ddisp
->shell
, ddisp
);
256 g_hash_table_insert (display_ht
, ddisp
->canvas
, ddisp
);
259 return ddisp
; /* set the user data */
263 display_hash(DDisplay
*ddisp
)
265 return (gulong
) ddisp
;
269 ddisplay_transform_coords_double(DDisplay
*ddisp
,
271 double *xi
, double *yi
)
273 Rectangle
*visible
= &ddisp
->visible
;
274 double width
= ddisp
->renderer
->pixel_width
;
275 double height
= ddisp
->renderer
->pixel_height
;
277 *xi
= (x
- visible
->left
) * (real
)width
/ (visible
->right
- visible
->left
);
278 *yi
= (y
- visible
->top
) * (real
)height
/ (visible
->bottom
- visible
->top
);
283 ddisplay_transform_coords(DDisplay
*ddisp
,
287 Rectangle
*visible
= &ddisp
->visible
;
288 int width
= ddisp
->renderer
->pixel_width
;
289 int height
= ddisp
->renderer
->pixel_height
;
291 *xi
= ROUND ( (x
- visible
->left
) * (real
)width
/
292 (visible
->right
- visible
->left
) );
293 *yi
= ROUND ( (y
- visible
->top
) * (real
)height
/
294 (visible
->bottom
- visible
->top
) );
297 /* Takes real length and returns pixel length */
299 ddisplay_transform_length(DDisplay
*ddisp
, real len
)
301 return len
* ddisp
->zoom_factor
;
304 /* Takes pixel length and returns real length */
306 ddisplay_untransform_length(DDisplay
*ddisp
, real len
)
308 return len
/ ddisp
->zoom_factor
;
313 ddisplay_untransform_coords(DDisplay
*ddisp
,
317 Rectangle
*visible
= &ddisp
->visible
;
318 int width
= ddisp
->renderer
->pixel_width
;
319 int height
= ddisp
->renderer
->pixel_height
;
321 *x
= visible
->left
+ xi
*(visible
->right
- visible
->left
) / (real
)width
;
322 *y
= visible
->top
+ yi
*(visible
->bottom
- visible
->top
) / (real
)height
;
327 ddisplay_add_update_pixels(DDisplay
*ddisp
, Point
*point
,
328 int pixel_width
, int pixel_height
)
333 size_x
= ddisplay_untransform_length(ddisp
, pixel_width
+1);
334 size_y
= ddisplay_untransform_length(ddisp
, pixel_height
+1);
336 rect
.left
= point
->x
- size_x
/2.0;
337 rect
.top
= point
->y
- size_y
/2.0;
338 rect
.right
= point
->x
+ size_x
/2.0;
339 rect
.bottom
= point
->y
+ size_y
/2.0;
341 ddisplay_add_update(ddisp
, &rect
);
345 ddisplay_add_update_all(DDisplay
*ddisp
)
347 ddisplay_add_update(ddisp
, &ddisp
->visible
);
351 ddisplay_add_update(DDisplay
*ddisp
, Rectangle
*rect
)
354 int top
,bottom
,left
,right
;
356 int width
= ddisp
->renderer
->pixel_width
;
357 int height
= ddisp
->renderer
->pixel_height
;
359 if (!rectangle_intersects(rect
, &ddisp
->visible
))
362 /* Temporarily just do a union of all rectangles: */
363 if (ddisp
->update_areas
==NULL
) {
364 r
= g_new(Rectangle
,1);
366 rectangle_intersection(r
, &ddisp
->visible
);
367 ddisp
->update_areas
= g_slist_prepend(ddisp
->update_areas
, r
);
369 r
= (Rectangle
*) ddisp
->update_areas
->data
;
370 rectangle_union(r
, rect
);
371 rectangle_intersection(r
, &ddisp
->visible
);
374 visible
= &ddisp
->visible
;
375 left
= floor( (r
->left
- visible
->left
) * (real
)width
/
376 (visible
->right
- visible
->left
) ) - 1;
377 top
= floor( (r
->top
- visible
->top
) * (real
)height
/
378 (visible
->bottom
- visible
->top
) ) - 1;
379 right
= ceil( (r
->right
- visible
->left
) * (real
)width
/
380 (visible
->right
- visible
->left
) ) + 1;
381 bottom
= ceil( (r
->bottom
- visible
->top
) * (real
)height
/
382 (visible
->bottom
- visible
->top
) ) + 1;
384 ddisplay_add_display_area(ddisp
,
390 ddisplay_add_display_area(DDisplay
*ddisp
,
392 int right
, int bottom
)
400 if (right
> ddisp
->renderer
->pixel_width
)
401 right
= ddisp
->renderer
->pixel_width
;
402 if (bottom
> ddisp
->renderer
->pixel_height
)
403 bottom
= ddisp
->renderer
->pixel_height
;
405 /* draw some rectangles to show where updates are...*/
406 /* gdk_draw_rectangle(ddisp->canvas->window, ddisp->canvas->style->black_gc, TRUE, left, top, right-left,bottom-top); */
408 /* Temporarily just do a union of all Irectangles: */
409 if (ddisp
->display_areas
==NULL
) {
410 r
= g_new(IRectangle
,1);
411 r
->top
= top
; r
->bottom
= bottom
;
412 r
->left
= left
; r
->right
= right
;
413 ddisp
->display_areas
= g_slist_prepend(ddisp
->display_areas
, r
);
415 r
= (IRectangle
*) ddisp
->display_areas
->data
;
417 r
->top
= MIN( r
->top
, top
);
418 r
->bottom
= MAX( r
->bottom
, bottom
);
419 r
->left
= MIN( r
->left
, left
);
420 r
->right
= MAX( r
->right
, right
);
425 ddisplay_update_handler(DDisplay
*ddisp
)
429 Rectangle
*r
, totrect
;
432 /* Renders updates to pixmap + copies display_areas to canvas(screen) */
434 renderer
= ddisp
->renderer
;
436 (renderer
->interactive_ops
->clip_region_clear
)(renderer
);
438 l
= ddisp
->update_areas
;
440 totrect
= ddisp
->visible
;
442 totrect
= *(Rectangle
*) l
->data
;
445 r
= (Rectangle
*) l
->data
;
447 rectangle_union(&totrect
, r
);
448 (renderer
->interactive_ops
->clip_region_add_rect
)(renderer
, r
);
453 /* Free update_areas list: */
454 l
= ddisp
->update_areas
;
459 g_slist_free(ddisp
->update_areas
);
460 ddisp
->update_areas
= NULL
;
463 totrect
.right
+= 0.1;
465 totrect
.bottom
+= 0.1;
467 ddisplay_render_pixmap(ddisp
, &totrect
);
469 l
= ddisp
->display_areas
;
471 ir
= (IRectangle
*) l
->data
;
473 if (ddisp
->aa_renderer
)
474 renderer_libart_copy_to_window((RendererLibart
*)ddisp
->renderer
, ddisp
->canvas
->window
,
476 ir
->right
- ir
->left
, ir
->bottom
- ir
->top
);
478 renderer_gdk_copy_to_window((RendererGdk
*)ddisp
->renderer
, ddisp
->canvas
->window
,
480 ir
->right
- ir
->left
, ir
->bottom
- ir
->top
);
485 /* Free display_areas list */
486 l
= ddisp
->display_areas
;
491 g_slist_free(ddisp
->display_areas
);
492 ddisp
->display_areas
= NULL
;
494 ddisp
->update_id
= 0;
499 ddisplay_flush(DDisplay
*ddisp
)
501 /* if no update is queued, queue update */
502 if (!ddisp
->update_id
)
503 ddisp
->update_id
= gtk_idle_add((GtkFunction
) ddisplay_update_handler
,
508 ddisplay_obj_render(Object
*obj
, Renderer
*renderer
,
512 DDisplay
*ddisp
= (DDisplay
*)data
;
515 obj
->ops
->draw(obj
, renderer
);
516 if (active_layer
&& ddisp
->show_cx_pts
) {
517 for (i
=0;i
<obj
->num_connections
;i
++) {
518 connectionpoint_draw(obj
->connections
[i
], ddisp
);
524 ddisplay_render_pixmap(DDisplay
*ddisp
, Rectangle
*update
)
531 if (ddisp
->renderer
==NULL
) {
532 printf("ERROR! Renderer was NULL!!\n");
536 renderer
= ddisp
->renderer
;
538 /* Erase background */
539 (renderer
->interactive_ops
->fill_pixel_rect
)(renderer
,
541 renderer
->pixel_width
-1,
542 renderer
->pixel_height
-1,
543 &ddisp
->diagram
->data
->bg_color
);
546 grid_draw(ddisp
, update
);
548 data_render(ddisp
->diagram
->data
, (Renderer
*)ddisp
->renderer
, update
,
549 ddisplay_obj_render
, (gpointer
) ddisp
);
551 /* Draw handles for all selected objects */
552 list
= ddisp
->diagram
->data
->selected
;
554 obj
= (Object
*) list
->data
;
556 for (i
=0;i
<obj
->num_handles
;i
++) {
557 handle_draw(obj
->handles
[i
], ddisp
);
559 list
= g_list_next(list
);
564 ddisplay_update_scrollbars(DDisplay
*ddisp
)
566 Rectangle
*extents
= &ddisp
->diagram
->data
->extents
;
567 Rectangle
*visible
= &ddisp
->visible
;
568 GtkAdjustment
*hsbdata
, *vsbdata
;
570 hsbdata
= ddisp
->hsbdata
;
572 hsbdata
->lower
= MIN(extents
->left
, visible
->left
);
573 hsbdata
->upper
= MAX(extents
->right
, visible
->right
);
574 hsbdata
->page_size
= visible
->right
- visible
->left
- 0.0001;
575 /* remove some to fix strange behaviour in gtk_range_adjustment_changed */
576 hsbdata
->page_increment
= (visible
->right
- visible
->left
) / 2.0;
577 hsbdata
->step_increment
= (visible
->right
- visible
->left
) / 10.0;
578 hsbdata
->value
= visible
->left
;
580 gtk_signal_emit_by_name (GTK_OBJECT (ddisp
->hsbdata
), "changed");
583 vsbdata
= ddisp
->vsbdata
;
584 vsbdata
->lower
= MIN(extents
->top
, visible
->top
);
585 vsbdata
->upper
= MAX(extents
->bottom
, visible
->bottom
);
586 vsbdata
->page_size
= visible
->bottom
- visible
->top
- 0.00001;
587 /* remove some to fix strange behaviour in gtk_range_adjustment_changed */
588 vsbdata
->page_increment
= (visible
->bottom
- visible
->top
) / 2.0;
589 vsbdata
->step_increment
= (visible
->bottom
- visible
->top
) / 10.0;
590 vsbdata
->value
= visible
->top
;
592 gtk_signal_emit_by_name (GTK_OBJECT (ddisp
->vsbdata
), "changed");
596 ddisplay_set_origo(DDisplay
*ddisp
, coord x
, coord y
)
598 Rectangle
*extents
= &ddisp
->diagram
->data
->extents
;
599 Rectangle
*visible
= &ddisp
->visible
;
602 /* updaterar origo+visible+rulers */
606 if (ddisp
->zoom_factor
<DDISPLAY_MIN_ZOOM
)
607 ddisp
->zoom_factor
= DDISPLAY_MIN_ZOOM
;
609 if (ddisp
->zoom_factor
> DDISPLAY_MAX_ZOOM
)
610 ddisp
->zoom_factor
= DDISPLAY_MAX_ZOOM
;
612 width
= ddisp
->renderer
->pixel_width
;
613 height
= ddisp
->renderer
->pixel_height
;
615 visible
->left
= ddisp
->origo
.x
;
616 visible
->top
= ddisp
->origo
.y
;
617 visible
->right
= ddisp
->origo
.x
+ width
/ddisp
->zoom_factor
;
618 visible
->bottom
= ddisp
->origo
.y
+ height
/ddisp
->zoom_factor
;
620 gtk_ruler_set_range (GTK_RULER (ddisp
->hrule
),
624 MAX(extents
->right
, visible
->right
)/* max_size*/);
625 gtk_ruler_set_range (GTK_RULER (ddisp
->vrule
),
629 MAX(extents
->bottom
, visible
->bottom
)/* max_size*/);
633 ddisplay_zoom(DDisplay
*ddisp
, Point
*point
, real magnify
)
638 visible
= &ddisp
->visible
;
640 width
= (visible
->right
- visible
->left
)/magnify
;
641 height
= (visible
->bottom
- visible
->top
)/magnify
;
643 if ((ddisp
->zoom_factor
<= DDISPLAY_MIN_ZOOM
) && (magnify
<=1.0))
645 if ((ddisp
->zoom_factor
>= DDISPLAY_MAX_ZOOM
) && (magnify
>=1.0))
648 ddisp
->zoom_factor
*= magnify
;
650 ddisplay_set_origo(ddisp
, point
->x
- width
/2.0, point
->y
- height
/2.0);
652 ddisplay_update_scrollbars(ddisp
);
653 ddisplay_add_update_all(ddisp
);
654 ddisplay_flush(ddisp
);
656 update_zoom_status (ddisp
);
660 ddisplay_autoscroll(DDisplay
*ddisp
, int x
, int y
)
662 guint16 width
, height
;
665 if (! ddisp
->autoscroll
)
668 scroll
.x
= scroll
.y
= 0;
670 width
= GTK_WIDGET(ddisp
->canvas
)->allocation
.width
;
671 height
= GTK_WIDGET(ddisp
->canvas
)->allocation
.height
;
679 scroll
.x
= x
- width
;
688 scroll
.y
= y
- height
;
691 if ((scroll
.x
!= 0) || (scroll
.y
!= 0))
695 scroll
.x
= ddisplay_untransform_length(ddisp
, scroll
.x
);
696 scroll
.y
= ddisplay_untransform_length(ddisp
, scroll
.y
);
698 scrolled
= ddisplay_scroll(ddisp
, &scroll
);
701 ddisplay_flush(ddisp
);
709 ddisplay_scroll(DDisplay
*ddisp
, Point
*delta
)
711 Rectangle
*visible
= &ddisp
->visible
;
712 real width
= visible
->right
- visible
->left
;
713 real height
= visible
->bottom
- visible
->top
;
715 Rectangle extents
= ddisp
->diagram
->data
->extents
;
716 real ex_width
= extents
.right
- extents
.left
;
717 real ex_height
= extents
.bottom
- extents
.top
;
719 Point new_origo
= ddisp
->origo
;
720 point_add(&new_origo
, delta
);
722 rectangle_union(&extents
, visible
);
724 if (new_origo
.x
< extents
.left
- ex_width
)
725 new_origo
.x
= extents
.left
- ex_width
;
727 if (new_origo
.x
+width
> extents
.right
+ ex_width
)
728 new_origo
.x
= extents
.right
- width
+ ex_width
;
730 if (new_origo
.y
< extents
.top
- ex_height
)
731 new_origo
.y
= extents
.top
- ex_height
;
733 if (new_origo
.y
+height
> extents
.bottom
+ ex_height
)
734 new_origo
.y
= extents
.bottom
- height
+ ex_height
;
736 if ( (new_origo
.x
!= ddisp
->origo
.x
) ||
737 (new_origo
.y
!= ddisp
->origo
.y
) ) {
738 ddisplay_set_origo(ddisp
, new_origo
.x
, new_origo
.y
);
739 ddisplay_update_scrollbars(ddisp
);
740 ddisplay_add_update_all(ddisp
);
746 void ddisplay_scroll_up(DDisplay
*ddisp
)
751 delta
.y
= -(ddisp
->visible
.bottom
- ddisp
->visible
.top
)/4.0;
753 ddisplay_scroll(ddisp
, &delta
);
756 void ddisplay_scroll_down(DDisplay
*ddisp
)
761 delta
.y
= (ddisp
->visible
.bottom
- ddisp
->visible
.top
)/4.0;
763 ddisplay_scroll(ddisp
, &delta
);
766 void ddisplay_scroll_left(DDisplay
*ddisp
)
770 delta
.x
= -(ddisp
->visible
.right
- ddisp
->visible
.left
)/4.0;
773 ddisplay_scroll(ddisp
, &delta
);
776 void ddisplay_scroll_right(DDisplay
*ddisp
)
780 delta
.x
= (ddisp
->visible
.right
- ddisp
->visible
.left
)/4.0;
783 ddisplay_scroll(ddisp
, &delta
);
787 ddisplay_set_renderer(DDisplay
*ddisp
, int aa_renderer
)
791 if (ddisp
->aa_renderer
) {
793 destroy_libart_renderer((RendererLibart
*)ddisp
->renderer
);
796 destroy_gdk_renderer((RendererGdk
*)ddisp
->renderer
);
799 ddisp
->aa_renderer
= aa_renderer
;
801 width
= ddisp
->canvas
->allocation
.width
;
802 height
= ddisp
->canvas
->allocation
.height
;
804 if (ddisp
->aa_renderer
){
805 ddisp
->renderer
= (Renderer
*)new_libart_renderer(ddisp
, 1);
806 libart_renderer_set_size((RendererLibart
*)ddisp
->renderer
, ddisp
->canvas
->window
, width
, height
);
808 ddisp
->renderer
= (Renderer
*)new_gdk_renderer(ddisp
);
809 gdk_renderer_set_size((RendererGdk
*)ddisp
->renderer
, ddisp
->canvas
->window
, width
, height
);
814 ddisplay_resize_canvas(DDisplay
*ddisp
,
815 int width
, int height
)
817 if (ddisp
->renderer
==NULL
) {
818 if (ddisp
->aa_renderer
)
819 ddisp
->renderer
= (Renderer
*)new_libart_renderer(ddisp
, 1);
821 ddisp
->renderer
= (Renderer
*)new_gdk_renderer(ddisp
);
824 if (ddisp
->aa_renderer
)
825 libart_renderer_set_size((RendererLibart
*)ddisp
->renderer
, ddisp
->canvas
->window
, width
, height
);
827 gdk_renderer_set_size((RendererGdk
*)ddisp
->renderer
, ddisp
->canvas
->window
, width
, height
);
829 ddisplay_set_origo(ddisp
, ddisp
->origo
.x
, ddisp
->origo
.y
);
831 ddisplay_add_update(ddisp
, &ddisp
->visible
);
832 ddisplay_flush(ddisp
);
836 ddisplay_active(void)
838 return active_display
;
842 ddisplay_active_diagram(void)
844 DDisplay
*ddisp
= ddisplay_active ();
846 if (!ddisp
) return NULL
;
847 return ddisp
->diagram
;
851 ddisp_destroy(DDisplay
*ddisp
)
853 if (ddisp
->update_id
) {
854 gtk_idle_remove(ddisp
->update_id
);
855 ddisp
->update_id
= 0;
857 gtk_widget_destroy (ddisp
->shell
);
861 are_you_sure_close_dialog_cancel(GtkWidget
*widget
, GtkWidget
*dialog
)
863 gtk_widget_destroy(dialog
);
867 are_you_sure_close_dialog_yes(GtkWidget
*widget
,
872 ddisp
= gtk_object_get_user_data(GTK_OBJECT(dialog
));
875 diagram_save(ddisp
->diagram
, ddisp
->diagram
->filename
);
877 if (ddisp
->update_id
) {
878 gtk_idle_remove(ddisp
->update_id
);
879 ddisp
->update_id
= 0;
882 gtk_widget_destroy(dialog
);
883 ddisp_destroy (ddisp
);
887 are_you_sure_close_dialog_no(GtkWidget
*widget
,
892 ddisp
= gtk_object_get_user_data(GTK_OBJECT(dialog
));
894 gtk_widget_destroy(dialog
);
895 ddisp_destroy(ddisp
);
899 ddisplay_close(DDisplay
*ddisp
)
902 GtkWidget
*dialog
, *vbox
;
907 dia
= ddisp
->diagram
;
909 if ( (dia
->display_count
> 1) ||
911 ddisp_destroy(ddisp
);
916 dialog
= gnome_dialog_new(_("Close Diagram?"),
917 GNOME_STOCK_BUTTON_YES
,GNOME_STOCK_BUTTON_NO
,NULL
);
918 gnome_dialog_set_default(GNOME_DIALOG(dialog
), 0);
919 vbox
= GNOME_DIALOG(dialog
)->vbox
;
921 dialog
= gtk_dialog_new();
922 gtk_window_set_title (GTK_WINDOW (dialog
), _("Really close?"));
923 gtk_container_set_border_width (GTK_CONTAINER (dialog
), 0);
924 vbox
= GTK_DIALOG(dialog
)->vbox
;
927 label
= gtk_label_new (_("This diagram has not been saved.\n"
928 "Save changes now?"));
930 gtk_misc_set_padding (GTK_MISC (label
), 10, 10);
931 gtk_box_pack_start (GTK_BOX (vbox
), label
, TRUE
, TRUE
, 0);
933 gtk_widget_show (label
);
935 gtk_object_set_user_data(GTK_OBJECT(dialog
), ddisp
);
938 gnome_dialog_button_connect(GNOME_DIALOG(dialog
), 0,
939 GTK_SIGNAL_FUNC(are_you_sure_close_dialog_yes
),
941 gnome_dialog_button_connect(GNOME_DIALOG(dialog
), 1,
942 GTK_SIGNAL_FUNC(are_you_sure_close_dialog_no
),
945 button
= gtk_button_new_with_label (_("Yes"));
946 GTK_WIDGET_SET_FLAGS (button
, GTK_CAN_DEFAULT
);
947 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog
)->action_area
),
948 button
, TRUE
, TRUE
, 0);
949 gtk_widget_grab_default (button
);
950 gtk_signal_connect (GTK_OBJECT (button
), "clicked",
951 GTK_SIGNAL_FUNC(are_you_sure_close_dialog_yes
),
953 gtk_widget_show (button
);
955 button
= gtk_button_new_with_label (_("No"));
956 GTK_WIDGET_SET_FLAGS (button
, GTK_CAN_DEFAULT
);
957 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog
)->action_area
),
958 button
, TRUE
, TRUE
, 0);
960 gtk_signal_connect (GTK_OBJECT (button
), "clicked",
961 GTK_SIGNAL_FUNC(are_you_sure_close_dialog_no
),
964 gtk_widget_show (button
);
966 button
= gtk_button_new_with_label (_("Cancel"));
967 GTK_WIDGET_SET_FLAGS (button
, GTK_CAN_DEFAULT
);
968 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog
)->action_area
),
969 button
, TRUE
, TRUE
, 0);
971 gtk_signal_connect (GTK_OBJECT (button
), "clicked",
972 GTK_SIGNAL_FUNC(are_you_sure_close_dialog_cancel
),
975 gtk_widget_show (button
);
978 /* Make dialog modal: */
979 gtk_window_set_modal(GTK_WINDOW(dialog
), TRUE
);
981 gtk_widget_show(dialog
);
985 display_update_menu_state(DDisplay
*ddisp
)
987 static gboolean initialized
= 0;
989 static GtkWidget
*rulers
;
990 static GtkWidget
*visible_grid
;
991 static GtkWidget
*snap_to_grid
;
992 static GtkWidget
*show_cx_pts
;
994 static GtkWidget
*antialiased
;
997 if ((!initialized
) && (ddisp
->menu_bar
== NULL
)) {
998 rulers
= menus_get_item_from_path("<Display>/View/Show Rulers", NULL
);
999 visible_grid
= menus_get_item_from_path("<Display>/View/Visible Grid", NULL
);
1000 snap_to_grid
= menus_get_item_from_path("<Display>/View/Snap To Grid", NULL
);
1002 menus_get_item_from_path("<Display>/View/Show Connection Points", NULL
);
1004 antialiased
= menus_get_item_from_path("<Display>/View/AntiAliased", NULL
);
1009 ddisplay_do_update_menu_sensitivity (ddisp
);
1011 if (ddisp
->menu_bar
) {
1012 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ddisp
->rulers
),
1013 GTK_WIDGET_VISIBLE (ddisp
->hrule
) ? 1 : 0);
1014 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ddisp
->visible_grid
),
1015 ddisp
->grid
.visible
);
1016 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ddisp
->snap_to_grid
),
1018 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ddisp
->show_cx_pts_mitem
),
1019 ddisp
->show_cx_pts
);
1021 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ddisp
->antialiased
),
1022 ddisp
->aa_renderer
);
1026 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(rulers
),
1027 GTK_WIDGET_VISIBLE (ddisp
->hrule
) ? 1 : 0);
1028 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(visible_grid
),
1029 ddisp
->grid
.visible
);
1030 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(snap_to_grid
),
1032 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(show_cx_pts
),
1033 ddisp
->show_cx_pts
);
1035 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(antialiased
),
1036 ddisp
->aa_renderer
);
1042 ddisplay_do_update_menu_sensitivity (DDisplay
*ddisp
)
1046 dia
= ddisp
->diagram
;
1047 if (ddisp
->menu_bar
) {
1048 diagram_update_menubar_sensitivity(dia
, &ddisp
->updatable_menu_items
);
1051 diagram_update_popupmenu_sensitivity(dia
);
1057 /* This is called when ddisp->shell is destroyed... */
1059 ddisplay_really_destroy(DDisplay
*ddisp
)
1064 if (active_display
== ddisp
)
1065 display_set_active(NULL
);
1067 dia
= ddisp
->diagram
;
1069 diagram_remove_ddisplay(dia
, ddisp
);
1071 if (ddisp
->aa_renderer
)
1072 destroy_libart_renderer((RendererLibart
*)ddisp
->renderer
);
1074 destroy_gdk_renderer((RendererGdk
*)ddisp
->renderer
);
1076 ddisp
->renderer
= NULL
;
1078 g_hash_table_remove(display_ht
, ddisp
->shell
);
1079 g_hash_table_remove(display_ht
, ddisp
->canvas
);
1081 /* Free update_areas list: */
1082 l
= ddisp
->update_areas
;
1085 l
= g_slist_next(l
);
1087 g_slist_free(ddisp
->update_areas
);
1088 /* Free display_areas list */
1089 l
= ddisp
->display_areas
;
1092 l
= g_slist_next(l
);
1094 g_slist_free(ddisp
->display_areas
);
1102 ddisplay_set_title(DDisplay
*ddisp
, char *title
)
1104 gtk_window_set_title (GTK_WINDOW (ddisp
->shell
), title
);
1108 ddisplay_set_all_cursor(GdkCursor
*cursor
)
1115 current_cursor
= cursor
;
1117 list
= open_diagrams
;
1118 while (list
!= NULL
) {
1119 dia
= (Diagram
*) list
->data
;
1121 slist
= dia
->displays
;
1122 while (slist
!= NULL
) {
1123 ddisp
= (DDisplay
*) slist
->data
;
1125 ddisplay_set_cursor(ddisp
, cursor
);
1127 slist
= g_slist_next(slist
);
1130 list
= g_list_next(list
);
1135 ddisplay_set_cursor(DDisplay
*ddisp
, GdkCursor
*cursor
)
1137 gdk_window_set_cursor(ddisp
->canvas
->window
, cursor
);
1141 ddisplay_update_statusbar(DDisplay
*ddisp
)
1143 /* update_snap_status (ddisp);*/
1144 update_zoom_status (ddisp
);
1145 update_modified_status (ddisp
);
1149 display_set_active(DDisplay
*ddisp
)
1151 if (ddisp
!= active_display
) {
1152 active_display
= ddisp
;
1154 /* perform notification here (such as switch layers dialog) */
1155 layer_dialog_set_diagram(ddisp
? ddisp
->diagram
: NULL
);
1156 diagram_properties_set_diagram(ddisp
? ddisp
->diagram
: NULL
);
1159 display_update_menu_state(ddisp
);