source: tags/cvs_2_svn/WINDOW/AW_at.cxx

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