source: tags/arb_5.5/AWT/AWT_canvas.cxx

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