editor: allow reordering tracks by dragging mouse

Previously the only way of reordering tracks were with an
obscure keyboard short-cut. Most users would expect to be
able to do this with the mouse, so we'll allow that.
This commit is contained in:
Erik Faye-Lund 2010-04-20 23:00:25 +02:00
parent b5edcbe55d
commit 31ec5064b2
2 changed files with 96 additions and 4 deletions

View File

@ -63,7 +63,9 @@ TrackView::TrackView()
rampPen = CreatePen(PS_SOLID, 2, RGB(0, 0, 255));
editBrush = CreateSolidBrush(RGB(255, 255, 0)); // yellow
handCursor = LoadCursor(NULL, IDC_HAND);
clipboardFormat = RegisterClipboardFormat("syncdata");
assert(0 != clipboardFormat);
}
@ -111,6 +113,19 @@ int TrackView::getScreenX(size_t track) const
return int(leftMarginWidth + (track * trackWidth)) - scrollPosX;
}
inline int divfloor(int a, int b)
{
if (a < 0)
return -abs(a) / b - 1;
return a / b;
}
int TrackView::getTrackFromX(int x) const
{
return divfloor(x + scrollPosX - leftMarginWidth, trackWidth);
}
LRESULT TrackView::onCreate()
{
// setFont((HFONT)GetStockObject(SYSTEM_FONT));
@ -1098,6 +1113,67 @@ LRESULT TrackView::onSize(int width, int height)
return FALSE;
}
LRESULT TrackView::onSetCursor(HWND win, UINT hitTest, UINT message)
{
POINT cpos;
GetCursorPos(&cpos);
ScreenToClient(hwnd, &cpos);
int track = getTrackFromX(cpos.x);
if (cpos.y < topMarginHeight &&
track >= 0 && track < int(getTrackCount())) {
SetCursor(handCursor);
return TRUE;
}
return DefWindowProc(this->hwnd, WM_SETCURSOR, (WPARAM)hwnd,
MAKELPARAM(hitTest, message));
}
LRESULT TrackView::onLButtonDown(UINT flags, POINTS pos)
{
int track = getTrackFromX(pos.x);
if (pos.y < topMarginHeight &&
track >= 0 && track < int(getTrackCount())) {
setEditTrack(track, false);
SetCapture(hwnd);
anchorTrack = track;
}
return FALSE;
}
LRESULT TrackView::onLButtonUp(UINT flags, POINTS pos)
{
ReleaseCapture();
setEditTrack(editTrack);
return FALSE;
}
LRESULT TrackView::onMouseMove(UINT flags, POINTS pos)
{
if (GetCapture() == hwnd) {
SyncDocument *doc = getDocument();
const int posTrack = getTrackFromX(pos.x),
trackCount = getTrackCount();
if (!doc || posTrack < 0 || posTrack >= trackCount)
return FALSE;
if (posTrack > anchorTrack) {
for (int i = anchorTrack; i < posTrack; ++i)
doc->swapTrackOrder(i, i + 1);
anchorTrack = posTrack;
setEditTrack(posTrack);
InvalidateRect(hwnd, NULL, FALSE);
} else if (posTrack < anchorTrack) {
for (int i = anchorTrack; i > posTrack; --i)
doc->swapTrackOrder(i, i - 1);
anchorTrack = posTrack;
setEditTrack(posTrack);
InvalidateRect(hwnd, NULL, FALSE);
}
}
return FALSE;
}
LRESULT TrackView::windowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
assert(hwnd == this->hwnd);
@ -1111,7 +1187,16 @@ LRESULT TrackView::windowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_PAINT: return onPaint();
case WM_KEYDOWN: return onKeyDown((UINT)wParam, (UINT)lParam);
case WM_CHAR: return onChar((UINT)wParam, (UINT)lParam);
case WM_LBUTTONDOWN:
return onLButtonDown((UINT)wParam, MAKEPOINTS(lParam));
case WM_LBUTTONUP:
return onLButtonUp((UINT)wParam, MAKEPOINTS(lParam));
case WM_MOUSEMOVE:
return onMouseMove((UINT)wParam, MAKEPOINTS(lParam));
case WM_SETCURSOR:
return onSetCursor((HWND)wParam, LOWORD(lParam),
HIWORD(lParam));
case WM_COPY: editCopy(); break;
case WM_CUT: editCut(); break;
case WM_PASTE:

View File

@ -102,7 +102,11 @@ private:
LRESULT onSize(int width, int height);
LRESULT onKeyDown(UINT keyCode, UINT flags);
LRESULT onChar(UINT keyCode, UINT flags);
LRESULT onSetCursor(HWND win, UINT hitTest, UINT message);
LRESULT onLButtonDown(UINT flags, POINTS pos);
LRESULT onLButtonUp(UINT flags, POINTS pos);
LRESULT onMouseMove(UINT flags, POINTS pos);
void paintTracks(HDC hdc, RECT rcTracks);
void paintTopMargin(HDC hdc, RECT rcTracks);
@ -160,7 +164,8 @@ private:
int getScreenY(int row) const;
int getScreenX(size_t track) const;
int getTrackFromX(int x) const;
size_t getTrackCount() const
{
const SyncDocument *doc = getDocument();
@ -184,6 +189,7 @@ private:
HPEN rowPen, rowSelectPen;
HBRUSH editBrush;
HPEN lerpPen, cosinePen, rampPen;
HCURSOR handCursor;
/* cursor position */
int editRow, editTrack;
@ -199,6 +205,7 @@ private:
HWND hwnd;
UINT clipboardFormat;
int anchorTrack;
};
ATOM registerTrackViewWindowClass(HINSTANCE hInstance);