GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator 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 string 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 
109  /* we want the box to fit into window horizontally */
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 * 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 
122  b = Y_BORDER + t + (dots_per_line * n_options) + 1;
123  r = 2 * X_BORDER + l + (text_size * 0.8) * max_len;
124 
125  /* Adjust, if necessary, to make sure window is all on screen */
126  if (t < R_screen_top()) {
127  b = b + (R_screen_top() - t);
128  t = R_screen_top();
129  }
130  if (b > R_screen_bot()) {
131  t = t - (b - R_screen_bot());
132  b = R_screen_bot();
133  }
134  if (t < R_screen_top())
135  G_fatal_error("popup window too big vertically\n");
136 
137  if (l < R_screen_left()) {
138  r = r + (R_screen_left() - l);
139  l = R_screen_left();
140  }
141  if (r > R_screen_rite()) {
142  l = l - (r - R_screen_rite());
143  r = R_screen_rite();
144  }
145  if (l < R_screen_left()) {
146  /* actually, this should never happen */
147  fprintf(stderr, "ERROR:\n");
148  fprintf(stderr, "popup window too big horizontally\n");
149  fprintf(stderr, "to fit into the graphics window.\n");
150  fprintf(stderr, "Widen the graphics window.");
151  fprintf(stderr, "\nExiting...\n");
152  exit(1);
153  }
154 
155  /* Make sure text is not drawn outside of window */
156  R_set_window(t, b, l, r);
157 
158  /* Save the panel in some name */
159  panel = G_tempfile();
160  R_panel_save(panel, t, b, l, r);
161 
162  /* Clear the panel */
163  R_standard_color(back_colr);
164  R_box_abs(l, t, r, b);
165 
166  /* Draw border */
167  R_standard_color(text_colr);
168  R_move_abs(l + 0, t + 0);
169  R_cont_abs(r - 1, t + 0);
170  R_cont_abs(r - 1, b - 1);
171  R_cont_abs(l + 0, b - 1);
172  R_cont_abs(l + 0, t + 0);
173 
174  /* Prepare for text */
175  R_text_size(text_size, text_size);
176 
177  /* list the options */
178  for (opt = 1; opt <= n_options; opt++) {
179  if (opt != n_options) {
180  R_standard_color(div_colr);
181  R_move_abs(l + 2, t + Y_BORDER + opt * dots_per_line);
182  R_cont_rel(r - l - 4, 0);
183  }
184  R_standard_color(text_colr);
185  R_move_abs(l + X_BORDER,
186  t + Y_BORDER + opt * dots_per_line - text_raise);
187  R_text(options[opt - 1]);
188  }
189 
190  R_flush();
191 
192  x = (l + r) / 2;
193  y = (t + b) / 2;
194 
195  while (1) {
196  int n;
197 
198  R_get_location_with_pointer(&x, &y, &button);
199  if (x > r || x < l
200  || y < t + Y_BORDER + dots_per_line || y > b - Y_BORDER)
201  continue;
202 
203  n = y - t - Y_BORDER;
204  if (n % dots_per_line == 0)
205  continue;
206 
207  /* cleanup */
208  R_panel_restore(panel);
209  R_panel_delete(panel);
210 
211  return (n / dots_per_line);
212  }
213 }
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
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
int
Definition: g3dcolor.c:48
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