Step 88: drag-and-drop open

This commit is contained in:
Bill
2026-02-09 09:38:57 -07:00
parent a1efe93ba3
commit 23e3758cca
5 changed files with 92 additions and 0 deletions

View File

@@ -496,6 +496,9 @@ target_include_directories(step86_test PRIVATE src)
add_executable(step87_test tests/step87_test.cpp)
target_include_directories(step87_test PRIVATE src)
add_executable(step88_test tests/step88_test.cpp)
target_include_directories(step88_test PRIVATE src)
find_package(SDL2 CONFIG REQUIRED)
find_package(OpenGL REQUIRED)
find_package(glad CONFIG REQUIRED)

View File

@@ -0,0 +1,24 @@
#pragma once
// Step 88: Drag-and-drop handler
#include <string>
#include <functional>
#include <filesystem>
class DragDropHandler {
public:
using FileCallback = std::function<void(const std::string&)>;
using FolderCallback = std::function<void(const std::string&)>;
static void handleDrop(const std::string& path,
const FileCallback& onFile,
const FolderCallback& onFolder) {
if (path.empty()) return;
std::filesystem::path p(path);
if (std::filesystem::is_directory(p)) {
if (onFolder) onFolder(path);
} else {
if (onFile) onFile(path);
}
}
};

View File

@@ -22,6 +22,7 @@
#include "FileDialog.h"
#include "FileTree.h"
#include "WelcomeScreen.h"
#include "DragDropHandler.h"
#include "ast/Generator.h"
#include <cstdio>
@@ -624,6 +625,18 @@ int main(int, char**) {
event.window.event == SDL_WINDOWEVENT_CLOSE &&
event.window.windowID == SDL_GetWindowID(window))
done = true;
if (event.type == SDL_DROPFILE) {
char* droppedFile = event.drop.file;
if (droppedFile) {
DragDropHandler::handleDrop(droppedFile,
[&](const std::string& p) { state.doOpen(p); },
[&](const std::string& p) {
state.workspaceRoot = p;
state.fileTreeDirty = true;
});
SDL_free(droppedFile);
}
}
// Handle keyboard shortcuts via KeybindingManager
if (event.type == SDL_KEYDOWN && !io.WantTextInput) {

View File

@@ -0,0 +1,49 @@
// Step 88 TDD Test: Drag-and-drop handler
//
// Tests:
// 1. File drop invokes file callback
// 2. Folder drop invokes folder callback
#include <cassert>
#include <iostream>
#include <filesystem>
#include <fstream>
#include "DragDropHandler.h"
int main() {
int passed = 0;
int failed = 0;
std::filesystem::path root = std::filesystem::current_path() / "tmp_step88";
std::filesystem::create_directories(root / "dir");
std::filesystem::path file = root / "file.txt";
std::ofstream f(file.string());
f << "x";
f.close();
bool fileCalled = false;
bool folderCalled = false;
DragDropHandler::handleDrop(file.string(),
[&](const std::string& p){ fileCalled = (p == file.string()); },
[&](const std::string& p){ folderCalled = (p == (root / "dir").string()); }
);
assert(fileCalled);
std::cout << "Test 1 PASS: File drop" << std::endl;
++passed;
fileCalled = false;
folderCalled = false;
DragDropHandler::handleDrop((root / "dir").string(),
[&](const std::string& p){ fileCalled = (p == file.string()); },
[&](const std::string& p){ folderCalled = (p == (root / "dir").string()); }
);
assert(folderCalled);
std::cout << "Test 2 PASS: Folder drop" << std::endl;
++passed;
std::filesystem::remove_all(root);
std::cout << "\n=== Step 88 Results: " << passed << " passed, " << failed << " failed ===" << std::endl;
return failed > 0 ? 1 : 0;
}