Perpustakaan C kecil yang secara portir memohon file asli terbuka, folder pilih dan file simpan dialog. Tulis kode dialog sekali dan minta dialog asli di semua platform yang didukung. Hindari menghubungkan dependensi besar seperti WXWIDGETS dan QT.
Perpustakaan ini didasarkan pada dialog file asli Michael Labbe (MLABBE/NativeFiledialog).
Fitur:
C/C++ Source files (*.c;*.cpp) bukan (*.c;*.cpp) ) pada platform yang mendukungnyaUntitled.c )wchar_t ) di WindowsIFileDialog modern Vista di Windowsunique_ptr dan parameter opsional, untuk mereka yang menggunakan pustaka ini dari C ++Perbandingan dengan dialog file asli asli:
Fitur nama ramah adalah alasan utama untuk melanggar kompatibilitas API dengan perpustakaan Michael Labbe (dan karenanya perpustakaan ini mungkin tidak akan pernah digabungkan dengan itu). Ada juga sejumlah penyesuaian yang menyebabkan perbedaan yang dapat diamati di perpustakaan ini.
Fitur yang ditambahkan dalam dialog File Asli Diperpanjang:
wchar_t ) di Windowsunique_ptr dan Parameter OpsionalAda juga refraktor kode yang signifikan, terutama untuk implementasi Windows.
Wiki melacak ikatan bahasa yang dikenal dan proyek -proyek populer yang dikenal yang bergantung pada perpustakaan ini.
#include <nfd.h>
#include <stdio.h>
#include <stdlib.h>
int main ( void )
{
NFD_Init ();
nfdu8char_t * outPath ;
nfdu8filteritem_t filters [ 2 ] = { { "Source code" , "c,cpp,cc" }, { "Headers" , "h,hpp" } };
nfdopendialogu8args_t args = { 0 };
args . filterList = filters ;
args . filterCount = 2 ;
nfdresult_t result = NFD_OpenDialogU8_With ( & outPath , & args );
if ( result == NFD_OKAY )
{
puts ( "Success!" );
puts ( outPath );
NFD_FreePathU8 ( outPath );
}
else if ( result == NFD_CANCEL )
{
puts ( "User pressed cancel." );
}
else
{
printf ( "Error: %sn" , NFD_GetError ());
}
NFD_Quit ();
return 0 ;
} U8 / u8 di NFDE merujuk ke API untuk karakter UTF-8 ( char ), yang mungkin diinginkan sebagian besar konsumen. Versi N / n juga tersedia, yang menggunakan tipe karakter asli ( wchar_t pada Windows dan char di platform lain).
Untuk daftar lengkap argumen yang dapat Anda atur pada args struct, lihat bagian "Semua Opsi" di bawah ini.
Jika Anda menggunakan kerangka kerja abstraksi platform seperti SDL atau GLFW, juga lihat bagian "Penggunaan dengan Kerangka Abstraksi Platform" di bawah ini.






Jika proyek Anda menggunakan CMake, cukup tambahkan baris berikut ke cmakelists Anda. TXT:
add_subdirectory(path/to/nativefiledialog-extended)
target_link_libraries(MyProgram PRIVATE nfd)
Pastikan Anda juga memiliki dependensi yang dibutuhkan.
Ketika dimasukkan sebagai subproyject, program sampel tidak dibangun dan target instalasi dinonaktifkan secara default. Tambahkan -DNFD_BUILD_TESTS=ON untuk membangun program sampel dan -DNFD_INSTALL=ON untuk mengaktifkan target instalasi.
Jika Anda ingin membangun perpustakaan statis mandiri, jalankan perintah berikut (mulai dari direktori root proyek):
Untuk GCC dan Clang:
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
Untuk msvc:
mkdir build
cd build
cmake ..
cmake --build . --config Release
Perintah di atas akan membuat direktori build , dan membangun proyek (dalam mode rilis) di sana. Jika Anda mengembangkan NFDE, Anda mungkin ingin melakukan -DCMAKE_BUILD_TYPE=Debug / --config Debug untuk membangun versi debug perpustakaan sebagai gantinya.
Saat membangun sebagai perpustakaan mandiri, program sampel dibangun dan target instalasi diaktifkan secara default. Tambahkan -DNFD_BUILD_TESTS=OFF untuk menonaktifkan program sampel bangunan dan -DNFD_INSTALL=OFF untuk menonaktifkan target instalasi.
Di Linux, jika Anda ingin menggunakan Portal Desktop Flatpak, bukan GTK, tambahkan -DNFD_PORTAL=ON . (Jika tidak, GTK akan digunakan.) Lihat bagian "Penggunaan" di bawah ini untuk informasi lebih lanjut.
Lihat file CI Build untuk beberapa contoh perintah build.
Versi terbaru dari Visual Studio memiliki dukungan CMAKE yang dibangun ke dalam IDE. Anda harus dapat "membuka folder" di Direktori Root Proyek, dan Visual Studio akan mengenali dan mengkonfigurasi proyek dengan tepat. Dari sana, Anda akan dapat mengatur konfigurasi untuk rilis debug vs, dan untuk x86 vs x64. Untuk informasi lebih lanjut, lihat halaman Microsoft Docs. Ini telah diuji untuk bekerja di Visual Studio 2019, dan mungkin berfungsi pada Visual Studio 2017 juga.
src/include ke jalur pencarian termasuk Anda.nfd.lib atau nfd_d.lib ke daftar pustaka statis untuk ditautkan (untuk rilis atau debug, masing -masing).build/<debug|release>/<arch> ke jalur pencarian perpustakaan. Pastikan libgtk-3-dev diinstal pada sistem Anda.
Pastikan libdbus-1-dev diinstal pada sistem Anda.
Pada macOS, tambahkan AppKit dan UniformTypeIdentifiers ke dalam daftar kerangka kerja.
Pada Windows (baik MSVC dan MINGW), pastikan Anda membangun melawan ole32.lib , uuid.lib , dan shell32.lib .
Untuk membuka dialog, Anda mengatur opsi pada struct dan kemudian meneruskan struct itu ke fungsi NFDE, misalnya:
nfdopendialogu8args_t args = { 0 };
args . filterList = filters ;
args . filterCount = 2 ;
nfdresult_t result = NFD_OpenDialogU8_With ( & outPath , & args ); Semua opsi opsional dan dapat diatur secara individual (nol inisialisasi set semua opsi ke default yang masuk akal), kecuali untuk filterList dan filterCount yang harus diatur atau keduanya tidak disetel.
Versi NFDE di masa depan dapat menambahkan opsi tambahan ke akhir argumen struct tanpa menabrak nomor versi utama, jadi untuk memastikan kompatibilitas API mundur, Anda tidak boleh berasumsi bahwa struct memiliki panjang atau jumlah bidang tertentu. Anda dapat mengasumsikan bahwa inisialisasi nol dari struct akan terus mengatur semua opsi ke default yang wajar, sehingga menetapkan {0} ke struct dapat diterima. Untuk pustaka bersama NFDE, kompatibilitas ABI mundur dipastikan oleh indeks versi internal ( NFD_INTERFACE_VERSION ), yang diharapkan transparan bagi konsumen.
OPENDIALOG / OPENENDIALOGMULTIPLE :
typedef struct {
const nfdu8filteritem_t * filterList ;
nfdfiltersize_t filterCount ;
const nfdu8char_t * defaultPath ;
nfdwindowhandle_t parentWindow ;
} nfdopendialogu8args_t ;Savedialog :
typedef struct {
const nfdu8filteritem_t * filterList ;
nfdfiltersize_t filterCount ;
const nfdu8char_t * defaultPath ;
const nfdu8char_t * defaultName ;
nfdwindowhandle_t parentWindow ;
} nfdsavedialogu8args_t ;Pickfolder / pickfolderMultiple :
typedef struct {
const nfdu8char_t * defaultPath ;
nfdwindowhandle_t parentWindow ;
} nfdpickfolderu8args_t ;filterList dan filterCount : Atur ini untuk menyesuaikan filter file (muncul sebagai menu dropdown di Windows dan Linux, tetapi cukup menyembunyikan file di macOS). Atur filterList ke pointer ke awal array item filter dan filterCount ke jumlah item filter dalam array itu. Lihat bagian "Sintaks File File" di bawah ini untuk detailnya.defaultPath : Atur ini ke folder default yang harus dibuka dialog (pada Windows, jika ada folder yang baru digunakan, terbuka ke folder itu alih -alih folder yang Anda lewati, kecuali opsi build NFD_OVERRIDE_RECENT_WITH_DEFAULT diatur ke ON).defaultName : (Untuk SaveDialog saja) Atur ini ke nama file yang harus diisi sebelumnya pada dialog.parentWindow : Atur ini ke pegangan jendela asli dari induk dialog ini. Lihat bagian "Penggunaan dengan Kerangka Abstraksi Platform" untuk detailnya. Dimungkinkan juga untuk melewati pegangan bahkan jika Anda tidak menggunakan kerangka kerja abstraksi platform. Lihat Direktori test untuk Contoh Kode (baik C dan C ++).
Jika Anda menyalakan opsi untuk membangun direktori test ( -DNFD_BUILD_TESTS=ON ), maka build/bin akan berisi program pengujian yang dikompilasi.
Ada juga contoh SDL2, yang perlu diaktifkan secara terpisah dengan -DNFD_BUILD_SDL2_TESTS=ON . Dibutuhkan SDL2 untuk diinstal pada mesin Anda.
Contoh yang dikompilasi (termasuk contoh SDL2) juga diunggah sebagai artefak untuk tindakan github, dan dapat diunduh dari sana.
File dapat difilter oleh grup ekstensi file:
nfdu8filteritem_t filters [ 2 ] = { { "Source code" , "c,cpp,cc" }, { "Headers" , "h,hpp" } };Filter file adalah sepasang string yang terdiri dari nama yang ramah dan spesifikasi (beberapa ekstensi file dipisahkan secara koma).
Daftar file file dapat disahkan sebagai argumen saat memohon perpustakaan.
Filter wildcard selalu ditambahkan ke setiap dialog.
Catatan: Pada macOS, dialog file tidak memiliki nama yang ramah dan tidak ada cara untuk beralih di antara filter, sehingga spesifikasi filter digabungkan (misalnya C, CPP, CC, H, HPP "). Spesifikasi filter juga tidak pernah secara eksplisit ditunjukkan kepada pengguna. Ini adalah perilaku macOS yang biasa dan pengguna mengharapkannya.
Catatan 2: Anda harus memastikan bahwa string spesifikasi tidak kosong dan bahwa setiap ekstensi file memiliki setidaknya satu karakter. Kalau tidak, hal -hal buruk mungkin terjadi (yaitu perilaku yang tidak ditentukan).
Catatan 3: Di Linux, ekstensi file ditambahkan (jika hilang) ketika pengguna menekan tombol "Simpan". Ekstensi file yang ditambahkan akan tetap terlihat oleh pengguna, bahkan jika prompt yang ditampilkan ditampilkan dan pengguna kemudian menekan "Batal".
Catatan 4: Pada Windows, parameter folder default hanya digunakan jika tidak ada folder yang baru digunakan, kecuali opsi build NFD_OVERRIDE_RECENT_WITH_DEFAULT diatur ke ON. Kalau tidak, folder default akan menjadi folder yang terakhir digunakan. Secara internal, implementasi Windows memanggil iFeDiLialog :: setDefaultFolder (IsHellItem). Ini adalah perilaku Windows yang biasa dan pengguna mengharapkannya.
Dialog terbuka file yang mendukung beberapa seleksi menghasilkan pathset, yang merupakan abstraksi tipis atas koleksi khusus platform. Ada dua cara untuk mengulangi di atas pathset:
Metode ini memang akses seperti array pada pathset, dan merupakan yang termudah untuk digunakan. Namun, pada platform tertentu (Linux, dan mungkin Windows), dibutuhkan total waktu O (n 2 ) untuk mengulangi seluruh pathset, karena implementasi spesifik platform yang mendasarinya menggunakan daftar tertaut.
Lihat test_opendialogmultiple.c.
Metode ini menggunakan objek enumerator untuk mengulangi jalur dalam pathset. Dijamin akan membutuhkan waktu total untuk mengulangi seluruh pathset.
Lihat test_opendialogmultiple_enum.c.
API ini bersifat eksperimental, dan dapat berubah.
Anda dapat menentukan makro berikut sebelum memasukkan nfd.h / nfd.hpp :
NFD_NATIVE : NFD_OpenDialogN ini sebelum memasukkan nfd.h NFD_OpenDialogU8 membuat nama fungsi dan typedefs yang tidak tertahan (mis NFD_OpenDialog Makro ini tidak mempengaruhi C ++ Wrapper nfd.hpp .NFD_THROWS_EXCEPTIONS : (hanya c ++) Tentukan ini sebelum memasukkan nfd.hpp untuk membuat NFD::Guard construction throw std::runtime_error jika NFD_Init gagal. Kalau tidak, tidak ada cara untuk mendeteksi kegagalan di NFD::Guard Construction. Makro yang mungkin ditentukan oleh nfd.h :
NFD_DIFFERENT_NATIVE_FUNCTIONS : didefinisikan jika fungsi fungsi asli dan UTF-8 berbeda (yaitu kompilasi untuk windows); tidak ditentukan sebaliknya. Jika NFD_DIFFERENT_NATIVE_FUNCTIONS tidak didefinisikan, maka versi fungsi UTF-8 adalah alias untuk versi asli. Ini mungkin berguna jika Anda menulis fungsi yang ingin memberikan kelebihan beban tergantung pada apakah fungsi asli dan fungsi UTF-8 adalah sama. (Asli adalah UTF-16 ( wchar_t ) untuk Windows dan UTF-8 ( char ) untuk Mac/Linux.) NFDE diketahui bekerja dengan SDL2 dan GLFW, dan juga harus bekerja dengan framwork abstraksi platform lainnya. Bagian ini menjelaskan cara menggunakan NFDE dengan benar dengan kerangka kerja tersebut.
Argumen parentWindow memungkinkan pengguna untuk memberikan dialog kepada orang tua.
Jika menggunakan SDL2, sertakan <nfd_sdl2.h> dan hubungi fungsi berikut untuk mengatur pegangan jendela induk:
NFD_GetNativeWindowFromSDLWindow ( sdlWindow /* SDL_Window* */ , & args . parentWindow ); Jika menggunakan GLFW3, tentukan makro GLFW_EXPOSE_NATIVE_* yang sesuai yang dijelaskan pada halaman akses asli GLFW, dan kemudian sertakan <nfd_glfw3.h> dan hubungi fungsi berikut untuk mengatur pegangan jendela induk:
NFD_GetNativeWindowFromGLFWWindow ( glfwWindow /* GLFWwindow* */ , & args . parentWindow ); Jika Anda menggunakan kerangka kerja abstraksi platform lain, atau tidak menggunakan kerangka kerja seperti itu, Anda dapat mengatur args.parentWindow secara manual.
Win32 (Windows), Cocoa (MacOS), dan X11 (Linux) didukung. Melewati jendela Wayland (Linux) saat ini tidak melakukan apa pun (yaitu dialog bertindak seolah -olah tidak memiliki orang tua), tetapi dukungan kemungkinan akan ditambahkan di masa depan.
Untuk membuat jendela (dalam hal ini dialog file) tetap di atas jendela lain, kita perlu mendeklarasikan jendela bawah sebagai induk dari jendela atas. Ini menjaga jendela dialog dari menghilang di belakang jendela induk jika pengguna mengklik jendela induk saat dialog terbuka. Menjaga dialog di atas jendela yang memohon itu adalah perilaku yang diharapkan pada semua sistem operasi yang didukung, dan dengan demikian melewati pegangan jendela induknya disarankan jika memungkinkan.
Anda harus menginisialisasi NFDE setelah menginisialisasi kerangka kerja, dan mungkin harus mendepialisasi NFDE sebelum mendeinitialisasi kerangka kerja. Ini karena beberapa kerangka kerja diharapkan diinisialisasi pada "batu tulis bersih", dan mereka dapat mengkonfigurasi sistem dengan cara yang berbeda dari NFDE. NFD_Init umumnya sangat berhati -hati untuk tidak mengganggu konfigurasi yang ada kecuali diperlukan, dan NFD_Quit mengembalikan konfigurasi kembali dengan tepat apa yang sebelum diinisialisasi.
Contoh dengan SDL2:
// Initialize SDL2 first
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) != 0) {
// display some error here
}
// Then initialize NFDe
if (NFD_Init() != NFD_OKAY) {
// display some error here
}
/*
Your main program goes here
*/
NFD_Quit(); // deinitialize NFDe first
SDL_Quit(); // Then deinitialize SDL2
Di Linux, Anda dapat menggunakan implementasi portal alih -alih GTK, yang akan membuka pemilih file "asli" yang dipilih oleh OS atau disesuaikan oleh pengguna. Pengguna harus memiliki xdg-desktop-portal dan backend yang sesuai yang diinstal (ini sudah dipasang sebelumnya dengan distro desktop yang paling umum), jika tidak, NFD_ERROR akan dikembalikan.
Untuk menggunakan implementasi portal, tambahkan -DNFD_PORTAL=ON ke perintah build.
*Catatan: Pemilih folder hanya didukung pada org.freedesktop.portal.FileChooser Versi Versi> = 3, yang sesuai dengan versi XDG-desktop-portal> = 1.7.1. NFD_PickFolder() akan menanyakan versi antarmuka saat runtime, dan mengembalikan NFD_ERROR jika versinya terlalu rendah.
Tidak seperti Windows dan MacOS, Linux tidak memiliki pemilih file yang dipanggang ke dalam sistem operasi. Aplikasi Linux yang menginginkan pemilih file biasanya menautkan dengan perpustakaan yang menyediakan satu (seperti GTK, seperti pada tangkapan layar Linux di atas). Ini adalah solusi yang sebagian besar dapat diterima yang banyak digunakan oleh banyak aplikasi, tetapi dapat membuat pemilih file terlihat asing pada distro non-GTK.
Flatpak diperkenalkan pada tahun 2015, dan dengan itu datang antarmuka standar untuk membuka pemilih file. Aplikasi yang menggunakan antarmuka ini tidak perlu datang dengan pemilih file, dan dapat menggunakan yang disediakan oleh Flatpak. Antarmuka ini dikenal sebagai portal desktop, dan penggunaannya diperluas ke aplikasi non-flatpak. Sekarang, sebagian besar distro desktop utama dilengkapi dengan portal desktop yang diinstal, dengan pemilih file yang sesuai dengan tema distro. Pengguna juga dapat menginstal backend portal yang berbeda jika diinginkan. Saat ini ada tiga backend yang diketahui dengan dukungan pemilih file: GTK, KDE, dan LXQT; Backends Gnome dan Xapp bergantung pada GTK One untuk fungsi ini. Backend Xapp telah dirancang untuk kayu manis, pasangan, dan xfce. Lingkungan desktop lain tampaknya saat ini tidak memiliki backend portal.
Info.plist Anda sesuai dokumentasi Apple. -DNFD_USE_ALLOWEDCONTENTTYPES_IF_AVAILABLE=OFFGetOpenFileName . (Tidak ada rencana untuk mendukung ini; Anda tidak boleh tetap menggunakan Windows XP.)Harap gunakan pelacak masalah GitHub untuk melaporkan bug atau berkontribusi pada repositori ini. Jangan ragu untuk mengirimkan laporan bug apa pun.
Bernard Teo (saya) dan kontributor lain untuk semua yang bukan dari dialog file asli Michael Labbe.
Michael Labbe untuk Perpustakaan Dialog File Asli yang Luar Biasa, dan kontributor lainnya untuk perpustakaan itu.
Sebagian besar readme ini juga telah disalin dari readme repositori dialog file asli asli.
Segala sesuatu dalam repositori ini didistribusikan di bawah lisensi Zlib, seperti pustaka dialog file asli asli.
Saya tidak memberikan dukungan berbayar. Michael Labbe tampaknya memberikan dukungan berbayar untuk perpustakaannya pada saat penulisan.