Skip to content

Commit 3bad016

Browse files
committed
Add DragSource and DropTarget for dragging files and text in and out of windows
1 parent dd522c1 commit 3bad016

30 files changed

Lines changed: 3192 additions & 1 deletion

‎CMakeLists.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ add_subdirectory(examples/url_opener_c_example)
3232
add_subdirectory(examples/window_c_example)
3333
add_subdirectory(examples/window_example)
3434
add_subdirectory(examples/window_drag_session_example)
35+
add_subdirectory(examples/drag_drop_example)
3536
add_subdirectory(examples/desktop_features_example)
3637

3738
if(BUILD_TESTING)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
cmake_minimum_required(VERSION 3.10)
2+
3+
project(drag_drop_example VERSION 0.0.1 LANGUAGES CXX)
4+
5+
# Set C++ standard
6+
set(CMAKE_CXX_STANDARD 17)
7+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
8+
9+
# Add example program
10+
add_executable(drag_drop_example
11+
"main.cpp"
12+
)
13+
14+
# Link main library
15+
target_link_libraries(drag_drop_example PRIVATE nativeapi)
16+
17+
# Set example program properties
18+
set_target_properties(drag_drop_example PROPERTIES
19+
OUTPUT_NAME "drag_drop_example"
20+
)
21+
22+
# Set example program compile options (macOS only)
23+
if(APPLE)
24+
set_source_files_properties("main.cpp"
25+
PROPERTIES
26+
COMPILE_FLAGS "-x objective-c++"
27+
)
28+
endif()
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#include <cstdio>
2+
#include <filesystem>
3+
#include <fstream>
4+
#include <iostream>
5+
#include "nativeapi.h"
6+
7+
using nativeapi::DragOperation;
8+
using nativeapi::DragSource;
9+
using nativeapi::DragSourceEndedEvent;
10+
using nativeapi::DropTarget;
11+
using nativeapi::DropTargetDroppedEvent;
12+
using nativeapi::DropTargetEnteredEvent;
13+
using nativeapi::DropTargetExitedEvent;
14+
using nativeapi::DropTargetMovedEvent;
15+
using nativeapi::RunApp;
16+
using nativeapi::Window;
17+
using nativeapi::WindowFocusedEvent;
18+
using nativeapi::WindowManager;
19+
20+
namespace {
21+
22+
const char* OperationName(DragOperation operation) {
23+
switch (operation) {
24+
case DragOperation::Copy:
25+
return "copy";
26+
case DragOperation::Move:
27+
return "move";
28+
case DragOperation::Link:
29+
return "link";
30+
case DragOperation::None:
31+
break;
32+
}
33+
return "none";
34+
}
35+
36+
} // namespace
37+
38+
// Drag and drop without any UI toolkit.
39+
//
40+
// - Drop files or text from a file manager or editor onto the "Drop here"
41+
// window; every event is printed.
42+
// - Press inside the "Drag me" window (not on its title bar) and keep dragging
43+
// to drag a text file out of it, into a file manager or the "Drop here"
44+
// window. There is no widget to press on, so the window becoming focused
45+
// stands in for the mouse-down.
46+
int main() {
47+
WindowManager& window_manager = WindowManager::GetInstance();
48+
49+
auto drop_window = std::make_shared<Window>();
50+
drop_window->SetTitle("Drop here");
51+
drop_window->SetSize({480, 320}, false);
52+
drop_window->Center();
53+
54+
auto source_window = std::make_shared<Window>();
55+
source_window->SetTitle("Drag me");
56+
source_window->SetSize({240, 160}, false);
57+
auto position = drop_window->GetPosition();
58+
source_window->SetPosition({position.x + 520, position.y});
59+
source_window->Show();
60+
61+
std::cout << "Drop target supported: " << DropTarget::IsSupported()
62+
<< ", drag source supported: " << DragSource::IsSupported() << std::endl;
63+
64+
auto target = std::make_shared<DropTarget>(drop_window);
65+
target->AddListener<DropTargetEnteredEvent>([](const DropTargetEnteredEvent& event) {
66+
auto p = event.GetPosition();
67+
std::cout << "Entered at (" << p.x << ", " << p.y << ")" << std::endl;
68+
});
69+
target->AddListener<DropTargetMovedEvent>([](const DropTargetMovedEvent& event) {
70+
auto p = event.GetPosition();
71+
std::cout << "Moved to (" << p.x << ", " << p.y << ")" << std::endl;
72+
});
73+
target->AddListener<DropTargetExitedEvent>([](const DropTargetExitedEvent&) {
74+
std::cout << "Exited" << std::endl;
75+
});
76+
target->AddListener<DropTargetDroppedEvent>([](const DropTargetDroppedEvent& event) {
77+
auto p = event.GetPosition();
78+
std::cout << "Dropped at (" << p.x << ", " << p.y << ")" << std::endl;
79+
for (const auto& path : event.GetFilePaths()) {
80+
std::cout << " file: " << path << std::endl;
81+
}
82+
if (!event.GetText().empty()) {
83+
std::cout << " text: " << event.GetText() << std::endl;
84+
}
85+
});
86+
std::cout << "Drop target active: " << target->IsActive() << std::endl;
87+
auto content = drop_window->GetContentBounds();
88+
std::cout << "Drop content at (" << content.x << ", " << content.y << ")" << std::endl;
89+
90+
// A file to drag out.
91+
auto file = std::filesystem::temp_directory_path() / "nativeapi-drag-drop-example.txt";
92+
std::ofstream(file) << "Dragged out of drag_drop_example.\n";
93+
94+
auto source = std::make_shared<DragSource>();
95+
source->SetFilePaths({file.string()});
96+
source->SetText("Hello from drag_drop_example");
97+
source->AddListener<DragSourceEndedEvent>([](const DragSourceEndedEvent& event) {
98+
std::cout << "Drag ended: " << OperationName(event.GetOperation()) << std::endl;
99+
});
100+
101+
window_manager.AddListener<WindowFocusedEvent>([&](const WindowFocusedEvent& event) {
102+
if (event.GetWindowId() != source_window->GetId() || source->IsDragging()) {
103+
return;
104+
}
105+
if (source->StartDragging(source_window)) {
106+
std::cout << "Dragging " << file.string() << std::endl;
107+
}
108+
});
109+
110+
std::cout << "Drop something on \"Drop here\", or press inside \"Drag me\" and drag."
111+
<< std::endl;
112+
return RunApp(drop_window);
113+
}

‎include/nativeapi.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "../src/dialog.h"
1313
#include "../src/display.h"
1414
#include "../src/display_manager.h"
15+
#include "../src/drag_source.h"
16+
#include "../src/drop_target.h"
1517
#include "../src/file_dialog.h"
1618
#include "../src/foundation/color.h"
1719
#include "../src/foundation/geometry.h"
@@ -46,6 +48,8 @@
4648
#include "../src/capi/dialog_c.h"
4749
#include "../src/capi/display_c.h"
4850
#include "../src/capi/display_manager_c.h"
51+
#include "../src/capi/drag_source_c.h"
52+
#include "../src/capi/drop_target_c.h"
4953
#include "../src/capi/file_dialog_c.h"
5054
#include "../src/capi/geometry_c.h"
5155
#include "../src/capi/image_c.h"

‎src/CMakeLists.txt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,5 @@ elseif(APPLE)
100100
elseif(CMAKE_SYSTEM_NAME STREQUAL "OHOS")
101101
target_link_libraries(nativeapi PUBLIC hilog_ndk.z)
102102
elseif(WIN32)
103-
target_link_libraries(nativeapi PUBLIC user32 shell32 comctl32 dwmapi gdiplus crypt32 advapi32 version)
103+
target_link_libraries(nativeapi PUBLIC user32 shell32 ole32 uuid comctl32 dwmapi gdiplus crypt32 advapi32 version)
104104
endif ()

0 commit comments

Comments
 (0)