/* $Id: edit.c,v 10.1 92/10/06 22:58:18 ca Exp $ */ #include #include #include "sim.h" #include "simx.h" #include "meters.h" #include "xtables.h" #include "comptypes.h" #include "eventdefs.h" extern list *comps; Window pop_comp_window(); XCOMPONENT *get_xcomponent(); #define QUERY_X 200 #define QUERY_Y 200 #define EDIT_X 500 /* X & Y position of the component types window. */ #define EDIT_Y 100 #define EDIT_WIDTH 170 #define EDIT_HEIGHT 30 #define EDIT_X_PAD 4 #define EDIT_Y_PAD 20 destroy_component() { XCOMPONENT *xcomponent; PFP the_action; COMPONENT *scomponent; xprintclear(); printx("Click on component(s) to destroy. Click on QUIT to finish."); for (;;) { if((xcomponent = get_xcomponent()) == NULL) break; scomponent = (COMPONENT *) xcomponent->scomponent; /* destroy component */ the_action = component_types[scomponent->co_type].action; delete_component_array_modify(scomponent); unpop_comp_window(scomponent); le_del(comps, scomponent); the_action(NULL, scomponent, EV_DEL, NULL, NULL); xprintclear(); printx("Component Destroyed"); XClearWindow(the_environment.the_display, the_environment.back_window); connect_components(); sleep(1); xprintclear(); } xprintclear(); sim_reset(comps); } int get_type() { int counter; int num_types; Window the_window; XEvent event; XButtonPressedEvent *bevent; XExposeEvent *xevent; XTextItem xtext; int type = -1; for (num_types = 0; component_types[num_types].action; ++num_types) ; the_window = XCreateSimpleWindow(the_environment.the_display, the_environment.back_window, EDIT_X, EDIT_Y, EDIT_WIDTH, EDIT_HEIGHT * (num_types + 1), the_environment.border_width, the_environment.fore_color, the_environment.edit_color); XSelectInput(the_environment.the_display, the_window, ExposureMask); XMapWindow(the_environment.the_display, the_window); for (;;) { XNextEvent(the_environment.the_display, &event); if (event.type == ButtonPress) { bevent = (XButtonPressedEvent *) &event; if (bevent->subwindow != the_window) continue; if ((bevent->y - EDIT_Y) < (num_types * EDIT_HEIGHT)) type = ((int) ((bevent->y - EDIT_Y)/ EDIT_HEIGHT)); XDestroyWindow(the_environment.the_display, the_window); XFlush(the_environment.the_display); return (type); } else if (event.type == Expose) { xevent = (XExposeEvent *) &event; if (xevent->window == the_window) { for (counter = 0; counter != num_types; ++counter) { xtext.chars = component_types[counter].typename; xtext.nchars = strlen(component_types[counter].typename); xtext.font = the_environment.edit_font; xtext.delta = 0; XDrawText(the_environment.the_display, the_window, the_environment.the_gc, EDIT_X_PAD, (counter * EDIT_HEIGHT) + EDIT_Y_PAD, &xtext, 1); XDrawLine(the_environment.the_display, the_window, the_environment.the_gc, 0, (EDIT_HEIGHT * (counter +1)), EDIT_WIDTH, (EDIT_HEIGHT * (counter + 1))); } xtext.chars = "ABORT"; xtext.nchars = 5; xtext.delta = 0; XDrawText(the_environment.the_display, the_window, the_environment.the_gc, EDIT_X_PAD, (num_types * EDIT_HEIGHT) + EDIT_Y_PAD, &xtext, 1); } else { general_expose_event_handler(xevent); } } } } get_parameters(scomponent, new_flag) COMPONENT *scomponent; int new_flag; { PARAM *parameter; char parameter_string[20]; int info_window_position; xprintclear(); for (parameter = (Param *)scomponent->co_params->q_head, info_window_position = 0; parameter; parameter = parameter->p_next, info_window_position += parameter ? ((parameter->p_flags & DisplayMask) ? 1 : 0) : 0) { if (!(parameter->p_flags & InputMask)) continue; printx(parameter->p_name); if (!new_flag) { xprint("[", 1); printx((*parameter->p_make_short_text)(scomponent, parameter)); xprint("]", 1); } xprint(":", 1); xinput(parameter_string, 20); xprintclear(); if ((parameter_string[0] == '\0') && (new_flag != TRUE)) continue; if ((*parameter->p_input) (parameter, parameter_string, scomponent)) { draw_info_text(scomponent->co_picture, info_window_position, TRUE); if (parameter == (PARAM *)scomponent->co_params->q_head) update_component_name(scomponent); continue; } } } /* This routine accepts a parameter and its component as arguements. It then allows the user to change the component's value, or simply leave the parameter with its present value. It does not return anything. */ edit_parameter(scomponent, parameter) COMPONENT *scomponent; PARAM *parameter; { char parameter_string[80]; if (parameter->p_flags & (InputMask | ModifyMask)) { xprintclear(); printx(parameter->p_name); xprint("[", 1); printx((*parameter->p_make_short_text)(scomponent, parameter)); printx("]:"); if (xinput(parameter_string, 80) != 0) { (*parameter->p_input) (parameter, parameter_string, scomponent); /* If the first in the list, it is the component name */ if (parameter == (PARAM *)scomponent->co_params->q_head) update_component_name(scomponent); } xprintclear(); } } neighbor_event_handler(bevent) XButtonPressedEvent *bevent; { static XCOMPONENT *last_xcomponent = NULL; NEIGHBOR *neighbor; PARAM *parameter; XCOMPONENT *present_xcomponent; caddr_t result_flag; int param_array_size1= 0, param_array_size2 = 0; int they_are_neigh; if (bevent->subwindow == 0) { last_xcomponent = NULL; return (-1); } if (XFindContext(the_environment.the_display, bevent->subwindow, comp_xtable, (caddr_t *) &present_xcomponent) != 0) { last_xcomponent = NULL; return (-1); } if (present_xcomponent->which_one == INFO_WINDOW) { last_xcomponent = NULL; return (-1); } if (last_xcomponent == NULL) { last_xcomponent = present_xcomponent; return(1); } if (present_xcomponent == last_xcomponent) { return(1); } /* Ok, the user wants has chosen two neighbors. If they are neighbors, uneighbor them. If they are not neighbors, make them neighbors. Return 1 if it works, -1 if it doesn't. */ they_are_neigh = FALSE; for (neighbor = (NEIGHBOR *) last_xcomponent->scomponent->co_neighbors->l_head; neighbor != NULL; neighbor = neighbor->n_next) { if (neighbor->n_c == present_xcomponent->scomponent) { they_are_neigh = TRUE; break; } } /* Count number of displayable params in each comp before... */ for (param_array_size1 = 0, parameter = (PARAM *)last_xcomponent->scomponent->co_params->q_head; parameter; parameter = parameter->p_next) if (parameter->p_flags & DisplayMask) param_array_size1++; for (param_array_size2 = 0, parameter = (PARAM *)present_xcomponent->scomponent->co_params->q_head; parameter; parameter = parameter->p_next) if (parameter->p_flags & DisplayMask) param_array_size2++; /* Ok, they are neighbors, uneighbor them. */ if (they_are_neigh) { (*last_xcomponent->scomponent->co_action)(NULL, last_xcomponent->scomponent, EV_UNEIGHBOR, NULL, present_xcomponent->scomponent); (*present_xcomponent->scomponent->co_action)(NULL, present_xcomponent->scomponent, EV_UNEIGHBOR, NULL, last_xcomponent->scomponent); delete_connection_array_modify(last_xcomponent->scomponent, present_xcomponent->scomponent); XClearWindow(the_environment.the_display, the_environment.back_window); } else { /* Ok, they are not neighbors, make them neighbors. */ result_flag = (*last_xcomponent->scomponent->co_action)(NULL, last_xcomponent->scomponent, EV_NEIGHBOR, NULL, present_xcomponent->scomponent); if (result_flag) { if ((*present_xcomponent->scomponent->co_action)(NULL, present_xcomponent->scomponent, EV_NEIGHBOR, NULL, last_xcomponent->scomponent)) { add_connection_array_modify(present_xcomponent->scomponent, last_xcomponent->scomponent); } else { (*last_xcomponent->scomponent->co_action)(NULL, last_xcomponent->scomponent, EV_UNEIGHBOR, NULL, present_xcomponent->scomponent); last_xcomponent = present_xcomponent; return (-1); } } else { last_xcomponent = present_xcomponent; return (-1); } } /* If number of params has changed, redo the infowindow */ /* Count number of displayable params after... */ for (parameter = (PARAM *)last_xcomponent->scomponent->co_params->q_head; parameter; parameter = parameter->p_next) if (parameter->p_flags & DisplayMask) param_array_size1--; for (parameter = (PARAM *)present_xcomponent->scomponent->co_params->q_head; parameter; parameter = parameter->p_next) if (parameter->p_flags & DisplayMask) param_array_size2--; if ((last_xcomponent->scomponent->co_menu_up) && param_array_size1 != 0) { unpop_info_window(last_xcomponent->scomponent); pop_info_window(last_xcomponent->scomponent); } if ((present_xcomponent->scomponent->co_menu_up) && param_array_size2 != 0) { unpop_info_window(present_xcomponent->scomponent); pop_info_window(present_xcomponent->scomponent); } connect_components(); last_xcomponent = present_xcomponent; return (1); } int create_component(x, y, scomponent) int x,y; /* position on screen to create the component */ COMPONENT *scomponent; /* if not Null, use same type of component as this one. */ { int type; PFP the_action; COMPONENT *the_component; XEvent event; if (scomponent != NULL) the_action = scomponent->co_action; else if ((type = get_type()) != -1) the_action = component_types[type].action; else return (-1); the_component = (COMPONENT *) ((*the_action)(NULL, NULL, EV_CREATE, NULL, "Default")); if (the_component != NULL) { le_addt(comps, the_component); the_component->co_picture = (COMP_OBJECT) pop_comp_window(the_component, x + the_environment.x, y + the_environment.y); paint_comp_window(the_component, NULL); } else { return(-1); } pop_info_window(the_component); paint_info_window(the_component, NULL, NULL); while (XPending(the_environment.the_display) != 0) { XNextEvent(the_environment.the_display, &event); if (event.type == Expose) general_expose_event_handler((XExposeEvent *) &event); } xprintclear(); printx("Now enter the parameters"); sleep(1); xprintclear(); get_parameters(the_component, TRUE); return (1); } update_component_name(the_component) COMPONENT *the_component; { PARAM *parameter; XCOMPONENT *xcomponent; char name_string[40]; parameter = (Param *)the_component->co_params->q_head; xcomponent = (XCOMPONENT *) the_component->co_picture; strcpy(name_string, (*(parameter->p_make_text)) (the_component, parameter)); xcomponent->hposition = (int) xcomponent->height - ((xcomponent->height - the_environment.comp_font_info->ascent - the_environment.comp_font_info->descent)/2); xcomponent->wposition = (int) (xcomponent->width - XTextWidth(the_environment.comp_font_info, name_string, strlen(name_string))) / 2; XClearWindow(the_environment.the_display, xcomponent->comp_window); paint_comp_window(xcomponent->scomponent, xcomponent); } METER *edit_meter(meter, position) METER *meter; int position; { char output_string[50]; char *a_string; char input_string[40]; PARAM *parameter; int type; double scale; PARAM *temp_parameter; COMPONENT *temp_scomponent; short temp_dname, temp_dscale; XWindowAttributes xinfo; extern METER *histogram_adjust_knob (); if (position > the_environment.meter_info_window_entries) position = the_environment.meter_info_window_entries; if (position == 1) return (NULL); if (position == 4) { if (((meter->parameter->p_display_type & MeterTypeMask) != TIME_HISTORY)) return (NULL); if (change_th_time_increment(meter->th) == (int) NULL) return (NULL); else return (meter); } if (position == 5) { if (meter->display_name == 0) meter->display_name = 1; else meter->display_name = 0; return (meter); } if (position == 6) { if (meter->display_scale == 0) meter->display_scale = 1; else meter->display_scale = 0; return (meter); } if (position == 3) { a_string = (char *) meter_info_make_name_string(position); strcpy(output_string, a_string); strcat(output_string, " ["); a_string = (char *) meter_info_make_value_string(meter, position); strcat(output_string, a_string); strcat(output_string, "] : "); xprintclear(); printx(output_string); if (xinput(input_string, 38) == 0) { xprintclear(); return (NULL); } else if (sscanf(input_string, "%lf", &scale) == (int) NULL) { xprintclear(); return (NULL); } else { xprintclear(); /* Don't let scale be <= 0.0 */ meter->parameter->p_scale = scale > 0.0 ? scale : 1.0; return (meter); } } if (position == 2) { parameter = meter->parameter; type = get_meter_type_info(parameter); if (type != meter->type) { int tempx = meter->x; int tempy = meter->y; int tempwidth = meter->width, tempheight = meter->height; temp_parameter = meter->parameter; temp_scomponent = meter->scomponent; strcpy(output_string, meter->name); temp_dname = meter->display_name; temp_dscale = meter->display_scale; unpop_meter(meter->scomponent, meter->parameter); parameter->p_display_type = (type | (parameter->p_display_type & ~MeterTypeMask)); pop_meter(temp_scomponent, temp_parameter, tempx, tempy, tempwidth, tempheight); meter = (METER *) parameter->p_my_picture; strcpy(meter->name, output_string); meter->display_name = temp_dname; meter->display_scale = temp_dscale; pop_meter_info_window(meter); return (meter); } } if (position == 0) { a_string = (char *) meter_info_make_name_string(position); strcpy(output_string, a_string); strcat(output_string, " ["); a_string = (char *) meter_info_make_value_string(meter, position); strcat(output_string, a_string); strcat(output_string, "] : "); xprintclear(); printx(output_string); if (xinput(input_string, 19) == 0) { xprintclear(); return (NULL); } else { xprintclear(); strcpy(meter->name, input_string); return (meter); } } if ((position > 6) && (position < 11)) { return (histogram_adjust_knob (meter, position)); } /* the program should never get to this line */ return (NULL); }