source: tags/svn.1.5.4/AWT/AWT_canvas.cxx

Last change on this file was 8233, checked in by westram, 12 years ago
  • AWT_canvas
    • option to toggle whether text is considered in size-calculation (on zoom-reset)
  • NTREE: added tree display options to toggle between traditional and new zoom-behavior
    • defaults are
      • similar to traditional behavior for dendro/irs-tree
      • new behavior for radial tree
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.8 KB
Line 
1// ================================================================ //
2//                                                                  //
3//   File      : AWT_canvas.cxx                                     //
4//   Purpose   :                                                    //
5//                                                                  //
6//   Institute of Microbiology (Technical University Munich)        //
7//   http://www.arb-home.de/                                        //
8//                                                                  //
9// ================================================================ //
10
11#include "awt_canvas.hxx"
12#include "awt.hxx"
13
14#include <aw_root.hxx>
15#include <aw_msg.hxx>
16#include <arbdbt.h>
17
18#include <algorithm>
19
20using namespace std;
21using namespace AW;
22
23void AWT_graphic_exports::clear() {
24    zoom_reset       = 0;
25    resize           = 0;
26    refresh          = 0;
27    save             = 0;
28    structure_change = 0;
29}
30
31void AWT_graphic_exports::init() {
32    clear();
33    padding.clear();
34
35    dont_fit_x      = 0;
36    dont_fit_y      = 0;
37    dont_fit_larger = 0;
38    dont_scroll     = 0;
39}
40
41inline void AWT_canvas::push_transaction() const { if (gb_main) GB_push_transaction(gb_main); }
42inline void AWT_canvas::pop_transaction() const { if (gb_main) GB_pop_transaction(gb_main); }
43
44void AWT_canvas::set_horizontal_scrollbar_position(AW_window *, int pos) {
45    int maxpos = int(worldsize.r-rect.r)-1;
46    if (pos>maxpos) pos = maxpos;
47    if (pos<0) pos = 0;
48    aww->set_horizontal_scrollbar_position(pos);
49}
50
51void AWT_canvas::set_vertical_scrollbar_position(AW_window *, int pos) {
52    int maxpos = int(worldsize.b-rect.b)-1;
53    if (pos>maxpos) pos = maxpos;
54    if (pos<0) pos = 0;
55    aww->set_vertical_scrollbar_position(pos);
56}
57
58void AWT_canvas::set_scrollbars() {
59    AW_pos width = this->worldinfo.r - this->worldinfo.l;
60    AW_pos height = this->worldinfo.b - this->worldinfo.t;
61
62    worldsize.l = 0;
63    worldsize.r = width*this->trans_to_fit + tree_disp->exports.get_x_padding();
64    worldsize.t = 0;
65    AW_pos scale = this->trans_to_fit;
66    if (tree_disp->exports.dont_fit_y) {
67        scale = 1.0;
68    }
69    worldsize.b = height*scale + tree_disp->exports.get_y_padding();
70
71    aww->tell_scrolled_picture_size(worldsize);
72
73    aww->calculate_scrollbars();
74
75    this->old_hor_scroll_pos = (int)((-this->worldinfo.l -
76                                      this->shift_x_to_fit)*
77                                     this->trans_to_fit +
78                                     tree_disp->exports.get_left_padding());
79    this->set_horizontal_scrollbar_position(this->aww, old_hor_scroll_pos);
80
81    this->old_vert_scroll_pos = (int)((-this->worldinfo.t -
82                                       this->shift_y_to_fit)*
83                                      this->trans_to_fit+
84                                      tree_disp->exports.get_top_padding());
85
86    this->set_vertical_scrollbar_position(this->aww, old_vert_scroll_pos);
87}
88
89void AWT_canvas::init_device(AW_device *device) {
90    device->reset();
91    device->shift(AW::Vector(shift_x_to_fit, shift_y_to_fit));
92    device->zoom(this->trans_to_fit);
93}
94
95void AWT_canvas::recalc_size(bool adjust_scrollbars) {
96    GB_transaction  dummy(this->gb_main);
97    AW_device_size *size_device = aww->get_size_device(AW_MIDDLE_AREA);
98
99    size_device->set_filter(AW_SIZE|(consider_text_for_size ? AW_SIZE_UNSCALED : 0));
100    size_device->reset();
101
102    tree_disp->show(size_device);
103
104    if (consider_text_for_size) {
105        tree_disp->exports.set_extra_text_padding(size_device->get_unscaleable_overlap());
106    }
107
108    size_device->get_size_information(&(this->worldinfo));
109    rect = size_device->get_area_size();   // real world size (no offset)
110
111    if (adjust_scrollbars) set_scrollbars();
112}
113
114void AWT_canvas::zoom_reset() {
115    recalc_size(false);
116
117    AW_pos width  = this->worldinfo.r - this->worldinfo.l;
118    AW_pos height = this->worldinfo.b - this->worldinfo.t;
119
120    AW_pos net_window_width  = rect.r - rect.l - tree_disp->exports.get_x_padding();
121    AW_pos net_window_height = rect.b - rect.t - tree_disp->exports.get_y_padding();
122   
123    if (net_window_width<AWT_MIN_WIDTH) net_window_width   = AWT_MIN_WIDTH;
124    if (net_window_height<AWT_MIN_WIDTH) net_window_height = AWT_MIN_WIDTH;
125
126    if (width <EPS) width   = EPS;
127    if (height <EPS) height = EPS;
128
129    AW_pos x_scale = net_window_width/width;
130    AW_pos y_scale = net_window_height/height;
131
132    if (tree_disp->exports.dont_fit_larger) {
133        if (width>height) {     // like dont_fit_x = 1; dont_fit_y = 0;
134            x_scale = y_scale;
135        }
136        else {                  // like dont_fit_y = 1; dont_fit_x = 0;
137            y_scale = x_scale;
138        }
139    }
140    else {
141        if (tree_disp->exports.dont_fit_x) {
142            if (tree_disp->exports.dont_fit_y) {
143                x_scale = y_scale = 1.0;
144            }
145            else {
146                x_scale = y_scale;
147            }
148        }
149        else {
150            if (tree_disp->exports.dont_fit_y) {
151                y_scale = x_scale;
152            }
153            else {
154                ;
155            }
156        }
157    }
158
159    this->trans_to_fit = x_scale;
160
161    // complete, upper left corner
162    this->shift_x_to_fit = - this->worldinfo.l + tree_disp->exports.get_left_padding()/x_scale;
163    this->shift_y_to_fit = - this->worldinfo.t + tree_disp->exports.get_top_padding()/x_scale;
164
165    this->old_hor_scroll_pos  = 0;
166    this->old_vert_scroll_pos = 0;
167
168    // scale
169
170    this->set_scrollbars();
171}
172
173void AWT_canvas::zoom(AW_device *device, bool zoomIn, const Rectangle& wanted_part, const Rectangle& current_part) {
174    // zooms the device.
175    //
176    // zoomIn == true -> wanted_part is zoomed to current_part
177    // zoomIn == false -> current_part is zoomed to wanted_part
178    //
179    // If wanted_part is very small -> assume mistake (act like single click)
180    // Single click zooms by 10% centering on click position
181
182    init_device(device);
183
184    if (!tree_disp) {
185        awt_assert(0); // we have no display - does this occur?
186                       // if yes, pls inform devel@arb-home.de about circumstances
187        return;
188    }
189
190    AW_pos width  = worldinfo.r-worldinfo.l;
191    AW_pos height = worldinfo.b-worldinfo.t;
192
193    if (width<EPS) width = EPS;
194    if (height<EPS) height = EPS;
195
196    bool takex = true;
197    bool takey = true;
198
199    if (tree_disp->exports.dont_fit_y) takey = false;
200    if (tree_disp->exports.dont_fit_x) takex = false;
201    if (tree_disp->exports.dont_fit_larger) {
202        if (width>height)   takey = false;
203        else                takex = false;
204    }
205
206    if (!takex && !takey) {
207        aw_message("Zoom does not work in this mode");
208        return;
209    }
210
211    Rectangle current(device->rtransform(current_part));
212    Rectangle wanted;
213
214    bool isClick = false;
215    if (takex) {
216        if (takey) {
217            if (wanted_part.line_vector().length()<40.0) isClick = true;
218        }
219        else {
220            if (wanted_part.width()<30.0) isClick = true;
221        }
222    }
223    else {
224        if (wanted_part.height()<30.0) isClick = true;
225    }
226
227    if (isClick) { // very small part or single click
228        // -> zoom by 10 % on click position
229        Vector wanted_diagonal = current.diagonal()*0.45;
230
231        Position clickPos     = device->rtransform(wanted_part.centroid());
232        Position screenCenter = current.centroid();
233
234        Vector center2click(screenCenter, clickPos);
235        Vector center2click_zoomed = center2click / 0.9;
236
237        Position clickPos_zoomed = screenCenter+center2click_zoomed;
238        Vector   to_zoomed(clickPos, clickPos_zoomed);
239
240        Position zoomedCenter = screenCenter+to_zoomed;
241
242        // zoom-rectangle around center
243        wanted = Rectangle(zoomedCenter-wanted_diagonal, 2*wanted_diagonal);
244    }
245    else {
246        wanted = Rectangle(device->rtransform(wanted_part));
247    }
248
249    if (!zoomIn) {
250        // calculate big rectangle (outside of viewport), which is zoomed into viewport
251
252        if (takex && takey) {
253            double    factor = current.diagonal().length()/wanted.diagonal().length();
254            Vector    curr2wanted(current.upper_left_corner(), wanted.upper_left_corner());
255            Rectangle big(current.upper_left_corner()+(curr2wanted*-factor), current.diagonal()*factor);
256
257            wanted = big;
258        }
259        else {
260            double factor;
261            if (takex) {
262                factor = current.width()/wanted.width();
263            }
264            else {
265                factor = current.height()/wanted.height();
266                awt_assert(takey);
267            }
268            Vector    curr2wanted_start(current.upper_left_corner(), wanted.upper_left_corner());
269            Vector    curr2wanted_end(current.lower_right_corner(), wanted.lower_right_corner());
270            Rectangle big(current.upper_left_corner()+(curr2wanted_start*-factor),
271                          current.lower_right_corner()+(curr2wanted_end*-factor));
272
273            wanted = big;
274        }
275    }
276
277    // scroll
278    shift_x_to_fit = takex ? -wanted.start().xpos() : (shift_x_to_fit+worldinfo.l)*trans_to_fit;
279    shift_y_to_fit = takey ? -wanted.start().ypos() : (shift_y_to_fit+worldinfo.t)*trans_to_fit;
280
281    // scale
282    if ((rect.r-rect.l)<EPS) rect.r = rect.l+1;
283    if ((rect.b-rect.t)<EPS) rect.b = rect.t+1;
284
285    AW_pos max_trans_to_fit;
286    if (takex) {
287        if (takey) { // take both
288            trans_to_fit     = max((rect.r-rect.l)/wanted.width(), (rect.b-rect.t)/wanted.height());
289            max_trans_to_fit = 32000.0/max(width, height);
290        }
291        else { // takex
292            trans_to_fit = (rect.r-rect.l)/wanted.width();
293            max_trans_to_fit = 32000.0/width;
294        }
295    }
296    else { // takey
297        trans_to_fit = (rect.b-rect.t)/wanted.height();
298        max_trans_to_fit = 32000.0/height;
299    }
300    if (trans_to_fit > max_trans_to_fit) {
301        trans_to_fit = max_trans_to_fit;
302    }
303
304    // correct scrolling for "dont_fit"-direction
305    if (takex == 0) shift_x_to_fit = (shift_x_to_fit/trans_to_fit)-worldinfo.l;
306    if (takey == 0) shift_y_to_fit = (shift_y_to_fit/trans_to_fit)-worldinfo.t;
307
308    set_scrollbars();
309}
310
311inline void nt_draw_zoom_box(AW_device *device, int gc, AW_pos x1, AW_pos y1, AW_pos x2, AW_pos y2) {
312    device->box(gc, false, x1, y1, x2-x1, y2-y1);
313}
314inline void nt_draw_zoom_box(AW_device *device, AWT_canvas *ntw) {
315    nt_draw_zoom_box(device, ntw->drag_gc,
316                     ntw->zoom_drag_sx, ntw->zoom_drag_sy,
317                     ntw->zoom_drag_ex, ntw->zoom_drag_ey);
318}
319
320static void clip_expose(AW_window *aww, AWT_canvas *ntw,
321                        int left_border, int right_border,
322                        int top_border, int bottom_border,
323                        int hor_overlap, int ver_overlap)
324{
325    AW_device *device = aww->get_device (AW_MIDDLE_AREA);
326    device->set_filter(AW_SCREEN);
327    device->reset();
328
329    device->set_top_clip_border(top_border);
330    device->set_bottom_clip_border(bottom_border);
331    device->set_left_clip_border(left_border);
332    device->set_right_clip_border(right_border);
333
334    device->clear_part(left_border, top_border, right_border-left_border,
335                       bottom_border-top_border, -1);
336
337    GB_transaction dummy(ntw->gb_main);
338
339    if (ntw->tree_disp->check_update(ntw->gb_main)>0) {
340        ntw->zoom_reset();
341    }
342
343    ntw->init_device(device);
344
345    if (hor_overlap> 0.0) {
346        device->set_right_clip_border(right_border + hor_overlap);
347    }
348    if (hor_overlap< 0.0) {
349        device->set_left_clip_border(left_border + hor_overlap);
350    }
351    if (ver_overlap> 0.0) {
352        device->set_bottom_clip_border(bottom_border + ver_overlap);
353    }
354    if (ver_overlap< 0.0) {
355        device->set_top_clip_border(top_border + ver_overlap);
356    }
357    ntw->tree_disp->show(device);
358}
359
360void AWT_expose_cb(AW_window *, AWT_canvas *ntw, AW_CL) {
361    ntw->refresh();
362}
363
364void AWT_canvas::refresh() {
365    AW_device *device = this->aww->get_device (AW_MIDDLE_AREA);
366    device->clear(-1);
367    clip_expose(this->aww, this, this->rect.l, this->rect.r,
368                this->rect.t, this->rect.b, 0, 0);
369}
370
371void AWT_resize_cb(AW_window *, AWT_canvas *ntw, AW_CL) {
372    ntw->zoom_reset();
373    AWT_expose_cb(ntw->aww, ntw, 0);
374}
375
376
377static void focus_cb(AW_window *, AWT_canvas *ntw) {
378    if (ntw->gb_main) {
379        ntw->push_transaction();
380
381        int flags = ntw->tree_disp->check_update(ntw->gb_main);
382        if (flags) ntw->recalc_size_and_refresh();
383
384        ntw->pop_transaction();
385    }
386}
387
388static bool handleZoomEvent(AW_window *aww, AWT_canvas *ntw, AW_device *device, const AW_event& event) {
389    bool handled = false;
390    bool zoomIn  = true;
391
392    if      (event.button == AWT_M_LEFT)  { handled = true; }
393    else if (event.button == AWT_M_RIGHT) { handled = true; zoomIn  = false; }
394
395    if (handled) {
396        if (event.type == AW_Mouse_Press) {
397            ntw->drag = 1;
398            ntw->zoom_drag_sx = ntw->zoom_drag_ex = event.x;
399            ntw->zoom_drag_sy = ntw->zoom_drag_ey = event.y;
400        }
401        else {
402            // delete last box
403            nt_draw_zoom_box(device, ntw);
404            ntw->drag = 0;
405
406            Rectangle screen(ntw->rect, INCLUSIVE_OUTLINE);
407            Rectangle drag(ntw->zoom_drag_sx, ntw->zoom_drag_sy, ntw->zoom_drag_ex, ntw->zoom_drag_ey);
408
409            ntw->zoom(device, zoomIn, drag, screen);
410            AWT_expose_cb(aww, ntw, 0);
411        }
412    }
413    return handled;
414}
415
416static void input_event(AW_window *aww, AWT_canvas *ntw, AW_CL /*cd2*/) {
417    AW_event event;
418    aww->get_event(&event);
419   
420    AW_device *device = aww->get_device(AW_MIDDLE_AREA);
421    device->set_filter(AW_SCREEN);
422    device->reset();
423
424    ntw->tree_disp->exports.clear();
425    ntw->push_transaction();
426
427    ntw->tree_disp->check_update(ntw->gb_main);
428
429    bool event_handled = false;
430
431    if (ntw->mode == AWT_MODE_ZOOM) { // zoom mode is identical for all applications, so handle it here
432        event_handled = handleZoomEvent(aww, ntw, device, event);
433    }
434
435    if (!event_handled) {
436        AW_device_click *click_device = aww->get_click_device(AW_MIDDLE_AREA, event.x, event.y, AWT_CATCH_LINE, AWT_CATCH_TEXT, 0);
437        click_device->set_filter(AW_CLICK);
438        device->set_filter(AW_SCREEN);
439
440        ntw->init_device(click_device);
441        ntw->init_device(device);
442
443        ntw->tree_disp->show(click_device);
444        click_device->get_clicked_line(&ntw->clicked_line);
445        click_device->get_clicked_text(&ntw->clicked_text);
446
447        ntw->tree_disp->command(device, ntw->mode,
448                                event.button, event.keymodifier, event.keycode, event.character,
449                                event.type, event.x,
450                                event.y, &ntw->clicked_line,
451                                &ntw->clicked_text);
452        if (ntw->tree_disp->exports.save) {
453            // save it
454            GB_ERROR error = ntw->tree_disp->save(ntw->gb_main, 0, 0, 0);
455            if (error) {
456                aw_message(error);
457                ntw->tree_disp->load(ntw->gb_main, 0, 0, 0);
458            }
459        }
460        if (ntw->gb_main) {
461            ntw->tree_disp->update(ntw->gb_main);
462        }
463        ntw->refresh_by_exports();
464    }
465
466    ntw->zoom_drag_ex = event.x;
467    ntw->zoom_drag_ey = event.y;
468    ntw->pop_transaction();
469}
470
471
472void AWT_canvas::set_dragEndpoint(int dragx, int dragy) {
473    bool fit_proportional = false;
474    if (tree_disp) {
475        bool dont_fit_x = tree_disp->exports.dont_fit_x;
476        bool dont_fit_y = tree_disp->exports.dont_fit_y;
477
478        if (tree_disp->exports.dont_fit_larger) {
479            AW_pos width  = worldinfo.r-worldinfo.l;
480            AW_pos height = worldinfo.b-worldinfo.t;
481
482            if (width>height) {                     // like dont_fit_x = 1; dont_fit_y = 0;
483                dont_fit_x = true;
484            }
485            else {                                  // like dont_fit_y = 1; dont_fit_x = 0;
486                dont_fit_y = true;
487            }
488        }
489
490        if (dont_fit_y) {
491            zoom_drag_sy = rect.t;
492            zoom_drag_ey = rect.b-1;
493            zoom_drag_ex = dragx;
494        }
495        else if (dont_fit_x) {
496            zoom_drag_sx = rect.l;
497            zoom_drag_ex = rect.r-1;
498            zoom_drag_ey = dragy;
499        }
500        else {
501            fit_proportional = true;
502        }
503    }
504    else {
505        fit_proportional = true;
506    }
507
508    if (fit_proportional) {
509        zoom_drag_ex = dragx;
510        zoom_drag_ey = dragy;
511
512        int drag_sx = zoom_drag_ex-zoom_drag_sx;
513        int drag_sy = zoom_drag_ey-zoom_drag_sy;
514
515        bool   correct_x = false;
516        bool   correct_y = false;
517        double factor;
518
519        int scr_sx = rect.r-rect.l;
520        int scr_sy = rect.b-rect.t;
521
522        if (drag_sx == 0) {
523            if (drag_sy != 0) { factor = double(drag_sy)/scr_sy; correct_x = true; }
524        }
525        else {
526            if (drag_sy == 0) { factor = double(drag_sx)/scr_sx; correct_y = true; }
527            else {
528                double facx = double(drag_sx)/scr_sx;
529                double facy = double(drag_sy)/scr_sy;
530
531                if (fabs(facx)>fabs(facy)) { factor = facx; correct_y = true; }
532                else                       { factor = facy; correct_x = true; }
533            }
534        }
535
536        if (correct_x) {
537            int width    = int(scr_sx*factor) * ((drag_sx*drag_sy) < 0 ? -1 : 1);
538            zoom_drag_ex = zoom_drag_sx+width;
539        }
540        else if (correct_y) {
541            int height = int(scr_sy*factor) * ((drag_sx*drag_sy) < 0 ? -1 : 1);
542            zoom_drag_ey = zoom_drag_sy+height;
543        }
544    }
545}
546
547static void motion_event(AW_window *aww, AWT_canvas *ntw, AW_CL /*cd2*/) {
548    AW_device *device = aww->get_device(AW_MIDDLE_AREA);
549    device->reset();
550    device->set_filter(AW_SCREEN);
551
552    ntw->push_transaction();
553
554    AW_event event;
555    aww->get_event(&event);
556
557    if (event.button == AWT_M_MIDDLE) {
558        // shift display in ALL modes
559        int dx = event.x - ntw->zoom_drag_ex;
560        int dy = event.y - ntw->zoom_drag_ey;
561
562        ntw->zoom_drag_ex = event.x;
563        ntw->zoom_drag_ey = event.y;
564
565
566        // display
567        ntw->scroll(aww, -dx *3, -dy *3);
568    }
569    else {
570        bool run_command = true;
571
572        if (event.button == AWT_M_LEFT || event.button == AWT_M_RIGHT) {
573            switch (ntw->mode) {
574                case AWT_MODE_ZOOM:
575                    nt_draw_zoom_box(device, ntw);
576                    ntw->set_dragEndpoint(event.x, event.y);
577                    nt_draw_zoom_box(device, ntw);
578                    run_command = false;
579                    break;
580
581                case AWT_MODE_SWAP2:
582                    if (event.button == AWT_M_RIGHT) break;
583                    // fall-through
584                case AWT_MODE_MOVE: {
585                    ntw->init_device(device);
586                    AW_device_click *click_device = aww->get_click_device(AW_MIDDLE_AREA,
587                                                                          event.x, event.y, AWT_CATCH_LINE,
588                                                                          AWT_CATCH_TEXT, 0);
589                    click_device->set_filter(AW_CLICK_DRAG);
590                    ntw->init_device(click_device);
591                    ntw->tree_disp->show(click_device);
592                    click_device->get_clicked_line(&ntw->clicked_line);
593                    click_device->get_clicked_text(&ntw->clicked_text);
594                    run_command  = false;
595                    break;
596                }
597                default:
598                    break;
599            }
600        }
601
602        if (run_command) {
603            ntw->init_device(device);
604            ntw->tree_disp->command(device, ntw->mode,
605                                    event.button, event.keymodifier, event.keycode, event.character, AW_Mouse_Drag, event.x,
606                                    event.y, &ntw->clicked_line,
607                                    &ntw->clicked_text);
608            if (ntw->gb_main) {
609                ntw->tree_disp->update(ntw->gb_main);
610            }
611        }
612    }
613
614    ntw->refresh_by_exports();
615    ntw->pop_transaction();
616}
617
618void AWT_canvas::scroll(AW_window *, int dx, int dy, bool dont_update_scrollbars) {
619    int csx, cdx, cwidth, csy, cdy, cheight;
620    AW_device *device;
621    if (!dont_update_scrollbars) {
622        this->old_hor_scroll_pos += dx;
623        this->set_horizontal_scrollbar_position(aww, this->old_hor_scroll_pos);
624        this->old_vert_scroll_pos += dy;
625        this->set_vertical_scrollbar_position(aww, this->old_vert_scroll_pos);
626    }
627    device = aww->get_device (AW_MIDDLE_AREA);
628    device->set_filter(AW_SCREEN);
629    device->reset();
630    int screenwidth = this->rect.r-this->rect.l;
631    int screenheight = this->rect.b-this->rect.t;
632
633    // compute move area params
634
635    if (dx>0) {
636        csx = dx;
637        cdx = 0;
638        cwidth = screenwidth-dx;
639    }
640    else {
641        csx = 0;
642        cdx = -dx;
643        cwidth = screenwidth+dx;
644    }
645    if (dy>0) {
646        csy = dy;
647        cdy = 0;
648        cheight = screenheight-dy;
649    }
650    else {
651        csy = 0;
652        cdy = -dy;
653        cheight = screenheight+dy;
654    }
655
656    // move area
657    if (!tree_disp->exports.dont_scroll) {
658        device->move_region(csx, csy, cwidth, cheight, cdx, cdy);
659        // redraw stripes
660        this->shift_x_to_fit -= dx/this->trans_to_fit;
661        this->shift_y_to_fit -= dy/this->trans_to_fit;
662
663        // x-stripe
664        if ((int)dx>0) {
665            clip_expose(aww, this,
666                        screenwidth-dx, screenwidth, 0, screenheight,
667                        -CLIP_OVERLAP,  0);
668        }
669        if ((int)dx<0) {
670            clip_expose(aww, this,
671                        0, -dx, 0, screenheight,
672                        CLIP_OVERLAP, 0);
673        }
674
675        // y-stripe
676        if ((int)dy>0) {
677            clip_expose(aww, this,
678                        0, screenwidth, screenheight-dy, screenheight,
679                        0, -CLIP_OVERLAP);
680        }
681        if ((int)dy<0) {
682            clip_expose(aww, this,
683                        0, screenwidth, 0,  -dy,
684                        0,  CLIP_OVERLAP);
685        }
686    }
687    else {          // redraw everything
688        // redraw stripes
689        this->shift_x_to_fit -= dx/this->trans_to_fit;
690        this->shift_y_to_fit -= dy/this->trans_to_fit;
691        AWT_expose_cb(aww, this,  0);
692    }
693    this->refresh();
694}
695
696static void scroll_vert_cb(AW_window *aww, AWT_canvas* ntw, AW_CL /*cl1*/) {
697    int delta_screen_y;
698
699    int new_vert = aww->slider_pos_vertical;
700    delta_screen_y = (new_vert - ntw->old_vert_scroll_pos);
701
702
703    ntw->scroll(aww, 0, delta_screen_y, true);
704
705    ntw->old_vert_scroll_pos = (int)new_vert;
706
707}
708
709static void scroll_hor_cb(AW_window *aww, AWT_canvas* ntw, AW_CL /*cl1*/) {
710    int delta_screen_x;
711
712    int new_hor = aww->slider_pos_horizontal;
713    delta_screen_x = (new_hor - ntw->old_hor_scroll_pos);
714
715    ntw->scroll(aww, delta_screen_x, 0, true);
716
717    ntw->old_hor_scroll_pos = new_hor;
718}
719
720
721AWT_canvas::AWT_canvas(GBDATA *gb_maini, AW_window *awwi, AWT_graphic *awd, AW_gc_manager &set_gc_manager, const char *user_awari)
722    : consider_text_for_size(true) 
723    , user_awar(strdup(user_awari))
724    , shift_x_to_fit(0)
725    , shift_y_to_fit(0)
726    , gb_main(gb_maini)
727    , aww(awwi)
728    , awr(aww->get_root())
729    , tree_disp(awd)
730    , gc_manager(tree_disp->init_devices(aww, aww->get_device (AW_MIDDLE_AREA), this, (AW_CL)0))
731    , drag_gc(aww->main_drag_gc)
732    , mode(AWT_MODE_NONE)
733{
734    tree_disp->drag_gc  = drag_gc;
735    set_gc_manager      = gc_manager;
736
737    memset((char *)&clicked_line, 0, sizeof(clicked_line));
738    memset((char *)&clicked_text, 0, sizeof(clicked_text));
739
740    AWT_resize_cb(aww, this, 0);
741
742    aww->set_expose_callback(AW_MIDDLE_AREA, (AW_CB)AWT_expose_cb, (AW_CL)this, 0);
743    aww->set_resize_callback(AW_MIDDLE_AREA, (AW_CB)AWT_resize_cb, (AW_CL)this, 0);
744    aww->set_input_callback(AW_MIDDLE_AREA, (AW_CB)input_event, (AW_CL)this, 0);
745    aww->set_focus_callback((AW_CB)focus_cb, (AW_CL)this, 0);
746
747    aww->set_motion_callback(AW_MIDDLE_AREA, (AW_CB)motion_event, (AW_CL)this, 0);
748    aww->set_horizontal_change_callback((AW_CB)scroll_hor_cb, (AW_CL)this, 0);
749    aww->set_vertical_change_callback((AW_CB)scroll_vert_cb, (AW_CL)this, 0);
750}
751
752// --------------------
753//      AWT_graphic
754// --------------------
755
756void AWT_graphic::command(AW_device *, AWT_COMMAND_MODE, int, AW_key_mod, AW_key_code, char,
757                          AW_event_type, AW_pos, AW_pos, AW_clicked_line *, AW_clicked_text *)
758{
759}
760
761void AWT_graphic::text(AW_device * /* device */, char * /* text */) {
762}
763
764// --------------------------
765//      AWT_nonDB_graphic
766// --------------------------
767
768GB_ERROR AWT_nonDB_graphic::load(GBDATA *, const char *, AW_CL, AW_CL) {
769    return "AWT_nonDB_graphic cannot be loaded";
770}
771
772GB_ERROR AWT_nonDB_graphic::save(GBDATA *, const char *, AW_CL, AW_CL) {
773    return "AWT_nonDB_graphic cannot be saved";
774}
775
776int AWT_nonDB_graphic::check_update(GBDATA *) {
777#if defined(DEBUG)
778    printf("AWT_nonDB_graphic can't be check for update\n");
779#endif // DEBUG
780    return -1;
781}
782void AWT_nonDB_graphic::update(GBDATA *) {
783#if defined(DEBUG)
784    printf("AWT_nonDB_graphic can't be updated\n");
785#endif // DEBUG
786}
787
Note: See TracBrowser for help on using the repository browser.