mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-03 17:56:44 +02:00
[common, shortcutguide] move d2d files from common to scg (#7844)
Also remove d2d classes from common documentation
This commit is contained in:
117
src/modules/shortcut_guide/d2d_svg.cpp
Normal file
117
src/modules/shortcut_guide/d2d_svg.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
#include "pch.h"
|
||||
#include "d2d_svg.h"
|
||||
|
||||
D2DSVG& D2DSVG::load(const std::wstring& filename, ID2D1DeviceContext5* d2d_dc)
|
||||
{
|
||||
svg = nullptr;
|
||||
winrt::com_ptr<IStream> svg_stream;
|
||||
winrt::check_hresult(SHCreateStreamOnFileEx(filename.c_str(),
|
||||
STGM_READ,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
FALSE,
|
||||
nullptr,
|
||||
svg_stream.put()));
|
||||
|
||||
winrt::check_hresult(d2d_dc->CreateSvgDocument(
|
||||
svg_stream.get(),
|
||||
D2D1::SizeF(1, 1),
|
||||
svg.put()));
|
||||
|
||||
winrt::com_ptr<ID2D1SvgElement> root;
|
||||
svg->GetRoot(root.put());
|
||||
float tmp;
|
||||
winrt::check_hresult(root->GetAttributeValue(L"width", &tmp));
|
||||
svg_width = (int)tmp;
|
||||
winrt::check_hresult(root->GetAttributeValue(L"height", &tmp));
|
||||
svg_height = (int)tmp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
D2DSVG& D2DSVG::resize(int x, int y, int width, int height, float fill, float max_scale)
|
||||
{
|
||||
// Center
|
||||
transform = D2D1::Matrix3x2F::Identity();
|
||||
transform = transform * D2D1::Matrix3x2F::Translation((width - svg_width) / 2.0f, (height - svg_height) / 2.0f);
|
||||
float h_scale = fill * height / svg_height;
|
||||
float v_scale = fill * width / svg_width;
|
||||
used_scale = std::min(h_scale, v_scale);
|
||||
if (max_scale > 0)
|
||||
{
|
||||
used_scale = std::min(used_scale, max_scale);
|
||||
}
|
||||
transform = transform * D2D1::Matrix3x2F::Scale(used_scale, used_scale, D2D1::Point2F(width / 2.0f, height / 2.0f));
|
||||
transform = transform * D2D1::Matrix3x2F::Translation((float)x, (float)y);
|
||||
return *this;
|
||||
}
|
||||
|
||||
D2DSVG& D2DSVG::recolor(uint32_t oldcolor, uint32_t newcolor)
|
||||
{
|
||||
auto new_color = D2D1::ColorF(newcolor & 0xFFFFFF, 1);
|
||||
auto old_color = D2D1::ColorF(oldcolor & 0xFFFFFF, 1);
|
||||
std::function<void(ID2D1SvgElement * element)> recurse = [&](ID2D1SvgElement* element) {
|
||||
if (!element)
|
||||
return;
|
||||
if (element->IsAttributeSpecified(L"fill"))
|
||||
{
|
||||
D2D1_COLOR_F elem_fill;
|
||||
winrt::com_ptr<ID2D1SvgPaint> paint;
|
||||
element->GetAttributeValue(L"fill", paint.put());
|
||||
paint->GetColor(&elem_fill);
|
||||
if (elem_fill.r == old_color.r && elem_fill.g == old_color.g && elem_fill.b == old_color.b)
|
||||
{
|
||||
winrt::check_hresult(element->SetAttributeValue(L"fill", new_color));
|
||||
}
|
||||
}
|
||||
winrt::com_ptr<ID2D1SvgElement> sub;
|
||||
element->GetFirstChild(sub.put());
|
||||
while (sub)
|
||||
{
|
||||
recurse(sub.get());
|
||||
winrt::com_ptr<ID2D1SvgElement> next;
|
||||
element->GetNextChild(sub.get(), next.put());
|
||||
sub = next;
|
||||
}
|
||||
};
|
||||
winrt::com_ptr<ID2D1SvgElement> root;
|
||||
svg->GetRoot(root.put());
|
||||
recurse(root.get());
|
||||
return *this;
|
||||
}
|
||||
|
||||
D2DSVG& D2DSVG::render(ID2D1DeviceContext5* d2d_dc)
|
||||
{
|
||||
D2D1_MATRIX_3X2_F current;
|
||||
d2d_dc->GetTransform(¤t);
|
||||
d2d_dc->SetTransform(transform * current);
|
||||
d2d_dc->DrawSvgDocument(svg.get());
|
||||
d2d_dc->SetTransform(current);
|
||||
return *this;
|
||||
}
|
||||
|
||||
D2DSVG& D2DSVG::toggle_element(const wchar_t* id, bool visible)
|
||||
{
|
||||
winrt::com_ptr<ID2D1SvgElement> element;
|
||||
if (svg->FindElementById(id, element.put()) != S_OK)
|
||||
return *this;
|
||||
if (!element)
|
||||
return *this;
|
||||
element->SetAttributeValue(L"display", visible ? D2D1_SVG_DISPLAY::D2D1_SVG_DISPLAY_INLINE : D2D1_SVG_DISPLAY::D2D1_SVG_DISPLAY_NONE);
|
||||
return *this;
|
||||
}
|
||||
|
||||
winrt::com_ptr<ID2D1SvgElement> D2DSVG::find_element(const std::wstring& id)
|
||||
{
|
||||
winrt::com_ptr<ID2D1SvgElement> element;
|
||||
winrt::check_hresult(svg->FindElementById(id.c_str(), element.put()));
|
||||
return element;
|
||||
}
|
||||
|
||||
D2D1_RECT_F D2DSVG::rescale(D2D1_RECT_F rect)
|
||||
{
|
||||
D2D1_RECT_F result;
|
||||
auto src = reinterpret_cast<D2D1_POINT_2F*>(&rect);
|
||||
auto dst = reinterpret_cast<D2D1_POINT_2F*>(&result);
|
||||
dst[0] = src[0] * transform;
|
||||
dst[1] = src[1] * transform;
|
||||
return result;
|
||||
}
|
||||
26
src/modules/shortcut_guide/d2d_svg.h
Normal file
26
src/modules/shortcut_guide/d2d_svg.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include <d2d1_3.h>
|
||||
#include <d2d1_3helper.h>
|
||||
#include <winrt/base.h>
|
||||
#include <string>
|
||||
|
||||
class D2DSVG
|
||||
{
|
||||
public:
|
||||
D2DSVG& load(const std::wstring& filename, ID2D1DeviceContext5* d2d_dc);
|
||||
D2DSVG& resize(int x, int y, int width, int height, float fill, float max_scale = -1.0f);
|
||||
D2DSVG& render(ID2D1DeviceContext5* d2d_dc);
|
||||
D2DSVG& recolor(uint32_t oldcolor, uint32_t newcolor);
|
||||
float get_scale() const { return used_scale; }
|
||||
int width() const { return svg_width; }
|
||||
int height() const { return svg_height; }
|
||||
D2DSVG& toggle_element(const wchar_t* id, bool visible);
|
||||
winrt::com_ptr<ID2D1SvgElement> find_element(const std::wstring& id);
|
||||
D2D1_RECT_F rescale(D2D1_RECT_F rect);
|
||||
|
||||
protected:
|
||||
float used_scale = 1.0f;
|
||||
winrt::com_ptr<ID2D1SvgDocument> svg;
|
||||
int svg_width = -1, svg_height = -1;
|
||||
D2D1::Matrix3x2F transform;
|
||||
};
|
||||
54
src/modules/shortcut_guide/d2d_text.cpp
Normal file
54
src/modules/shortcut_guide/d2d_text.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "pch.h"
|
||||
#include "d2d_text.h"
|
||||
|
||||
D2DText::D2DText(float text_size, float scale)
|
||||
{
|
||||
winrt::check_hresult(DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(factory), reinterpret_cast<IUnknown**>(factory.put_void())));
|
||||
resize(text_size, scale);
|
||||
winrt::check_hresult(format->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER));
|
||||
winrt::check_hresult(format->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER));
|
||||
}
|
||||
|
||||
D2DText& D2DText::resize(float text_size, float scale)
|
||||
{
|
||||
format = nullptr;
|
||||
winrt::check_hresult(factory->CreateTextFormat(L"Segoe UI",
|
||||
nullptr,
|
||||
DWRITE_FONT_WEIGHT_NORMAL,
|
||||
DWRITE_FONT_STYLE_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
text_size * scale,
|
||||
L"en-us",
|
||||
format.put()));
|
||||
winrt::check_hresult(format->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER));
|
||||
return *this;
|
||||
}
|
||||
|
||||
D2DText& D2DText::set_alignment_left()
|
||||
{
|
||||
winrt::check_hresult(format->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING));
|
||||
return *this;
|
||||
}
|
||||
|
||||
D2DText& D2DText::set_alignment_center()
|
||||
{
|
||||
winrt::check_hresult(format->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER));
|
||||
return *this;
|
||||
}
|
||||
|
||||
D2DText& D2DText::set_alignment_right()
|
||||
{
|
||||
winrt::check_hresult(format->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_TRAILING));
|
||||
return *this;
|
||||
}
|
||||
|
||||
void D2DText::write(ID2D1DeviceContext5* d2d_dc, D2D1_COLOR_F color, D2D1_RECT_F rect, std::wstring text)
|
||||
{
|
||||
winrt::com_ptr<ID2D1SolidColorBrush> brush;
|
||||
d2d_dc->CreateSolidColorBrush(color, brush.put());
|
||||
d2d_dc->DrawText(text.c_str(),
|
||||
(UINT32)text.length(),
|
||||
format.get(),
|
||||
rect,
|
||||
brush.get());
|
||||
}
|
||||
18
src/modules/shortcut_guide/d2d_text.h
Normal file
18
src/modules/shortcut_guide/d2d_text.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <winrt/base.h>
|
||||
#include <dwrite.h>
|
||||
|
||||
class D2DText
|
||||
{
|
||||
public:
|
||||
D2DText(float text_size = 15.0f, float scale = 1.0f);
|
||||
D2DText& resize(float text_size, float scale);
|
||||
D2DText& set_alignment_left();
|
||||
D2DText& set_alignment_center();
|
||||
D2DText& set_alignment_right();
|
||||
void write(ID2D1DeviceContext5* d2d_dc, D2D1_COLOR_F color, D2D1_RECT_F rect, std::wstring text);
|
||||
|
||||
private:
|
||||
winrt::com_ptr<IDWriteFactory> factory;
|
||||
winrt::com_ptr<IDWriteTextFormat> format;
|
||||
};
|
||||
215
src/modules/shortcut_guide/d2d_window.cpp
Normal file
215
src/modules/shortcut_guide/d2d_window.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
#include "pch.h"
|
||||
#include "d2d_window.h"
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
|
||||
D2DWindow::D2DWindow(std::optional<std::function<std::remove_pointer_t<WNDPROC>>> _pre_wnd_proc) :
|
||||
pre_wnd_proc(std::move(_pre_wnd_proc))
|
||||
{
|
||||
static const WCHAR* class_name = L"PToyD2DPopup";
|
||||
WNDCLASS wc = {};
|
||||
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wc.hInstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
||||
wc.lpszClassName = class_name;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = d2d_window_proc;
|
||||
RegisterClass(&wc);
|
||||
hwnd = CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_TOPMOST | WS_EX_NOREDIRECTIONBITMAP | WS_EX_LAYERED,
|
||||
wc.lpszClassName,
|
||||
L"PToyD2DPopup",
|
||||
WS_POPUP | WS_VISIBLE,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
nullptr,
|
||||
nullptr,
|
||||
wc.hInstance,
|
||||
this);
|
||||
WINRT_VERIFY(hwnd);
|
||||
}
|
||||
|
||||
void D2DWindow::show(UINT x, UINT y, UINT width, UINT height)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
base_init();
|
||||
}
|
||||
base_resize(width, height);
|
||||
render_empty();
|
||||
hidden = false;
|
||||
on_show();
|
||||
SetWindowPos(hwnd, HWND_TOPMOST, x, y, width, height, 0);
|
||||
ShowWindow(hwnd, SW_SHOWNORMAL);
|
||||
UpdateWindow(hwnd);
|
||||
}
|
||||
|
||||
void D2DWindow::hide()
|
||||
{
|
||||
hidden = true;
|
||||
ShowWindow(hwnd, SW_HIDE);
|
||||
on_hide();
|
||||
}
|
||||
|
||||
void D2DWindow::initialize()
|
||||
{
|
||||
base_init();
|
||||
}
|
||||
|
||||
void D2DWindow::base_init()
|
||||
{
|
||||
std::unique_lock lock(mutex);
|
||||
// D2D1Factory is independent from the device, no need to recreate it if we need to recreate the device.
|
||||
if (!d2d_factory)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
D2D1_FACTORY_OPTIONS options = { D2D1_DEBUG_LEVEL_INFORMATION };
|
||||
#else
|
||||
D2D1_FACTORY_OPTIONS options = {};
|
||||
#endif
|
||||
winrt::check_hresult(D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED,
|
||||
__uuidof(d2d_factory),
|
||||
&options,
|
||||
d2d_factory.put_void()));
|
||||
}
|
||||
// For all other stuff - assign nullptr first to release the object, to reset the com_ptr.
|
||||
d2d_dc = nullptr;
|
||||
d2d_device = nullptr;
|
||||
dxgi_factory = nullptr;
|
||||
dxgi_device = nullptr;
|
||||
d3d_device = nullptr;
|
||||
winrt::check_hresult(D3D11CreateDevice(nullptr,
|
||||
D3D_DRIVER_TYPE_HARDWARE,
|
||||
nullptr,
|
||||
D3D11_CREATE_DEVICE_BGRA_SUPPORT,
|
||||
nullptr,
|
||||
0,
|
||||
D3D11_SDK_VERSION,
|
||||
d3d_device.put(),
|
||||
nullptr,
|
||||
nullptr));
|
||||
winrt::check_hresult(d3d_device->QueryInterface(__uuidof(dxgi_device), dxgi_device.put_void()));
|
||||
winrt::check_hresult(CreateDXGIFactory2(0, __uuidof(dxgi_factory), dxgi_factory.put_void()));
|
||||
winrt::check_hresult(d2d_factory->CreateDevice(dxgi_device.get(), d2d_device.put()));
|
||||
winrt::check_hresult(d2d_device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, d2d_dc.put()));
|
||||
init();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
void D2DWindow::base_resize(UINT width, UINT height)
|
||||
{
|
||||
std::unique_lock lock(mutex);
|
||||
if (!initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
window_width = width;
|
||||
window_height = height;
|
||||
if (window_width == 0 || window_height == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
DXGI_SWAP_CHAIN_DESC1 sc_description = {};
|
||||
sc_description.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
sc_description.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sc_description.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
sc_description.BufferCount = 2;
|
||||
sc_description.SampleDesc.Count = 1;
|
||||
sc_description.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
|
||||
sc_description.Width = window_width;
|
||||
sc_description.Height = window_height;
|
||||
dxgi_swap_chain = nullptr;
|
||||
winrt::check_hresult(dxgi_factory->CreateSwapChainForComposition(dxgi_device.get(),
|
||||
&sc_description,
|
||||
nullptr,
|
||||
dxgi_swap_chain.put()));
|
||||
composition_device = nullptr;
|
||||
winrt::check_hresult(DCompositionCreateDevice(dxgi_device.get(),
|
||||
__uuidof(composition_device),
|
||||
composition_device.put_void()));
|
||||
|
||||
composition_target = nullptr;
|
||||
winrt::check_hresult(composition_device->CreateTargetForHwnd(hwnd, true, composition_target.put()));
|
||||
|
||||
composition_visual = nullptr;
|
||||
winrt::check_hresult(composition_device->CreateVisual(composition_visual.put()));
|
||||
winrt::check_hresult(composition_visual->SetContent(dxgi_swap_chain.get()));
|
||||
winrt::check_hresult(composition_target->SetRoot(composition_visual.get()));
|
||||
|
||||
dxgi_surface = nullptr;
|
||||
winrt::check_hresult(dxgi_swap_chain->GetBuffer(0, __uuidof(dxgi_surface), dxgi_surface.put_void()));
|
||||
D2D1_BITMAP_PROPERTIES1 properties = {};
|
||||
properties.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
|
||||
properties.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
properties.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
|
||||
|
||||
d2d_bitmap = nullptr;
|
||||
winrt::check_hresult(d2d_dc->CreateBitmapFromDxgiSurface(dxgi_surface.get(),
|
||||
properties,
|
||||
d2d_bitmap.put()));
|
||||
d2d_dc->SetTarget(d2d_bitmap.get());
|
||||
resize();
|
||||
}
|
||||
|
||||
void D2DWindow::base_render()
|
||||
{
|
||||
std::unique_lock lock(mutex);
|
||||
if (!initialized || !d2d_dc || !d2d_bitmap)
|
||||
return;
|
||||
d2d_dc->BeginDraw();
|
||||
render(d2d_dc.get());
|
||||
winrt::check_hresult(d2d_dc->EndDraw());
|
||||
winrt::check_hresult(dxgi_swap_chain->Present(1, 0));
|
||||
winrt::check_hresult(composition_device->Commit());
|
||||
}
|
||||
|
||||
void D2DWindow::render_empty()
|
||||
{
|
||||
std::unique_lock lock(mutex);
|
||||
if (!initialized || !d2d_dc || !d2d_bitmap)
|
||||
return;
|
||||
d2d_dc->BeginDraw();
|
||||
d2d_dc->Clear();
|
||||
winrt::check_hresult(d2d_dc->EndDraw());
|
||||
winrt::check_hresult(dxgi_swap_chain->Present(1, 0));
|
||||
winrt::check_hresult(composition_device->Commit());
|
||||
}
|
||||
|
||||
D2DWindow::~D2DWindow()
|
||||
{
|
||||
ShowWindow(hwnd, SW_HIDE);
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
D2DWindow* D2DWindow::this_from_hwnd(HWND window)
|
||||
{
|
||||
return reinterpret_cast<D2DWindow*>(GetWindowLongPtr(window, GWLP_USERDATA));
|
||||
}
|
||||
|
||||
LRESULT __stdcall D2DWindow::d2d_window_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
auto self = this_from_hwnd(window);
|
||||
if (self && self->pre_wnd_proc.has_value())
|
||||
{
|
||||
(*self->pre_wnd_proc)(window, message, wparam, lparam);
|
||||
}
|
||||
switch (message)
|
||||
{
|
||||
case WM_NCCREATE:
|
||||
{
|
||||
auto create_struct = reinterpret_cast<CREATESTRUCT*>(lparam);
|
||||
SetWindowLongPtr(window, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(create_struct->lpCreateParams));
|
||||
return TRUE;
|
||||
}
|
||||
case WM_MOVE:
|
||||
case WM_SIZE:
|
||||
self->base_resize((unsigned)lparam & 0xFFFF, (unsigned)lparam >> 16);
|
||||
[[fallthrough]];
|
||||
case WM_PAINT:
|
||||
self->base_render();
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return DefWindowProc(window, message, wparam, lparam);
|
||||
}
|
||||
}
|
||||
67
src/modules/shortcut_guide/d2d_window.h
Normal file
67
src/modules/shortcut_guide/d2d_window.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
#include <winrt/base.h>
|
||||
#include <Windows.h>
|
||||
#include <dxgi1_3.h>
|
||||
#include <d3d11_2.h>
|
||||
#include <d2d1_3.h>
|
||||
#include <d2d1_3helper.h>
|
||||
#include <d2d1helper.h>
|
||||
#include <dcomp.h>
|
||||
#include <dwmapi.h>
|
||||
#include <string>
|
||||
#include "d2d_svg.h"
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
||||
class D2DWindow
|
||||
{
|
||||
public:
|
||||
D2DWindow(std::optional<std::function<std::remove_pointer_t<WNDPROC>>> pre_wnd_proc = std::nullopt);
|
||||
void show(UINT x, UINT y, UINT width, UINT height);
|
||||
void hide();
|
||||
void initialize();
|
||||
virtual ~D2DWindow();
|
||||
|
||||
protected:
|
||||
// Implement this:
|
||||
|
||||
// Initialization - called when D2D device needs to be created.
|
||||
// When called all D2DWindow members will be initialized, including d2d_dc
|
||||
virtual void init() = 0;
|
||||
// resize - when called, window_width and window_height will have current window size
|
||||
virtual void resize() = 0;
|
||||
// render - called on WM_PAIT, BeginPaint/EndPaint is handled by D2DWindow
|
||||
virtual void render(ID2D1DeviceContext5* d2d_dc) = 0;
|
||||
// on_show, on_hide - called when the window is about to be shown or about to be hidden
|
||||
virtual void on_show() = 0;
|
||||
virtual void on_hide() = 0;
|
||||
|
||||
static LRESULT __stdcall d2d_window_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam);
|
||||
static D2DWindow* this_from_hwnd(HWND window);
|
||||
|
||||
void base_init();
|
||||
void base_resize(UINT width, UINT height);
|
||||
void base_render();
|
||||
void render_empty();
|
||||
|
||||
std::recursive_mutex mutex;
|
||||
bool hidden = true;
|
||||
bool initialized = false;
|
||||
HWND hwnd;
|
||||
UINT window_width, window_height;
|
||||
winrt::com_ptr<ID3D11Device> d3d_device;
|
||||
winrt::com_ptr<IDXGIDevice> dxgi_device;
|
||||
winrt::com_ptr<IDXGIFactory2> dxgi_factory;
|
||||
winrt::com_ptr<IDXGISwapChain1> dxgi_swap_chain;
|
||||
winrt::com_ptr<IDCompositionDevice> composition_device;
|
||||
winrt::com_ptr<IDCompositionTarget> composition_target;
|
||||
winrt::com_ptr<IDCompositionVisual> composition_visual;
|
||||
winrt::com_ptr<IDXGISurface2> dxgi_surface;
|
||||
winrt::com_ptr<ID2D1Bitmap1> d2d_bitmap;
|
||||
winrt::com_ptr<ID2D1Factory6> d2d_factory;
|
||||
winrt::com_ptr<ID2D1Device5> d2d_device;
|
||||
winrt::com_ptr<ID2D1DeviceContext5> d2d_dc;
|
||||
|
||||
std::optional<std::function<std::remove_pointer_t<WNDPROC>>> pre_wnd_proc;
|
||||
};
|
||||
@@ -71,7 +71,7 @@ ScaleResult D2DOverlaySVG::get_thumbnail_rect_and_scale(int x_offset, int y_offs
|
||||
}
|
||||
float scale_h = fill * thumbnail_scaled_rect_width / window_cx;
|
||||
float scale_v = fill * thumbnail_scaled_rect_heigh / window_cy;
|
||||
float use_scale = min(scale_h, scale_v);
|
||||
float use_scale = std::min(scale_h, scale_v);
|
||||
RECT thumb_rect;
|
||||
thumb_rect.left = thumbnail_scaled_rect.left + (int)(thumbnail_scaled_rect_width - use_scale * window_cx) / 2 + x_offset;
|
||||
thumb_rect.right = thumbnail_scaled_rect.right - (int)(thumbnail_scaled_rect_width - use_scale * window_cx) / 2 + x_offset;
|
||||
@@ -254,10 +254,10 @@ void D2DOverlayWindow::show(HWND active_window, bool snappable)
|
||||
total_screen = ScreenSize(monitors[0].rect);
|
||||
for (auto& monitor : monitors)
|
||||
{
|
||||
total_screen.rect.left = min(total_screen.rect.left, monitor.rect.left);
|
||||
total_screen.rect.top = min(total_screen.rect.top, monitor.rect.top);
|
||||
total_screen.rect.right = max(total_screen.rect.right, monitor.rect.right);
|
||||
total_screen.rect.bottom = max(total_screen.rect.bottom, monitor.rect.bottom);
|
||||
total_screen.rect.left = std::min(total_screen.rect.left, monitor.rect.left);
|
||||
total_screen.rect.top = std::min(total_screen.rect.top, monitor.rect.top);
|
||||
total_screen.rect.right = std::max(total_screen.rect.right, monitor.rect.right);
|
||||
total_screen.rect.bottom = std::max(total_screen.rect.bottom, monitor.rect.bottom);
|
||||
}
|
||||
// make sure top-right corner of all the monitor rects is (0,0)
|
||||
monitor_dx = -total_screen.left();
|
||||
@@ -693,10 +693,10 @@ void D2DOverlayWindow::render(ID2D1DeviceContext5* d2d_dc)
|
||||
auto total_monitor_with_screen = total_screen;
|
||||
if (thumb_window)
|
||||
{
|
||||
total_monitor_with_screen.rect.left = min(total_monitor_with_screen.rect.left, thumb_window->left + monitor_dx);
|
||||
total_monitor_with_screen.rect.top = min(total_monitor_with_screen.rect.top, thumb_window->top + monitor_dy);
|
||||
total_monitor_with_screen.rect.right = max(total_monitor_with_screen.rect.right, thumb_window->right + monitor_dx);
|
||||
total_monitor_with_screen.rect.bottom = max(total_monitor_with_screen.rect.bottom, thumb_window->bottom + monitor_dy);
|
||||
total_monitor_with_screen.rect.left = std::min(total_monitor_with_screen.rect.left, thumb_window->left + monitor_dx);
|
||||
total_monitor_with_screen.rect.top = std::min(total_monitor_with_screen.rect.top, thumb_window->top + monitor_dy);
|
||||
total_monitor_with_screen.rect.right = std::max(total_monitor_with_screen.rect.right, thumb_window->right + monitor_dx);
|
||||
total_monitor_with_screen.rect.bottom = std::max(total_monitor_with_screen.rect.bottom, thumb_window->bottom + monitor_dy);
|
||||
}
|
||||
// Only allow the new rect being slight bigger.
|
||||
if (total_monitor_with_screen.width() - total_screen.width() > (thumb_window->right - thumb_window->left) / 2 ||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "common/d2d_svg.h"
|
||||
#include "common/d2d_window.h"
|
||||
#include "common/d2d_text.h"
|
||||
#include "d2d_svg.h"
|
||||
#include "d2d_window.h"
|
||||
#include "d2d_text.h"
|
||||
#include "common/monitors.h"
|
||||
#include "common/animation.h"
|
||||
#include "common/windows_colors.h"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#define NOMINMAX
|
||||
#include <winrt/base.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
|
||||
@@ -105,6 +105,9 @@
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="d2d_svg.h" />
|
||||
<ClInclude Include="d2d_text.h" />
|
||||
<ClInclude Include="d2d_window.h" />
|
||||
<ClInclude Include="overlay_window.h" />
|
||||
<ClInclude Include="keyboard_state.h" />
|
||||
<ClInclude Include="Generated Files/resource.h" />
|
||||
@@ -116,6 +119,9 @@
|
||||
<ClInclude Include="trace.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="d2d_svg.cpp" />
|
||||
<ClCompile Include="d2d_text.cpp" />
|
||||
<ClCompile Include="d2d_window.cpp" />
|
||||
<ClCompile Include="overlay_window.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="keyboard_state.cpp" />
|
||||
|
||||
@@ -18,6 +18,15 @@
|
||||
<ClCompile Include="trace.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="d2d_svg.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="d2d_text.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="d2d_window.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
@@ -39,6 +48,16 @@
|
||||
<ClInclude Include="Generated Files/resource.h">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ShortcutGuideConstants.h" />
|
||||
<ClInclude Include="d2d_svg.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="d2d_text.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="d2d_window.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
|
||||
Reference in New Issue
Block a user