15 #include "crosshair.h"
17 #include "../hidint.h"
19 #include "hid/common/hidnogui.h"
20 #include "hid/common/draw_helpers.h"
21 #include "pcb-printf.h"
23 #ifdef HAVE_LIBDMALLOC
28 pan_common (GHidPort
*port
)
32 /* We need to fix up the PCB coordinates corresponding to the last
33 * event so convert it back to event coordinates temporarily. */
34 ghid_pcb_to_event_coords (gport
->pcb_x
, gport
->pcb_y
, &event_x
, &event_y
);
36 /* Don't pan so far the board is completely off the screen */
37 port
->view
.x0
= MAX (-port
->view
.width
, port
->view
.x0
);
38 port
->view
.y0
= MAX (-port
->view
.height
, port
->view
.y0
);
39 port
->view
.x0
= MIN ( port
->view
.x0
, PCB
->MaxWidth
);
40 port
->view
.y0
= MIN ( port
->view
.y0
, PCB
->MaxHeight
);
42 /* Fix up noted event coordinates to match where we clamped. Alternatively
43 * we could call ghid_note_event_location (NULL); to get a new pointer
44 * location, but this costs us an xserver round-trip (on X11 platforms)
46 ghid_event_to_pcb_coords (event_x
, event_y
, &gport
->pcb_x
, &gport
->pcb_y
);
48 ghidgui
->adjustment_changed_holdoff
= TRUE
;
49 gtk_range_set_value (GTK_RANGE (ghidgui
->h_range
), gport
->view
.x0
);
50 gtk_range_set_value (GTK_RANGE (ghidgui
->v_range
), gport
->view
.y0
);
51 ghidgui
->adjustment_changed_holdoff
= FALSE
;
53 ghid_port_ranges_changed();
57 ghid_pan_view_abs (Coord pcb_x
, Coord pcb_y
, int widget_x
, int widget_y
)
59 gport
->view
.x0
= SIDE_X (pcb_x
) - widget_x
* gport
->view
.coord_per_px
;
60 gport
->view
.y0
= SIDE_Y (pcb_y
) - widget_y
* gport
->view
.coord_per_px
;
66 ghid_pan_view_rel (Coord dx
, Coord dy
)
75 /* gport->view.coord_per_px:
76 * zoom value is PCB units per screen pixel. Larger numbers mean zooming
77 * out - the largest value means you are looking at the whole board.
79 * gport->view_width and gport->view_height are in PCB coordinates
82 #define ALLOW_ZOOM_OUT_BY 10 /* Arbitrary, and same as the lesstif HID */
84 ghid_zoom_view_abs (Coord center_x
, Coord center_y
, double new_zoom
)
86 double min_zoom
, max_zoom
;
89 /* Limit the "minimum" zoom constant (maximum zoom), at 1 pixel per PCB
90 * unit, and set the "maximum" zoom constant (minimum zoom), such that
91 * the entire board just fits inside the viewport
94 max_zoom
= MAX (PCB
->MaxWidth
/ gport
->width
,
95 PCB
->MaxHeight
/ gport
->height
) * ALLOW_ZOOM_OUT_BY
;
96 new_zoom
= MIN (MAX (min_zoom
, new_zoom
), max_zoom
);
98 if (gport
->view
.coord_per_px
== new_zoom
)
101 xtmp
= (SIDE_X (center_x
) - gport
->view
.x0
) / (double)gport
->view
.width
;
102 ytmp
= (SIDE_Y (center_y
) - gport
->view
.y0
) / (double)gport
->view
.height
;
104 gport
->view
.coord_per_px
= new_zoom
;
105 pixel_slop
= new_zoom
;
106 ghid_port_ranges_scale ();
108 gport
->view
.x0
= SIDE_X (center_x
) - xtmp
* gport
->view
.width
;
109 gport
->view
.y0
= SIDE_Y (center_y
) - ytmp
* gport
->view
.height
;
113 ghid_set_status_line_label ();
117 ghid_zoom_view_rel (Coord center_x
, Coord center_y
, double factor
)
119 ghid_zoom_view_abs (center_x
, center_y
, gport
->view
.coord_per_px
* factor
);
123 ghid_zoom_view_fit (void)
125 ghid_pan_view_abs (SIDE_X (0), SIDE_Y (0), 0, 0);
126 ghid_zoom_view_abs (SIDE_X (0), SIDE_Y (0),
127 MAX (PCB
->MaxWidth
/ gport
->width
,
128 PCB
->MaxHeight
/ gport
->height
));
132 ghid_flip_view (Coord center_x
, Coord center_y
, bool flip_x
, bool flip_y
)
134 int widget_x
, widget_y
;
136 /* Work out where on the screen the flip point is */
137 ghid_pcb_to_event_coords (center_x
, center_y
, &widget_x
, &widget_y
);
139 gport
->view
.flip_x
= gport
->view
.flip_x
!= flip_x
;
140 gport
->view
.flip_y
= gport
->view
.flip_y
!= flip_y
;
142 /* Pan the board so the center location remains in the same place */
143 ghid_pan_view_abs (center_x
, center_y
, widget_x
, widget_y
);
145 ghid_invalidate_all ();
148 /* ------------------------------------------------------------ */
150 static const char zoom_syntax
[] =
155 static const char zoom_help
[] =
156 N_("Various zoom factor changes.");
158 /* %start-doc actions Zoom
159 Changes the zoom (magnification) of the view of the board. If no
160 arguments are passed, the view is scaled such that the board just fits
161 inside the visible window (i.e. ``view all''). Otherwise,
162 @var{factor} specifies a change in zoom factor. It may be prefixed by
163 @code{+}, @code{-}, or @code{=} to change how the zoom factor is
164 modified. The @var{factor} is a floating point number, such as
165 @code{1.5} or @code{0.75}.
170 Values greater than 1.0 cause the board to be drawn smaller; more of
171 the board will be visible. Values between 0.0 and 1.0 cause the board
172 to be drawn bigger; less of the board will be visible.
175 Values greater than 1.0 cause the board to be drawn bigger; less of
176 the board will be visible. Values between 0.0 and 1.0 cause the board
177 to be drawn smaller; more of the board will be visible.
181 The @var{factor} is an absolute zoom factor; the unit for this value
182 is "PCB units per screen pixel". Since PCB units are 0.01 mil, a
183 @var{factor} of 1000 means 10 mils (0.01 in) per pixel, or 100 DPI,
184 about the actual resolution of most screens - resulting in an "actual
185 size" board. Similarly, a @var{factor} of 100 gives you a 10x actual
190 Note that zoom factors of zero are silently ignored.
197 Zoom (int argc
, char **argv
, Coord x
, Coord y
)
207 ghid_zoom_view_fit ();
212 if (*vp
== '+' || *vp
== '-' || *vp
== '=')
214 v
= g_ascii_strtod (vp
, 0);
220 ghid_zoom_view_rel (x
, y
, 1 / v
);
224 ghid_zoom_view_rel (x
, y
, v
);
227 ghid_zoom_view_abs (x
, y
, v
);
234 /* ------------------------------------------------------------ */
237 ghid_calibrate (double xval
, double yval
)
239 printf (_("ghid_calibrate() -- not implemented\n"));
243 ghid_notify_gui_is_up ()
249 ghid_shift_is_pressed ()
251 GdkModifierType mask
;
252 GHidPort
*out
= &ghid_port
;
257 gdk_window_get_pointer (gtk_widget_get_window (out
->drawing_area
),
259 return (mask
& GDK_SHIFT_MASK
) ? TRUE
: FALSE
;
263 ghid_control_is_pressed ()
265 GdkModifierType mask
;
266 GHidPort
*out
= &ghid_port
;
271 gdk_window_get_pointer (gtk_widget_get_window (out
->drawing_area
),
273 return (mask
& GDK_CONTROL_MASK
) ? TRUE
: FALSE
;
277 ghid_mod1_is_pressed ()
279 GdkModifierType mask
;
280 GHidPort
*out
= &ghid_port
;
285 gdk_window_get_pointer (gtk_widget_get_window (out
->drawing_area
),
288 return (mask
& ( 1 << 13 ) ) ? TRUE
: FALSE
; // The option key is not MOD1, although it should be...
290 return (mask
& GDK_MOD1_MASK
) ? TRUE
: FALSE
;
295 ghid_set_crosshair (int x
, int y
, int action
)
299 int offset_x
, offset_y
;
300 int widget_x
, widget_y
;
301 int pointer_x
, pointer_y
;
304 if (gport
->crosshair_x
!= x
|| gport
->crosshair_y
!= y
)
306 ghid_set_cursor_position_labels ();
307 gport
->crosshair_x
= x
;
308 gport
->crosshair_y
= y
;
310 /* FIXME - does this trigger the idle_proc stuff? It is in the
311 * lesstif HID. Maybe something is needed here?
317 if (action
!= HID_SC_PAN_VIEWPORT
&&
318 action
!= HID_SC_WARP_POINTER
)
321 /* Find out where the drawing area is on the screen. gdk_display_get_pointer
322 * and gdk_display_warp_pointer work relative to the whole display, whilst
323 * our coordinates are relative to the drawing area origin.
325 gdk_window_get_origin (gtk_widget_get_window (gport
->drawing_area
),
326 &offset_x
, &offset_y
);
327 display
= gdk_display_get_default ();
330 case HID_SC_PAN_VIEWPORT
:
331 /* Pan the board in the viewport so that the crosshair (who's location
332 * relative on the board was set above) lands where the pointer is.
333 * We pass the request to pan a particular point on the board to a
334 * given widget coordinate of the viewport into the rendering code
337 /* Find out where the pointer is relative to the display */
338 gdk_display_get_pointer (display
, NULL
, &pointer_x
, &pointer_y
, NULL
);
340 widget_x
= pointer_x
- offset_x
;
341 widget_y
= pointer_y
- offset_y
;
343 ghid_event_to_pcb_coords (widget_x
, widget_y
, &pcb_x
, &pcb_y
);
344 ghid_pan_view_abs (pcb_x
, pcb_y
, widget_x
, widget_y
);
346 /* Just in case we couldn't pan the board the whole way,
347 * we warp the pointer to where the crosshair DID land.
351 case HID_SC_WARP_POINTER
:
352 screen
= gdk_display_get_default_screen (display
);
354 ghid_pcb_to_event_coords (x
, y
, &widget_x
, &widget_y
);
356 pointer_x
= offset_x
+ widget_x
;
357 pointer_y
= offset_y
+ widget_y
;
359 gdk_display_warp_pointer (display
, screen
, pointer_x
, pointer_y
);
367 void (*func
) (hidval
);
373 /* We need a wrapper around the hid timer because a gtk timer needs
374 | to return FALSE else the timer will be restarted.
377 ghid_timer (GuiTimer
* timer
)
379 (*timer
->func
) (timer
->user_data
);
380 ghid_mode_cursor (Settings
.Mode
);
381 return FALSE
; /* Turns timer off */
385 ghid_add_timer (void (*func
) (hidval user_data
),
386 unsigned long milliseconds
, hidval user_data
)
388 GuiTimer
*timer
= g_new0 (GuiTimer
, 1);
392 timer
->user_data
= user_data
;
393 timer
->id
= g_timeout_add (milliseconds
, (GSourceFunc
) ghid_timer
, timer
);
394 ret
.ptr
= (void *) timer
;
399 ghid_stop_timer (hidval timer
)
401 void *ptr
= timer
.ptr
;
403 g_source_remove (((GuiTimer
*) ptr
)->id
);
409 void (*func
) ( hidval
, int, unsigned int, hidval
);
417 /* We need a wrapper around the hid file watch to pass the correct flags
420 ghid_watch (GIOChannel
*source
, GIOCondition condition
, gpointer data
)
422 unsigned int pcb_condition
= 0;
424 GuiWatch
*watch
= (GuiWatch
*)data
;
426 if (condition
& G_IO_IN
)
427 pcb_condition
|= PCB_WATCH_READABLE
;
428 if (condition
& G_IO_OUT
)
429 pcb_condition
|= PCB_WATCH_WRITABLE
;
430 if (condition
& G_IO_ERR
)
431 pcb_condition
|= PCB_WATCH_ERROR
;
432 if (condition
& G_IO_HUP
)
433 pcb_condition
|= PCB_WATCH_HANGUP
;
435 x
.ptr
= (void *) watch
;
436 watch
->func (x
, watch
->fd
, pcb_condition
, watch
->user_data
);
437 ghid_mode_cursor (Settings
.Mode
);
439 return TRUE
; /* Leave watch on */
443 ghid_watch_file (int fd
, unsigned int condition
, void (*func
) (hidval watch
, int fd
, unsigned int condition
, hidval user_data
),
446 GuiWatch
*watch
= g_new0 (GuiWatch
, 1);
448 unsigned int glib_condition
= 0;
450 if (condition
& PCB_WATCH_READABLE
)
451 glib_condition
|= G_IO_IN
;
452 if (condition
& PCB_WATCH_WRITABLE
)
453 glib_condition
|= G_IO_OUT
;
454 if (condition
& PCB_WATCH_ERROR
)
455 glib_condition
|= G_IO_ERR
;
456 if (condition
& PCB_WATCH_HANGUP
)
457 glib_condition
|= G_IO_HUP
;
460 watch
->user_data
= user_data
;
462 watch
->channel
= g_io_channel_unix_new( fd
);
463 watch
->id
= g_io_add_watch( watch
->channel
, (GIOCondition
)glib_condition
, ghid_watch
, watch
);
465 ret
.ptr
= (void *) watch
;
470 ghid_unwatch_file (hidval data
)
472 GuiWatch
*watch
= (GuiWatch
*)data
.ptr
;
474 g_io_channel_shutdown( watch
->channel
, TRUE
, NULL
);
475 g_io_channel_unref( watch
->channel
);
482 void (*func
) (hidval user_data
);
486 static gboolean
ghid_block_hook_prepare (GSource
*source
,
488 static gboolean
ghid_block_hook_check (GSource
*source
);
489 static gboolean
ghid_block_hook_dispatch (GSource
*source
,
490 GSourceFunc callback
,
493 static GSourceFuncs ghid_block_hook_funcs
= {
494 ghid_block_hook_prepare
,
495 ghid_block_hook_check
,
496 ghid_block_hook_dispatch
,
497 NULL
// No destroy notification
501 ghid_block_hook_prepare (GSource
*source
,
504 hidval data
= ((BlockHookSource
*)source
)->user_data
;
505 ((BlockHookSource
*)source
)->func( data
);
510 ghid_block_hook_check (GSource
*source
)
516 ghid_block_hook_dispatch (GSource
*source
,
517 GSourceFunc callback
,
524 ghid_add_block_hook (void (*func
) (hidval data
),
528 BlockHookSource
*source
;
530 source
= (BlockHookSource
*)g_source_new (&ghid_block_hook_funcs
, sizeof( BlockHookSource
));
533 source
->user_data
= user_data
;
535 g_source_attach ((GSource
*)source
, NULL
);
537 ret
.ptr
= (void *) source
;
542 ghid_stop_block_hook (hidval mlpoll
)
544 GSource
*source
= (GSource
*)mlpoll
.ptr
;
545 g_source_destroy( source
);
549 ghid_confirm_dialog (char *msg
, ...)
553 char *cancelmsg
= NULL
, *okmsg
= NULL
;
554 static gint x
= -1, y
= -1;
556 GHidPort
*out
= &ghid_port
;
559 cancelmsg
= va_arg (ap
, char *);
560 okmsg
= va_arg (ap
, char *);
565 cancelmsg
= _("_Cancel");
569 dialog
= gtk_message_dialog_new (GTK_WINDOW (out
->top_window
),
570 (GtkDialogFlags
) (GTK_DIALOG_MODAL
|
571 GTK_DIALOG_DESTROY_WITH_PARENT
),
572 GTK_MESSAGE_QUESTION
,
575 gtk_dialog_add_button (GTK_DIALOG (dialog
),
576 cancelmsg
, GTK_RESPONSE_CANCEL
);
579 gtk_dialog_add_button (GTK_DIALOG (dialog
),
580 okmsg
, GTK_RESPONSE_OK
);
584 gtk_window_move(GTK_WINDOW (dialog
), x
, y
);
587 if (gtk_dialog_run (GTK_DIALOG (dialog
)) == GTK_RESPONSE_OK
)
590 gtk_window_get_position(GTK_WINDOW (dialog
), &x
, &y
);
592 gtk_widget_destroy (dialog
);
597 ghid_close_confirm_dialog ()
599 switch (ghid_dialog_close_confirm ())
601 case GUI_DIALOG_CLOSE_CONFIRM_SAVE
:
603 if (hid_actionl ("Save", NULL
))
605 return 0; /* Cancel */
607 return 1; /* Close */
610 case GUI_DIALOG_CLOSE_CONFIRM_NOSAVE
:
612 return 1; /* Close */
614 case GUI_DIALOG_CLOSE_CONFIRM_CANCEL
:
617 return 0; /* Cancel */
623 ghid_report_dialog (char *title
, char *msg
)
625 ghid_dialog_report (title
, msg
);
629 ghid_prompt_for (const char *msg
, const char *default_string
)
633 rv
= ghid_dialog_input (msg
, default_string
);
637 /* FIXME -- implement a proper file select dialog */
640 ghid_fileselect (const char *title
, const char *descr
,
641 char *default_file
, char *default_ext
,
642 const char *history_tag
, int flags
)
646 rv
= ghid_dialog_input (title
, default_file
);
652 ghid_show_item (void *item
)
654 ghid_pinout_window_show (&ghid_port
, (ElementType
*) item
);
663 struct progress_dialog
674 gulong response_handler
;
675 gulong destroy_handler
;
676 gulong delete_handler
;
680 run_response_handler (GtkDialog
*dialog
,
684 struct progress_dialog
*pd
= data
;
686 pd
->response_id
= response_id
;
690 run_delete_handler (GtkDialog
*dialog
,
694 struct progress_dialog
*pd
= data
;
696 pd
->response_id
= GTK_RESPONSE_DELETE_EVENT
;
698 return TRUE
; /* Do not destroy */
702 run_destroy_handler (GtkDialog
*dialog
, gpointer data
)
704 struct progress_dialog
*pd
= data
;
706 pd
->destroyed
= TRUE
;
709 static struct progress_dialog
*
710 make_progress_dialog (void)
712 struct progress_dialog
*pd
;
713 GtkWidget
*content_area
;
714 GtkWidget
*alignment
;
717 pd
= g_new0 (struct progress_dialog
, 1);
718 pd
->response_id
= GTK_RESPONSE_NONE
;
720 pd
->dialog
= gtk_dialog_new_with_buttons (_("Progress"),
721 GTK_WINDOW (gport
->top_window
),
722 /* Modal so nothing else can get events whilst
723 the main mainloop isn't running */
724 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
,
729 gtk_window_set_deletable (GTK_WINDOW (pd
->dialog
), FALSE
);
730 gtk_window_set_skip_pager_hint (GTK_WINDOW (pd
->dialog
), TRUE
);
731 gtk_window_set_skip_taskbar_hint (GTK_WINDOW (pd
->dialog
), TRUE
);
732 gtk_widget_set_size_request (pd
->dialog
, 300, -1);
734 pd
->message
= gtk_label_new (NULL
);
735 gtk_misc_set_alignment (GTK_MISC (pd
->message
), 0., 0.);
737 pd
->progress
= gtk_progress_bar_new ();
738 gtk_widget_set_size_request (pd
->progress
, -1, 26);
740 vbox
= gtk_vbox_new (false, 0);
741 gtk_box_pack_start (GTK_BOX (vbox
), pd
->message
, true, true, 8);
742 gtk_box_pack_start (GTK_BOX (vbox
), pd
->progress
, false, true, 8);
744 alignment
= gtk_alignment_new (0., 0., 1., 1.);
745 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment
), 8, 8, 8, 8);
746 gtk_container_add (GTK_CONTAINER (alignment
), vbox
);
748 content_area
= gtk_dialog_get_content_area (GTK_DIALOG (pd
->dialog
));
749 gtk_box_pack_start (GTK_BOX (content_area
), alignment
, true, true, 0);
751 gtk_widget_show_all (alignment
);
753 g_object_ref (pd
->dialog
);
754 gtk_window_present (GTK_WINDOW (pd
->dialog
));
756 pd
->response_handler
=
757 g_signal_connect (pd
->dialog
, "response",
758 G_CALLBACK (run_response_handler
), pd
);
760 g_signal_connect (pd
->dialog
, "delete-event",
761 G_CALLBACK (run_delete_handler
), pd
);
762 pd
->destroy_handler
=
763 g_signal_connect (pd
->dialog
, "destroy",
764 G_CALLBACK (run_destroy_handler
), pd
);
766 pd
->loop
= g_main_loop_new (NULL
, FALSE
);
767 pd
->timer
= g_timer_new ();
773 destroy_progress_dialog (struct progress_dialog
*pd
)
780 g_signal_handler_disconnect (pd
->dialog
, pd
->response_handler
);
781 g_signal_handler_disconnect (pd
->dialog
, pd
->delete_handler
);
782 g_signal_handler_disconnect (pd
->dialog
, pd
->destroy_handler
);
785 g_timer_destroy (pd
->timer
);
786 g_object_unref (pd
->dialog
);
787 g_main_loop_unref (pd
->loop
);
789 gtk_widget_destroy (pd
->dialog
);
796 handle_progress_dialog_events (struct progress_dialog
*pd
)
798 GMainContext
* context
= g_main_loop_get_context (pd
->loop
);
801 while (g_main_context_pending (context
))
803 g_main_context_iteration (context
, FALSE
);
807 #define MIN_TIME_SEPARATION (50./1000.) /* 50ms */
809 ghid_progress (int so_far
, int total
, const char *message
)
811 static struct progress_dialog
*pd
= NULL
;
813 /* If we are finished, destroy any dialog */
814 if (so_far
== 0 && total
== 0 && message
== NULL
)
816 destroy_progress_dialog (pd
);
822 pd
= make_progress_dialog ();
824 /* We don't want to keep the underlying process too busy whilst we
825 * process events. If we get called quickly after the last progress
826 * update, wait a little bit before we respond - perhaps the next
827 * time progress is reported.
829 * The exception here is that we always want to process the first
830 * batch of events after having shown the dialog for the first time
832 if (pd
->started
&& g_timer_elapsed (pd
->timer
, NULL
) < MIN_TIME_SEPARATION
)
835 gtk_label_set_text (GTK_LABEL (pd
->message
), message
);
836 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pd
->progress
),
837 (double)so_far
/ (double)total
);
839 handle_progress_dialog_events (pd
);
840 g_timer_start (pd
->timer
);
844 return (pd
->response_id
== GTK_RESPONSE_CANCEL
||
845 pd
->response_id
== GTK_RESPONSE_DELETE_EVENT
) ? 1 : 0;
848 /* ---------------------------------------------------------------------- */
857 static AttrRow
*attr_row
= 0;
858 static int attr_num_rows
= 0;
859 static int attr_max_rows
= 0;
860 static AttributeListType
*attributes_list
;
861 static GtkWidget
*attributes_dialog
, *attr_table
;
863 static void attributes_delete_callback (GtkWidget
*w
, void *v
);
865 #define GA_RESPONSE_REVERT 1
866 #define GA_RESPONSE_NEW 2
869 ghid_attr_set_table_size ()
871 gtk_table_resize (GTK_TABLE (attr_table
), attr_num_rows
> 0 ? attr_num_rows
: 1, 3);
875 ghid_attributes_need_rows (int new_max
)
877 if (attr_max_rows
< new_max
)
880 attr_row
= (AttrRow
*) realloc (attr_row
, new_max
* sizeof(AttrRow
));
882 attr_row
= (AttrRow
*) malloc (new_max
* sizeof(AttrRow
));
884 while (attr_max_rows
< new_max
)
886 /* add [attr_max_rows] */
887 attr_row
[attr_max_rows
].del
= gtk_button_new_with_label ("del");
888 gtk_table_attach (GTK_TABLE (attr_table
), attr_row
[attr_max_rows
].del
,
890 attr_max_rows
, attr_max_rows
+1,
891 (GtkAttachOptions
)(GTK_FILL
| GTK_EXPAND
),
894 g_signal_connect (G_OBJECT (attr_row
[attr_max_rows
].del
), "clicked",
895 G_CALLBACK (attributes_delete_callback
), GINT_TO_POINTER (attr_max_rows
) );
897 attr_row
[attr_max_rows
].w_name
= gtk_entry_new ();
898 gtk_table_attach (GTK_TABLE (attr_table
), attr_row
[attr_max_rows
].w_name
,
900 attr_max_rows
, attr_max_rows
+1,
901 (GtkAttachOptions
)(GTK_FILL
| GTK_EXPAND
),
905 attr_row
[attr_max_rows
].w_value
= gtk_entry_new ();
906 gtk_table_attach (GTK_TABLE (attr_table
), attr_row
[attr_max_rows
].w_value
,
908 attr_max_rows
, attr_max_rows
+1,
909 (GtkAttachOptions
)(GTK_FILL
| GTK_EXPAND
),
916 /* Manage any previously unused rows we now need to show. */
917 while (attr_num_rows
< new_max
)
919 /* manage attr_num_rows */
920 gtk_widget_show (attr_row
[attr_num_rows
].del
);
921 gtk_widget_show (attr_row
[attr_num_rows
].w_name
);
922 gtk_widget_show (attr_row
[attr_num_rows
].w_value
);
928 ghid_attributes_revert ()
932 ghid_attributes_need_rows (attributes_list
->Number
);
934 /* Unmanage any previously used rows we don't need. */
935 while (attr_num_rows
> attributes_list
->Number
)
938 gtk_widget_hide (attr_row
[attr_num_rows
].del
);
939 gtk_widget_hide (attr_row
[attr_num_rows
].w_name
);
940 gtk_widget_hide (attr_row
[attr_num_rows
].w_value
);
944 for (i
=0; i
<attributes_list
->Number
; i
++)
947 gtk_entry_set_text (GTK_ENTRY (attr_row
[i
].w_name
), attributes_list
->List
[i
].name
);
948 gtk_entry_set_text (GTK_ENTRY (attr_row
[i
].w_value
), attributes_list
->List
[i
].value
);
952 ghid_attr_set_table_size ();
956 attributes_delete_callback (GtkWidget
*w
, void *v
)
960 n
= GPOINTER_TO_INT (v
);
962 for (i
=n
; i
<attr_num_rows
-1; i
++)
964 gtk_entry_set_text (GTK_ENTRY (attr_row
[i
].w_name
),
965 gtk_entry_get_text (GTK_ENTRY (attr_row
[i
+1].w_name
)));
966 gtk_entry_set_text (GTK_ENTRY (attr_row
[i
].w_value
),
967 gtk_entry_get_text (GTK_ENTRY (attr_row
[i
+1].w_value
)));
971 gtk_widget_hide (attr_row
[attr_num_rows
].del
);
972 gtk_widget_hide (attr_row
[attr_num_rows
].w_name
);
973 gtk_widget_hide (attr_row
[attr_num_rows
].w_value
);
975 ghid_attr_set_table_size ();
979 ghid_attributes (char *owner
, AttributeListType
*attrs
)
981 GtkWidget
*content_area
;
984 attributes_list
= attrs
;
989 attributes_dialog
= gtk_dialog_new_with_buttons (owner
,
990 GTK_WINDOW (ghid_port
.top_window
),
992 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
993 "Revert", GA_RESPONSE_REVERT
,
994 "New", GA_RESPONSE_NEW
,
995 GTK_STOCK_OK
, GTK_RESPONSE_OK
, NULL
);
997 attr_table
= gtk_table_new (attrs
->Number
, 3, 0);
999 content_area
= gtk_dialog_get_content_area (GTK_DIALOG (attributes_dialog
));
1000 gtk_box_pack_start (GTK_BOX (content_area
), attr_table
, FALSE
, FALSE
, 0);
1002 gtk_widget_show (attr_table
);
1004 ghid_attributes_revert ();
1008 response
= gtk_dialog_run (GTK_DIALOG (attributes_dialog
));
1010 if (response
== GTK_RESPONSE_CANCEL
)
1013 if (response
== GTK_RESPONSE_OK
)
1016 /* Copy the values back */
1017 for (i
=0; i
<attributes_list
->Number
; i
++)
1019 if (attributes_list
->List
[i
].name
)
1020 free (attributes_list
->List
[i
].name
);
1021 if (attributes_list
->List
[i
].value
)
1022 free (attributes_list
->List
[i
].value
);
1024 if (attributes_list
->Max
< attr_num_rows
)
1026 int sz
= attr_num_rows
* sizeof (AttributeType
);
1027 if (attributes_list
->List
== NULL
)
1028 attributes_list
->List
= (AttributeType
*) malloc (sz
);
1030 attributes_list
->List
= (AttributeType
*) realloc (attributes_list
->List
, sz
);
1031 attributes_list
->Max
= attr_num_rows
;
1033 for (i
=0; i
<attr_num_rows
; i
++)
1035 attributes_list
->List
[i
].name
= strdup (gtk_entry_get_text (GTK_ENTRY (attr_row
[i
].w_name
)));
1036 attributes_list
->List
[i
].value
= strdup (gtk_entry_get_text (GTK_ENTRY (attr_row
[i
].w_value
)));
1037 attributes_list
->Number
= attr_num_rows
;
1043 if (response
== GA_RESPONSE_REVERT
)
1046 ghid_attributes_revert ();
1049 if (response
== GA_RESPONSE_NEW
)
1051 ghid_attributes_need_rows (attr_num_rows
+ 1); /* also bumps attr_num_rows */
1053 gtk_entry_set_text (GTK_ENTRY (attr_row
[attr_num_rows
-1].w_name
), "");
1054 gtk_entry_set_text (GTK_ENTRY (attr_row
[attr_num_rows
-1].w_value
), "");
1056 ghid_attr_set_table_size ();
1060 gtk_widget_destroy (attributes_dialog
);
1065 /* ---------------------------------------------------------------------- */
1067 HID_DRC_GUI ghid_drc_gui
= {
1068 1, /* log_drc_overview */
1069 0, /* log_drc_details */
1070 ghid_drc_window_reset_message
,
1071 ghid_drc_window_append_violation
,
1072 ghid_drc_window_throw_dialog
,
1075 extern HID_Attribute
*ghid_get_export_options (int *);
1078 /* ------------------------------------------------------------
1080 * Actions specific to the GTK HID follow from here
1085 /* ------------------------------------------------------------ */
1086 static const char about_syntax
[] =
1089 static const char about_help
[] =
1090 N_("Tell the user about this version of PCB.");
1092 /* %start-doc actions About
1094 This just pops up a dialog telling the user which version of
1095 @code{pcb} they're running.
1101 About (int argc
, char **argv
, Coord x
, Coord y
)
1103 ghid_dialog_about ();
1107 /* ------------------------------------------------------------ */
1108 static const char getxy_syntax
[] =
1111 static const char getxy_help
[] =
1112 N_("Get a coordinate.");
1114 /* %start-doc actions GetXY
1116 Prompts the user for a coordinate, if one is not already selected.
1121 GetXY (int argc
, char **argv
, Coord x
, Coord y
)
1126 /* ---------------------------------------------------------------------- */
1128 static int PointCursor (int argc
, char **argv
, Coord x
, Coord y
)
1134 ghid_point_cursor ();
1136 ghid_mode_cursor (Settings
.Mode
);
1140 /* ---------------------------------------------------------------------- */
1143 RouteStylesChanged (int argc
, char **argv
, Coord x
, Coord y
)
1145 if (!ghidgui
|| !ghidgui
->route_style_selector
)
1148 ghid_route_style_selector_sync
1149 (GHID_ROUTE_STYLE_SELECTOR (ghidgui
->route_style_selector
),
1150 Settings
.LineThickness
, Settings
.ViaDrillingHole
,
1151 Settings
.ViaThickness
, Settings
.Keepaway
);
1156 /* ---------------------------------------------------------------------- */
1159 PCBChanged (int argc
, char **argv
, Coord x
, Coord y
)
1164 ghid_window_set_name_label (PCB
->Name
);
1169 if (ghidgui
->route_style_selector
)
1171 ghid_route_style_selector_empty
1172 (GHID_ROUTE_STYLE_SELECTOR (ghidgui
->route_style_selector
));
1173 make_route_style_buttons
1174 (GHID_ROUTE_STYLE_SELECTOR (ghidgui
->route_style_selector
));
1176 RouteStylesChanged (0, NULL
, 0, 0);
1178 ghid_port_ranges_scale ();
1179 ghid_zoom_view_fit ();
1180 ghid_sync_with_new_layout ();
1184 /* ---------------------------------------------------------------------- */
1187 LayerGroupsChanged (int argc
, char **argv
, Coord x
, Coord y
)
1189 printf (_("LayerGroupsChanged -- not implemented\n"));
1193 /* ---------------------------------------------------------------------- */
1196 LibraryChanged (int argc
, char **argv
, Coord x
, Coord y
)
1198 /* No need to show the library window every time it changes...
1199 * ghid_library_window_show (&ghid_port, FALSE);
1204 /* ---------------------------------------------------------------------- */
1207 Command (int argc
, char **argv
, Coord x
, Coord y
)
1209 ghid_handle_user_command (TRUE
);
1213 /* ---------------------------------------------------------------------- */
1216 Load (int argc
, char **argv
, Coord x
, Coord y
)
1221 static gchar
*current_element_dir
= NULL
;
1222 static gchar
*current_layout_dir
= NULL
;
1223 static gchar
*current_netlist_dir
= NULL
;
1225 /* we've been given the file name */
1227 return hid_actionv ("LoadFrom", argc
, argv
);
1229 function
= argc
? argv
[0] : (char *)"Layout";
1231 if (strcasecmp (function
, "Netlist") == 0)
1233 name
= ghid_dialog_file_select_open (_("Load netlist file"),
1234 ¤t_netlist_dir
,
1237 else if (strcasecmp (function
, "ElementToBuffer") == 0)
1239 name
= ghid_dialog_file_select_open (_("Load element to buffer"),
1240 ¤t_element_dir
,
1241 Settings
.LibraryTree
);
1243 else if (strcasecmp (function
, "LayoutToBuffer") == 0)
1245 name
= ghid_dialog_file_select_open (_("Load layout file to buffer"),
1246 ¤t_layout_dir
,
1249 else if (strcasecmp (function
, "Layout") == 0)
1251 name
= ghid_dialog_file_select_open (_("Load layout file"),
1252 ¤t_layout_dir
,
1258 if (Settings
.verbose
)
1259 fprintf (stderr
, "%s: Calling LoadFrom(%s, %s)\n", __FUNCTION__
,
1261 hid_actionl ("LoadFrom", function
, name
, NULL
);
1269 /* ---------------------------------------------------------------------- */
1270 static const char save_syntax
[] =
1272 "Save(Layout|LayoutAs)\n"
1273 "Save(AllConnections|AllUnusedPins|ElementConnections)\n"
1274 "Save(PasteBuffer)";
1276 static const char save_help
[] =
1277 N_("Save layout and/or element data to a user-selected file.");
1279 /* %start-doc actions Save
1281 This action is a GUI front-end to the core's @code{SaveTo} action
1282 (@pxref{SaveTo Action}). If you happen to pass a filename, like
1283 @code{SaveTo}, then @code{SaveTo} is called directly. Else, the
1284 user is prompted for a filename to save, and then @code{SaveTo} is
1285 called with that filename.
1290 Save (int argc
, char **argv
, Coord x
, Coord y
)
1296 static gchar
*current_dir
= NULL
;
1299 return hid_actionv ("SaveTo", argc
, argv
);
1301 function
= argc
? argv
[0] : (char *)"Layout";
1303 if (strcasecmp (function
, "Layout") == 0)
1305 return hid_actionl ("SaveTo", "Layout", PCB
->Filename
, NULL
);
1307 if (strcasecmp (function
, "PasteBuffer") == 0)
1308 prompt
= _("Save element as");
1310 prompt
= _("Save layout as");
1312 name
= ghid_dialog_file_select_save (prompt
,
1314 PCB
->Filename
, Settings
.FilePath
);
1318 if (Settings
.verbose
)
1319 fprintf (stderr
, "%s: Calling SaveTo(%s, %s)\n",
1320 __FUNCTION__
, function
, name
);
1322 if (strcasecmp (function
, "PasteBuffer") == 0)
1323 hid_actionl ("PasteBuffer", "Save", name
, NULL
);
1327 * if we got this far and the function is Layout, then
1328 * we really needed it to be a LayoutAs. Otherwise
1329 * ActionSaveTo() will ignore the new file name we
1332 if (strcasecmp (function
, "Layout") == 0)
1333 hid_actionl ("SaveTo", "LayoutAs", name
, NULL
);
1335 hid_actionl ("SaveTo", function
, name
, NULL
);
1347 /* ---------------------------------------------------------------------- */
1348 static const char swapsides_syntax
[] =
1349 "SwapSides(|v|h|r)";
1351 static const char swapsides_help
[] =
1352 N_("Swaps the side of the board you're looking at.");
1354 /* %start-doc actions SwapSides
1356 This action changes the way you view the board.
1361 Flips the board over vertically (up/down).
1364 Flips the board over horizontally (left/right), like flipping pages in
1368 Rotates the board 180 degrees without changing sides.
1372 If no argument is given, the board isn't moved but the opposite side
1375 Normally, this action changes which pads and silk layer are drawn as
1376 true silk, and which are drawn as the "invisible" layer. It also
1377 determines which solder mask you see.
1379 As a special case, if the layer group for the side you're looking at
1380 is visible and currently active, and the layer group for the opposite
1381 is not visible (i.e. disabled), then this action will also swap which
1382 layer group is visible and active, effectively swapping the ``working
1383 side'' of the board.
1389 SwapSides (int argc
, char **argv
, Coord x
, Coord y
)
1391 int active_group
= GetLayerGroupNumberByNumber (LayerStack
[0]);
1392 int comp_group
= GetLayerGroupNumberByNumber (component_silk_layer
);
1393 int solder_group
= GetLayerGroupNumberByNumber (solder_silk_layer
);
1394 bool comp_on
= LAYER_PTR (PCB
->LayerGroups
.Entries
[comp_group
][0])->On
;
1395 bool solder_on
= LAYER_PTR (PCB
->LayerGroups
.Entries
[solder_group
][0])->On
;
1399 switch (argv
[0][0]) {
1402 ghid_flip_view (gport
->pcb_x
, gport
->pcb_y
, true, false);
1406 ghid_flip_view (gport
->pcb_x
, gport
->pcb_y
, false, true);
1410 ghid_flip_view (gport
->pcb_x
, gport
->pcb_y
, true, true);
1411 Settings
.ShowSolderSide
= !Settings
.ShowSolderSide
; /* Swapped back below */
1418 Settings
.ShowSolderSide
= !Settings
.ShowSolderSide
;
1420 if ((active_group
== comp_group
&& comp_on
&& !solder_on
) ||
1421 (active_group
== solder_group
&& solder_on
&& !comp_on
))
1423 bool new_solder_vis
= Settings
.ShowSolderSide
;
1425 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[comp_group
][0],
1426 !new_solder_vis
, !new_solder_vis
);
1427 ChangeGroupVisibility (PCB
->LayerGroups
.Entries
[solder_group
][0],
1428 new_solder_vis
, new_solder_vis
);
1434 /* ------------------------------------------------------------ */
1436 static const char print_syntax
[] =
1439 static const char print_help
[] =
1440 N_("Print the layout.");
1442 /* %start-doc actions Print
1444 This will find the default printing HID, prompt the user for its
1445 options, and print the layout.
1450 Print (int argc
, char **argv
, Coord x
, Coord y
)
1454 HID
*printer
= NULL
;
1456 hids
= hid_enumerate ();
1457 for (i
= 0; hids
[i
]; i
++)
1459 if (hids
[i
]->printer
)
1463 if (printer
== NULL
)
1465 gui
->log (_("Can't find a suitable printer HID"));
1469 /* check if layout is empty */
1470 if (!IsDataEmpty (PCB
->Data
))
1472 ghid_dialog_print (printer
);
1475 gui
->log (_("Can't print empty layout"));
1481 /* ------------------------------------------------------------ */
1483 static HID_Attribute
1484 printer_calibrate_attrs
[] = {
1485 {N_("Enter Values here:"), "",
1486 HID_Label
, 0, 0, {0, 0, 0}, 0, 0},
1487 {N_("x-calibration"), N_("X scale for calibrating your printer"),
1488 HID_Real
, 0.5, 25, {0, 0, 1.00}, 0, 0},
1489 {N_("y-calibration"), N_("Y scale for calibrating your printer"),
1490 HID_Real
, 0.5, 25, {0, 0, 1.00}, 0, 0}
1492 static HID_Attr_Val printer_calibrate_values
[3];
1494 static const char printcalibrate_syntax
[] =
1497 static const char printcalibrate_help
[] =
1498 N_("Calibrate the printer.");
1500 /* %start-doc actions PrintCalibrate
1502 This will print a calibration page, which you would measure and type
1503 the measurements in, so that future printouts will be more precise.
1508 PrintCalibrate (int argc
, char **argv
, Coord x
, Coord y
)
1510 HID
*printer
= hid_find_printer ();
1511 printer
->calibrate (0.0, 0.0);
1513 if (gui
->attribute_dialog (printer_calibrate_attrs
, 3,
1514 printer_calibrate_values
,
1515 _("Printer Calibration Values"),
1516 _("Enter calibration values for your printer")))
1518 printer
->calibrate (printer_calibrate_values
[1].real_value
,
1519 printer_calibrate_values
[2].real_value
);
1523 /* ------------------------------------------------------------ */
1526 Export (int argc
, char **argv
, Coord x
, Coord y
)
1529 /* check if layout is empty */
1530 if (!IsDataEmpty (PCB
->Data
))
1532 ghid_dialog_export ();
1535 gui
->log (_("Can't export empty layout"));
1540 /* ------------------------------------------------------------ */
1543 Benchmark (int argc
, char **argv
, Coord x
, Coord y
)
1547 GdkDisplay
*display
;
1549 display
= gdk_drawable_get_display (gport
->drawable
);
1551 gdk_display_sync (display
);
1555 ghid_invalidate_all ();
1556 gdk_window_process_updates (gtk_widget_get_window (gport
->drawing_area
),
1561 while (end
- start
< 10);
1563 printf (_("%g redraws per second\n"), i
/ 10.0);
1568 /* ------------------------------------------------------------ */
1570 static const char center_syntax
[] =
1573 static const char center_help
[] =
1574 N_("Moves the pointer to the center of the window.");
1576 /* %start-doc actions Center
1578 Move the pointer to the center of the window, but only if it's
1579 currently within the window already.
1584 Center(int argc
, char **argv
, Coord pcb_x
, Coord pcb_y
)
1586 GdkDisplay
*display
;
1588 int offset_x
, offset_y
;
1589 int widget_x
, widget_y
;
1590 int pointer_x
, pointer_y
;
1595 /* Aim to put the given x, y PCB coordinates in the center of the widget */
1596 widget_x
= gport
->width
/ 2;
1597 widget_y
= gport
->height
/ 2;
1599 ghid_pan_view_abs (pcb_x
, pcb_y
, widget_x
, widget_y
);
1601 /* Now move the mouse pointer to the place where the board location
1602 * actually ended up.
1604 * XXX: Should only do this if we confirm we are inside our window?
1607 ghid_pcb_to_event_coords (pcb_x
, pcb_y
, &widget_x
, &widget_y
);
1608 gdk_window_get_origin (gtk_widget_get_window (gport
->drawing_area
),
1609 &offset_x
, &offset_y
);
1611 pointer_x
= offset_x
+ widget_x
;
1612 pointer_y
= offset_y
+ widget_y
;
1614 display
= gdk_display_get_default ();
1615 screen
= gdk_display_get_default_screen (display
);
1616 gdk_display_warp_pointer (display
, screen
, pointer_x
, pointer_y
);
1621 /* ------------------------------------------------------------ */
1622 static const char cursor_syntax
[] =
1623 "Cursor(Type,DeltaUp,DeltaRight,Units)";
1625 static const char cursor_help
[] =
1626 N_("Move the cursor.");
1628 /* %start-doc actions Cursor
1630 This action moves the mouse cursor. Unlike other actions which take
1631 coordinates, this action's coordinates are always relative to the
1632 user's view of the board. Thus, a positive @var{DeltaUp} may move the
1633 cursor towards the board origin if the board is inverted.
1635 Type is one of @samp{Pan} or @samp{Warp}. @samp{Pan} causes the
1636 viewport to move such that the crosshair is under the mouse cursor.
1637 @samp{Warp} causes the mouse cursor to move to be above the crosshair.
1639 @var{Units} can be one of the following:
1645 The cursor is moved by that amount, in board units.
1648 The cursor is moved by that many grid points.
1651 The values are percentages of the viewport's view. Thus, a pan of
1652 @samp{100} would scroll the viewport by exactly the width of the
1656 The values are percentages of the board size. Thus, a move of
1657 @samp{50,50} moves you halfway across the board.
1664 CursorAction(int argc
, char **argv
, Coord x
, Coord y
)
1666 UnitList extra_units_x
= {
1667 { "grid", PCB
->Grid
, 0 },
1668 { "view", gport
->view
.width
, UNIT_PERCENT
},
1669 { "board", PCB
->MaxWidth
, UNIT_PERCENT
},
1672 UnitList extra_units_y
= {
1673 { "grid", PCB
->Grid
, 0 },
1674 { "view", gport
->view
.height
, UNIT_PERCENT
},
1675 { "board", PCB
->MaxHeight
, UNIT_PERCENT
},
1678 int pan_warp
= HID_SC_DO_NOTHING
;
1684 if (strcasecmp (argv
[0], "pan") == 0)
1685 pan_warp
= HID_SC_PAN_VIEWPORT
;
1686 else if (strcasecmp (argv
[0], "warp") == 0)
1687 pan_warp
= HID_SC_WARP_POINTER
;
1691 dx
= GetValueEx (argv
[1], argv
[3], NULL
, extra_units_x
, "");
1692 if (gport
->view
.flip_x
)
1694 dy
= GetValueEx (argv
[2], argv
[3], NULL
, extra_units_y
, "");
1695 if (!gport
->view
.flip_y
)
1698 EventMoveCrosshair (Crosshair
.X
+ dx
, Crosshair
.Y
+ dy
);
1699 gui
->set_crosshair (Crosshair
.X
, Crosshair
.Y
, pan_warp
);
1703 /* ------------------------------------------------------------ */
1705 static const char dowindows_syntax
[] =
1706 "DoWindows(1|2|3|4|5|6)\n"
1707 "DoWindows(Layout|Library|Log|Netlist|Preferences|DRC)";
1709 static const char dowindows_help
[] =
1710 N_("Open various GUI windows.");
1712 /* %start-doc actions DoWindows
1718 Open the layout window. Since the layout window is always shown
1719 anyway, this has no effect.
1723 Open the library window.
1727 Open the log window.
1731 Open the netlist window.
1735 Open the preferences window.
1739 Open the DRC violations window.
1746 DoWindows (int argc
, char **argv
, Coord x
, Coord y
)
1748 char *a
= argc
== 1 ? argv
[0] : (char *)"";
1750 if (strcmp (a
, "1") == 0 || strcasecmp (a
, "Layout") == 0)
1753 else if (strcmp (a
, "2") == 0 || strcasecmp (a
, "Library") == 0)
1755 ghid_library_window_show (gport
, TRUE
);
1757 else if (strcmp (a
, "3") == 0 || strcasecmp (a
, "Log") == 0)
1759 ghid_log_window_show (TRUE
);
1761 else if (strcmp (a
, "4") == 0 || strcasecmp (a
, "Netlist") == 0)
1763 ghid_netlist_window_show (gport
, TRUE
);
1765 else if (strcmp (a
, "5") == 0 || strcasecmp (a
, "Preferences") == 0)
1767 ghid_config_window_show ();
1769 else if (strcmp (a
, "6") == 0 || strcasecmp (a
, "DRC") == 0)
1771 ghid_drc_window_show (TRUE
);
1781 /* ------------------------------------------------------------ */
1782 static const char setunits_syntax
[] =
1785 static const char setunits_help
[] =
1786 N_("Set the default measurement units.");
1788 /* %start-doc actions SetUnits
1793 Sets the display units to mils (1/1000 inch).
1796 Sets the display units to millimeters.
1803 SetUnits (int argc
, char **argv
, Coord x
, Coord y
)
1805 const Unit
*new_unit
;
1809 new_unit
= get_unit_struct (argv
[0]);
1810 if (new_unit
!= NULL
&& new_unit
->allow
!= NO_PRINT
)
1812 Settings
.grid_unit
= new_unit
;
1813 Settings
.increments
= get_increments_struct (Settings
.grid_unit
->family
);
1814 AttributePut (PCB
, "PCB::grid::unit", argv
[0]);
1817 ghid_config_handle_units_changed ();
1819 ghid_set_status_line_label ();
1822 * lesstif_sizes_reset ();
1823 * lesstif_styles_update_values ();
1828 /* ------------------------------------------------------------ */
1829 static const char scroll_syntax
[] =
1830 "Scroll(up|down|left|right, [div])";
1832 static const char scroll_help
[] =
1833 N_("Scroll the viewport.");
1835 /* % start-doc actions Scroll
1837 @item up|down|left|right
1838 Specifies the direction to scroll
1841 Optional. Specifies how much to scroll by. The viewport is scrolled
1842 by 1/div of what is visible, so div = 1 scrolls a whole page. If not
1843 default is given, div=40.
1848 ScrollAction (int argc
, char **argv
, Coord x
, Coord y
)
1850 gdouble dx
= 0.0, dy
= 0.0;
1856 if (argc
!= 1 && argc
!= 2)
1860 div
= atoi(argv
[1]);
1862 if (strcasecmp (argv
[0], "up") == 0)
1863 dy
= -gport
->view
.height
/ div
;
1864 else if (strcasecmp (argv
[0], "down") == 0)
1865 dy
= gport
->view
.height
/ div
;
1866 else if (strcasecmp (argv
[0], "right") == 0)
1867 dx
= gport
->view
.width
/ div
;
1868 else if (strcasecmp (argv
[0], "left") == 0)
1869 dx
= -gport
->view
.width
/ div
;
1873 ghid_pan_view_rel (dx
, dy
);
1878 /* ------------------------------------------------------------ */
1879 static const char pan_syntax
[] =
1880 "Pan([thumb], Mode)";
1882 static const char pan_help
[] =
1883 N_("Start or stop panning (Mode = 1 to start, 0 to stop)\n"
1884 "Optional thumb argument is ignored for now in gtk hid.\n");
1886 /* %start-doc actions Pan
1888 Start or stop panning. To start call with Mode = 1, to stop call with
1894 PanAction (int argc
, char **argv
, Coord x
, Coord y
)
1901 if (argc
!= 1 && argc
!= 2)
1905 mode
= atoi(argv
[0]);
1908 mode
= atoi(argv
[1]);
1909 Message (_("The gtk gui currently ignores the optional first argument "
1910 "to the Pan action.\nFeel free to provide patches.\n"));
1913 gport
->panning
= mode
;
1918 /* ------------------------------------------------------------ */
1919 static const char popup_syntax
[] =
1920 "Popup(MenuName, [Button])";
1922 static const char popup_help
[] =
1923 N_("Bring up the popup menu specified by @code{MenuName}.\n"
1924 "If called by a mouse event then the mouse button number\n"
1925 "must be specified as the optional second argument.");
1927 /* %start-doc actions Popup
1929 This just pops up the specified menu. The menu must have been defined
1930 as a named subresource of the Popups resource in the menu resource
1931 file. The second, optional (and ignored) argument represents the mouse
1932 button number which is triggering the popup.
1938 Popup (int argc
, char **argv
, Coord x
, Coord y
)
1942 if (argc
!= 1 && argc
!= 2)
1945 menu
= ghid_main_menu_get_popup (GHID_MAIN_MENU (ghidgui
->menu_bar
), argv
[0]);
1946 if (! GTK_IS_MENU (menu
))
1948 Message (_("The specified popup menu \"%s\" has not been defined.\n"), argv
[0]);
1953 ghidgui
->in_popup
= TRUE
;
1954 gtk_widget_grab_focus (ghid_port
.drawing_area
);
1955 gtk_menu_popup (menu
, NULL
, NULL
, NULL
, NULL
, 0,
1956 gtk_get_current_event_time());
1960 /* ------------------------------------------------------------ */
1961 static const char importgui_syntax
[] =
1964 static const char importgui_help
[] =
1965 N_("Asks user which schematics to import into PCB.\n");
1967 /* %start-doc actions ImportGUI
1969 Asks user which schematics to import into PCB.
1975 ImportGUI (int argc
, char **argv
, Coord x
, Coord y
)
1977 GSList
*names
= NULL
;
1980 static gchar
*current_layout_dir
= NULL
;
1981 static int I_am_recursing
= 0;
1988 names
= ghid_dialog_file_select_multiple (_("Load schematics"),
1989 ¤t_layout_dir
,
1993 while (names
!= NULL
)
1998 printf("File selected = %s\n", name
);
2001 sprintf (sname
, "import::src%d", nsources
);
2002 AttributePut (PCB
, sname
, name
);
2006 names
= g_slist_next (names
);
2008 g_slist_free (names
);
2011 rv
= hid_action ("Import");
2017 /* ------------------------------------------------------------ */
2019 Busy (int argc
, char **argv
, Coord x
, Coord y
)
2021 ghid_watch_cursor ();
2025 HID_Action ghid_main_action_list
[] = {
2026 {"About", 0, About
, about_help
, about_syntax
},
2027 {"Benchmark", 0, Benchmark
},
2029 {"Center", N_("Click on a location to center"), Center
, center_help
, center_syntax
},
2030 {"Command", 0, Command
},
2031 {"Cursor", 0, CursorAction
, cursor_help
, cursor_syntax
},
2032 {"DoWindows", 0, DoWindows
, dowindows_help
, dowindows_syntax
},
2033 {"Export", 0, Export
},
2034 {"GetXY", "", GetXY
, getxy_help
, getxy_syntax
},
2035 {"ImportGUI", 0, ImportGUI
, importgui_help
, importgui_syntax
},
2036 {"LayerGroupsChanged", 0, LayerGroupsChanged
},
2037 {"LibraryChanged", 0, LibraryChanged
},
2039 {"Pan", 0, PanAction
, pan_help
, pan_syntax
},
2040 {"PCBChanged", 0, PCBChanged
},
2041 {"PointCursor", 0, PointCursor
},
2042 {"Popup", 0, Popup
, popup_help
, popup_syntax
},
2044 print_help
, print_syntax
},
2045 {"PrintCalibrate", 0, PrintCalibrate
,
2046 printcalibrate_help
, printcalibrate_syntax
},
2047 {"RouteStylesChanged", 0, RouteStylesChanged
},
2048 {"Save", 0, Save
, save_help
, save_syntax
},
2049 {"Scroll", N_("Click on a place to scroll"), ScrollAction
, scroll_help
, scroll_syntax
},
2050 {"SetUnits", 0, SetUnits
, setunits_help
, setunits_syntax
},
2051 {"SwapSides", 0, SwapSides
, swapsides_help
, swapsides_syntax
},
2052 {"Zoom", N_("Click on zoom focus"), Zoom
, zoom_help
, zoom_syntax
}
2055 REGISTER_ACTIONS (ghid_main_action_list
)
2059 flag_flipx (void *data
)
2061 return gport
->view
.flip_x
;
2065 flag_flipy (void *data
)
2067 return gport
->view
.flip_y
;
2070 HID_Flag ghid_main_flag_list
[] = {
2071 {"flip_x", flag_flipx
, NULL
},
2072 {"flip_y", flag_flipy
, NULL
}
2075 REGISTER_FLAGS (ghid_main_flag_list
)
2077 #include "dolists.h"
2080 * We will need these for finding the windows installation
2081 * directory. Without that we can't find our fonts and
2082 * footprint libraries.
2085 #include <windows.h>
2090 HID_DRAW ghid_graphics
;
2103 tmps
= g_win32_get_package_installation_directory (PACKAGE
"-" VERSION
, NULL
);
2104 #define REST_OF_PATH G_DIR_SEPARATOR_S "share" G_DIR_SEPARATOR_S PACKAGE
2105 #define REST_OF_CACHE G_DIR_SEPARATOR_S "loaders.cache"
2106 share_dir
= (char *) malloc(strlen(tmps
) +
2107 strlen(REST_OF_PATH
) +
2109 sprintf (share_dir
, "%s%s", tmps
, REST_OF_PATH
);
2111 /* Point to our gdk-pixbuf loader cache. */
2112 loader_cache
= (char *) malloc (strlen (bindir
) +
2113 strlen (REST_OF_CACHE
) +
2115 sprintf (loader_cache
, "%s%s", bindir
, REST_OF_CACHE
);
2116 loader_file
= fopen (loader_cache
, "r");
2119 fclose (loader_file
);
2120 g_setenv ("GDK_PIXBUF_MODULE_FILE", loader_cache
, TRUE
);
2125 printf ("\"Share\" installation path is \"%s\"\n", share_dir
);
2129 memset (&ghid_hid
, 0, sizeof (HID
));
2130 memset (&ghid_graphics
, 0, sizeof (HID_DRAW
));
2132 common_nogui_init (&ghid_hid
);
2133 common_draw_helpers_init (&ghid_graphics
);
2135 ghid_hid
.struct_size
= sizeof (HID
);
2136 ghid_hid
.name
= "gtk";
2137 ghid_hid
.description
= "Gtk - The Gimp Toolkit";
2139 ghid_hid
.poly_after
= 1;
2141 ghid_hid
.get_export_options
= ghid_get_export_options
;
2142 ghid_hid
.do_export
= ghid_do_export
;
2143 ghid_hid
.parse_arguments
= ghid_parse_arguments
;
2144 ghid_hid
.invalidate_lr
= ghid_invalidate_lr
;
2145 ghid_hid
.invalidate_all
= ghid_invalidate_all
;
2146 ghid_hid
.notify_crosshair_change
= ghid_notify_crosshair_change
;
2147 ghid_hid
.notify_mark_change
= ghid_notify_mark_change
;
2148 ghid_hid
.set_layer
= ghid_set_layer
;
2150 ghid_hid
.calibrate
= ghid_calibrate
;
2151 ghid_hid
.shift_is_pressed
= ghid_shift_is_pressed
;
2152 ghid_hid
.control_is_pressed
= ghid_control_is_pressed
;
2153 ghid_hid
.mod1_is_pressed
= ghid_mod1_is_pressed
,
2154 ghid_hid
.get_coords
= ghid_get_coords
;
2155 ghid_hid
.set_crosshair
= ghid_set_crosshair
;
2156 ghid_hid
.add_timer
= ghid_add_timer
;
2157 ghid_hid
.stop_timer
= ghid_stop_timer
;
2158 ghid_hid
.watch_file
= ghid_watch_file
;
2159 ghid_hid
.unwatch_file
= ghid_unwatch_file
;
2160 ghid_hid
.add_block_hook
= ghid_add_block_hook
;
2161 ghid_hid
.stop_block_hook
= ghid_stop_block_hook
;
2163 ghid_hid
.log
= ghid_log
;
2164 ghid_hid
.logv
= ghid_logv
;
2165 ghid_hid
.confirm_dialog
= ghid_confirm_dialog
;
2166 ghid_hid
.close_confirm_dialog
= ghid_close_confirm_dialog
;
2167 ghid_hid
.report_dialog
= ghid_report_dialog
;
2168 ghid_hid
.prompt_for
= ghid_prompt_for
;
2169 ghid_hid
.fileselect
= ghid_fileselect
;
2170 ghid_hid
.attribute_dialog
= ghid_attribute_dialog
;
2171 ghid_hid
.show_item
= ghid_show_item
;
2172 ghid_hid
.beep
= ghid_beep
;
2173 ghid_hid
.progress
= ghid_progress
;
2174 ghid_hid
.drc_gui
= &ghid_drc_gui
,
2175 ghid_hid
.edit_attributes
= ghid_attributes
;
2177 ghid_hid
.request_debug_draw
= ghid_request_debug_draw
;
2178 ghid_hid
.flush_debug_draw
= ghid_flush_debug_draw
;
2179 ghid_hid
.finish_debug_draw
= ghid_finish_debug_draw
;
2181 ghid_hid
.notify_save_pcb
= ghid_notify_save_pcb
;
2182 ghid_hid
.notify_filename_changed
= ghid_notify_filename_changed
;
2184 ghid_hid
.graphics
= &ghid_graphics
;
2186 ghid_graphics
.make_gc
= ghid_make_gc
;
2187 ghid_graphics
.destroy_gc
= ghid_destroy_gc
;
2188 ghid_graphics
.use_mask
= ghid_use_mask
;
2189 ghid_graphics
.set_color
= ghid_set_color
;
2190 ghid_graphics
.set_line_cap
= ghid_set_line_cap
;
2191 ghid_graphics
.set_line_width
= ghid_set_line_width
;
2192 ghid_graphics
.set_draw_xor
= ghid_set_draw_xor
;
2193 ghid_graphics
.draw_line
= ghid_draw_line
;
2194 ghid_graphics
.draw_arc
= ghid_draw_arc
;
2195 ghid_graphics
.draw_rect
= ghid_draw_rect
;
2196 ghid_graphics
.fill_circle
= ghid_fill_circle
;
2197 ghid_graphics
.fill_polygon
= ghid_fill_polygon
;
2198 ghid_graphics
.fill_rect
= ghid_fill_rect
;
2200 ghid_graphics
.draw_pcb_polygon
= common_gui_draw_pcb_polygon
;
2202 hid_register_hid (&ghid_hid
);
2203 #include "gtk_lists.h"