source: tags/arb-6.0/WINDOW/AW_at.cxx

Last change on this file was 11102, checked in by westram, 10 years ago
  • get rid of declaration of 'Mask' shadows a global declaration
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.4 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : AW_at.cxx                                         //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "aw_at.hxx"
12#include "aw_window.hxx"
13#include "aw_xfig.hxx"
14#include "aw_root.hxx"
15
16#include <arbdb.h>
17
18AW_at::AW_at() {
19    memset((char*)this, 0, sizeof(AW_at));
20
21    length_of_buttons = 10;
22    height_of_buttons = 0;
23    shadow_thickness  = 2;
24    widget_mask       = AWM_ALL;
25}
26
27
28void AW_window::shadow_width (int shadow_thickness) { _at->shadow_thickness = shadow_thickness; }
29
30void AW_window::label_length(int length) { _at->length_of_label_for_inputfield = length; }
31
32void AW_window::button_length(int length) { _at->length_of_buttons = length; }
33void AW_window::button_height(int height) { _at->height_of_buttons = height>1 ? height : 0; }
34int  AW_window::get_button_length() const { return _at->length_of_buttons; }
35int  AW_window::get_button_height() const { return _at->height_of_buttons; }
36
37void AW_window::highlight() { _at->highlight = true; }
38
39void AW_window::auto_increment(int x, int y) {
40    _at->do_auto_increment = true;
41    _at->auto_increment_x  = x;
42    _at->auto_increment_y  = y;
43
44    _at->do_auto_space = false;
45
46    _at->x_for_newline             = _at->x_for_next_button;
47    _at->biggest_height_of_buttons = 0;
48}
49
50
51void AW_window::auto_space(int x, int y) {
52    _at->do_auto_space = true;
53    _at->auto_space_x  = x;
54    _at->auto_space_y  = y;
55   
56    _at->do_auto_increment = false;
57
58    _at->x_for_newline             = _at->x_for_next_button;
59    _at->biggest_height_of_buttons = 0;
60}
61
62
63void AW_window::auto_off() {
64    _at->do_auto_space     = false;
65    _at->do_auto_increment = false;
66}
67
68void AW_window::at_set_min_size(int xmin, int ymin) {
69    if (xmin > _at->max_x_size) _at->max_x_size = xmin; // this looks wrong, but its right!
70    if (ymin > _at->max_y_size) _at->max_y_size = ymin;
71
72    if (recalc_size_at_show != AW_KEEP_SIZE) {
73        set_window_size(_at->max_x_size+1000, _at->max_y_size+1000);
74    }
75}
76
77void AW_window::help_text(const char *help_id) {
78    delete _at->helptext_for_next_button;
79    _at->helptext_for_next_button   = strdup(help_id);
80}
81
82void AW_window::sens_mask(AW_active mask) {
83    aw_assert(legal_mask(mask));
84    _at->widget_mask = mask;
85}
86
87void AW_window::callback(const WindowCallback& cb) {
88    _callback = new AW_cb(this, cb);
89}
90
91void AW_window::d_callback(const WindowCallback& cb) {
92    _d_callback = new AW_cb(this, cb);
93}
94
95void AW_window::label(const char *Label) {
96    freedup(_at->label_for_inputfield, Label);
97}
98
99
100void AW_window::at(int x, int y) {
101    at_x(x);
102    at_y(y);
103}
104
105void AW_window::at_x(int x) {
106    if (_at->x_for_next_button > _at->max_x_size) _at->max_x_size = _at->x_for_next_button;
107    _at->x_for_next_button = x;
108    if (_at->x_for_next_button > _at->max_x_size) _at->max_x_size = _at->x_for_next_button;
109}
110
111
112void AW_window::at_y(int y) {
113    if (_at->y_for_next_button + _at->biggest_height_of_buttons > _at->max_y_size)
114        _at->max_y_size = _at->y_for_next_button + _at->biggest_height_of_buttons;
115    _at->biggest_height_of_buttons = _at->biggest_height_of_buttons + _at->y_for_next_button - y;
116    if (_at->biggest_height_of_buttons<0) {
117        _at->biggest_height_of_buttons = 0;
118        if (_at->max_y_size < y)    _at->max_y_size = y;
119    }
120    _at->y_for_next_button = y;
121}
122
123
124void AW_window::at_shift(int x, int y) {
125    at(x+_at->x_for_next_button, y+_at->y_for_next_button);
126}
127
128void AW_window::at_newline() {
129    if (_at->do_auto_increment) {
130        at_y(_at->auto_increment_y + _at->y_for_next_button);
131    }
132    else {
133        if (_at->do_auto_space) {
134            at_y(_at->y_for_next_button + _at->auto_space_y + _at->biggest_height_of_buttons);
135        }
136        else {
137            GBK_terminate("neither auto_space nor auto_increment activated while using at_newline");
138        }
139    }
140    at_x(_at->x_for_newline);
141}
142
143
144void AW_window::at(const char *at_id) {
145    char to_position[100]; memset(to_position, 0, sizeof(to_position));
146
147    _at->attach_y   = _at->attach_x = false;
148    _at->attach_ly  = _at->attach_lx = false;
149    _at->attach_any = false;
150
151    if (!xfig_data) GBK_terminatef("no xfig-data loaded, can't position at(\"%s\")", at_id);
152
153    AW_xfig     *xfig = (AW_xfig *)xfig_data;
154    AW_xfig_pos *pos;
155
156    pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, at_id);
157
158    if (!pos) {
159        sprintf(to_position, "X:%s", at_id);
160        pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, to_position);
161        if (pos) _at->attach_any = _at->attach_lx = true;
162    }
163    if (!pos) {
164        sprintf(to_position, "Y:%s", at_id);
165        pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, to_position);
166        if (pos) _at->attach_any = _at->attach_ly = true;
167    }
168    if (!pos) {
169        sprintf(to_position, "XY:%s", at_id);
170        pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, to_position);
171        if (pos) _at->attach_any = _at->attach_lx = _at->attach_ly = true;
172    }
173
174    if (!pos) GBK_terminatef("ID '%s' does not exist in xfig file", at_id);
175
176    at((pos->x - xfig->minx), (pos->y - xfig->miny - this->get_root()->font_height - 9));
177    _at->correct_for_at_center = pos->center;
178
179    sprintf(to_position, "to:%s", at_id);
180    pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, to_position);
181
182    if (!pos) {
183        sprintf(to_position, "to:X:%s", at_id);
184        pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, to_position);
185        if (pos) _at->attach_any = _at->attach_x = true;
186    }
187    if (!pos) {
188        sprintf(to_position, "to:Y:%s", at_id);
189        pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, to_position);
190        if (pos) _at->attach_any = _at->attach_y = true;
191    }
192    if (!pos) {
193        sprintf(to_position, "to:XY:%s", at_id);
194        pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, to_position);
195        if (pos) _at->attach_any = _at->attach_x = _at->attach_y = true;
196    }
197
198    if (pos) {
199        _at->to_position_exists = true;
200        _at->to_position_x = (pos->x - xfig->minx);
201        _at->to_position_y = (pos->y - xfig->miny);
202        _at->correct_for_at_center = 0; // always justify left when a to-position exists
203    }
204    else {
205        _at->to_position_exists = false;
206    }
207}
208
209
210// set "$XY:id" manually
211
212void AW_window::at_attach(bool attach_x, bool attach_y) {
213    aw_assert(0); // this does not work
214    _at->attach_lx  = attach_x;
215    _at->attach_ly  = attach_y;
216    _at->attach_any = attach_x || attach_y;
217}
218
219// set "$to:XY:id" manually
220// use negative offsets to set offset from right/lower border to to-position
221
222void AW_window::at_set_to(bool attach_x, bool attach_y, int xoff, int yoff) {
223    _at->attach_any = attach_x || attach_y;
224    _at->attach_x   = attach_x;
225    _at->attach_y   = attach_y;
226
227    _at->to_position_exists = true;
228    _at->to_position_x      = xoff >= 0 ? _at->x_for_next_button + xoff : _at->max_x_size+xoff;
229    _at->to_position_y      = yoff >= 0 ? _at->y_for_next_button + yoff : _at->max_y_size+yoff;
230
231    if (_at->to_position_x > _at->max_x_size) _at->max_x_size = _at->to_position_x;
232    if (_at->to_position_y > _at->max_y_size) _at->max_y_size = _at->to_position_y;
233
234    _at->correct_for_at_center = 0;
235}
236
237void AW_window::at_unset_to() {
238    _at->attach_x   = _at->attach_y = _at->to_position_exists = false;
239    _at->attach_any = _at->attach_lx || _at->attach_ly;
240}
241
242bool AW_window::at_ifdef(const  char *at_id) {
243    if (!xfig_data) return false;
244    AW_xfig *xfig = (AW_xfig *)xfig_data;
245    char     buffer[100];
246
247#if defined(DEBUG)
248    int printed =
249#endif // DEBUG
250        sprintf(buffer, "XY:%s", at_id);
251#if defined(DEBUG)
252    aw_assert(printed<100);
253#endif // DEBUG
254
255    if (GBS_read_hash(xfig->at_pos_hash, buffer+3)) return true; // "tag"
256    if (GBS_read_hash(xfig->at_pos_hash, buffer+1)) return true; // "Y:tag"
257    if (GBS_read_hash(xfig->at_pos_hash, buffer)) return true; // "XY:tag"
258    buffer[1] = 'X';
259    if (GBS_read_hash(xfig->at_pos_hash, buffer+1)) return true; // "X:tag"
260
261    return false;
262}
263
264void AW_window::get_at_position(int *x, int *y) const { *x = _at->x_for_next_button; *y = _at->y_for_next_button; }
265int AW_window::get_at_xposition() const { return _at->x_for_next_button; }
266int AW_window::get_at_yposition() const { return _at->y_for_next_button; }
267
268void AW_window::store_at_size_and_attach(AW_at_size *at_size) {
269    at_size->store(_at);
270}
271
272void AW_window::restore_at_size_and_attach(const AW_at_size *at_size) {
273    at_size->restore(_at);
274}
275
276void AW_window::unset_at_commands() {
277    _callback   = NULL;
278    _d_callback = NULL;
279
280    _at->correct_for_at_center = 0;
281    _at->to_position_exists    = false;
282    _at->highlight             = false;
283
284    freenull(_at->helptext_for_next_button);
285    freenull(_at->label_for_inputfield);
286
287    _at->background_color = 0;
288}
289
290void AW_window::increment_at_commands(int width, int height) {
291
292    at_shift(width, 0);
293    at_shift(-width, 0);        // set bounding box
294
295    if (_at->do_auto_increment) {
296        at_shift(_at->auto_increment_x, 0);
297    }
298    if (_at->do_auto_space) {
299        at_shift(_at->auto_space_x + width, 0);
300    }
301
302    if (_at->biggest_height_of_buttons < height) {
303        _at->biggest_height_of_buttons = height;
304    }
305
306    if (_at->max_y_size < (_at->y_for_next_button + _at->biggest_height_of_buttons + 3.0)) {
307        _at->max_y_size = _at->y_for_next_button + _at->biggest_height_of_buttons + 3;
308    }
309
310    if (_at->max_x_size < (_at->x_for_next_button + this->get_root()->font_width)) {
311        _at->max_x_size = _at->x_for_next_button + this->get_root()->font_width;
312    }
313}
314
315int AW_window::calculate_string_width(int columns) const {
316    if (xfig_data) {
317        AW_xfig *xfig = (AW_xfig *)xfig_data;
318        return (int)(columns * xfig->font_scale * XFIG_DEFAULT_FONT_WIDTH);   // stdfont 8x13
319    }
320    else {
321        return columns * XFIG_DEFAULT_FONT_WIDTH; // stdfont 8x13
322    }
323}
324
325int AW_window::calculate_string_height(int rows, int offset) const {
326    if (xfig_data) {
327        AW_xfig *xfig = (AW_xfig *)xfig_data;
328        return (int)((rows * XFIG_DEFAULT_FONT_HEIGHT + offset) * xfig->font_scale); // stdfont 8x13
329    }
330    else {
331        return (rows * XFIG_DEFAULT_FONT_HEIGHT + offset);    // stdfont 8x13
332    }
333}
334
335
336char *AW_window::align_string(const char *label_text, int columns) {
337    // shortens or expands 'label_text' to 'columns' columns
338    // if label_text contains '\n', each "line" is handled separately
339
340    const char *lf     = strchr(label_text, '\n');
341    char       *result = 0;
342
343    if (!lf) {
344        result = (char*)malloc(columns+1);
345
346        int len              = strlen(label_text);
347        if (len>columns) len = columns;
348
349        memcpy(result, label_text, len);
350        if (len<columns) memset(result+len, ' ', columns-len);
351        result[columns] = 0;
352    }
353    else {
354        char *part1    = GB_strpartdup(label_text, lf-1);
355        char *aligned1 = align_string(part1, columns);
356        char *aligned2 = align_string(lf+1, columns);
357
358        result = GBS_global_string_copy("%s\n%s", aligned1, aligned2);
359
360        free(aligned2);
361        free(aligned1);
362        free(part1);
363    }
364    return result;
365}
366
367// -------------------
368//      AW_at_size
369
370void AW_at_size::store(const AW_at *at) {
371    to_position_exists = at->to_position_exists;
372    if (to_position_exists) {
373        to_offset_x = at->to_position_x - at->x_for_next_button;
374        to_offset_y = at->to_position_y - at->y_for_next_button;
375    }
376    attach_x   = at->attach_x;
377    attach_y   = at->attach_y;
378    attach_lx  = at->attach_lx;
379    attach_ly  = at->attach_ly;
380    attach_any = at->attach_any;
381}
382void AW_at_size::restore(AW_at *at) const {
383    at->to_position_exists = to_position_exists;
384    if (to_position_exists) {
385        at->to_position_x = at->x_for_next_button + to_offset_x;
386        at->to_position_y = at->y_for_next_button + to_offset_y;
387    }
388    at->attach_x   = attach_x;
389    at->attach_y   = attach_y;
390    at->attach_lx  = attach_lx;
391    at->attach_ly  = attach_ly;
392    at->attach_any = attach_any;
393}
394
395
396
397// ----------------------
398//      AW_at_maxsize
399
400void AW_at_maxsize::store(const AW_at *at) {
401    maxx = at->max_x_size;
402    maxy = at->max_y_size;
403}
404void AW_at_maxsize::restore(AW_at *at) const {
405    at->max_x_size = maxx;
406    at->max_y_size = maxy;
407}
408
409// --------------------
410//      AW_at_auto
411
412void AW_at_auto::store(const AW_at *at) {
413    if   (at->do_auto_increment) { type = INC;   x = at->auto_increment_x; y = at->auto_increment_y; }
414    else if (at->do_auto_space)  { type = SPACE; x = at->auto_space_x;     y = at->auto_space_y;     }
415    else                         { type = OFF; }
416
417    xfn  = at->x_for_newline;
418    xfnb = at->x_for_next_button;
419    yfnb = at->y_for_next_button;
420    bhob = at->biggest_height_of_buttons;
421}
422
423void AW_at_auto::restore(AW_at *at) const {
424    at->do_auto_space     = (type == SPACE);
425    at->do_auto_increment = (type == INC);
426
427    if      (at->do_auto_space)     { at->auto_space_x     = x; at->auto_space_y     = y; }
428    else if (at->do_auto_increment) { at->auto_increment_x = x; at->auto_increment_y = y; }
429
430    at->x_for_newline             = xfn;
431    at->x_for_next_button         = xfnb;
432    at->y_for_next_button         = yfnb;
433    at->biggest_height_of_buttons = bhob;
434}
Note: See TracBrowser for help on using the repository browser.