17 #include "crosshair.h"
19 #include "../hidint.h"
21 #include "hid/common/hidnogui.h"
22 #include "hid/common/draw_helpers.h"
23 #include "pcb-printf.h"
25 #ifdef HAVE_LIBDMALLOC
34 pan_common (GHidPort
*port
)
38 /* We need to fix up the PCB coordinates corresponding to the last
39 * event so convert it back to event coordinates temporarily. */
40 ghid_pcb_to_event_coords (gport
->pcb_x
, gport
->pcb_y
, &event_x
, &event_y
);
42 /* Don't pan so far the board is completely off the screen */
43 port
->view
.x0
= MAX (-port
->view
.width
, port
->view
.x0
);
44 port
->view
.y0
= MAX (-port
->view
.height
, port
->view
.y0
);
45 port
->view
.x0
= MIN ( port
->view
.x0
, PCB
->MaxWidth
);
46 port
->view
.y0
= MIN ( port
->view
.y0
, PCB
->MaxHeight
);
48 /* Fix up noted event coordinates to match where we clamped. Alternatively
49 * we could call ghid_note_event_location (NULL); to get a new pointer
50 * location, but this costs us an xserver round-trip (on X11 platforms)
52 ghid_event_to_pcb_coords (event_x
, event_y
, &gport
->pcb_x
, &gport
->pcb_y
);
54 ghidgui
->adjustment_changed_holdoff
= TRUE
;
55 gtk_range_set_value (GTK_RANGE (ghidgui
->h_range
), gport
->view
.x0
);
56 gtk_range_set_value (GTK_RANGE (ghidgui
->v_range
), gport
->view
.y0
);
57 ghidgui
->adjustment_changed_holdoff
= FALSE
;
59 ghid_port_ranges_changed();
63 ghid_pan_view_abs (Coord pcb_x
, Coord pcb_y
, int widget_x
, int widget_y
)
65 gport
->view
.x0
= SIDE_X (pcb_x
) - widget_x
* gport
->view
.coord_per_px
;
66 gport
->view
.y0
= SIDE_Y (pcb_y
) - widget_y
* gport
->view
.coord_per_px
;
72 ghid_pan_view_rel (Coord dx
, Coord dy
)
81 /* gport->view.coord_per_px:
82 * zoom value is PCB units per screen pixel. Larger numbers mean zooming
83 * out - the largest value means you are looking at the whole board.
85 * gport->view_width and gport->view_height are in PCB coordinates
88 #define ALLOW_ZOOM_OUT_BY 10 /* Arbitrary, and same as the lesstif HID */
90 ghid_zoom_view_abs (Coord center_x
, Coord center_y
, double new_zoom
)
92 double min_zoom
, max_zoom
;
95 /* Limit the "minimum" zoom constant (maximum zoom), at 1 pixel per PCB
96 * unit, and set the "maximum" zoom constant (minimum zoom), such that
97 * the entire board just fits inside the viewport
100 max_zoom
= MAX (PCB
->MaxWidth
/ gport
->width
,
101 PCB
->MaxHeight
/ gport
->height
) * ALLOW_ZOOM_OUT_BY
;
102 new_zoom
= MIN (MAX (min_zoom
, new_zoom
), max_zoom
);
104 if (gport
->view
.coord_per_px
== new_zoom
)
107 xtmp
= (SIDE_X (center_x
) - gport
->view
.x0
) / (double)gport
->view
.width
;
108 ytmp
= (SIDE_Y (center_y
) - gport
->view
.y0
) / (double)gport
->view
.height
;
110 gport
->view
.coord_per_px
= new_zoom
;
111 pixel_slop
= new_zoom
;
112 ghid_port_ranges_scale ();
114 gport
->view
.x0
= SIDE_X (center_x
) - xtmp
* gport
->view
.width
;
115 gport
->view
.y0
= SIDE_Y (center_y
) - ytmp
* gport
->view
.height
;
119 ghid_set_status_line_label ();
123 ghid_zoom_view_rel (Coord center_x
, Coord center_y
, double factor
)
125 ghid_zoom_view_abs (center_x
, center_y
, gport
->view
.coord_per_px
* factor
);
129 ghid_zoom_view_fit (void)
131 ghid_pan_view_abs (0, 0, 0, 0);
132 ghid_zoom_view_abs (0, 0, MAX (PCB
->MaxWidth
/ gport
->width
,
133 PCB
->MaxHeight
/ gport
->height
));
137 ghid_flip_view (Coord center_x
, Coord center_y
, bool flip_x
, bool flip_y
)
139 int widget_x
, widget_y
;
141 /* Work out where on the screen the flip point is */
142 ghid_pcb_to_event_coords (center_x
, center_y
, &widget_x
, &widget_y
);
144 gport
->view
.flip_x
= gport
->view
.flip_x
!= flip_x
;
145 gport
->view
.flip_y
= gport
->view
.flip_y
!= flip_y
;
147 /* Pan the board so the center location remains in the same place */
148 ghid_pan_view_abs (center_x
, center_y
, widget_x
, widget_y
);
150 ghid_invalidate_all ();
153 /* ------------------------------------------------------------ */
155 static const char zoom_syntax
[] =
160 static const char zoom_help
[] =
161 N_("Various zoom factor changes.");
163 /* %start-doc actions Zoom
164 Changes the zoom (magnification) of the view of the board. If no
165 arguments are passed, the view is scaled such that the board just fits
166 inside the visible window (i.e. ``view all''). Otherwise,
167 @var{factor} specifies a change in zoom factor. It may be prefixed by
168 @code{+}, @code{-}, or @code{=} to change how the zoom factor is
169 modified. The @var{factor} is a floating point number, such as
170 @code{1.5} or @code{0.75}.
175 Values greater than 1.0 cause the board to be drawn smaller; more of
176 the board will be visible. Values between 0.0 and 1.0 cause the board
177 to be drawn bigger; less of the board will be visible.
180 Values greater than 1.0 cause the board to be drawn bigger; less of
181 the board will be visible. Values between 0.0 and 1.0 cause the board
182 to be drawn smaller; more of the board will be visible.
186 The @var{factor} is an absolute zoom factor; the unit for this value
187 is "PCB units per screen pixel". Since PCB units are 0.01 mil, a
188 @var{factor} of 1000 means 10 mils (0.01 in) per pixel, or 100 DPI,
189 about the actual resolution of most screens - resulting in an "actual
190 size" board. Similarly, a @var{factor} of 100 gives you a 10x actual
195 Note that zoom factors of zero are silently ignored.
202 Zoom (int argc
, char **argv
, Coord x
, Coord y
)
212 ghid_zoom_view_fit ();
217 if (*vp
== '+' || *vp
== '-' || *vp
== '=')
225 ghid_zoom_view_rel (x
, y
, 1 / v
);
229 ghid_zoom_view_rel (x
, y
, v
);
232 ghid_zoom_view_abs (x
, y
, v
);
239 /* ------------------------------------------------------------ */
242 ghid_calibrate (double xval
, double yval
)
244 printf (_("ghid_calibrate() -- not implemented\n"));
247 static int ghid_gui_is_up
= 0;
250 ghid_notify_gui_is_up ()
256 ghid_shift_is_pressed ()
258 GdkModifierType mask
;
259 GHidPort
*out
= &ghid_port
;
261 if( ! ghid_gui_is_up
)
264 gdk_window_get_pointer (gtk_widget_get_window (out
->drawing_area
),
266 return (mask
& GDK_SHIFT_MASK
) ? TRUE
: FALSE
;
270 ghid_control_is_pressed ()
272 GdkModifierType mask
;
273 GHidPort
*out
= &ghid_port
;
275 if( ! ghid_gui_is_up
)
278 gdk_window_get_pointer (gtk_widget_get_window (out
->drawing_area
),
280 return (mask
& GDK_CONTROL_MASK
) ? TRUE
: FALSE
;
284 ghid_mod1_is_pressed ()
286 GdkModifierType mask
;
287 GHidPort
*out
= &ghid_port
;
289 if( ! ghid_gui_is_up
)
292 gdk_window_get_pointer (gtk_widget_get_window (out
->drawing_area
),
295 return (mask
& ( 1 << 13 ) ) ? TRUE
: FALSE
; // The option key is not MOD1, although it should be...
297 return (mask
& GDK_MOD1_MASK
) ? TRUE
: FALSE
;
302 ghid_set_crosshair (int x
, int y
, int action
)
306 int offset_x
, offset_y
;
307 int widget_x
, widget_y
;
308 int pointer_x
, pointer_y
;
311 if (gport
->crosshair_x
!= x
|| gport
->crosshair_y
!= y
)
313 ghid_set_cursor_position_labels ();
314 gport
->crosshair_x
= x
;
315 gport
->crosshair_y
= y
;
317 /* FIXME - does this trigger the idle_proc stuff? It is in the
318 * lesstif HID. Maybe something is needed here?
324 if (action
!= HID_SC_PAN_VIEWPORT
&&
325 action
!= HID_SC_WARP_POINTER
)
328 /* Find out where the drawing area is on the screen. gdk_display_get_pointer
329 * and gdk_display_warp_pointer work relative to the whole display, whilst
330 * our coordinates are relative to the drawing area origin.
332 gdk_window_get_origin (gtk_widget_get_window (gport
->drawing_area
),
333 &offset_x
, &offset_y
);
334 display
= gdk_display_get_default ();
337 case HID_SC_PAN_VIEWPORT
:
338 /* Pan the board in the viewport so that the crosshair (who's location
339 * relative on the board was set above) lands where the pointer is.
340 * We pass the request to pan a particular point on the board to a
341 * given widget coordinate of the viewport into the rendering code
344 /* Find out where the pointer is relative to the display */
345 gdk_display_get_pointer (display
, NULL
, &pointer_x
, &pointer_y
, NULL
);
347 widget_x
= pointer_x
- offset_x
;
348 widget_y
= pointer_y
- offset_y
;
350 ghid_event_to_pcb_coords (widget_x
, widget_y
, &pcb_x
, &pcb_y
);
351 ghid_pan_view_abs (pcb_x
, pcb_y
, widget_x
, widget_y
);
353 /* Just in case we couldn't pan the board the whole way,
354 * we warp the pointer to where the crosshair DID land.
358 case HID_SC_WARP_POINTER
:
359 screen
= gdk_display_get_default_screen (display
);
361 ghid_pcb_to_event_coords (x
, y
, &widget_x
, &widget_y
);
363 pointer_x
= offset_x
+ widget_x
;
364 pointer_y
= offset_y
+ widget_y
;
366 gdk_display_warp_pointer (display
, screen
, pointer_x
, pointer_y
);
374 void (*func
) (hidval
);
380 /* We need a wrapper around the hid timer because a gtk timer needs
381 | to return FALSE else the timer will be restarted.
384 ghid_timer (GuiTimer
* timer
)
386 (*timer
->func
) (timer
->user_data
);
387 ghid_mode_cursor (Settings
.Mode
);
388 return FALSE
; /* Turns timer off */
392 ghid_add_timer (void (*func
) (hidval user_data
),
393 unsigned long milliseconds
, hidval user_data
)
395 GuiTimer
*timer
= g_new0 (GuiTimer
, 1);
399 timer
->user_data
= user_data
;
400 timer
->id
= g_timeout_add (milliseconds
, (GSourceFunc
) ghid_timer
, timer
);
401 ret
.ptr
= (void *) timer
;
406 ghid_stop_timer (hidval timer
)
408 void *ptr
= timer
.ptr
;
410 g_source_remove (((GuiTimer
*) ptr
)->id
);
416 void (*func
) ( hidval
, int, unsigned int, hidval
);
424 /* We need a wrapper around the hid file watch to pass the correct flags
427 ghid_watch (GIOChannel
*source
, GIOCondition condition
, gpointer data
)
429 unsigned int pcb_condition
= 0;
431 GuiWatch
*watch
= (GuiWatch
*)data
;
433 if (condition
& G_IO_IN
)
434 pcb_condition
|= PCB_WATCH_READABLE
;
435 if (condition
& G_IO_OUT
)
436 pcb_condition
|= PCB_WATCH_WRITABLE
;
437 if (condition
& G_IO_ERR
)
438 pcb_condition
|= PCB_WATCH_ERROR
;
439 if (condition
& G_IO_HUP
)
440 pcb_condition
|= PCB_WATCH_HANGUP
;
442 x
.ptr
= (void *) watch
;
443 watch
->func (x
, watch
->fd
, pcb_condition
, watch
->user_data
);
444 ghid_mode_cursor (Settings
.Mode
);
446 return TRUE
; /* Leave watch on */
450 ghid_watch_file (int fd
, unsigned int condition
, void (*func
) (hidval watch
, int fd
, unsigned int condition
, hidval user_data
),
453 GuiWatch
*watch
= g_new0 (GuiWatch
, 1);
455 unsigned int glib_condition
= 0;
457 if (condition
& PCB_WATCH_READABLE
)
458 glib_condition
|= G_IO_IN
;
459 if (condition
& PCB_WATCH_WRITABLE
)
460 glib_condition
|= G_IO_OUT
;
461 if (condition
& PCB_WATCH_ERROR
)
462 glib_condition
|= G_IO_ERR
;
463 if (condition
& PCB_WATCH_HANGUP
)
464 glib_condition
|= G_IO_HUP
;
467 watch
->user_data
= user_data
;
469 watch
->channel
= g_io_channel_unix_new( fd
);
470 watch
->id
= g_io_add_watch( watch
->channel
, (GIOCondition
)glib_condition
, ghid_watch
, watch
);
472 ret
.ptr
= (void *) watch
;
477 ghid_unwatch_file (hidval data
)
479 GuiWatch
*watch
= (GuiWatch
*)data
.ptr
;
481 g_io_channel_shutdown( watch
->channel
, TRUE
, NULL
);
482 g_io_channel_unref( watch
->channel
);
489 void (*func
) (hidval user_data
);
493 static gboolean
ghid_block_hook_prepare (GSource
*source
,
495 static gboolean
ghid_block_hook_check (GSource
*source
);
496 static gboolean
ghid_block_hook_dispatch (GSource
*source
,
497 GSourceFunc callback
,
500 static GSourceFuncs ghid_block_hook_funcs
= {
501 ghid_block_hook_prepare
,
502 ghid_block_hook_check
,
503 ghid_block_hook_dispatch
,
504 NULL
// No destroy notification
508 ghid_block_hook_prepare (GSource
*source
,
511 hidval data
= ((BlockHookSource
*)source
)->user_data
;
512 ((BlockHookSource
*)source
)->func( data
);
517 ghid_block_hook_check (GSource
*source
)
523 ghid_block_hook_dispatch (GSource
*source
,
524 GSourceFunc callback
,
531 ghid_add_block_hook (void (*func
) (hidval data
),
535 BlockHookSource
*source
;
537 source
= (BlockHookSource
*)g_source_new (&ghid_block_hook_funcs
, sizeof( BlockHookSource
));
540 source
->user_data
= user_data
;
542 g_source_attach ((GSource
*)source
, NULL
);
544 ret
.ptr
= (void *) source
;
549 ghid_stop_block_hook (hidval mlpoll
)
551 GSource
*source
= (GSource
*)mlpoll
.ptr
;
552 g_source_destroy( source
);
556 ghid_confirm_dialog (char *msg
, ...)
560 char *cancelmsg
= NULL
, *okmsg
= NULL
;
561 static gint x
= -1, y
= -1;
563 GHidPort
*out
= &ghid_port
;
566 cancelmsg
= va_arg (ap
, char *);
567 okmsg
= va_arg (ap
, char *);
572 cancelmsg
= _("_Cancel");
576 dialog
= gtk_message_dialog_new (GTK_WINDOW (out
->top_window
),
577 (GtkDialogFlags
) (GTK_DIALOG_MODAL
|
578 GTK_DIALOG_DESTROY_WITH_PARENT
),
579 GTK_MESSAGE_QUESTION
,
582 gtk_dialog_add_button (GTK_DIALOG (dialog
),
583 cancelmsg
, GTK_RESPONSE_CANCEL
);
586 gtk_dialog_add_button (GTK_DIALOG (dialog
),
587 okmsg
, GTK_RESPONSE_OK
);
591 gtk_window_move(GTK_WINDOW (dialog
), x
, y
);
594 if (gtk_dialog_run (GTK_DIALOG (dialog
)) == GTK_RESPONSE_OK
)
597 gtk_window_get_position(GTK_WINDOW (dialog
), &x
, &y
);
599 gtk_widget_destroy (dialog
);
604 ghid_close_confirm_dialog ()
606 switch (ghid_dialog_close_confirm ())
608 case GUI_DIALOG_CLOSE_CONFIRM_SAVE
:
610 if (hid_actionl ("Save", NULL
))
612 return 0; /* Cancel */
614 return 1; /* Close */
617 case GUI_DIALOG_CLOSE_CONFIRM_NOSAVE
:
619 return 1; /* Close */
621 case GUI_DIALOG_CLOSE_CONFIRM_CANCEL
:
624 return 0; /* Cancel */
630 ghid_report_dialog (char *title
, char *msg
)
632 ghid_dialog_report (title
, msg
);
636 ghid_prompt_for (const char *msg
, const char *default_string
)
640 rv
= ghid_dialog_input (msg
, default_string
);
644 /* FIXME -- implement a proper file select dialog */
647 ghid_fileselect (const char *title
, const char *descr
,
648 char *default_file
, char *default_ext
,
649 const char *history_tag
, int flags
)
653 rv
= ghid_dialog_input (title
, default_file
);
659 ghid_show_item (void *item
)
661 ghid_pinout_window_show (&ghid_port
, (ElementTypePtr
) item
);
670 struct progress_dialog
681 gulong response_handler
;
682 gulong destroy_handler
;
683 gulong delete_handler
;
687 run_response_handler (GtkDialog
*dialog
,
691 struct progress_dialog
*pd
= data
;
693 pd
->response_id
= response_id
;
697 run_delete_handler (GtkDialog
*dialog
,
701 struct progress_dialog
*pd
= data
;
703 pd
->response_id
= GTK_RESPONSE_DELETE_EVENT
;
705 return TRUE
; /* Do not destroy */
709 run_destroy_handler (GtkDialog
*dialog
, gpointer data
)
711 struct progress_dialog
*pd
= data
;
713 pd
->destroyed
= TRUE
;
716 static struct progress_dialog
*
717 make_progress_dialog (void)
719 struct progress_dialog
*pd
;
720 GtkWidget
*content_area
;
721 GtkWidget
*alignment
;
724 pd
= g_new0 (struct progress_dialog
, 1);
725 pd
->response_id
= GTK_RESPONSE_NONE
;
727 pd
->dialog
= gtk_dialog_new_with_buttons (_("Progress"),
728 GTK_WINDOW (gport
->top_window
),
729 /* Modal so nothing else can get events whilst
730 the main mainloop isn't running */
731 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
,
736 gtk_window_set_deletable (GTK_WINDOW (pd
->dialog
), FALSE
);
737 gtk_window_set_skip_pager_hint (GTK_WINDOW (pd
->dialog
), TRUE
);
738 gtk_window_set_skip_taskbar_hint (GTK_WINDOW (pd
->dialog
), TRUE
);
739 gtk_widget_set_size_request (pd
->dialog
, 300, -1);
741 pd
->message
= gtk_label_new (NULL
);
742 gtk_misc_set_alignment (GTK_MISC (pd
->message
), 0., 0.);
744 pd
->progress
= gtk_progress_bar_new ();
745 gtk_widget_set_size_request (pd
->progress
, -1, 26);
747 vbox
= gtk_vbox_new (false, 0);
748 gtk_box_pack_start (GTK_BOX (vbox
), pd
->message
, true, true, 8);
749 gtk_box_pack_start (GTK_BOX (vbox
), pd
->progress
, false, true, 8);
751 alignment
= gtk_alignment_new (0., 0., 1., 1.);
752 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment
), 8, 8, 8, 8);
753 gtk_container_add (GTK_CONTAINER (alignment
), vbox
);
755 content_area
= gtk_dialog_get_content_area (GTK_DIALOG (pd
->dialog
));
756 gtk_box_pack_start (GTK_BOX (content_area
), alignment
, true, true, 0);
758 gtk_widget_show_all (alignment
);
760 g_object_ref (pd
->dialog
);
761 gtk_window_present (GTK_WINDOW (pd
->dialog
));
763 pd
->response_handler
=
764 g_signal_connect (pd
->dialog
, "response",
765 G_CALLBACK (run_response_handler
), pd
);
767 g_signal_connect (pd
->dialog
, "delete-event",
768 G_CALLBACK (run_delete_handler
), pd
);
769 pd
->destroy_handler
=
770 g_signal_connect (pd
->dialog
, "destroy",
771 G_CALLBACK (run_destroy_handler
), pd
);
773 pd
->loop
= g_main_loop_new (NULL
, FALSE
);
774 pd
->timer
= g_timer_new ();
780 destroy_progress_dialog (struct progress_dialog
*pd
)
787 g_signal_handler_disconnect (pd
->dialog
, pd
->response_handler
);
788 g_signal_handler_disconnect (pd
->dialog
, pd
->delete_handler
);
789 g_signal_handler_disconnect (pd
->dialog
, pd
->destroy_handler
);
792 g_timer_destroy (pd
->timer
);
793 g_object_unref (pd
->dialog
);
794 g_main_loop_unref (pd
->loop
);
796 gtk_widget_destroy (pd
->dialog
);
803 handle_progress_dialog_events (struct progress_dialog
*pd
)
805 GMainContext
* context
= g_main_loop_get_context (pd
->loop
);
808 while (g_main_context_pending (context
))
810 g_main_context_iteration (context
, FALSE
);
814 #define MIN_TIME_SEPARATION (50./1000.) /* 50ms */
816 ghid_progress (int so_far
, int total
, const char *message
)
818 static struct progress_dialog
*pd
= NULL
;
820 /* If we are finished, destroy any dialog */
821 if (so_far
== 0 && total
== 0 && message
== NULL
)
823 destroy_progress_dialog (pd
);
829 pd
= make_progress_dialog ();
831 /* We don't want to keep the underlying process too busy whilst we
832 * process events. If we get called quickly after the last progress
833 * update, wait a little bit before we respond - perhaps the next
834 * time progress is reported.
836 * The exception here is that we always want to process the first
837 * batch of events after having shown the dialog for the first time
839 if (pd
->started
&& g_timer_elapsed (pd
->timer
, NULL
) < MIN_TIME_SEPARATION
)
842 gtk_label_set_text (GTK_LABEL (pd
->message
), message
);
843 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pd
->progress
),
844 (double)so_far
/ (double)total
);
846 handle_progress_dialog_events (pd
);
847 g_timer_start (pd
->timer
);
851 return (pd
->response_id
== GTK_RESPONSE_CANCEL
||
852 pd
->response_id
== GTK_RESPONSE_DELETE_EVENT
) ? 1 : 0;
855 /* ---------------------------------------------------------------------- */
864 static AttrRow
*attr_row
= 0;
865 static int attr_num_rows
= 0;
866 static int attr_max_rows
= 0;
867 static AttributeListType
*attributes_list
;
868 static GtkWidget
*attributes_dialog
, *attr_table
;
870 static void attributes_delete_callback (GtkWidget
*w
, void *v
);
872 #define GA_RESPONSE_REVERT 1
873 #define GA_RESPONSE_NEW 2
876 ghid_attr_set_table_size ()
878 gtk_table_resize (GTK_TABLE (attr_table
), attr_num_rows
> 0 ? attr_num_rows
: 1, 3);
882 ghid_attributes_need_rows (int new_max
)
884 if (attr_max_rows
< new_max
)
887 attr_row
= (AttrRow
*) realloc (attr_row
, new_max
* sizeof(AttrRow
));
889 attr_row
= (AttrRow
*) malloc (new_max
* sizeof(AttrRow
));
891 while (attr_max_rows
< new_max
)
893 /* add [attr_max_rows] */
894 attr_row
[attr_max_rows
].del
= gtk_button_new_with_label ("del");
895 gtk_table_attach (GTK_TABLE (attr_table
), attr_row
[attr_max_rows
].del
,
897 attr_max_rows
, attr_max_rows
+1,
898 (GtkAttachOptions
)(GTK_FILL
| GTK_EXPAND
),
901 g_signal_connect (G_OBJECT (attr_row
[attr_max_rows
].del
), "clicked",
902 G_CALLBACK (attributes_delete_callback
), GINT_TO_POINTER (attr_max_rows
) );
904 attr_row
[attr_max_rows
].w_name
= gtk_entry_new ();
905 gtk_table_attach (GTK_TABLE (attr_table
), attr_row
[attr_max_rows
].w_name
,
907 attr_max_rows
, attr_max_rows
+1,
908 (GtkAttachOptions
)(GTK_FILL
| GTK_EXPAND
),
912 attr_row
[attr_max_rows
].w_value
= gtk_entry_new ();
913 gtk_table_attach (GTK_TABLE (attr_table
), attr_row
[attr_max_rows
].w_value
,
915 attr_max_rows
, attr_max_rows
+1,
916 (GtkAttachOptions
)(GTK_FILL
| GTK_EXPAND
),
923 /* Manage any previously unused rows we now need to show. */
924 while (attr_num_rows
< new_max
)
926 /* manage attr_num_rows */
927 gtk_widget_show (attr_row
[attr_num_rows
].del
);
928 gtk_widget_show (attr_row
[attr_num_rows
].w_name
);
929 gtk_widget_show (attr_row
[attr_num_rows
].w_value
);
935 ghid_attributes_revert ()
939 ghid_attributes_need_rows (attributes_list
->Number
);
941 /* Unmanage any previously used rows we don't need. */
942 while (attr_num_rows
> attributes_list
->Number
)
945 gtk_widget_hide (attr_row
[attr_num_rows
].del
);
946 gtk_widget_hide (attr_row
[attr_num_rows
].w_name
);
947 gtk_widget_hide (attr_row
[attr_num_rows
].w_value
);
951 for (i
=0; i
<attributes_list
->Number
; i
++)
954 gtk_entry_set_text (GTK_ENTRY (attr_row
[i
].w_name
), attributes_list
->List
[i
].name
);
955 gtk_entry_set_text (GTK_ENTRY (attr_row
[i
].w_value
), attributes_list
->List
[i
].value
);
959 ghid_attr_set_table_size ();
963 attributes_delete_callback (GtkWidget
*w
, void *v
)
967 n
= GPOINTER_TO_INT (v
);
969 for (i
=n
; i
<attr_num_rows
-1; i
++)
971 gtk_entry_set_text (GTK_ENTRY (attr_row
[i
].w_name
),
972 gtk_entry_get_text (GTK_ENTRY (attr_row
[i
+1].w_name
)));
973 gtk_entry_set_text (GTK_ENTRY (attr_row
[i
].w_value
),
974 gtk_entry_get_text (GTK_ENTRY (attr_row
[i
+1].w_value
)));
978 gtk_widget_hide (attr_row
[attr_num_rows
].del
);
979 gtk_widget_hide (attr_row
[attr_num_rows
].w_name
);
980 gtk_widget_hide (attr_row
[attr_num_rows
].w_value
);
982 ghid_attr_set_table_size ();
986 ghid_attributes (char *owner
, AttributeListType
*attrs
)
988 GtkWidget
*content_area
;
991 attributes_list
= attrs
;
996 attributes_dialog
= gtk_dialog_new_with_buttons (owner
,
997 GTK_WINDOW (ghid_port
.top_window
),
999 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
1000 "Revert", GA_RESPONSE_REVERT
,
1001 "New", GA_RESPONSE_NEW
,
1002 GTK_STOCK_OK
, GTK_RESPONSE_OK
, NULL
);
1004 attr_table
= gtk_table_new (attrs
->Number
, 3, 0);
1006 content_area
= gtk_dialog_get_content_area (GTK_DIALOG (attributes_dialog
));
1007 gtk_box_pack_start (GTK_BOX (content_area
), attr_table
, FALSE
, FALSE
, 0);
1009 gtk_widget_show (attr_table
);
1011 ghid_attributes_revert ();
1015 response
= gtk_dialog_run (GTK_DIALOG (attributes_dialog
));
1017 if (response
== GTK_RESPONSE_CANCEL
)
1020 if (response
== GTK_RESPONSE_OK
)
1023 /* Copy the values back */
1024 for (i
=0; i
<attributes_list
->Number
; i
++)
1026 if (attributes_list
->List
[i
].name
)
1027 free (attributes_list
->List
[i
].name
);
1028 if (attributes_list
->List
[i
].value
)
1029 free (attributes_list
->List
[i
].value
);
1031 if (attributes_list
->Max
< attr_num_rows
)
1033 int sz
= attr_num_rows
* sizeof (AttributeType
);
1034 if (attributes_list
->List
== NULL
)
1035 attributes_list
->List
= (AttributeType
*) malloc (sz
);
1037 attributes_list
->List
= (AttributeType
*) realloc (attributes_list
->List
, sz
);
1038 attributes_list
->Max
= attr_num_rows
;
1040 for (i
=0; i
<attr_num_rows
; i
++)
1042 attributes_list
->List
[i
].name
= strdup (gtk_entry_get_text (GTK_ENTRY (attr_row
[i
].w_name
)));
1043 attributes_list
->List
[i
].value
= strdup (gtk_entry_get_text (GTK_ENTRY (attr_row
[i
].w_value
)));
1044 attributes_list
->Number
= attr_num_rows
;
1050 if (response
== GA_RESPONSE_REVERT
)
1053 ghid_attributes_revert ();
1056 if (response
== GA_RESPONSE_NEW
)
1058 ghid_attributes_need_rows (attr_num_rows
+ 1); /* also bumps attr_num_rows */
1060 gtk_entry_set_text (GTK_ENTRY (attr_row
[attr_num_rows
-1].w_name
), "");
1061 gtk_entry_set_text (GTK_ENTRY (attr_row
[attr_num_rows
-1].w_value
), "");
1063 ghid_attr_set_table_size ();
1067 gtk_widget_destroy (attributes_dialog
);
1072 /* ---------------------------------------------------------------------- */
1074 HID_DRC_GUI ghid_drc_gui
= {
1075 1, /* log_drc_overview */
1076 0, /* log_drc_details */
1077 ghid_drc_window_reset_message
,
1078 ghid_drc_window_append_violation
,
1079 ghid_drc_window_throw_dialog
,
1082 extern HID_Attribute
*ghid_get_export_options (int *);
1085 /* ------------------------------------------------------------
1087 * Actions specific to the GTK HID follow from here
1092 /* ------------------------------------------------------------ */
1093 static const char about_syntax
[] =
1096 static const char about_help
[] =
1097 N_("Tell the user about this version of PCB.");
1099 /* %start-doc actions About
1101 This just pops up a dialog telling the user which version of
1102 @code{pcb} they're running.
1108 About (int argc
, char **argv
, Coord x
, Coord y
)
1110 ghid_dialog_about ();
1114 /* ------------------------------------------------------------ */
1115 static const char getxy_syntax
[] =
1118 static const char getxy_help
[] =
1119 N_("Get a coordinate.");
1121 /* %start-doc actions GetXY
1123 Prompts the user for a coordinate, if one is not already selected.
1128 GetXY (int argc
, char **argv
, Coord x
, Coord y
)
1133 /* ---------------------------------------------------------------------- */
1135 static int PointCursor (int argc
, char **argv
, Coord x
, Coord y
)
1141 ghid_point_cursor ();
1143 ghid_mode_cursor (Settings
.Mode
);
1147 /* ---------------------------------------------------------------------- */
1150 RouteStylesChanged (int argc
, char **argv
, Coord x
, Coord y
)
1152 if (!ghidgui
|| !ghidgui
->route_style_selector
)
1155 ghid_route_style_selector_sync
1156 (GHID_ROUTE_STYLE_SELECTOR (ghidgui
->route_style_selector
),
1157 Settings
.LineThickness
, Settings
.ViaDrillingHole
,
1158 Settings
.ViaThickness
, Settings
.Keepaway
);
1163 /* ---------------------------------------------------------------------- */
1166 PCBChanged (int argc
, char **argv
, Coord x
, Coord y
)
1171 ghid_window_set_name_label (PCB
->Name
);
1176 if (ghidgui
->route_style_selector
)
1178 ghid_route_style_selector_empty
1179 (GHID_ROUTE_STYLE_SELECTOR (ghidgui
->route_style_selector
));
1180 make_route_style_buttons
1181 (GHID_ROUTE_STYLE_SELECTOR (ghidgui
->route_style_selector
));
1183 RouteStylesChanged (0, NULL
, 0, 0);
1185 ghid_port_ranges_scale ();
1186 ghid_zoom_view_fit ();
1187 ghid_sync_with_new_layout ();
1191 /* ---------------------------------------------------------------------- */
1194 LayerGroupsChanged (int argc
, char **argv
, Coord x
, Coord y
)
1196 printf (_("LayerGroupsChanged -- not implemented\n"));
1200 /* ---------------------------------------------------------------------- */
1203 LibraryChanged (int argc
, char **argv
, Coord x
, Coord y
)
1205 /* No need to show the library window every time it changes...
1206 * ghid_library_window_show (&ghid_port, FALSE);
1211 /* ---------------------------------------------------------------------- */
1214 Command (int argc
, char **argv
, Coord x
, Coord y
)
1216 ghid_handle_user_command (TRUE
);
1220 /* ---------------------------------------------------------------------- */
1223 Load (int argc
, char **argv
, Coord x
, Coord y
)
1228 static gchar
*current_element_dir
= NULL
;
1229 static gchar
*current_layout_dir
= NULL
;
1230 static gchar
*current_netlist_dir
= NULL
;
1232 /* we've been given the file name */
1234 return hid_actionv ("LoadFrom", argc
, argv
);
1236 function
= argc
? argv
[0] : (char *)"Layout";
1238 if (strcasecmp (function
, "Netlist") == 0)
1240 name
= ghid_dialog_file_select_open (_("Load netlist file"),
1241 ¤t_netlist_dir
,
1244 else if (strcasecmp (function
, "ElementToBuffer") == 0)
1246 name
= ghid_dialog_file_select_open (_("Load element to buffer"),
1247 ¤t_element_dir
,
1248 Settings
.LibraryTree
);
1250 else if (strcasecmp (function
, "LayoutToBuffer") == 0)
1252 name
= ghid_dialog_file_select_open (_("Load layout file to buffer"),
1253 ¤t_layout_dir
,
1256 else if (strcasecmp (function
, "Layout") == 0)
1258 name
= ghid_dialog_file_select_open (_("Load layout file"),
1259 ¤t_layout_dir
,
1265 if (Settings
.verbose
)
1266 fprintf (stderr
, "%s: Calling LoadFrom(%s, %s)\n", __FUNCTION__
,
1268 hid_actionl ("LoadFrom", function
, name
, NULL
);
1276 /* ---------------------------------------------------------------------- */
1277 static const char save_syntax
[] =
1279 "Save(Layout|LayoutAs)\n"
1280 "Save(AllConnections|AllUnusedPins|ElementConnections)\n"
1281 "Save(PasteBuffer)";
1283 static const char save_help
[] =
1284 N_("Save layout and/or element data to a user-selected file.");
1286 /* %start-doc actions Save
1288 This action is a GUI front-end to the core's @code{SaveTo} action
1289 (@pxref{SaveTo Action}). If you happen to pass a filename, like
1290 @code{SaveTo}, then @code{SaveTo} is called directly. Else, the
1291 user is prompted for a filename to save, and then @code{SaveTo} is
1292 called with that filename.
1297 Save (int argc
, char **argv
, Coord x
, Coord y
)
1303 static gchar
*current_dir
= NULL
;
1306 return hid_actionv ("SaveTo", argc
, argv
);
1308 function
= argc
? argv
[0] : (char *)"Layout";
1310 if (strcasecmp (function
, "Layout") == 0)
1312 return hid_actionl ("SaveTo", "Layout", PCB
->Filename
, NULL
);
1314 if (strcasecmp (function
, "PasteBuffer") == 0)
1315 prompt
= _("Save element as");
1317 prompt
= _("Save layout as");
1319 name
= ghid_dialog_file_select_save (prompt
,
1321 PCB
->Filename
, Settings
.FilePath
);
1325 if (Settings
.verbose
)
1326 fprintf (stderr
, "%s: Calling SaveTo(%s, %s)\n",
1327 __FUNCTION__
, function
, name
);
1329 if (strcasecmp (function
, "PasteBuffer") == 0)
1330 hid_actionl ("PasteBuffer", "Save", name
, NULL
);
1334 * if we got this far and the function is Layout, then
1335 * we really needed it to be a LayoutAs. Otherwise
1336 * ActionSaveTo() will ignore the new file name we
1339 if (strcasecmp (function
, "Layout") == 0)
1340 hid_actionl ("SaveTo", "LayoutAs", name
, NULL
);
1342 hid_actionl ("SaveTo", function
, name
, NULL
);
1354 /* ---------------------------------------------------------------------- */
1355 static const char swapsides_syntax
[] =
1356 "SwapSides(|v|h|r)";
1358 static const char swapsides_help
[] =
1359 N_("Swaps the side of the board you're looking at.");
1361 /* %start-doc actions SwapSides
1363 This action changes the way you view the board.
1368 Flips the board over vertically (up/down).
1371 Flips the board over horizontally (left/right), like flipping pages in
1375 Rotates the board 180 degrees without changing sides.
1379 If no argument is given, the board isn't moved but the opposite side
1382 Normally, this action changes which pads and silk layer are drawn as
1383 true silk, and which are drawn as the "invisible" layer. It also
1384 determines which solder mask you see.
1386 As a special case, if the layer group for the side you're looking at
1387 is visible and currently active, and the layer group for the opposite
1388 is not visible (i.e. disabled), then this action will also swap which
1389 layer group is visible and active, effectively swapping the ``working
1390 side'' of the board.
1396 SwapSides (int argc
, char **argv
, Coord x
, Coord y
)
1398 int active_group
= GetLayerGroupNumberByNumber (LayerStack
[0]);
1399 int comp_group
= GetLayerGroupNumberByNumber (component_silk_layer
);
1400 int solder_group
= GetLayerGroupNumberByNumber (solder_silk_layer
);
1401 bool comp_on
= LAYER_PTR (PCB
->LayerGroups
.Entries
[comp_group
][0])->On
;
1402 bool solder_on
= LAYER_PTR (PCB
->LayerGroups
.Entries
[solder_group
][0])->On
;
1406 switch (argv
[0][0]) {
1409 ghid_flip_view (gport
->pcb_x
, gport
->pcb_y
, true, false);
1413 ghid_flip_view (gport
->pcb_x
, gport
->pcb_y
, false, true);
1417 ghid_flip_view (gport
->pcb_x
, gport
->pcb_y
, true, true);
1418 Settings
.ShowSolderSide
= !Settings
.ShowSolderSide
; /* Swapped back below */
1425 Settings
.ShowSolderSide
= !Settings
.ShowSolderSide
;
1427 if ((active_group
== comp_group
&& comp_on
&& !solder_on
) ||
1428 (active_group
== solder_group
&& solder_on
&& !comp_on
))
1430 bool new_solder_vis
= Settings
.ShowSolderSide
;
1432 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[comp_group
][0],
1433 !new_solder_vis
, !new_solder_vis
);
1434 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[solder_group
][0],
1435 new_solder_vis
, new_solder_vis
);
1441 /* ------------------------------------------------------------ */
1443 static const char print_syntax
[] =
1446 static const char print_help
[] =
1447 N_("Print the layout.");
1449 /* %start-doc actions Print
1451 This will find the default printing HID, prompt the user for its
1452 options, and print the layout.
1457 Print (int argc
, char **argv
, Coord x
, Coord y
)
1461 HID
*printer
= NULL
;
1463 hids
= hid_enumerate ();
1464 for (i
= 0; hids
[i
]; i
++)
1466 if (hids
[i
]->printer
)
1470 if (printer
== NULL
)
1472 gui
->log (_("Can't find a suitable printer HID"));
1476 /* check if layout is empty */
1477 if (!IsDataEmpty (PCB
->Data
))
1479 ghid_dialog_print (printer
);
1482 gui
->log (_("Can't print empty layout"));
1488 /* ------------------------------------------------------------ */
1490 static HID_Attribute
1491 printer_calibrate_attrs
[] = {
1492 {N_("Enter Values here:"), "",
1493 HID_Label
, 0, 0, {0, 0, 0}, 0, 0},
1494 {N_("x-calibration"), N_("X scale for calibrating your printer"),
1495 HID_Real
, 0.5, 25, {0, 0, 1.00}, 0, 0},
1496 {N_("y-calibration"), N_("Y scale for calibrating your printer"),
1497 HID_Real
, 0.5, 25, {0, 0, 1.00}, 0, 0}
1499 static HID_Attr_Val printer_calibrate_values
[3];
1501 static const char printcalibrate_syntax
[] =
1504 static const char printcalibrate_help
[] =
1505 N_("Calibrate the printer.");
1507 /* %start-doc actions PrintCalibrate
1509 This will print a calibration page, which you would measure and type
1510 the measurements in, so that future printouts will be more precise.
1515 PrintCalibrate (int argc
, char **argv
, Coord x
, Coord y
)
1517 HID
*printer
= hid_find_printer ();
1518 printer
->calibrate (0.0, 0.0);
1520 if (gui
->attribute_dialog (printer_calibrate_attrs
, 3,
1521 printer_calibrate_values
,
1522 _("Printer Calibration Values"),
1523 _("Enter calibration values for your printer")))
1525 printer
->calibrate (printer_calibrate_values
[1].real_value
,
1526 printer_calibrate_values
[2].real_value
);
1530 /* ------------------------------------------------------------ */
1533 Export (int argc
, char **argv
, Coord x
, Coord y
)
1536 /* check if layout is empty */
1537 if (!IsDataEmpty (PCB
->Data
))
1539 ghid_dialog_export ();
1542 gui
->log (_("Can't export empty layout"));
1547 /* ------------------------------------------------------------ */
1550 Benchmark (int argc
, char **argv
, Coord x
, Coord y
)
1554 GdkDisplay
*display
;
1556 display
= gdk_drawable_get_display (gport
->drawable
);
1558 gdk_display_sync (display
);
1562 ghid_invalidate_all ();
1563 gdk_window_process_updates (gtk_widget_get_window (gport
->drawing_area
),
1568 while (end
- start
< 10);
1570 printf (_("%g redraws per second\n"), i
/ 10.0);
1575 /* ------------------------------------------------------------ */
1577 static const char center_syntax
[] =
1580 static const char center_help
[] =
1581 N_("Moves the pointer to the center of the window.");
1583 /* %start-doc actions Center
1585 Move the pointer to the center of the window, but only if it's
1586 currently within the window already.
1591 Center(int argc
, char **argv
, Coord pcb_x
, Coord pcb_y
)
1593 GdkDisplay
*display
;
1595 int offset_x
, offset_y
;
1596 int widget_x
, widget_y
;
1597 int pointer_x
, pointer_y
;
1602 /* Aim to put the given x, y PCB coordinates in the center of the widget */
1603 widget_x
= gport
->width
/ 2;
1604 widget_y
= gport
->height
/ 2;
1606 ghid_pan_view_abs (pcb_x
, pcb_y
, widget_x
, widget_y
);
1608 /* Now move the mouse pointer to the place where the board location
1609 * actually ended up.
1611 * XXX: Should only do this if we confirm we are inside our window?
1614 ghid_pcb_to_event_coords (pcb_x
, pcb_y
, &widget_x
, &widget_y
);
1615 gdk_window_get_origin (gtk_widget_get_window (gport
->drawing_area
),
1616 &offset_x
, &offset_y
);
1618 pointer_x
= offset_x
+ widget_x
;
1619 pointer_y
= offset_y
+ widget_y
;
1621 display
= gdk_display_get_default ();
1622 screen
= gdk_display_get_default_screen (display
);
1623 gdk_display_warp_pointer (display
, screen
, pointer_x
, pointer_y
);
1628 /* ------------------------------------------------------------ */
1629 static const char cursor_syntax
[] =
1630 "Cursor(Type,DeltaUp,DeltaRight,Units)";
1632 static const char cursor_help
[] =
1633 N_("Move the cursor.");
1635 /* %start-doc actions Cursor
1637 This action moves the mouse cursor. Unlike other actions which take
1638 coordinates, this action's coordinates are always relative to the
1639 user's view of the board. Thus, a positive @var{DeltaUp} may move the
1640 cursor towards the board origin if the board is inverted.
1642 Type is one of @samp{Pan} or @samp{Warp}. @samp{Pan} causes the
1643 viewport to move such that the crosshair is under the mouse cursor.
1644 @samp{Warp} causes the mouse cursor to move to be above the crosshair.
1646 @var{Units} can be one of the following:
1652 The cursor is moved by that amount, in board units.
1655 The cursor is moved by that many grid points.
1658 The values are percentages of the viewport's view. Thus, a pan of
1659 @samp{100} would scroll the viewport by exactly the width of the
1663 The values are percentages of the board size. Thus, a move of
1664 @samp{50,50} moves you halfway across the board.
1671 CursorAction(int argc
, char **argv
, Coord x
, Coord y
)
1673 UnitList extra_units_x
= {
1674 { "grid", PCB
->Grid
, 0 },
1675 { "view", gport
->view
.width
, UNIT_PERCENT
},
1676 { "board", PCB
->MaxWidth
, UNIT_PERCENT
},
1679 UnitList extra_units_y
= {
1680 { "grid", PCB
->Grid
, 0 },
1681 { "view", gport
->view
.height
, UNIT_PERCENT
},
1682 { "board", PCB
->MaxHeight
, UNIT_PERCENT
},
1685 int pan_warp
= HID_SC_DO_NOTHING
;
1691 if (strcasecmp (argv
[0], "pan") == 0)
1692 pan_warp
= HID_SC_PAN_VIEWPORT
;
1693 else if (strcasecmp (argv
[0], "warp") == 0)
1694 pan_warp
= HID_SC_WARP_POINTER
;
1698 dx
= GetValueEx (argv
[1], argv
[3], NULL
, extra_units_x
, "");
1699 if (gport
->view
.flip_x
)
1701 dy
= GetValueEx (argv
[2], argv
[3], NULL
, extra_units_y
, "");
1702 if (!gport
->view
.flip_y
)
1705 EventMoveCrosshair (Crosshair
.X
+ dx
, Crosshair
.Y
+ dy
);
1706 gui
->set_crosshair (Crosshair
.X
, Crosshair
.Y
, pan_warp
);
1710 /* ------------------------------------------------------------ */
1712 static const char dowindows_syntax
[] =
1713 "DoWindows(1|2|3|4|5|6)\n"
1714 "DoWindows(Layout|Library|Log|Netlist|Preferences|DRC)";
1716 static const char dowindows_help
[] =
1717 N_("Open various GUI windows.");
1719 /* %start-doc actions DoWindows
1725 Open the layout window. Since the layout window is always shown
1726 anyway, this has no effect.
1730 Open the library window.
1734 Open the log window.
1738 Open the netlist window.
1742 Open the preferences window.
1746 Open the DRC violations window.
1753 DoWindows (int argc
, char **argv
, Coord x
, Coord y
)
1755 char *a
= argc
== 1 ? argv
[0] : (char *)"";
1757 if (strcmp (a
, "1") == 0 || strcasecmp (a
, "Layout") == 0)
1760 else if (strcmp (a
, "2") == 0 || strcasecmp (a
, "Library") == 0)
1762 ghid_library_window_show (gport
, TRUE
);
1764 else if (strcmp (a
, "3") == 0 || strcasecmp (a
, "Log") == 0)
1766 ghid_log_window_show (TRUE
);
1768 else if (strcmp (a
, "4") == 0 || strcasecmp (a
, "Netlist") == 0)
1770 ghid_netlist_window_show (gport
, TRUE
);
1772 else if (strcmp (a
, "5") == 0 || strcasecmp (a
, "Preferences") == 0)
1774 ghid_config_window_show ();
1776 else if (strcmp (a
, "6") == 0 || strcasecmp (a
, "DRC") == 0)
1778 ghid_drc_window_show (TRUE
);
1788 /* ------------------------------------------------------------ */
1789 static const char setunits_syntax
[] =
1792 static const char setunits_help
[] =
1793 N_("Set the default measurement units.");
1795 /* %start-doc actions SetUnits
1800 Sets the display units to mils (1/1000 inch).
1803 Sets the display units to millimeters.
1810 SetUnits (int argc
, char **argv
, Coord x
, Coord y
)
1812 const Unit
*new_unit
;
1816 new_unit
= get_unit_struct (argv
[0]);
1817 if (new_unit
!= NULL
&& new_unit
->allow
!= NO_PRINT
)
1819 Settings
.grid_unit
= new_unit
;
1820 Settings
.increments
= get_increments_struct (Settings
.grid_unit
->suffix
);
1821 AttributePut (PCB
, "PCB::grid::unit", argv
[0]);
1824 ghid_config_handle_units_changed ();
1826 ghid_set_status_line_label ();
1829 * lesstif_sizes_reset ();
1830 * lesstif_styles_update_values ();
1835 /* ------------------------------------------------------------ */
1836 static const char scroll_syntax
[] =
1837 "Scroll(up|down|left|right, [div])";
1839 static const char scroll_help
[] =
1840 N_("Scroll the viewport.");
1842 /* % start-doc actions Scroll
1844 @item up|down|left|right
1845 Specifies the direction to scroll
1848 Optional. Specifies how much to scroll by. The viewport is scrolled
1849 by 1/div of what is visible, so div = 1 scrolls a whole page. If not
1850 default is given, div=40.
1855 ScrollAction (int argc
, char **argv
, Coord x
, Coord y
)
1857 gdouble dx
= 0.0, dy
= 0.0;
1863 if (argc
!= 1 && argc
!= 2)
1867 div
= atoi(argv
[1]);
1869 if (strcasecmp (argv
[0], "up") == 0)
1870 dy
= -gport
->view
.height
/ div
;
1871 else if (strcasecmp (argv
[0], "down") == 0)
1872 dy
= gport
->view
.height
/ div
;
1873 else if (strcasecmp (argv
[0], "right") == 0)
1874 dx
= gport
->view
.width
/ div
;
1875 else if (strcasecmp (argv
[0], "left") == 0)
1876 dx
= -gport
->view
.width
/ div
;
1880 ghid_pan_view_rel (dx
, dy
);
1885 /* ------------------------------------------------------------ */
1886 static const char pan_syntax
[] =
1887 "Pan([thumb], Mode)";
1889 static const char pan_help
[] =
1890 N_("Start or stop panning (Mode = 1 to start, 0 to stop)\n"
1891 "Optional thumb argument is ignored for now in gtk hid.\n");
1893 /* %start-doc actions Pan
1895 Start or stop panning. To start call with Mode = 1, to stop call with
1896 Mode = 0. If the Mode is turned on and off with the cross hairs at
1897 the same coordinates, the auto pan mode is toggled.
1902 PanAction (int argc
, char **argv
, Coord x
, Coord y
)
1904 static int on_x
, on_y
;
1910 if (argc
!= 1 && argc
!= 2)
1914 mode
= atoi(argv
[0]);
1917 mode
= atoi(argv
[1]);
1918 Message (_("The gtk gui currently ignores the optional first argument "
1919 "to the Pan action.\nFeel free to provide patches.\n"));
1922 gport
->panning
= mode
;
1929 else if (x
== on_x
&& y
== on_y
)
1931 notify_crosshair_change (false);
1932 ghidgui
->auto_pan_on
= !ghidgui
->auto_pan_on
;
1933 notify_crosshair_change (true);
1939 /* ------------------------------------------------------------ */
1940 static const char popup_syntax
[] =
1941 "Popup(MenuName, [Button])";
1943 static const char popup_help
[] =
1944 N_("Bring up the popup menu specified by @code{MenuName}.\n"
1945 "If called by a mouse event then the mouse button number\n"
1946 "must be specified as the optional second argument.");
1948 /* %start-doc actions Popup
1950 This just pops up the specified menu. The menu must have been defined
1951 as a named subresource of the Popups resource in the menu resource
1958 Popup (int argc
, char **argv
, Coord x
, Coord y
)
1962 if (argc
!= 1 && argc
!= 2)
1965 menu
= ghid_main_menu_get_popup (GHID_MAIN_MENU (ghidgui
->menu_bar
), argv
[0]);
1966 if (! GTK_IS_MENU (menu
))
1968 Message (_("The specified popup menu \"%s\" has not been defined.\n"), argv
[0]);
1973 ghidgui
->in_popup
= TRUE
;
1974 gtk_widget_grab_focus (ghid_port
.drawing_area
);
1975 gtk_menu_popup (menu
, NULL
, NULL
, NULL
, NULL
, 0,
1976 gtk_get_current_event_time());
1980 /* ------------------------------------------------------------ */
1981 static const char importgui_syntax
[] =
1984 static const char importgui_help
[] =
1985 N_("Asks user which schematics to import into PCB.\n");
1987 /* %start-doc actions ImportGUI
1989 Asks user which schematics to import into PCB.
1995 ImportGUI (int argc
, char **argv
, Coord x
, Coord y
)
1998 static gchar
*current_layout_dir
= NULL
;
1999 static int I_am_recursing
= 0;
2006 name
= ghid_dialog_file_select_open (_("Load schematics"),
2007 ¤t_layout_dir
,
2011 printf("File selected = %s\n", name
);
2014 AttributePut (PCB
, "import::src0", name
);
2018 rv
= hid_action ("Import");
2024 /* ------------------------------------------------------------ */
2026 Busy (int argc
, char **argv
, Coord x
, Coord y
)
2028 ghid_watch_cursor ();
2032 HID_Action ghid_main_action_list
[] = {
2033 {"About", 0, About
, about_help
, about_syntax
},
2034 {"Benchmark", 0, Benchmark
},
2036 {"Center", N_("Click on a location to center"), Center
, center_help
, center_syntax
},
2037 {"Command", 0, Command
},
2038 {"Cursor", 0, CursorAction
, cursor_help
, cursor_syntax
},
2039 {"DoWindows", 0, DoWindows
, dowindows_help
, dowindows_syntax
},
2040 {"Export", 0, Export
},
2041 {"GetXY", "", GetXY
, getxy_help
, getxy_syntax
},
2042 {"ImportGUI", 0, ImportGUI
, importgui_help
, importgui_syntax
},
2043 {"LayerGroupsChanged", 0, LayerGroupsChanged
},
2044 {"LibraryChanged", 0, LibraryChanged
},
2046 {"Pan", N_("Click on a place to pan"), PanAction
, pan_help
, pan_syntax
},
2047 {"PCBChanged", 0, PCBChanged
},
2048 {"PointCursor", 0, PointCursor
},
2049 {"Popup", 0, Popup
, popup_help
, popup_syntax
},
2051 print_help
, print_syntax
},
2052 {"PrintCalibrate", 0, PrintCalibrate
,
2053 printcalibrate_help
, printcalibrate_syntax
},
2054 {"RouteStylesChanged", 0, RouteStylesChanged
},
2055 {"Save", 0, Save
, save_help
, save_syntax
},
2056 {"Scroll", N_("Click on a place to scroll"), ScrollAction
, scroll_help
, scroll_syntax
},
2057 {"SetUnits", 0, SetUnits
, setunits_help
, setunits_syntax
},
2058 {"SwapSides", 0, SwapSides
, swapsides_help
, swapsides_syntax
},
2059 {"Zoom", N_("Click on zoom focus"), Zoom
, zoom_help
, zoom_syntax
}
2062 REGISTER_ACTIONS (ghid_main_action_list
)
2068 return gport
->view
.flip_x
;
2074 return gport
->view
.flip_y
;
2077 HID_Flag ghid_main_flag_list
[] = {
2078 {"flip_x", flag_flipx
, 0},
2079 {"flip_y", flag_flipy
, 0}
2082 REGISTER_FLAGS (ghid_main_flag_list
)
2084 #include "dolists.h"
2087 * We will need these for finding the windows installation
2088 * directory. Without that we can't find our fonts and
2089 * footprint libraries.
2092 #include <windows.h>
2107 tmps
= g_win32_get_package_installation_directory (PACKAGE
"-" VERSION
, NULL
);
2108 #define REST_OF_PATH G_DIR_SEPARATOR_S "share" G_DIR_SEPARATOR_S PACKAGE
2109 share_dir
= (char *) malloc(strlen(tmps
) +
2110 strlen(REST_OF_PATH
) +
2112 sprintf (share_dir
, "%s%s", tmps
, REST_OF_PATH
);
2115 printf ("\"Share\" installation path is \"%s\"\n", share_dir
);
2118 memset (&ghid_hid
, 0, sizeof (HID
));
2120 common_nogui_init (&ghid_hid
);
2121 common_draw_helpers_init (&ghid_hid
);
2123 ghid_hid
.struct_size
= sizeof (HID
);
2124 ghid_hid
.name
= "gtk";
2125 ghid_hid
.description
= "Gtk - The Gimp Toolkit";
2127 ghid_hid
.poly_after
= 1;
2129 ghid_hid
.get_export_options
= ghid_get_export_options
;
2130 ghid_hid
.do_export
= ghid_do_export
;
2131 ghid_hid
.parse_arguments
= ghid_parse_arguments
;
2132 ghid_hid
.invalidate_lr
= ghid_invalidate_lr
;
2133 ghid_hid
.invalidate_all
= ghid_invalidate_all
;
2134 ghid_hid
.notify_crosshair_change
= ghid_notify_crosshair_change
;
2135 ghid_hid
.notify_mark_change
= ghid_notify_mark_change
;
2136 ghid_hid
.set_layer
= ghid_set_layer
;
2137 ghid_hid
.make_gc
= ghid_make_gc
;
2138 ghid_hid
.destroy_gc
= ghid_destroy_gc
;
2139 ghid_hid
.use_mask
= ghid_use_mask
;
2140 ghid_hid
.set_color
= ghid_set_color
;
2141 ghid_hid
.set_line_cap
= ghid_set_line_cap
;
2142 ghid_hid
.set_line_width
= ghid_set_line_width
;
2143 ghid_hid
.set_draw_xor
= ghid_set_draw_xor
;
2144 ghid_hid
.draw_line
= ghid_draw_line
;
2145 ghid_hid
.draw_arc
= ghid_draw_arc
;
2146 ghid_hid
.draw_rect
= ghid_draw_rect
;
2147 ghid_hid
.fill_circle
= ghid_fill_circle
;
2148 ghid_hid
.fill_polygon
= ghid_fill_polygon
;
2149 ghid_hid
.fill_rect
= ghid_fill_rect
;
2151 ghid_hid
.calibrate
= ghid_calibrate
;
2152 ghid_hid
.shift_is_pressed
= ghid_shift_is_pressed
;
2153 ghid_hid
.control_is_pressed
= ghid_control_is_pressed
;
2154 ghid_hid
.mod1_is_pressed
= ghid_mod1_is_pressed
,
2155 ghid_hid
.get_coords
= ghid_get_coords
;
2156 ghid_hid
.set_crosshair
= ghid_set_crosshair
;
2157 ghid_hid
.add_timer
= ghid_add_timer
;
2158 ghid_hid
.stop_timer
= ghid_stop_timer
;
2159 ghid_hid
.watch_file
= ghid_watch_file
;
2160 ghid_hid
.unwatch_file
= ghid_unwatch_file
;
2161 ghid_hid
.add_block_hook
= ghid_add_block_hook
;
2162 ghid_hid
.stop_block_hook
= ghid_stop_block_hook
;
2164 ghid_hid
.log
= ghid_log
;
2165 ghid_hid
.logv
= ghid_logv
;
2166 ghid_hid
.confirm_dialog
= ghid_confirm_dialog
;
2167 ghid_hid
.close_confirm_dialog
= ghid_close_confirm_dialog
;
2168 ghid_hid
.report_dialog
= ghid_report_dialog
;
2169 ghid_hid
.prompt_for
= ghid_prompt_for
;
2170 ghid_hid
.fileselect
= ghid_fileselect
;
2171 ghid_hid
.attribute_dialog
= ghid_attribute_dialog
;
2172 ghid_hid
.show_item
= ghid_show_item
;
2173 ghid_hid
.beep
= ghid_beep
;
2174 ghid_hid
.progress
= ghid_progress
;
2175 ghid_hid
.drc_gui
= &ghid_drc_gui
,
2176 ghid_hid
.edit_attributes
= ghid_attributes
;
2178 ghid_hid
.request_debug_draw
= ghid_request_debug_draw
;
2179 ghid_hid
.flush_debug_draw
= ghid_flush_debug_draw
;
2180 ghid_hid
.finish_debug_draw
= ghid_finish_debug_draw
;
2182 ghid_hid
.notify_save_pcb
= ghid_notify_save_pcb
;
2183 ghid_hid
.notify_filename_changed
= ghid_notify_filename_changed
;
2185 hid_register_hid (&ghid_hid
);
2186 #include "gtk_lists.h"