From 217292388ddd214f241e467993d92273feca437d Mon Sep 17 00:00:00 2001 From: rylek Date: Mon, 15 Nov 2010 12:01:03 +0000 Subject: [PATCH] .Geom/Ctrl: minor extensions in PlotterCtrl to implement UI standards of commercial GIS software (fast mouse panning, zooming in and out) git-svn-id: svn://ultimatepp.org/upp/trunk@2846 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Geom/Ctrl/PlotterCtrl.cpp | 121 +++++++++++++++++++++---------- uppsrc/Geom/Ctrl/PlotterCtrl.h | 3 +- 2 files changed, 83 insertions(+), 41 deletions(-) diff --git a/uppsrc/Geom/Ctrl/PlotterCtrl.cpp b/uppsrc/Geom/Ctrl/PlotterCtrl.cpp index 45d0882d5..f0a4f1d5d 100644 --- a/uppsrc/Geom/Ctrl/PlotterCtrl.cpp +++ b/uppsrc/Geom/Ctrl/PlotterCtrl.cpp @@ -57,6 +57,7 @@ PlotterCtrl::PlotterCtrl() , lock_short_drag_drop(false) , is_painting(false) , background(White()) +, drag_mode(DRAG_NONE) { hscroll .NoAutoHide().NoAutoDisable(); vscroll .NoAutoHide().NoAutoDisable(); @@ -666,19 +667,36 @@ void PlotterCtrl::RefreshBuffer(const Rect& rc) Image PlotterCtrl::CursorImage(Point pt, dword keyflags) { Image out = Image::Arrow(); - if(!custom_drag) { - if(keyflags & K_SHIFT) + int dm = drag_mode; + if(!IsDragging()) { + dm = (drag_drop ? DRAG_CUSTOM + : keyflags & K_SHIFT ? DRAG_ZOOM_IN + : keyflags & K_CTRL ? DRAG_ZOOM_OUT + : DRAG_PAN); + } + + switch(dm) { + case DRAG_CUSTOM: { + lock_drag_drop = true; + out = drag_drop->Cursor(FromClient(pt), keyflags, IsDragging()); + lock_drag_drop = false; + break; + } + case DRAG_ZOOM_IN: { out = PlotterImg::view_zoom_in(); - else if(keyflags & K_CTRL) + break; + } + case DRAG_ZOOM_OUT: { out = PlotterImg::view_zoom_out(); - else if(keyflags & K_MOUSELEFT) - out = PlotterImg::view_pan(); - } - else if(drag_drop) { - lock_drag_drop = true; - out = drag_drop->Cursor(FromClient(pt), keyflags, IsDragging()); - lock_drag_drop = false; + break; + } + case DRAG_PAN: { + if(IsDragging()) + out = PlotterImg::view_pan(); + break; + } } + return out; } @@ -693,7 +711,18 @@ bool PlotterCtrl::Push(Point pt, dword keyflags) bool push = false; SyncPush(); drag_start = FromPushClient(pt); - custom_drag = (drag_drop && drag_drop->Push(drag_start, keyflags)); + if(drag_drop && drag_drop->Push(drag_start, keyflags)) + drag_mode = DRAG_CUSTOM; + else if(keyflags & K_MOUSELEFT) { + if(keyflags & K_SHIFT) + drag_mode = DRAG_ZOOM_IN; + else if(keyflags & K_CTRL) + drag_mode = DRAG_ZOOM_OUT; + else + drag_mode = DRAG_PAN; + } + else + drag_mode = DRAG_NONE; return true; } @@ -703,57 +732,69 @@ void PlotterCtrl::Drag(Point start, Point prev, Point curr, dword keyflags) // LLOG("PlotterCtrl::Drag, short = " << ~short_drag_drop << ", " << (~short_drag_drop // ? typeid(*short_drag_drop).name() : "NULL") << ", long = " << ~drag_drop << ", " // << (~drag_drop ? typeid(*drag_drop).name() : "NULL")); - if(!custom_drag) { - if(keyflags & (K_SHIFT | K_CTRL)) { + switch(drag_mode) { + case DRAG_ZOOM_IN: + case DRAG_ZOOM_OUT: { Rect rc_prev = Null, rc_curr = Null; if(!IsNull(prev)) rc_prev = RectSort(start, prev); if(!IsNull(curr)) rc_curr = RectSort(start, curr); ViewDraw draw(this); DrawDragDropRect(draw, rc_prev, rc_curr, 2); + break; } - else { + case DRAG_PAN: { if(!IsNull(curr)) PanOffset(curr - start); + break; + } + case DRAG_CUSTOM: { + lock_drag_drop = true; +// LLOG("PlotterCtrl::Drag->drag_drop::Drag"); + drag_drop->Drag(drag_start, FromPushClientNull(prev), FromPushClientNull(curr), keyflags); +// LLOG("//PlotterCtrl::Drag->drag_drop::Drag"); + lock_drag_drop = false; + break; } - } - else if(drag_drop) { - lock_drag_drop = true; -// LLOG("PlotterCtrl::Drag->drag_drop::Drag"); - drag_drop->Drag(drag_start, FromPushClientNull(prev), FromPushClientNull(curr), keyflags); -// LLOG("//PlotterCtrl::Drag->drag_drop::Drag"); - lock_drag_drop = false; } // LLOG("//PlotterCtrl::Drag"); } void PlotterCtrl::Drop(Point start, Point end, dword keyflags) { - if(!custom_drag) { + if(drag_mode == DRAG_CUSTOM) { + if(drag_drop) + drag_drop->Drop(drag_start, FromPushClient(end), keyflags); + } + else { Rect rc = RectSort(start, end); Rectf log = FromClient(rc); Pointf log_center = log.CenterPoint(); Rectf view = GetViewRect(); double ratio = max(1e-10, fpabsmax(log.Size() / view.GetSize())); - if(keyflags & K_SHIFT) { - Sizef new_scale = GetScale() / ratio; - Pointf new_delta = Sizef(GetSize() >> 1) - Sizef(log_center) * new_scale; - SetZoom(new_scale, new_delta); - WhenUserZoom(); - } - else if(keyflags & K_CTRL) { - Point scr_center = ToClient(log_center); - Sizef new_scale = GetScale() * ratio; - Pointf new_delta = Pointf(scr_center) - Sizef(view.CenterPoint()) * new_scale; - SetZoom(new_scale, new_delta); - WhenUserZoom(); - } - else { - SetDelta(push_delta + Sizef(end - start)); - PanOffset(Point(0, 0)); + switch(drag_mode) { + case DRAG_ZOOM_IN: { + Sizef new_scale = GetScale() / ratio; + Pointf new_delta = Sizef(GetSize() >> 1) - Sizef(log_center) * new_scale; + SetZoom(new_scale, new_delta); + WhenUserZoom(); + break; + } + case DRAG_ZOOM_OUT: { + Point scr_center = ToClient(log_center); + Sizef new_scale = GetScale() * ratio; + Pointf new_delta = Pointf(scr_center) - Sizef(view.CenterPoint()) * new_scale; + SetZoom(new_scale, new_delta); + WhenUserZoom(); + break; + } + case DRAG_PAN: { + SetDelta(push_delta + Sizef(end - start)); + PanOffset(Point(0, 0)); + break; + } } } - else if(drag_drop) - drag_drop->Drop(drag_start, FromPushClient(end), keyflags); + drag_mode = DRAG_NONE; } void PlotterCtrl::Click(Point pt, dword keyflags) diff --git a/uppsrc/Geom/Ctrl/PlotterCtrl.h b/uppsrc/Geom/Ctrl/PlotterCtrl.h index b19bf0be6..bdbf38697 100644 --- a/uppsrc/Geom/Ctrl/PlotterCtrl.h +++ b/uppsrc/Geom/Ctrl/PlotterCtrl.h @@ -234,7 +234,8 @@ private: bool show_scroll; bool lock_drag_drop; bool lock_short_drag_drop; - bool custom_drag; + int drag_mode; + enum { DRAG_NONE, DRAG_CUSTOM, DRAG_PAN, DRAG_ZOOM_IN, DRAG_ZOOM_OUT }; }; template