root/trunk/EDIT4/ED4_window.cxx

Revision 8630, 15.0 KB (checked in by westram, 5 weeks ago)

merge from e4fix [8430] [8431] [8432] [8433] [8434] [8435] [8436] [8437] [8438] [8440] [8441] [8442]

  • fixed display concerns
    • wrong mark boxes for unmarked species when (slowly) scrolling vertically
    • tiny gaps when moving cursor leftwards (best visible if species is selected)
    • do not draw all spacer terminals
    • rewrote ED4_bracket_terminal::draw (increased bracket-width by 1 pixel)
  • marked_species_select and selected_species_mark produced wrong counters since [8625]. fixed
  • signature of AW_device::clear_part now same as box_impl
  • Rectangle::distinct_from() no longer counts adjacent rectangles as distinct
  • AW_screen_area_conversion_mode
    • removed FAULTY_OLD_CONVERSION
    • added UPPER_LEFT_OUTLINE
  • added functions using namespace-AW-Positions
    • coordinate transformation
    • ED4_base::get_screen_area
  • no need for virtual adjust_clipping_rectangle()
    • both methods (ED4_base and ED4_terminal) were identical
  • get_screen_area -> get_win_area
    • decrement size by 1
    • use in ED4_bracket_terminal::draw and ED4_base::adjust_clipping_rectangle (eliminating confusing -1 offsets at both places)
  • added get_multi_species_manager() to ED4_area_manager and ED4_group_manager
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : ED4_window.cxx                                    //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include <ed4_extern.hxx>
12#include "ed4_class.hxx"
13#include "ed4_tools.hxx"
14#include <aw_awar.hxx>
15#include <aw_root.hxx>
16#include <arbdb.h>
17
18int ED4_window::no_of_windows = 0;                  // static variable has to be initialized only once
19
20void ED4_window::reset_all_for_new_config() {
21    scrolled_rect.reset(*this);
22    e4_assert(ED4_foldable::is_reset());
23
24    slider_pos_horizontal = 0;
25    slider_pos_vertical   = 0;
26
27    coords.top_area_x      = 0;
28    coords.top_area_y      = 0;
29    coords.top_area_height = 0;
30
31    coords.middle_area_x = 0;
32    coords.middle_area_y = 0;
33
34    coords.window_width  = 0;
35    coords.window_height = 0;
36
37    coords.window_upper_clip_point = 0;
38    coords.window_lower_clip_point = 0;
39    coords.window_left_clip_point  = 0;
40    coords.window_right_clip_point = 0;
41
42    ED4_ROOT->aw_root->awar(awar_path_for_cursor)->write_int(0);
43    ED4_ROOT->aw_root->awar(awar_path_for_Ecoli)->write_int(0);
44    ED4_ROOT->aw_root->awar(awar_path_for_basePos)->write_int(0);
45    ED4_ROOT->aw_root->awar(awar_path_for_IUPAC)->write_string(ED4_IUPAC_EMPTY);
46    ED4_ROOT->aw_root->awar(awar_path_for_helixNr)->write_string("");
47
48    if (next) next->reset_all_for_new_config();
49}
50
51
52void ED4_window::update_window_coords()
53{
54    AW_pos       x, y;
55    AW_screen_area area_size;
56
57    ED4_ROOT->top_area_man->calc_world_coords(&x, &y);
58
59    coords.top_area_x      = (long) x;
60    coords.top_area_y      = (long) y;
61    coords.top_area_height = (long) ED4_ROOT->top_area_man->extension.size[HEIGHT];
62
63    ED4_ROOT->middle_area_man->calc_world_coords(&x, &y);
64
65    coords.middle_area_x = (long) x;
66    coords.middle_area_y = (long) y;
67
68    aww->_get_area_size (AW_MIDDLE_AREA, &area_size);
69
70    coords.window_width  = area_size.r;
71    coords.window_height = area_size.b;
72
73    // world coordinates
74    coords.window_upper_clip_point = coords.middle_area_y + aww->slider_pos_vertical; // coordinate of upper clipping point of middle area
75    coords.window_lower_clip_point = coords.window_upper_clip_point + coords.window_height - coords.middle_area_y;
76
77    if (ED4_ROOT->scroll_links.link_for_hor_slider) {
78        ED4_ROOT->scroll_links.link_for_hor_slider->calc_world_coords(&x, &y);
79        coords.window_left_clip_point = (long) x + aww->slider_pos_horizontal;
80        coords.window_right_clip_point = coords.window_left_clip_point + coords.window_width - (long) x;
81    }
82
83#if defined(DEBUG) && 0
84    printf("left %d right %d (xdiff=%d) upper %d lower %d (ydiff=%d) width=%d height=%d\n",
85           coords.window_left_clip_point,
86           coords.window_right_clip_point,
87           coords.window_right_clip_point-coords.window_left_clip_point,
88           coords.window_upper_clip_point,
89           coords.window_lower_clip_point,
90           coords.window_lower_clip_point-coords.window_upper_clip_point,
91           coords.window_width,
92           coords.window_height);
93#endif
94}
95
96
97
98ED4_folding_line* ED4_foldable::insert_folding_line(AW_pos world_pos, AW_pos dimension, ED4_properties prop) {
99    ED4_folding_line *fl = NULL;
100
101    if (prop == ED4_P_VERTICAL || prop == ED4_P_HORIZONTAL) {
102        fl = new ED4_folding_line(world_pos, dimension);
103        fl->insertAs(prop == ED4_P_VERTICAL ? vertical_fl : horizontal_fl);
104    }
105    return fl;
106}
107
108ED4_window *ED4_window::get_matching_ed4w(AW_window *aw) {
109    e4_assert(aw);
110   
111    ED4_window *window = ED4_ROOT->first_window;
112    while (window && window->aww != aw) {
113        window = window->next;
114    }
115   
116    e4_assert(window); // aw is not an edit-window
117    return window;
118}
119
120
121
122void ED4_foldable::delete_folding_line(ED4_folding_line *fl, ED4_properties prop) {
123    if (prop == ED4_P_HORIZONTAL) {
124        horizontal_fl = horizontal_fl->delete_member(fl);
125    }
126    else {
127        e4_assert(prop == ED4_P_VERTICAL);
128        vertical_fl = vertical_fl->delete_member(fl);
129    }
130}
131
132AW::Rectangle ED4_scrolled_rectangle::get_world_rect() const {
133    e4_assert(is_linked());
134   
135    AW_pos x, y, dummy;
136    x_link->calc_world_coords(&x, &dummy);
137    y_link->calc_world_coords(&dummy, &y);
138
139    AW::Vector size(width_link->extension.size[WIDTH],
140                    height_link->extension.size[HEIGHT]);
141
142    return AW::Rectangle(AW::Position(x, y), size);
143}
144
145void ED4_window::update_scrolled_rectangle() {
146    if (scrolled_rect.exists()) {
147        e4_assert(scrolled_rect.is_linked());
148
149        AW::Rectangle srect = scrolled_rect.get_world_rect();
150        scrolled_rect.set_rect_and_update_folding_line_positions(srect);
151
152        // if slider positions stored in AW_window and ED4_window differ,
153        // we correct folding line dimensions:
154       
155        {
156            // update dimension and window position of folding lines at the borders of scrolled rectangle
157            int dx = aww->slider_pos_horizontal - slider_pos_horizontal;
158            int dy = aww->slider_pos_vertical - slider_pos_vertical;
159
160            scrolled_rect.add_to_top_left_dimension(dx, dy);
161        }
162
163        const AW_screen_area& area_size = get_device()->get_area_size();
164        scrolled_rect.calc_bottomRight_folding_dimensions(area_size.r, area_size.b);
165
166        update_window_coords(); // @@@ do at end of this function? (since it uses aww-slider_pos_horizontal,
167                                // which might get modified by calculate_scrollbars below);
168
169        // update window scrollbars
170        AW_world rect = { 0, srect.height(), 0, srect.width() };
171        set_scrollbar_indents();
172        aww->tell_scrolled_picture_size(rect);
173        aww->calculate_scrollbars();
174
175        check_valid_scrollbar_values(); // test that AW_window slider positions and folding line dimensions are in sync
176    }
177
178    // store synced slider positions in ED4_window
179    slider_pos_vertical   = aww->slider_pos_vertical;
180    slider_pos_horizontal = aww->slider_pos_horizontal;
181}
182
183ED4_returncode ED4_window::set_scrolled_rectangle(ED4_base *x_link, ED4_base *y_link, ED4_base *width_link, ED4_base *height_link) {
184    e4_assert(x_link);
185    e4_assert(y_link);
186    e4_assert(width_link);
187    e4_assert(height_link);
188
189    scrolled_rect.destroy_folding_lines(*this); // first remove existing scrolled rectangle
190
191    x_link->update_info.linked_to_scrolled_rectangle      = 1;
192    y_link->update_info.linked_to_scrolled_rectangle      = 1;
193    width_link->update_info.linked_to_scrolled_rectangle  = 1;
194    height_link->update_info.linked_to_scrolled_rectangle = 1;
195
196    scrolled_rect.link(x_link, y_link, width_link, height_link);
197
198    const AW_screen_area& area_size = get_device()->get_area_size();
199
200    AW::Rectangle rect = scrolled_rect.get_world_rect();
201    scrolled_rect.create_folding_lines(*this, rect, area_size.r, area_size.b);
202
203    scrolled_rect.set_rect(rect);
204
205    return ED4_R_OK;
206}
207
208static inline void clear_and_update_rectangle(AW_pos x1, AW_pos y1, AW_pos x2, AW_pos y2)
209// clears and updates any range of the screen (in win coordinates)
210// clipping range should be set correctly
211{
212    AW_screen_area rect;
213
214    rect.t = int(y1);
215    rect.b = int(y2);
216    rect.l = int(x1);
217    rect.r = int(x2);
218    ED4_set_clipping_rectangle(&rect);
219
220#if defined(DEBUG) && 0
221    static int toggle = 0;
222    current_device()->box(ED4_G_COLOR_2+toggle, true, x1, y1, x2-x1, y2-y1, AW_ALL_DEVICES_SCALED);    // fill range with color (for testing)
223    toggle = (toggle+1)&7;
224#else
225    current_device()->clear_part(x1, y1, x2-x1, y2-y1, AW_ALL_DEVICES);
226#endif
227
228    ED4_ROOT->main_manager->Show(1, 1); // direct call to Show (critical)
229}
230
231static inline void move_and_update_rectangle(AW_pos x1, AW_pos y1, AW_pos x2, AW_pos y2, int dx, int dy)
232// x1/y1=upper-left-corner (win coordinates)
233// x2/y2=lower-right-corner
234// dx/dy=movement
235{
236    AW_pos fx = dx<0 ? x1-dx : x1;  // move from position ..
237    AW_pos fy = dy<0 ? y1-dy : y1;
238    AW_pos tx = dx>0 ? x1+dx : x1;  // ..to position ..
239    AW_pos ty = dy>0 ? y1+dy : y1;
240    int xs = int(x2-x1-abs(dx));        // ..size
241    int ys = int(y2-y1-abs(dy));
242
243    {
244        AW_screen_area rect;
245        rect.t = int(ty);
246        rect.b = int(ty+ys-1);
247        rect.l = int(tx);
248        rect.r = int(tx+xs-1);
249        ED4_set_clipping_rectangle(&rect);
250    }
251
252    AW_device *device = current_device();
253    device->move_region(fx, fy, xs, ys, tx, ty);
254
255    if (dy<0) { // scroll to the top
256        device->set_top_font_overlap(true);
257        clear_and_update_rectangle(x1, y2+dy, x2, y2);
258        device->set_top_font_overlap(false);
259    }
260    else if (dy>0) { // scroll to the bottom
261        device->set_bottom_font_overlap(true);
262        clear_and_update_rectangle(x1, y1, x2, y1+dy);
263        device->set_bottom_font_overlap(false);
264    }
265
266    int char_width = ED4_ROOT->font_group.get_max_width() * 2;
267    if (dx<0) { // scroll left
268        device->set_left_font_overlap(true);
269        clear_and_update_rectangle(x2+dx-char_width, y1, x2, y2);
270        device->set_left_font_overlap(false);
271    }
272    else if (dx>0) { // scroll right
273        device->set_right_font_overlap(true);
274        clear_and_update_rectangle(x1, y1, x1+dx+char_width, y2);
275        device->set_right_font_overlap(false);
276    }
277}
278
279static inline void update_rectangle(AW_pos x1, AW_pos y1, AW_pos x2, AW_pos y2) // x1/y1=upper-left-corner x2/y2=lower-right-corner
280{
281    AW_screen_area rect;
282    rect.t = int(y1);
283    rect.b = int(y2);
284    rect.l = int(x1);
285    rect.r = int(x2);
286
287    ED4_set_clipping_rectangle(&rect);
288    clear_and_update_rectangle(x1, y1, x2, y2);
289}
290
291
292ED4_returncode ED4_window::scroll_rectangle(int dx, int dy)
293{
294    int skip_move;
295
296    if (!dx && !dy) return ED4_R_OK; // scroll not
297
298    AW::Rectangle rect = scrolled_rect.get_window_rect();
299
300    AW::Position ul = rect.upper_left_corner();
301    AW::Position lr = rect.lower_right_corner();
302
303    AW_pos left_x   = ul.xpos();
304    AW_pos top_y    = ul.ypos();
305    AW_pos right_x  = lr.xpos();
306    AW_pos bottom_y = lr.ypos();
307
308    scrolled_rect.scroll(dx, dy);
309
310    skip_move = (ABS(int(dy)) > (bottom_y - top_y - 20)) || (ABS(int(dx)) > (right_x - left_x - 20));
311
312    AW_pos leftmost_x = coords.middle_area_x;
313    AW_pos toptop_y = coords.top_area_y;
314    AW_pos topbottom_y = toptop_y + coords.top_area_height - 1;
315
316    get_device()->push_clip_scale();
317
318    // main area
319
320    if (skip_move)  update_rectangle(left_x, top_y, right_x, bottom_y); // main area
321    else            move_and_update_rectangle(left_x, top_y, right_x, bottom_y, int(dx), int(dy)); // main area
322
323    // name area (scroll only vertically)
324
325    if (dy) {
326        if (skip_move)  update_rectangle(leftmost_x, top_y, left_x, bottom_y);
327        else            move_and_update_rectangle(leftmost_x, top_y, left_x, bottom_y, 0, int(dy));
328    }
329
330    // top area (scroll only horizontally)
331
332    if (dx) {
333        if (skip_move)  update_rectangle(left_x, toptop_y, right_x, topbottom_y);
334        else            move_and_update_rectangle(left_x, toptop_y, right_x, topbottom_y, int(dx), 0);
335    }
336
337    get_device()->pop_clip_scale();
338
339    return (ED4_R_OK);
340}
341
342void ED4_window::set_scrollbar_indents() {
343    if (scrolled_rect.exists()) {
344        AW::Rectangle rect = scrolled_rect.get_window_rect();
345        aww->set_vertical_scrollbar_top_indent(rect.top() + SLIDER_OFFSET);
346        aww->set_horizontal_scrollbar_left_indent(rect.left() + SLIDER_OFFSET);
347    }
348}
349
350
351void ED4_window::delete_window(ED4_window *window) {
352    // delete from window list
353    ED4_window *temp, *temp2;
354
355    if (window == ED4_ROOT->first_window) {
356        temp = ED4_ROOT->first_window;                  // delete temp afterwards
357        ED4_ROOT->first_window = ED4_ROOT->first_window->next;
358    }
359    else {
360        temp = temp2 = ED4_ROOT->first_window;
361
362        while (temp != window) {
363            temp2 = temp;
364            temp = temp->next;
365        }
366
367        temp2->next = temp->next;
368    }
369
370    ED4_ROOT->aw_root->awar(temp->awar_path_for_cursor)->write_int(0);              // save in database
371    ED4_ROOT->aw_root->awar(temp->awar_path_for_Ecoli)->write_int(0);
372    ED4_ROOT->aw_root->awar(temp->awar_path_for_basePos)->write_int(0);
373    ED4_ROOT->aw_root->awar(temp->awar_path_for_IUPAC)->write_string(ED4_IUPAC_EMPTY);
374    ED4_ROOT->aw_root->awar(temp->awar_path_for_helixNr)->write_string("");
375    delete temp;
376}
377
378static void ED4_expose_cb(AW_window *aww, AW_CL /*cd1*/, AW_CL /*cd2*/) {
379    ED4_LocalWinContext uses(aww);
380    GB_transaction      ta(GLOBAL_gb_main);
381
382    ED4_expose_recalculations();
383    current_ed4w()->update_scrolled_rectangle();
384
385    current_device()->reset();
386    ED4_ROOT->special_window_refresh(true);
387}
388
389static void ED4_resize_cb(AW_window *aww, AW_CL /*cd1*/, AW_CL /*cd2*/) {
390    ED4_LocalWinContext uses(aww);
391    GB_transaction      ta(GLOBAL_gb_main);
392
393    current_device()->reset();
394    current_ed4w()->update_scrolled_rectangle();
395}
396
397
398ED4_window *ED4_window::insert_window(AW_window *new_aww) {
399    ED4_window *last, *temp;
400
401    temp = ED4_ROOT->first_window;          // append at end of window list
402    last = temp;
403    while (temp) {
404        last = temp;
405        temp = temp->next;
406    }
407
408    temp = new ED4_window (new_aww);
409
410    if (!ED4_ROOT->first_window) {       // this is the first window
411        ED4_ROOT->first_window = temp;
412    }
413    else if (last != NULL) {
414        last->next = temp;
415    }
416
417    // treat devices
418    new_aww->set_expose_callback(AW_MIDDLE_AREA, ED4_expose_cb, 0, 0);
419    new_aww->set_resize_callback(AW_MIDDLE_AREA, ED4_resize_cb, 0, 0);
420    new_aww->set_input_callback (AW_MIDDLE_AREA, ED4_input_cb,  0, 0);
421    new_aww->set_motion_callback(AW_MIDDLE_AREA, ED4_motion_cb, 0, 0);
422
423    new_aww->set_horizontal_change_callback(ED4_horizontal_change_cb, 0, 0);
424    new_aww->set_vertical_change_callback  (ED4_vertical_change_cb,   0, 0);
425
426    ED4_ROOT->temp_gc = ED4_G_STANDARD;
427
428    return temp;
429}
430
431ED4_window::ED4_window(AW_window *window)
432    : aww(window),
433      next(NULL),
434      slider_pos_horizontal(0),
435      slider_pos_vertical(0),
436      id(++no_of_windows),
437      is_hidden(false),
438      cursor(this)
439{
440    coords.clear();
441
442    sprintf(awar_path_for_cursor, AWAR_EDIT_SEQ_POSITION, id);
443    ED4_ROOT->aw_root->awar_int(awar_path_for_cursor, 0, AW_ROOT_DEFAULT);
444
445    sprintf(awar_path_for_Ecoli, AWAR_EDIT_ECOLI_POSITION, id);
446    ED4_ROOT->aw_root->awar_int(awar_path_for_Ecoli, 0, AW_ROOT_DEFAULT);
447
448    sprintf(awar_path_for_basePos, AWAR_EDIT_BASE_POSITION, id);
449    ED4_ROOT->aw_root->awar_int(awar_path_for_basePos, 0, AW_ROOT_DEFAULT);
450
451    sprintf(awar_path_for_IUPAC, AWAR_EDIT_IUPAC, id);
452    ED4_ROOT->aw_root->awar_string(awar_path_for_IUPAC, ED4_IUPAC_EMPTY, AW_ROOT_DEFAULT);
453
454    sprintf(awar_path_for_helixNr, AWAR_EDIT_HELIXNR, id);
455    ED4_ROOT->aw_root->awar_string(awar_path_for_helixNr, "", AW_ROOT_DEFAULT);
456}
457
458
459ED4_window::~ED4_window() {
460    delete aww;
461    no_of_windows --;
462}
Note: See TracBrowser for help on using the browser.