void TrackView::editBiasValue(float amount) { SyncDocument *doc = getDocument(); if (0 == getTrackCount()) { QApplication::beep(); return; } QRect selection = getSelection(); doc->beginMacro("bias"); for (int track = selection.left(); track <= selection.right(); ++track) { Q_ASSERT(track < getTrackCount()); SyncTrack *t = getTrack(track); for (int row = selection.top(); row <= selection.bottom(); ++row) { if (t->isKeyFrame(row)) { SyncTrack::TrackKey k = t->getKeyFrame(row); // copy old key k.value += amount; // modify value // add sub-command doc->setKeyFrame(t, k); } } } doc->endMacro(); dirtyCurrentValue(); }
void TrackView::editToggleInterpolationType() { SyncDocument *doc = getDocument(); if (editTrack < getTrackCount()) { SyncTrack *t = getTrack(editTrack); QMap<int, SyncTrack::TrackKey> keyMap = t->getKeyMap(); QMap<int, SyncTrack::TrackKey>::const_iterator it = keyMap.lowerBound(editRow); if (it != keyMap.constBegin() && it.key() != editRow) --it; if (it.key() > editRow || it == keyMap.constEnd()) { QApplication::beep(); return; } // copy and modify SyncTrack::TrackKey newKey = *it; newKey.type = (SyncTrack::TrackKey::KeyType) ((newKey.type + 1) % SyncTrack::TrackKey::KEY_TYPE_COUNT); // apply change to data-set doc->setKeyFrame(t, newKey); // update user interface dirtyCurrentValue(); } else QApplication::beep(); }
bool fileSaveAs() { wchar_t temp[_MAX_FNAME + 1]; temp[0] = '\0'; OPENFILENAMEW ofn; ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.lpstrFile = temp; ofn.nMaxFile = _MAX_FNAME; ofn.lpstrDefExt = L"rocket"; ofn.lpstrFilter = L"ROCKET File (*.rocket)\0*.rocket\0All Files (*.*)\0*.*\0\0"; ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT; if (GetSaveFileNameW(&ofn)) { if (document.save(temp)) { document.sendSaveCommand(); setWindowFileName(temp); fileName = temp; mruFileList.insert(temp); mruFileList.update(); DrawMenuBar(hwnd); return true; } else error("Failed to save file"); } return false; }
void TrackView::editToggleInterpolationType() { SyncDocument *doc = getDocument(); if (NULL == doc) return; if (editTrack < int(getTrackCount())) { size_t trackIndex = doc->getTrackIndexFromPos(editTrack); const sync_track *t = doc->tracks[trackIndex]; int idx = key_idx_floor(t, editRow); if (idx < 0) { MessageBeep(~0U); return; } // copy and modify track_key newKey = t->keys[idx]; newKey.type = (enum key_type) ((newKey.type + 1) % KEY_TYPE_COUNT); // apply change to data-set SyncDocument::Command *cmd = doc->getSetKeyFrameCommand(int(trackIndex), newKey); doc->exec(cmd); // update user interface SendMessage(GetParent(getWin()), WM_CURRVALDIRTY, 0, 0); InvalidateRect(getWin(), NULL, FALSE); } else MessageBeep(~0U); }
void TrackView::editEnterValue() { SyncDocument *doc = getDocument(); if (NULL == doc) return; if (int(editString.size()) > 0 && editTrack < int(getTrackCount())) { size_t trackIndex = doc->getTrackIndexFromPos(editTrack); const sync_track *t = doc->tracks[trackIndex]; track_key newKey; newKey.type = KEY_STEP; newKey.row = editRow; int idx = sync_find_key(t, editRow); if (idx >= 0) newKey = t->keys[idx]; // copy old key newKey.value = float(atof(editString.c_str())); // modify value editString.clear(); SyncDocument::Command *cmd = doc->getSetKeyFrameCommand(int(trackIndex), newKey); doc->exec(cmd); SendMessage(GetParent(getWin()), WM_CURRVALDIRTY, 0, 0); InvalidateRect(getWin(), NULL, FALSE); } else MessageBeep(~0U); }
void TrackView::editEnterValue() { SyncDocument *doc = getDocument(); if (!lineEdit->isVisible()) return; if (lineEdit->text().length() > 0 && editTrack < getTrackCount()) { SyncTrack *t = getTrack(editTrack); SyncTrack::TrackKey newKey; newKey.type = SyncTrack::TrackKey::STEP; newKey.row = editRow; if (t->isKeyFrame(editRow)) newKey = t->getKeyFrame(editRow); // copy old key QString text = lineEdit->text(); text.remove(lineEdit->validator()->locale().groupSeparator()); // workaround QTBUG-40456 newKey.value = lineEdit->validator()->locale().toFloat(text); // modify value doc->setKeyFrame(t, newKey); dirtyCurrentValue(); } else QApplication::beep(); lineEdit->hide(); setFocus(); }
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; }
void TrackView::editNextBookmark() { SyncDocument *doc = getDocument(); int row = doc->nextRowBookmark(getEditRow()); if (row >= 0) setEditRow(row, false); }
void TrackView::editPreviousBookmark() { SyncDocument *doc = getDocument(); int row = doc->prevRowBookmark(getEditRow()); if (row >= 0) setEditRow(row, false); }
static void processCommand(ClientSocket &sock) { SyncDocument *doc = trackView->getDocument(); int strLen, serverIndex, newRow; std::string trackName; const sync_track *t; unsigned char cmd = 0; if (sock.recv((char*)&cmd, 1)) { switch (cmd) { case GET_TRACK: // read data sock.recv((char *)&strLen, sizeof(int)); strLen = ntohl(strLen); if (!sock.connected()) return; if (!strLen) { sock.disconnect(); InvalidateRect(trackViewWin, NULL, FALSE); return; } trackName.resize(strLen); if (!sock.recv(&trackName[0], strLen)) return; if (int(strlen(trackName.c_str())) != strLen) { sock.disconnect(); InvalidateRect(trackViewWin, NULL, FALSE); return; } // find track serverIndex = sync_find_track(doc, trackName.c_str()); if (0 > serverIndex) serverIndex = int(doc->createTrack(trackName)); // setup remap doc->clientSocket.clientTracks[trackName] = clientIndex++; // send key-frames t = doc->tracks[serverIndex]; for (int i = 0; i < (int)t->num_keys; ++i) doc->clientSocket.sendSetKeyCommand(trackName, t->keys[i]); InvalidateRect(trackViewWin, NULL, FALSE); break; case SET_ROW: sock.recv((char*)&newRow, sizeof(int)); trackView->setEditRow(ntohl(newRow)); break; } } }
void TrackView::editRedo() { SyncDocument *doc = getDocument(); if (!doc->canRedo()) QApplication::beep(); else doc->redo(); }
static void attemptQuit() { SyncDocument *doc = trackView->getDocument(); if (doc->modified()) { UINT res = MessageBox(hwnd, "Save before exit?", mainWindowTitle, MB_YESNOCANCEL | MB_ICONQUESTION); if ((IDYES == res && fileSave()) || (IDNO == res)) DestroyWindow(hwnd); } else DestroyWindow(hwnd); }
bool fileSave() { if (fileName.empty()) return fileSaveAs(); if (!document.save(fileName.c_str())) { document.sendSaveCommand(); error("Failed to save file"); return false; } return true; }
static bool fileSave() { SyncDocument *doc = trackView->getDocument(); if (doc->fileName.empty()) return fileSaveAs(); if (!doc->save(doc->fileName)) { doc->clientSocket.sendSaveCommand(); error("Failed to save file"); return false; } return true; }
void processCommand(NetworkSocket &sock) { size_t clientIndex = 0; int strLen, serverIndex, newRow; std::string trackName; const sync_track *t; unsigned char cmd = 0; if (sock.recv((char*)&cmd, 1, 0)) { switch (cmd) { case GET_TRACK: // read data sock.recv((char *)&clientIndex, sizeof(int), 0); sock.recv((char *)&strLen, sizeof(int), 0); clientIndex = ntohl(clientIndex); strLen = ntohl(strLen); if (!sock.connected()) return; trackName.resize(strLen); if (!sock.recv(&trackName[0], strLen, 0)) return; // find track serverIndex = sync_find_track(&document, trackName.c_str()); if (0 > serverIndex) serverIndex = int(document.createTrack(trackName)); // setup remap document.clientRemap[serverIndex] = clientIndex; // send key-frames t = document.tracks[serverIndex]; for (int i = 0; i < (int)t->num_keys; ++i) document.sendSetKeyCommand(int(serverIndex), t->keys[i]); InvalidateRect(trackViewWin, NULL, FALSE); break; case SET_ROW: sock.recv((char*)&newRow, sizeof(int), 0); trackView->setEditRow(ntohl(newRow)); break; } } }
void TrackView::editBiasValue(float amount) { SyncDocument *doc = getDocument(); if (NULL == doc) return; int selectLeft = min(selectStartTrack, selectStopTrack); int selectRight = max(selectStartTrack, selectStopTrack); int selectTop = min(selectStartRow, selectStopRow); int selectBottom = max(selectStartRow, selectStopRow); if (0 == getTrackCount()) { MessageBeep(~0U); return; } SyncDocument::MultiCommand *multiCmd = new SyncDocument::MultiCommand(); for (int track = selectLeft; track <= selectRight; ++track) { assert(track < int(getTrackCount())); size_t trackIndex = doc->getTrackIndexFromPos(track); const sync_track *t = doc->tracks[trackIndex]; for (int row = selectTop; row <= selectBottom; ++row) { int idx = sync_find_key(t, row); if (idx >= 0) { struct track_key k = t->keys[idx]; // copy old key k.value += amount; // modify value // add sub-command SyncDocument::Command *cmd = doc->getSetKeyFrameCommand(int(trackIndex), k); multiCmd->addCommand(cmd); } } } if (0 == multiCmd->getSize()) { MessageBeep(~0U); delete multiCmd; } else { doc->exec(multiCmd); SendMessage(GetParent(getWin()), WM_CURRVALDIRTY, 0, 0); invalidateRange(selectLeft, selectRight, selectTop, selectBottom); } }
void fileNew() { // document.purgeUnusedTracks(); SyncDocument::MultiCommand *multiCmd = new SyncDocument::MultiCommand(); for (size_t i = 0; i < document.num_tracks; ++i) { sync_track *t = document.tracks[i]; for (size_t j = 0; j < t->num_keys; ++j) multiCmd->addCommand(new SyncDocument::DeleteCommand(i, t->keys[j].row)); } document.exec(multiCmd); setWindowFileName(L"Untitled"); fileName.clear(); document.clearUndoStack(); document.clearRedoStack(); }
void attemptQuit() { if (document.modified()) { UINT res = MessageBox(hwnd, "Save before exit?", mainWindowTitle, MB_YESNOCANCEL | MB_ICONQUESTION); if ((IDYES == res && fileSave()) || (IDNO == res)) DestroyWindow(hwnd); } else DestroyWindow(hwnd); }
void loadDocument(const std::wstring &_fileName) { fileNew(); if (document.load(_fileName)) { setWindowFileName(_fileName.c_str()); fileName = _fileName; mruFileList.insert(_fileName); mruFileList.update(); DrawMenuBar(hwnd); document.clearUndoStack(); document.clearRedoStack(); trackView->setDocument(&document); SendMessage(hwnd, WM_CURRVALDIRTY, 0, 0); InvalidateRect(trackViewWin, NULL, FALSE); } else error("failed to open file"); }
void TrackView::editClear() { SyncDocument *doc = getDocument(); QRect selection = getSelection(); if (0 == getTrackCount()) return; Q_ASSERT(selection.right() < getTrackCount()); doc->beginMacro("clear"); for (int track = selection.left(); track <= selection.right(); ++track) { SyncTrack *t = getTrack(track); for (int row = selection.top(); row <= selection.bottom(); ++row) { if (t->isKeyFrame(row)) doc->deleteKeyFrame(t, row); } } doc->endMacro(); dirtyCurrentValue(); }
void TrackView::editDelete() { SyncDocument *doc = getDocument(); if (NULL == doc) return; int selectLeft = min(selectStartTrack, selectStopTrack); int selectRight = max(selectStartTrack, selectStopTrack); int selectTop = min(selectStartRow, selectStopRow); int selectBottom = max(selectStartRow, selectStopRow); if (0 == getTrackCount()) return; assert(selectRight < int(getTrackCount())); SyncDocument::MultiCommand *multiCmd = new SyncDocument::MultiCommand(); for (int track = selectLeft; track <= selectRight; ++track) { size_t trackIndex = doc->getTrackIndexFromPos(track); const sync_track *t = doc->tracks[trackIndex]; for (int row = selectTop; row <= selectBottom; ++row) { if (is_key_frame(t, row)) { SyncDocument::Command *cmd = new SyncDocument::DeleteCommand(int(trackIndex), row); multiCmd->addCommand(cmd); } } } if (0 == multiCmd->getSize()) { MessageBeep(~0U); delete multiCmd; } else { doc->exec(multiCmd); SendMessage(GetParent(getWin()), WM_CURRVALDIRTY, 0, 0); InvalidateRect(getWin(), NULL, FALSE); } }
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nShowCmd*/) { #ifdef _DEBUG _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); /* _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG); _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); */ // _CrtSetBreakAlloc(254); #endif hInst = hInstance; CoInitialize(NULL); WSADATA wsa; if (0 != WSAStartup(MAKEWORD(2, 0), &wsa)) die("Failed to init network"); SOCKET serverSocket = 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(1338); if (SOCKET_ERROR == bind(serverSocket, (struct sockaddr *)&sin, sizeof(sin))) die("Could not start server"); while (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) ; /* nothing */ ATOM mainClass = registerMainWindowClass(hInstance); ATOM trackViewClass = registerTrackViewWindowClass(hInstance); if (!mainClass || !trackViewClass) die("Window Registration Failed!"); trackView = new TrackView(); trackView->setDocument(&document); hwnd = CreateWindowExW( 0, mainWindowClassName, mainWindowTitleW, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, // x, y CW_USEDEFAULT, CW_USEDEFAULT, // width, height NULL, NULL, hInstance, NULL ); if (NULL == hwnd) die("Window Creation Failed!"); fileNew(); HACCEL accel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); ShowWindow(hwnd, TRUE); UpdateWindow(hwnd); bool done = false; MSG msg; bool guiConnected = false; while (!done) { if (!document.clientSocket.connected()) { SOCKET clientSocket = INVALID_SOCKET; fd_set fds; FD_ZERO(&fds); #pragma warning(suppress: 4127) FD_SET(serverSocket, &fds); struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 0; // look for new clients if (select(0, &fds, NULL, NULL, &timeout) > 0) { SendMessage(statusBarWin, SB_SETTEXT, 0, (LPARAM)"Accepting..."); sockaddr_in client; clientSocket = clientConnect(serverSocket, &client); if (INVALID_SOCKET != clientSocket) { char temp[256]; snprintf(temp, 256, "Connected to %s", inet_ntoa(client.sin_addr)); SendMessage(statusBarWin, SB_SETTEXT, 0, (LPARAM)temp); document.clientSocket = NetworkSocket(clientSocket); document.clientRemap.clear(); document.sendPauseCommand(true); document.sendSetRowCommand(trackView->getEditRow()); guiConnected = true; } else SendMessage(statusBarWin, SB_SETTEXT, 0, (LPARAM)"Not Connected."); } } if (document.clientSocket.connected()) { NetworkSocket &clientSocket = document.clientSocket; // look for new commands while (clientSocket.pollRead()) processCommand(clientSocket); } if (!document.clientSocket.connected() && guiConnected) { document.clientPaused = true; InvalidateRect(trackViewWin, NULL, FALSE); SendMessage(statusBarWin, SB_SETTEXT, 0, (LPARAM)"Not Connected."); guiConnected = false; } while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (!TranslateAccelerator(hwnd, accel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); if (WM_QUIT == msg.message) done = true; } } Sleep(1); } closesocket(serverSocket); WSACleanup(); delete trackView; trackView = NULL; UnregisterClassW(mainWindowClassName, hInstance); return int(msg.wParam); }
void TrackView::editPaste() { SyncDocument *doc = getDocument(); if (0 == getTrackCount()) { QApplication::beep(); return; } const QMimeData *mimeData = QApplication::clipboard()->mimeData(); if (mimeData->hasFormat("application/x-gnu-rocket")) { const QByteArray mimeDataBuffer = mimeData->data("application/x-gnu-rocket"); const char *clipbuf = mimeDataBuffer.data(); // copy data int buffer_width, buffer_height, buffer_size; memcpy(&buffer_width, clipbuf + 0, sizeof(int)); memcpy(&buffer_height, clipbuf + sizeof(int), sizeof(int)); memcpy(&buffer_size, clipbuf + 2 * sizeof(int), sizeof(int)); doc->beginMacro("paste"); for (int i = 0; i < buffer_width; ++i) { int trackPos = editTrack + i; if (trackPos >= getTrackCount()) continue; SyncTrack *t = getTrack(trackPos); for (int j = 0; j < buffer_height; ++j) { int row = editRow + j; if (t->isKeyFrame(row)) doc->deleteKeyFrame(t, row); } } const char *src = clipbuf + 2 * sizeof(int) + sizeof(size_t); for (int i = 0; i < buffer_size; ++i) { struct CopyEntry ce; memcpy(&ce, src, sizeof(CopyEntry)); src += sizeof(CopyEntry); Q_ASSERT(ce.track >= 0); Q_ASSERT(ce.track < buffer_width); Q_ASSERT(ce.keyFrame.row >= 0); Q_ASSERT(ce.keyFrame.row < buffer_height); int trackPos = editTrack + ce.track; if (trackPos < getTrackCount()) { SyncTrack::TrackKey key = ce.keyFrame; key.row += editRow; // since we deleted all keyframes in the edit-box already, we can just insert this one. doc->setKeyFrame(getTrack(trackPos), key); } } doc->endMacro(); dirtyCurrentValue(); clipbuf = NULL; } else QApplication::beep(); }
static LRESULT CALLBACK mainWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CREATE: { trackViewWin = trackView->create(hInst, hwnd); InitCommonControls(); statusBarWin = createStatusBar(hInst, hwnd); if (ERROR_SUCCESS != RegOpenKey(HKEY_CURRENT_USER, keyName, ®ConfigKey)) { if (ERROR_SUCCESS != RegCreateKey(HKEY_CURRENT_USER, keyName, ®ConfigKey)) die("failed to create registry key"); } /* Recent Files menu */ mruFileList = RecentFiles(findSubMenuContaining(GetMenu(hwnd), ID_RECENTFILES_NORECENTFILES)); mruFileList.load(regConfigKey); } break; case WM_CLOSE: attemptQuit(); break; case WM_DESTROY: mruFileList.save(regConfigKey); RegCloseKey(regConfigKey); regConfigKey = NULL; PostQuitMessage(0); break; case WM_SIZE: { int width = LOWORD(lParam); int height = HIWORD(lParam); 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_SETROWS: trackView->setRows(int(lParam)); break; case WM_BIASSELECTION: trackView->editBiasValue(float(lParam)); break; case WM_COMMAND: switch (LOWORD(wParam)) { case ID_FILE_NEW: fileNew(); InvalidateRect(trackViewWin, NULL, FALSE); break; case ID_FILE_OPEN: fileOpen(); break; case ID_FILE_SAVE_AS: fileSaveAs(); break; case ID_FILE_SAVE: fileSave(); break; case ID_EDIT_SELECTALL: trackView->selectAll(); break; case ID_EDIT_SELECTTRACK: trackView->selectTrack(trackView->getEditTrack()); break; case ID_EDIT_SELECTROW: trackView->selectRow(trackView->getEditRow()); break; case ID_FILE_REMOTEEXPORT: document.sendSaveCommand(); break; case ID_RECENTFILES_FILE1: case ID_RECENTFILES_FILE2: case ID_RECENTFILES_FILE3: case ID_RECENTFILES_FILE4: case ID_RECENTFILES_FILE5: { int index = LOWORD(wParam) - ID_RECENTFILES_FILE1; std::wstring fileName; if (mruFileList.getEntry(index, fileName)) { loadDocument(fileName); } } break; case ID_FILE_EXIT: attemptQuit(); break; case ID_EDIT_UNDO: SendMessage(trackViewWin, WM_UNDO, 0, 0); break; case ID_EDIT_REDO: SendMessage(trackViewWin, WM_REDO, 0, 0); break; case ID_EDIT_COPY: SendMessage(trackViewWin, WM_COPY, 0, 0); break; case ID_EDIT_CUT: SendMessage(trackViewWin, WM_CUT, 0, 0); break; case ID_EDIT_PASTE: SendMessage(trackViewWin, WM_PASTE, 0, 0); break; case ID_EDIT_SETROWS: { int rows = int(trackView->getRows()); INT_PTR result = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SETROWS), hwnd, (DLGPROC)setRowsDialogProc, (LPARAM)&rows); if (FAILED(result)) error("unable to create dialog box"); } break; case ID_EDIT_BIAS: { int initialBias = 0; INT_PTR result = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_BIASSELECTION), hwnd, (DLGPROC)biasSelectionDialogProc, (LPARAM)&initialBias); if (FAILED(result)) error("unable to create dialog box"); } break; } break; case WM_ROWCHANGED: { char temp[256]; snprintf(temp, 256, "%d", lParam ); SendMessage(statusBarWin, SB_SETTEXT, 1, (LPARAM)temp); } break; case WM_TRACKCHANGED: { char temp[256]; snprintf(temp, 256, "%d", lParam); SendMessage(statusBarWin, SB_SETTEXT, 2, (LPARAM)temp); } break; case WM_CURRVALDIRTY: { char temp[256]; if (document.num_tracks > 0) { const sync_track *t = document.tracks[document.getTrackIndexFromPos(trackView->getEditTrack())]; int row = trackView->getEditRow(); int idx = key_idx_floor(t, row); snprintf(temp, 256, "%f", sync_get_val(t, row)); const char *str = "---"; if (idx >= 0) { switch (t->keys[idx].type) { case KEY_STEP: str = "step"; break; case KEY_LINEAR: str = "linear"; break; case KEY_SMOOTH: str = "smooth"; break; case KEY_RAMP: str = "ramp"; break; } } SendMessage(statusBarWin, SB_SETTEXT, 4, (LPARAM)str); } else snprintf(temp, 256, "---"); SendMessage(statusBarWin, SB_SETTEXT, 3, (LPARAM)temp); } break; default: return DefWindowProcW(hwnd, msg, wParam, lParam); } return 0; }
void TrackView::editPaste() { SyncDocument *doc = getDocument(); if (NULL == doc) return; if (0 == getTrackCount()) { MessageBeep(~0U); return; } if (FAILED(OpenClipboard(getWin()))) { MessageBox(NULL, "Failed to open clipboard", NULL, MB_OK); return; } if (IsClipboardFormatAvailable(clipboardFormat)) { HGLOBAL hmem = GetClipboardData(clipboardFormat); char *clipbuf = (char *)GlobalLock(hmem); // copy data int buffer_width, buffer_height, buffer_size; memcpy(&buffer_width, clipbuf + 0, sizeof(int)); memcpy(&buffer_height, clipbuf + sizeof(int), sizeof(int)); memcpy(&buffer_size, clipbuf + 2 * sizeof(int), sizeof(size_t)); SyncDocument::MultiCommand *multiCmd = new SyncDocument::MultiCommand(); for (int i = 0; i < buffer_width; ++i) { size_t trackPos = editTrack + i; if (trackPos >= getTrackCount()) continue; size_t trackIndex = doc->getTrackIndexFromPos(trackPos); const sync_track *t = doc->tracks[trackIndex]; for (int j = 0; j < buffer_height; ++j) { int row = editRow + j; if (is_key_frame(t, row)) multiCmd->addCommand(new SyncDocument::DeleteCommand(int(trackIndex), row)); } } char *src = clipbuf + 2 * sizeof(int) + sizeof(size_t); for (int i = 0; i < buffer_size; ++i) { struct CopyEntry ce; memcpy(&ce, src, sizeof(CopyEntry)); src += sizeof(CopyEntry); assert(ce.track >= 0); assert(ce.track < buffer_width); assert(ce.keyFrame.row >= 0); assert(ce.keyFrame.row < buffer_height); size_t trackPos = editTrack + ce.track; if (trackPos < getTrackCount()) { size_t trackIndex = doc->getTrackIndexFromPos(trackPos); track_key key = ce.keyFrame; key.row += editRow; // since we deleted all keyframes in the edit-box already, we can just insert this one. SyncDocument::Command *cmd = new SyncDocument::InsertCommand(int(trackIndex), key); multiCmd->addCommand(cmd); } } doc->exec(multiCmd); GlobalUnlock(hmem); clipbuf = NULL; } else MessageBeep(~0U); CloseClipboard(); }
void TrackView::keyPressEvent(QKeyEvent *event) { SyncDocument *doc = getDocument(); if (!readOnly && lineEdit->isVisible()) { switch (event->key()) { case Qt::Key_Up: case Qt::Key_Down: case Qt::Key_Left: case Qt::Key_Right: case Qt::Key_PageUp: case Qt::Key_PageDown: case Qt::Key_Home: case Qt::Key_End: case Qt::Key_Space: editEnterValue(); return; } } bool shiftDown = (event->modifiers() & Qt::ShiftModifier) != 0; bool ctrlDown = (event->modifiers() & Qt::ControlModifier) != 0; bool selecting = shiftDown; if (lineEdit->isHidden()) { switch (event->key()) { case Qt::Key_Backtab: if (ctrlDown) { // the main window will handle this event->ignore(); return; } selecting = false; // FALLTHROUGH case Qt::Key_Left: if (ctrlDown) { if (0 < editTrack) page->swapTrackOrder(editTrack, editTrack - 1); else QApplication::beep(); } if (0 != getTrackCount()) setEditTrack(editTrack - 1, selecting); else QApplication::beep(); return; case Qt::Key_Tab: if (ctrlDown) { // the main window will handle this event->ignore(); return; } selecting = false; // FALLTHROUGH case Qt::Key_Right: if (ctrlDown) { if (getTrackCount() > editTrack + 1) page->swapTrackOrder(editTrack, editTrack + 1); else QApplication::beep(); } if (0 != getTrackCount()) setEditTrack(editTrack + 1, selecting); else QApplication::beep(); return; } } if (lineEdit->isHidden()) { if (!readOnly && ctrlDown) { switch (event->key()) { case Qt::Key_Up: if (getTrackCount() > editTrack) editBiasValue(shiftDown ? 0.1f : 1.0f); else QApplication::beep(); return; case Qt::Key_Down: if (getTrackCount() > editTrack) editBiasValue(shiftDown ? -0.1f : -1.0f); else QApplication::beep(); return; case Qt::Key_PageUp: editBiasValue(shiftDown ? 100.0f : 10.0f); return; case Qt::Key_PageDown: editBiasValue(shiftDown ? -100.0f : -10.0f); return; } } switch (event->key()) { case Qt::Key_Up: setEditRow(editRow - 1, selecting); return; case Qt::Key_Down: setEditRow(editRow + 1, selecting); return; case Qt::Key_PageUp: setEditRow(editRow - 0x10, selecting); return; case Qt::Key_PageDown: setEditRow(editRow + 0x10, selecting); return; case Qt::Key_Home: if (ctrlDown) setEditTrack(0, false); else setEditRow(0, selecting); return; case Qt::Key_End: if (ctrlDown) setEditTrack(getTrackCount() - 1, false); else setEditRow(getRows() - 1, selecting); return; } } switch (event->key()) { case Qt::Key_Delete: editClear(); return; case Qt::Key_Cancel: case Qt::Key_Escape: if (!readOnly && lineEdit->isVisible()) { // return to old value (i.e don't clear) lineEdit->hide(); setFocus(); QApplication::beep(); } return; case Qt::Key_I: editToggleInterpolationType(); return; case Qt::Key_K: doc->toggleRowBookmark(getEditRow()); return; } if (!readOnly && !ctrlDown && lineEdit->isHidden() && event->text().length() && doc->getTrackCount()) { // no line-edit, check if input matches a double QString str = event->text(); int pos = 0; if (lineEdit->validator()->validate(str, pos) != QValidator::Invalid) { lineEdit->move(getPhysicalX(getEditTrack()), getPhysicalY(getEditRow())); lineEdit->resize(trackWidth, rowHeight); lineEdit->setText(""); lineEdit->show(); lineEdit->event(event); lineEdit->setFocus(); return; } } event->ignore(); }
SyncDocument *SyncDocument::load(const QString &fileName) { SyncDocument *ret = new SyncDocument; ret->fileName = fileName; QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { QMessageBox::critical(NULL, "Error", file.errorString()); return NULL; } QDomDocument doc; QString err; if (!doc.setContent(&file, &err)) { file.close(); QMessageBox::critical(NULL, "Error", err); return NULL; } file.close(); QDomNamedNodeMap attribs = doc.documentElement().attributes(); QDomNode rowsParam = attribs.namedItem("rows"); if (!rowsParam.isNull()) { QString rowsString = rowsParam.nodeValue(); ret->setRows(rowsString.toInt()); } QDomNodeList trackNodes = doc.documentElement().elementsByTagName("track"); for (int i = 0; i < int(trackNodes.length()); ++i) { QDomNode trackNode = trackNodes.item(i); QDomNamedNodeMap attribs = trackNode.attributes(); QString name = attribs.namedItem("name").nodeValue(); // look up track-name, create it if it doesn't exist SyncTrack *t = ret->findTrack(name.toUtf8()); if (!t) t = ret->createTrack(name.toUtf8().constData()); QDomNodeList rowNodes = trackNode.childNodes(); for (int i = 0; i < int(rowNodes.length()); ++i) { QDomNode keyNode = rowNodes.item(i); QString baseName = keyNode.nodeName(); if (baseName == "key") { QDomNamedNodeMap rowAttribs = keyNode.attributes(); QString rowString = rowAttribs.namedItem("row").nodeValue(); QString valueString = rowAttribs.namedItem("value").nodeValue(); QString interpolationString = rowAttribs.namedItem("interpolation").nodeValue(); SyncTrack::TrackKey k; k.row = rowString.toInt(); k.value = valueString.toFloat(); k.type = SyncTrack::TrackKey::KeyType(interpolationString.toInt()); Q_ASSERT(!t->isKeyFrame(k.row)); t->setKey(k); } } } // YUCK: gathers from entire document QDomNodeList bookmarkNodes = doc.documentElement().elementsByTagName("bookmark"); for (int i = 0; i < int(bookmarkNodes.length()); ++i) { QDomNode bookmarkNode = bookmarkNodes.item(i); QDomNamedNodeMap bookmarkAttribs = bookmarkNode.attributes(); QString str = bookmarkAttribs.namedItem("row").nodeValue(); int row = str.toInt(); ret->toggleRowBookmark(row); } return ret; }
LRESULT TrackView::onKeyDown(UINT keyCode, UINT /*flags*/) { SyncDocument *doc = getDocument(); if (NULL == doc) return FALSE; if (!editString.empty()) { switch(keyCode) { case VK_UP: case VK_DOWN: case VK_LEFT: case VK_RIGHT: case VK_PRIOR: case VK_NEXT: case VK_HOME: case VK_END: editEnterValue(); } } if (editString.empty()) { switch (keyCode) { case VK_LEFT: if (GetKeyState(VK_CONTROL) < 0) { if (0 < editTrack) doc->swapTrackOrder(editTrack, editTrack - 1); else MessageBeep(~0U); } if (0 != getTrackCount()) setEditTrack(editTrack - 1); else MessageBeep(~0U); break; case VK_RIGHT: if (GetKeyState(VK_CONTROL) < 0) { if (int(getTrackCount()) > editTrack + 1) doc->swapTrackOrder(editTrack, editTrack + 1); else MessageBeep(~0U); } if (0 != getTrackCount()) setEditTrack(editTrack + 1); else MessageBeep(~0U); break; } } if (editString.empty() && doc->clientSocket.clientPaused) { switch (keyCode) { case VK_UP: if (GetKeyState(VK_CONTROL) < 0) { float bias = 1.0f; if (GetKeyState(VK_SHIFT) < 0) bias = 0.1f; if (int(getTrackCount()) > editTrack) editBiasValue(bias); else MessageBeep(~0U); } else setEditRow(editRow - 1); break; case VK_DOWN: if (GetKeyState(VK_CONTROL) < 0) { float bias = 1.0f; if (GetKeyState(VK_SHIFT) < 0) bias = 0.1f; if (int(getTrackCount()) > editTrack) editBiasValue(-bias); else MessageBeep(~0U); } else setEditRow(editRow + 1); break; case VK_PRIOR: if (GetKeyState(VK_CONTROL) < 0) { float bias = 10.0f; if (GetKeyState(VK_SHIFT) < 0) bias = 100.0f; editBiasValue(bias); } else setEditRow(editRow - 0x10); break; case VK_NEXT: if (GetKeyState(VK_CONTROL) < 0) { float bias = 10.0f; if (GetKeyState(VK_SHIFT) < 0) bias = 100.0f; editBiasValue(-bias); } else setEditRow(editRow + 0x10); break; case VK_HOME: if (GetKeyState(VK_CONTROL) < 0) setEditTrack(0); else setEditRow(0); break; case VK_END: if (GetKeyState(VK_CONTROL) < 0) setEditTrack(int(getTrackCount()) - 1); else setEditRow(int(getRows()) - 1); break; } } switch (keyCode) { case VK_RETURN: editEnterValue(); break; case VK_DELETE: editDelete(); break; case VK_BACK: if (!editString.empty()) { editString.resize(editString.size() - 1); invalidatePos(editTrack, editRow); } else MessageBeep(~0U); break; case VK_CANCEL: case VK_ESCAPE: if (!editString.empty()) { // return to old value (i.e don't clear) editString.clear(); invalidatePos(editTrack, editRow); MessageBeep(~0U); } break; case VK_SPACE: if (!editString.empty()) { editString.clear(); invalidatePos(editTrack, editRow); MessageBeep(~0U); } doc->clientSocket.sendPauseCommand( !doc->clientSocket.clientPaused ); break; } return FALSE; }