/* DRAW A RECTANGULAR BOX WITH THICKNESS OF "THICK" */ void draw_box(int x0, int y0, int xp, int yp, int thick) { int i; /*PARAMETERS: x0 = leftmost position y0 = topmost position xp = rightmost position yp = bottommost position thick = thickness i = individual screen pixels */ for (i = 0; i <= thick; i++) { R_move_abs(x0 + i, y0 + i); R_cont_abs(x0 + i, yp - i); R_cont_abs(xp - i, yp - i); R_cont_abs(xp - i, y0 + i); R_cont_abs(x0 + i, y0 + i); R_move_abs(x0 - i, y0 - i); R_cont_abs(x0 - i, yp + i); R_cont_abs(xp + i, yp + i); R_cont_abs(xp + i, y0 - i); R_cont_abs(x0 - i, y0 - i); } R_flush(); return; }
static int pick(int x, int y, int button) { int n; if (inbox(&more, x, y)) { cancel_which(); if (page + 1 >= npages) return 0; page++; return -1; } if (inbox(&less, x, y)) { cancel_which(); if (page == 0) return 0; page--; return -1; } if (inbox(&cancel, x, y)) { if (which == -2) return -2; cancel_which(); which = -2; R_standard_color(RED); Outline_box(cancel.top, cancel.bottom, cancel.left, cancel.right); R_flush(); return 0; } /* search name list. handle double click */ for (n = 0; n < count; n++) if (inbox(&list[n].box, x, y)) { if (n == which) /* second click! */ return 1; cancel_which(); which = n; R_standard_color(RED); Outline_box(list[n].box.top, list[n].box.bottom, list[n].box.left, list[n].box.right); R_flush(); return 0; /* ignore first click */ } cancel_which(); return 0; }
static int cancel_which(void) { if (which == -2) { R_standard_color(BLACK); Outline_box(cancel.top, cancel.bottom, cancel.left, cancel.right); } else if (which >= 0) { R_standard_color(BLACK); Outline_box(list[which].box.top, list[which].box.bottom, list[which].box.left, list[which].box.right); } which = -1; R_flush(); return 0; }
int Menu_msg(char *msg) { int size, edge; size = VIEW_MENU->nrows - 4; edge = 2; Erase_view(VIEW_MENU); if (*msg) { R_text_size(size, size); R_standard_color(BLACK); Text(msg, VIEW_MENU->top, VIEW_MENU->bottom, VIEW_MENU->left, VIEW_MENU->right, edge); } R_flush(); replot = 1; return 0; }
/* DRAW A CIRCLE WITH THICKNESS OF "THICK" */ void draw_circle(int x0, int y0, int xp, int yp, int thick) { int i, j, xstart, ystart, x2, yr; double ang, xinc, yinc; /*PARAMETERS x0 = leftmost position of enclosing square y0 = topmost position of enclosing square xp = rightmost position of enclosing square yp = bottommost position of enclosing square thick = thickness in screen pixels for drawing lines i = index for incrementing process j = individual screen pixels x1 = x coordinate of point where circle touches enclosing square ang = angle in radians that is the angle to be moved in connecting a straight line segment to the previous location */ for (j = 0; j < thick; j++) { xstart = x0 + (xp - x0) / 2; ystart = y0 + j; ang = 0.049087385; R_move_abs(xstart, ystart); for (i = 1; i < 129; i++) { xinc = cos((double)i * ang / 2.0) * sin((double)i * ang / 2.0) * (double)(yp - y0 - 2 * j); yinc = sin((double)i * ang / 2.0) * sin((double)i * ang / 2.0) * (double)(yp - y0 - 2 * j); R_cont_abs(xstart + (int)xinc, ystart + (int)yinc); } } R_flush(); return; }
static int dobox(struct box *box, char *text, int color, int top, int left, int right, int centered) { int bottom; bottom = top + height; /* fill inside of box with color */ R_standard_color(color); R_box_abs(left + 1, top + 1, right - 1, bottom - 1); /* draw box outline and text in black */ R_standard_color(BLACK); Outline_box(top, bottom, left, right); dotext(text, top, bottom, left, right, centered); R_flush(); box->top = top; box->bottom = bottom; box->left = left; box->right = right; return 0; }
int ask_magnification(int *magnification) { static int use = 1; int x, y; int height; int stat; int width; int top, bottom, left, right; static Objects objects[] = { OTHER(incr, &use), {0} }; Menu_msg(""); mag = *magnification; if (mag < 1) mag = 1; height = VIEW_MENU->nrows; R_text_size(height - 4, height - 4); Get_mouse_xy(&x, &y); top = y - height / 2; if (top < SCREEN_TOP) top = SCREEN_TOP; bottom = top + 4 * height; if (bottom >= VIEW_MENU->top) { top -= bottom - (VIEW_MENU->top - 1); bottom = VIEW_MENU->top - 1; } width = Text_width("MAGNIFICATION") + 4; left = x - width / 2; if (left < SCREEN_LEFT) left = SCREEN_LEFT; right = left + width; if (right > SCREEN_RIGHT) { left -= right - SCREEN_RIGHT; right = SCREEN_RIGHT; } R_panel_save(tempfile1, top, bottom, left, right); R_standard_color(WHITE); R_box_abs(left, top, right, bottom); R_standard_color(BLACK); Outline_box(top, bottom, left, right); plus.top = top + height; plus.bottom = plus.top + height; plus.left = left; plus.right = plus.left + Text_width("++") + 4; Outline_box(plus.top, plus.bottom, plus.left, plus.right); minus.top = top + height; minus.bottom = minus.top + height; minus.right = right; minus.left = minus.right - Text_width("--") - 4; Outline_box(minus.top, minus.bottom, minus.left, minus.right); value.top = top + height; value.bottom = value.top + height; value.left = plus.right; value.right = minus.left; Outline_box(value.top, value.bottom, value.left, value.right); accept.top = value.bottom; accept.bottom = accept.top + height; accept.left = left; accept.right = right; Outline_box(accept.top, accept.bottom, accept.left, accept.right); cancel.top = accept.bottom; cancel.bottom = cancel.top + height; cancel.left = left; cancel.right = right; Outline_box(cancel.top, cancel.bottom, cancel.left, cancel.right); dotext("MAGNIFICATION", top, top + height, left, right, WHITE); dotext("+", plus.top, plus.bottom, plus.left, plus.right, GREY); dotext("-", minus.top, minus.bottom, minus.left, minus.right, GREY); dotext("ACCEPT", accept.top, accept.bottom, accept.left, accept.right, GREY); dotext("CANCEL", cancel.top, cancel.bottom, cancel.left, cancel.right, GREY); draw_mag(); stat = Input_pointer(objects); /* to respond to user */ R_standard_color(WHITE); R_box_abs(left, top, right, bottom); R_flush(); R_panel_restore(tempfile1); R_panel_delete(tempfile1); *magnification = mag; return stat > 0; }
int ask_line_color(char *colors, int len1, char *xname, int position) { static int use = 1; int pick(); static Objects objects[] = { OTHER(pick, &use), {0} }; char msg[100]; int width; int len2 = 0, len; long offset; long *page_offset; int col, nlist; int line; int stat; char buf[100]; int top, bottom, left, right, center; int topx, bottomx, leftx, rightx, widthx; char name[100], mapset[100], cur_mapset[100]; int new_mapset; Menu_msg(""); sprintf(msg, "Double click on color to assign to vector layer"); /* * build a popup window at center of the screen. * 35% the height and wide enough to hold 2 columms of file names * * the window is for choosing file names and will be laid out in 2 columns * * ------------------------------------------ * | CANCEL | (MORE) | (LESS) | * ------------------------------------------ * | mapset | * ------------------------------------------ * | name1 | name2 | * ------------------------------------------ * | name3 | name4 | * ------------------------------------------ * | name5 | name6 | * | . | * | . | * | . | * ------------------------------------------ */ /* height of 1 line, based on NLINES taking up 35% vertical space */ height = (.35 * (SCREEN_BOTTOM - SCREEN_TOP)) / NLINES + 1; /* size of text, 80% of line height */ text_size = .8 * height; size = text_size - 1; /* fudge for computing pixels width of text */ /* indent for the text */ edge = .1 * height + 1; /* this is a fudge to determine the length of the largest text */ len1 = 2 * len1; /* name in 2 columns */ len2 += strlen("mapset "); len = (len1 > len2 ? len1 : len2); /* width is for max chars plus sidecar for more/less */ width = len * size + height; widthx = strlen(msg) * size; if (widthx < width) widthx = width; /* define the window */ top = (SCREEN_TOP + SCREEN_BOTTOM - height * NLINES) / 2; bottom = top + height * NLINES; center = (SCREEN_LEFT + SCREEN_RIGHT) / 2; if (position > 0) { right = (center + SCREEN_RIGHT + width) / 2; if (right >= SCREEN_RIGHT) right = SCREEN_RIGHT - 1; left = right - width; } else if (position < 0) { left = (center + SCREEN_LEFT - width) / 2; if (left <= SCREEN_LEFT) left = SCREEN_LEFT + 1; right = left + width; } else { left = center + width / 2; right = left + width; } topx = top - 3 * height; bottomx = topx + 2 * height; leftx = (left + right - widthx) / 2; if (leftx < SCREEN_LEFT) leftx = SCREEN_LEFT; rightx = leftx + widthx; /* save what is under these areas, so they can be restored */ R_panel_save(tempfile1, top, bottom, left, right); R_panel_save(tempfile2, topx, bottomx, leftx, rightx); /* fill it top with GREY, pick area with white */ R_standard_color(WHITE); R_box_abs(left, top, right, bottom); R_standard_color(GREY); R_box_abs(leftx, topx, rightx, bottomx); R_standard_color(BLACK); Outline_box(top, bottom, left, right); right -= height; /* reduce it to exclude sidecar */ Outline_box(top, bottom, left, right); /* print messages above the files */ dotext(msg, topx, topx + height, leftx, rightx, 1); dotext("Double click here to cancel", topx + height, bottomx, leftx, rightx, 1); cancel.top = topx; cancel.bottom = bottomx; cancel.left = leftx; cancel.right = rightx; /* start the mouse in the cancel box */ Set_mouse_xy((leftx + rightx) / 2, (topx + bottomx) / 2); dobox(&less, "", WHITE, top, right, right + height, 0); dobox(&more, "", WHITE, bottom - height, right, right + height, 0); /* as we read the file of names, keep track of pages so we can * page backward */ page = 0; page_offset = (long *)G_calloc(npages = 1, sizeof(long)); *page_offset = ftell(fd); nlist = sizeof(list) / sizeof(list[0]); for (stat = -1; stat < 0;) { line = 0; count = 0; *cur_mapset = 0; col = 0; while (1) { /* offset = ftell (fd); if (fgets (buf, sizeof buf, fd) == NULL || sscanf (buf, "%s %s", name, mapset) != 2) break; if(new_mapset = (strcmp (cur_mapset,mapset) != 0)) { if(line) line++; if (col) line++; col = 0; } if (count >= nlist || line+new_mapset >= NLINES) { if (page+1 == npages) { npages++; page_offset = (long *) G_realloc (page_offset, npages * sizeof (long)); page_offset[npages-1] = offset; } break; } if (new_mapset) { struct box dummy; char label[100]; strcpy (cur_mapset, mapset); sprintf (label, "Mapset %s", mapset); dobox (&dummy, label, WHITE, top+line*height, left, right, 0); line++; } if (col) { dobox (&list[count].box, name, GREY, top+line*height, left+width/2, right, 0); line++; col = 0; } else { dobox (&list[count].box, name, GREY, top+line*height, left, left+width/2, 0); col = 1; } strcpy (list[count].name, name); strcpy (list[count].mapset, mapset); count++; } downarrow (&more, page+1 < npages ? BLACK : WHITE); uparrow (&less, page > 0 ? BLACK : WHITE); which = -1; switch(Input_pointer(objects)) { case -1: /* more or less */ break; case -2: /* cancel */ stat = 0; continue; default: /* file picked */ strcpy(xname, list[which].name); stat = 1; continue; } fseek(fd, page_offset[page], 0); R_standard_color(WHITE); R_box_abs(left + 1, top + 1, right - 1, bottom - 1); } /* all done. restore what was under the window */ right += height; /* move it back over the sidecar */ R_standard_color(WHITE); R_box_abs(left, top, right, bottom); R_panel_restore(tempfile1); R_panel_restore(tempfile2); R_panel_delete(tempfile1); R_panel_delete(tempfile2); R_flush(); G_free(page_offset); return stat; }
int analyze(void) { static int use = 1; static Objects objects[] = { MENU("DONE", done, &use), MENU("PRINT", to_printer, &use), MENU("FILE", to_file, &use), MENU("OVERLAY", do_warp, &use), MENU(delete_msg, delete_mark, &use), INFO("Transform->", &use), MENU(order_msg, get_order, &use), INFO(pick_msg, &use), OTHER(pick, &use), {0} }; int color; int tsize; int cury; int len; int line; int top, bottom, left, right, width, middle, nums; /* to give user a response of some sort */ Menu_msg("Preparing analysis ..."); /* * build a popup window at center of the screen. * 35% the height and wide enough to hold the report * */ /* height of 1 line, based on NLINES taking up 35% vertical space */ height = (.35 * (SCREEN_BOTTOM - SCREEN_TOP)) / NLINES + 1; /* size of text, 80% of line height */ tsize = .8 * height; size = tsize - 2; /* fudge for computing pixels width of text */ /* indent for the text */ edge = .1 * height + 1; /* determine the length, in chars, of printed line */ FMT0(buf, 0); nums = strlen(buf) * size; FMT1(buf, 0.0, 0.0, 0.0); len = strlen(buf); middle = len * size; FMT2(buf, 0.0, 0.0, 0.0, 0.0); len += strlen(buf); /* width is for max chars plus sidecar for more/less */ width = len * size + nums + 2 * height; if ((SCREEN_RIGHT - SCREEN_LEFT) < width) width = SCREEN_RIGHT - SCREEN_LEFT; /* define the window */ bottom = VIEW_MENU->top - 1; top = bottom - height * NLINES; left = SCREEN_LEFT; right = left + width; middle += left + nums; nums += left; /* save what is under this area, so it can be restored */ R_panel_save(tempfile1, top, bottom + 1, left, right + 1); /* fill it with white */ R_standard_color(BACKGROUND); R_box_abs(left, top, right, bottom); right -= 2 * height; /* reduce it to exclude sidecar */ /* print messages in message area */ R_text_size(tsize, tsize); /* setup the more/less boxes in the sidecar */ R_standard_color(BLACK); less.top = top; less.bottom = top + 2 * height; less.left = right; less.right = right + 2 * height; Outline_box(less.top, less.bottom, less.left, less.right); more.top = bottom - 2 * height; more.bottom = bottom; more.left = right; more.right = right + 2 * height; Outline_box(more.top, more.bottom, more.left, more.right); /* * top two lines are for column labels * last two line is for overall rms error. */ nlines = NLINES - 3; first_point = 0; /* allocate predicted values */ xres = (double *)G_calloc(group.points.count, sizeof(double)); yres = (double *)G_calloc(group.points.count, sizeof(double)); gnd = (double *)G_calloc(group.points.count, sizeof(double)); /* compute transformation for the first time */ compute_transformation(); /* put head on the report */ cury = top; dotext(LHEAD1, cury, cury + height, left, middle, 0, BLACK); dotext(RHEAD1, cury, cury + height, middle, right - 1, 0, BLACK); cury += height; dotext(LHEAD2, cury, cury + height, left, middle, 0, BLACK); dotext(RHEAD2, cury, cury + height, middle, right - 1, 0, BLACK); cury += height; R_move_abs(left, cury - 1); R_cont_abs(right, cury - 1); /* isolate the sidecar */ R_move_abs(right, top); R_cont_abs(right, bottom); /* define report box */ report.top = cury; report.left = left; report.right = right; /* lets do it */ pager = 1; while (1) { R_text_size(tsize, tsize); line = 0; curp = first_point; cury = top + 2 * height; while (1) { if (line >= nlines || curp >= group.points.count) break; line++; if (!delete_mode) color = BLACK; else color = BLUE; if (group.equation_stat > 0 && group.points.status[curp] > 0) { /* color = BLACK; */ FMT1(buf, xres[curp], yres[curp], gnd[curp]); if (curp == xmax || curp == ymax || curp == gmax) color = RED; dotext(buf, cury, cury + height, nums, middle, 0, color); } else if (group.points.status[curp] > 0) dotext("?", cury, cury + height, nums, middle, 1, color); else dotext("not used", cury, cury + height, nums, middle, 1, color); if (pager) { FMT0(buf, curp + 1); dotext(buf, cury, cury + height, left, nums, 0, color); FMT2(buf, group.points.e1[curp], group.points.n1[curp], group.points.e2[curp], group.points.n2[curp]); dotext(buf, cury, cury + height, middle, right - 1, 0, color); } cury += height; curp++; } report.bottom = cury; downarrow(&more, curp < group.points.count ? color : BACKGROUND); uparrow(&less, first_point > 0 ? color : BACKGROUND); R_standard_color(BACKGROUND); R_box_abs(left, cury, right - 1, bottom); if (group.equation_stat < 0) { if (group.equation_stat == -1) { color = RED; strcpy(buf, "Poorly placed control points"); } else { if (group.equation_stat == -2) G_fatal_error("NOT ENOUGH MEMORY"); else G_fatal_error("PARAMETER ERROR"); } } else if (group.equation_stat == 0) { color = RED; strcpy(buf, "No active control points"); } else { color = BLACK; sprintf(buf, "Overall rms error: %.2f", rms); } dotext(buf, bottom - height, bottom, left, right - 1, 0, color); R_standard_color(BLACK); R_move_abs(left, bottom - height); R_cont_abs(right - 1, bottom - height); pager = 0; which = -1; if (Input_pointer(objects) < 0) break; display_points(1); } /* all done. restore what was under the window */ right += 2 * height; /* move it back over the sidecar */ R_standard_color(BACKGROUND); R_box_abs(left, top, right, bottom); R_panel_restore(tempfile1); R_panel_delete(tempfile1); R_flush(); G_free(xres); G_free(yres); G_free(gnd); I_put_control_points(group.name, &group.points); display_points(1); return 0; /* return but don't QUIT */ }
static int pick(int x, int y) { int n; int cur; cur = which; cancel_which(); if (inbox(&more, x, y)) { if (curp >= group.points.count) return 0; first_point = curp; pager = 1; return 1; } if (inbox(&less, x, y)) { if (first_point == 0) return 0; first_point -= nlines; if (first_point < 0) first_point = 0; pager = 1; return 1; } if (!inbox(&report, x, y)) { return 0; } n = (y - report.top) / height; if (n == cur) { /* second click! */ if (!delete_mode) { group.points.status[first_point + n] = !group.points.status[first_point + n]; compute_transformation(); show_point(first_point + n, 1); return 1; } else { delete_control_point(first_point + n); first_point = 0; compute_transformation(); pager = 1; return 1; } } /* first click */ which = n; show_point(first_point + n, 0); if (!delete_mode) R_standard_color(RED); else R_standard_color(ORANGE); Outline_box((report.top + n * height) + 1, report.top + (n + 1) * height, report.left, report.right - 1); R_flush(); return 0; /* ignore first click */ }
static int draw_objects(Objects * objects) { Objects *obj; int top, bottom, left, right; int size, edge; /* erase the menu window */ Erase_view(VIEW_MENU); R_flush(); /* determine sizes and text indentation */ size = VIEW_MENU->nrows - 4; edge = 2; R_text_size(size, size); left = VIEW_MENU->left; top = VIEW_MENU->top; bottom = VIEW_MENU->bottom; /* put the (boxed) text on the menu view */ for (obj = objects; obj->type; obj++) { if (!visible(obj)) continue; switch (obj->type) { case OPTION_OBJECT: case MENU_OBJECT: right = left + 2 * edge + Text_width(obj->label); obj->left = left; obj->right = right; obj->top = top; obj->bottom = bottom; R_standard_color(FILL_COLOR); R_box_abs(left, top, right, bottom); R_standard_color(TEXT_COLOR); Text(obj->label, top, bottom, left, right, edge); R_standard_color(OUTLINE_COLOR); Outline_box(top, bottom, left, right); left = right; break; case INFO_OBJECT: if (*obj->label == 0) break; if (*obj->status < 0) break; right = left + 2 * edge + Text_width(obj->label); R_standard_color(BLACK); Text(obj->label, top, bottom, left, right, edge); left = right; break; } } draw_option_boxes(objects); R_flush(); return 0; }