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

« back to all changes in this revision

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