GRASS Programmer's Manual
6.4.2(2012)
|
00001 00002 /**************************************************************************** 00003 * D_popup(back_colr, text_colr, div_colr, top, left, percent_per_line, options) 00004 * int back_colr ; color of window 00005 * int text_color ; color of text and border 00006 * int div_color ; color of item divider lines 00007 * int left, top ; pixle coordinates of top-left corner 00008 * (Coordinate system is 0,0 lower left, 00009 * 100,100 upper right) 00010 * int percent_per_line ; percent of entire window per line of text 00011 * char *options[] ; array of text showing options. 00012 * The first entry is a title, not an option 00013 * 00014 * The bottom-right coordinates are calculated based on the top-left coors., 00015 * the percent_per_line, the number of options, and the longest option text 00016 * length. If necessary, the window is moved to make sure it is inside 00017 * the screen. 00018 * 00019 * - Current screen contents are stashed away in the area. 00020 * - Area is blanked with the background color and fringed with the 00021 * text color. 00022 * - Options are drawn using the current font. 00023 * - User uses the mouse to choose the desired option. 00024 * - Area is restored with the original contents. 00025 * - Number of this option is returned to the calling program. 00026 ***************************************************************************/ 00027 #include <string.h> 00028 #include <stdlib.h> 00029 #include <grass/gis.h> 00030 #include <grass/raster.h> 00031 #include <grass/display.h> 00032 00033 #define Y_BORDER 5 00034 #define X_BORDER 5 00035 00036 00080 int D_popup(int back_colr, int text_colr, int div_colr, 00081 int top, int left, int percent_per_line, char *options[]) 00082 { 00083 int t, l, b, r; 00084 int opt; 00085 int x, y; 00086 int button; 00087 int text_size; 00088 int text_raise; 00089 int n_options; 00090 int max_len; 00091 int len; 00092 char *panel; 00093 int dots_per_line, dots_per_char, height, width; 00094 00095 /* Figure the number of options and the max length of options */ 00096 max_len = 0; 00097 for (n_options = 0; options[n_options] != NULL; n_options++) { 00098 len = strlen(options[n_options]); 00099 if (max_len < len) 00100 max_len = len; 00101 } 00102 00103 /* Figure the dots per line and dots_per_char */ 00104 height = R_screen_bot() - R_screen_top(); 00105 width = R_screen_rite() - R_screen_left(); 00106 dots_per_line = height * percent_per_line / 100; 00107 dots_per_char = width / (max_len + 2); 00108 /* we want the box to fit into window horizontally */ 00109 00110 t = R_screen_bot() - (R_screen_bot() - R_screen_top()) * top / 100; 00111 l = R_screen_left() + (R_screen_rite() - R_screen_left()) * left / 100; 00112 00113 /* Figure the bottom and right of the window */ 00114 text_size = (int)(.8 * (float)dots_per_line); 00115 if (text_size > dots_per_char) 00116 text_size = dots_per_char; 00117 00118 text_raise = (dots_per_line - text_size + 1) / 2; 00119 if (text_raise == 0) 00120 text_raise = 1; 00121 b = Y_BORDER + t + dots_per_line * n_options; 00122 r = 2 * X_BORDER + l + text_size * max_len; 00123 00124 /* Adjust, if necessary, to make sure window is all on screen */ 00125 if (t < R_screen_top()) { 00126 b = b + (R_screen_top() - t); 00127 t = R_screen_top(); 00128 } 00129 if (b > R_screen_bot()) { 00130 t = t - (b - R_screen_bot()); 00131 b = R_screen_bot(); 00132 } 00133 if (t < R_screen_top()) 00134 G_fatal_error("popup window too big vertically\n"); 00135 00136 if (l < R_screen_left()) { 00137 r = r + (R_screen_left() - l); 00138 l = R_screen_left(); 00139 } 00140 if (r > R_screen_rite()) { 00141 l = l - (r - R_screen_rite()); 00142 r = R_screen_rite(); 00143 } 00144 if (l < R_screen_left()) { 00145 /* actually, this should never happen */ 00146 fprintf(stderr, "ERROR:\n"); 00147 fprintf(stderr, "popup window too big horizontally\n"); 00148 fprintf(stderr, "to fit into the graphics window.\n"); 00149 fprintf(stderr, "Widen the graphics window."); 00150 fprintf(stderr, "\nExiting...\n"); 00151 exit(1); 00152 } 00153 00154 /* Make sure text is not drawn outside of window */ 00155 R_set_window(t, b, l, r); 00156 00157 /* Save the panel in some name */ 00158 panel = G_tempfile(); 00159 R_panel_save(panel, t, b, l, r); 00160 00161 /* Clear the panel */ 00162 R_standard_color(back_colr); 00163 R_box_abs(l, t, r, b); 00164 00165 /* Draw border */ 00166 R_standard_color(text_colr); 00167 R_move_abs(l + 1, t + 1); 00168 R_cont_abs(r - 1, t + 1); 00169 R_cont_abs(r - 1, b - 1); 00170 R_cont_abs(l + 1, b - 1); 00171 R_cont_abs(l + 1, t + 1); 00172 00173 /* Prepare for text */ 00174 R_text_size(text_size, text_size); 00175 00176 /* list the options */ 00177 for (opt = 1; opt <= n_options; opt++) { 00178 if (opt != n_options) { 00179 R_standard_color(div_colr); 00180 R_move_abs(l + 2, t + Y_BORDER + opt * dots_per_line); 00181 R_cont_rel(r - l - 4, 0); 00182 } 00183 R_standard_color(text_colr); 00184 R_move_abs(l + X_BORDER, 00185 t + Y_BORDER + opt * dots_per_line - text_raise); 00186 R_text(options[opt - 1]); 00187 } 00188 00189 R_flush(); 00190 00191 x = (l + r) / 2; 00192 y = (t + b) / 2; 00193 00194 while (1) { 00195 int n; 00196 00197 R_get_location_with_pointer(&x, &y, &button); 00198 if (x > r 00199 || x < l || y < t + Y_BORDER + dots_per_line || y > b - Y_BORDER) 00200 continue; 00201 00202 n = y - t - Y_BORDER; 00203 if (n % dots_per_line == 0) 00204 continue; 00205 00206 R_panel_restore(panel); 00207 R_panel_delete(panel); 00208 return (n / dots_per_line); 00209 } 00210 }