00001
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <gtk/gtk.h>
00028 #include <glib.h>
00029 #include "preview.h"
00030
00031
00035 static void
00036 preview_close_cb
00037 (
00038 GtkWidget * widget,
00040 GtkWidget *preview_window
00042 )
00043 {
00044 gtk_widget_destroy (preview_window);
00045 }
00046
00047
00053 static gboolean
00054 preview_configure_event
00055 (
00056 GtkWidget *widget,
00058 GdkEventConfigure *event
00060 )
00061 {
00062 gint depth = -1;
00063 if (pixmap)
00064 g_object_unref (pixmap);
00065 pixmap = gdk_pixmap_new (
00066 widget->window,
00067 widget->allocation.width,
00068 widget->allocation.height,
00069 depth);
00070 gdk_draw_rectangle (
00071 pixmap,
00072 widget->style->white_gc,
00073 TRUE,
00074 0,
00075 0,
00076 widget->allocation.width,
00077 widget->allocation.height);
00078 return TRUE;
00079 }
00080
00081
00085 void
00086 preview_delete_event
00087 (
00088 GtkWidget *widget,
00090 GdkEvent *event
00092 )
00093 {
00094 gtk_widget_destroy (widget);
00095 }
00096
00097
00104 int
00105 preview_set_fg_color
00106 (
00107 GdkGC *gc,
00109 const char *color_name
00111 )
00112 {
00113 if (!gc)
00114 return (EXIT_FAILURE);
00115 if (!color_name)
00116 {
00117 fprintf (stderr, "WARNING in %s(): color_name = NULL, setting color to magenta.\n",
00118 __FUNCTION__);
00119 color_name = "magenta";
00120 return (EXIT_FAILURE);
00121 }
00122 GdkColor color;
00123 if (!gdk_color_parse (color_name, &color))
00124 {
00125 fprintf (stderr, "WARNING in %s(): could not parse color %s.\n",
00126 __FUNCTION__, color_name);
00127 return (EXIT_FAILURE);
00128 }
00129 gdk_gc_set_foreground (gc, &color);
00130 return (EXIT_SUCCESS);
00131 }
00132
00133
00140 int
00141 preview_set_fill_mode
00142 (
00143 GdkGC *gc,
00145 GdkFill fill_mode
00164 )
00165 {
00166 if (!gc)
00167 return (EXIT_FAILURE);
00168 if (!fill_mode)
00169 {
00170 fprintf (stderr, "WARNING in %s(): fill mode = NULL, setting fill mode to SOLID.\n",
00171 __FUNCTION__);
00172 fill_mode = GDK_SOLID;
00173 return (EXIT_FAILURE);
00174 }
00175 gdk_gc_set_fill
00176 (
00177 gc,
00178 fill_mode
00179 );
00180 return (EXIT_SUCCESS);
00181 }
00182
00183
00190 int
00191 preview_set_line_cap
00192 (
00193 GdkGC *gc,
00195 GdkCapStyle line_cap
00214 )
00215 {
00216 if (!gc)
00217 return (EXIT_FAILURE);
00218 if (!line_cap)
00219 {
00220 fprintf (stderr, "WARNING in %s(): line cap = NULL, setting line cap to ROUND.\n",
00221 __FUNCTION__);
00222 line_cap = GDK_CAP_ROUND;
00223 return (EXIT_FAILURE);
00224 }
00225 GdkGCValues gc_values;
00226 gdk_gc_get_values (gc, &gc_values);
00227 gdk_gc_set_line_attributes
00228 (
00229 gc,
00230 gc_values.line_width,
00231 gc_values.line_style,
00232 line_cap,
00233 gc_values.join_style
00234 );
00235 return (EXIT_SUCCESS);
00236 }
00237
00238
00245 int
00246 preview_set_line_style
00247 (
00248 GdkGC *gc,
00250 GdkLineStyle line_style
00266 )
00267 {
00268 if (!gc)
00269 return (EXIT_FAILURE);
00270 if (!line_style)
00271 {
00272 fprintf (stderr, "WARNING in %s(): line style = NULL, setting line style to SOLID.\n",
00273 __FUNCTION__);
00274 line_style = GDK_LINE_SOLID;
00275 return (EXIT_FAILURE);
00276 }
00277 GdkGCValues gc_values;
00278 gdk_gc_get_values (gc, &gc_values);
00279 gdk_gc_set_line_attributes
00280 (
00281 gc,
00282 gc_values.line_width,
00283 line_style,
00284 gc_values.cap_style,
00285 gc_values.join_style
00286 );
00287 return (EXIT_SUCCESS);
00288 }
00289
00290
00297 int
00298 preview_set_line_width
00299 (
00300 GdkGC *gc,
00302 gint line_width
00304 )
00305 {
00306 if ((!gc) || (line_width == 0))
00307 {
00308 return (EXIT_FAILURE);
00309 }
00310 GdkGCValues gc_values;
00311 gdk_gc_get_values (gc, &gc_values);
00312 if (line_width < 0)
00313 {
00314 gdk_gc_set_line_attributes
00315 (
00316 gc,
00317 abs (line_width),
00318 GDK_LINE_DOUBLE_DASH,
00319 gc_values.cap_style,
00320 gc_values.join_style
00321 );
00322 }
00323 else
00324 {
00325 gdk_gc_set_line_attributes
00326 (
00327 gc,
00328 line_width,
00329 gc_values.line_style,
00330 gc_values.cap_style,
00331 gc_values.join_style
00332 );
00333 }
00334 return (EXIT_SUCCESS);
00335 }
00336
00337
00346 int
00347 preview_use_gc
00348 (
00349 GdkDrawable *drawable,
00354 GdkGC *gc,
00356 const char * color_name,
00358 gint line_width,
00360 GdkCapStyle line_cap,
00379 GdkLineStyle line_style,
00395 GdkFill fill_mode
00414 )
00415 {
00416 if (!drawable)
00417 {
00418 fprintf (stderr, "WARNING: couldn't allocate a gc, invalid drawable was passed.\n");
00419 return (EXIT_FAILURE);
00420 }
00421 if (!gc)
00422 {
00423 GdkGC *gc = gdk_gc_new (drawable);
00424 preview_set_fg_color (gc, color_name);
00425 preview_set_line_width (gc, line_width);
00426 preview_set_line_cap (gc, line_cap);
00427 preview_set_line_style (gc, line_style);
00428 preview_set_fill_mode (gc, fill_mode);
00429
00430 return (EXIT_SUCCESS);
00431 }
00432 }
00433
00434
00442 static void
00443 preview_draw_arc
00444 (
00445 GtkWidget *widget,
00447 preview_arc arc
00449 )
00450 {
00451 if (!arc)
00452 {
00453 fprintf (stderr, "WARNING: passed arc was invalid.\n");
00454 return;
00455 }
00456
00457 arc->angle1 = 64.0 * arc->angle1;
00458 gdk_draw_arc
00459 (
00460 arc->drawable,
00461 arc->gc,
00462 arc->filled,
00463 arc->x,
00464 arc->y,
00465 arc->width,
00466 arc->height,
00467 arc->angle1,
00468 arc->angle2
00469 );
00470 }
00471
00472
00476 static void
00477 preview_draw_background
00478 (
00479 GtkWidget *widget,
00481 gdouble x,
00483 gdouble y
00485 )
00486 {
00487 GdkRectangle update_rect;
00488 update_rect.x = x - 5;
00489 update_rect.y = y - 5;
00490 update_rect.width = 10;
00491 update_rect.height = 10;
00492 gdk_draw_rectangle
00493 (
00494 pixmap,
00495 widget->style->black_gc,
00496 TRUE,
00497 update_rect.x,
00498 update_rect.y,
00499 update_rect.width,
00500 update_rect.height
00501 );
00502 gtk_widget_queue_draw_area
00503 (
00504 widget,
00505 update_rect.x,
00506 update_rect.y,
00507 update_rect.width,
00508 update_rect.height
00509 );
00510 }
00511
00512
00518 static void
00519 preview_draw_line
00520 (
00521 GtkWidget *widget,
00523 preview_line line
00525 )
00526 {
00527 if (!line)
00528 {
00529 fprintf (stderr, "WARNING: passed line was invalid.\n");
00530 return;
00531 }
00532 gdk_draw_line
00533 (
00534 line->drawable,
00535 line->gc,
00536 line->x1,
00537 line->y1,
00538 line->x2,
00539 line->y2
00540 );
00541 }
00542
00543
00547 static void
00548 preview_draw_pad
00549 (
00550 GtkWidget *widget
00552 )
00553 {
00555 }
00556
00557
00561 static void
00562 preview_draw_pin
00563 (
00564 GtkWidget *widget
00566 )
00567 {
00569 }
00570
00571
00575 static void
00576 preview_draw_polygon
00577 (
00578 GtkWidget *widget,
00580 preview_polygon polygon
00582 )
00583 {
00584 if (!polygon)
00585 {
00586 fprintf (stderr, "WARNING: passed polygon was invalid.\n");
00587 return;
00588 }
00589 gdk_draw_polygon
00590 (
00591 polygon->drawable,
00592 polygon->gc,
00593 polygon->filled,
00594 polygon->points,
00595 polygon->npoints
00596 );
00597 }
00598
00599
00613 static void
00614 preview_draw_rectangle
00615 (
00616 GtkWidget *widget,
00618 preview_rectangle rectangle
00620 )
00621 {
00622 if (!rectangle)
00623 {
00624 fprintf (stderr, "WARNING: passed rectangle was invalid.\n");
00625 return;
00626 }
00627 gdk_draw_rectangle
00628 (
00629 rectangle->drawable,
00630 rectangle->gc,
00631 rectangle->filled,
00632 rectangle->x,
00633 rectangle->y,
00634 rectangle->width,
00635 rectangle->height
00636 );
00637 }
00638
00639
00645 static gboolean
00646 preview_expose_event
00647 (
00648 GtkWidget *widget,
00650 GdkEventExpose *event
00652 )
00653 {
00654 gdk_draw_drawable (widget->window,
00655 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
00656 pixmap,
00657 event->area.x,
00658 event->area.y,
00659 event->area.x,
00660 event->area.y,
00661 event->area.width,
00662 event->area.height);
00663
00667 return FALSE;
00668 }
00669
00670
00679 int
00680 preview_create_window
00681 (
00682 gchar *footprint_name,
00684 gint width,
00686 gint height
00688 )
00689 {
00690
00691 GtkWidget *preview_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00692
00693
00694 gtk_window_set_destroy_with_parent (GTK_WINDOW (preview_window), TRUE);
00695
00696 gchar *preview_window_title = g_strdup_printf ("pcb-fpw preview: %s",
00697 footprint_name);
00698 gtk_window_set_title (GTK_WINDOW (preview_window),
00699 preview_window_title);
00700 g_free (preview_window_title);
00701 gtk_container_set_border_width (GTK_CONTAINER (preview_window), 10);
00702
00703 g_signal_connect
00704 (
00705 GTK_OBJECT (preview_window),
00706 "delete_event",
00707 (GtkSignalFunc) preview_delete_event,
00708 NULL
00709 );
00710
00711 GtkWidget *vbox = gtk_vbox_new (FALSE, 10);
00712 gtk_container_add (GTK_CONTAINER (preview_window), vbox);
00713
00714 GtkWidget *preview_drawing_area = gtk_drawing_area_new ();
00715 gtk_widget_set_size_request (preview_drawing_area, width, height);
00716
00717 g_signal_connect
00718 (
00719 GTK_OBJECT (preview_drawing_area),
00720 "expose_event",
00721 (GtkSignalFunc) preview_expose_event,
00722 NULL
00723 );
00724 g_signal_connect
00725 (
00726 GTK_OBJECT (preview_drawing_area),
00727 "configure_event",
00728 (GtkSignalFunc) preview_configure_event,
00729 NULL
00730 );
00731 gtk_widget_set_events
00732 (
00733 preview_drawing_area,
00734 GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK
00735 );
00736
00737 GtkWidget *preview_viewport = gtk_viewport_new (NULL, NULL);
00738 gtk_viewport_set_shadow_type (GTK_VIEWPORT (preview_viewport), GTK_SHADOW_IN);
00739
00740 gtk_box_pack_start (GTK_BOX (vbox), preview_viewport, TRUE, TRUE, 0);
00741
00742 gtk_container_add (GTK_CONTAINER (preview_viewport), preview_drawing_area);
00743
00744 GtkWidget *hbox = gtk_hbutton_box_new ();
00745 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
00746
00747 GtkWidget *button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
00748 g_signal_connect
00749 (
00750 G_OBJECT (button),
00751 "clicked",
00752 G_CALLBACK (preview_close_cb),
00753 preview_window
00754 );
00755
00756 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
00757
00758 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
00759
00760 gtk_window_set_default_size
00761 (
00762 GTK_WINDOW (preview_window),
00763 width + 50,
00764 height + 50
00765 );
00766
00767 gtk_widget_realize (preview_window);
00768 gtk_widget_show_all (preview_window);
00769
00770 gtk_main ();
00771 return 0;
00772 }
00773
00774