GRASS Programmer's Manual  6.4.3(2013)-r
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Pages
popup.c
Go to the documentation of this file.
1 
2 /****************************************************************************
3  * D_popup(back_colr, text_colr, div_colr, top, left, percent_per_line, options)
4  * int back_colr ; color of window
5  * int text_color ; color of text and border
6  * int div_color ; color of item divider lines
7  * int left, top ; pixle coordinates of top-left corner
8  * (Coordinate system is 0,0 lower left,
9  * 100,100 upper right)
10  * int percent_per_line ; percent of entire window per line of text
11  * char *options[] ; array of text showing options.
12  * The first entry is a title, not an option
13  *
14  * The bottom-right coordinates are calculated based on the top-left coors.,
15  * the percent_per_line, the number of options, and the longest option text
16  * length. If necessary, the window is moved to make sure it is inside
17  * the screen.
18  *
19  * - Current screen contents are stashed away in the area.
20  * - Area is blanked with the background color and fringed with the
21  * text color.
22  * - Options are drawn using the current font.
23  * - User uses the mouse to choose the desired option.
24  * - Area is restored with the original contents.
25  * - Number of this option is returned to the calling program.
26  ***************************************************************************/
27 #include <string.h>
28 #include <stdlib.h>
29 #include <grass/gis.h>
30 #include <grass/raster.h>
31 #include <grass/display.h>
32 
33 #define Y_BORDER 5
34 #define X_BORDER 5
35 
36 
80 int D_popup(int back_colr, int text_colr, int div_colr,
81  int top, int left, int percent_per_line, char *options[])
82 {
83  int t, l, b, r;
84  int opt;
85  int x, y;
86  int button;
87  int text_size;
88  int text_raise;
89  int n_options;
90  int max_len;
91  int len;
92  char *panel;
93  int dots_per_line, dots_per_char, height, width;
94 
95  /* Figure the number of options and the max length of options */
96  max_len = 0;
97  for (n_options = 0; options[n_options] != NULL; n_options++) {
98  len = strlen(options[n_options]);
99  if (max_len < len)
100  max_len = len;
101  }
102 
103  /* Figure the dots per line and dots_per_char */
104  height = R_screen_bot() - R_screen_top();
105  width = R_screen_rite() - R_screen_left();
106  dots_per_line = height * percent_per_line / 100;
107  dots_per_char = width / (max_len + 2);
108  /* we want the box to fit into window horizontally */
109 
110  t = R_screen_bot() - (R_screen_bot() - R_screen_top()) * top / 100;
111  l = R_screen_left() + (R_screen_rite() - R_screen_left()) * left / 100;
112 
113  /* Figure the bottom and right of the window */
114  text_size = (int)(.8 * (float)dots_per_line);
115  if (text_size > dots_per_char)
116  text_size = dots_per_char;
117 
118  text_raise = (dots_per_line - text_size + 1) / 2;
119  if (text_raise == 0)
120  text_raise = 1;
121  b = Y_BORDER + t + dots_per_line * n_options;
122  r = 2 * X_BORDER + l + text_size * max_len;
123 
124  /* Adjust, if necessary, to make sure window is all on screen */
125  if (t < R_screen_top()) {
126  b = b + (R_screen_top() - t);
127  t = R_screen_top();
128  }
129  if (b > R_screen_bot()) {
130  t = t - (b - R_screen_bot());
131  b = R_screen_bot();
132  }
133  if (t < R_screen_top())
134  G_fatal_error("popup window too big vertically\n");
135 
136  if (l < R_screen_left()) {
137  r = r + (R_screen_left() - l);
138  l = R_screen_left();
139  }
140  if (r > R_screen_rite()) {
141  l = l - (r - R_screen_rite());
142  r = R_screen_rite();
143  }
144  if (l < R_screen_left()) {
145  /* actually, this should never happen */
146  fprintf(stderr, "ERROR:\n");
147  fprintf(stderr, "popup window too big horizontally\n");
148  fprintf(stderr, "to fit into the graphics window.\n");
149  fprintf(stderr, "Widen the graphics window.");
150  fprintf(stderr, "\nExiting...\n");
151  exit(1);
152  }
153 
154  /* Make sure text is not drawn outside of window */
155  R_set_window(t, b, l, r);
156 
157  /* Save the panel in some name */
158  panel = G_tempfile();
159  R_panel_save(panel, t, b, l, r);
160 
161  /* Clear the panel */
162  R_standard_color(back_colr);
163  R_box_abs(l, t, r, b);
164 
165  /* Draw border */
166  R_standard_color(text_colr);
167  R_move_abs(l + 1, t + 1);
168  R_cont_abs(r - 1, t + 1);
169  R_cont_abs(r - 1, b - 1);
170  R_cont_abs(l + 1, b - 1);
171  R_cont_abs(l + 1, t + 1);
172 
173  /* Prepare for text */
174  R_text_size(text_size, text_size);
175 
176  /* list the options */
177  for (opt = 1; opt <= n_options; opt++) {
178  if (opt != n_options) {
179  R_standard_color(div_colr);
180  R_move_abs(l + 2, t + Y_BORDER + opt * dots_per_line);
181  R_cont_rel(r - l - 4, 0);
182  }
183  R_standard_color(text_colr);
184  R_move_abs(l + X_BORDER,
185  t + Y_BORDER + opt * dots_per_line - text_raise);
186  R_text(options[opt - 1]);
187  }
188 
189  R_flush();
190 
191  x = (l + r) / 2;
192  y = (t + b) / 2;
193 
194  while (1) {
195  int n;
196 
197  R_get_location_with_pointer(&x, &y, &button);
198  if (x > r
199  || x < l || y < t + Y_BORDER + dots_per_line || y > b - Y_BORDER)
200  continue;
201 
202  n = y - t - Y_BORDER;
203  if (n % dots_per_line == 0)
204  continue;
205 
206  R_panel_restore(panel);
207  R_panel_delete(panel);
208  return (n / dots_per_line);
209  }
210 }
void R_flush(void)
flush graphics
Definition: common.c:17
void R_panel_save(const char *name, int t, int b, int l, int r)
Definition: com_proto.c:500
void R_panel_restore(const char *name)
Definition: com_proto.c:505
int l
Definition: dataquad.c:292
float b
Definition: named_colr.c:8
int R_screen_bot(void)
bottom of screen
Definition: com_proto.c:52
int
Definition: y.tab.c:1344
void R_box_abs(int x1, int y1, int x2, int y2)
fill a box
Definition: com_proto.c:350
float r
Definition: named_colr.c:8
tuple width
void R_standard_color(int index)
select standard color
Definition: com_proto.c:90
char * G_tempfile(void)
Returns a temporary file name.
Definition: tempfile.c:47
void R_panel_delete(const char *name)
Definition: com_proto.c:510
int y
Definition: plot.c:34
int R_screen_rite(void)
screen right edge
Definition: com_proto.c:38
void R_text(const char *text)
write text
Definition: com_proto.c:421
void R_cont_abs(int x, int y)
draw line
Definition: com_proto.c:190
int R_screen_left(void)
screen left edge
Definition: com_proto.c:24
void R_move_abs(int x, int y)
move current location
Definition: com_proto.c:153
int R_screen_top(void)
top of screen
Definition: com_proto.c:67
void R_text_size(int width, int height)
set text size
Definition: com_proto.c:383
return NULL
Definition: dbfopen.c:1394
void R_get_location_with_pointer(int *wx, int *wy, int *button)
Definition: com_get.c:17
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
void R_set_window(int t, int b, int l, int r)
set text clipping frame
Definition: com_proto.c:406
int height
int n
Definition: dataquad.c:291
void R_cont_rel(int x, int y)
draw line
Definition: com_proto.c:212