mirror of
https://gitlab.com/kelteseth/ScreenPlay.git
synced 2024-11-25 20:22:39 +01:00
Add working Godot Wallpaper
This commit is contained in:
parent
7ecbd2e8d1
commit
c70fa6224a
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@ -4,6 +4,7 @@
|
|||||||
"delgan.qml-format",
|
"delgan.qml-format",
|
||||||
"ms-vscode.cpptools-extension-pack",
|
"ms-vscode.cpptools-extension-pack",
|
||||||
"ms-vscode.cmake-tools",
|
"ms-vscode.cmake-tools",
|
||||||
"seanwu.vscode-qt-for-python"
|
"seanwu.vscode-qt-for-python",
|
||||||
|
"josetr.cmake-language-support-vscode"
|
||||||
]
|
]
|
||||||
}
|
}
|
2
Content/wallpaper_godot_fjord/.gitattributes
vendored
Normal file
2
Content/wallpaper_godot_fjord/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Normalize EOL for all files that Git considers text files.
|
||||||
|
* text=auto eol=lf
|
2
Content/wallpaper_godot_fjord/.gitignore
vendored
Normal file
2
Content/wallpaper_godot_fjord/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Godot 4+ specific ignores
|
||||||
|
.godot/
|
16
Content/wallpaper_godot_fjord/Path3D.gd
Normal file
16
Content/wallpaper_godot_fjord/Path3D.gd
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
extends Path3D
|
||||||
|
|
||||||
|
# Reference to the PathFollow node
|
||||||
|
@onready var path_follow = $PathFollow3D
|
||||||
|
|
||||||
|
# Speed of the movement along the path
|
||||||
|
var speed = 0.4
|
||||||
|
|
||||||
|
func _process(delta):
|
||||||
|
# Update the offset to move the object along the path
|
||||||
|
path_follow.progress += speed * delta
|
||||||
|
print(path_follow.progress)
|
||||||
|
|
||||||
|
# Loop back to the start if we've reached the end of the path
|
||||||
|
if path_follow.progress > 10:
|
||||||
|
path_follow.progress = 0.0
|
61
Content/wallpaper_godot_fjord/export_presets.cfg
Normal file
61
Content/wallpaper_godot_fjord/export_presets.cfg
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
[preset.0]
|
||||||
|
|
||||||
|
name="Windows Desktop"
|
||||||
|
platform="Windows Desktop"
|
||||||
|
runnable=true
|
||||||
|
dedicated_server=false
|
||||||
|
custom_features=""
|
||||||
|
export_filter="all_resources"
|
||||||
|
include_filter=""
|
||||||
|
exclude_filter=""
|
||||||
|
export_path=""
|
||||||
|
encryption_include_filters=""
|
||||||
|
encryption_exclude_filters=""
|
||||||
|
encrypt_pck=false
|
||||||
|
encrypt_directory=false
|
||||||
|
|
||||||
|
[preset.0.options]
|
||||||
|
|
||||||
|
custom_template/debug=""
|
||||||
|
custom_template/release=""
|
||||||
|
debug/export_console_wrapper=1
|
||||||
|
binary_format/embed_pck=false
|
||||||
|
texture_format/bptc=true
|
||||||
|
texture_format/s3tc=true
|
||||||
|
texture_format/etc=false
|
||||||
|
texture_format/etc2=false
|
||||||
|
binary_format/architecture="x86_64"
|
||||||
|
codesign/enable=false
|
||||||
|
codesign/timestamp=true
|
||||||
|
codesign/timestamp_server_url=""
|
||||||
|
codesign/digest_algorithm=1
|
||||||
|
codesign/description=""
|
||||||
|
codesign/custom_options=PackedStringArray()
|
||||||
|
application/modify_resources=true
|
||||||
|
application/icon=""
|
||||||
|
application/console_wrapper_icon=""
|
||||||
|
application/icon_interpolation=4
|
||||||
|
application/file_version=""
|
||||||
|
application/product_version=""
|
||||||
|
application/company_name=""
|
||||||
|
application/product_name=""
|
||||||
|
application/file_description=""
|
||||||
|
application/copyright=""
|
||||||
|
application/trademarks=""
|
||||||
|
ssh_remote_deploy/enabled=false
|
||||||
|
ssh_remote_deploy/host="user@host_ip"
|
||||||
|
ssh_remote_deploy/port="22"
|
||||||
|
ssh_remote_deploy/extra_args_ssh=""
|
||||||
|
ssh_remote_deploy/extra_args_scp=""
|
||||||
|
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
|
||||||
|
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
|
||||||
|
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
|
||||||
|
$settings = New-ScheduledTaskSettingsSet
|
||||||
|
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
|
||||||
|
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
|
||||||
|
Start-ScheduledTask -TaskName godot_remote_debug
|
||||||
|
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
|
||||||
|
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
|
||||||
|
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
|
||||||
|
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
|
||||||
|
Remove-Item -Recurse -Force '{temp_dir}'"
|
1
Content/wallpaper_godot_fjord/icon.svg
Normal file
1
Content/wallpaper_godot_fjord/icon.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="124" height="124" rx="14" fill="#363d52" stroke="#212532" stroke-width="4"/><g transform="scale(.101) translate(122 122)"><g fill="#fff"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 813 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H447l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c3 34 55 34 58 0v-86c-3-34-55-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></g></svg>
|
After Width: | Height: | Size: 950 B |
37
Content/wallpaper_godot_fjord/icon.svg.import
Normal file
37
Content/wallpaper_godot_fjord/icon.svg.import
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://boex5vkldqpl5"
|
||||||
|
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://icon.svg"
|
||||||
|
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=1.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
20
Content/wallpaper_godot_fjord/project.godot
Normal file
20
Content/wallpaper_godot_fjord/project.godot
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
; Engine configuration file.
|
||||||
|
; It's best edited using the editor UI and not directly,
|
||||||
|
; since the parameters that go here are not all obvious.
|
||||||
|
;
|
||||||
|
; Format:
|
||||||
|
; [section] ; section goes between []
|
||||||
|
; param=value ; assign values to parameters
|
||||||
|
|
||||||
|
config_version=5
|
||||||
|
|
||||||
|
[application]
|
||||||
|
|
||||||
|
config/name="Fjord"
|
||||||
|
run/main_scene="res://wallpaper.tscn"
|
||||||
|
config/features=PackedStringArray("4.1", "Mobile")
|
||||||
|
config/icon="res://icon.svg"
|
||||||
|
|
||||||
|
[rendering]
|
||||||
|
|
||||||
|
renderer/rendering_method="mobile"
|
36
Content/wallpaper_godot_fjord/wallpaper.tscn
Normal file
36
Content/wallpaper_godot_fjord/wallpaper.tscn
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://cxlfu6y6b3l5o"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://Path3D.gd" id="1_76sq1"]
|
||||||
|
|
||||||
|
[sub_resource type="Curve3D" id="Curve3D_8adw4"]
|
||||||
|
_data = {
|
||||||
|
"points": PackedVector3Array(0, 0, 0, 0, 0, 0, -0.820513, 0.281883, 0.141011, 0, 0, 0, 0, 0, 0, -0.1735, 0.399895, -0.280881, 0, 0, 0, 0, 0, 0, 0.510953, 0.524736, -0.727188, 0, 0, 0, 0, 0, 0, 2.26923, 2.38419e-07, -1.10178, 0, 0, 0, 0, 0, 0, 2.53764, -0.832639, -0.471864, 0, 0, 0, 0, 0, 0, 0.836093, -1.07116, 0.572063, 0, 0, 0, 0, 0, 0, -0.416085, -0.732896, 0.871186, 0, 0, 0, 0, 0, 0, -0.809435, -0.0867326, 0.472196),
|
||||||
|
"tilts": PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
point_count = 8
|
||||||
|
|
||||||
|
[node name="Node3D" type="Node3D"]
|
||||||
|
|
||||||
|
[node name="Camera3D" type="Camera3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.04825, 4.0185)
|
||||||
|
|
||||||
|
[node name="CSGBox3D" type="CSGBox3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.093655, 0)
|
||||||
|
size = Vector3(5.24075, 0.0764128, 3.72353)
|
||||||
|
|
||||||
|
[node name="Path3D" type="Path3D" parent="."]
|
||||||
|
curve = SubResource("Curve3D_8adw4")
|
||||||
|
script = ExtResource("1_76sq1")
|
||||||
|
|
||||||
|
[node name="PathFollow3D" type="PathFollow3D" parent="Path3D"]
|
||||||
|
transform = Transform3D(0.546201, -0.126512, -0.828045, 7.45058e-09, 0.988529, -0.151031, 0.837654, 0.0824935, 0.539936, -0.820513, 0.281883, 0.141011)
|
||||||
|
|
||||||
|
[node name="OmniLight3D" type="OmniLight3D" parent="Path3D/PathFollow3D"]
|
||||||
|
light_color = Color(0.921569, 0.52549, 0.32549, 1)
|
||||||
|
|
||||||
|
[node name="Label3D" type="Label3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.391226, -1.25994)
|
||||||
|
shaded = true
|
||||||
|
text = "GODO WALLPAPER"
|
||||||
|
font_size = 126
|
||||||
|
outline_size = 42
|
@ -38,6 +38,7 @@ set(SOURCES ${SOURCES} main.cpp src/basewindow.cpp)
|
|||||||
set(HEADER ${HEADER} src/basewindow.h)
|
set(HEADER ${HEADER} src/basewindow.h)
|
||||||
|
|
||||||
set(QML
|
set(QML
|
||||||
|
|
||||||
# cmake-format: sort
|
# cmake-format: sort
|
||||||
qml/GifWallpaper.qml
|
qml/GifWallpaper.qml
|
||||||
qml/MultimediaView.qml
|
qml/MultimediaView.qml
|
||||||
@ -48,6 +49,17 @@ set(QML
|
|||||||
|
|
||||||
set(RESOURCES dot.png qtquickcontrols2.conf index.html)
|
set(RESOURCES dot.png qtquickcontrols2.conf index.html)
|
||||||
|
|
||||||
|
set(LIB_SOURCES ${SOURCES} src/basewindow.cpp)
|
||||||
|
set(LIB_HEADER ${HEADER} src/basewindow.h)
|
||||||
|
|
||||||
|
add_library(ScreenPlayWallpaperLib STATIC src/windowshook.cpp src/windowshook.h)
|
||||||
|
target_include_directories(ScreenPlayWallpaperLib PUBLIC src)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
# Used for query windows monitor data
|
||||||
|
target_link_libraries(ScreenPlayWallpaperLib PUBLIC shcore.lib)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADER})
|
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADER})
|
||||||
|
|
||||||
qt_add_qml_module(
|
qt_add_qml_module(
|
||||||
@ -68,6 +80,7 @@ qt_add_qml_module(
|
|||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
${PROJECT_NAME}
|
${PROJECT_NAME}
|
||||||
PRIVATE ScreenPlaySDK
|
PRIVATE ScreenPlaySDK
|
||||||
|
ScreenPlayWallpaperLib
|
||||||
ScreenPlayUtil
|
ScreenPlayUtil
|
||||||
ScreenPlayWeatherplugin
|
ScreenPlayWeatherplugin
|
||||||
Qt6::Quick
|
Qt6::Quick
|
||||||
@ -79,6 +92,7 @@ target_link_libraries(
|
|||||||
Qt6::Multimedia
|
Qt6::Multimedia
|
||||||
Qt6::WebEngineCore
|
Qt6::WebEngineCore
|
||||||
Qt6::WebEngineQuick)
|
Qt6::WebEngineQuick)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE ScreenPlaySysInfoplugin)
|
target_link_libraries(${PROJECT_NAME} PRIVATE ScreenPlaySysInfoplugin)
|
||||||
elseif(UNIX AND NOT APPLE)
|
elseif(UNIX AND NOT APPLE)
|
||||||
@ -92,6 +106,7 @@ endif()
|
|||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE "-framework Cocoa")
|
target_link_libraries(${PROJECT_NAME} PRIVATE "-framework Cocoa")
|
||||||
|
|
||||||
if(NOT OSX_BUNDLE)
|
if(NOT OSX_BUNDLE)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET ${PROJECT_NAME}
|
TARGET ${PROJECT_NAME}
|
||||||
|
@ -27,11 +27,9 @@ if ( APPLE )
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Main project information
|
# Main project information
|
||||||
project( GDExtensionTemplate
|
project(ScreenPlayGodotWallpaper
|
||||||
LANGUAGES
|
LANGUAGES
|
||||||
CXX
|
CXX
|
||||||
VERSION
|
|
||||||
0.1.0
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create our library
|
# Create our library
|
||||||
@ -45,6 +43,7 @@ target_compile_features( ${PROJECT_NAME}
|
|||||||
# LIB_ARCH is the architecture being built. It is set to the build system's architecture.
|
# LIB_ARCH is the architecture being built. It is set to the build system's architecture.
|
||||||
# For macOS, we build a universal library (both arm64 and x86_64).
|
# For macOS, we build a universal library (both arm64 and x86_64).
|
||||||
set(LIB_ARCH ${CMAKE_SYSTEM_PROCESSOR})
|
set(LIB_ARCH ${CMAKE_SYSTEM_PROCESSOR})
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set(LIB_ARCH "universal")
|
set(LIB_ARCH "universal")
|
||||||
endif()
|
endif()
|
||||||
@ -58,13 +57,15 @@ message( STATUS "Building ${PROJECT_NAME} for ${LIB_ARCH} on ${CMAKE_SYSTEM_NAME
|
|||||||
|
|
||||||
# BUILD_OUTPUT_DIR is where we put the resulting library (in the build directory)
|
# BUILD_OUTPUT_DIR is where we put the resulting library (in the build directory)
|
||||||
set(BUILD_OUTPUT_DIR "${PROJECT_BINARY_DIR}/${PROJECT_NAME}/")
|
set(BUILD_OUTPUT_DIR "${PROJECT_BINARY_DIR}/${PROJECT_NAME}/")
|
||||||
|
set(OUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../ScreenPlayGodot/${PROJECT_NAME}/)
|
||||||
|
|
||||||
|
# Compile directly into our Godot project
|
||||||
set_target_properties(${PROJECT_NAME}
|
set_target_properties(${PROJECT_NAME}
|
||||||
PROPERTIES
|
PROPERTIES
|
||||||
CXX_VISIBILITY_PRESET hidden
|
CXX_VISIBILITY_PRESET hidden
|
||||||
VISIBILITY_INLINES_HIDDEN true
|
VISIBILITY_INLINES_HIDDEN true
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${BUILD_OUTPUT_DIR}/${LIB_DIR}"
|
RUNTIME_OUTPUT_DIRECTORY "${OUT_PATH}/${LIB_DIR}"
|
||||||
LIBRARY_OUTPUT_DIRECTORY "${BUILD_OUTPUT_DIR}/${LIB_DIR}"
|
LIBRARY_OUTPUT_DIRECTORY "${OUT_PATH}/${LIB_DIR}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
|
if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
|
||||||
@ -125,4 +126,5 @@ set_target_properties( godot-cpp
|
|||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
godot-cpp
|
godot-cpp
|
||||||
|
ScreenPlayWallpaperLib
|
||||||
)
|
)
|
||||||
|
@ -2,10 +2,8 @@
|
|||||||
|
|
||||||
target_sources(${PROJECT_NAME}
|
target_sources(${PROJECT_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
ScreenPlayWallpaper.h
|
ScreenPlayGodotWallpaper.h
|
||||||
ScreenPlayWallpaper.cpp
|
ScreenPlayGodotWallpaper.cpp
|
||||||
GDExtensionTemplate.h
|
|
||||||
GDExtensionTemplate.cpp
|
|
||||||
RegisterExtension.cpp
|
RegisterExtension.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
// SPDX-License-Identifier: Unlicense
|
|
||||||
|
|
||||||
#include "godot_cpp/core/class_db.hpp"
|
|
||||||
|
|
||||||
#include "GDExtensionTemplate.h"
|
|
||||||
#include "Version.h"
|
|
||||||
|
|
||||||
/// @file
|
|
||||||
/// GDExtensionTemplate example implementation.
|
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief Get the version string for this extension.
|
|
||||||
|
|
||||||
@details
|
|
||||||
The version string is generated by cmake using src/Version.h.in.
|
|
||||||
|
|
||||||
It uses the form "<project name> <last tag>-<# commits since last tag>-<short commit hash>".
|
|
||||||
If there are no commits since the last tag, only the tag is shown.
|
|
||||||
|
|
||||||
@return The version string (e.g. "Foo v1.2.3-gdedbd01").
|
|
||||||
*/
|
|
||||||
godot::String GDExtensionTemplate::version()
|
|
||||||
{
|
|
||||||
return VersionInfo::VERSION_STR.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Bind our methods so GDScript can access them.
|
|
||||||
void GDExtensionTemplate::_bind_methods()
|
|
||||||
{
|
|
||||||
godot::ClassDB::bind_static_method( "GDExtensionTemplate", godot::D_METHOD( "version" ),
|
|
||||||
&GDExtensionTemplate::version );
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
// SPDX-License-Identifier: Unlicense
|
|
||||||
|
|
||||||
#include "godot_cpp/classes/object.hpp"
|
|
||||||
|
|
||||||
namespace godot
|
|
||||||
{
|
|
||||||
class ClassDB;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GDExtensionTemplate : public godot::Object
|
|
||||||
{
|
|
||||||
GDCLASS( GDExtensionTemplate, godot::Object )
|
|
||||||
|
|
||||||
public:
|
|
||||||
static godot::String version();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void _bind_methods();
|
|
||||||
};
|
|
@ -6,8 +6,7 @@
|
|||||||
#include "godot_cpp/core/defs.hpp"
|
#include "godot_cpp/core/defs.hpp"
|
||||||
#include "godot_cpp/godot.hpp"
|
#include "godot_cpp/godot.hpp"
|
||||||
|
|
||||||
#include "GDExtensionTemplate.h"
|
#include "ScreenPlayGodotWallpaper.h"
|
||||||
#include "ScreenPlayWallpaper.h"
|
|
||||||
|
|
||||||
/// @file
|
/// @file
|
||||||
/// Register our classes with Godot.
|
/// Register our classes with Godot.
|
||||||
@ -24,13 +23,7 @@ void initializeExtension(godot::ModuleInitializationLevel p_level)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
godot::ClassDB::register_class<ScreenPlayWallpaper>();
|
godot::ClassDB::register_class<ScreenPlayGodotWallpaper>();
|
||||||
godot::ClassDB::register_class<ExampleMin>();
|
|
||||||
godot::ClassDB::register_class<Example>();
|
|
||||||
godot::ClassDB::register_class<ExampleVirtual>(true);
|
|
||||||
godot::ClassDB::register_abstract_class<ExampleAbstract>();
|
|
||||||
|
|
||||||
godot::ClassDB::register_class<GDExtensionTemplate>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Called by Godot to let us do any cleanup.
|
/// @brief Called by Godot to let us do any cleanup.
|
||||||
|
@ -0,0 +1,117 @@
|
|||||||
|
// Copied from godot-cpp/test/src and modified.
|
||||||
|
|
||||||
|
#include "ScreenPlayGodotWallpaper.h"
|
||||||
|
#include "godot_cpp/classes/display_server.hpp"
|
||||||
|
#include "godot_cpp/classes/global_constants.hpp"
|
||||||
|
#include "godot_cpp/classes/label.hpp"
|
||||||
|
#include "godot_cpp/classes/os.hpp"
|
||||||
|
#include "godot_cpp/core/class_db.hpp"
|
||||||
|
#include "godot_cpp/variant/utility_functions.hpp"
|
||||||
|
|
||||||
|
//// ScreenPlayWallpaper
|
||||||
|
|
||||||
|
int ScreenPlayGodotWallpaper::sInstanceCount = 0;
|
||||||
|
int ScreenPlayGodotWallpaper::sLastID = 0;
|
||||||
|
|
||||||
|
ScreenPlayGodotWallpaper::ScreenPlayGodotWallpaper()
|
||||||
|
{
|
||||||
|
mID = ++sLastID;
|
||||||
|
sInstanceCount++;
|
||||||
|
|
||||||
|
godot::UtilityFunctions::print(
|
||||||
|
"ScreenPlayWallpaper ", godot::itos(mID),
|
||||||
|
" created, current instance count: ", godot::itos(sInstanceCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenPlayGodotWallpaper::~ScreenPlayGodotWallpaper()
|
||||||
|
{
|
||||||
|
sInstanceCount--;
|
||||||
|
godot::UtilityFunctions::print(
|
||||||
|
"ScreenPlayWallpaper ", godot::itos(mID),
|
||||||
|
" destroyed, current instance count: ", godot::itos(sInstanceCount));
|
||||||
|
|
||||||
|
// Somehow this gets called at editor startup
|
||||||
|
// so just return if not initialized
|
||||||
|
if (!m_hook)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ShowWindow(m_hook->windowHandle, SW_HIDE);
|
||||||
|
|
||||||
|
// Force refresh so that we display the regular
|
||||||
|
// desktop wallpaper again
|
||||||
|
ShowWindow(m_hook->windowHandleWorker, SW_HIDE);
|
||||||
|
ShowWindow(m_hook->windowHandleWorker, SW_SHOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScreenPlayGodotWallpaper::configureWindowGeometry()
|
||||||
|
{
|
||||||
|
if (!m_hook->searchWorkerWindowToParentTo()) {
|
||||||
|
godot::UtilityFunctions::print("No worker window found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT rect {};
|
||||||
|
if (!GetWindowRect(m_hook->windowHandleWorker, &rect)) {
|
||||||
|
godot::UtilityFunctions::print("Unable to get WindoeRect from worker");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Windows coordante system begins at 0x0 at the
|
||||||
|
// main monitors upper left and not at the most left top monitor.
|
||||||
|
// This can be easily read from the worker window.
|
||||||
|
m_hook->zeroPoint = { std::abs(rect.left), std::abs(rect.top) };
|
||||||
|
|
||||||
|
// WARNING: Setting Window flags must be called *here*!
|
||||||
|
SetWindowLongPtr(m_hook->windowHandle, GWL_EXSTYLE, WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT);
|
||||||
|
SetWindowLongPtr(m_hook->windowHandle, GWL_STYLE, WS_POPUPWINDOW);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool ScreenPlayGodotWallpaper::init(int activeScreen)
|
||||||
|
{
|
||||||
|
auto* displayServer = godot::DisplayServer::get_singleton();
|
||||||
|
int64_t handle_int = displayServer->window_get_native_handle(godot::DisplayServer::HandleType::WINDOW_HANDLE, activeScreen);
|
||||||
|
HWND hwnd = reinterpret_cast<HWND>(static_cast<intptr_t>(handle_int));
|
||||||
|
m_hook = std::make_unique<WindowsHook>();
|
||||||
|
m_hook->windowHandle = hwnd;
|
||||||
|
if (!configureWindowGeometry()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ShowWindow(m_hook->windowHandle, SW_HIDE);
|
||||||
|
|
||||||
|
const int borderWidth = 2;
|
||||||
|
const float scaling = m_hook->getScaling(activeScreen); // Assuming getScaling is your own function
|
||||||
|
const int borderOffset = -1;
|
||||||
|
|
||||||
|
WinMonitorStats monitors; // Assuming this is your own function
|
||||||
|
const int width = static_cast<int>(std::abs(monitors.rcMonitors[activeScreen].right - monitors.rcMonitors[activeScreen].left) / scaling) + borderWidth;
|
||||||
|
const int height = static_cast<int>(std::abs(monitors.rcMonitors[activeScreen].top - monitors.rcMonitors[activeScreen].bottom) / scaling) + borderWidth;
|
||||||
|
|
||||||
|
const int x = monitors.rcMonitors[activeScreen].left + m_hook->zeroPoint.x + borderOffset; // Assuming m_zeroPoint is a POINT struct
|
||||||
|
const int y = monitors.rcMonitors[activeScreen].top + m_hook->zeroPoint.y + borderOffset;
|
||||||
|
|
||||||
|
godot::String output = "Setup window activeScreen: " + godot::itos(activeScreen) + " scaling: " + godot::rtos(scaling) + " x: " + godot::itos(x) + " y: " + godot::itos(y) + " width: " + godot::itos(width) + " height: " + godot::itos(height);
|
||||||
|
godot::UtilityFunctions::print(output);
|
||||||
|
|
||||||
|
// Must be called twice for some reason when window has scaling...
|
||||||
|
if (!SetWindowPos(m_hook->windowHandle, nullptr, x, y, width, height, SWP_HIDEWINDOW)) {
|
||||||
|
godot::UtilityFunctions::print("Could not set window pos");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!SetWindowPos(m_hook->windowHandle, nullptr, x, y, width, height, SWP_HIDEWINDOW)) {
|
||||||
|
godot::UtilityFunctions::print("Could not set window pos 2");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SetParent(m_hook->windowHandle, m_hook->windowHandleWorker) == nullptr) {
|
||||||
|
godot::UtilityFunctions::print("Could not attach to parent window");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
displayServer->window_set_size(godot::Vector2((real_t)width, (real_t)height));
|
||||||
|
ShowWindow(m_hook->windowHandle, SW_SHOW);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenPlayGodotWallpaper::_bind_methods()
|
||||||
|
{
|
||||||
|
godot::ClassDB::bind_method(godot::D_METHOD("init"), &ScreenPlayGodotWallpaper::init);
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
// Copied from godot-cpp/test/src and modified.
|
||||||
|
|
||||||
|
#include "godot_cpp/classes/control.hpp"
|
||||||
|
#include "godot_cpp/classes/global_constants.hpp"
|
||||||
|
#include "godot_cpp/classes/viewport.hpp"
|
||||||
|
#include "godot_cpp/core/binder_common.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "ScreenPlayGodotWallpaper.h"
|
||||||
|
#include "windowshook.h"
|
||||||
|
|
||||||
|
class ScreenPlayGodotWallpaper : public godot::Node {
|
||||||
|
GDCLASS(ScreenPlayGodotWallpaper, Node)
|
||||||
|
|
||||||
|
public:
|
||||||
|
ScreenPlayGodotWallpaper();
|
||||||
|
~ScreenPlayGodotWallpaper() override;
|
||||||
|
|
||||||
|
bool init(int activeScreen);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool configureWindowGeometry();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int sInstanceCount;
|
||||||
|
static int sLastID;
|
||||||
|
|
||||||
|
int mID;
|
||||||
|
std::unique_ptr<WindowsHook> m_hook;
|
||||||
|
};
|
@ -1,475 +0,0 @@
|
|||||||
// Copied from godot-cpp/test/src and modified.
|
|
||||||
|
|
||||||
#include "godot_cpp/classes/global_constants.hpp"
|
|
||||||
#include "godot_cpp/classes/label.hpp"
|
|
||||||
#include "godot_cpp/core/class_db.hpp"
|
|
||||||
#include "godot_cpp/variant/utility_functions.hpp"
|
|
||||||
|
|
||||||
#include "ScreenPlayWallpaper.h"
|
|
||||||
|
|
||||||
// Used to mark unused parameters to indicate intent and suppress warnings.
|
|
||||||
#define UNUSED(expr) (void)(expr)
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
constexpr int MAGIC_NUMBER = 42;
|
|
||||||
}
|
|
||||||
|
|
||||||
//// ScreenPlayWallpaper
|
|
||||||
|
|
||||||
int ScreenPlayWallpaper::sInstanceCount = 0;
|
|
||||||
int ScreenPlayWallpaper::sLastID = 0;
|
|
||||||
|
|
||||||
ScreenPlayWallpaper::ScreenPlayWallpaper()
|
|
||||||
{
|
|
||||||
mID = ++sLastID;
|
|
||||||
sInstanceCount++;
|
|
||||||
|
|
||||||
godot::UtilityFunctions::print(
|
|
||||||
"ScreenPlayWallpaper ", godot::itos(mID),
|
|
||||||
" created, current instance count: ", godot::itos(sInstanceCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
ScreenPlayWallpaper::~ScreenPlayWallpaper()
|
|
||||||
{
|
|
||||||
sInstanceCount--;
|
|
||||||
godot::UtilityFunctions::print(
|
|
||||||
"ScreenPlayWallpaper ", godot::itos(mID),
|
|
||||||
" destroyed, current instance count: ", godot::itos(sInstanceCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
int ScreenPlayWallpaper::getID() const
|
|
||||||
{
|
|
||||||
return mID;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenPlayWallpaper::_bind_methods()
|
|
||||||
{
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("get_id"), &ScreenPlayWallpaper::getID);
|
|
||||||
}
|
|
||||||
|
|
||||||
//// ExampleMin
|
|
||||||
|
|
||||||
void ExampleMin::_bind_methods()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//// Example
|
|
||||||
|
|
||||||
Example::Example()
|
|
||||||
{
|
|
||||||
godot::UtilityFunctions::print("Constructor.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Example::~Example()
|
|
||||||
{
|
|
||||||
godot::UtilityFunctions::print("Destructor.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Methods.
|
|
||||||
void Example::simpleFunc()
|
|
||||||
{
|
|
||||||
godot::UtilityFunctions::print(" Simple func called.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::simpleConstFunc() const
|
|
||||||
{
|
|
||||||
godot::UtilityFunctions::print(" Simple const func called.");
|
|
||||||
}
|
|
||||||
|
|
||||||
godot::String Example::returnSomething(const godot::String& inBase)
|
|
||||||
{
|
|
||||||
godot::UtilityFunctions::print(" Return something called.");
|
|
||||||
|
|
||||||
return inBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
godot::Viewport* Example::returnSomethingConst() const
|
|
||||||
{
|
|
||||||
godot::UtilityFunctions::print(" Return something const called.");
|
|
||||||
|
|
||||||
if (is_inside_tree()) {
|
|
||||||
godot::Viewport* result = get_viewport();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
godot::Ref<ScreenPlayWallpaper> Example::returnEmptyRef() const
|
|
||||||
{
|
|
||||||
godot::Ref<ScreenPlayWallpaper> ref;
|
|
||||||
return ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScreenPlayWallpaper* Example::returnExtendedRef() const
|
|
||||||
{
|
|
||||||
// You can instance and return a refcounted object like this, but keep in mind that refcounting
|
|
||||||
// starts with the returned object and it will be destroyed when all references are destroyed.
|
|
||||||
// If you store this pointer you run the risk of having a pointer to a destroyed object.
|
|
||||||
return memnew(ScreenPlayWallpaper());
|
|
||||||
}
|
|
||||||
|
|
||||||
godot::Ref<ScreenPlayWallpaper> Example::extendedRefChecks(godot::Ref<ScreenPlayWallpaper> inRef) const
|
|
||||||
{
|
|
||||||
// This is the preferred way of instancing and returning a refcounted object:
|
|
||||||
godot::Ref<ScreenPlayWallpaper> ref;
|
|
||||||
ref.instantiate();
|
|
||||||
|
|
||||||
godot::UtilityFunctions::print(
|
|
||||||
" Example ref checks called with value: ", inRef->get_instance_id(),
|
|
||||||
", returning value: ", ref->get_instance_id());
|
|
||||||
|
|
||||||
return ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
godot::Variant Example::varargsFunc(const godot::Variant** inArgs, GDExtensionInt inArgCount,
|
|
||||||
GDExtensionCallError& outError)
|
|
||||||
{
|
|
||||||
UNUSED(inArgs);
|
|
||||||
UNUSED(outError);
|
|
||||||
|
|
||||||
godot::UtilityFunctions::print(" Varargs (Variant return) called with ",
|
|
||||||
godot::String::num_int64(inArgCount), " arguments");
|
|
||||||
|
|
||||||
return inArgCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Example::varargsFuncNonVoidReturn(const godot::Variant** inArgs, GDExtensionInt inArgCount,
|
|
||||||
GDExtensionCallError& outError)
|
|
||||||
{
|
|
||||||
UNUSED(inArgs);
|
|
||||||
UNUSED(outError);
|
|
||||||
|
|
||||||
godot::UtilityFunctions::print(" Varargs (int return) called with ",
|
|
||||||
godot::String::num_int64(inArgCount), " arguments");
|
|
||||||
|
|
||||||
return MAGIC_NUMBER;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::varargsFuncVoidReturn(const godot::Variant** inArgs, GDExtensionInt inArgCount,
|
|
||||||
GDExtensionCallError& outError)
|
|
||||||
{
|
|
||||||
UNUSED(inArgs);
|
|
||||||
UNUSED(outError);
|
|
||||||
|
|
||||||
godot::UtilityFunctions::print(" Varargs (no return) called with ",
|
|
||||||
godot::String::num_int64(inArgCount), " arguments");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::emitCustomSignal(const godot::String& inName, int inValue)
|
|
||||||
{
|
|
||||||
emit_signal("custom_signal", inName, inValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Example::defArgs(int inA, int inB) const
|
|
||||||
{
|
|
||||||
return inA + inB;
|
|
||||||
}
|
|
||||||
|
|
||||||
godot::Array Example::testArray() const
|
|
||||||
{
|
|
||||||
godot::Array arr;
|
|
||||||
|
|
||||||
arr.resize(2);
|
|
||||||
arr[0] = godot::Variant(1);
|
|
||||||
arr[1] = godot::Variant(2);
|
|
||||||
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::testTypedArrayArg(const godot::TypedArray<int64_t>& inArray)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < inArray.size(); ++i) {
|
|
||||||
godot::UtilityFunctions::print(inArray[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
godot::TypedArray<godot::Vector2> Example::testTypedArray() const
|
|
||||||
{
|
|
||||||
godot::TypedArray<godot::Vector2> arr;
|
|
||||||
|
|
||||||
arr.resize(2);
|
|
||||||
arr[0] = godot::Vector2(1, 2);
|
|
||||||
arr[1] = godot::Vector2(2, 3);
|
|
||||||
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
godot::Dictionary Example::testDictionary() const
|
|
||||||
{
|
|
||||||
godot::Dictionary dict;
|
|
||||||
|
|
||||||
dict["hello"] = "world";
|
|
||||||
dict["foo"] = "bar";
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
Example* Example::testNodeArgument(Example* inNode) const
|
|
||||||
{
|
|
||||||
// This should use godot::String::num_uint64(), but it is currently broken:
|
|
||||||
// https://github.com/godotengine/godot-cpp/issues/1014
|
|
||||||
godot::UtilityFunctions::print(
|
|
||||||
" Test node argument called with ",
|
|
||||||
(inNode != nullptr)
|
|
||||||
? godot::String::num_int64(static_cast<int64_t>(inNode->get_instance_id()))
|
|
||||||
: "null");
|
|
||||||
return inNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
godot::String Example::testStringOps() const
|
|
||||||
{
|
|
||||||
godot::String s = godot::String("A");
|
|
||||||
s += "B";
|
|
||||||
s += "C";
|
|
||||||
s += char32_t(0x010E);
|
|
||||||
s = s + "E";
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Example::testVectorOps() const
|
|
||||||
{
|
|
||||||
godot::PackedInt32Array arr;
|
|
||||||
arr.push_back(10);
|
|
||||||
arr.push_back(20);
|
|
||||||
arr.push_back(30);
|
|
||||||
arr.push_back(45);
|
|
||||||
|
|
||||||
int ret = 0;
|
|
||||||
for (const int32_t& E : arr) {
|
|
||||||
ret += E;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
godot::BitField<Example::Flags> Example::testBitfield(godot::BitField<Flags> inFlags)
|
|
||||||
{
|
|
||||||
godot::UtilityFunctions::print(" Got BitField: ", godot::String::num_int64(inFlags));
|
|
||||||
return inFlags;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Properties.
|
|
||||||
void Example::setCustomPosition(const godot::Vector2& inPos)
|
|
||||||
{
|
|
||||||
mCustomPosition = inPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
godot::Vector2 Example::getCustomPosition() const
|
|
||||||
{
|
|
||||||
return mCustomPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
godot::Vector4 Example::getV4() const
|
|
||||||
{
|
|
||||||
return { 1.2f, 3.4f, 5.6f, 7.8f };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static methods
|
|
||||||
int Example::testStatic(int inA, int inB)
|
|
||||||
{
|
|
||||||
return inA + inB;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::testStatic2()
|
|
||||||
{
|
|
||||||
godot::UtilityFunctions::print(" void static");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Virtual function override.
|
|
||||||
bool Example::_has_point(const godot::Vector2& inPoint) const
|
|
||||||
{
|
|
||||||
auto* label = godot::Control::get_node<godot::Label>("Label");
|
|
||||||
|
|
||||||
label->set_text("Got point: " + godot::Variant(inPoint).stringify());
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::_bind_methods()
|
|
||||||
{
|
|
||||||
// Methods.
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("simple_func"), &Example::simpleFunc);
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("simple_const_func"),
|
|
||||||
&Example::simpleConstFunc);
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("return_something"), &Example::returnSomething);
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("return_something_const"),
|
|
||||||
&Example::returnSomethingConst);
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("return_empty_ref"), &Example::returnEmptyRef);
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("return_extended_ref"),
|
|
||||||
&Example::returnExtendedRef);
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("extended_ref_checks", "ref"),
|
|
||||||
&Example::extendedRefChecks);
|
|
||||||
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("test_array"), &Example::testArray);
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("test_tarray_arg", "array"),
|
|
||||||
&Example::testTypedArrayArg);
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("test_tarray"), &Example::testTypedArray);
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("test_dictionary"), &Example::testDictionary);
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("test_node_argument"),
|
|
||||||
&Example::testNodeArgument);
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("test_string_ops"), &Example::testStringOps);
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("test_vector_ops"), &Example::testVectorOps);
|
|
||||||
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("test_bitfield", "flags"),
|
|
||||||
&Example::testBitfield);
|
|
||||||
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("def_args", "a", "b"), &Example::defArgs,
|
|
||||||
DEFVAL(100), DEFVAL(200));
|
|
||||||
|
|
||||||
godot::ClassDB::bind_static_method("Example", godot::D_METHOD("test_static", "a", "b"),
|
|
||||||
&Example::testStatic);
|
|
||||||
godot::ClassDB::bind_static_method("Example", godot::D_METHOD("test_static2"),
|
|
||||||
&Example::testStatic2);
|
|
||||||
|
|
||||||
{
|
|
||||||
godot::MethodInfo mi;
|
|
||||||
mi.arguments.emplace_back(godot::Variant::STRING, "some_argument");
|
|
||||||
mi.name = "varargs_func";
|
|
||||||
|
|
||||||
godot::ClassDB::bind_vararg_method(godot::METHOD_FLAGS_DEFAULT, "varargs_func",
|
|
||||||
&Example::varargsFunc, mi);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
godot::MethodInfo mi;
|
|
||||||
mi.arguments.emplace_back(godot::Variant::STRING, "some_argument");
|
|
||||||
mi.name = "varargs_func_nv";
|
|
||||||
|
|
||||||
godot::ClassDB::bind_vararg_method(godot::METHOD_FLAGS_DEFAULT, "varargs_func_nv",
|
|
||||||
&Example::varargsFuncNonVoidReturn, mi);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
godot::MethodInfo mi;
|
|
||||||
mi.arguments.emplace_back(godot::Variant::STRING, "some_argument");
|
|
||||||
mi.name = "varargs_func_void";
|
|
||||||
|
|
||||||
godot::ClassDB::bind_vararg_method(godot::METHOD_FLAGS_DEFAULT, "varargs_func_void",
|
|
||||||
&Example::varargsFuncVoidReturn, mi);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Properties.
|
|
||||||
ADD_GROUP("Test group", "group_");
|
|
||||||
ADD_SUBGROUP("Test subgroup", "group_subgroup_");
|
|
||||||
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("get_custom_position"),
|
|
||||||
&Example::getCustomPosition);
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("get_v4"), &Example::getV4);
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("set_custom_position", "position"),
|
|
||||||
&Example::setCustomPosition);
|
|
||||||
ADD_PROPERTY(godot::PropertyInfo(godot::Variant::VECTOR2, "group_subgroup_custom_position"),
|
|
||||||
"set_custom_position", "get_custom_position");
|
|
||||||
|
|
||||||
// Signals.
|
|
||||||
ADD_SIGNAL(godot::MethodInfo("custom_signal",
|
|
||||||
godot::PropertyInfo(godot::Variant::STRING, "name"),
|
|
||||||
godot::PropertyInfo(godot::Variant::INT, "value")));
|
|
||||||
godot::ClassDB::bind_method(godot::D_METHOD("emit_custom_signal", "name", "value"),
|
|
||||||
&Example::emitCustomSignal);
|
|
||||||
|
|
||||||
// Constants.
|
|
||||||
BIND_ENUM_CONSTANT(FIRST)
|
|
||||||
BIND_ENUM_CONSTANT(ANSWER_TO_EVERYTHING)
|
|
||||||
|
|
||||||
BIND_BITFIELD_FLAG(FLAG_ONE);
|
|
||||||
BIND_BITFIELD_FLAG(FLAG_TWO);
|
|
||||||
|
|
||||||
BIND_CONSTANT(CONSTANT_WITHOUT_ENUM);
|
|
||||||
BIND_ENUM_CONSTANT(OUTSIDE_OF_CLASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::_notification(int inWhat)
|
|
||||||
{
|
|
||||||
godot::UtilityFunctions::print("Notification: ", godot::String::num(inWhat));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Example::_set(const godot::StringName& inName, const godot::Variant& inValue)
|
|
||||||
{
|
|
||||||
godot::String name = inName;
|
|
||||||
|
|
||||||
if (name.begins_with("dproperty")) {
|
|
||||||
int64_t index = name.get_slicec('_', 1).to_int();
|
|
||||||
mDProp[index] = inValue;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name == "property_from_list") {
|
|
||||||
mPropertyFromList = inValue;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Example::_get(const godot::StringName& inName, godot::Variant& outReturn) const
|
|
||||||
{
|
|
||||||
godot::String name = inName;
|
|
||||||
|
|
||||||
if (name.begins_with("dproperty")) {
|
|
||||||
int64_t index = name.get_slicec('_', 1).to_int();
|
|
||||||
outReturn = mDProp[index];
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name == "property_from_list") {
|
|
||||||
outReturn = mPropertyFromList;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::_get_property_list(godot::List<godot::PropertyInfo>* outList) const
|
|
||||||
{
|
|
||||||
outList->push_back(godot::PropertyInfo(godot::Variant::VECTOR3, "property_from_list"));
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
|
||||||
outList->push_back(
|
|
||||||
godot::PropertyInfo(godot::Variant::VECTOR2, "dproperty_" + godot::itos(i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Example::_property_can_revert(const godot::StringName& inName) const
|
|
||||||
{
|
|
||||||
if (inName == godot::StringName("property_from_list") && mPropertyFromList != godot::Vector3(MAGIC_NUMBER, MAGIC_NUMBER, MAGIC_NUMBER)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool Example::_property_get_revert(const godot::StringName& inName,
|
|
||||||
godot::Variant& outProperty) const
|
|
||||||
{
|
|
||||||
if (inName == godot::StringName("property_from_list")) {
|
|
||||||
outProperty = godot::Vector3(MAGIC_NUMBER, MAGIC_NUMBER, MAGIC_NUMBER);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
godot::String Example::_to_string() const
|
|
||||||
{
|
|
||||||
return "[ GDExtension::Example <--> Instance ID:" + godot::uitos(get_instance_id()) + " ]";
|
|
||||||
}
|
|
||||||
|
|
||||||
//// ExampleVirtual
|
|
||||||
|
|
||||||
void ExampleVirtual::_bind_methods()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//// ExampleAbstract
|
|
||||||
|
|
||||||
void ExampleAbstract::_bind_methods()
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,135 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
// Copied from godot-cpp/test/src and modified.
|
|
||||||
|
|
||||||
#include "godot_cpp/classes/control.hpp"
|
|
||||||
#include "godot_cpp/classes/global_constants.hpp"
|
|
||||||
#include "godot_cpp/classes/viewport.hpp"
|
|
||||||
#include "godot_cpp/core/binder_common.hpp"
|
|
||||||
|
|
||||||
class ScreenPlayWallpaper : public godot::RefCounted {
|
|
||||||
GDCLASS(ScreenPlayWallpaper, RefCounted)
|
|
||||||
|
|
||||||
public:
|
|
||||||
ScreenPlayWallpaper();
|
|
||||||
~ScreenPlayWallpaper() override;
|
|
||||||
|
|
||||||
int getID() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void _bind_methods();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static int sInstanceCount;
|
|
||||||
static int sLastID;
|
|
||||||
|
|
||||||
int mID;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ExampleMin : public godot::Control {
|
|
||||||
GDCLASS(ExampleMin, Control)
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void _bind_methods();
|
|
||||||
};
|
|
||||||
|
|
||||||
class Example : public godot::Control {
|
|
||||||
GDCLASS(Example, godot::Control)
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Constants.
|
|
||||||
enum Constants {
|
|
||||||
FIRST,
|
|
||||||
ANSWER_TO_EVERYTHING = 42,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
CONSTANT_WITHOUT_ENUM = 314,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Flags {
|
|
||||||
FLAG_ONE = 1,
|
|
||||||
FLAG_TWO = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
Example();
|
|
||||||
~Example() override;
|
|
||||||
|
|
||||||
// Functions.
|
|
||||||
void simpleFunc();
|
|
||||||
void simpleConstFunc() const;
|
|
||||||
godot::String returnSomething(const godot::String& inBase);
|
|
||||||
godot::Viewport* returnSomethingConst() const;
|
|
||||||
godot::Ref<ScreenPlayWallpaper> returnEmptyRef() const;
|
|
||||||
ScreenPlayWallpaper* returnExtendedRef() const;
|
|
||||||
godot::Ref<ScreenPlayWallpaper> extendedRefChecks(godot::Ref<ScreenPlayWallpaper> inRef) const;
|
|
||||||
godot::Variant varargsFunc(const godot::Variant** inArgs, GDExtensionInt inArgCount,
|
|
||||||
GDExtensionCallError& outError);
|
|
||||||
int varargsFuncNonVoidReturn(const godot::Variant** inArgs, GDExtensionInt inArgCount,
|
|
||||||
GDExtensionCallError& outError);
|
|
||||||
void varargsFuncVoidReturn(const godot::Variant** inArgs, GDExtensionInt inArgCount,
|
|
||||||
GDExtensionCallError& outError);
|
|
||||||
|
|
||||||
void emitCustomSignal(const godot::String& inName, int inValue);
|
|
||||||
int defArgs(int inA = 100, int inB = 200) const;
|
|
||||||
|
|
||||||
godot::Array testArray() const;
|
|
||||||
void testTypedArrayArg(const godot::TypedArray<int64_t>& inArray);
|
|
||||||
godot::TypedArray<godot::Vector2> testTypedArray() const;
|
|
||||||
godot::Dictionary testDictionary() const;
|
|
||||||
Example* testNodeArgument(Example* inNode) const;
|
|
||||||
godot::String testStringOps() const;
|
|
||||||
int testVectorOps() const;
|
|
||||||
|
|
||||||
godot::BitField<Flags> testBitfield(godot::BitField<Flags> inFlags);
|
|
||||||
|
|
||||||
// Property.
|
|
||||||
void setCustomPosition(const godot::Vector2& inPos);
|
|
||||||
godot::Vector2 getCustomPosition() const;
|
|
||||||
godot::Vector4 getV4() const;
|
|
||||||
|
|
||||||
// Static method.
|
|
||||||
static int testStatic(int inA, int inB);
|
|
||||||
static void testStatic2();
|
|
||||||
|
|
||||||
// Virtual function override (no need to bind manually).
|
|
||||||
virtual bool _has_point(const godot::Vector2& inPoint) const override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void _bind_methods();
|
|
||||||
|
|
||||||
void _notification(int inWhat);
|
|
||||||
bool _set(const godot::StringName& inName, const godot::Variant& inValue);
|
|
||||||
bool _get(const godot::StringName& inName, godot::Variant& outReturn) const;
|
|
||||||
void _get_property_list(godot::List<godot::PropertyInfo>* outList) const;
|
|
||||||
bool _property_can_revert(const godot::StringName& inName) const;
|
|
||||||
bool _property_get_revert(const godot::StringName& inName, godot::Variant& outProperty) const;
|
|
||||||
|
|
||||||
godot::String _to_string() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
godot::Vector2 mCustomPosition;
|
|
||||||
godot::Vector3 mPropertyFromList;
|
|
||||||
godot::Vector2 mDProp[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
VARIANT_ENUM_CAST(Example::Constants);
|
|
||||||
VARIANT_BITFIELD_CAST(Example::Flags);
|
|
||||||
|
|
||||||
enum EnumWithoutClass {
|
|
||||||
OUTSIDE_OF_CLASS = 512
|
|
||||||
};
|
|
||||||
VARIANT_ENUM_CAST(EnumWithoutClass);
|
|
||||||
|
|
||||||
class ExampleVirtual : public godot::Object {
|
|
||||||
GDCLASS(ExampleVirtual, godot::Object)
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void _bind_methods();
|
|
||||||
};
|
|
||||||
|
|
||||||
class ExampleAbstract : public godot::Object {
|
|
||||||
GDCLASS(ExampleAbstract, godot::Object)
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void _bind_methods();
|
|
||||||
};
|
|
@ -11,6 +11,7 @@ add_dependencies( ${PROJECT_NAME} templates )
|
|||||||
# We shouldn't be relying on CMAKE_BUILD_TYPE (see https://github.com/asmaloney/GDExtensionTemplate/issues/25)
|
# We shouldn't be relying on CMAKE_BUILD_TYPE (see https://github.com/asmaloney/GDExtensionTemplate/issues/25)
|
||||||
# But until we fix it here and in godot-cpp, ensure it's one we expect.
|
# But until we fix it here and in godot-cpp, ensure it's one we expect.
|
||||||
set(ALLOWED_BUILDS "Debug;Release")
|
set(ALLOWED_BUILDS "Debug;Release")
|
||||||
|
|
||||||
if(NOT "${CMAKE_BUILD_TYPE}" IN_LIST ALLOWED_BUILDS)
|
if(NOT "${CMAKE_BUILD_TYPE}" IN_LIST ALLOWED_BUILDS)
|
||||||
message(FATAL_ERROR "CMAKE_BUILD_TYPE must be set to Debug or Release")
|
message(FATAL_ERROR "CMAKE_BUILD_TYPE must be set to Debug or Release")
|
||||||
endif()
|
endif()
|
||||||
@ -25,8 +26,9 @@ if ( MINGW )
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Generate our project's .gdextension file from the template
|
# Generate our project's .gdextension file from the template
|
||||||
|
set(OUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../ScreenPlayGodot/${PROJECT_NAME}/)
|
||||||
set(GD_EXTENSION_FILE ${PROJECT_NAME}.gdextension)
|
set(GD_EXTENSION_FILE ${PROJECT_NAME}.gdextension)
|
||||||
configure_file( ${GD_EXTENSION_FILE_INPUT} ${PROJECT_BINARY_DIR}/${PROJECT_NAME}/${GD_EXTENSION_FILE} )
|
configure_file(${GD_EXTENSION_FILE_INPUT} ${OUT_PATH}/${GD_EXTENSION_FILE})
|
||||||
|
|
||||||
# Install the gdextension file from the build directory
|
# Install the gdextension file from the build directory
|
||||||
install(
|
install(
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
[configuration]
|
||||||
|
|
||||||
|
entry_symbol = "GDExtensionInit"
|
||||||
|
compatibility_minimum = 4.1
|
||||||
|
|
||||||
|
[libraries]
|
||||||
|
|
||||||
|
linux.debug.x86_64 = "res://ScreenPlayGodotWallpaper/lib/Linux-x86_64/libScreenPlayGodotWallpaper-d.so"
|
||||||
|
macos.debug = "res://ScreenPlayGodotWallpaper/lib/Darwin-Universal/libScreenPlayGodotWallpaper-d.dylib"
|
||||||
|
windows.debug.x86_64 = "res://ScreenPlayGodotWallpaper/lib/Windows-AMD64/ScreenPlayGodotWallpaper-d.dll"
|
@ -1,13 +1,18 @@
|
|||||||
extends Node3D
|
extends Node3D
|
||||||
|
|
||||||
|
@onready var screen_play_wallpaper = $ScreenPlayGodotWallpaper
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var path = ""
|
# "C:\\Code\\cpp\\ScreenPlay\\ScreenPlay\\Content\\wallpaper_godot_fjord\\fjord.zip"
|
||||||
|
var path = "C:\\Code\\cpp\\ScreenPlay\\ScreenPlay\\Content\\wallpaper_godot_fjord\\fjord.zip"
|
||||||
var success = ProjectSettings.load_resource_pack (path)
|
var success = ProjectSettings.load_resource_pack (path)
|
||||||
if success:
|
if success:
|
||||||
var scene_resource = load("res://wallpaper.tscn")
|
var scene_resource = load("res://wallpaper.tscn")
|
||||||
if scene_resource:
|
if scene_resource:
|
||||||
var scene_instance = scene_resource.instantiate()
|
var scene_instance = scene_resource.instantiate()
|
||||||
add_child(scene_instance)
|
add_child(scene_instance)
|
||||||
|
var ok = screen_play_wallpaper.init(0)
|
||||||
|
print("init ", ok)
|
||||||
else:
|
else:
|
||||||
print("Failed to load the wallpaper.tscn scene.")
|
print("Failed to load the wallpaper.tscn scene.")
|
||||||
else:
|
else:
|
||||||
|
@ -4,3 +4,5 @@
|
|||||||
|
|
||||||
[node name="Wallpaper" type="Node3D"]
|
[node name="Wallpaper" type="Node3D"]
|
||||||
script = ExtResource("1_ceeuk")
|
script = ExtResource("1_ceeuk")
|
||||||
|
|
||||||
|
[node name="ScreenPlayGodotWallpaper" type="ScreenPlayGodotWallpaper" parent="."]
|
||||||
|
@ -14,8 +14,18 @@ config/name="ScreenPlay"
|
|||||||
run/main_scene="res://main.tscn"
|
run/main_scene="res://main.tscn"
|
||||||
config/features=PackedStringArray("4.1", "Mobile")
|
config/features=PackedStringArray("4.1", "Mobile")
|
||||||
boot_splash/show_image=false
|
boot_splash/show_image=false
|
||||||
|
boot_splash/fullsize=false
|
||||||
config/icon="res://icon.svg"
|
config/icon="res://icon.svg"
|
||||||
|
|
||||||
|
[display]
|
||||||
|
|
||||||
|
window/size/viewport_width=1
|
||||||
|
window/size/viewport_height=1
|
||||||
|
window/size/mode=1
|
||||||
|
window/size/initial_position_type=0
|
||||||
|
window/size/initial_position=Vector2i(9999999, 9999999)
|
||||||
|
window/size/borderless=true
|
||||||
|
|
||||||
[rendering]
|
[rendering]
|
||||||
|
|
||||||
renderer/rendering_method="mobile"
|
renderer/rendering_method="mobile"
|
||||||
|
111
ScreenPlayWallpaper/src/windowshook.cpp
Normal file
111
ScreenPlayWallpaper/src/windowshook.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#include "windowshook.h"
|
||||||
|
|
||||||
|
BOOL CALLBACK WinMonitorStats::MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData)
|
||||||
|
{
|
||||||
|
WinMonitorStats* pThis = reinterpret_cast<WinMonitorStats*>(pData);
|
||||||
|
auto scaleFactor = DEVICE_SCALE_FACTOR::DEVICE_SCALE_FACTOR_INVALID;
|
||||||
|
GetScaleFactorForMonitor(hMon, &scaleFactor);
|
||||||
|
|
||||||
|
UINT x = 0;
|
||||||
|
UINT y = 0;
|
||||||
|
GetDpiForMonitor(hMon, MONITOR_DPI_TYPE::MDT_RAW_DPI, &x, &y);
|
||||||
|
pThis->sizes.push_back({ x, y });
|
||||||
|
pThis->scaleFactor.push_back(scaleFactor);
|
||||||
|
pThis->hMonitors.push_back(hMon);
|
||||||
|
pThis->hdcMonitors.push_back(hdc);
|
||||||
|
pThis->rcMonitors.push_back(*lprcMonitor);
|
||||||
|
pThis->iMonitors.push_back(static_cast<int>(pThis->hdcMonitors.size()));
|
||||||
|
|
||||||
|
// qInfo() << std::abs(lprcMonitor->right - lprcMonitor->left) << std::abs(lprcMonitor->top - lprcMonitor->bottom);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
/*!
|
||||||
|
\brief Searches for the worker window for our window to parent to.
|
||||||
|
*/
|
||||||
|
BOOL WINAPI SearchForWorkerWindow(HWND hwnd, LPARAM lparam)
|
||||||
|
{
|
||||||
|
// 0xXXXXXXX "" WorkerW
|
||||||
|
// ...
|
||||||
|
// 0xXXXXXXX "" SHELLDLL_DefView
|
||||||
|
// 0xXXXXXXXX "FolderView" SysListView32
|
||||||
|
// 0xXXXXXXXX "" WorkerW <---- We want this one
|
||||||
|
// 0xXXXXXXXX "Program Manager" Progman
|
||||||
|
if (FindWindowExW(hwnd, nullptr, L"SHELLDLL_DefView", nullptr))
|
||||||
|
*reinterpret_cast<HWND*>(lparam) = FindWindowExW(nullptr, hwnd, L"WorkerW", nullptr);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WindowsHook::searchWorkerWindowToParentTo()
|
||||||
|
{
|
||||||
|
|
||||||
|
HWND progman_hwnd = FindWindowW(L"Progman", L"Program Manager");
|
||||||
|
const DWORD WM_SPAWN_WORKER = 0x052C;
|
||||||
|
SendMessageTimeoutW(progman_hwnd, WM_SPAWN_WORKER, 0xD, 0x1, SMTO_NORMAL,
|
||||||
|
10000, nullptr);
|
||||||
|
|
||||||
|
return EnumWindows(SearchForWorkerWindow, reinterpret_cast<LPARAM>(&windowHandleWorker));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Returns scaling factor as reported by Windows.
|
||||||
|
*/
|
||||||
|
float WindowsHook::getScaling(const int monitorIndex) const
|
||||||
|
{
|
||||||
|
// Get all monitors
|
||||||
|
int monitorCount = GetSystemMetrics(SM_CMONITORS);
|
||||||
|
|
||||||
|
if (monitorIndex < 0 || monitorIndex >= monitorCount) {
|
||||||
|
// Invalid monitor index
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
DISPLAY_DEVICE displayDevice;
|
||||||
|
ZeroMemory(&displayDevice, sizeof(displayDevice));
|
||||||
|
displayDevice.cb = sizeof(displayDevice);
|
||||||
|
|
||||||
|
// Enumerate through monitors until we find the one we're looking for
|
||||||
|
for (int i = 0; EnumDisplayDevices(NULL, i, &displayDevice, 0); i++) {
|
||||||
|
if (i == monitorIndex) {
|
||||||
|
DEVMODE devMode;
|
||||||
|
ZeroMemory(&devMode, sizeof(devMode));
|
||||||
|
devMode.dmSize = sizeof(devMode);
|
||||||
|
|
||||||
|
// Get settings for selected monitor
|
||||||
|
if (!EnumDisplaySettings(displayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &devMode)) {
|
||||||
|
// Unable to get monitor settings
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get DPI for selected monitor
|
||||||
|
HMONITOR hMonitor = MonitorFromPoint({ devMode.dmPosition.x, devMode.dmPosition.y }, MONITOR_DEFAULTTONEAREST);
|
||||||
|
UINT dpiX = 0, dpiY = 0;
|
||||||
|
if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) {
|
||||||
|
return (float)dpiX / 96.0f; // Standard DPI is 96
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we reach here, it means we couldn't find the monitor with the given index or couldn't get the DPI.
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Returns true of at least one monitor has active scaling enabled.
|
||||||
|
*/
|
||||||
|
bool WindowsHook::hasWindowScaling() const
|
||||||
|
{
|
||||||
|
auto enumMonitorCallback = [](HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) -> BOOL {
|
||||||
|
int scaling = GetDeviceCaps(hdcMonitor, LOGPIXELSX) / 96;
|
||||||
|
if (scaling != 1) {
|
||||||
|
*(bool*)dwData = true;
|
||||||
|
return false; // Stop enumeration
|
||||||
|
}
|
||||||
|
return true; // Continue enumeration
|
||||||
|
};
|
||||||
|
|
||||||
|
bool hasScaling = false;
|
||||||
|
EnumDisplayMonitors(NULL, NULL, enumMonitorCallback, (LPARAM)&hasScaling);
|
||||||
|
|
||||||
|
return hasScaling;
|
||||||
|
}
|
41
ScreenPlayWallpaper/src/windowshook.h
Normal file
41
ScreenPlayWallpaper/src/windowshook.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <shellscalingapi.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct WinMonitorStats {
|
||||||
|
|
||||||
|
WinMonitorStats()
|
||||||
|
{
|
||||||
|
EnumDisplayMonitors(NULL, NULL, MonitorEnum, (LPARAM)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData);
|
||||||
|
std::vector<int> iMonitors;
|
||||||
|
std::vector<HMONITOR> hMonitors;
|
||||||
|
std::vector<HDC> hdcMonitors;
|
||||||
|
std::vector<RECT> rcMonitors;
|
||||||
|
std::vector<DEVICE_SCALE_FACTOR> scaleFactor;
|
||||||
|
std::vector<std::pair<UINT, UINT>> sizes;
|
||||||
|
int index = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Point {
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WindowsHook {
|
||||||
|
bool searchWorkerWindowToParentTo();
|
||||||
|
float getScaling(const int monitorIndex) const;
|
||||||
|
bool hasWindowScaling() const;
|
||||||
|
HWND windowHandle {};
|
||||||
|
HWND windowHandleWorker {};
|
||||||
|
Point zeroPoint;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user