mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-01-18 22:43:31 +08:00
Good progress on D2D
This commit is contained in:
parent
92a3ff9b2a
commit
0c544409dd
@ -158,6 +158,7 @@ private:
|
||||
void UpdateActiveZoneSet(_In_opt_ IZoneSet* zoneSet) noexcept;
|
||||
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||
void OnPaint(HDC hdc) noexcept;
|
||||
void OnPaintD2D() noexcept;
|
||||
void OnKeyUp(WPARAM wparam) noexcept;
|
||||
std::vector<size_t> ZonesFromPoint(POINT pt) noexcept;
|
||||
void CycleActiveZoneSetInternal(DWORD wparam, Trace::ZoneWindow::InputMode mode) noexcept;
|
||||
@ -181,6 +182,7 @@ private:
|
||||
std::atomic<bool> m_animating;
|
||||
OnThreadExecutor m_paintExecutor;
|
||||
ULONG_PTR gdiplusToken;
|
||||
std::unique_ptr<ZoneWindowDrawing> m_zoneWindowDrawing;
|
||||
};
|
||||
|
||||
ZoneWindow::ZoneWindow(HINSTANCE hinstance)
|
||||
@ -240,6 +242,7 @@ bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monit
|
||||
|
||||
MakeWindowTransparent(m_window.get());
|
||||
|
||||
m_zoneWindowDrawing = std::make_unique<ZoneWindowDrawing>(m_window.get());
|
||||
// Ignore flashZones
|
||||
/*
|
||||
if (flashZones)
|
||||
@ -596,12 +599,12 @@ LRESULT ZoneWindow::WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept
|
||||
|
||||
case WM_PRINTCLIENT:
|
||||
{
|
||||
OnPaint(reinterpret_cast<HDC>(wparam));
|
||||
// OnPaint(reinterpret_cast<HDC>(wparam));
|
||||
}
|
||||
break;
|
||||
case WM_PAINT:
|
||||
{
|
||||
OnPaint(NULL);
|
||||
OnPaintD2D();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -659,6 +662,12 @@ void ZoneWindow::OnPaint(HDC hdc) noexcept
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneWindow::OnPaintD2D() noexcept
|
||||
{
|
||||
m_zoneWindowDrawing->DrawActiveZoneSet(m_activeZoneSet->GetZones(), m_highlightZone, m_host);
|
||||
m_zoneWindowDrawing->Render();
|
||||
}
|
||||
|
||||
void ZoneWindow::OnKeyUp(WPARAM wparam) noexcept
|
||||
{
|
||||
bool fRedraw = false;
|
||||
|
@ -34,11 +34,172 @@ namespace ZoneWindowDrawingNS
|
||||
|
||||
class ZoneWindowDrawing
|
||||
{
|
||||
struct DrawableRect
|
||||
{
|
||||
D2D1_RECT_F rect;
|
||||
D2D1_COLOR_F borderColor;
|
||||
D2D1_COLOR_F fillColor;
|
||||
};
|
||||
|
||||
HWND m_window;
|
||||
winrt::com_ptr<IZoneWindowHost> m_host;
|
||||
RECT m_clientRect;
|
||||
// winrt::com_ptr<IZoneWindowHost> m_host;
|
||||
ID2D1HwndRenderTarget* m_renderTarget;
|
||||
|
||||
std::mutex m_sceneMutex;
|
||||
std::vector<DrawableRect> m_sceneRects;
|
||||
std::vector<DrawableRect> m_sceneLabels;
|
||||
|
||||
void DrawBackdrop()
|
||||
{
|
||||
m_renderTarget->Clear(D2D1::ColorF(0.f, 0.f, 0.f, 0.f));
|
||||
}
|
||||
|
||||
static ID2D1Factory* GetD2DFactory()
|
||||
{
|
||||
static ID2D1Factory* pD2DFactory = 0;
|
||||
if (!pD2DFactory)
|
||||
{
|
||||
D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &pD2DFactory);
|
||||
}
|
||||
return pD2DFactory;
|
||||
|
||||
// TODO: Destroy factory
|
||||
}
|
||||
|
||||
static D2D1_COLOR_F ConvertColor(COLORREF color)
|
||||
{
|
||||
return D2D1::ColorF(GetRValue(color) / 255.f,
|
||||
GetGValue(color) / 255.f,
|
||||
GetBValue(color) / 255.f,
|
||||
1.f);
|
||||
}
|
||||
|
||||
static D2D1_RECT_F ConvertRect(RECT rect)
|
||||
{
|
||||
return D2D1::RectF(rect.left, rect.top, rect.right, rect.bottom);
|
||||
}
|
||||
|
||||
public:
|
||||
ZoneWindowDrawing(HWND window);
|
||||
void StartAnimation(unsigned millis);
|
||||
void DrawActiveZoneSet(const std::vector<winrt::com_ptr<IZone>>& zones, const std::vector<size_t>& highlightZones);
|
||||
};
|
||||
ZoneWindowDrawing(HWND window)
|
||||
{
|
||||
m_window = window;
|
||||
|
||||
// Obtain the size of the drawing area.
|
||||
GetClientRect(window, &m_clientRect);
|
||||
|
||||
// Create a Direct2D render target
|
||||
GetD2DFactory()->CreateHwndRenderTarget(
|
||||
D2D1::RenderTargetProperties(
|
||||
D2D1_RENDER_TARGET_TYPE_DEFAULT,
|
||||
D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED)),
|
||||
D2D1::HwndRenderTargetProperties(
|
||||
window,
|
||||
D2D1::SizeU(
|
||||
m_clientRect.right - m_clientRect.left,
|
||||
m_clientRect.bottom - m_clientRect.top)),
|
||||
&m_renderTarget);
|
||||
}
|
||||
|
||||
void Render()
|
||||
{
|
||||
std::unique_lock lock(m_sceneMutex);
|
||||
|
||||
m_renderTarget->BeginDraw();
|
||||
DrawBackdrop();
|
||||
|
||||
for (const auto& drawableRect : m_sceneRects)
|
||||
{
|
||||
ID2D1SolidColorBrush* borderBrush = NULL;
|
||||
ID2D1SolidColorBrush* fillBrush = NULL;
|
||||
// TODO: hresult and null checks
|
||||
m_renderTarget->CreateSolidColorBrush(drawableRect.borderColor, &borderBrush);
|
||||
m_renderTarget->CreateSolidColorBrush(drawableRect.fillColor, &fillBrush);
|
||||
|
||||
if (fillBrush)
|
||||
{
|
||||
m_renderTarget->FillRectangle(drawableRect.rect, fillBrush);
|
||||
fillBrush->Release();
|
||||
}
|
||||
|
||||
if (borderBrush)
|
||||
{
|
||||
m_renderTarget->DrawRectangle(drawableRect.rect, borderBrush);
|
||||
borderBrush->Release();
|
||||
}
|
||||
}
|
||||
|
||||
m_renderTarget->EndDraw();
|
||||
}
|
||||
|
||||
void StartAnimation(unsigned millis)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DrawActiveZoneSet(const std::vector<winrt::com_ptr<IZone>>& zones,
|
||||
const std::vector<size_t>& highlightZones,
|
||||
winrt::com_ptr<IZoneWindowHost> host)
|
||||
{
|
||||
std::unique_lock lock(m_sceneMutex);
|
||||
|
||||
m_sceneRects = {};
|
||||
|
||||
auto borderColor = ConvertColor(host->GetZoneBorderColor());
|
||||
auto inactiveColor = ConvertColor(host->GetZoneColor());
|
||||
auto highlightColor = ConvertColor(host->GetZoneHighlightColor());
|
||||
|
||||
inactiveColor.a = host->GetZoneHighlightOpacity() / 255.f;
|
||||
highlightColor.a = host->GetZoneHighlightOpacity() / 255.f;
|
||||
|
||||
std::vector<bool> isHighlighted(zones.size(), false);
|
||||
for (size_t x : highlightZones)
|
||||
{
|
||||
isHighlighted[x] = true;
|
||||
}
|
||||
|
||||
// First draw the inactive zones
|
||||
for (auto iter = zones.begin(); iter != zones.end(); iter++)
|
||||
{
|
||||
int zoneId = static_cast<int>(iter - zones.begin());
|
||||
winrt::com_ptr<IZone> zone = iter->try_as<IZone>();
|
||||
if (!zone)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isHighlighted[zoneId])
|
||||
{
|
||||
DrawableRect drawableRect{
|
||||
.rect = ConvertRect(zone->GetZoneRect()),
|
||||
.borderColor = borderColor,
|
||||
.fillColor = inactiveColor
|
||||
};
|
||||
|
||||
m_sceneRects.push_back(drawableRect);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the active zones on top of the inactive zones
|
||||
for (auto iter = zones.begin(); iter != zones.end(); iter++)
|
||||
{
|
||||
int zoneId = static_cast<int>(iter - zones.begin());
|
||||
winrt::com_ptr<IZone> zone = iter->try_as<IZone>();
|
||||
if (!zone)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isHighlighted[zoneId])
|
||||
{
|
||||
DrawableRect drawableRect{
|
||||
.rect = ConvertRect(zone->GetZoneRect()),
|
||||
.borderColor = borderColor,
|
||||
.fillColor = highlightColor
|
||||
};
|
||||
|
||||
m_sceneRects.push_back(drawableRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user