GRASS Programmer's Manual  6.4.2(2012)
popup.c
Go to the documentation of this file.
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 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines