edit with undo!
This commit is contained in:
parent
bb3aeab4f9
commit
8f9877f79b
21
syncdata.h
21
syncdata.h
@ -51,11 +51,22 @@ public:
|
||||
return &iter->second;
|
||||
}
|
||||
|
||||
void deleteKeyFrame(int row)
|
||||
{
|
||||
keyFrames.erase(row);
|
||||
}
|
||||
|
||||
void setKeyFrame(int row, const KeyFrame &keyFrame)
|
||||
{
|
||||
keyFrames[row] = keyFrame;
|
||||
}
|
||||
|
||||
void setKeyFrame(int row, const float value)
|
||||
{
|
||||
keyFrames[row] = KeyFrame(value);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
typedef std::map<int, struct KeyFrame> KeyFrameContainer;
|
||||
KeyFrameContainer keyFrames;
|
||||
@ -71,6 +82,16 @@ public:
|
||||
return tracks[name] = SyncTrack();
|
||||
}
|
||||
|
||||
SyncTrack &getTrack(size_t track)
|
||||
{
|
||||
assert(track >= 0);
|
||||
assert(track < tracks.size());
|
||||
|
||||
SyncData::TrackContainer::iterator trackIter = tracks.begin();
|
||||
for (size_t currTrack = 0; currTrack < track; ++currTrack, ++trackIter);
|
||||
return trackIter->second;
|
||||
}
|
||||
|
||||
size_t getTrackCount() { return tracks.size(); }
|
||||
|
||||
// private:
|
||||
|
||||
148
synctracker2.cpp
148
synctracker2.cpp
@ -3,6 +3,7 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "trackview.h"
|
||||
|
||||
@ -10,27 +11,86 @@ const TCHAR *mainWindowClassName = _T("MainWindow");
|
||||
|
||||
TrackView *trackView;
|
||||
HWND trackViewWin;
|
||||
HWND statusBarWin;
|
||||
|
||||
static LRESULT CALLBACK mainWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
{
|
||||
trackViewWin = trackView->create(GetModuleHandle(NULL), hwnd);
|
||||
|
||||
InitCommonControls();
|
||||
statusBarWin = CreateWindowEx(
|
||||
0, // no extended styles
|
||||
STATUSCLASSNAME, // status bar
|
||||
(LPCTSTR)"mordi", // no text
|
||||
SBARS_SIZEGRIP | WS_VISIBLE | WS_CHILD, // styles
|
||||
0, 0, 0, 0, // x, y, cx, cy
|
||||
hwnd, // parent window
|
||||
(HMENU)100, // window ID
|
||||
GetModuleHandle(NULL), // instance
|
||||
NULL // window data
|
||||
);
|
||||
|
||||
int statwidths[] = {100, -1};
|
||||
SendMessage(statusBarWin, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);
|
||||
SendMessage(statusBarWin, SB_SETTEXT, 0, (LPARAM)"Hi there :)");
|
||||
|
||||
HMENU fileMenu = CreatePopupMenu();
|
||||
AppendMenu(fileMenu, MF_STRING, 0, "&Open\tCtrl+O");
|
||||
AppendMenu(fileMenu, MF_STRING, 2, "&Save\tCtrl+S");
|
||||
AppendMenu(fileMenu, MF_STRING, 3, "Save &As");
|
||||
AppendMenu(fileMenu, MF_SEPARATOR, 0, NULL);
|
||||
AppendMenu(fileMenu, MF_STRING, 3, "&Exit");
|
||||
|
||||
HMENU editMenu = CreatePopupMenu();
|
||||
AppendMenu(editMenu, MF_STRING, WM_USER+0, "&Undo\tCtrl+Z");
|
||||
AppendMenu(editMenu, MF_STRING, WM_USER+1, "&Redo\tShift+Ctrl+Z");
|
||||
AppendMenu(editMenu, MF_SEPARATOR, 0, NULL);
|
||||
AppendMenu(editMenu, MF_STRING, WM_CUT, "Cu&t\tCtrl+X");
|
||||
AppendMenu(editMenu, MF_STRING, WM_COPY, "&Copy\tCtrl+C");
|
||||
AppendMenu(editMenu, MF_STRING, WM_PASTE, "&Paste\tCtrl+V");
|
||||
|
||||
HMENU rootMenu = CreateMenu();
|
||||
AppendMenu(rootMenu, MF_STRING | MF_POPUP, (UINT_PTR)fileMenu, "&File");
|
||||
AppendMenu(rootMenu, MF_STRING | MF_POPUP, (UINT_PTR)editMenu, "&Edit");
|
||||
SetMenu(hwnd, rootMenu);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
{
|
||||
int width = LOWORD(lParam);
|
||||
int height = HIWORD(lParam);
|
||||
MoveWindow(trackViewWin, 0, 0, width, height, TRUE);
|
||||
|
||||
RECT statusBarRect;
|
||||
GetClientRect(statusBarWin, &statusBarRect);
|
||||
int statusBarHeight = statusBarRect.bottom - statusBarRect.top;
|
||||
|
||||
MoveWindow(trackViewWin, 0, 0, width, height - statusBarHeight, TRUE);
|
||||
MoveWindow(statusBarWin, 0, height - statusBarHeight, width, statusBarHeight, TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
SetFocus(trackViewWin); // needed to forward keyboard input
|
||||
break;
|
||||
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (wParam)
|
||||
{
|
||||
case WM_COPY:
|
||||
/* PostMessage(m_hWnd, WM_COPY, 0, 0); */
|
||||
/* HMMMM.... not working... */
|
||||
printf("copy!\n");
|
||||
break;
|
||||
default:
|
||||
printf("cmd %d %d\n", wParam, lParam);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
@ -57,12 +117,84 @@ static ATOM registerMainWindowClass(HINSTANCE hInstance)
|
||||
return RegisterClassEx(&wc);
|
||||
}
|
||||
|
||||
|
||||
#include <winsock2.h>
|
||||
|
||||
int _tmain(int argc, _TCHAR* argv[])
|
||||
{
|
||||
HWND hwnd;
|
||||
MSG Msg;
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
|
||||
#if 0
|
||||
WSADATA wsaData;
|
||||
int error = WSAStartup( MAKEWORD( 2, 0 ), &wsaData );
|
||||
if (0 != error)
|
||||
{
|
||||
fputs("Failed to init WinSock", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 0)
|
||||
{
|
||||
fputs("Wrong version of WinSock", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SOCKET server = socket( AF_INET, SOCK_STREAM, 0 );
|
||||
|
||||
struct sockaddr_in sin;
|
||||
memset( &sin, 0, sizeof sin );
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = INADDR_ANY;
|
||||
sin.sin_port = htons( 21 );
|
||||
|
||||
if (SOCKET_ERROR == bind( server, (struct sockaddr *)&sin, sizeof(sin)))
|
||||
{
|
||||
fputs("Coult not start server", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while ( listen( server, SOMAXCONN ) == SOCKET_ERROR );
|
||||
|
||||
int length = sizeof(sin);
|
||||
SOCKET client = accept( server, (sockaddr *)&sin, &length );
|
||||
|
||||
const char *test = "TEST123";
|
||||
int sent = send( client, test, strlen(test), 0);
|
||||
if (SOCKET_ERROR == sent)
|
||||
{
|
||||
int err = WSAGetLastError();
|
||||
fprintf(stderr, "failed to send - err %d\n", err);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
unsigned long int nonBlock = 1;
|
||||
if (ioctlsocket(client, FIONBIO, &nonBlock) == SOCKET_ERROR)
|
||||
{
|
||||
printf("ioctlsocket() failed \n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int read = 0;
|
||||
while (read < 20)
|
||||
{
|
||||
char buffer[1024];
|
||||
int len = recv(client, buffer, 1024, 0);
|
||||
if (0 < len)
|
||||
{
|
||||
printf("got \"%s\" - left: %d\n", buffer, 20 - (read + len));
|
||||
read += len;
|
||||
}
|
||||
}
|
||||
|
||||
closesocket(client);
|
||||
closesocket(server);
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
SyncData syncData;
|
||||
SyncTrack &camXTrack = syncData.getTrack("cam.x");
|
||||
SyncTrack &camYTrack = syncData.getTrack("cam.y");
|
||||
@ -118,13 +250,23 @@ int _tmain(int argc, _TCHAR* argv[])
|
||||
|
||||
ShowWindow(hwnd, TRUE);
|
||||
UpdateWindow(hwnd);
|
||||
|
||||
|
||||
#if 0
|
||||
/* while (1)
|
||||
{
|
||||
SOCKET client;
|
||||
int length;
|
||||
length = sizeof sin;
|
||||
client = accept( server, (sockaddr *)&sin, &length );
|
||||
} */
|
||||
#else
|
||||
// Step 3: The Message Loop
|
||||
while(GetMessage(&Msg, NULL, 0, 0) > 0)
|
||||
{
|
||||
TranslateMessage(&Msg);
|
||||
DispatchMessage(&Msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
delete trackView;
|
||||
trackView = NULL;
|
||||
|
||||
@ -60,6 +60,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib comctl32.lib "
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
@ -134,6 +135,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib comctl32.lib "
|
||||
LinkIncremental="1"
|
||||
GenerateManifest="false"
|
||||
GenerateDebugInformation="true"
|
||||
|
||||
230
trackview.cpp
230
trackview.cpp
@ -11,10 +11,9 @@ static const int fontHeight = 16;
|
||||
static const int fontWidth = 6;
|
||||
|
||||
static const int trackWidth = fontWidth * 16;
|
||||
|
||||
static const int rows = 0x80;
|
||||
|
||||
TrackView::TrackView() : syncData(NULL)
|
||||
TrackView::TrackView()
|
||||
{
|
||||
scrollPosX = 0;
|
||||
scrollPosY = 0;
|
||||
@ -44,12 +43,13 @@ int TrackView::getScreenX(int track)
|
||||
return leftMarginWidth + (track * trackWidth) - scrollPosX;
|
||||
}
|
||||
|
||||
void TrackView::onCreate()
|
||||
LRESULT TrackView::onCreate()
|
||||
{
|
||||
setupScrollBars();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void TrackView::onPaint()
|
||||
LRESULT TrackView::onPaint()
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc = BeginPaint(hwnd, &ps);
|
||||
@ -59,6 +59,8 @@ void TrackView::onPaint()
|
||||
paintTracks(hdc, ps.rcPaint);
|
||||
|
||||
EndPaint(hwnd, &ps);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void TrackView::paintTopMargin(HDC hdc, RECT rcTracks)
|
||||
@ -202,17 +204,21 @@ void TrackView::paintTracks(HDC hdc, RECT rcTracks)
|
||||
RECT fillRect = patternDataRect;
|
||||
// if (row == editRow && track == editTrack) DrawEdge(hdc, &fillRect, BDR_RAISEDINNER | BDR_SUNKENOUTER, BF_ADJUST | BF_TOP | BF_BOTTOM | BF_LEFT | BF_RIGHT);
|
||||
FillRect( hdc, &fillRect, bgBrush);
|
||||
|
||||
bool drawEditString = false;
|
||||
if (row == editRow && track == editTrack)
|
||||
{
|
||||
// DrawFocusRect(hdc, &fillRect);
|
||||
Rectangle(hdc, fillRect.left, fillRect.top, fillRect.right, fillRect.bottom);
|
||||
if (editString.size() > 0) drawEditString = true;
|
||||
}
|
||||
|
||||
const SyncTrack &track = trackIter->second;
|
||||
bool key = track.isKeyFrame(row);
|
||||
|
||||
/* format the text */
|
||||
if (!key) _sntprintf_s(temp, 256, _T("---"));
|
||||
if (drawEditString) _sntprintf_s(temp, 256, editString.c_str());
|
||||
else if (!key) _sntprintf_s(temp, 256, _T("---"));
|
||||
else
|
||||
{
|
||||
float val = track.getKeyFrame(row)->value;
|
||||
@ -347,21 +353,6 @@ void TrackView::setEditTrack(int newEditTrack)
|
||||
editTrack = max(editTrack, 0);
|
||||
editTrack = min(editTrack, getTrackCount() - 1);
|
||||
|
||||
// sync up iterators
|
||||
/* int currEditTrack = oldEditTrack;
|
||||
while (editTrack != currEditTrack)
|
||||
{
|
||||
if (currEditTrack < editTrack)
|
||||
{
|
||||
currEditTrack++;
|
||||
}
|
||||
else
|
||||
{
|
||||
currEditTrack--;
|
||||
}
|
||||
} */
|
||||
|
||||
|
||||
RECT trackRect;
|
||||
|
||||
// dirty old and new marker
|
||||
@ -406,7 +397,7 @@ static int getScrollPos(HWND hwnd, int bar)
|
||||
return int(si.nTrackPos);
|
||||
}
|
||||
|
||||
void TrackView::onVScroll(UINT sbCode, int newPos)
|
||||
LRESULT TrackView::onVScroll(UINT sbCode, int newPos)
|
||||
{
|
||||
switch (sbCode)
|
||||
{
|
||||
@ -435,9 +426,11 @@ void TrackView::onVScroll(UINT sbCode, int newPos)
|
||||
setEditRow(getScrollPos(hwnd, SB_VERT));
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void TrackView::onHScroll(UINT sbCode, int newPos)
|
||||
LRESULT TrackView::onHScroll(UINT sbCode, int newPos)
|
||||
{
|
||||
switch (sbCode)
|
||||
{
|
||||
@ -470,57 +463,73 @@ void TrackView::onHScroll(UINT sbCode, int newPos)
|
||||
setEditTrack(getScrollPos(hwnd, SB_HORZ));
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void TrackView::onKeyDown(UINT keyCode, UINT flags)
|
||||
LRESULT TrackView::onKeyDown(UINT keyCode, UINT flags)
|
||||
{
|
||||
bool refreshCaret = false;
|
||||
bool ctrlDown = GetKeyState(VK_CONTROL) < 0 ? true : false;
|
||||
bool shiftDown = GetKeyState(VK_SHIFT) < 0 ? true : false;
|
||||
bool altDown = GetKeyState(VK_MENU) < 0 ? true : false;
|
||||
|
||||
if (editString.empty())
|
||||
{
|
||||
switch (keyCode)
|
||||
{
|
||||
case VK_UP: setEditRow(editRow - 1); break;
|
||||
case VK_DOWN: setEditRow(editRow + 1); break;
|
||||
|
||||
case VK_LEFT: setEditTrack(editTrack - 1); break;
|
||||
case VK_RIGHT: setEditTrack(editTrack + 1); break;
|
||||
|
||||
case VK_PRIOR: setEditRow(editRow - windowRows / 2); break;
|
||||
case VK_NEXT: setEditRow(editRow + windowRows / 2); break;
|
||||
|
||||
case 'U':
|
||||
if (true == ctrlDown && true == shiftDown)
|
||||
{
|
||||
if (!syncDataEdit.redo()) MessageBeep(0);
|
||||
}
|
||||
else if (true == ctrlDown)
|
||||
{
|
||||
if (!syncDataEdit.undo()) MessageBeep(0);
|
||||
}
|
||||
InvalidateRect(hwnd, NULL, TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (keyCode)
|
||||
{
|
||||
case VK_UP: setEditRow(editRow - 1); break;
|
||||
case VK_DOWN: setEditRow(editRow + 1); break;
|
||||
|
||||
case VK_LEFT: setEditTrack(editTrack - 1); break;
|
||||
case VK_RIGHT: setEditTrack(editTrack + 1); break;
|
||||
|
||||
case VK_PRIOR: setEditRow(editRow - windowRows / 2); break;
|
||||
case VK_NEXT: setEditRow(editRow + windowRows / 2); break;
|
||||
}
|
||||
}
|
||||
|
||||
void TrackView::onChar(UINT keyCode, UINT flags)
|
||||
{
|
||||
bool refresh = false;
|
||||
printf("char: \"%c\" (%d) - flags: %x\n", (char)keyCode, keyCode, flags);
|
||||
switch ((char)keyCode)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '.':
|
||||
editString.push_back(keyCode);
|
||||
printf("accepted: %c - %s\n", (char)keyCode, editString.c_str());
|
||||
refresh = true;
|
||||
case VK_RETURN:
|
||||
{
|
||||
SyncDataEdit::EditCommand *cmd = new SyncDataEdit::EditCommand(
|
||||
editTrack, editRow,
|
||||
float(atof(editString.c_str()))
|
||||
);
|
||||
|
||||
syncDataEdit.exec(cmd);
|
||||
|
||||
editString.clear();
|
||||
refreshCaret = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case VK_RETURN:
|
||||
printf("submit: %f\n", atof(editString.c_str()));
|
||||
// TODO: submit new number
|
||||
editString.clear();
|
||||
refresh = true;
|
||||
case VK_DELETE:
|
||||
{
|
||||
SyncTrack &track = getSyncData()->getTrack(editTrack);
|
||||
track.deleteKeyFrame(editRow);
|
||||
refreshCaret = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case VK_BACK:
|
||||
if (editString.size() > 0)
|
||||
{
|
||||
editString.resize(editString.size() - 1);
|
||||
refresh = true;
|
||||
refreshCaret = true;
|
||||
}
|
||||
else MessageBeep(0);
|
||||
break;
|
||||
@ -532,28 +541,67 @@ void TrackView::onChar(UINT keyCode, UINT flags)
|
||||
// return to old value (i.e don't clear)
|
||||
editString.clear();
|
||||
|
||||
refresh = true;
|
||||
refreshCaret = true;
|
||||
MessageBeep(0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
MessageBeep(0);
|
||||
}
|
||||
|
||||
if (refresh)
|
||||
if (refreshCaret)
|
||||
{
|
||||
/* RECT rowRect;
|
||||
NB: getScreenX(int track)
|
||||
rowRect.left = clientRect.left;
|
||||
rowRect.right = clientRect.right;
|
||||
rowRect.top = getScreenY(oldEditRow);
|
||||
rowRect.bottom = rowRect.top + fontHeight;
|
||||
InvalidateRect(hwnd, &rowRect, TRUE); */
|
||||
RECT rowRect;
|
||||
rowRect.left = getScreenX(editTrack);
|
||||
rowRect.right = getScreenX(editTrack + 1);
|
||||
rowRect.top = getScreenY(editRow);
|
||||
rowRect.bottom = getScreenY(editRow + 1);
|
||||
InvalidateRect(hwnd, &rowRect, TRUE);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void TrackView::onSize(int width, int height)
|
||||
LRESULT TrackView::onChar(UINT keyCode, UINT flags)
|
||||
{
|
||||
bool refreshCaret = false;
|
||||
printf("char: \"%c\" (%d) - flags: %x\n", (char)keyCode, keyCode, flags);
|
||||
switch ((char)keyCode)
|
||||
{
|
||||
case '.':
|
||||
// only one '.' allowed
|
||||
if (std::string::npos != editString.find('.'))
|
||||
{
|
||||
MessageBeep(0);
|
||||
break;
|
||||
}
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
editString.push_back(keyCode);
|
||||
printf("accepted: %c - %s\n", (char)keyCode, editString.c_str());
|
||||
refreshCaret = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (refreshCaret)
|
||||
{
|
||||
RECT rowRect;
|
||||
rowRect.left = getScreenX(editTrack);
|
||||
rowRect.right = getScreenX(editTrack + 1);
|
||||
rowRect.top = getScreenY(editRow);
|
||||
rowRect.bottom = getScreenY(editRow + 1);
|
||||
InvalidateRect(hwnd, &rowRect, TRUE);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LRESULT TrackView::onSize(int width, int height)
|
||||
{
|
||||
const int oldWindowWidth = windowWidth;
|
||||
const int oldWindowHeight = windowHeight;
|
||||
@ -566,6 +614,7 @@ void TrackView::onSize(int width, int height)
|
||||
|
||||
setEditRow(editRow);
|
||||
setupScrollBars();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LRESULT TrackView::windowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
@ -574,9 +623,7 @@ LRESULT TrackView::windowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
onCreate();
|
||||
break;
|
||||
case WM_CREATE: return onCreate();
|
||||
|
||||
case WM_CLOSE:
|
||||
DestroyWindow(hwnd);
|
||||
@ -586,28 +633,15 @@ LRESULT TrackView::windowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
onSize(LOWORD(lParam), HIWORD(lParam));
|
||||
break;
|
||||
|
||||
case WM_VSCROLL:
|
||||
onVScroll(LOWORD(wParam), getScrollPos(hwnd, SB_VERT));
|
||||
break;
|
||||
|
||||
case WM_HSCROLL:
|
||||
onHScroll(LOWORD(wParam), getScrollPos(hwnd, SB_HORZ));
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
onPaint();
|
||||
break;
|
||||
|
||||
case WM_KEYDOWN:
|
||||
onKeyDown((UINT)wParam, (UINT)lParam);
|
||||
break;
|
||||
|
||||
case WM_CHAR:
|
||||
onChar((UINT)wParam, (UINT)lParam);
|
||||
case WM_SIZE: return onSize(LOWORD(lParam), HIWORD(lParam));
|
||||
case WM_VSCROLL: return onVScroll(LOWORD(wParam), getScrollPos(hwnd, SB_VERT));
|
||||
case WM_HSCROLL: return onHScroll(LOWORD(wParam), getScrollPos(hwnd, SB_HORZ));
|
||||
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_COPY:
|
||||
printf("copy!\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
145
trackview.h
145
trackview.h
@ -2,47 +2,152 @@
|
||||
|
||||
#include "syncdata.h"
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <stack>
|
||||
|
||||
class SyncData;
|
||||
|
||||
class SyncDataEdit
|
||||
{
|
||||
public:
|
||||
SyncDataEdit() : syncData(NULL) {}
|
||||
|
||||
void setSyncData(SyncData *syncData) { this->syncData = syncData; }
|
||||
SyncData *getSyncData() { return syncData; }
|
||||
|
||||
class Command
|
||||
{
|
||||
public:
|
||||
virtual ~Command() {}
|
||||
virtual void exec(SyncDataEdit *data) = 0;
|
||||
virtual void undo(SyncDataEdit *data) = 0;
|
||||
};
|
||||
|
||||
class EditCommand : public Command
|
||||
{
|
||||
public:
|
||||
EditCommand(int track, int row, float value) : track(track), row(row), newVal(value) {}
|
||||
~EditCommand() {}
|
||||
|
||||
virtual void exec(SyncDataEdit *data)
|
||||
{
|
||||
SyncTrack &track = data->getSyncData()->getTrack(this->track);
|
||||
oldValExisting = track.isKeyFrame(row);
|
||||
if (oldValExisting) oldVal = track.getKeyFrame(row)->value;
|
||||
track.setKeyFrame(row, newVal);
|
||||
}
|
||||
|
||||
virtual void undo(SyncDataEdit *data)
|
||||
{
|
||||
SyncTrack &track = data->getSyncData()->getTrack(this->track);
|
||||
if (!oldValExisting) track.deleteKeyFrame(row);
|
||||
else track.setKeyFrame(row, oldVal);
|
||||
}
|
||||
|
||||
private:
|
||||
int track, row;
|
||||
float newVal, oldVal;
|
||||
bool oldValExisting;
|
||||
};
|
||||
|
||||
void exec(Command *cmd)
|
||||
{
|
||||
undoStack.push(cmd);
|
||||
cmd->exec(this);
|
||||
clearRedoStack();
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
if (undoStack.size() == 0) return false;
|
||||
|
||||
Command *cmd = undoStack.top();
|
||||
undoStack.pop();
|
||||
|
||||
redoStack.push(cmd);
|
||||
cmd->undo(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool redo()
|
||||
{
|
||||
if (redoStack.size() == 0) return false;
|
||||
|
||||
Command *cmd = redoStack.top();
|
||||
redoStack.pop();
|
||||
|
||||
undoStack.push(cmd);
|
||||
cmd->exec(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void clearRedoStack()
|
||||
{
|
||||
while (!redoStack.empty())
|
||||
{
|
||||
Command *cmd = redoStack.top();
|
||||
redoStack.pop();
|
||||
delete cmd;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::stack<Command*> undoStack;
|
||||
std::stack<Command*> redoStack;
|
||||
|
||||
SyncData *syncData;
|
||||
};
|
||||
|
||||
class TrackView
|
||||
{
|
||||
public:
|
||||
TrackView();
|
||||
~TrackView();
|
||||
|
||||
|
||||
HWND create(HINSTANCE hInstance, HWND hwndParent);
|
||||
HWND getWin(){ return hwnd; }
|
||||
|
||||
void setSyncData(SyncData *syncData) { this->syncData = syncData; }
|
||||
SyncData *getSyncData() { return syncData; }
|
||||
|
||||
|
||||
void setSyncData(SyncData *syncData) { this->syncDataEdit.setSyncData(syncData); }
|
||||
SyncData *getSyncData() { return syncDataEdit.getSyncData(); }
|
||||
|
||||
private:
|
||||
// some nasty hackery to forward the window messages
|
||||
friend static LRESULT CALLBACK trackViewWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT windowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
// events
|
||||
void onCreate();
|
||||
void onPaint();
|
||||
void onVScroll(UINT sbCode, int newPos);
|
||||
void onHScroll(UINT sbCode, int newPos);
|
||||
void onSize(int width, int height);
|
||||
void onKeyDown(UINT keyCode, UINT flags);
|
||||
void onChar(UINT keyCode, UINT flags);
|
||||
LRESULT onCreate();
|
||||
LRESULT onPaint();
|
||||
LRESULT onVScroll(UINT sbCode, int newPos);
|
||||
LRESULT onHScroll(UINT sbCode, int newPos);
|
||||
LRESULT onSize(int width, int height);
|
||||
LRESULT onKeyDown(UINT keyCode, UINT flags);
|
||||
LRESULT onChar(UINT keyCode, UINT flags);
|
||||
|
||||
// the window procedure
|
||||
|
||||
|
||||
void paintTracks(HDC hdc, RECT rcTracks);
|
||||
void paintTopMargin(HDC hdc, RECT rcTracks);
|
||||
|
||||
void setupScrollBars();
|
||||
void setScrollPos(int newScrollPosX, int newScrollPosY);
|
||||
void scrollWindow(int newScrollPosX, int newScrollPosY);
|
||||
|
||||
|
||||
void invalidatePos(int track, int row)
|
||||
{
|
||||
RECT rect;
|
||||
rect.left = getScreenX(track);
|
||||
rect.right = getScreenX(track + 1);
|
||||
rect.top = getScreenY(row);
|
||||
rect.bottom = getScreenY(row + 1);
|
||||
InvalidateRect(hwnd, &rect, TRUE);
|
||||
}
|
||||
|
||||
void setEditRow(int newEditRow);
|
||||
void setEditTrack(int newEditTrack);
|
||||
|
||||
|
||||
int getScreenY(int row);
|
||||
int getScreenX(int track);
|
||||
|
||||
@ -52,16 +157,16 @@ private:
|
||||
if (NULL == syncData) return 0;
|
||||
return int(syncData->getTrackCount());
|
||||
};
|
||||
|
||||
|
||||
/* cursor position */
|
||||
int editRow, editTrack;
|
||||
|
||||
|
||||
int scrollPosX, scrollPosY;
|
||||
int windowWidth, windowHeight;
|
||||
int windowRows, windowTracks;
|
||||
|
||||
SyncData *syncData;
|
||||
|
||||
SyncDataEdit syncDataEdit;
|
||||
|
||||
std::string editString;
|
||||
|
||||
HWND hwnd;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user