/* window division related controls */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "robot.h" #define FACTOR 5 /* factor by which the demo-canvas is smaller than * the full size one */ extern Canvas canvas; double xborder_r; double xborder_l; double yborder_u; double yborder_d; double x_size; double y_size; static GC gc_demo; static XGCValues gcvalues; static Window xwin; static Canvas split_canvas; static int x_start; /* start position for sliders */ char string[40]; int i; /* multiple use integer variable */ Bool Changed; Frame split_frame; Panel_item divide_x, divide_y, divide_button; Panel_item select_x, select_y, select_button; Panel_item window_gap_slider, window_gap_x_slider, window_gap_y_slider; Panel_item page_use_button; Panel_item xlow, xhigh, ylow, yhigh; int divx, divy, selx, sely; double startx, starty, endx, endy, stepx, stepy; void flip_demo() { /* make sure canvas is set to 1/5 of the actual plotting canvas */ /* if(xv_get(split_canvas, XV_WIDTH) != xv_get(canvas, XV_WIDTH)/FACTOR){ xv_set(split_canvas, XV_WIDTH, xv_get(canvas, XV_WIDTH)/FACTOR, NULL); } if(xv_get(split_canvas, XV_HEIGHT) != xv_get(canvas, XV_HEIGHT)/FACTOR){ xv_set(split_canvas, XV_HEIGHT, xv_get(canvas, XV_HEIGHT)/FACTOR, NULL); } */ /* With current big range allowed now keep scaled to nominal size * of 1 */ /* Just determine if it's landscape or portrait */ if (xv_get(canvas, XV_HEIGHT) > xv_get(canvas, XV_WIDTH)){ /* normal state - portrait */ xv_set(split_canvas, XV_HEIGHT, MY_CANVAS_HEIGHT/FACTOR, XV_WIDTH, MY_CANVAS_WIDTH/FACTOR, NULL); } else { xv_set(split_canvas, XV_WIDTH, MY_CANVAS_HEIGHT/FACTOR, XV_HEIGHT, MY_CANVAS_WIDTH/FACTOR, NULL); } xv_set(split_canvas, XV_X, xv_get(split_panel, XV_WIDTH) - xv_get(split_canvas, XV_WIDTH), NULL); gshow_(); } /* show how current plot area is split up, gaps, and present plotting * area */ void demo_gaps() { double xgap; double ygap; int plotx, ploty; unsigned int widthx, widthy; int j; selx = xv_get(select_x, PANEL_VALUE); sely = xv_get(select_y, PANEL_VALUE); divx = xv_get(divide_x, PANEL_VALUE); divy = xv_get(divide_y, PANEL_VALUE); /* No point in selecting if there's only one option */ if(divx == 1 && divy == 1) xv_set(select_button, PANEL_INACTIVE, TRUE, NULL); else xv_set(select_button, PANEL_INACTIVE, FALSE, NULL); if(divx == 1){ xv_set(select_x, PANEL_INACTIVE, TRUE, NULL); } else{ xv_set(select_x, PANEL_INACTIVE, FALSE, NULL); } if(divy == 1){ xv_set(select_y, PANEL_INACTIVE, TRUE, NULL); } else{ xv_set(select_y, PANEL_INACTIVE, FALSE, NULL); } xgap = (double) xv_get(window_gap_x_slider, PANEL_VALUE); ygap = (double) xv_get(window_gap_y_slider, PANEL_VALUE); xgap = xgap/100.; ygap = ygap/100.; xborder_l = (double)xv_get(xlow, PANEL_VALUE)/100.; xborder_r = (double)xv_get(xhigh, PANEL_VALUE)/100.; yborder_u = (double)xv_get(yhigh, PANEL_VALUE)/100.; yborder_d = (double)xv_get(ylow, PANEL_VALUE)/100.; sprintf(string, "Sub-window = (%d, %d)", selx, sely); xv_set(split_frame, FRAME_LEFT_FOOTER, string, NULL); sprintf(string, "of %d (X) by %d (Y)", divx, divy); xv_set(split_frame, FRAME_RIGHT_FOOTER, string, NULL); /* draw a very crude representation of window splitting */ XClearWindow(dpy, xwin); /* edge of page XDrawLine(dpy, xwin, gc_demo, (int) size, 0, (int) size, (int) size);*/ x_size = (double) xv_get(split_canvas, XV_WIDTH); y_size = (double) xv_get(split_canvas, XV_HEIGHT); startx = x_size * xborder_l; starty = y_size * (1.0 - yborder_u); endx = x_size * xborder_r; endy = y_size * (1.0 - yborder_d); stepx = (endx - startx)/divx; stepy = (endy - starty)/divy; widthx = (int) ((double) stepx * (1. - 2.0 * xgap)); widthy = (int) ((double) stepy * (1. - 2.0 * ygap)); for(i = 1; i <= divx; i++){ for(j = 1; j <= divy; j++){ plotx = startx + stepx * (i-1); plotx = plotx + (int) ((double) stepx * xgap); ploty = endy - stepy * j; ploty = ploty + (int) ((double) stepy * ygap); XDrawRectangle(dpy, xwin, gc_demo, plotx, ploty, widthx, widthy); if(i == selx && j == sely){ XFillRectangle(dpy, xwin, gc_demo, plotx, ploty, widthx, widthy); } } } } void pusechk_(xlo, ylo, xhi, yhi) double *xlo, *ylo, *xhi, *yhi; { Changed = FALSE; i = (int) (*xlo); if(xv_get(xlow, PANEL_VALUE) != i){ xv_set(xlow, PANEL_VALUE, i, NULL); Changed = TRUE; } i = (int) (*ylo); if(xv_get(ylow, PANEL_VALUE) != i){ xv_set(ylow, PANEL_VALUE, i, NULL); Changed = TRUE; } i = (int) (*xhi); if(xv_get(xhigh, PANEL_VALUE) != i){ xv_set(xhigh, PANEL_VALUE, i, NULL); Changed = TRUE; } i = (int) (*yhi); if(xv_get(yhigh, PANEL_VALUE) != i){ xv_set(yhigh, PANEL_VALUE, i, NULL); Changed = TRUE; } if(Changed)demo_gaps(); } void gapcheck_(xgap, ygap) double *xgap; double *ygap; { #define FUDGEIT 0.001 Changed = FALSE; i = (int) ((*xgap * 100.) + FUDGEIT); if(xv_get(window_gap_x_slider, PANEL_VALUE) != i){ xv_set(window_gap_x_slider, PANEL_VALUE, i, NULL); Changed = TRUE; } i = (int) ((*ygap * 100.) + FUDGEIT); if(xv_get(window_gap_y_slider, PANEL_VALUE) != i){ xv_set(window_gap_y_slider, PANEL_VALUE, i, NULL); Changed = TRUE; } /* set generic gap slider to minimum (kind of a kludge) */ i = MIN(xv_get(window_gap_x_slider, PANEL_VALUE), xv_get(window_gap_y_slider, PANEL_VALUE)); if(xv_get(window_gap_slider, PANEL_VALUE) != i){ xv_set(window_gap_slider, PANEL_VALUE, i, NULL); Changed = TRUE; } if(Changed)demo_gaps(); } void divcheck_(x, y) double *x; double *y; { Changed = FALSE; i = (int) *x; if(xv_get(divide_x, PANEL_VALUE) != i){ if(i > xv_get(divide_x, PANEL_MAX_VALUE)) xv_set(divide_x, PANEL_MAX_VALUE, i, NULL); xv_set(divide_x, PANEL_VALUE, i, NULL); xv_set(select_x, PANEL_MAX_VALUE, i, NULL); Changed = TRUE; } i = (int) *y; if(xv_get(divide_y, PANEL_VALUE) != i){ if(i > xv_get(divide_y, PANEL_MAX_VALUE)) xv_set(divide_y, PANEL_MAX_VALUE, i, NULL); xv_set(divide_y, PANEL_VALUE, i, NULL); xv_set(select_y, PANEL_MAX_VALUE, i, NULL); Changed = TRUE; } if(Changed)demo_gaps(); } /* check whether panel settings have correct values */ void selcheck_(x, y) double *x; double *y; { Changed = FALSE; i = (int) *x; if(xv_get(select_x, PANEL_VALUE) != i){ xv_set(select_x, PANEL_VALUE, i, NULL); Changed = TRUE; } i = (int) *y; if(xv_get(select_y, PANEL_VALUE) != i){ xv_set(select_y, PANEL_VALUE, i, NULL); Changed = TRUE; } if(Changed)demo_gaps(); } void set_divide_active() { /* If the x or y divide sliders was altered then the divide button * now can be used - set to active. */ xv_set(divide_button, PANEL_INACTIVE, FALSE, NULL); } void divide_window() { xv_set(select_x, PANEL_MAX_VALUE, xv_get(divide_x, PANEL_VALUE), NULL); xv_set(select_y, PANEL_MAX_VALUE, xv_get(divide_y, PANEL_VALUE), NULL); sprintf(inst, "DIVWINDOW %d %d", (int) xv_get(divide_x, PANEL_VALUE), (int) xv_get(divide_y, PANEL_VALUE)); xv_set(divide_button, PANEL_INACTIVE, TRUE, NULL); to_robot(); demo_gaps(); } void select_window() { sprintf(inst, "SELWINDOW %d %d", (int) xv_get(select_x, PANEL_VALUE), (int) xv_get(select_y, PANEL_VALUE)); to_robot(); demo_gaps(); } void window_gap(item, value, event) Panel_item item; int value; Event *event; { int gap; gap = xv_get(item, PANEL_VALUE); if(item == window_gap_slider){ sprintf(inst, "WINDOWGAP %d", gap); xv_set(window_gap_x_slider, PANEL_VALUE, gap, NULL); xv_set(window_gap_y_slider, PANEL_VALUE, gap, NULL); } else if(item == window_gap_x_slider){ sprintf(inst, "XWINDOWGAP %d", gap); } else if(item == window_gap_y_slider){ sprintf(inst, "YWINDOWGAP %d", gap); } else{ printf("Error in window_gap proc\n"); } to_robot(); demo_gaps(); } void split_canvas_proc(window, event) Xv_Window window; Event *event; { double ix, iy; int iwind, jwind; switch (event_action(event)) { case ACTION_SELECT: if(event_is_down(event)){ ix = (double) event_x(event); iy = (double) event_y(event); /* decode which window this is */ selx = xv_get(select_x, PANEL_VALUE); sely = xv_get(select_y, PANEL_VALUE); xborder_l = (double)(xv_get(xlow, PANEL_VALUE))/100.; xborder_r = (double)(xv_get(xhigh, PANEL_VALUE))/100.; yborder_u = (double)(xv_get(yhigh, PANEL_VALUE))/100.; yborder_d = (double)(xv_get(ylow, PANEL_VALUE))/100.; /* ix = ix - xborder_l; iy = iy - yborder_u; */ divx = xv_get(divide_x, PANEL_VALUE); divy = xv_get(divide_y, PANEL_VALUE); x_size = (double) xv_get(split_canvas, XV_WIDTH); y_size = (double) xv_get(split_canvas, XV_HEIGHT); startx = x_size * xborder_l; starty = y_size * (1 - yborder_u); endx = x_size * xborder_r; endy = y_size * (1 - yborder_d); /* return if clicked outside the box */ if(ix > endx || iy > endy || ix < startx || iy < starty) return; stepx = (endx - startx)/divx; stepy = (endy - starty)/divy; iwind = (int) ((ix - startx)/ stepx) + 1; jwind = (int) (iy - starty)/ stepy; jwind = divy - jwind; /* select window if different from the current one */ if(iwind != selx || jwind != sely){ sprintf(inst, "SELWINDOW %d %d", iwind, jwind); to_robot(); } } break; default: return; } } void page_use() { xv_set(page_use_button, PANEL_INACTIVE, TRUE, NULL); sprintf(inst, "PAGEUSE %d %d %d %d", (int) xv_get(xlow, PANEL_VALUE), (int) xv_get(ylow, PANEL_VALUE), (int) xv_get(xhigh, PANEL_VALUE), (int) xv_get(yhigh, PANEL_VALUE)); to_robot(); demo_gaps(); } void demo_canvas_off() { xv_set(canvas_paint_window(split_canvas), WIN_IGNORE_X_EVENT_MASK, ButtonPressMask | ButtonReleaseMask, NULL); } void demo_canvas_on() { xv_set(canvas_paint_window(split_canvas), WIN_CONSUME_X_EVENT_MASK, ButtonPressMask | ButtonReleaseMask | ExposureMask | KeyPressMask | VisibilityChangeMask, NULL); } /* activate Page Use button if sliders were moved */ void page_use_slider() { if(xv_get(page_use_button, PANEL_INACTIVE) == TRUE) xv_set(page_use_button, PANEL_INACTIVE, FALSE, NULL); } void make_split_frame(frame) Frame frame; { split_frame = xv_create(frame, FRAME_CMD, FRAME_LABEL, "Robot: Sub-Window Controls", FRAME_CMD_PUSHPIN_IN, TRUE, FRAME_SHOW_FOOTER, TRUE, NULL); split_panel = xv_get(split_frame, FRAME_CMD_PANEL); xv_set(split_panel, PANEL_LAYOUT, PANEL_VERTICAL, XV_HELP_DATA, "robot:split_panel", NULL); divide_x = xv_create(split_panel, PANEL_SLIDER, PANEL_VALUE_DISPLAY_LENGTH, SLIDER_LENGTH, PANEL_LABEL_STRING, "No. of X Windows", PANEL_SLIDER_END_BOXES, TRUE, PANEL_MIN_VALUE, 1, PANEL_MAX_VALUE, 10, PANEL_NOTIFY_PROC, set_divide_active, XV_HELP_DATA, "robot:divide_x", NULL); divide_y = xv_create(split_panel, PANEL_SLIDER, PANEL_VALUE_DISPLAY_LENGTH, SLIDER_LENGTH, PANEL_LABEL_STRING, "No. of Y Windows", PANEL_SLIDER_END_BOXES, TRUE, PANEL_MIN_VALUE, 1, PANEL_MAX_VALUE, 10, PANEL_NOTIFY_PROC, set_divide_active, XV_HELP_DATA, "robot:divide_y", NULL); divide_button = xv_create(split_panel, PANEL_BUTTON, PANEL_LABEL_STRING, "Divide Plot Area", PANEL_NOTIFY_PROC, divide_window, XV_HELP_DATA, "robot:divide", PANEL_INACTIVE, TRUE, NULL); select_x = xv_create(split_panel, PANEL_SLIDER, PANEL_VALUE_DISPLAY_LENGTH, SLIDER_LENGTH, PANEL_LABEL_STRING, "Select Window (X)", PANEL_SLIDER_END_BOXES, TRUE, PANEL_MIN_VALUE, 1, PANEL_MAX_VALUE, 1, XV_HELP_DATA, "robot:select_x", NULL); select_y = xv_create(split_panel, PANEL_SLIDER, PANEL_VALUE_DISPLAY_LENGTH, SLIDER_LENGTH, PANEL_LABEL_STRING, "Select Window (Y)", PANEL_SLIDER_END_BOXES, TRUE, PANEL_MIN_VALUE, 1, PANEL_MAX_VALUE, 1, XV_HELP_DATA, "robot:select_y", NULL); select_button = xv_create(split_panel, PANEL_BUTTON, PANEL_LABEL_STRING, "Select Window", PANEL_NOTIFY_PROC, select_window, PANEL_INACTIVE, TRUE, XV_HELP_DATA, "robot:select", NULL); /* x_start = xv_get(select_y, PANEL_VALUE_X); */ window_gap_slider = xv_create(split_panel, PANEL_SLIDER, PANEL_VALUE_DISPLAY_LENGTH, SLIDER_LENGTH, PANEL_LABEL_STRING, "Window Gap (%)", PANEL_SLIDER_END_BOXES, TRUE, PANEL_MIN_VALUE, 0, PANEL_MAX_VALUE, 49, PANEL_NOTIFY_PROC, window_gap, XV_HELP_DATA, "robot:window_gap", /* PANEL_VALUE_X, x_start, */ NULL); window_gap_x_slider = xv_create(split_panel, PANEL_SLIDER, PANEL_VALUE_DISPLAY_LENGTH, SLIDER_LENGTH, PANEL_LABEL_STRING, "X Window Gap (%)", PANEL_SLIDER_END_BOXES, TRUE, PANEL_MIN_VALUE, 0, PANEL_MAX_VALUE, 49, PANEL_NOTIFY_PROC, window_gap, XV_HELP_DATA, "robot:window_gap_x", /* PANEL_VALUE_X, x_start, */ NULL); window_gap_y_slider = xv_create(split_panel, PANEL_SLIDER, PANEL_VALUE_DISPLAY_LENGTH, SLIDER_LENGTH, PANEL_LABEL_STRING, "Y Window Gap (%)", PANEL_SLIDER_END_BOXES, TRUE, PANEL_MIN_VALUE, 0, PANEL_MAX_VALUE, 49, PANEL_NOTIFY_PROC, window_gap, XV_HELP_DATA, "robot:window_gap_y", /* PANEL_VALUE_X, x_start, */ NULL); x_start = MAX(xv_get(window_gap_slider, PANEL_VALUE_X), xv_get(window_gap_x_slider, PANEL_VALUE_X)); x_start = MAX(x_start, xv_get(window_gap_y_slider, PANEL_VALUE_X)); xv_set(window_gap_slider, PANEL_VALUE_X, x_start, NULL); xv_set(window_gap_x_slider, PANEL_VALUE_X, x_start, NULL); xv_set(window_gap_y_slider, PANEL_VALUE_X, x_start, NULL); page_use_button = xv_create(split_panel, PANEL_BUTTON, PANEL_LABEL_STRING, "Page Use", PANEL_NOTIFY_PROC, page_use, XV_HELP_DATA, "robot:page_use", PANEL_INACTIVE, TRUE, NULL); ylow = xv_create(split_panel, PANEL_SLIDER, PANEL_LABEL_STRING, "Min. Y", PANEL_MIN_VALUE, 0, PANEL_MAX_VALUE, 100, PANEL_VALUE_DISPLAY_LENGTH, SLIDER_LENGTH, PANEL_DIRECTION, PANEL_HORIZONTAL, PANEL_SLIDER_END_BOXES, TRUE, XV_HELP_DATA, "robot:split_min_y", PANEL_NOTIFY_PROC, page_use_slider, NULL); xv_set(split_panel, PANEL_LAYOUT, PANEL_HORIZONTAL, NULL); yhigh = xv_create(split_panel, PANEL_SLIDER, PANEL_LABEL_STRING, "Max. Y", PANEL_MIN_VALUE, 0, PANEL_MAX_VALUE, 100, PANEL_VALUE_DISPLAY_LENGTH, SLIDER_LENGTH, PANEL_DIRECTION, PANEL_HORIZONTAL, PANEL_SLIDER_END_BOXES, TRUE, XV_HELP_DATA, "robot:split_max_y", PANEL_NOTIFY_PROC, page_use_slider, NULL); xv_set(split_panel, PANEL_LAYOUT, PANEL_VERTICAL, NULL); xlow = xv_create(split_panel, PANEL_SLIDER, PANEL_LABEL_STRING, "Min. X", PANEL_MIN_VALUE, 0, PANEL_MAX_VALUE, 100, PANEL_DIRECTION, PANEL_HORIZONTAL, PANEL_VALUE_DISPLAY_LENGTH, SLIDER_LENGTH, PANEL_SLIDER_END_BOXES, TRUE, XV_HELP_DATA, "robot:split_min_x", PANEL_NOTIFY_PROC, page_use_slider, NULL); xv_set(split_panel, PANEL_LAYOUT, PANEL_HORIZONTAL, NULL); xhigh = xv_create(split_panel, PANEL_SLIDER, PANEL_LABEL_STRING, "Max. X", PANEL_MIN_VALUE, 0, PANEL_MAX_VALUE, 100, PANEL_VALUE_DISPLAY_LENGTH, SLIDER_LENGTH, PANEL_DIRECTION, PANEL_HORIZONTAL, PANEL_SLIDER_END_BOXES, TRUE, XV_HELP_DATA, "robot:split_max_x", PANEL_NOTIFY_PROC, page_use_slider, NULL); /* line up buttons */ x_start = MAX(xv_get(xlow, PANEL_VALUE_X), xv_get(ylow, PANEL_VALUE_X)); xv_set(xlow, PANEL_VALUE_X, x_start, NULL); xv_set(ylow, PANEL_VALUE_X, x_start, NULL); window_fit(split_panel); x_start = MAX(xv_get(xhigh, PANEL_VALUE_X), xv_get(yhigh, PANEL_VALUE_X)); xv_set(xhigh, PANEL_VALUE_X, x_start, NULL); xv_set(yhigh, PANEL_VALUE_X, x_start, NULL); if(not_open_look){ xv_set(split_panel, PANEL_LAYOUT, PANEL_VERTICAL, NULL); xv_create(split_panel, PANEL_BUTTON, XV_HELP_DATA, "robot:dismiss", PANEL_LABEL_STRING, DISMISS, PANEL_NOTIFY_PROC, hide_me, NULL); } window_fit(split_panel); window_fit(split_frame); /* With -fn fixed the last slider is sometimes in trouble - * an XView bug? */ split_canvas = (Canvas) xv_create(split_frame, CANVAS, XV_HELP_DATA, "robot:split_canvas", CANVAS_REPAINT_PROC, demo_gaps, WIN_X, 0, XV_HEIGHT, MY_CANVAS_HEIGHT/FACTOR, XV_WIDTH, MY_CANVAS_WIDTH/FACTOR, NULL); xv_set(split_canvas, XV_X, xv_get(split_panel, XV_WIDTH) - xv_get(split_canvas, XV_WIDTH), XV_Y, 0, NULL); xv_set(canvas_paint_window(split_canvas), WIN_EVENT_PROC, split_canvas_proc, NULL); demo_canvas_on(); window_fit(split_panel); window_fit(split_frame); gcvalues.foreground = BlackPixel(dpy, DefaultScreen(dpy)); gcvalues.background = WhitePixel(dpy, DefaultScreen(dpy)); gc_demo = XCreateGC(dpy, RootWindow(dpy, DefaultScreen(dpy)), (GCForeground | GCBackground), &gcvalues); xwin = xv_get(canvas_paint_window(split_canvas), XV_XID); } void show_split() { xv_set(split_frame, XV_SHOW, TRUE, FRAME_CMD_PUSHPIN_IN, TRUE, NULL); /* update sub-window demo */ flip_demo(); demo_gaps(); }