~ubuntu-branches/ubuntu/precise/grass/precise

« back to all changes in this revision

Viewing changes to imagery/i.ortho.photo/i.photo.2target/ask.c

  • Committer: Bazaar Package Importer
  • Author(s): Francesco Paolo Lovergine
  • Date: 2011-04-13 17:08:41 UTC
  • mfrom: (8.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20110413170841-ss1t9bic0d0uq0gz
Tags: 6.4.1-1
* New upstream version.
* Now build-dep on libjpeg-dev and current libreadline6-dev.
* Removed patch swig: obsolete.
* Policy bumped to 3.9.2, without changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ask.c */
 
2
#include <string.h>
 
3
#include <grass/raster.h>
 
4
#include "globals.h"
 
5
#include "local_proto.h"
 
6
 
 
7
#define NLINES 18
 
8
struct box
 
9
{
 
10
    int top, bottom, left, right;
 
11
};
 
12
 
 
13
static int text_size;
 
14
static int which;
 
15
static struct box cancel, more, less;
 
16
static int height, size, edge, count;
 
17
static int page, npages;
 
18
 
 
19
static int dobox(struct box *, char *, int, int, int, int, int);
 
20
static int uparrow(struct box *, int);
 
21
static int downarrow(struct box *, int);
 
22
static int pick(int, int);
 
23
static int cancel_which(void);
 
24
static int inbox(struct box *, int, int);
 
25
static int dotext(char *, int, int, int, int, int);
 
26
 
 
27
static struct
 
28
{
 
29
    char name[30], mapset[30];
 
30
    struct box box;
 
31
} list[NLINES * 2];
 
32
 
 
33
int ask_gis_files(char *type, char *file,
 
34
                  char *xname, char *xmapset, int position)
 
35
{
 
36
    static int use = 1;
 
37
    static Objects objects[] = {
 
38
        OTHER(pick, &use),
 
39
        {0}
 
40
    };
 
41
 
 
42
    char msg[100];
 
43
    FILE *fd;
 
44
    int width;
 
45
    int len1, len2, len;
 
46
    long offset;
 
47
    long *page_offset;
 
48
    int col, nlist;
 
49
    int line;
 
50
    int stat;
 
51
    char buf[100];
 
52
    int top, bottom, left, right, center;
 
53
    int topx, bottomx, leftx, rightx, widthx;
 
54
    char name[30], mapset[30], cur_mapset[30];
 
55
    int new_mapset;
 
56
 
 
57
    Menu_msg("");
 
58
 
 
59
    fd = fopen(file, "r");
 
60
    if (fd == NULL)
 
61
        G_fatal_error("ask_gis_files: can't read tempfile");
 
62
    if (fread(&len1, sizeof(len1), 1, fd) != 1
 
63
        || fread(&len2, sizeof(len2), 1, fd) != 1 || len1 <= 0 || len2 <= 0) {
 
64
        fclose(fd);
 
65
        return 0;
 
66
    }
 
67
 
 
68
    sprintf(msg, "Double click on %s file to be plotted", type);
 
69
 
 
70
    /*
 
71
     * build a popup window at center of the screen.
 
72
     * 35% the height and wide enough to hold 2 columms of file names
 
73
     *
 
74
     * the window is for choosing file names and will be laid out in 2 columns
 
75
     *
 
76
     *             ------------------------------------------
 
77
     *             |     CANCEL           | (MORE) | (LESS) | 
 
78
     *             ------------------------------------------
 
79
     *             |             mapset                     |
 
80
     *             ------------------------------------------
 
81
     *             |      name1        |   name2            |
 
82
     *             ------------------------------------------
 
83
     *             |      name3        |   name4            |
 
84
     *             ------------------------------------------
 
85
     *             |      name5        |   name6            |
 
86
     *             |                   .                    |
 
87
     *             |                   .                    |
 
88
     *             |                   .                    |
 
89
     *             ------------------------------------------
 
90
     */
 
91
 
 
92
    /* height of 1 line, based on NLINES taking up 35% vertical space */
 
93
    height = (.35 * (SCREEN_BOTTOM - SCREEN_TOP)) / NLINES + 1;
 
94
 
 
95
    /* size of text, 80% of line height */
 
96
    text_size = .8 * height;
 
97
    size = text_size - 1;       /* fudge for computing pixels width of text */
 
98
 
 
99
    /* indent for the text */
 
100
    edge = .1 * height + 1;
 
101
 
 
102
    /* this is a fudge to determine the length of the largest text */
 
103
    len1 = 2 * len1;            /* name in 2 columns */
 
104
    len2 += strlen("mapset ");
 
105
    len = (len1 > len2 ? len1 : len2);
 
106
 
 
107
    /* width is for max chars plus sidecar for more/less */
 
108
    width = len * size + height;
 
109
    widthx = strlen(msg) * size;
 
110
    if (widthx < width)
 
111
        widthx = width;
 
112
 
 
113
    /* define the window */
 
114
    top = (SCREEN_TOP + SCREEN_BOTTOM - height * NLINES) / 2;
 
115
    bottom = top + height * NLINES;
 
116
 
 
117
    center = (SCREEN_LEFT + SCREEN_RIGHT) / 2;
 
118
    if (position > 0) {
 
119
        right = (center + SCREEN_RIGHT + width) / 2;
 
120
        if (right >= SCREEN_RIGHT)
 
121
            right = SCREEN_RIGHT - 1;
 
122
        left = right - width;
 
123
    }
 
124
    else if (position < 0) {
 
125
        left = (center + SCREEN_LEFT - width) / 2;
 
126
        if (left <= SCREEN_LEFT)
 
127
            left = SCREEN_LEFT + 1;
 
128
        right = left + width;
 
129
    }
 
130
    else {
 
131
        left = center + width / 2;
 
132
        right = left + width;
 
133
    }
 
134
 
 
135
    topx = top - 3 * height;
 
136
    bottomx = topx + 2 * height;
 
137
    leftx = (left + right - widthx) / 2;
 
138
    if (leftx < SCREEN_LEFT)
 
139
        leftx = SCREEN_LEFT;
 
140
    rightx = leftx + widthx;
 
141
 
 
142
    /* save what is under these areas, so they can be restored */
 
143
    R_panel_save(tempfile1, top, bottom+1, left, right+1);
 
144
    R_panel_save(tempfile2, topx, bottomx+1, leftx, rightx+1);
 
145
 
 
146
    /* fill it top with GREY, pick area with white */
 
147
    R_standard_color(WHITE);
 
148
    R_box_abs(left, top, right, bottom);
 
149
    R_standard_color(GREY);
 
150
    R_box_abs(leftx, topx, rightx, bottomx);
 
151
 
 
152
    R_standard_color(BLACK);
 
153
    Outline_box(top, bottom, left, right);
 
154
    right -= height;            /* reduce it to exclude sidecar */
 
155
    Outline_box(top, bottom, left, right);
 
156
 
 
157
    /* print messages above the files */
 
158
    dotext(msg, topx, topx + height, leftx, rightx, 1);
 
159
    dotext("Double click here to cancel", topx + height, bottomx, leftx,
 
160
           rightx, 1);
 
161
    cancel.top = topx;
 
162
    cancel.bottom = bottomx;
 
163
    cancel.left = leftx;
 
164
    cancel.right = rightx;
 
165
 
 
166
    /* start the mouse in the cancel box */
 
167
    Set_mouse_xy((leftx + rightx) / 2, (topx + bottomx) / 2);
 
168
 
 
169
    dobox(&less, "", WHITE, top, right, right + height, 0);
 
170
    dobox(&more, "", WHITE, bottom - height, right, right + height, 0);
 
171
 
 
172
    /* as we read the file of names, keep track of pages so we can
 
173
     * page backward
 
174
     */
 
175
    page = 0;
 
176
    page_offset = (long *)G_calloc(npages = 1, sizeof(long));
 
177
    *page_offset = ftell(fd);
 
178
 
 
179
    nlist = sizeof(list) / sizeof(list[0]);
 
180
    for (stat = -1; stat < 0;) {
 
181
        line = 0;
 
182
        count = 0;
 
183
        *cur_mapset = 0;
 
184
        col = 0;
 
185
        while (1) {
 
186
            offset = ftell(fd);
 
187
            if (fgets(buf, sizeof buf, fd) == NULL
 
188
                || sscanf(buf, "%s %s", name, mapset) != 2)
 
189
                break;
 
190
            if ((new_mapset = (strcmp(cur_mapset, mapset)) != 0)) {
 
191
                if (line)
 
192
                    line++;
 
193
                if (col)
 
194
                    line++;
 
195
                col = 0;
 
196
            }
 
197
            if (count >= nlist || line + new_mapset >= NLINES) {
 
198
                if (page + 1 == npages) {
 
199
                    npages++;
 
200
                    page_offset =
 
201
                        (long *)G_realloc(page_offset, npages * sizeof(long));
 
202
                    page_offset[npages - 1] = offset;
 
203
                }
 
204
                break;
 
205
            }
 
206
            if (new_mapset) {
 
207
                struct box dummy;
 
208
                char label[100];
 
209
 
 
210
                strcpy(cur_mapset, mapset);
 
211
                sprintf(label, "Mapset %s", mapset);
 
212
                dobox(&dummy, label, WHITE, top + line * height, left, right,
 
213
                      0);
 
214
                line++;
 
215
            }
 
216
            if (col) {
 
217
                dobox(&list[count].box, name, GREY, top + line * height,
 
218
                      left + width / 2, right, 0);
 
219
                line++;
 
220
                col = 0;
 
221
            }
 
222
            else {
 
223
                dobox(&list[count].box, name, GREY, top + line * height, left,
 
224
                      left + width / 2, 0);
 
225
                col = 1;
 
226
            }
 
227
            strcpy(list[count].name, name);
 
228
            strcpy(list[count].mapset, mapset);
 
229
            count++;
 
230
        }
 
231
        downarrow(&more, page + 1 < npages ? BLACK : WHITE);
 
232
        uparrow(&less, page > 0 ? BLACK : WHITE);
 
233
        which = -1;
 
234
        switch (Input_pointer(objects)) {
 
235
        case -1:                /* more or less */
 
236
            break;
 
237
        case -2:                /* cancel */
 
238
            stat = 0;
 
239
            continue;
 
240
        default:                /* file picked */
 
241
            strcpy(xname, list[which].name);
 
242
            strcpy(xmapset, list[which].mapset);
 
243
            stat = 1;
 
244
            continue;
 
245
        }
 
246
        fseek(fd, page_offset[page], 0);
 
247
        R_standard_color(WHITE);
 
248
        R_box_abs(left + 1, top + 1, right - 1, bottom - 1);
 
249
    }
 
250
 
 
251
    /* all done. restore what was under the window */
 
252
    right += height;            /* move it back over the sidecar */
 
253
    R_standard_color(WHITE);
 
254
    R_box_abs(left, top, right, bottom);
 
255
    R_panel_restore(tempfile1);
 
256
    R_panel_restore(tempfile2);
 
257
    R_panel_delete(tempfile1);
 
258
    R_panel_delete(tempfile2);
 
259
    R_flush();
 
260
 
 
261
    G_free(page_offset);
 
262
    return stat;
 
263
}
 
264
 
 
265
static int dobox(struct box *box, char *text, int color, int top, int left,
 
266
                 int right, int centered)
 
267
{
 
268
    int bottom;
 
269
 
 
270
    bottom = top + height;
 
271
    /* fill inside of box with color */
 
272
    R_standard_color(color);
 
273
    R_box_abs(left + 1, top + 1, right - 1, bottom - 1);
 
274
 
 
275
    /* draw box outline and text in black */
 
276
    R_standard_color(BLACK);
 
277
    Outline_box(top, bottom, left, right);
 
278
    dotext(text, top, bottom, left, right, centered);
 
279
    R_flush();
 
280
 
 
281
    box->top = top;
 
282
    box->bottom = bottom;
 
283
    box->left = left;
 
284
    box->right = right;
 
285
 
 
286
    return 0;
 
287
}
 
288
 
 
289
static int uparrow(struct box *box, int color)
 
290
{
 
291
    R_standard_color(color);
 
292
    Uparrow(box->top + edge, box->bottom - edge, box->left + edge,
 
293
            box->right - edge);
 
294
 
 
295
    return 0;
 
296
}
 
297
 
 
298
static int downarrow(struct box *box, int color)
 
299
{
 
300
    R_standard_color(color);
 
301
    Downarrow(box->top + edge, box->bottom - edge, box->left + edge,
 
302
              box->right - edge);
 
303
    return 0;
 
304
}
 
305
 
 
306
static int pick(int x, int y)
 
307
{
 
308
    int n;
 
309
 
 
310
    if (inbox(&more, x, y)) {
 
311
        cancel_which();
 
312
        if (page + 1 >= npages)
 
313
            return 0;
 
314
        page++;
 
315
        return -1;
 
316
    }
 
317
    if (inbox(&less, x, y)) {
 
318
        cancel_which();
 
319
        if (page == 0)
 
320
            return 0;
 
321
        page--;
 
322
        return -1;
 
323
    }
 
324
    if (inbox(&cancel, x, y)) {
 
325
        if (which == -2)
 
326
            return -2;
 
327
        cancel_which();
 
328
        which = -2;
 
329
        R_standard_color(RED);
 
330
        Outline_box(cancel.top, cancel.bottom, cancel.left, cancel.right);
 
331
        R_flush();
 
332
        return 0;
 
333
    }
 
334
    /* search name list. handle double click */
 
335
    for (n = 0; n < count; n++)
 
336
        if (inbox(&list[n].box, x, y)) {
 
337
            if (n == which)     /* second click! */
 
338
                return 1;
 
339
            cancel_which();
 
340
            which = n;
 
341
            R_standard_color(RED);
 
342
            Outline_box(list[n].box.top, list[n].box.bottom,
 
343
                        list[n].box.left, list[n].box.right);
 
344
            R_flush();
 
345
            return 0;           /* ignore first click */
 
346
        }
 
347
 
 
348
    cancel_which();
 
349
    return 0;
 
350
}
 
351
 
 
352
static int cancel_which(void)
 
353
{
 
354
    if (which == -2) {
 
355
        R_standard_color(BLACK);
 
356
        Outline_box(cancel.top, cancel.bottom, cancel.left, cancel.right);
 
357
    }
 
358
    else if (which >= 0) {
 
359
        R_standard_color(BLACK);
 
360
        Outline_box(list[which].box.top, list[which].box.bottom,
 
361
                    list[which].box.left, list[which].box.right);
 
362
    }
 
363
    which = -1;
 
364
 
 
365
    return 0;
 
366
}
 
367
 
 
368
static int inbox(struct box *box, int x, int y)
 
369
{
 
370
    return (x > box->left && x < box->right && y > box->top &&
 
371
            y < box->bottom);
 
372
}
 
373
 
 
374
static int dotext(char *text, int top, int bottom, int left, int right,
 
375
                  int centered)
 
376
{
 
377
    R_text_size(text_size, text_size);
 
378
    R_move_abs(left + 1 + edge, bottom - 1 - edge);
 
379
    if (centered)
 
380
        R_move_rel((right - left - strlen(text) * size) / 2, 0);
 
381
    R_set_window(top, bottom, left, right);     /* for text clipping */
 
382
    R_text(text);
 
383
    R_set_window(SCREEN_TOP, SCREEN_BOTTOM, SCREEN_LEFT, SCREEN_RIGHT);
 
384
 
 
385
    return 0;
 
386
}