home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
x
/
volume8
/
xfig2.8
/
part18
/
change.c
Wrap
C/C++ Source or Header
|
1990-07-03
|
39KB
|
1,534 lines
/*
* FIG : Facility for Interactive Generation of figures
*
* Created March 1990 by Jon Tombs <jon@uk.ac.oxford.robots>
* This is my first X program please excuse the style, probably
* only works with X11R4
* Last Update 1st April 1989
*
* %W% %G%
*
* Based on the file of the same name from the fig-fs distribution:
*
* Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
* January 1985.
* 1st revision : Aug 1985.
*
* Change function implemented by Frank Schmuck (schmuck@svax.cs.cornell.edu)
* July 1988.
*/
#include "fig.h"
#include "resources.h"
#include "func.h"
#include "object.h"
#include "paintop.h"
#include "font.h"
#include "psfonts.h"
#define TOLERANCE 7
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) > (b)) ? (a) : (b))
extern char *panel_get_value();
extern Widget make_popup_menu();
extern void toggle();
extern (*canvas_kbd_proc)();
extern (*canvas_locmove_proc)();
extern (*canvas_leftbut_proc)();
extern (*canvas_middlebut_proc)();
extern (*canvas_rightbut_proc)();
extern (*return_proc)();
extern null_proc();
extern set_popupmenu();
extern F_text *text_search();
extern int foreground_color, background_color;
extern Pixmap font_menu_bitmaps[];
extern int *font_sel; /* pointer to store font selected from popup */
extern Widget image_widget; /* which widget to store image of font in */
extern Window canvas_win;
extern change_text();
extern change_item();
extern change_depth_up();
extern change_depth_down();
extern void Quit();
static void new_generic_values();
static generic_window();
static font_image_panel();
static int_panel();
static str_panel();
static toggle_panel();
static xy_panel();
static f_pos_panel();
static get_f_pos();
static points_panel();
static get_points();
static void line_style_select();
static void text_adjust_select();
static Widget popup, form;
static Widget below, beside;
extern F_line *line_search(), *copy_line();
extern F_arc *arc_search(), *copy_arc();
extern F_ellipse *ellipse_search(), *copy_ellipse();
extern F_text *text_search(), *copy_text();
extern F_spline *spline_search(), *copy_spline();
extern F_compound *compound_search();
extern F_arrow *forward_arrow(), *backward_arrow();
extern F_compound objects;
#define NUM_IMAGES 15
extern PIXRECT cirrad_ic, cirdia_ic, ellrad_ic, elldia_ic,
c_spl_ic, spl_ic, c_intspl_ic, intspl_ic,
line_ic, polygon_ic, box_ic, arc_box_ic,
arc_ic, text_ic, blank_ic;
extern int SIDERULER_WIDTH, PANL_WID;
extern int RHS_PANL;
extern float cur_dashlength;
extern float cur_dotgap;
/* not use init_change();*/
static int done_compound();
static int done_line();
static int done_text();
static int done_arc();
static int done_ellipse();
static int done_spline();
static F_line *new_line;
static F_ellipse *new_ellipse;
static F_text *new_text;
static F_spline *new_spline;
static F_arc *new_arc;
static F_compound *new_compound;
static Widget label;
static Widget thickness_panel;
static Widget color_panel;
static Widget depth_panel;
static Widget angle_panel;
static Widget adjust_panel;
static Widget area_fill_panel;
static Widget fill_pct_label;
static Widget style_panel;
static Widget style_val_panel;
static Widget for_arrow_panel;
static Widget back_arrow_panel;
static Widget text_panel;
static Widget x1_panel, y1_panel;
static Widget x2_panel, y2_panel;
static Widget x3_panel, y3_panel;
static Widget font_panel;
static Widget font_size_panel;
static Widget filled_panel;
static Widget radius;
static Widget entry, menu, adjust_menu;
static Widget but1;
Arg args[12];
#define MAX_POINTS 100
static Widget px_panel[MAX_POINTS];
static Widget py_panel[MAX_POINTS];
static int ellipse_flag;
static int no_fill_flag;
static int (*done_proc)();
static int button_result;
static int text_adjust;
static int new_font;
#define CANCEL 0
#define DONE 1
#define APPLY 2
static struct {
int thickness;
int color;
int depth;
int style;
float style_val;
int pen;
int area_fill;
int for_arrow;
int back_arrow;
} generic_vals;
#define put_generic_vals(x) \
generic_vals.thickness = x->thickness; \
generic_vals.color = x->color; \
generic_vals.depth = x->depth; \
generic_vals.style = x->style; \
generic_vals.style_val = x->style_val; \
generic_vals.pen = x->pen; \
generic_vals.area_fill = x->area_fill
#define get_generic_vals(x) \
new_generic_values(NULL, NULL); \
x->thickness = generic_vals.thickness; \
x->color = generic_vals.color; \
x->depth = generic_vals.depth; \
x->style = generic_vals.style; \
x->style_val = generic_vals.style_val; \
x->pen = generic_vals.pen; \
x->area_fill = generic_vals.area_fill
#define put_generic_arrows(x) \
generic_vals.for_arrow = (x->for_arrow != NULL); \
generic_vals.back_arrow = (x->back_arrow != NULL)
#define get_generic_arrows(x) \
if (x->for_arrow) \
free((char*)x->for_arrow); \
if (x->back_arrow) \
free((char*)x->back_arrow); \
x->for_arrow = (generic_vals.for_arrow)? forward_arrow(): NULL; \
x->back_arrow = (generic_vals.back_arrow)? backward_arrow(): NULL
change_item_selected()
{
canvas_kbd_proc = null_proc;
canvas_locmove_proc = null_proc;
canvas_leftbut_proc = change_item;
canvas_middlebut_proc = null_proc;
canvas_rightbut_proc = set_popupmenu;
return_proc = change_item_selected;
set_cursor(&pick9_cursor);
reset_action_on();
}
change_item(x, y)
int x, y;
{
extern F_line *line_search();
extern F_arc *arc_search();
extern F_ellipse *ellipse_search();
extern F_text *text_search();
extern F_spline *spline_search();
extern F_compound *compound_search();
F_line *l;
F_arc *a;
F_ellipse *e;
F_text *t;
F_spline *s;
F_compound *c;
int dummy;
if ((l = line_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL) {
make_window_line(l);
}
else if ((t = text_search(x, y)) != NULL) {
make_window_text(t);
}
else if ((e = ellipse_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL){
make_window_ellipse(e);
}
else if ((a = arc_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL){
make_window_arc(a);
}
else if ((s = spline_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL) {
make_window_spline(s);
}
else if ((c = compound_search(x, y, TOLERANCE, &dummy, &dummy)) != NULL)
make_window_compound(c);
else
return;
XtPopup(popup, XtGrabExclusive);
}
make_window_compound(c)
F_compound *c;
{
generic_window("COMPOUND", "Cannot be changed!", &blank_ic,
done_compound, 0, 0);
}
static
done_compound()
{
if (button_result != APPLY) {
clean_up();
show_pointmarker();
}
}
make_window_line(l)
F_line *l;
{
struct f_point p1, p2;
new_line = copy_line(l);
new_line->next = l;
put_generic_vals(new_line);
switch (new_line->type) {
case T_POLYLINE:
put_generic_arrows(new_line);
generic_window("POLYLINE", "Polyline", &line_ic, done_line, 1, 1);
points_panel(new_line->points, 0);
break;
case T_POLYGON:
put_generic_arrows(new_line);
generic_window("POLYLINE", "Polygon", &polygon_ic, done_line, 1, 1);
points_panel(new_line->points, 1);
break;
case T_BOX:
generic_window("POLYLINE", "Box", &box_ic, done_line, 1, 0);
p1 = *new_line->points;
p2 = *new_line->points->next->next;
xy_panel(p1.x, p1.y, "Top Left", &x1_panel, &y1_panel);
xy_panel(p2.x, p2.y, "Bottom Right", &x2_panel, &y2_panel);
break;
case T_ARC_BOX:
generic_window("POLYLINE", "ArcBox", &arc_box_ic, done_line, 1, 0);
p1 = *new_line->points;
p2 = *new_line->points->next->next;
xy_panel(p1.x, p1.y, "Top Left", &x1_panel, &y1_panel);
xy_panel(p2.x, p2.y, "Bottom Right", &x2_panel, &y2_panel);
int_panel(new_line->radius, "Radius:", &radius);
break;
}
}
static
get_new_line_values()
{
struct f_point p1, p2, *p;
get_generic_vals(new_line);
if ((new_line->type != T_BOX) && (new_line->type != T_ARC_BOX)) {
get_generic_arrows(new_line);
get_points(new_line->points, (new_line->type == T_POLYGON));
}
else {
p1.x = atoi(panel_get_value(x1_panel));
p1.y = atoi(panel_get_value(y1_panel));
p2.x = atoi(panel_get_value(x2_panel));
p2.y = atoi(panel_get_value(y2_panel));
p = new_line->points;
p->x = p1.x; p->y = p1.y; p = p->next;
p->x = p2.x; p->y = p1.y; p = p->next;
p->x = p2.x; p->y = p2.y; p = p->next;
p->x = p1.x; p->y = p2.y; p = p->next;
p->x = p1.x; p->y = p1.y;
if (new_line->type == T_ARC_BOX)
new_line->radius = atoi(panel_get_value(radius));
}
}
static
done_line()
{
F_line *old_line;
draw_line(new_line, ERASE);
old_line = new_line->next;
switch (button_result) {
case APPLY:
get_new_line_values();
draw_line(new_line, PAINT);
break;
case DONE:
clean_up();
get_new_line_values();
set_action_object(F_CHANGE, O_POLYLINE);
new_line->next = NULL;
delete_line(&objects.lines, old_line);
insert_line(&objects.lines, new_line);
set_latestline(old_line);
old_line->next = new_line;
draw_line(new_line, PAINT);
show_pointmarker();
set_modifiedflag();
break;
case CANCEL:
clean_up();
new_line->next = NULL;
free_line(&new_line);
draw_line(old_line, PAINT);
show_pointmarker();
break;
}
}
#define round(x) ((int) ((x) + ((x >= 0)? 0.5: -0.5)))
make_window_text(t)
F_text *t;
{
PIX_FONT temp_font;
int i,cw;
static char * adjust_item_names[] = {
"Left Justified ", "Centered ", "Right Justified"};
new_text = copy_text(t);
new_text->next = t;
generic_window("TEXT", "", &text_ic, done_text, 0, 0);
#ifdef notdef
subtype_panel = panel_create_item(change_panel, PANEL_CYCLE,
PANEL_LABEL_X, ATTR_COL(2),
PANEL_LABEL_Y, ATTR_ROW(2),
PANEL_VALUE_X, ATTR_COL(20),
PANEL_VALUE_Y, ATTR_ROW(2),
PANEL_LABEL_STRING, "Text alignment:",
PANEL_CHOICE_STRINGS, "left justified", "center justified",
"right justified", 0,
PANEL_VALUE, new_text->type,
0);
font_panel = panel_create_item(change_panel, PANEL_CYCLE,
PANEL_LABEL_X, ATTR_COL(2),
PANEL_LABEL_Y, ATTR_ROW(3),
PANEL_VALUE_X, ATTR_COL(20),
PANEL_VALUE_Y, ATTR_ROW(3),
PANEL_LABEL_STRING, "Font:",
PANEL_CHOICE_STRINGS, "default", "roman",
"bold", "italic",
"modern", "typewriter", 0,
PANEL_VALUE, new_text->font,
0);
#endif
text_adjust = new_text->type; /* get current justification */
new_font = new_text->font; /* get current font */
int_panel(new_text->size, "Size:", &font_size_panel);
int_panel(new_text->color, "Color:", &color_panel);
int_panel(new_text->depth, "Depth:", &depth_panel);
int_panel(round(180/M_PI * new_text->angle), "Angle:", &angle_panel);
/* make text justification menu */
XtSetArg(args[0], XtNfromVert, below);
adjust_panel = XtCreateManagedWidget(
adjust_item_names[text_adjust], menuButtonWidgetClass,
form, args, ONE);
below = adjust_panel;
adjust_menu = make_popup_menu(adjust_item_names, XtNumber(adjust_item_names),
adjust_panel, text_adjust_select);
xy_panel(new_text->base_x,new_text->base_y, "Origin:", &x1_panel, &y1_panel);
font_image_panel(font_menu_bitmaps[new_text->font], "Font:", &font_panel);
str_panel(new_text->cstring, "Text:", &text_panel);
}
static
get_new_text_values()
{
char *s;
PR_SIZE size;
#ifdef notdef
new_text->type = atoi(panel_get_value(subtype_panel));
new_text->font = atoi(panel_get_value(font_panel));
#else
new_text->type = text_adjust;
new_text->font = new_font;
#endif
new_text->size = atoi(panel_get_value(font_size_panel));
if (new_text->size < 1)
{
new_text->size = 1;
panel_set_value(font_size_panel, "1");
}
new_text->color = atoi(panel_get_value(color_panel));
new_text->depth = atoi(panel_get_value(depth_panel));
new_text->angle = M_PI/180*atoi(panel_get_value(angle_panel));
new_text->base_x = atoi(panel_get_value(x1_panel));
new_text->base_y = atoi(panel_get_value(y1_panel));
if (new_text->cstring)
cfree(new_text->cstring);
s = panel_get_value(text_panel);
new_text->cstring = (char *) calloc((unsigned)(strlen(s)+1), sizeof(char));
strcpy(new_text->cstring, s);
size = pf_textwidth(new_text->font, new_text->size, strlen(s), s);
new_text->height = size.y;
new_text->length = size.x;
}
static
done_text()
{
F_text *old_text;
draw_text(new_text, INV_PAINT);
old_text = new_text->next;
switch (button_result) {
case APPLY:
get_new_text_values();
break;
case DONE:
clean_up();
get_new_text_values();
set_action_object(F_CHANGE, O_TEXT);
new_text->next = NULL;
delete_text(&objects.texts, old_text);
insert_text(&objects.texts, new_text);
set_latesttext(old_text);
old_text->next = new_text;
show_pointmarker();
set_modifiedflag();
break;
case CANCEL:
clean_up();
new_text->next = NULL;
free_text(&new_text);
new_text = old_text;
show_pointmarker();
break;
}
draw_text(new_text, PAINT);
}
make_window_ellipse(e)
F_ellipse *e;
{
char *s1, *s2;
PIXRECT *image;
new_ellipse = copy_ellipse(e);
new_ellipse->next = e;
switch (new_ellipse->type) {
case T_ELLIPSE_BY_RAD:
s1 = "ELLIPSE";
s2 = "specified by radius";
ellipse_flag = 1;
image = &ellrad_ic;
break;
case T_ELLIPSE_BY_DIA:
s1 = "ELLIPSE";
s2 = "specified by diameter";
ellipse_flag = 1;
image = &elldia_ic;
break;
case T_CIRCLE_BY_RAD:
s1 = "CIRCLE";
s2 = "specified by radius";
ellipse_flag = 0;
image = &cirrad_ic;
break;
case T_CIRCLE_BY_DIA:
s1 = "CIRCLE";
s2 = "specified by diameter";
ellipse_flag = 0;
image = &cirdia_ic;
break;
}
put_generic_vals(new_ellipse);
generic_window(s1, s2, image, done_ellipse, 1, 0);
int_panel(round(180/M_PI * new_ellipse->angle), "Angle:", &angle_panel);
if (ellipse_flag) {
f_pos_panel(&new_ellipse->center, "Center ",
&x1_panel, &y1_panel);
f_pos_panel(&new_ellipse->radiuses, "Radiuses",
&x2_panel, &y2_panel);
}
else {
f_pos_panel(&new_ellipse->center,"Center",
&x1_panel, &y1_panel);
int_panel(new_ellipse->radiuses.x, "Radius",
&x2_panel);
}
}
static
get_new_ellipse_values()
{
F_pos old_center;
F_pos old_radiuses;
# define adjust_ref(s,f) \
s.f = new_ellipse->center.f + \
((s.f - old_center.f)*new_ellipse->radiuses.f)/old_radiuses.f
get_generic_vals(new_ellipse);
new_ellipse->angle = M_PI/180*atoi(panel_get_value(angle_panel));
old_center = new_ellipse->center;
old_radiuses = new_ellipse->radiuses;
get_f_pos(&new_ellipse->center, x1_panel, y1_panel);
if (ellipse_flag)
get_f_pos(&new_ellipse->radiuses, x2_panel, y2_panel);
else
new_ellipse->radiuses.x = new_ellipse->radiuses.y =
atoi(panel_get_value(x2_panel));
adjust_ref(new_ellipse->start, x);
adjust_ref(new_ellipse->start, y);
adjust_ref(new_ellipse->end, x);
adjust_ref(new_ellipse->end, y);
}
static
done_ellipse()
{
F_ellipse *old_ellipse;
draw_ellipse(new_ellipse, background_color);
old_ellipse = new_ellipse->next;
switch (button_result) {
case APPLY:
get_new_ellipse_values();
draw_ellipse(new_ellipse, foreground_color);
break;
case DONE:
clean_up();
get_new_ellipse_values();
set_action_object(F_CHANGE, O_ELLIPSE);
new_ellipse->next = NULL;
delete_ellipse(&objects.ellipses, old_ellipse);
insert_ellipse(&objects.ellipses, new_ellipse);
set_latestellipse(old_ellipse);
old_ellipse->next = new_ellipse;
draw_ellipse(new_ellipse, foreground_color);
show_pointmarker();
set_modifiedflag();
break;
case CANCEL:
clean_up();
new_ellipse->next = NULL;
free_ellipse(&new_ellipse);
draw_ellipse(old_ellipse, foreground_color);
show_pointmarker();
break;
}
}
make_window_arc(a)
F_arc *a;
{
new_arc = copy_arc(a);
new_arc->next = a;
put_generic_vals(new_arc);
put_generic_arrows(new_arc);
generic_window("ARC", "Specified by 3 points", &arc_ic, done_arc, 1, 1);
f_pos_panel(&new_arc->point[0], "p1", &x1_panel, &y1_panel);
f_pos_panel(&new_arc->point[1], "p2", &x2_panel, &y2_panel);
f_pos_panel(&new_arc->point[2], "p3", &x3_panel, &y3_panel);
}
static
get_new_arc_values()
{
F_pos p0, p1, p2;
float cx, cy;
get_generic_vals(new_arc);
get_generic_arrows(new_arc);
get_f_pos(&p0, x1_panel, y1_panel);
get_f_pos(&p1, x2_panel, y2_panel);
get_f_pos(&p2, x3_panel, y3_panel);
if (compute_arccenter(p0, p1, p2, &cx, &cy)) {
new_arc->point[0] = p0;
new_arc->point[1] = p1;
new_arc->point[2] = p2;
new_arc->center.x = cx;
new_arc->center.y = cy;
new_arc->direction = compute_direction(p0, p1, p2);
}
else
put_msg("Invalid ARC points!");
}
static
done_arc()
{
F_arc *old_arc;
draw_arc(new_arc, background_color);
old_arc = new_arc->next;
switch (button_result) {
case APPLY:
get_new_arc_values();
draw_arc(new_arc, foreground_color);
break;
case DONE:
clean_up();
get_new_arc_values();
set_action_object(F_CHANGE, O_ARC);
new_arc->next = NULL;
delete_arc(&objects.arcs, old_arc);
insert_arc(&objects.arcs, new_arc);
set_latestarc(old_arc);
old_arc->next = new_arc;
draw_arc(new_arc, foreground_color);
show_pointmarker();
set_modifiedflag();
break;
case CANCEL:
clean_up();
new_arc->next = NULL;
free_arc(&new_arc);
draw_arc(old_arc, foreground_color);
show_pointmarker();
break;
}
}
make_window_spline(s)
F_spline *s;
{
new_spline = copy_spline(s);
new_spline->next = s;
put_generic_vals(new_spline);
put_generic_arrows(new_spline);
switch (new_spline->type) {
case T_OPEN_NORMAL:
generic_window("SPLINE", "Normal open", &spl_ic,
done_spline, 1, 1);
points_panel(new_spline->points, 0);
break;
case T_CLOSED_NORMAL:
generic_window("SPLINE", "Normal closed", &c_spl_ic,
done_spline, 1, 1);
points_panel(new_spline->points, 1);
break;
case T_OPEN_INTERPOLATED:
generic_window("SPLINE", "Interpolated open", &intspl_ic,
done_spline, 1, 1);
points_panel(new_spline->points, 0);
break;
case T_CLOSED_INTERPOLATED:
generic_window("SPLINE","Interpolated closed", &c_intspl_ic,
done_spline, 1,1);
points_panel(new_spline->points, 1);
break;
}
}
static
done_spline()
{
F_spline *old_spline;
draw_spline(new_spline, ERASE);
old_spline = new_spline->next;
switch (button_result) {
case APPLY:
get_generic_vals(new_spline);
get_generic_arrows(new_spline);
get_points(new_spline->points, closed_spline(new_spline));
if (int_spline(new_spline))
remake_control_points(new_spline);
draw_spline(new_spline, PAINT);
break;
case DONE:
clean_up();
get_generic_vals(new_spline);
get_generic_arrows(new_spline);
get_points(new_spline->points, closed_spline(new_spline));
set_action_object(F_CHANGE, O_SPLINE);
if (int_spline(new_spline))
remake_control_points(new_spline);
new_spline->next = NULL;
delete_spline(&objects.splines, old_spline);
insert_spline(&objects.splines, new_spline);
set_latestspline(old_spline);
old_spline->next = new_spline;
draw_spline(new_spline, PAINT);
show_pointmarker();
set_modifiedflag();
break;
case CANCEL:
clean_up();
new_spline->next = NULL;
free_spline(&new_spline);
draw_spline(old_spline, PAINT);
show_pointmarker();
break;
}
}
/*
* The following routines
* change_line, change_arc, change_ellipse, change_spline,
* change_text
* are called by the UNDO function (undo.c).
* saved_objects.xxxx contains a pointer to the original, unchanged version
* of the object. saved_objects.xxxx->next contains a pointer to the new,
* changed version of the object.
*/
change_line(lold, lnew)
F_line *lold, *lnew;
{
lnew->next = NULL;
delete_line(&objects.lines, lold);
insert_line(&objects.lines, lnew);
set_latestline(lold);
lold->next = lnew;
draw_line(lold, ERASE);
draw_line(lnew, PAINT);
}
change_arc(aold, anew)
F_arc *aold, *anew;
{
anew->next = NULL;
delete_arc(&objects.arcs, aold);
insert_arc(&objects.arcs, anew);
set_latestarc(aold);
aold->next = anew;
draw_arc(aold, background_color);
draw_arc(anew, foreground_color);
}
change_ellipse(eold, enew)
F_ellipse *eold, *enew;
{
enew->next = NULL;
delete_ellipse(&objects.ellipses, eold);
insert_ellipse(&objects.ellipses, enew);
set_latestellipse(eold);
eold->next = enew;
draw_ellipse(eold, background_color);
draw_ellipse(enew, foreground_color);
}
change_spline(sold, snew)
F_spline *sold, *snew;
{
snew->next = NULL;
delete_spline(&objects.splines, sold);
insert_spline(&objects.splines, snew);
set_latestspline(sold);
sold->next = snew;
draw_spline(sold, ERASE);
draw_spline(snew, PAINT);
}
change_text(told, tnew)
F_text *told, *tnew;
{
tnew->next = NULL;
delete_text(&objects.texts, told);
insert_text(&objects.texts, tnew);
set_latesttext(told);
told->next = tnew;
draw_text(told, INV_PAINT);
draw_text(tnew, PAINT);
}
static void
new_generic_values()
{
int fill;
char buf[5];
char *val;
generic_vals.thickness = atoi(panel_get_value(thickness_panel));
generic_vals.color = atoi(panel_get_value(color_panel));
generic_vals.depth = atoi(panel_get_value(depth_panel));
if (!no_fill_flag)
{
val = panel_get_value(area_fill_panel);
if (*val >= ' ' && *val <= '9')
{
if ((fill = atoi(val)) > 100)
fill = 100;
generic_vals.area_fill = NUMFILLPATS - (fill / (100/(NUMFILLPATS-1)));
}
fill = (NUMFILLPATS - generic_vals.area_fill) * (100/(NUMFILLPATS-1));
sprintf(buf,"%d",fill);
panel_set_value(area_fill_panel,buf);
}
else
generic_vals.area_fill = 0;
}
static
new_arrow_values()
{
generic_vals.for_arrow = (int)panel_get_value(for_arrow_panel);
generic_vals.back_arrow = (int)panel_get_value(back_arrow_panel);
}
static char *
style_val_string(s, v)
int s;
double v;
{
static char buf[64];
switch(s) {
case SOLID_LINE:
sprintf(buf, " ");
return buf;
case DASH_LINE:
sprintf(buf, "dash length = %3.1f", v);
return buf;
case DOTTED_LINE:
sprintf(buf, "dot gap = %3.1f", v);
return buf;
}
return NULL;
}
static
done_button(panel_local,item, event)
Widget panel_local;
Widget *item;
int *event;
{
button_result = DONE;
done_proc();
Quit();
}
static
apply_button(panel_local,item, event)
Widget panel_local;
Widget *item;
int *event;
{
button_result = APPLY;
done_proc();
}
static
cancel_button(panel_local,item, event)
Widget panel_local;
Widget *item;
int *event;
{
button_result = CANCEL;
done_proc();
Quit();
}
/*
the following pix_table entries are guaranteed to be
initialized to 0 by the compiler
*/
static struct {
PIXRECT image;
Pixmap image_pm;
} pix_table[NUM_IMAGES];
static
generic_window(object_type, sub_type, icon, d_proc, generics, arrows)
char *object_type, *sub_type;
PIXRECT icon;
int (*d_proc)();
int generics, arrows;
{
char buf[64];
Position x_val, y_val;
Dimension width, height;
Dimension label_height, image_height;
int button_distance;
Cardinal n;
int i, fill, dist;
Widget image;
Pixmap image_pm;
static char * menu_item_names[] = {
"Solid Line ", "Dashed Line", "Dotted Line"};
XtSetArg(args[0], XtNwidth, &width);
XtSetArg(args[1], XtNheight, &height);
XtGetValues(tool, args, TWO);
XtTranslateCoords(tool, (Position) (width / 2), (Position) (height / 5),
&x_val, &y_val);
n=0;
XtSetArg(args[n], XtNx, x_val); n++;
XtSetArg(args[n], XtNy, y_val); n++;
popup = XtCreatePopupShell("change", transientShellWidgetClass, tool,
args, n);
form = XtCreateManagedWidget("form", formWidgetClass, popup,NULL, 0);
done_proc = d_proc;
sprintf(buf,"%s:%s",object_type, sub_type);
label = XtCreateManagedWidget(buf, labelWidgetClass, form, NULL, 0);
/* put in the image */
/* search to see if that pixmap has already been created */
image_pm = NULL;
for (i=0; i<NUM_IMAGES; i++)
{
if (pix_table[i].image == 0)
break;
if (pix_table[i].image == icon)
{
image_pm = pix_table[i].image_pm;
break;
}
}
/* doesn't already exist, create a pixmap from the data (ala panel.c) */
if (!image_pm)
{
image_pm = XCreateBitmapFromData(tool_d, canvas_win,
icon->data, icon->width, icon->height);
pix_table[i].image_pm = image_pm;
pix_table[i].image = icon;
}
n=0;
XtSetArg(args[n], XtNbitmap, image_pm); n++;
XtSetArg(args[n], XtNfromHoriz, label); n++;
XtSetArg(args[n], XtNtop, XtChainTop); n++;
XtSetArg(args[n], XtNbottom, XtChainTop); n++;
XtSetArg(args[n], XtNleft, XtChainRight); n++;
XtSetArg(args[n], XtNright, XtChainRight); n++;
image = XtCreateManagedWidget("image", labelWidgetClass, form, args, n);
/* get height of label widget and distance between widgets */
n = 0;
XtSetArg(args[n], XtNheight, &label_height); n++;
XtSetArg(args[n], XtNvertDistance, &button_distance); n++;
XtGetValues(label, args, n);
/* do the same for the image widget */
n = 0;
XtSetArg(args[n], XtNheight, &image_height); n++;
XtGetValues(image, args, n);
if (image_height > label_height)
dist = image_height - label_height + button_distance;
else
dist = button_distance;
n=0;
XtSetArg(args[n], XtNfromVert, label); n++;
XtSetArg(args[n], XtNvertDistance, dist); n++;
but1= XtCreateManagedWidget("done", commandWidgetClass, form, args, n);
XtAddCallback(but1, XtNcallback, done_button, NULL);
below = but1;
n=0;
XtSetArg(args[n], XtNfromHoriz, but1); n++;
XtSetArg(args[n], XtNfromVert,label); n++;
XtSetArg(args[n], XtNvertDistance, dist); n++;
but1= XtCreateManagedWidget("apply", commandWidgetClass, form, args, n);
XtAddCallback(but1, XtNcallback, apply_button, NULL);
n=0;
XtSetArg(args[0], XtNfromHoriz, but1); n++;
XtSetArg(args[1], XtNfromVert,label); n++;
XtSetArg(args[n], XtNvertDistance, dist); n++;
but1= XtCreateManagedWidget("cancel",commandWidgetClass, form, args, n);
XtAddCallback(but1, XtNcallback, cancel_button, NULL);
if (generics) {
int_panel(generic_vals.thickness, "Width:", &thickness_panel);
int_panel(generic_vals.color, "Color:", &color_panel);
int_panel(generic_vals.depth, "Depth:", &depth_panel);
if (generic_vals.area_fill == 0 ||
strcmp(sub_type,"Polyline") == 0) /* no area fill for polyline */
{
fill = 100;
no_fill_flag = TRUE;
}
else
{
fill = (NUMFILLPATS-generic_vals.area_fill) * (100/(NUMFILLPATS-1));
no_fill_flag = FALSE;
}
if (strcmp(sub_type,"Polyline") != 0) /* no area fill for polyline */
{
toggle_panel(no_fill_flag, no_fill_flag? "Not Filled": "Filled ",
&filled_panel);
int_panel(fill,"Fill%:", &area_fill_panel);
fill_pct_label = beside; /* save pointer to Fill% label */
XtSetArg(args[0], XtNsensitive, no_fill_flag? False: True);
XtSetArg(args[1], XtNvertDistance, 2);
XtSetValues(area_fill_panel, args, TWO);
XtSetValues(fill_pct_label, args, TWO);
if (no_fill_flag)
sprintf(buf," ");
else
sprintf(buf,"%d",fill);
panel_set_value(area_fill_panel,buf);
}
/* make popup line style menu */
XtSetArg(args[0], XtNfromVert, below);
style_panel = XtCreateManagedWidget(
menu_item_names[generic_vals.style], menuButtonWidgetClass,
form, args, ONE);
below = style_panel;
menu = make_popup_menu(menu_item_names, XtNumber(menu_item_names),
style_panel, line_style_select);
#ifdef notdef
}
if (arrows)
{
for_arrow_panel = panel_create_item(change_panel, PANEL_TOGGLE,
PANEL_LABEL_X, ATTR_COL(2),
PANEL_LABEL_Y, ATTR_ROW(10),
PANEL_VALUE_X, ATTR_COL(20),
PANEL_VALUE_Y, ATTR_ROW(10),
PANEL_LABEL_STRING, "Forward arrow:",
PANEL_VALUE, generic_vals.for_arrow,
PANEL_FEEDBACK, PANEL_MARKED,
PANEL_NOTIFY_PROC, new_arrow_values,
0);
back_arrow_panel = panel_create_item(change_panel, PANEL_TOGGLE,
PANEL_LABEL_X, ATTR_COL(2),
PANEL_LABEL_Y, ATTR_ROW(11),
PANEL_VALUE_X, ATTR_COL(20),
PANEL_VALUE_Y, ATTR_ROW(11),
PANEL_LABEL_STRING, "Backward arrow:",
PANEL_VALUE, generic_vals.back_arrow,
PANEL_FEEDBACK, PANEL_MARKED,
PANEL_NOTIFY_PROC, new_arrow_values,
0);
#endif /* not def */
}
}
/* make a button panel with the image 'pixmap' in it */
/* for the font selection */
void f_menu_popup();
static XtCallbackRec f_sel_callback[] =
{
{ f_menu_popup, NULL },
{ NULL, NULL },
};
static
font_image_panel(pixmap, label, pi_x)
Pixmap pixmap;
char *label;
Widget *pi_x;
{
char buf[32];
XtSetArg(args[0], XtNfromVert, below);
XtSetArg(args[1], XtNlabel, label);
below = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO);
XtSetArg(args[0], XtNfromVert, below);
XtSetArg(args[1], XtNvertDistance, 2);
XtSetArg(args[2], XtNbitmap, pixmap);
XtSetArg(args[3], XtNcallback, f_sel_callback);
*pi_x = XtCreateManagedWidget(label, commandWidgetClass, form, args, FOUR);
below = *pi_x;
}
/* come here when user presses font image button */
void
f_menu_popup()
{
font_sel = &new_font; /* store selected font number in new_font */
image_widget = font_panel; /* and image in this widget */
XtPopup(fontmenu,XtGrabNonexclusive); /* popup the font menu */
setup_fontmenu_cursor(); /* now define the cursor for the font menu */
}
/*
make a popup menu with "nent" button entries (labels) that call
"callback" when pressed
*/
Widget
make_popup_menu(entries, nent, parent, callback)
char *entries[];
int nent;
Widget parent;
XtCallbackProc callback;
{
Widget pop_menu,entry;
int i;
pop_menu = XtCreatePopupShell("menu", simpleMenuWidgetClass, parent,
NULL, ZERO);
for (i = 0; i < nent ; i++)
{
entry = XtCreateManagedWidget(entries[i], smeBSBObjectClass, pop_menu,
NULL, ZERO);
XtAddCallback(entry, XtNcallback, callback, (XtPointer) i);
}
return pop_menu;
}
static
int_panel(x, label, pi_x)
int x;
char *label;
Widget *pi_x;
{
char buf[32];
XtSetArg(args[0], XtNfromVert, below);
XtSetArg(args[1], XtNlabel, label);
beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO);
sprintf(buf, "%d", x);
XtSetArg(args[1], XtNstring, buf);
XtSetArg(args[2], XtNinsertPosition, strlen(buf));
XtSetArg(args[3], XtNfromHoriz, beside);
XtSetArg(args[4], XtNeditType, "append");
XtSetArg(args[5], XtNwidth, 40);
*pi_x = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args, SIX);
below = *pi_x;
}
/* don't allow newlines in text until we handle multiple line texts */
static String text_translations =
"<Key>Return: no-op(RingBell)\n\
Ctrl<Key>J: no-op(RingBell)\n\
Ctrl<Key>M: no-op(RingBell)\n";
static
str_panel(string, label, pi_x)
char *string;
char *label;
Widget *pi_x;
{
int width,nlines,i,n;
Dimension pwidth;
PIX_FONT temp_font;
XtSetArg(args[0], XtNfromVert, below);
XtSetArg(args[1], XtNlabel, label);
beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO);
/* get the font and width of above label widget */
n=0;
XtSetArg(args[n], XtNfont, &temp_font); n++;
XtSetArg(args[n], XtNwidth, &pwidth); n++;
XtGetValues(beside, args, n);
/* make panel as wide as image pane above less the label widget's width */
/* but at least 200 pixels wide */
width = max(FONT_PANE_WIDTH-pwidth+2, 200);
/* count number of lines in this text string */
nlines=1; /* number of lines in string */
for (i=0; i<strlen(string); i++)
{
if (string[i]=='\n')
{
nlines++;
}
}
if (nlines > 6) /* limit to displaying 6 lines and show scrollbars */
nlines=6;
n=0;
XtSetArg(args[n], XtNfromVert, below); n++;
XtSetArg(args[n], XtNstring, string); n++;
XtSetArg(args[n], XtNinsertPosition, strlen(string)); n++;
XtSetArg(args[n], XtNfromHoriz, beside); n++;
XtSetArg(args[n], XtNeditType, "edit"); n++;
XtSetArg(args[n], XtNwidth, width); n++;
XtSetArg(args[n], XtNheight, char_height(temp_font)*nlines+4); n++;
XtSetArg(args[n], XtNscrollHorizontal, XawtextScrollWhenNeeded);n++;
XtSetArg(args[n], XtNscrollVertical, XawtextScrollWhenNeeded); n++;
*pi_x = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args, n);
/* make Newline do nothing for now */
XtOverrideTranslations(*pi_x,XtParseTranslationTable(text_translations));
below = *pi_x;
}
static
toggle_panel(x, label, pi_x)
int x;
char *label;
Widget *pi_x;
{
XtSetArg(args[0], XtNfromVert, below);
XtSetArg(args[1], XtNlabel, label);
XtSetArg(args[2], XtNvalue, x);
*pi_x = XtCreateManagedWidget(label, toggleWidgetClass, form, args, THREE);
XtAddCallback(*pi_x, XtNcallback, toggle, NULL);
below = *pi_x;
}
static
xy_panel(x, y, label, pi_x, pi_y)
int x, y;
char *label;
Widget *pi_x, *pi_y;
{
char buf[32];
XtSetArg(args[0], XtNfromVert, below);
XtSetArg(args[1], XtNlabel, label);
below = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO);
XtSetArg(args[0], XtNfromVert, below);
XtSetArg(args[1], XtNvertDistance, 2);
XtSetArg(args[2], XtNlabel, "X:");
beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, THREE);
sprintf(buf, "%d", x);
XtSetArg(args[2], XtNstring, buf);
XtSetArg(args[3], XtNinsertPosition, strlen(buf));
XtSetArg(args[4], XtNfromHoriz, beside);
XtSetArg(args[5], XtNeditType, "append");
XtSetArg(args[6], XtNwidth, 40);
*pi_x = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args, SEVEN);
XtSetArg(args[2], XtNlabel, "Y:");
XtSetArg(args[3], XtNfromHoriz, *pi_x);
beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, FOUR);
sprintf(buf, "%d", y);
XtSetArg(args[2], XtNstring, buf);
XtSetArg(args[3], XtNfromHoriz, beside);
XtSetArg(args[4], XtNinsertPosition, strlen(buf));
XtSetArg(args[5], XtNeditType, "append");
XtSetArg(args[6], XtNwidth, 40);
*pi_y = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args ,SEVEN);
below = *pi_x;
}
static
f_pos_panel(fp, label, pi_x, pi_y)
F_pos *fp;
char *label;
Widget *pi_x, *pi_y;
{
char buf[32];
XtSetArg(args[0], XtNfromVert, below);
below = XtCreateManagedWidget(label, labelWidgetClass, form, args, ONE);
XtSetArg(args[0], XtNfromVert, below);
XtSetArg(args[1], XtNlabel, "X:");
beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO);
sprintf(buf, "%d", fp->x);
XtSetArg(args[1], XtNstring, buf);
XtSetArg(args[2], XtNinsertPosition, strlen(buf));
XtSetArg(args[3], XtNfromHoriz, beside);
XtSetArg(args[4], XtNeditType, "append");
XtSetArg(args[5], XtNwidth, 40);
*pi_x = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args, SIX);
XtSetArg(args[1], XtNlabel, "Y:");
XtSetArg(args[2], XtNfromHoriz, *pi_x);
beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, THREE);
sprintf(buf, "%d", fp->y);
XtSetArg(args[1], XtNstring, buf);
XtSetArg(args[2], XtNinsertPosition, strlen(buf));
XtSetArg(args[3], XtNfromHoriz, beside);
XtSetArg(args[4], XtNeditType, "append");
XtSetArg(args[5], XtNwidth, 40);
*pi_y = XtCreateManagedWidget(label, asciiTextWidgetClass, form, args ,SIX);
below = *pi_x;
}
static
get_f_pos(fp, pi_x, pi_y)
F_pos *fp;
Widget pi_x, pi_y;
{
fp->x = (atoi(panel_get_value(pi_x)));
fp->y = (atoi(panel_get_value(pi_y)));
}
static
points_panel(p, closed)
struct f_point *p;
int closed;
{
char buf[32];
char bufxy[32];
int i;
for (i = 0; p != NULL; i++) {
if (i >= MAX_POINTS)
break;
XtSetArg(args[0], XtNfromVert,below);
sprintf(buf,"X:%d",i);
XtSetArg(args[1], XtNlabel, buf);
beside = XtCreateManagedWidget(label, labelWidgetClass, form, args, TWO);
sprintf(bufxy, "%d", p->x);
XtSetArg(args[1], XtNstring, bufxy);
XtSetArg(args[2], XtNinsertPosition, strlen(bufxy));
XtSetArg(args[3], XtNfromHoriz, beside);
XtSetArg(args[4], XtNeditType, "append");
XtSetArg(args[5], XtNwidth, 40);
px_panel[i] = XtCreateManagedWidget("xy", asciiTextWidgetClass,
form, args, SIX);
sprintf(buf,"Y:%d",i);
XtSetArg(args[1], XtNlabel, buf);
XtSetArg(args[2], XtNfromHoriz, px_panel[i]);
beside = XtCreateManagedWidget(label, labelWidgetClass,
form, args, THREE);
sprintf(bufxy, "%d", p->y);
XtSetArg(args[1], XtNstring, bufxy);
XtSetArg(args[2], XtNinsertPosition, strlen(bufxy));
XtSetArg(args[3], XtNfromHoriz,beside);
XtSetArg(args[4], XtNeditType, "append");
XtSetArg(args[5], XtNwidth, 40);
py_panel[i] = XtCreateManagedWidget("xy", asciiTextWidgetClass,
form, args, SIX);
below = px_panel[i];
p = p->next;
if (closed && (p == NULL || p->next == NULL))
break;
}
}
static
get_points(p, closed)
struct f_point *p;
{
struct f_point *q;
int i;
for (q = p, i = 0; q != NULL; i++) {
if (i >= MAX_POINTS)
break;
q->x = (atoi(panel_get_value(px_panel[i])));
q->y = (atoi(panel_get_value(py_panel[i])));
q = q->next;
if (closed) {
if (q == NULL)
break;
else if (q->next == NULL) {
q->x = p->x;
q->y = p->y;
break;
}
}
}
}
void
Quit(widget, client_data, call_data)
Widget widget;
XtPointer client_data, call_data;
{
XtDestroyWidget(popup);
}
char *
panel_get_value(widg)
Widget widg;
{
char *val;
XtSetArg(args[0], XtNstring, &val);
XtGetValues(widg, args, ONE);
if(atol(val) < 0)
{
panel_set_value(widg,"0");
return "0";
}
return val;
}
panel_set_value(widg, val)
Widget widg;
char *val;
{
XtSetArg(args[0], XtNstring, val);
XtSetValues(widg, args, ONE);
XtSetArg(args[0], XtNinsertPosition, strlen(val));
XtSetValues(widg, args, ONE);
}
static void
line_style_select(w, style, garbage)
Widget w;
XtPointer style, garbage;
{
XtSetArg(args[0], XtNlabel, XtName(w));
XtSetValues(style_panel, args, ONE);
generic_vals.style = (int) style;
switch(generic_vals.style)
{
case SOLID_LINE:
generic_vals.style_val = 0.0;
break;
case DASH_LINE:
generic_vals.style_val = cur_dashlength;
break;
case DOTTED_LINE:
generic_vals.style_val = cur_dotgap;
break;
}
}
static void
text_adjust_select(w, adjust, garbage)
Widget w;
XtPointer adjust, garbage;
{
XtSetArg(args[0], XtNlabel, XtName(w));
XtSetValues(adjust_panel, args, ONE);
text_adjust = (int) adjust;
}
void
toggle(w, clos, garbage)
Widget w;
XtPointer clos, garbage;
{
char buf[5];
int fill;
if(no_fill_flag == TRUE)
no_fill_flag = FALSE;
else
no_fill_flag = TRUE;
/* set label to reflect fill flag */
XtSetArg(args[0], XtNlabel, no_fill_flag? "Not Filled": "Filled ");
XtSetValues(w, args, ONE);
/* make fill% panel sensitive or insensitive depending on fill flag */
XtSetArg(args[0], XtNsensitive, no_fill_flag? False: True);
XtSetValues(area_fill_panel, args, ONE);
XtSetValues(fill_pct_label, args, ONE);
fill = (NUMFILLPATS - generic_vals.area_fill) * (100/(NUMFILLPATS-1));
if (fill > 100)
fill = 100;
if (no_fill_flag)
sprintf(buf," ");
else
sprintf(buf,"%d",fill);
panel_set_value(area_fill_panel,buf);
}