beginnings of drag and drop #33
20 changed files with 894 additions and 1141 deletions
commit
9abdea2d2a
12
Doxyfile
12
Doxyfile
|
|
@ -1,9 +1,6 @@
|
|||
PROJECT_LOGO = resource/logo/logo64.png
|
||||
PROJECT_NAME = Milsko
|
||||
PROJECT_BRIEF = "Lightweight and fast GUI toolkit"
|
||||
OUTPUT_DIRECTORY = doxygen
|
||||
TAB_SIZE = 8
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
PROJECT_LOGO = resource / logo / logo64.png PROJECT_NAME = Milsko
|
||||
PROJECT_BRIEF = "Lightweight and fast GUI toolkit" OUTPUT_DIRECTORY = doxygen
|
||||
TAB_SIZE = 8 OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
MARKDOWN_SUPPORT = YES
|
||||
FILE_PATTERNS = *.h*.md
|
||||
INPUT = include / Mw
|
||||
|
|
@ -22,5 +19,4 @@ OUTPUT_LANGUAGE = English
|
|||
GENERATE_LATEX = NO
|
||||
EXTRACT_ALL = YES
|
||||
|
||||
HTML_EXTRA_STYLESHEET = resource/doxygen-theme/doxygen-awesome.css
|
||||
HTML_COLORSTYLE = LIGHT
|
||||
HTML_EXTRA_STYLESHEET = resource / doxygen - theme / doxygen - awesome.css HTML_COLORSTYLE = LIGHT
|
||||
|
|
|
|||
42
Jenkinsfile
vendored
42
Jenkinsfile
vendored
|
|
@ -1,22 +1,14 @@
|
|||
pipeline {
|
||||
agent{
|
||||
label "built-in"
|
||||
}
|
||||
stages {
|
||||
label "built-in"} stages {
|
||||
stage("Build document") {
|
||||
when{
|
||||
branch "master"
|
||||
}
|
||||
agent {
|
||||
label "built-in"
|
||||
}
|
||||
steps {
|
||||
branch "master"} agent{
|
||||
label "built-in"} steps{
|
||||
sh("rm -rf include/Mw/LowLevel/Wayland")
|
||||
sh("doxygen")
|
||||
sh("rm -rf /var/www/milsko-doxygen")
|
||||
sh("mv doxygen/html /var/www/milsko-doxygen")
|
||||
}
|
||||
post {
|
||||
sh("mv doxygen/html /var/www/milsko-doxygen")} post {
|
||||
always {
|
||||
notifyDiscord()
|
||||
}
|
||||
|
|
@ -26,9 +18,7 @@ pipeline {
|
|||
parallel {
|
||||
stage("Build for Linux 64-bit") {
|
||||
agent{
|
||||
label "built-in"
|
||||
}
|
||||
steps {
|
||||
label "built-in"} steps {
|
||||
sh("git clean -dfx")
|
||||
sh("./configure --enable-opengl --enable-vulkan --without-vulkan-string-helper")
|
||||
sh("make -j4")
|
||||
|
|
@ -38,9 +28,7 @@ pipeline {
|
|||
}
|
||||
stage("Build for Windows 32-bit") {
|
||||
agent{
|
||||
label "built-in"
|
||||
}
|
||||
steps {
|
||||
label "built-in"} steps {
|
||||
sh("git clean -dfx")
|
||||
sh("./configure --enable-opengl --enable-stb-truetype --disable-freetype2 --cross --target=Windows --host=i686-w64-mingw32")
|
||||
sh("make -j4")
|
||||
|
|
@ -51,9 +39,7 @@ pipeline {
|
|||
}
|
||||
stage("Build for Windows 64-bit") {
|
||||
agent{
|
||||
label "built-in"
|
||||
}
|
||||
steps {
|
||||
label "built-in"} steps {
|
||||
sh("git clean -dfx")
|
||||
sh("./configure --enable-opengl --enable-stb-truetype --disable-freetype2 --cross --target=Windows --host=x86_64-w64-mingw32")
|
||||
sh("make -j4")
|
||||
|
|
@ -64,9 +50,7 @@ pipeline {
|
|||
}
|
||||
stage("Build for Windows 32-bit (MSVC)") {
|
||||
agent{
|
||||
label "2012r2"
|
||||
}
|
||||
steps {
|
||||
label "2012r2"} steps {
|
||||
bat("git clean -dfx")
|
||||
bat("nmake -f NTMakefile")
|
||||
bat("move /y src\\Mw.dll MwMSVC32.dll")
|
||||
|
|
@ -76,14 +60,8 @@ pipeline {
|
|||
}
|
||||
stage("Build for Windows 32-bit (Watcom)") {
|
||||
agent{
|
||||
label "built-in"
|
||||
}
|
||||
environment {
|
||||
WATCOM = "/usr/watcom"
|
||||
INCLUDE = "/usr/watcom/h:/usr/watcom/h/nt"
|
||||
PATH = "/usr/watcom/binl64:${env.PATH}"
|
||||
}
|
||||
steps {
|
||||
label "built-in"} environment{
|
||||
WATCOM = "/usr/watcom" INCLUDE = "/usr/watcom/h:/usr/watcom/h/nt" PATH = "/usr/watcom/binl64:${env.PATH}"} steps {
|
||||
sh("git clean -dfx")
|
||||
sh("wmake -f WatMakefile")
|
||||
sh("mv src/Mw.dll MwWat32.dll")
|
||||
|
|
|
|||
42
LICENSE
42
LICENSE
|
|
@ -1,24 +1,28 @@
|
|||
Copyright (c) 2025-2026, Pyrite development team
|
||||
All rights reserved.
|
||||
Copyright(c) 2025 - 2026, Pyrite development team All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
Redistribution and use in source and binary forms,
|
||||
with or without
|
||||
modification,
|
||||
are permitted provided that the following conditions are met : *Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and / or other materials provided with the distribution.* Neither the name of the<organization> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING,
|
||||
BUT NOT LIMITED TO,
|
||||
THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED.IN NO EVENT SHALL<COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
DIRECT,
|
||||
INDIRECT,
|
||||
INCIDENTAL,
|
||||
SPECIAL,
|
||||
EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY,
|
||||
OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
|
|||
380
NTMakefile
generated
380
NTMakefile
generated
File diff suppressed because one or more lines are too long
588
WatMakefile
generated
588
WatMakefile
generated
File diff suppressed because one or more lines are too long
88
configure
vendored
88
configure
vendored
|
|
@ -7,7 +7,8 @@ if (index($target, "MINGW") != -1) {
|
|||
$target = "Windows";
|
||||
}
|
||||
|
||||
foreach my $l (@ARGV) {
|
||||
foreach
|
||||
my $l(@ARGV) {
|
||||
if($l = ~/ ^--.+ $ /) {
|
||||
}
|
||||
elsif($l = ~/ ^(.+) = (.+) $ /) {
|
||||
|
|
@ -54,8 +55,7 @@ param_set("examples", 1);
|
|||
#(option that only makes sense on x11)
|
||||
param_set("allow-sloppy-focus", 0);
|
||||
|
||||
my %features = (
|
||||
"classic-theme" => "use classic theme",
|
||||
my % features = ("classic-theme" = > "use classic theme",
|
||||
"stb-image" = > "use stb_image, instead use libjpeg/libpng",
|
||||
"stb-truetype" = > "use stb_truetype",
|
||||
"freetype2" = > "use FreeType2",
|
||||
|
|
@ -69,26 +69,25 @@ my %features = (
|
|||
"wayland" = > "enable wayland backend",
|
||||
"gnustep" = > "use gnustep",
|
||||
"dbus" = > "use DBus on supported platform",
|
||||
"allow-sloppy-focus" => "prevent the x11 backend from using XSetInputFocus to enforce click-to-focus"
|
||||
);
|
||||
my @features_keys = (
|
||||
"1classic-theme", "1stb-image",
|
||||
"allow-sloppy-focus" = > "prevent the x11 backend from using XSetInputFocus to enforce click-to-focus");
|
||||
my @features_keys = ("1classic-theme", "1stb-image",
|
||||
"1stb-truetype", "1freetype2", "1gdi-text",
|
||||
"1opengl", "2xrender",
|
||||
"1vulkan", "2vulkan-string-helper",
|
||||
"1shared", "1static",
|
||||
"1wayland", "1gnustep",
|
||||
"1dbus"
|
||||
);
|
||||
"1dbus");
|
||||
|
||||
sub def_platform {
|
||||
if($target eq "Windows") {
|
||||
param_set("freetype2", 0);
|
||||
param_set("stb-truetype", 0);
|
||||
} elsif($target ne "Darwin" and $target ne "ClassicMacOS" and $target ne "Haiku") {
|
||||
}
|
||||
elsif($target ne "Darwin" and $target ne "ClassicMacOS" and $target ne "Haiku") {
|
||||
param_set("freetype2", 1);
|
||||
param_set("stb-truetype", 0);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
param_set("freetype2", 0);
|
||||
param_set("stb-truetype", 1);
|
||||
}
|
||||
|
|
@ -110,7 +109,8 @@ sub def_platform {
|
|||
}
|
||||
}
|
||||
|
||||
foreach my $l (@ARGV) {
|
||||
foreach
|
||||
my $l(@ARGV) {
|
||||
if($l = ~/ ^--target = (.+) $ /) {
|
||||
$target = $1;
|
||||
}
|
||||
|
|
@ -118,8 +118,8 @@ foreach my $l (@ARGV) {
|
|||
|
||||
def_platform();
|
||||
|
||||
|
||||
foreach my $l (@ARGV) {
|
||||
foreach
|
||||
my $l(@ARGV) {
|
||||
if($l = ~/ ^--with - ([^=] +) = (.+) $ /) {
|
||||
param_set($1, $2);
|
||||
}
|
||||
|
|
@ -161,12 +161,12 @@ foreach my $l (@ARGV) {
|
|||
print(" --disable-FEATURE Do not use FEATURE\n");
|
||||
print(" --without-FEATURE Do not use FEATURE\n");
|
||||
|
||||
foreach my $l (@features_keys) {
|
||||
my $flag = (
|
||||
(substr($l, 0, 1) eq '1')
|
||||
foreach
|
||||
my $l(@features_keys) {
|
||||
my $flag = ((substr($l, 0, 1) eq '1')
|
||||
? (param_get(substr($l, 1)) ? "--disable-" : "--enable-")
|
||||
: (param_get(substr($l, 1)) ? "--without-" : "--with-")
|
||||
) . substr($l, 1);
|
||||
: (param_get(substr($l, 1)) ? "--without-" : "--with-"))
|
||||
.substr($l, 1);
|
||||
my $do = param_get(substr($l, 1)) ? "Do not " : "";
|
||||
my $feat = $features{substr($l, 1)};
|
||||
if(not(param_get(substr($l, 1)))) {
|
||||
|
|
@ -180,11 +180,9 @@ foreach my $l (@ARGV) {
|
|||
|
||||
if(-f "./pl/ostype/${target}.pl") {
|
||||
require("./pl/ostype/${target}.pl");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print(
|
||||
"Perl file (pl/ostype/${target}.pl) was not found for your target. Please add one.\n"
|
||||
);
|
||||
"Perl file (pl/ostype/${target}.pl) was not found for your target. Please add one.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
@ -193,7 +191,8 @@ require("./pl/rules.pl");
|
|||
print("Target : ".$target."\n");
|
||||
|
||||
my @l = ();
|
||||
foreach my $e (param_list()) {
|
||||
foreach
|
||||
my $e(param_list()) {
|
||||
if(not(param_get($e))) {
|
||||
next;
|
||||
}
|
||||
|
|
@ -234,18 +233,15 @@ print(OUT "install: lib\n");
|
|||
print(OUT
|
||||
" mkdir -p \$(DESTDIR)\$(PREFIX)/lib \$(DESTDIR)\$(PREFIX)/include\n");
|
||||
print(OUT
|
||||
" -cp src/${library_prefix}Mw${library_suffix} \$(DESTDIR)\$(PREFIX)/lib/\n"
|
||||
);
|
||||
" -cp src/${library_prefix}Mw${library_suffix} \$(DESTDIR)\$(PREFIX)/lib/\n");
|
||||
print(OUT " -cp src/libMw.a \$(DESTDIR)\$(PREFIX)/lib/\n");
|
||||
print(OUT " cp -rf include \$(DESTDIR)\$(PREFIX)/\n");
|
||||
print(OUT "\n");
|
||||
print(OUT "format:\n");
|
||||
print(OUT
|
||||
" clang-format --verbose -i `find tools src include examples \"(\" -name \"*.c\" -or -name \"*.cc\" -or -name \"*.h\" -or -name \"*.m\" \")\" -and -not -name \"*ttf.c\"`\n"
|
||||
);
|
||||
" clang-format --verbose -i `find tools src include examples \"(\" -name \"*.c\" -or -name \"*.cc\" -or -name \"*.h\" -or -name \"*.m\" \")\" -and -not -name \"*ttf.c\"`\n");
|
||||
print(OUT
|
||||
" perltidy -b -bext=\"/\" --paren-tightness=2 `find tools pl configure -name \"*.pl\"`\n"
|
||||
);
|
||||
" perltidy -b -bext=\"/\" --paren-tightness=2 `find tools pl configure -name \"*.pl\"`\n");
|
||||
print(OUT "\n");
|
||||
print(OUT "lib:");
|
||||
|
||||
|
|
@ -276,7 +272,8 @@ if (param_get("static")) {
|
|||
print(OUT " \$(AR) rcs src/libMw.a ".join(" ", @library_targets)."\n");
|
||||
}
|
||||
|
||||
foreach my $l (@library_targets) {
|
||||
foreach
|
||||
my $l(@library_targets) {
|
||||
my $warn = "-Wall -Wextra -Wno-sign-compare -Wno-unused-value";
|
||||
my $s = $l;
|
||||
my $compiler = "CC";
|
||||
|
|
@ -306,7 +303,8 @@ print(OUT "\n");
|
|||
if(param_get("examples")) {
|
||||
print(OUT "examples: ".join(" ", @examples_targets)."\n");
|
||||
print(OUT "\n");
|
||||
foreach my $l (@examples_targets) {
|
||||
foreach
|
||||
my $l(@examples_targets) {
|
||||
my $libs = "";
|
||||
my $s = $l;
|
||||
my $o = $executable_suffix;
|
||||
|
|
@ -319,36 +317,32 @@ if (param_get("examples")) {
|
|||
|
||||
if(param_get("shared")) {
|
||||
print(OUT
|
||||
"${l}: ${s}${object_suffix} src/${library_prefix}Mw${library_suffix}\n"
|
||||
);
|
||||
"${l}: ${s}${object_suffix} src/${library_prefix}Mw${library_suffix}\n");
|
||||
} else {
|
||||
print(OUT
|
||||
"${l}: ${s}${object_suffix} src/${library_prefix}Mw.a\n"
|
||||
);
|
||||
"${l}: ${s}${object_suffix} src/${library_prefix}Mw.a\n");
|
||||
}
|
||||
if(grep(/ ^cocoa$ /, @backends)) {
|
||||
print(OUT
|
||||
" \$(CC) -L./src \$\(LIBDIR) -o ${l} ${s}${object_suffix} -lMw ${math} ${libs}\n"
|
||||
);
|
||||
}
|
||||
else {
|
||||
" \$(CC) -L./src \$\(LIBDIR) -o ${l} ${s}${object_suffix} -lMw ${math} ${libs}\n");
|
||||
} else {
|
||||
print(OUT
|
||||
" \$(CC) -L src -Wl,-R./src \$\(LIBDIR) -o ${l} ${s}${object_suffix} -lMw ${math} ${libs}\n"
|
||||
);
|
||||
" \$(CC) -L src -Wl,-R./src \$\(LIBDIR) -o ${l} ${s}${object_suffix} -lMw ${math} ${libs}\n");
|
||||
}
|
||||
|
||||
if($target eq "ClassicMacOS") {
|
||||
print(OUT
|
||||
" ".$ENV{RETRO68_TOOLCHAIN_PATH}."/bin/MakePEF ${l} -o ${s}.pef\n");
|
||||
" ".$ENV{RETRO68_TOOLCHAIN_PATH}
|
||||
."/bin/MakePEF ${l} -o ${s}.pef\n");
|
||||
print(OUT
|
||||
" Rez -I ".$ENV{RETRO68_TOOLCHAIN_PATH}."/RIncludes ".$ENV{RETRO68_TOOLCHAIN_PATH}."/RIncludes/Retro68APPL.r -DCFRAG_NAME=\"example\" --data ${l}.pef --cc ${l}.dsk -t APPL\n"
|
||||
);
|
||||
" Rez -I ".$ENV{RETRO68_TOOLCHAIN_PATH}
|
||||
."/RIncludes ".$ENV{RETRO68_TOOLCHAIN_PATH}
|
||||
."/RIncludes/Retro68APPL.r -DCFRAG_NAME=\"example\" --data ${l}.pef --cc ${l}.dsk -t APPL\n");
|
||||
}
|
||||
|
||||
print(OUT "${s}${object_suffix}: ${s}.c\n");
|
||||
print(OUT
|
||||
" \$(CC) -c \$\(INCDIR) -o ${s}${object_suffix} ${s}.c -lMw ${math}\n"
|
||||
);
|
||||
" \$(CC) -c \$\(INCDIR) -o ${s}${object_suffix} ${s}.c -lMw ${math}\n");
|
||||
}
|
||||
}
|
||||
print(OUT "\n");
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ struct _MwLLCommon {
|
|||
int type;
|
||||
int coordinate_type;
|
||||
MwBool supports_transparency;
|
||||
const char** known_mime_types;
|
||||
|
||||
MwLLHandler handler;
|
||||
};
|
||||
|
|
@ -315,6 +316,12 @@ MWDECL void (*MwLLGetClipboard)(MwLL handle, int clipboard_type);
|
|||
MWDECL void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point);
|
||||
MWDECL void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect);
|
||||
|
||||
/*!
|
||||
* @brief Setup drag and drop capabilities, should the user request it with MwNacceptsDnD
|
||||
* @param handle Handle
|
||||
*/
|
||||
MWDECL void (*MwLLSetupDragAndDrop)(MwLL handle);
|
||||
|
||||
/*!
|
||||
* @brief Set any extra parameters for dark theme
|
||||
* @param handle Handle
|
||||
|
|
|
|||
|
|
@ -29,6 +29,28 @@ struct _MwLLGDI {
|
|||
int force_render;
|
||||
int get_clipboard;
|
||||
int get_darktheme;
|
||||
|
||||
/* drag and drop */
|
||||
void *shell32lib;
|
||||
void *ole32lib;
|
||||
void *urlmonlib;
|
||||
UINT (*DragQueryFileW)(HDROP hDrop,UINT iFile,LPWSTR lpszFile,UINT cch);
|
||||
void (*ReleaseStgMedium)(LPSTGMEDIUM unnamedParam1);
|
||||
HRESULT (*OleInitialize)(LPVOID pvReserved);
|
||||
HRESULT (*RegisterDragDrop)(HWND hwnd, LPDROPTARGET pDropTarget);
|
||||
HRESULT (*FindMimeFromData)(
|
||||
LPBC pBC,
|
||||
LPCWSTR pwzUrl,
|
||||
LPVOID pBuffer,
|
||||
DWORD cbSize,
|
||||
LPCWSTR pwzMimeProposed,
|
||||
DWORD dwMimeFlags,
|
||||
LPWSTR *ppwzMimeOut,
|
||||
_Reserved_ DWORD dwReserved
|
||||
);
|
||||
struct _MwLLGDIDropTarget* dropTarget;
|
||||
MwBool listening_for_drag_and_drop;
|
||||
MwBool dnd_override;
|
||||
};
|
||||
|
||||
struct _MwLLGDIColor {
|
||||
|
|
@ -47,6 +69,14 @@ struct _MwLLGDIPixmap {
|
|||
HBITMAP hMask2;
|
||||
};
|
||||
|
||||
struct _MwLLGDIDropTarget{
|
||||
struct IDropTargetVtbl *lpVtbl;
|
||||
LONG refCount;
|
||||
HWND hwnd;
|
||||
MwLL handle;
|
||||
};
|
||||
typedef struct _MwLLGDIDropTarget MwLLGDIDropTarget;
|
||||
|
||||
MWDECL int MwLLGDICallInit(void);
|
||||
MWDECL HCURSOR MwLLGDICreateCursor(MwCursor* image, MwCursor* mask);
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#define MwNcolumnSpan "IcolumnSpan"
|
||||
#define MwNrowSpan "IrowSpan"
|
||||
#define MwNdisabled "Idisabled"
|
||||
#define MwNacceptsDnD "IacceptsDnD"
|
||||
|
||||
#define MwNtitle "Stitle"
|
||||
#define MwNtext "Stext"
|
||||
|
|
@ -62,6 +63,8 @@
|
|||
#define MwNforeground "Sforeground"
|
||||
#define MwNsubForeground "SsubForeground"
|
||||
#define MwNtitleForeground "StitleForeground"
|
||||
#define MwNacceptedMimeType "SacceptedMimeType"
|
||||
|
||||
|
||||
#define MwNvulkanExtension "SEvulkanExtension"
|
||||
#define MwNvulkanLayer "SEvulkanLayer"
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@
|
|||
<integer name="forceInverted" common="yes" boolean="yes" />
|
||||
<integer name="isRounded" common="yes" boolean="yes" />
|
||||
<integer name="darkTheme" common="yes" boolean="yes" />
|
||||
<integer name="acceptsDnD" common="yes" boolean="yes" />
|
||||
<integer name="useMonospace" common="yes" boolean="yes" />
|
||||
<integer name="fillArea" />
|
||||
<integer name="darkThemeAutomatic" common="yes" boolean="yes" />
|
||||
|
|
@ -191,6 +192,9 @@
|
|||
<handler name="darkTheme" common="yes">
|
||||
<integer pointer="yes" />
|
||||
</handler>
|
||||
<handler name="acceptsDnD" common="yes">
|
||||
<integer pointer="yes" />
|
||||
</handler>
|
||||
</handlers>
|
||||
<enumerations>
|
||||
<enumeration name="MwDIRECTION">
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
\
|
||||
MwLLGetCursorCoord = MwLLGetCursorCoordImpl; \
|
||||
MwLLGetScreenSize = MwLLGetScreenSizeImpl; \
|
||||
MwLLSetupDragAndDrop = MwLLSetupDragAndDropImpl; \
|
||||
\
|
||||
MwLLSetDarkTheme = MwLLSetDarkThemeImpl; \
|
||||
MwLLDoModern = MwLLDoModernImpl; \
|
||||
|
|
|
|||
|
|
@ -347,6 +347,10 @@ static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
|
|||
static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
||||
}
|
||||
|
||||
static void MwLLSetupDragAndDropImpl(MwLL handle) {
|
||||
(void)handle;
|
||||
}
|
||||
|
||||
static void MwLLBeginStateChangeImpl(MwLL handle) {
|
||||
MwLLShow(handle, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1146,6 +1146,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
|||
rect->height = [screen frame].size.height;
|
||||
}
|
||||
|
||||
static void MwLLSetupDragAndDropImpl(MwLL handle) {
|
||||
(void)handle;
|
||||
}
|
||||
|
||||
static void MwLLBeginStateChangeImpl(MwLL handle) {
|
||||
MwLLShow(handle, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include <Mw/Milsko.h>
|
||||
|
||||
#include "../../external/stb_ds.h"
|
||||
|
||||
typedef struct userdata {
|
||||
MwLL ll;
|
||||
POINT min;
|
||||
|
|
@ -547,6 +549,7 @@ static int MwLLPendingImpl(MwLL handle) {
|
|||
|
||||
(void)handle;
|
||||
|
||||
|
||||
if(handle->gdi.get_clipboard || handle->gdi.get_darktheme) return 1;
|
||||
return PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE) ? 1 : 0;
|
||||
}
|
||||
|
|
@ -994,6 +997,159 @@ static void MwLLClipImpl(MwLL handle, MwRect* rect) {
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE GDIDT_QueryInterface(IDropTarget* this_, REFIID riid, void** ppv) {
|
||||
if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDropTarget)) {
|
||||
*ppv = this_;
|
||||
this_->lpVtbl->AddRef(this_);
|
||||
return S_OK;
|
||||
}
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG STDMETHODCALLTYPE GDIDT_AddRef(IDropTarget* this_) {
|
||||
MwLLGDIDropTarget* self = (MwLLGDIDropTarget*)this_;
|
||||
return InterlockedIncrement(&self->refCount);
|
||||
}
|
||||
|
||||
static ULONG STDMETHODCALLTYPE GDIDT_Release(IDropTarget* this_) {
|
||||
MwLLGDIDropTarget* self = (MwLLGDIDropTarget*)this_;
|
||||
LONG c = InterlockedDecrement(&self->refCount);
|
||||
if(c == 0) free(self);
|
||||
return c;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE GDIDT_DragEnter(IDropTarget* this_, IDataObject* pDataObj,
|
||||
DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) {
|
||||
FORMATETC fmt = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
STGMEDIUM stg;
|
||||
MwLLGDIDropTarget* self = (MwLLGDIDropTarget*)this_;
|
||||
|
||||
if(pDataObj->lpVtbl->GetData(pDataObj, &fmt, &stg) == S_OK) {
|
||||
HDROP hDrop = (HDROP)stg.hGlobal;
|
||||
UINT count = self->handle->gdi.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0);
|
||||
UINT i;
|
||||
HRESULT hr;
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
wchar_t path[MAX_PATH];
|
||||
char mime_type_normal[MAX_PATH];
|
||||
wchar_t *mime_type = NULL;
|
||||
HRESULT hr;
|
||||
int i;
|
||||
self->handle->gdi.DragQueryFileW(hDrop, i, path, MAX_PATH);
|
||||
hr = self->handle->gdi.FindMimeFromData( NULL, path, NULL, 0,
|
||||
NULL, FMFD_URLASFILENAME, &mime_type, 0x0 );
|
||||
|
||||
wprintf(L"Dragged: %s\n", mime_type);
|
||||
/* TODO: Check if the file begin dragged matches a mime type registered with MwNacceptedMimeType, and only set the effect to DROPEFFECT_COPY if so */
|
||||
*pdwEffect = DROPEFFECT_COPY;
|
||||
break;
|
||||
}
|
||||
|
||||
self->handle->gdi.ReleaseStgMedium(&stg);
|
||||
} else {
|
||||
*pdwEffect = DROPEFFECT_NONE;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE GDIDT_DragOver(IDropTarget* this_, DWORD grfKeyState,
|
||||
POINTL pt, DWORD* pdwEffect) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE GDIDT_DragLeave(IDropTarget* this_) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE GDIDT_Drop(IDropTarget* this_, IDataObject* pDataObj,
|
||||
DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) {
|
||||
FORMATETC fmt = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
STGMEDIUM stg;
|
||||
MwLLGDIDropTarget* self = (MwLLGDIDropTarget*)this_;
|
||||
|
||||
if(pDataObj->lpVtbl->GetData(pDataObj, &fmt, &stg) == S_OK) {
|
||||
HDROP hDrop = (HDROP)stg.hGlobal;
|
||||
UINT count = self->handle->gdi.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0);
|
||||
UINT i;
|
||||
HRESULT hr;
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
wchar_t path[MAX_PATH];
|
||||
char mime_type_normal[MAX_PATH];
|
||||
wchar_t *mime_type = NULL;
|
||||
HRESULT hr;
|
||||
int i;
|
||||
self->handle->gdi.DragQueryFileW(hDrop, i, path, MAX_PATH);
|
||||
hr = self->handle->gdi.FindMimeFromData( NULL, path, NULL, 0,
|
||||
NULL, FMFD_URLASFILENAME, &mime_type, 0x0 );
|
||||
|
||||
/* TODO: Check if the file begin dragged matches a mime type registered with MwNacceptedMimeType, and call a user callback */
|
||||
wprintf(L"Dropped: %s\n", mime_type);
|
||||
}
|
||||
|
||||
self->handle->gdi.ReleaseStgMedium(&stg);
|
||||
*pdwEffect = DROPEFFECT_COPY;
|
||||
} else {
|
||||
*pdwEffect = DROPEFFECT_NONE;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static IDropTargetVtbl DropTarget_Vtbl = {
|
||||
GDIDT_QueryInterface,
|
||||
GDIDT_AddRef,
|
||||
GDIDT_Release,
|
||||
GDIDT_DragEnter,
|
||||
GDIDT_DragOver,
|
||||
GDIDT_DragLeave,
|
||||
GDIDT_Drop};
|
||||
|
||||
static void MwLLSetupDragAndDropImpl(MwLL handle) {
|
||||
HRESULT hr = 0;
|
||||
|
||||
if(!(handle->gdi.shell32lib = LoadLibrary("shell32.dll"))) return;
|
||||
if(!(handle->gdi.ole32lib = LoadLibrary("ole32.dll"))) return;
|
||||
if(!(handle->gdi.urlmonlib = LoadLibrary("Urlmon.dll"))) return;
|
||||
|
||||
#define SHELL32_FUNC(x) if(!(handle->gdi.x = (void*)GetProcAddress(handle->gdi.shell32lib, #x))) {printf(#x "not found, drag and drop will not be supported"); return;}
|
||||
#define OLE32_FUNC(x) if(!(handle->gdi.x = (void*)GetProcAddress(handle->gdi.ole32lib, #x))) {printf(#x "not found, drag and drop will not be supported"); return;}
|
||||
#define URLMON_FUNC(x) if(!(handle->gdi.x = (void*)GetProcAddress(handle->gdi.urlmonlib, #x))) {printf(#x "not found, drag and drop will not be supported"); return;}
|
||||
|
||||
SHELL32_FUNC(DragQueryFileW);
|
||||
OLE32_FUNC(ReleaseStgMedium);
|
||||
OLE32_FUNC(RegisterDragDrop);
|
||||
URLMON_FUNC(FindMimeFromData);
|
||||
|
||||
CoInitialize(NULL);
|
||||
hr = OleInitialize(NULL);
|
||||
if(!SUCCEEDED(hr)) {
|
||||
if(hr == RPC_E_CHANGED_MODE) {
|
||||
CoUninitialize();
|
||||
hr = OleInitialize(NULL);
|
||||
CoInitialize(NULL);
|
||||
} else {
|
||||
printf("OleInitialize failed; %08lx\n", hr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
handle->gdi.dropTarget = (MwLLGDIDropTarget*)malloc(sizeof(MwLLGDIDropTarget));
|
||||
handle->gdi.dropTarget->lpVtbl = &DropTarget_Vtbl;
|
||||
handle->gdi.dropTarget->refCount = 1;
|
||||
handle->gdi.dropTarget->hwnd = handle->gdi.hWnd;
|
||||
handle->gdi.dropTarget->handle = handle;
|
||||
|
||||
hr = handle->gdi.RegisterDragDrop(handle->gdi.hWnd, (IDropTarget*)handle->gdi.dropTarget);
|
||||
if(!SUCCEEDED(hr)) {
|
||||
printf("RegisterDragDrop failed; %08lx\n", hr);
|
||||
return;
|
||||
}
|
||||
printf("dnd setup\n");
|
||||
}
|
||||
|
||||
static int MwLLGDICallInitImpl(void) {
|
||||
void* ntdll;
|
||||
|
||||
|
|
|
|||
|
|
@ -879,6 +879,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
|||
delete screen;
|
||||
}
|
||||
|
||||
static void MwLLSetupDragAndDropImpl(MwLL handle) {
|
||||
(void)handle;
|
||||
}
|
||||
|
||||
static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) {
|
||||
(void)handle;
|
||||
(void)toggle;
|
||||
|
|
|
|||
|
|
@ -1779,6 +1779,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
|||
rect->height = handle->wayland.mh;
|
||||
}
|
||||
|
||||
static void MwLLSetupDragAndDropImpl(MwLL handle) {
|
||||
(void)handle;
|
||||
}
|
||||
|
||||
static void MwLLBeginStateChangeImpl(MwLL handle) {
|
||||
(void)handle;
|
||||
/* no-op */
|
||||
|
|
|
|||
|
|
@ -1361,6 +1361,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
|||
rect->height = xwa.height;
|
||||
}
|
||||
|
||||
static void MwLLSetupDragAndDropImpl(MwLL handle) {
|
||||
(void)handle;
|
||||
}
|
||||
|
||||
static void MwLLBeginStateChangeImpl(MwLL handle) {
|
||||
MwLLShow(handle, 0);
|
||||
}
|
||||
|
|
|
|||
10
src/core.c
10
src/core.c
|
|
@ -658,6 +658,10 @@ void MwSetInteger(MwWidget handle, const char* key, int n) {
|
|||
|
||||
if(h->lowlevel != NULL) MwLLSetDarkTheme(h->lowlevel, n);
|
||||
}
|
||||
|
||||
if(strcmp(key, MwNacceptsDnD) == 0) {
|
||||
if(handle->lowlevel != NULL) MwLLSetupDragAndDrop(handle->lowlevel);
|
||||
}
|
||||
}
|
||||
|
||||
void MwSetText(MwWidget handle, const char* key, const char* value) {
|
||||
|
|
@ -692,6 +696,12 @@ void MwSetText(MwWidget handle, const char* key, const char* value) {
|
|||
if(strcmp(key, MwNbackground) == 0 || strcmp(key, MwNforeground) == 0 || strcmp(key, MwNsubBackground) == 0 || strcmp(key, MwNsubForeground) == 0) {
|
||||
MwForceRender(handle);
|
||||
}
|
||||
|
||||
if(strcmp(key, MwNacceptedMimeType) == 0) {
|
||||
if(handle->lowlevel != NULL) {
|
||||
arrput(handle->lowlevel->common.known_mime_types, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MwSetVoid(MwWidget handle, const char* key, void* value) {
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ void (*MwLLGetClipboard)(MwLL, int clipboard_type) = NULL;
|
|||
|
||||
void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point) = NULL;
|
||||
void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect) = NULL;
|
||||
|
||||
void (*MwLLSetupDragAndDrop)(MwLL handle) = NULL;
|
||||
void (*MwLLSetDarkTheme)(MwLL handle, int toggle) = NULL;
|
||||
|
||||
MwBool (*MwLLDoModern)(MwLL handle) = NULL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue