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
;
315 if (help_up
) return; /* no multiple help windows */
317 /* for positioning the help window outside of the xcircuit */
318 /* window, get information about the display width and height */
319 /* and the xcircuit window. */
321 /* The "- 50" leaves space for the Windows-95-type title bar that */
322 /* runs across the bottom of the screen in some window managers */
323 /* (specifically, fvwm95 which is the default for RedHat Linux) */
325 xmax
= DisplayWidth(dpy
, DefaultScreen(dpy
)) - 100;
326 ymax
= DisplayHeight(dpy
, DefaultScreen(dpy
)) - 50;
328 XtnSetArg(XtNwidth
, &areawidth
);
329 XtGetValues(areawin
->area
, wargs
, n
); n
= 0;
330 XtTranslateCoords(areawin
->area
, (Position
) (areawidth
+ 10), -50,
333 /* Always direct the call to the main menu button. */
334 button
= OptionsHelpButton
;
336 savebutton
= getgeneric(button
, starthelp
, NULL
);
338 /* Generate the pixmap and write the help text to it */
340 if (helppix
== (Pixmap
)NULL
) printhelppix();
342 /* Use the pixmap size to size the help window */
344 if (xpos
+ helpwidth
+ SBARSIZE
> xmax
) xpos
= xmax
- helpwidth
- SBARSIZE
- 4;
345 if (ypos
+ helpheight
> ymax
) ypos
= ymax
- helpheight
- 4;
346 if (ypos
< 4) ypos
= 4;
348 XtnSetArg(XtNx
, xpos
);
349 XtnSetArg(XtNy
, ypos
);
350 popup
= XtCreatePopupShell("help", transientShellWidgetClass
,
351 button
, wargs
, n
); n
= 0;
356 XtnSetArg(XtNyResizable
, True
);
357 XtnSetArg(XtNxResizable
, False
);
358 help2
= XtCreateManagedWidget("help2", XwformWidgetClass
,
359 popup
, wargs
, n
); n
= 0;
361 XtnSetArg(XtNfont
, appdata
.xcfont
);
362 cancelbutton
= XtCreateManagedWidget("Dismiss", XwmenuButtonWidgetClass
,
363 help2
, wargs
, n
); n
= 0;
365 XtnSetArg(XtNwidth
, helpwidth
);
366 XtnSetArg(XtNheight
, areawin
->height
);
367 XtnSetArg(XtNyRefWidget
, cancelbutton
);
368 XtnSetArg(XtNyAddHeight
, True
);
369 XtnSetArg(XtNyAttachBottom
, True
);
370 XtnSetArg(XtNyResizable
, True
);
371 XtnSetArg(XtNborderWidth
, 0);
372 XtnSetArg(XtNxAttachRight
, False
);
373 hspace
= XtCreateManagedWidget("HSpace", XwworkSpaceWidgetClass
,
374 help2
, wargs
, n
); n
= 0;
376 /* Create scrollbar */
377 XtnSetArg(XtNwidth
, SBARSIZE
);
378 XtnSetArg(XtNxRefWidget
, hspace
);
379 XtnSetArg(XtNxAddWidth
, True
);
380 XtnSetArg(XtNyRefWidget
, cancelbutton
);
381 XtnSetArg(XtNyAddHeight
, True
);
382 XtnSetArg(XtNyResizable
, True
);
383 XtnSetArg(XtNyAttachBottom
, True
);
384 XtnSetArg(XtNborderWidth
, 1);
385 hsb
= XtCreateManagedWidget("HSB", XwworkSpaceWidgetClass
,
386 help2
, wargs
, n
); n
= 0;
388 okaystruct
= (popupstruct
*) malloc(sizeof(popupstruct
));
389 okaystruct
->buttonptr
= savebutton
;
390 okaystruct
->popup
= popup
;
391 okaystruct
->filter
= NULL
;
393 XtPopup(popup
, XtGrabNone
);
395 /* reposition the "Dismiss" button to center */
397 XtSetArg(wargs
[0], XtNwidth
, &bwidth
);
398 XtGetValues(cancelbutton
, wargs
, 1);
399 XtnSetArg(XtNx
, ((helpwidth
- bwidth
) >> 1));
400 XtSetValues(cancelbutton
, wargs
, n
); n
= 0;
402 XtSetArg(wargs
[0], XtNheight
, &pheight
);
403 XtGetValues(help2
, wargs
, 1);
405 if (pheight
> (ymax
- 8)) {
406 XtnSetArg(XtNheight
, ymax
- 8);
407 XtSetValues(help2
, wargs
, n
); n
= 0;
410 XtAddEventHandler(hsb
, ButtonMotionMask
| ButtonPressMask
, False
,
411 (XtEventHandler
)simplescroll
, hspace
);
413 /* Expose and End callbacks */
415 XtAddCallback(cancelbutton
, XtNselect
, (XtCallbackProc
)destroypopup
, okaystruct
);
416 XtAddCallback(hspace
, XtNexpose
, (XtCallbackProc
)exposehelp
, NULL
);
417 XtAddCallback(hsb
, XtNexpose
, (XtCallbackProc
)showhsb
, NULL
);
420 /*----------------------------------------------*/
421 /* Very simple scroll mechanism (grab-and-pan) */
422 /*----------------------------------------------*/
424 void simplescroll(xcWidget hsb
, xcWidget hspace
, XMotionEvent
*event
)
426 Dimension oldtop
= helptop
;
428 helptop
= (((int)(event
->y
) * helpheight
) / hheight
) - (hheight
/ 2);
430 if (helptop
< 0) helptop
= 0;
431 else if (helptop
> helpheight
- hheight
) helptop
= helpheight
- hheight
;
433 if (helptop
!= oldtop
) {
434 showhsb(hsb
, NULL
, NULL
);
439 /*----------------------------------------------*/
440 /* Expose callback for the help scrollbar */
441 /*----------------------------------------------*/
443 void showhsb(xcWidget hsb
, caddr_t clientdata
, caddr_t calldata
)
445 Window hwin
= xcWindow(hsb
);
450 if (helppix
== (Pixmap
)NULL
) printhelppix();
451 if (helpheight
== 0) helpheight
= 1;
453 pstart
= (helptop
* hheight
) / helpheight
;
454 pheight
= (hheight
* hheight
) / helpheight
;
456 if (pheight
< 3) pheight
= 3;
458 XClearArea(dpy
, hwin
, 0, 0, SBARSIZE
, pstart
, False
);
459 XClearArea(dpy
, hwin
, 0, pstart
+ pheight
, SBARSIZE
,
460 hheight
- (pstart
+ pheight
), False
);
462 XSetForeground(dpy
, hgc
, colorlist
[BARCOLOR
].color
.pixel
);
463 XFillRectangle(dpy
, hwin
, hgc
, 0, pstart
, SBARSIZE
, pheight
);
466 /*----------------------------------------------*/
467 /* Expose callback for the help window */
468 /*----------------------------------------------*/
470 void exposehelp(xcWidget hspace
, caddr_t clientdata
, caddr_t calldata
)
474 XtSetArg(wargs
[0], XtNheight
, &hheight
);
475 XtGetValues(hspace
, wargs
, 1);
477 if (helppix
== (Pixmap
)NULL
) printhelppix();
478 if (hheight
< 1) hheight
= 1;
483 /*----------------------------------------------*/
484 /* Expose callback for the help window */
485 /*----------------------------------------------*/
487 void printhelp(xcWidget hspace
)
489 Window hwin
= xcWindow(hspace
);
492 /* Draw the pixmap to the window */
494 XCopyArea(dpy
, helppix
, hwin
, hgc
, 0, helptop
- 5, helpwidth
, helpheight
,
497 /* flush out multiple expose events */
499 while (XCheckWindowEvent(dpy
, hwin
, ExposureMask
, &discard
) == True
);
504 /*----------------------------------------------------------------------*/
505 /* The TCL version assumes the existence of command "helpwindow". */
506 /*----------------------------------------------------------------------*/
510 void starthelp(xcWidget button
, caddr_t clientdata
, caddr_t calldata
)
512 Tcl_Eval(xcinterp
, "catch xcircuit::helpwindow");
515 #endif /* !TCL_WRAPPER */