1 /*----------------------------------------------------------------------*/
2 /* Copyright (c) 2002 Tim Edwards, Johns Hopkins University */
3 /*----------------------------------------------------------------------*/
5 /*----------------------------------------------------------------------*/
6 /* Spun off from xcircuit.c 10/4/98 */
7 /* Functionality will not be expanded in the Xt version. All new */
8 /* capabilities will be developed in the TCL version of help. */
9 /*----------------------------------------------------------------------*/
16 #include <X11/Intrinsic.h>
17 #include <X11/StringDefs.h>
18 #include <X11/Shell.h>
27 #include "Xw/WorkSpace.h"
28 #include "Xw/MenuBtn.h"
32 /*----------------------------------------------------------------------*/
34 /*----------------------------------------------------------------------*/
36 #include "colordefs.h"
40 /*----------------------------------------------------------------------*/
41 /* Function prototype declarations */
42 /*----------------------------------------------------------------------*/
43 #include "prototypes.h"
45 /*----------------------------------------------------------------------*/
46 /* Global Variable definitions */
47 /*----------------------------------------------------------------------*/
50 extern Tcl_Interp
*xcinterp
;
57 extern XCWindowData
*areawin
;
58 extern ApplicationData appdata
;
60 extern colorindex
*colorlist
;
62 extern xcWidget menuwidgets
[];
63 extern char *function_names
[NUM_FUNCTIONS
];
65 Pixmap helppix
= (Pixmap
)NULL
; /* For help window */
66 Dimension helpwidth
, helpheight
, hheight
;
70 /*-----------------------------------------*/
71 /* Print help list into a pixmap */
72 /* Return width and height of map through */
73 /* global variables helpwidth, helpheight. */
74 /*-----------------------------------------*/
83 static char *helptitle
= "Macro Key Binding Summary:";
84 static helpstruct helptext
[] = {
85 { XCF_Finish
, "Finish"},
86 { XCF_Cancel
, "Cancel"},
87 { XCF_Zoom_In
, "Zoom in 3/2"},
88 { XCF_Zoom_Out
, "Zoom out 3/2"},
89 { XCF_Pan
, "Pan (various modes)"},
90 { XCF_Double_Snap
, "Double snap-to spacing"},
91 { XCF_Halve_Snap
, "Halve snap-to spacing"},
92 { XCF_Next_Library
, "Go To Next Library"},
93 { XCF_Library_Pop
, "Return from Library"},
94 { XCF_Push
, "Push object"},
95 { XCF_Pop
, "Pop object"},
96 { XCF_Redraw
, "Refresh screen"},
97 { XCF_Page
, "Go To Page"},
98 { XCF_Write
, "Popup Output dialog"},
100 { XCF_Prompt
, "Python Command entry"},
102 { XCF_Prompt
, "Command entry"},
104 { XCF_Exit
, "Quit XCircuit"},
106 { XCF_Wire
, "Begin Polygon"},
107 { XCF_Box
, "Begin Box"},
108 { XCF_Arc
, "Begin Arc"},
109 { XCF_Text
, "Begin Text"},
110 { XCF_Spline
, "Begin Spline"},
111 { XCF_Select_Save
, "Make object"},
112 { XCF_Virtual
, "Make library instance"},
113 { XCF_Join
, "Join elements (make path)"},
114 { XCF_Unjoin
, "Un-join elements"},
115 { XCF_Dot
, "Place a dot"},
117 { XCF_Delete
, "Delete"},
120 { XCF_Select
, "Select"},
121 { XCF_Unselect
, "Deselect"},
125 { XCF_Rotate
, "Rotate"},
126 { XCF_Flip_X
, "Flip horizontally"},
127 { XCF_Flip_Y
, "Flip vertically"},
128 { XCF_Snap
, "Snap to grid"},
129 { XCF_Attach
, "Attach to"},
130 { XCF_Dashed
, "Dashed line style"},
131 { XCF_Dotted
, "Dotted line style"},
132 { XCF_Solid
, "Solid line style"},
134 { XCF_Anchor
, "Text Anchoring"},
135 { XCF_Superscript
, "Text Superscript"},
136 { XCF_Subscript
, "Text Subscript"},
137 { XCF_Font
, "Toggle text font"},
138 { XCF_Boldfont
, "Begin Bold text"},
139 { XCF_Italicfont
, "Begin Italic text"},
140 { XCF_Normalfont
, "Resume normal text"},
141 { XCF_ISO_Encoding
, "Begin Latin-1 encoding"},
142 { XCF_Overline
, "Begin text overline"},
143 { XCF_Underline
, "Begin text underline"},
144 { XCF_Parameter
, "Insert parameter"},
145 { XCF_Halfspace
, "Insert half-space"},
146 { XCF_Quarterspace
, "Insert quarter-space"},
147 { XCF_Linebreak
, "Insert return character"},
148 { XCF_Special
, "Insert special character"},
149 { XCF_TabStop
, "Set tab stop"},
150 { XCF_TabForward
, "Forward tab"},
151 { XCF_TabBackward
, "Backward tab"},
152 { XCF_Text_Home
, "Go to label beginning"},
153 { XCF_Text_End
, "Go to label end"},
154 { XCF_Text_Left
, "Move left one position"},
155 { XCF_Text_Right
, "Move right one position"},
156 { XCF_Text_Up
, "Move up one line"},
157 { XCF_Text_Down
, "Move down one line"},
158 { XCF_Text_Delete
, "Delete character(s)"},
159 { XCF_Text_Delete_Param
, "Delete parameter from text"},
160 { XCF_Text_Return
, "End text edit"},
161 { XCF_Text_Split
, "Split label at cursor"},
163 { XCF_Edit_Next
, "Edit: next position"},
164 { XCF_Edit_Delete
, "Edit: delete point"},
165 { XCF_Edit_Insert
, "Edit: insert point"},
166 { XCF_Edit_Param
, "Edit: insert parameter"},
168 { XCF_Library_Edit
, "Library: name edit"},
169 { XCF_Library_Move
, "Library: move object/page"},
170 { XCF_Library_Delete
, "Library: object delete"},
171 { XCF_Library_Hide
, "Library: hide object"},
172 { XCF_Library_Duplicate
, "Library: copy object"},
173 { XCF_Library_Virtual
, "Library: copy instance"},
175 { XCF_Pin_Label
, "Make Pin Label"},
176 { XCF_Pin_Global
, "Make Global Pin"},
177 { XCF_Info_Label
, "Make Info Label"},
178 { XCF_Swap
, "Go to Symbol or Schematic"},
179 { XCF_Connectivity
, "See net connectivity"},
180 { XCF_Sim
, "Generate Sim netlist"},
181 { XCF_SPICE
, "Generate SPICE netlist"},
182 { XCF_SPICEflat
, "Generate flattened SPICE"},
183 { XCF_PCB
, "Generate PCB netlist"},
184 { XCF_ENDDATA
, NULL
},
188 Window hwin
= DefaultRootWindow(dpy
);
189 Dimension htmp
, vtmp
, lineheight
, mwidth
;
190 int i
, j
, t1
, t2
, dum
, numlines
;
192 char *bindings
, *bptr
, *cptr
;
194 if (hwin
== 0) return;
196 /* Set up the GC for drawing to the help window pixmap */
199 values
.foreground
= colorlist
[FOREGROUND
].color
.pixel
;
200 values
.background
= colorlist
[BACKGROUND
].color
.pixel
;
201 values
.graphics_exposures
= False
;
202 values
.font
= appdata
.helpfont
->fid
;
203 hgc
= XCreateGC(dpy
, hwin
, GCForeground
| GCBackground
| GCFont
204 | GCGraphicsExposures
, &values
);
207 /* Determine the dimensions of the help text */
209 mwidth
= helpwidth
= lineheight
= numlines
= 0;
211 for (i
= 0; helptext
[i
].function
!= XCF_ENDDATA
; i
++) {
212 if (helptext
[i
].function
== XCF_SPACER
) {
217 htmp
= XTextWidth(appdata
.helpfont
, helptext
[i
].text
, strlen(helptext
[i
].text
));
218 if (htmp
> mwidth
) mwidth
= htmp
;
220 XTextExtents(appdata
.helpfont
, helptext
[i
].text
, strlen(helptext
[i
].text
),
221 &dum
, &t1
, &t2
, &csdum
);
223 if (vtmp
> lineheight
) lineheight
= vtmp
;
225 bindings
= function_binding_to_string(0, helptext
[i
].function
);
227 /* Limit list to three key bindings per line */
229 while (bptr
!= NULL
) {
231 for (j
= 0; j
< 3; j
++) {
232 cptr
= strchr(cptr
+ 1, ',');
233 if (cptr
== NULL
) break;
235 if (cptr
!= NULL
) *(++cptr
) = '\0';
237 htmp
= XTextWidth(appdata
.helpfont
, bptr
, strlen(bptr
));
238 if (htmp
> helpwidth
) helpwidth
= htmp
;
240 XTextExtents(appdata
.helpfont
, bptr
, strlen(bptr
),
241 &dum
, &t1
, &t2
, &csdum
);
243 if (vtmp
> lineheight
) lineheight
= vtmp
;
246 if (cptr
== NULL
) break;
251 XTextExtents(appdata
.helpfont
, helptitle
, strlen(helptitle
), &dum
, &t1
,
254 helpwidth
+= mwidth
+ 15;
256 helpheight
= lineheight
* numlines
+ 15 + t1
; /* full height of help text */
257 if (helppix
!= (Pixmap
)NULL
) {
258 Wprintf("Error: Help window not cancelled?");
261 helppix
= XCreatePixmap(dpy
, hwin
, helpwidth
, helpheight
,
262 DefaultDepthOfScreen(DefaultScreenOfDisplay(dpy
)));
264 XSetForeground(dpy
, hgc
, colorlist
[FOREGROUND
].color
.pixel
);
265 XFillRectangle(dpy
, helppix
, hgc
, 0, 0, helpwidth
, helpheight
);
267 XSetForeground(dpy
, hgc
, colorlist
[BACKGROUND
].color
.pixel
);
268 XDrawString(dpy
, helppix
, hgc
, (helpwidth
- XTextWidth(appdata
.helpfont
,
269 helptitle
, strlen(helptitle
))) >> 1, t1
+ 2, helptitle
, strlen(helptitle
));
270 vtmp
= lineheight
+ 15;
271 for (i
= 0; helptext
[i
].function
!= XCF_ENDDATA
; i
++) {
272 if (helptext
[i
].function
== XCF_SPACER
) {
276 XDrawString(dpy
, helppix
, hgc
, 7, vtmp
, helptext
[i
].text
,
277 strlen(helptext
[i
].text
));
278 bindings
= function_binding_to_string(0, helptext
[i
].function
);
280 while (bptr
!= NULL
) {
282 for (j
= 0; j
< 3; j
++) {
283 cptr
= strchr(cptr
+ 1, ',');
284 if (cptr
== NULL
) break;
286 if (cptr
!= NULL
) *(++cptr
) = '\0';
287 XDrawString(dpy
, helppix
, hgc
, 7 + mwidth
, vtmp
, bptr
, strlen(bptr
));
289 if (cptr
== NULL
) break;
294 XSetForeground(dpy
, hgc
, colorlist
[AUXCOLOR
].color
.pixel
);
295 XDrawLine(dpy
, helppix
, hgc
, 0, t1
+ 7, helpwidth
, t1
+ 7);
298 /*----------------------------------------------*/
299 /* Create the help popup window (Xt version) */
300 /*----------------------------------------------*/
304 void starthelp(xcWidget button
, caddr_t clientdata
, caddr_t calldata
)
307 xcWidget popup
, cancelbutton
, hspace
, help2
, hsb
;
309 popupstruct
*okaystruct
;
310 buttonsave
*savebutton
;
311 Dimension areawidth
, bwidth
, pheight
;
317 if (help_up
) return; /* no multiple help windows */
320 scale
= Tcl_GetVar2(xcinterp
, "XCOps", "scale", TCL_GLOBAL_ONLY
);
321 sbarsize
= SBARSIZE
* atoi(scale
);
326 /* for positioning the help window outside of the xcircuit */
327 /* window, get information about the display width and height */
328 /* and the xcircuit window. */
330 /* The "- 50" leaves space for the Windows-95-type title bar that */
331 /* runs across the bottom of the screen in some window managers */
332 /* (specifically, fvwm95 which is the default for RedHat Linux) */
334 xmax
= DisplayWidth(dpy
, DefaultScreen(dpy
)) - 100;
335 ymax
= DisplayHeight(dpy
, DefaultScreen(dpy
)) - 50;
337 XtnSetArg(XtNwidth
, &areawidth
);
338 XtGetValues(areawin
->area
, wargs
, n
); n
= 0;
339 XtTranslateCoords(areawin
->area
, (Position
) (areawidth
+ 10), -50,
342 savebutton
= getgeneric(button
, starthelp
, NULL
);
344 /* Generate the pixmap and write the help text to it */
346 if (helppix
== (Pixmap
)NULL
) printhelppix();
348 /* Use the pixmap size to size the help window */
350 if (xpos
+ helpwidth
+ sbarsize
> xmax
) xpos
= xmax
- helpwidth
- sbarsize
- 4;
351 if (ypos
+ helpheight
> ymax
) ypos
= ymax
- helpheight
- 4;
352 if (ypos
< 4) ypos
= 4;
354 XtnSetArg(XtNx
, xpos
);
355 XtnSetArg(XtNy
, ypos
);
356 popup
= XtCreatePopupShell("help", transientShellWidgetClass
,
357 button
, wargs
, n
); n
= 0;
362 XtnSetArg(XtNyResizable
, True
);
363 XtnSetArg(XtNxResizable
, False
);
364 help2
= XtCreateManagedWidget("help2", XwformWidgetClass
,
365 popup
, wargs
, n
); n
= 0;
367 XtnSetArg(XtNfont
, appdata
.xcfont
);
368 cancelbutton
= XtCreateManagedWidget("Dismiss", XwmenuButtonWidgetClass
,
369 help2
, wargs
, n
); n
= 0;
371 XtnSetArg(XtNwidth
, helpwidth
);
372 XtnSetArg(XtNheight
, areawin
->height
);
373 XtnSetArg(XtNyRefWidget
, cancelbutton
);
374 XtnSetArg(XtNyAddHeight
, True
);
375 XtnSetArg(XtNyAttachBottom
, True
);
376 XtnSetArg(XtNyResizable
, True
);
377 XtnSetArg(XtNborderWidth
, 0);
378 XtnSetArg(XtNxAttachRight
, False
);
379 hspace
= XtCreateManagedWidget("HSpace", XwworkSpaceWidgetClass
,
380 help2
, wargs
, n
); n
= 0;
382 /* Create scrollbar */
383 XtnSetArg(XtNwidth
, sbarsize
);
384 XtnSetArg(XtNxRefWidget
, hspace
);
385 XtnSetArg(XtNxAddWidth
, True
);
386 XtnSetArg(XtNyRefWidget
, cancelbutton
);
387 XtnSetArg(XtNyAddHeight
, True
);
388 XtnSetArg(XtNyResizable
, True
);
389 XtnSetArg(XtNyAttachBottom
, True
);
390 XtnSetArg(XtNborderWidth
, 1);
391 hsb
= XtCreateManagedWidget("HSB", XwworkSpaceWidgetClass
,
392 help2
, wargs
, n
); n
= 0;
394 okaystruct
= (popupstruct
*) malloc(sizeof(popupstruct
));
395 okaystruct
->buttonptr
= savebutton
;
396 okaystruct
->popup
= popup
;
397 okaystruct
->filter
= NULL
;
399 XtPopup(popup
, XtGrabNone
);
401 /* reposition the "Dismiss" button to center */
403 XtSetArg(wargs
[0], XtNwidth
, &bwidth
);
404 XtGetValues(cancelbutton
, wargs
, 1);
405 XtnSetArg(XtNx
, ((helpwidth
- bwidth
) >> 1));
406 XtSetValues(cancelbutton
, wargs
, n
); n
= 0;
408 XtSetArg(wargs
[0], XtNheight
, &pheight
);
409 XtGetValues(help2
, wargs
, 1);
411 if (pheight
> (ymax
- 8)) {
412 XtnSetArg(XtNheight
, ymax
- 8);
413 XtSetValues(help2
, wargs
, n
); n
= 0;
416 XtAddEventHandler(hsb
, ButtonMotionMask
| ButtonPressMask
, False
,
417 (XtEventHandler
)simplescroll
, hspace
);
419 /* Expose and End callbacks */
421 XtAddCallback(cancelbutton
, XtNselect
, (XtCallbackProc
)destroypopup
, okaystruct
);
422 XtAddCallback(hspace
, XtNexpose
, (XtCallbackProc
)exposehelp
, NULL
);
423 XtAddCallback(hsb
, XtNexpose
, (XtCallbackProc
)showhsb
, NULL
);
426 /*----------------------------------------------*/
427 /* Very simple scroll mechanism (grab-and-pan) */
428 /*----------------------------------------------*/
430 void simplescroll(xcWidget hsb
, xcWidget hspace
, XMotionEvent
*event
)
432 Dimension oldtop
= helptop
;
434 helptop
= (((int)(event
->y
) * helpheight
) / hheight
) - (hheight
/ 2);
436 if (helptop
< 0) helptop
= 0;
437 else if (helptop
> helpheight
- hheight
) helptop
= helpheight
- hheight
;
439 if (helptop
!= oldtop
) {
440 showhsb(hsb
, NULL
, NULL
);
445 /*----------------------------------------------*/
446 /* Expose callback for the help scrollbar */
447 /*----------------------------------------------*/
449 void showhsb(xcWidget hsb
, caddr_t clientdata
, caddr_t calldata
)
451 Window hwin
= xcWindow(hsb
);
459 scale
= Tcl_GetVar2(xcinterp
, "XCOps", "scale", TCL_GLOBAL_ONLY
);
460 sbarsize
= SBARSIZE
* atoi(scale
);
465 if (helppix
== (Pixmap
)NULL
) printhelppix();
466 if (helpheight
== 0) helpheight
= 1;
468 pstart
= (helptop
* hheight
) / helpheight
;
469 pheight
= (hheight
* hheight
) / helpheight
;
471 if (pheight
< 3) pheight
= 3;
473 XClearArea(dpy
, hwin
, 0, 0, sbarsize
, pstart
, False
);
474 XClearArea(dpy
, hwin
, 0, pstart
+ pheight
, sbarsize
,
475 hheight
- (pstart
+ pheight
), False
);
477 XSetForeground(dpy
, hgc
, colorlist
[BARCOLOR
].color
.pixel
);
478 XFillRectangle(dpy
, hwin
, hgc
, 0, pstart
, sbarsize
, pheight
);
481 /*----------------------------------------------*/
482 /* Expose callback for the help window */
483 /*----------------------------------------------*/
485 void exposehelp(xcWidget hspace
, caddr_t clientdata
, caddr_t calldata
)
489 XtSetArg(wargs
[0], XtNheight
, &hheight
);
490 XtGetValues(hspace
, wargs
, 1);
492 if (helppix
== (Pixmap
)NULL
) printhelppix();
493 if (hheight
< 1) hheight
= 1;
498 /*----------------------------------------------*/
499 /* Expose callback for the help window */
500 /*----------------------------------------------*/
502 void printhelp(xcWidget hspace
)
504 Window hwin
= xcWindow(hspace
);
507 /* Draw the pixmap to the window */
509 XCopyArea(dpy
, helppix
, hwin
, hgc
, 0, helptop
- 5, helpwidth
, helpheight
,
512 /* flush out multiple expose events */
514 while (XCheckWindowEvent(dpy
, hwin
, ExposureMask
, &discard
) == True
);
519 /*----------------------------------------------------------------------*/
520 /* The TCL version assumes the existence of command "helpwindow". */
521 /*----------------------------------------------------------------------*/
525 void starthelp(xcWidget button
, caddr_t clientdata
, caddr_t calldata
)
527 Tcl_Eval(xcinterp
, "catch xcircuit::helpwindow");
530 #endif /* !TCL_WRAPPER */