ARB
AW_at.cxx
Go to the documentation of this file.
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 <arbdbt.h>
17 
19  memset((char*)this, 0, sizeof(AW_at));
20 
21  length_of_buttons = 10;
23  shadow_thickness = 2;
25 }
26 
27 void AW_window::at(const char *at_id) {
28  char to_position[100];
29  memset(to_position, 0, sizeof(to_position));
30 
31  _at->attach_y = _at->attach_x = false;
32  _at->attach_ly = _at->attach_lx = false;
33  _at->attach_any = false;
34 
35  if (!xfig_data) GBK_terminatef("no xfig-data loaded, can't position at(\"%s\")", at_id);
36 
37  AW_xfig *xfig = (AW_xfig *)xfig_data;
38  AW_xfig_pos *pos;
39 
40  pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, at_id);
41 
42  if (!pos) {
43  sprintf(to_position, "X:%s", at_id);
44  pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, to_position);
45  if (pos) _at->attach_any = _at->attach_lx = true;
46  }
47  if (!pos) {
48  sprintf(to_position, "Y:%s", at_id);
49  pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, to_position);
50  if (pos) _at->attach_any = _at->attach_ly = true;
51  }
52  if (!pos) {
53  sprintf(to_position, "XY:%s", at_id);
54  pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, to_position);
55  if (pos) _at->attach_any = _at->attach_lx = _at->attach_ly = true;
56  }
57 
58  if (!pos) GBK_terminatef("ID '%s' does not exist in xfig file", at_id);
59 
60  at((pos->x - xfig->minx), (pos->y - xfig->miny - this->get_root()->font_height - 9));
61  _at->correct_for_at_center = pos->center;
62 
63  sprintf(to_position, "to:%s", at_id);
64  pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, to_position);
65 
66  if (!pos) {
67  sprintf(to_position, "to:X:%s", at_id);
68  pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, to_position);
69  if (pos) _at->attach_any = _at->attach_x = true;
70  }
71  if (!pos) {
72  sprintf(to_position, "to:Y:%s", at_id);
73  pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, to_position);
74  if (pos) _at->attach_any = _at->attach_y = true;
75  }
76  if (!pos) {
77  sprintf(to_position, "to:XY:%s", at_id);
78  pos = (AW_xfig_pos*)GBS_read_hash(xfig->at_pos_hash, to_position);
79  if (pos) _at->attach_any = _at->attach_x = _at->attach_y = true;
80  }
81 
82  if (pos) {
83  _at->to_position_exists = true;
84  _at->to_position_x = (pos->x - xfig->minx);
85  _at->to_position_y = (pos->y - xfig->miny);
86  _at->correct_for_at_center = 0; // always justify left when a to-position exists
87  }
88  else {
89  _at->to_position_exists = false;
90  }
91 }
92 
93 void AW_window::at(int x, int y) {
94  at_x(x);
95  at_y(y);
96 }
97 
98 void AW_window::at_x(int x) {
99  if (_at->x_for_next_button > _at->max_x_size) _at->max_x_size = _at->x_for_next_button;
100  _at->x_for_next_button = x;
101  if (_at->x_for_next_button > _at->max_x_size) _at->max_x_size = _at->x_for_next_button;
102 }
103 
104 void AW_window::at_y(int y) {
108  if (_at->biggest_height_of_buttons<0) {
109  _at->biggest_height_of_buttons = 0;
110  if (_at->max_y_size < y) _at->max_y_size = y;
111  }
112  _at->y_for_next_button = y;
113 }
114 
115 void AW_window::at_shift(int x, int y) {
116  at(x+_at->x_for_next_button, y+_at->y_for_next_button);
117 }
118 
120  if (_at->do_auto_increment) {
122  }
123  else {
124  if (_at->do_auto_space) {
126  }
127  else {
128  GBK_terminate("neither auto_space nor auto_increment activated while using at_newline");
129  }
130  }
131  at_x(_at->x_for_newline);
132 }
133 
134 bool AW_window::at_ifdef(const char *at_id_) {
135  AW_xfig *xfig = (AW_xfig *)xfig_data;
136  if (!xfig) return false;
137 
138  char buffer[100];
139 
140 #if defined(DEBUG)
141  int printed =
142 #endif // DEBUG
143  sprintf(buffer, "XY:%s", at_id_);
144 #if defined(DEBUG)
145  aw_assert(printed<100);
146 #endif // DEBUG
147 
148  if (GBS_read_hash(xfig->at_pos_hash, buffer+3)) return true; // "tag"
149  if (GBS_read_hash(xfig->at_pos_hash, buffer+1)) return true; // "Y:tag"
150  if (GBS_read_hash(xfig->at_pos_hash, buffer)) return true; // "XY:tag"
151  buffer[1] = 'X';
152  if (GBS_read_hash(xfig->at_pos_hash, buffer+1)) return true; // "X:tag"
153 
154  return false;
155 }
156 
157 void AW_window::at_attach(int x, int y) {
158  // similar to using "$XY:noId" in xfig, but works w/o defined 'noId' (ie. w/o having xfig)
159  //
160  // meaning of x/y:
161  // - positive values = absolute position like at(x, y) does
162  // - negative values = relative position to right/lower border.
163  // Position will get attached to that border.
164  // For 'x' position widget will also become right-aligned.
165  // - zero = keep current at-position
166  //
167  // Note: window should have already reached its minimum size when using an at_attach..-function!
168 
169  bool attach_x = x<0;
170  bool attach_y = y<0;
171 
172  _at->attach_any = attach_x || attach_y;
173 
174  aw_assert(_at->attach_any); // call has no effect (use at(x, y) to set an absolute position!)
175 
176  _at->attach_lx = attach_x;
177  _at->attach_ly = attach_y;
178  _at->correct_for_at_center = attach_x ? 2 : 0;
179 
180  int width, height;
181  get_window_size(width, height);
182 
183  if (x) at_x(attach_x ? width+x : x);
184  if (y) at_y(attach_y ? height+y : y);
185 }
186 
187 void AW_window::at_attach_to(bool attach_x, bool attach_y, int xoff, int yoff) {
188  // similar to using "$to:XY:noId" in xfig, but works w/o defined 'noId'
189  //
190  // negative offsets define the to-position of the widget relative to right/lower border (of the window)
191  // positive offsets define the size of the widget (from current at-position)
192  //
193  // Note: window should have already reached its minimum size when using an at_attach..-function!
194 
195  _at->attach_any = _at->attach_any || attach_x || attach_y;
196  _at->attach_x = attach_x;
197  _at->attach_y = attach_y;
198 
199  _at->to_position_exists = true;
200  _at->to_position_x = xoff >= 0 ? _at->x_for_next_button + xoff : _at->max_x_size+xoff;
201  _at->to_position_y = yoff >= 0 ? _at->y_for_next_button + yoff : _at->max_y_size+yoff;
202 
204  aw_assert(_at->to_position_y > _at->y_for_next_button); // invalid (would calculate ultra-large button-size in create_button)
205 
206  if (_at->to_position_x > _at->max_x_size) _at->max_x_size = _at->to_position_x;
207  if (_at->to_position_y > _at->max_y_size) _at->max_y_size = _at->to_position_y;
208 
209  _at->correct_for_at_center = 0;
210 }
212  _at->attach_any =
213  _at->attach_x = _at->attach_y =
214  _at->attach_lx = _at->attach_ly = false;
215 
216  _at->to_position_exists = false;
217  _at->correct_for_at_center = 0;
218 }
219 
221  _callback = NULp;
222  _d_callback = NULp;
223 
224  _at->correct_for_at_center = 0;
225  _at->to_position_exists = false;
226  _at->highlight = false;
227 
228  freenull(_at->helptext_for_next_button);
229  freenull(_at->label_for_inputfield);
230 
231  _at->background_color = 0;
232 }
233 
234 void AW_window::increment_at_commands(int width, int height) {
235 
236  at_shift(width, 0);
237  at_shift(-width, 0); // set bounding box
238 
239  if (_at->do_auto_increment) {
240  at_shift(_at->auto_increment_x, 0);
241  }
242  if (_at->do_auto_space) {
243  at_shift(_at->auto_space_x + width, 0);
244  }
245 
246  if (_at->biggest_height_of_buttons < height) {
247  _at->biggest_height_of_buttons = height;
248  }
249 
250  if (_at->max_y_size < (_at->y_for_next_button + _at->biggest_height_of_buttons + 3.0)) {
252  }
253 
254  if (_at->max_x_size < (_at->x_for_next_button + this->get_root()->font_width)) {
255  _at->max_x_size = _at->x_for_next_button + this->get_root()->font_width;
256  }
257 }
258 
259 void AW_window::auto_space(int x, int y) {
260  // Note: calling auto_space() again will reset coordinates used for at_newline()
261  // (might be helpful for generating a 2nd column in a window)
262 
263  _at->do_auto_space = true;
264  _at->auto_space_x = x;
265  _at->auto_space_y = y;
266 
267  _at->do_auto_increment = false;
268 
269  _at->x_for_newline = _at->x_for_next_button;
270  _at->biggest_height_of_buttons = 0;
271 }
272 
273 void AW_window::auto_increment(int x, int y) {
274  // Note: calling auto_increment() again will reset coordinates used for at_newline()
275 
276  _at->do_auto_increment = true;
277  _at->auto_increment_x = x;
278  _at->auto_increment_y = y;
279  _at->x_for_newline = _at->x_for_next_button;
280  _at->do_auto_space = false;
281  _at->biggest_height_of_buttons = 0;
282 }
283 
286 }
287 
289  _at->length_of_buttons = length;
290 }
291 
293  return _at->length_of_buttons;
294 }
295 
296 void AW_window::get_at_position(int *x, int *y) const {
297  *x = _at->x_for_next_button;
298  *y = _at->y_for_next_button;
299 }
300 
302  return _at->x_for_next_button;
303 }
304 
306  return _at->y_for_next_button;
307 }
308 
309 // -------------------
310 // AW_at_size
311 
312 class AW_at_size : public AW_at_storage {
313  int to_offset_x; // here we use offsets (not positions like in AW_at)
314  int to_offset_y;
315  bool to_position_exists;
316 
317  bool attach_x; // attach right side to right form
318  bool attach_y;
319  bool attach_lx; // attach left side to right form
320  bool attach_ly;
321  bool attach_any;
322 
323 public:
325  : to_offset_x(0),
326  to_offset_y(0),
327  to_position_exists(false),
328  attach_x(false),
329  attach_y(false),
330  attach_lx(false),
331  attach_ly(false),
332  attach_any(false)
333  {}
334 
335  void store(const AW_at& at) OVERRIDE;
336  void restore(AW_at& at) const OVERRIDE;
337 };
338 
339 void AW_at_size::store(const AW_at& at) {
340  to_position_exists = at.to_position_exists;
341  if (to_position_exists) {
342  to_offset_x = at.to_position_x - at.x_for_next_button;
343  to_offset_y = at.to_position_y - at.y_for_next_button;
344  }
345  attach_x = at.attach_x;
346  attach_y = at.attach_y;
347  attach_lx = at.attach_lx;
348  attach_ly = at.attach_ly;
349  attach_any = at.attach_any;
350 }
351 
352 void AW_at_size::restore(AW_at& at) const {
353  at.to_position_exists = to_position_exists;
354  if (to_position_exists) {
355  at.to_position_x = at.x_for_next_button + to_offset_x;
356  at.to_position_y = at.y_for_next_button + to_offset_y;
357  }
358  at.attach_x = attach_x;
359  at.attach_y = attach_y;
360  at.attach_lx = attach_lx;
361  at.attach_ly = attach_ly;
362  at.attach_any = attach_any;
363 }
364 
365 // -------------------
366 // AW_at_maxsize
367 
368 class AW_at_maxsize : public AW_at_storage {
369  int maxx;
370  int maxy;
371 
372 public:
374  : maxx(0),
375  maxy(0)
376  {}
377 
378  void store(const AW_at &at) OVERRIDE;
379  void restore(AW_at &at) const OVERRIDE;
380 };
381 
382 void AW_at_maxsize::store(const AW_at &at) {
383  maxx = at.max_x_size;
384  maxy = at.max_y_size;
385 }
386 
387 void AW_at_maxsize::restore(AW_at &at) const {
388  at.max_x_size = maxx;
389  at.max_y_size = maxy;
390 }
391 
392 // -------------------
393 // AW_at_auto
394 
395 class AW_at_auto : public AW_at_storage {
396  enum { INC, SPACE, OFF } type;
397  int x, y;
398  int xfn, xfnb, yfnb, bhob;
399 public:
400  AW_at_auto() : type(OFF), x(0), y(0), xfn(0), xfnb(0), yfnb(0), bhob(0) {}
401 
402  void store(const AW_at &at) OVERRIDE;
403  void restore(AW_at &at) const OVERRIDE;
404 };
405 
406 void AW_at_auto::store(const AW_at &at) {
407  if (at.do_auto_increment) {
408  type = INC;
409  x = at.auto_increment_x;
410  y = at.auto_increment_y;
411  }
412  else if (at.do_auto_space) {
413  type = SPACE;
414  x = at.auto_space_x;
415  y = at.auto_space_y;
416  }
417  else {
418  type = OFF;
419  }
420 
421  xfn = at.x_for_newline;
422  xfnb = at.x_for_next_button;
423  yfnb = at.y_for_next_button;
424  bhob = at.biggest_height_of_buttons;
425 }
426 
427 void AW_at_auto::restore(AW_at &at) const {
428  at.do_auto_space = (type == SPACE);
429  at.do_auto_increment = (type == INC);
430 
431  if (at.do_auto_space) {
432  at.auto_space_x = x;
433  at.auto_space_y = y;
434  }
435  else if (at.do_auto_increment) {
436  at.auto_increment_x = x;
437  at.auto_increment_y = y;
438  }
439 
440  at.x_for_newline = xfn;
441  at.x_for_next_button = xfnb;
442  at.y_for_next_button = yfnb;
443  at.biggest_height_of_buttons = bhob;
444 }
445 
446 // -------------------------------
447 // AW_at_storage factory
448 
450  AW_at_storage *s = NULp;
451  switch (type) {
452  case AW_AT_SIZE_AND_ATTACH: s = new AW_at_size(); break;
453  case AW_AT_AUTO: s = new AW_at_auto(); break;
454  case AW_AT_MAXSIZE: s = new AW_at_maxsize(); break;
455  }
456  aww->store_at_to(*s);
457  return s;
458 }
459 
460 int AW_window::calculate_string_width(int columns) const {
461  if (xfig_data) {
462  AW_xfig *xfig = (AW_xfig *)xfig_data;
463  return (int)(columns * xfig->font_scale * XFIG_DEFAULT_FONT_WIDTH); // stdfont 8x13
464  }
465  else {
466  return columns * XFIG_DEFAULT_FONT_WIDTH; // stdfont 8x13
467  }
468 }
469 
470 int AW_window::calculate_string_height(int rows, int offset) const {
471  if (xfig_data) {
472  AW_xfig *xfig = (AW_xfig *)xfig_data;
473  return (int)((rows * XFIG_DEFAULT_FONT_HEIGHT + offset) * xfig->font_scale); // stdfont 8x13
474  }
475  else {
476  return rows * XFIG_DEFAULT_FONT_HEIGHT + offset; // stdfont 8x13
477  }
478 }
479 
480 char *AW_window::align_string(const char *label_text, int columns) {
481  // shortens or expands 'label_text' to 'columns' columns
482  // if label_text contains '\n', each "line" is handled separately
483 
484  const char *lf = strchr(label_text, '\n');
485  char *result = NULp;
486 
487  if (!lf) {
488  ARB_alloc(result, columns+1);
489 
490  int len = strlen(label_text);
491  if (len>columns) len = columns;
492 
493  memcpy(result, label_text, len);
494  if (len<columns) memset(result+len, ' ', columns-len);
495  result[columns] = 0;
496  }
497  else {
498  char *part1 = ARB_strpartdup(label_text, lf-1);
499  char *aligned1 = align_string(part1, columns);
500  char *aligned2 = align_string(lf+1, columns);
501 
502  result = GBS_global_string_copy("%s\n%s", aligned1, aligned2);
503 
504  free(aligned2);
505  free(aligned1);
506  free(part1);
507  }
508  return result;
509 }
510 
bool to_position_exists
Definition: aw_at.hxx:40
bool attach_x
Definition: aw_at.hxx:58
int x_for_next_button
Definition: aw_at.hxx:33
AW_cb * _callback
Definition: aw_window.hxx:289
short length_of_buttons
Definition: aw_at.hxx:21
void get_at_position(int *x, int *y) const
Definition: AW_at.cxx:296
string result
bool attach_ly
Definition: aw_at.hxx:61
GB_TYPES type
void button_length(int length)
Definition: AW_at.cxx:288
int get_at_xposition() const
Definition: AW_at.cxx:301
bool do_auto_space
Definition: aw_at.hxx:42
static char * y[maxsp+1]
void store(const AW_at &at) OVERRIDE
Definition: AW_at.cxx:382
void at_x(int x)
Definition: AW_at.cxx:98
short y
Definition: aw_xfig.hxx:58
void store(const AW_at &at) OVERRIDE
Definition: AW_at.cxx:339
int auto_space_y
Definition: aw_at.hxx:44
short length_of_label_for_inputfield
Definition: aw_at.hxx:23
int max_y_size
Definition: aw_at.hxx:36
void at(int x, int y)
Definition: AW_at.cxx:93
AW_at()
Definition: AW_at.cxx:18
void unset_at_commands()
Definition: AW_at.cxx:220
short shadow_thickness
Definition: aw_at.hxx:20
void at_shift(int x, int y)
Definition: AW_at.cxx:115
int to_position_y
Definition: aw_at.hxx:39
void GBK_terminatef(const char *templat,...)
Definition: arb_msg.cxx:523
void restore(AW_at &at) const OVERRIDE
Definition: AW_at.cxx:387
Definition: aw_at.hxx:18
char * ARB_strpartdup(const char *start, const char *end)
Definition: arb_string.h:51
void restore(AW_at &at) const OVERRIDE
Definition: AW_at.cxx:352
short height_of_buttons
Definition: aw_at.hxx:22
short x_for_newline
Definition: aw_at.hxx:56
int auto_space_x
Definition: aw_at.hxx:43
char buffer[MESSAGE_BUFFERSIZE]
Definition: seq_search.cxx:34
double font_scale
Definition: aw_xfig.hxx:90
bool do_auto_increment
Definition: aw_at.hxx:46
TYPE * ARB_alloc(size_t nelem)
Definition: arb_mem.h:56
bool highlight
Definition: aw_at.hxx:24
int auto_increment_x
Definition: aw_at.hxx:47
int miny
Definition: aw_xfig.hxx:85
void increment_at_commands(int width, int height)
Definition: AW_at.cxx:234
void GBK_terminate(const char *error) __ATTR__NORETURN
Definition: arb_msg.cxx:509
AW_cb * _d_callback
Definition: aw_window.hxx:290
#define aw_assert(bed)
Definition: aw_position.hxx:29
bool attach_y
Definition: aw_at.hxx:59
#define false
Definition: ureadseq.h:13
char * helptext_for_next_button
Definition: aw_at.hxx:26
void at_unattach()
Definition: AW_at.cxx:211
short font_width
Definition: aw_root.hxx:122
AW_at_auto()
Definition: AW_at.cxx:400
void store(const AW_at &at) OVERRIDE
Definition: AW_at.cxx:406
int max_x_size
Definition: aw_at.hxx:35
int center
Definition: aw_xfig.hxx:59
int get_button_length() const
Definition: AW_at.cxx:292
AW_active widget_mask
Definition: aw_at.hxx:27
static AW_at_storage * make(AW_window *aww, AW_at_storage_type type)
Definition: AW_at.cxx:449
AW_at_size()
Definition: AW_at.cxx:324
int biggest_height_of_buttons
Definition: aw_at.hxx:50
const int XFIG_DEFAULT_FONT_WIDTH
Definition: aw_xfig.hxx:25
unsigned long int background_color
Definition: aw_at.hxx:29
void auto_space(int xspace, int yspace)
Definition: AW_at.cxx:259
void at_attach(int x, int y)
Definition: AW_at.cxx:157
#define OVERRIDE
Definition: cxxforward.h:112
int y_for_next_button
Definition: aw_at.hxx:34
int to_position_x
Definition: aw_at.hxx:38
int auto_increment_y
Definition: aw_at.hxx:48
void auto_increment(int dx, int dy)
Definition: AW_at.cxx:273
bool at_ifdef(const char *id)
Definition: AW_at.cxx:134
AW_root * get_root()
Definition: aw_window.hxx:359
void at_y(int y)
Definition: AW_at.cxx:104
#define NULp
Definition: cxxforward.h:116
char * label_for_inputfield
Definition: aw_at.hxx:31
#define offset(field)
Definition: GLwDrawA.c:73
void store_at_to(AW_at_storage &storage)
Definition: aw_window.hxx:559
short x
Definition: aw_xfig.hxx:58
int get_at_yposition() const
Definition: AW_at.cxx:305
AW_at_storage_type
Definition: aw_window.hxx:198
size_t length
GB_HASH * at_pos_hash
Definition: aw_xfig.hxx:83
void label_length(int length)
Definition: AW_at.cxx:284
bool attach_any
Definition: aw_at.hxx:62
bool attach_lx
Definition: aw_at.hxx:60
void at_newline()
Definition: AW_at.cxx:119
int minx
Definition: aw_xfig.hxx:85
int correct_for_at_center
Definition: aw_at.hxx:55
void at_attach_to(bool attach_x, bool attach_y, int xoff, int yoff)
Definition: AW_at.cxx:187
long GBS_read_hash(const GB_HASH *hs, const char *key)
Definition: adhash.cxx:392
void get_window_size(int &width, int &height)
Definition: AW_window.cxx:109
void restore(AW_at &at) const OVERRIDE
Definition: AW_at.cxx:427
char * GBS_global_string_copy(const char *templat,...)
Definition: arb_msg.cxx:194
const int XFIG_DEFAULT_FONT_HEIGHT
Definition: aw_xfig.hxx:26
GB_write_int const char s
Definition: AW_awar.cxx:154