21 #if defined(DEVEL_RALF)
25 #if defined(TRACE_MODEL_VIEW_UPDATES)
29 tm *tms = localtime(&t);
31 strftime(atime, 255,
"%k:%M:%S", tms);
32 fprintf(stderr,
"[MVU] %s: %s\n", atime, action);
34 #else // !TRACE_MODEL_VIEW_UPDATES
62 int maxpos =
int(worldsize.r-rect.r)-1;
63 if (pos>maxpos) pos = maxpos;
65 aww->set_horizontal_scrollbar_position(pos);
69 int maxpos =
int(worldsize.b-rect.b)-1;
70 if (pos>maxpos) pos = maxpos;
72 aww->set_vertical_scrollbar_position(pos);
76 AW_pos width = this->worldinfo.r - this->worldinfo.l;
77 AW_pos height = this->worldinfo.b - this->worldinfo.t;
82 AW::Vector zv = gfx->exports.zoomVector(trans_to_fit);
84 worldsize.r = width *zv.
x() + gfx->exports.get_x_padding();
85 worldsize.b = height*zv.
y() + gfx->exports.get_y_padding();
87 aww->tell_scrolled_picture_size(worldsize);
89 aww->calculate_scrollbars();
91 this->old_hor_scroll_pos = (
int)((-this->worldinfo.l -
92 this->shift_x_to_fit)*
94 gfx->exports.get_left_padding());
95 this->set_horizontal_scrollbar_position(this->aww, old_hor_scroll_pos);
97 this->old_vert_scroll_pos = (
int)((-this->worldinfo.t -
98 this->shift_y_to_fit)*
100 gfx->exports.get_top_padding());
102 this->set_vertical_scrollbar_position(this->aww, old_vert_scroll_pos);
108 device->
zoom(this->trans_to_fit);
116 AW_pos old_width = worldinfo.r - worldinfo.l;
117 AW_pos old_height = worldinfo.b - worldinfo.t;
123 size_device->
reset();
125 gfx->show(size_device);
127 if (consider_text_for_size) {
134 if (adjust_scrollbars) {
136 if (shift_x_to_fit<0) {
137 AW_pos new_width = worldinfo.
r - worldinfo.l;
138 shift_x_to_fit *= new_width/old_width;
142 if (shift_y_to_fit<0) {
143 AW_pos new_height = worldinfo.b - worldinfo.t;
144 shift_y_to_fit *= new_height/old_height;
151 gfx->exports.clear_resize_request();
152 gfx->exports.request_refresh();
156 instant_resize(
false);
159 AW_pos width = this->worldinfo.r - this->worldinfo.l;
160 AW_pos height = this->worldinfo.b - this->worldinfo.t;
162 AW_pos net_window_width = rect.r - rect.l - gfx->exports.get_x_padding();
163 AW_pos net_window_height = rect.b - rect.t - gfx->exports.get_y_padding();
168 if (width <
EPS) width =
EPS;
169 if (height <
EPS) height =
EPS;
171 AW_pos x_scale = net_window_width/width;
172 AW_pos y_scale = net_window_height/height;
175 switch (gfx->exports.fit_mode) {
177 case AWT_FIT_X: trans_to_fit = x_scale;
break;
178 case AWT_FIT_Y: trans_to_fit = y_scale;
break;
184 AW_pos center_shift_x = 0;
185 AW_pos center_shift_y = 0;
187 if (gfx->exports.zoom_mode&
AWT_ZOOM_X) center_shift_x = (net_window_width /trans_to_fit - width)/2;
188 if (gfx->exports.zoom_mode&
AWT_ZOOM_Y) center_shift_y = (net_window_height/trans_to_fit - height)/2;
191 this->shift_x_to_fit = - this->worldinfo.l + gfx->exports.get_left_padding()/trans_to_fit + center_shift_x;
192 this->shift_y_to_fit = - this->worldinfo.t + gfx->exports.get_top_padding()/trans_to_fit + center_shift_y;
194 this->old_hor_scroll_pos = 0;
195 this->old_vert_scroll_pos = 0;
199 this->set_scrollbars();
201 gfx->exports.clear_zoom_reset_request();
221 AW_pos width = worldinfo.r-worldinfo.l;
222 AW_pos height = worldinfo.b-worldinfo.t;
224 if (width<
EPS) width =
EPS;
225 if (height<
EPS) height =
EPS;
229 aw_message(
"Zoom does not work in this mode");
236 bool isClick =
false;
249 Vector click2UpperLeft = current.upper_left_corner()-clickPos;
250 Vector click2LowerRight = current.lower_right_corner()-clickPos;
252 double scale = (100-percent)/100.0;
254 wanted =
Rectangle(clickPos+scale*click2UpperLeft, clickPos+scale*click2LowerRight);
264 double factor = current.
diagonal().
length()/wanted.diagonal().length();
265 Vector curr2wanted(current.upper_left_corner(), wanted.upper_left_corner());
266 Rectangle big(current.upper_left_corner()+(curr2wanted*-factor), current.diagonal()*factor);
273 factor = current.
width()/wanted.width();
277 factor = current.height()/wanted.height();
279 Vector curr2wanted_start(current.upper_left_corner(), wanted.upper_left_corner());
280 Vector curr2wanted_end(current.lower_right_corner(), wanted.lower_right_corner());
281 Rectangle big(current.upper_left_corner()+(curr2wanted_start*-factor),
282 current.lower_right_corner()+(curr2wanted_end*-factor));
289 shift_x_to_fit = (zoom_mode&
AWT_ZOOM_X) ? -wanted.start().xpos() : (shift_x_to_fit+worldinfo.l)*trans_to_fit;
290 shift_y_to_fit = (zoom_mode&
AWT_ZOOM_Y) ? -wanted.start().ypos() : (shift_y_to_fit+worldinfo.t)*trans_to_fit;
293 if ((rect.r-rect.l)<
EPS) rect.r = rect.l+1;
294 if ((rect.b-rect.t)<
EPS) rect.b = rect.t+1;
296 AW_pos max_trans_to_fit = 0;
300 trans_to_fit =
max((rect.r-rect.l)/wanted.width(), (rect.b-rect.t)/wanted.height());
301 max_trans_to_fit = 32000.0/
max(width, height);
305 trans_to_fit = (rect.r-rect.l)/wanted.width();
306 max_trans_to_fit = 32000.0/width;
310 trans_to_fit = (rect.b-rect.t)/wanted.height();
311 max_trans_to_fit = 32000.0/height;
316 trans_to_fit =
std::min(trans_to_fit, max_trans_to_fit);
319 if (zoom_mode ==
AWT_ZOOM_Y) shift_x_to_fit = (shift_x_to_fit/trans_to_fit)-worldinfo.l;
320 if (zoom_mode ==
AWT_ZOOM_X) shift_y_to_fit = (shift_y_to_fit/trans_to_fit)-worldinfo.t;
336 int left_border,
int right_border,
337 int top_border,
int bottom_border,
338 int hor_overlap,
int ver_overlap)
349 device->
clear_part(left_border, top_border, right_border-left_border,
350 bottom_border-top_border, -1);
356 if (hor_overlap> 0.0) {
359 if (hor_overlap< 0.0) {
362 if (ver_overlap> 0.0) {
365 if (ver_overlap< 0.0) {
378 clip_expose(this->aww,
this, this->rect.l, this->rect.r,
379 this->rect.t, this->rect.b, 0, 0);
381 gfx->exports.clear_refresh_request();
397 switch (whatChanged) {
422 bool handled =
false;
442 scr->
zoom(device, zoomIn, drag, screen, percent);
471 int viewport_size = horizontal ? (rect.r-rect.l+1) : (rect.b-rect.t+1);
472 int gfx_size = horizontal ? (worldsize.r-worldsize.l) : (worldsize.b-worldsize.t);
475 int dist =
std::min(viewport_size / 20, gfx_size / 30);
476 int direction =
event.button ==
AW_WHEEL_UP ? -dist : dist;
478 int dx = horizontal ? direction : 0;
479 int dy = horizontal ? 0 : direction;
487 void AWT_graphic::update_DB_and_model_as_requested(
GBDATA *
gb_main) {
491 if (exports.needs_save()) {
496 load_from_DB(gb_main,
NULp);
498 exports.clear_save_request();
500 exports.request_structure_update();
503 if (exports.needs_structure_update()) {
506 exports.clear_structure_update_request();
508 exports.request_resize();
509 awt_assert(!exports.needs_structure_update());
511 if (gb_main) notify_synchronized(gb_main);
525 gfx->update_DB_and_model_as_requested(gb_main);
529 gfx->exports.update_display_as_requested(
this, perform_refresh);
548 bool event_handled =
false;
551 event_handled =
true;
557 if (!event_handled) {
561 if (!event_handled) {
589 switch (gfx->exports.zoom_mode) {
595 zoom_drag_sy = rect.t;
596 zoom_drag_ey = rect.b-1;
597 zoom_drag_ex = dragx;
601 zoom_drag_sx = rect.l;
602 zoom_drag_ex = rect.r-1;
603 zoom_drag_ey = dragy;
607 zoom_drag_ex = dragx;
608 zoom_drag_ey = dragy;
610 int drag_sx = zoom_drag_ex-zoom_drag_sx;
611 int drag_sy = zoom_drag_ey-zoom_drag_sy;
613 bool correct_x =
false;
614 bool correct_y =
false;
617 int scr_sx = rect.r-rect.l;
618 int scr_sy = rect.b-rect.t;
621 if (drag_sy != 0) { factor = double(drag_sy)/scr_sy; correct_x =
true; }
624 if (drag_sy == 0) { factor = double(drag_sx)/scr_sx; correct_y =
true; }
626 double facx = double(drag_sx)/scr_sx;
627 double facy = double(drag_sy)/scr_sy;
629 if (fabs(facx)>fabs(facy)) { factor = facx; correct_y =
true; }
630 else { factor = facy; correct_x =
true; }
635 int width =
int(scr_sx*factor) * ((drag_sx*drag_sy) < 0 ? -1 : 1);
636 zoom_drag_ex = zoom_drag_sx+width;
638 else if (correct_y) {
639 int height =
int(scr_sy*factor) * ((drag_sx*drag_sy) < 0 ? -1 : 1);
640 zoom_drag_ey = zoom_drag_sy+height;
669 scr->
scroll(-dx*3, -dy*3);
681 AW_device_click *click_device =
NULp;
703 int csx, cdx, cwidth, csy, cdy, cheight;
705 if (!dont_update_scrollbars) {
706 this->old_hor_scroll_pos += dx;
707 this->set_horizontal_scrollbar_position(aww, this->old_hor_scroll_pos);
708 this->old_vert_scroll_pos += dy;
709 this->set_vertical_scrollbar_position(aww, this->old_vert_scroll_pos);
714 int screenwidth = this->rect.r-this->rect.l;
715 int screenheight = this->rect.b-this->rect.t;
722 cwidth = screenwidth-dx;
727 cwidth = screenwidth+dx;
732 cheight = screenheight-dy;
737 cheight = screenheight+dy;
741 if (!gfx->exports.dont_scroll) {
742 device->
move_region(csx, csy, cwidth, cheight, cdx, cdy);
744 this->shift_x_to_fit -= dx/this->trans_to_fit;
745 this->shift_y_to_fit -= dy/this->trans_to_fit;
750 screenwidth-dx, screenwidth, 0, screenheight,
755 0, -dx, 0, screenheight,
762 0, screenwidth, screenheight-dy, screenheight,
767 0, screenwidth, 0, -dy,
773 this->shift_x_to_fit -= dx/this->trans_to_fit;
774 this->shift_y_to_fit -= dy/this->trans_to_fit;
777 this->request_refresh();
784 scr->
scroll(0, delta_screen_y,
true);
792 scr->
scroll(delta_screen_x, 0,
true);
798 consider_text_for_size(
true),
800 announce_update_cb(
NULp),
806 awr(aww->get_root()),
808 gc_manager(gfx->init_devices(aww, aww->get_device(
AW_MIDDLE_AREA), this)),
829 return "AWT_nonDB_graphic cannot be loaded";
833 return "AWT_nonDB_graphic cannot be saved";
838 printf(
"AWT_nonDB_graphic can't check_for_DB_update\n");
843 printf(
"AWT_nonDB_graphic can't notify_synchronized\n");
void zoom(AW_device *device, bool zoomIn, const AW::Rectangle &wanted_part, const AW::Rectangle ¤t_part, int percent)
virtual void clear(AW_bitset filteri)
void push_transaction() const
static void motion_event(AW_window *aww, AWT_canvas *scr)
void set_resize_callback(AW_area area, const WindowCallback &wcb)
const AW_bitset AW_SCREEN
void request_zoom_reset()
void set_horizontal_scrollbar_position(AW_window *aww, int pos)
AW_device * get_device(AW_area area)
const AW_screen_area & get_area_size() const
Position centroid() const
void set_left_clip_border(int left, bool allow_oversize=false)
void shift(const AW::Vector &doff)
const int ZOOM_SPEED_WHEEL
virtual void clear_part(const AW::Rectangle &rect, AW_bitset filteri)
char * ARB_strdup(const char *str)
void set_top_clip_border(int top, bool allow_oversize=false)
void sync_DB_model_and_view(bool perform_refresh)
void announce_screen_update()
void instant_zoom_reset()
int slider_pos_horizontal
current position of the vertical slider
AWT_canvas(GBDATA *gb_main_, AW_window *aww_, const char *gc_base_name_, AWT_graphic *gfx_)
void nt_draw_zoom_box(AW_device *device, int gc, AW_pos x1, AW_pos y1, AW_pos x2, AW_pos y2)
GB_ERROR GB_push_transaction(GBDATA *gbd)
void set_motion_callback(AW_area area, const WindowCallback &wcb)
struct Unfixed_cb_parameter * UNFIXED
void AWT_GC_changed_cb(GcChange whatChanged, AWT_canvas *scr)
int AW_get_drag_gc(AW_gc_manager *gcman)
void drag_target_detection(bool detect)
#define assert_no_auto_refresh_for(CANVAS)
void get_event(AW_event *eventi) const
GB_ERROR save_to_DB(GBDATA *gb_main, const char *name) OVERRIDE __ATTR__USERESULT
const int ZOOM_SPEED_CLICK
void set_bottom_clip_border(int bottom, bool allow_oversize=false)
AW_device_click * get_click_device(AW_area area, int mousex, int mousey, int max_distance)
void set_dragEndpoint(int x, int y)
void set_expose_callback(AW_area area, const WindowCallback &wcb)
AW::Vector rtransform(const AW::Vector &vec) const
static void error(const char *msg)
const AW_bitset AW_CLICK_DROP
void set_vertical_scrollbar_position(AW_window *aww, int pos)
GB_write_int const char GB_write_autoconv_string WRITE_SKELETON(write_pointer, GBDATA *,"%p", GB_write_pointer) char *AW_awa if)(!gb_var) return strdup("")
static void clip_expose(AW_window *aww, AWT_canvas *scr, int left_border, int right_border, int top_border, int bottom_border, int hor_overlap, int ver_overlap)
void AWT_expose_cb(UNFIXED, AWT_canvas *scr)
void check_for_DB_update(GBDATA *gb_main) OVERRIDE
GB_ERROR GB_pop_transaction(GBDATA *gbd)
GB_ERROR load_from_DB(GBDATA *gb_main, const char *name) OVERRIDE __ATTR__USERESULT
AW_borders get_unscaleable_overlap() const
const Vector & diagonal() const
const Vector & line_vector() const
virtual void handle_command(AW_device *device, AWT_graphic_event &event)=0
void set_right_clip_border(int right, bool allow_oversize=false)
void TRACE_UPDATE(const char *)
bool wants_drag_target() const
const double & length() const
static void canvas_resize_cb(UNFIXED, AWT_canvas *scr)
void scroll(int delta_x, int delta_y, bool dont_update_scrollbars=false)
static void scroll_hor_cb(AW_window *aww, AWT_canvas *scr)
static void canvas_focus_cb(AW_window *, AWT_canvas *scr)
void set_focus_callback(const WindowCallback &wcb)
static void input_event(AW_window *aww, AWT_canvas *scr)
void get_size_information(AW_world *ptr) const __ATTR__DEPRECATED_TODO("whole AW_world is deprecated")
AW_gc_manager * gc_manager
bool handleWheelEvent(AW_device *device, const AW_event &event)
static void scroll_vert_cb(AW_window *aww, AWT_canvas *scr)
AWT_graphic_exports exports
void init_device(AW_device *device)
const AW_bitset AW_SIZE_UNSCALED
void aw_message(const char *msg)
void set_filter(AW_bitset filteri)
virtual void move_region(AW_pos src_x, AW_pos src_y, AW_pos width, AW_pos height, AW_pos dest_x, AW_pos dest_y)
void pop_transaction() const
void instant_resize(bool adjust_scrollbars)
GB_transaction ta(gb_var)
void set_horizontal_change_callback(const WindowCallback &wcb)
bool box(int gc, AW::FillStyle filled, const AW::Rectangle &rect, AW_bitset filteri=AW_ALL_DEVICES_SCALED)
void set_vertical_change_callback(const WindowCallback &wcb)
static bool handleZoomEvent(AWT_canvas *scr, AW_device *device, const AW_event &event, int percent)
int slider_pos_vertical
window id
void set_input_callback(AW_area area, const WindowCallback &wcb)
void notify_synchronized(GBDATA *gb_main) OVERRIDE
virtual void show(AW_device *device)=0