1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2007 Ales Hvezda
4 * Copyright (C) 1998-2007 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
33 #include <libgeda/libgeda.h>
35 #include "../include/globals.h"
36 #include "../include/prototype.h"
38 #ifdef HAVE_LIBDMALLOC
42 #include "../include/x_preview.h"
45 extern int mouse_x
, mouse_y
;
53 static GObjectClass
*preview_parent_class
= NULL
;
56 static void preview_class_init (PreviewClass
*class);
57 static void preview_init (Preview
*preview
);
58 static void preview_set_property (GObject
*object
,
62 static void preview_get_property (GObject
*object
,
66 static void preview_dispose (GObject
*self
);
69 /*! \brief Completes initialitation of the widget after realization.
70 * \par Function Description
71 * This function terminates the initialization of preview's toplevel
72 * environment after the widget has been realized.
74 * It creates a preview page in the toplevel environment.
76 * \param [in] widget The preview widget.
77 * \param [in] user_data Unused user data.
80 preview_callback_realize (GtkWidget
*widget
,
83 Preview
*preview
= PREVIEW (widget
);
84 TOPLEVEL
*preview_toplevel
= preview
->preview_toplevel
;
87 preview_toplevel
->window
= preview_toplevel
->drawing_area
->window
;
88 gtk_widget_grab_focus (preview_toplevel
->drawing_area
);
90 preview_toplevel
->backingstore
= gdk_pixmap_new (
91 preview_toplevel
->window
,
92 preview_toplevel
->drawing_area
->allocation
.width
,
93 preview_toplevel
->drawing_area
->allocation
.height
, -1);
95 x_window_setup_gc (preview_toplevel
);
97 preview_page
= s_page_new (preview_toplevel
, "unknown");
98 s_page_goto (preview_toplevel
, preview_page
);
100 i_vars_set (preview_toplevel
);
102 /* be sure to turn off the grid */
103 preview_toplevel
->grid
= FALSE
;
105 /* preview_toplevel windows don't have toolbars */
106 preview_toplevel
->handleboxes
= FALSE
;
107 preview_toplevel
->toolbars
= FALSE
;
109 x_repaint_background(preview_toplevel
);
111 preview_toplevel
->DONT_RECALC
= 0;
112 preview_toplevel
->DONT_RESIZE
= 0;
113 preview_toplevel
->DONT_REDRAW
= 0;
115 a_zoom_extents(preview_toplevel
,
116 preview_page
->object_head
,
119 o_redraw_all(preview_toplevel
);
123 /*! \brief Redraws the view when widget is exposed.
124 * \par Function Description
125 * It redraws the preview pixmap every time the widget is exposed.
127 * \param [in] widget The preview widget.
128 * \param [in] event The event structure.
129 * \param [in] user_data Unused user data.
130 * \returns FALSE to propagate the event further.
133 preview_callback_expose (GtkWidget
*widget
,
134 GdkEventExpose
*event
,
137 Preview
*preview
= PREVIEW (widget
);
138 TOPLEVEL
*preview_toplevel
= preview
->preview_toplevel
;
140 gdk_draw_pixmap(widget
->window
,
141 widget
->style
->fg_gc
[GTK_WIDGET_STATE (widget
)],
142 preview_toplevel
->backingstore
,
143 event
->area
.x
, event
->area
.y
,
144 event
->area
.x
, event
->area
.y
,
145 event
->area
.width
, event
->area
.height
);
150 /*! \brief Handles the press on a mouse button.
151 * \par Function Description
152 * It handles the user inputs.
154 * Three action are available: zoom in, pan and zoom out on preview display.
156 * \param [in] widget The preview widget.
157 * \param [in] event The event structure.
158 * \param [in] user_data Unused user data.
159 * \returns FALSE to propagate the event further.
162 preview_callback_button_press (GtkWidget
*widget
,
163 GdkEventButton
*event
,
166 Preview
*preview
= PREVIEW (widget
);
167 TOPLEVEL
*preview_toplevel
= preview
->preview_toplevel
;
169 if (!preview
->active
|| preview
->filename
== NULL
) {
173 switch (event
->button
) {
174 case 1: /* left mouse button: zoom in */
175 a_zoom (preview_toplevel
, ZOOM_IN
, HOTKEY
, 0);
176 o_redraw_all_fast (preview_toplevel
);
178 case 2: /* middle mouse button: pan */
179 a_pan (preview_toplevel
, mouse_x
, mouse_y
);
181 case 3: /* right mouse button: zoom out */
182 a_zoom (preview_toplevel
, ZOOM_OUT
, HOTKEY
, 0);
183 o_redraw_all_fast (preview_toplevel
);
190 /*! \brief Handles the displacement of the pointer.
191 * \par Function Description
192 * This function temporary saves the position of the mouse pointer
193 * over the preview widget.
195 * This position can be later used when the user press a button of
196 * the mouse (see <B>preview_callback_button_press()</B>).
198 * \param [in] widget The preview widget.
199 * \param [in] event The event structure.
200 * \param [in] user_data Unused user data.
201 * \returns FALSE to propagate the event further.
204 preview_callback_motion_notify (GtkWidget
*widget
,
205 GdkEventMotion
*event
,
208 Preview
*preview
= PREVIEW (widget
);
210 if (!preview
->active
|| preview
->filename
== NULL
) {
214 mouse_x
= (int)event
->x
;
215 mouse_y
= (int)event
->y
;
220 /*! \brief Updates the preview widget.
221 * \par Function Description
222 * This function update the preview: if the preview is active and a
223 * filename has been given, it opens the file and display
224 * it. Otherwise it display a blank page.
226 * \param [in] preview The preview widget.
229 preview_update (Preview
*preview
)
231 TOPLEVEL
*preview_toplevel
= preview
->preview_toplevel
;
233 if (preview_toplevel
->page_current
== NULL
) {
237 /* delete old preview, create new page */
238 /* it would be better to just resets current page - Fix me */
239 s_page_delete (preview_toplevel
, preview_toplevel
->page_current
);
240 s_page_goto (preview_toplevel
, s_page_new (preview_toplevel
, "preview"));
242 if (preview
->active
&& preview
->filename
!= NULL
) {
243 /* open up file in current page */
244 f_open (preview_toplevel
, preview
->filename
);
245 /* test value returned by f_open... - Fix me */
246 /* we should display something if there an error occured - Fix me */
249 /* display current page (possibly empty) */
250 a_zoom_extents (preview_toplevel
,
251 preview_toplevel
->page_current
->object_head
,
253 o_redraw_all (preview_toplevel
);
260 static GType preview_type
= 0;
263 static const GTypeInfo preview_info
= {
264 sizeof(PreviewClass
),
265 NULL
, /* base_init */
266 NULL
, /* base_finalize */
267 (GClassInitFunc
) preview_class_init
,
268 NULL
, /* class_finalize */
269 NULL
, /* class_data */
272 (GInstanceInitFunc
) preview_init
,
275 preview_type
= g_type_register_static (GTK_TYPE_DRAWING_AREA
,
284 preview_class_init (PreviewClass
*klass
)
286 GObjectClass
*gobject_class
= G_OBJECT_CLASS (klass
);
288 preview_parent_class
= g_type_class_peek_parent (klass
);
290 gobject_class
->set_property
= preview_set_property
;
291 gobject_class
->get_property
= preview_get_property
;
292 gobject_class
->dispose
= preview_dispose
;
294 g_object_class_install_property (
295 gobject_class
, PROP_FILENAME
,
296 g_param_spec_string ("filename",
301 g_object_class_install_property(
302 gobject_class
, PROP_ACTIVE
,
303 g_param_spec_boolean ("active",
313 preview_init (Preview
*preview
)
316 gchar
*detailed_signal
;
318 } drawing_area_events
[] = {
319 { "realize", G_CALLBACK (preview_callback_realize
) },
320 { "expose_event", G_CALLBACK (preview_callback_expose
) },
321 { "button_press_event", G_CALLBACK (preview_callback_button_press
) },
322 { "motion_notify_event", G_CALLBACK (preview_callback_motion_notify
) },
325 TOPLEVEL
*preview_toplevel
;
327 preview_toplevel
= s_toplevel_new ();
329 preview_toplevel
->init_left
= 0;
330 preview_toplevel
->init_top
= 0;
331 preview_toplevel
->init_right
= WIDTH_C
;
332 preview_toplevel
->init_bottom
= HEIGHT_C
;
333 preview_toplevel
->width
= 160;
334 preview_toplevel
->height
= 120;
335 preview_toplevel
->win_width
= preview_toplevel
->width
;
336 preview_toplevel
->win_height
= preview_toplevel
->height
;
337 /* be sure to turn off scrollbars */
338 preview_toplevel
->scrollbars_flag
= FALSE
;
340 preview_toplevel
->drawing_area
= GTK_WIDGET (preview
);
341 preview
->preview_toplevel
= preview_toplevel
;
343 g_object_set (GTK_WIDGET (preview
),
344 "width-request", preview_toplevel
->width
,
345 "height-request", preview_toplevel
->height
,
348 preview
->active
= FALSE
;
349 preview
->filename
= NULL
;
351 gtk_widget_set_events (GTK_WIDGET (preview
),
353 GDK_POINTER_MOTION_MASK
|
354 GDK_BUTTON_PRESS_MASK
);
355 for (tmp
= drawing_area_events
; tmp
->detailed_signal
!= NULL
; tmp
++) {
356 g_signal_connect (preview
,
357 tmp
->detailed_signal
,
365 preview_set_property (GObject
*object
,
370 Preview
*preview
= PREVIEW (object
);
371 TOPLEVEL
*preview_toplevel
= preview
->preview_toplevel
;
373 g_assert (preview_toplevel
!= NULL
);
375 switch(property_id
) {
377 g_free (preview
->filename
);
378 preview
->filename
= g_strdup (g_value_get_string (value
));
379 if (preview
->active
) preview_update (preview
);
382 preview
->active
= g_value_get_boolean (value
);
383 preview_update (preview
);
386 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
392 preview_get_property (GObject
*object
,
397 Preview
*preview
= PREVIEW (object
);
398 TOPLEVEL
*preview_toplevel
= preview
->preview_toplevel
;
400 switch(property_id
) {
402 g_assert (preview_toplevel
!= NULL
);
403 /* return the filename of the current page in toplevel */
404 g_value_set_string (value
,
405 preview_toplevel
->page_current
->page_filename
);
408 g_value_set_boolean (value
, preview
->active
);
411 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
417 preview_dispose (GObject
*self
)
419 Preview
*preview
= PREVIEW (self
);
420 TOPLEVEL
*preview_toplevel
= preview
->preview_toplevel
;
422 if (preview_toplevel
!= NULL
) {
423 preview_toplevel
->drawing_area
= NULL
;
425 o_attrib_free_current (preview_toplevel
);
426 o_complex_free_filename (preview_toplevel
);
428 if (preview_toplevel
->backingstore
) {
429 gdk_pixmap_unref (preview_toplevel
->backingstore
);
432 x_window_free_gc (preview_toplevel
);
434 s_toplevel_delete (preview_toplevel
);
436 preview
->preview_toplevel
= NULL
;
439 G_OBJECT_CLASS (preview_parent_class
)->dispose (self
);