[FancyZones] Zone title bar pager and buttons styles

This commit is contained in:
float4
2022-05-14 00:00:00 +00:00
parent 10003cb110
commit eaf128cc99
14 changed files with 806 additions and 400 deletions

View File

@@ -86,7 +86,7 @@ void FancyZonesApp::InitHooks()
}
}
std::array<DWORD, 13> events_to_subscribe = {
std::array<DWORD, 12> events_to_subscribe = {
EVENT_SYSTEM_MOVESIZESTART,
EVENT_SYSTEM_MOVESIZEEND,
EVENT_OBJECT_NAMECHANGE,
@@ -98,8 +98,7 @@ void FancyZonesApp::InitHooks()
EVENT_SYSTEM_MINIMIZEEND,
EVENT_OBJECT_HIDE,
EVENT_OBJECT_DESTROY,
EVENT_SYSTEM_FOREGROUND,
EVENT_OBJECT_FOCUS
EVENT_OBJECT_REORDER
};
for (const auto event : events_to_subscribe)
{
@@ -179,8 +178,7 @@ void FancyZonesApp::HandleWinHookEvent(WinHookEvent* data) noexcept
case EVENT_SYSTEM_MINIMIZEEND:
case EVENT_OBJECT_HIDE:
case EVENT_OBJECT_DESTROY:
case EVENT_SYSTEM_FOREGROUND:
case EVENT_OBJECT_FOCUS:
case EVENT_OBJECT_REORDER:
{
fzCallback->HandleWinHookEvent(data);
}

View File

@@ -15,17 +15,7 @@ void CompositionDrawing::Init(HWND window)
}
// Create devices
D2D1_FACTORY_OPTIONS options = {
#ifdef _DEBUG
D2D1_DEBUG_LEVEL_INFORMATION
#endif
};
D2D1CreateFactory(
D2D1_FACTORY_TYPE_MULTI_THREADED,
__uuidof(m_d2dFactory),
&options,
m_d2dFactory.put_void());
m_d2dFactory.copy_from(GetD2DFactory());
if (!m_d2dFactory)
{
return;

View File

@@ -19,11 +19,17 @@ D2D1_COLOR_F Drawing::ConvertColor(winrt::Windows::UI::Color color)
color.A / 255.f);
}
ID2D1Factory* Drawing::GetD2DFactory()
ID2D1Factory6* Drawing::GetD2DFactory()
{
static auto pD2DFactory = [] {
ID2D1Factory* res = nullptr;
D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &res);
D2D1_FACTORY_OPTIONS options = {
#ifdef _DEBUG
D2D1_DEBUG_LEVEL_INFORMATION
#endif
};
ID2D1Factory6* res = nullptr;
D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, options, &res);
return res;
}();
return pD2DFactory;
@@ -140,6 +146,28 @@ winrt::com_ptr<ID2D1SolidColorBrush> Drawing::CreateBrush(D2D1_COLOR_F color) co
return brush;
}
winrt::com_ptr<ID2D1StrokeStyle1> Drawing::CreateStroke(float stokeWidht) const
{
if (!*this)
{
return nullptr;
}
winrt::com_ptr<ID2D1StrokeStyle1> stroke = nullptr;
auto properties = D2D1::StrokeStyleProperties1(
D2D1_CAP_STYLE_ROUND,
D2D1_CAP_STYLE_ROUND,
D2D1_CAP_STYLE_ROUND,
D2D1_LINE_JOIN_ROUND,
0.0f,
D2D1_DASH_STYLE_SOLID,
0.0f);
GetD2DFactory()->CreateStrokeStyle(properties, nullptr, 0, stroke.put());
return stroke;
}
winrt::com_ptr<ID2D1Bitmap> Drawing::CreateIcon(HICON icon) const
{
if (!*this)
@@ -179,6 +207,49 @@ winrt::com_ptr<ID2D1Bitmap> Drawing::CreateIcon(HICON icon) const
return bitmap;
}
winrt::com_ptr<ID2D1PathGeometry> Drawing::CreateTriangle(const D2D1_TRIANGLE& triangle) const
{
if (!*this)
{
return nullptr;
}
winrt::com_ptr<ID2D1PathGeometry> geometry = nullptr;
GetD2DFactory()->CreatePathGeometry(geometry.put());
if (!geometry)
{
return nullptr;
}
winrt::com_ptr<ID2D1GeometrySink> tessellationSink = nullptr;
geometry->Open(tessellationSink.put());
if (!tessellationSink)
{
return nullptr;
}
tessellationSink->BeginFigure(triangle.point1, D2D1_FIGURE_BEGIN_FILLED);
tessellationSink->AddLine(triangle.point2);
tessellationSink->AddLine(triangle.point3);
tessellationSink->EndFigure(D2D1_FIGURE_END_CLOSED);
auto hr = tessellationSink->Close();
if (FAILED(hr))
{
return nullptr;
}
return geometry;
}
void Drawing::FillRectangle(const D2D1_RECT_F& rect, D2D1_COLOR_F color)
{
if (!*this)
@@ -193,7 +264,7 @@ void Drawing::FillRectangle(const D2D1_RECT_F& rect, D2D1_COLOR_F color)
}
}
void Drawing::FillRoundedRectangle(const D2D1_RECT_F& rect, D2D1_COLOR_F color)
void Drawing::FillRoundedRectangle(const D2D1_RECT_F& rect, D2D1_COLOR_F color, float radiusFactor)
{
if (!*this)
{
@@ -205,8 +276,8 @@ void Drawing::FillRoundedRectangle(const D2D1_RECT_F& rect, D2D1_COLOR_F color)
{
D2D1_ROUNDED_RECT roundedRect;
roundedRect.rect = rect;
roundedRect.radiusX = (rect.right - rect.left) * .1f;
roundedRect.radiusY = (rect.bottom - rect.top) * .1f;
roundedRect.radiusX = (rect.right - rect.left) * radiusFactor;
roundedRect.radiusY = (rect.bottom - rect.top) * radiusFactor;
auto radius = min(roundedRect.radiusX, roundedRect.radiusY);
roundedRect.radiusX = radius;
@@ -216,6 +287,40 @@ void Drawing::FillRoundedRectangle(const D2D1_RECT_F& rect, D2D1_COLOR_F color)
}
}
void Drawing::FillEllipse(const D2D1_ELLIPSE& ellipse, D2D1_COLOR_F color)
{
if (!*this)
{
return;
}
auto brush = CreateBrush(color);
if (brush)
{
m_renderTarget->FillEllipse(ellipse, brush.get());
}
}
void Drawing::FillGeometry(ID2D1PathGeometry* geometry, D2D1_COLOR_F color, float strokeWidth)
{
if (!*this)
{
return;
}
auto brush = CreateBrush(color);
auto stroke = CreateStroke(strokeWidth);
if (brush)
{
m_renderTarget->FillGeometry(geometry, brush.get());
if (stroke)
{
m_renderTarget->DrawGeometry(geometry, brush.get(), strokeWidth, stroke.get());
}
}
}
void Drawing::DrawRectangle(const D2D1_RECT_F& rect, D2D1_COLOR_F color, float strokeWidth)
{
if (!*this)

View File

@@ -2,7 +2,7 @@
#include "util.h"
#include <d2d1.h>
#include <d2d1_1.h>
#include <d2d1_3.h>
#include <dwrite.h>
#include <wincodec.h>
#include <winrt/Windows.UI.ViewManagement.h>
@@ -21,10 +21,14 @@ public:
winrt::com_ptr<IDWriteTextFormat> CreateTextFormat(LPCWSTR fontFamilyName, FLOAT fontSize, DWRITE_FONT_WEIGHT fontWeight = DWRITE_FONT_WEIGHT_NORMAL) const;
winrt::com_ptr<ID2D1SolidColorBrush> CreateBrush(D2D1_COLOR_F color) const;
winrt::com_ptr<ID2D1StrokeStyle1> CreateStroke(float stokeWidht) const;
winrt::com_ptr<ID2D1Bitmap> CreateIcon(HICON icon) const;
winrt::com_ptr<ID2D1PathGeometry> CreateTriangle(const D2D1_TRIANGLE& triangle) const;
void FillRectangle(const D2D1_RECT_F& rect, D2D1_COLOR_F color);
void FillRoundedRectangle(const D2D1_RECT_F& rect, D2D1_COLOR_F color);
void FillRoundedRectangle(const D2D1_RECT_F& rect, D2D1_COLOR_F color, float radiusFactor = .1f);
void FillEllipse(const D2D1_ELLIPSE& ellipse, D2D1_COLOR_F color);
void FillGeometry(ID2D1PathGeometry* geometry, D2D1_COLOR_F color, float strokeWidth = 1.f);
void DrawRectangle(const D2D1_RECT_F& rect, D2D1_COLOR_F color, float strokeWidth = 1.f);
void DrawRoundedRectangle(const D2D1_RECT_F& rect, D2D1_COLOR_F color, float strokeWidth = 1.f);
void DrawTextW(std::wstring text, IDWriteTextFormat* format, const D2D1_RECT_F& rect, D2D1_COLOR_F color);
@@ -34,7 +38,7 @@ public:
void EndDraw();
protected:
static ID2D1Factory* GetD2DFactory();
static ID2D1Factory6* GetD2DFactory();
static IDWriteFactory* GetWriteFactory();
static IWICImagingFactory2* GetImageFactory();

View File

@@ -158,8 +158,7 @@ public:
}
break;
case EVENT_SYSTEM_FOREGROUND:
case EVENT_OBJECT_FOCUS:
case EVENT_OBJECT_REORDER:
PostMessageW(m_window, WM_PRIV_WINDOWREORDER, wparam, lparam);
break;
}

View File

@@ -23,7 +23,11 @@ enum struct ZoneTitleBarStyle : int
AutoHideTabs = 7,
Labels = 8,
AutoHideLabels = 9,
EnumElements = 10, // number of elements in the enum, not counting this
Pager = 10,
AutoHidePager = 11,
Buttons = 12,
AutoHideButtons = 13,
EnumElements = 14, // number of elements in the enum, not counting this
};
// in reality, this file needs to be kept in sync currently with src/settings-ui/Settings.UI.Library/FZConfigProperties.cs

View File

@@ -7,10 +7,16 @@ namespace NonLocalizable
const wchar_t WindowClassName[] = L"FancyZones_Window";
}
Window::Window(HINSTANCE hinstance, WndProc proc, DWORD style, DWORD extendedStyle, FancyZonesUtils::Rect position, LPCWSTR windowName, HWND parent, HMENU menu, int showCommand) noexcept :
Window::Window() noexcept :
m_window(NULL),
m_proc(proc)
m_proc(nullptr)
{
}
void Window::Init(HINSTANCE hinstance, WndProc proc, DWORD style, DWORD extendedStyle, FancyZonesUtils::Rect position, LPCWSTR windowName, HWND parent, HMENU menu, int showCommand) noexcept
{
m_proc = proc;
static ATOM windowClass = INVALID_ATOM;
if (windowClass == INVALID_ATOM)
{

View File

@@ -7,7 +7,7 @@ using WndProc = std::function<LRESULT(HWND window, UINT message, WPARAM wparam,
class Window
{
public:
Window(HINSTANCE hinstance, WndProc proc, DWORD style, DWORD extendedStyle, FancyZonesUtils::Rect position, LPCWSTR windowName = NULL, HWND parent = NULL, HMENU menu = NULL, int show = SW_SHOWNOACTIVATE) noexcept;
Window() noexcept;
~Window();
Window(const Window&) = delete;
@@ -15,6 +15,8 @@ public:
operator HWND() const { return m_window; }
void Init(HINSTANCE hinstance, WndProc proc, DWORD style, DWORD extendedStyle, FancyZonesUtils::Rect position, LPCWSTR windowName = NULL, HWND parent = NULL, HMENU menu = NULL, int show = SW_SHOWNOACTIVATE) noexcept;
private:
static LRESULT CALLBACK s_WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) noexcept;

View File

@@ -308,7 +308,7 @@ static bool ShouldSuppressMove(HWND window, RECT zoneRect, bool suppressMove)
if (GetWindowRect(window, &windowRect))
{
// Check if window is already in rect except for the zone title bar
if (zoneRect.left == windowRect.left &&
if (zoneRect.left <= windowRect.left &&
zoneRect.right == windowRect.right &&
zoneRect.bottom == windowRect.bottom &&
zoneRect.top <= windowRect.top)
@@ -374,7 +374,7 @@ ZoneSet::MoveWindowIntoZoneByIndexSet(HWND window, HWND workAreaWindow, const Zo
if (!sizeEmpty)
{
auto zoneTitleBar = m_zoneTitleBarByIndexSets.find(indexSet);
auto zoneTitleBarHeight = 0;
FancyZonesUtils::Rect zoneTitleBarInlineFrame;
// Are we are not alone?
if (!m_windowsByIndexSets[indexSet].empty())
@@ -399,15 +399,19 @@ ZoneSet::MoveWindowIntoZoneByIndexSet(HWND window, HWND workAreaWindow, const Zo
auto dpi = GetDpiForMonitor(MonitorFromWindow(workAreaWindow, MONITOR_DEFAULTTOPRIMARY));
zoneTitleBar = m_zoneTitleBarByIndexSets.emplace(indexSet, MakeZoneTitleBar(m_config.ZoneTitleBarStyle, m_hinstance, zone, dpi)).first;
zoneTitleBarHeight = zoneTitleBar->second->GetHeight();
rect.top += zoneTitleBarHeight;
SizeWindowToRect(hwnd, rect);
zoneTitleBarInlineFrame = zoneTitleBar->second->GetInlineFrame();
auto rectForResize = AdjustRectForSizeWindowToRect(hwnd, *zoneTitleBarInlineFrame.get(), workAreaWindow);
SizeWindowToRect(hwnd, rectForResize);
}
else
{
zoneTitleBarInlineFrame = rect;
}
}
else
{
// Adjust the rect
zoneTitleBarHeight = zoneTitleBar->second->GetHeight();
zoneTitleBarInlineFrame = zoneTitleBar->second->GetInlineFrame();
}
}
@@ -420,8 +424,15 @@ ZoneSet::MoveWindowIntoZoneByIndexSet(HWND window, HWND workAreaWindow, const Zo
auto shouldSuppressMove = ShouldSuppressMove(window, rect, suppressMove);
if (!shouldSuppressMove)
{
rect.top += zoneTitleBarHeight;
SizeWindowToRect(window, rect);
if (IsRectEmpty(zoneTitleBarInlineFrame.get()))
{
SizeWindowToRect(window, rect);
}
else
{
auto rectForResize = AdjustRectForSizeWindowToRect(window, *zoneTitleBarInlineFrame.get(), workAreaWindow);
SizeWindowToRect(window, rectForResize);
}
}
auto oldBitmask = GetWindowStamp(window);

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
#pragma once
#include "util.h"
#include "Window.h"
#include "Settings.h"
@@ -10,7 +11,7 @@ public:
virtual void Show(bool show) = 0;
virtual void UpdateZoneWindows(std::vector<HWND> zoneWindows) = 0;
virtual void ReadjustPos() = 0;
virtual int GetHeight() const = 0;
virtual FancyZonesUtils::Rect GetInlineFrame() const = 0;
};
std::unique_ptr<IZoneTitleBar> MakeZoneTitleBar(ZoneTitleBarStyle style, HINSTANCE hinstance, FancyZonesUtils::Rect zone, UINT dpi);

View File

@@ -51,6 +51,10 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
AutoHideTabs = 7,
Labels = 8,
AutoHideLabels = 9,
Pager = 10,
AutoHidePager = 11,
Buttons = 12,
AutoHideButtons = 13,
}
public FancyZonesViewModel(SettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, ISettingsRepository<FancyZonesSettings> moduleSettingsRepository, Func<string, int> ipcMSGCallBackFunc, string configFileSubfolder = "")

View File

@@ -1192,6 +1192,12 @@ Made with 💗 by Microsoft and the PowerToys community.</value>
<data name="FancyZones_ZoneTitleBarStyle_Labels.Content" xml:space="preserve">
<value>Labels</value>
</data>
<data name="FancyZones_ZoneTitleBarStyle_Pager.Content" xml:space="preserve">
<value>Pager</value>
</data>
<data name="FancyZones_ZoneTitleBarStyle_Buttons.Content" xml:space="preserve">
<value>Buttons</value>
</data>
<data name="FancyZones_ZoneTitleBar_AutoHide.Header" xml:space="preserve">
<value>Auto hide</value>
</data>

View File

@@ -104,6 +104,8 @@
<ComboBoxItem x:Uid="FancyZones_ZoneTitleBarStyle_Icons" />
<ComboBoxItem x:Uid="FancyZones_ZoneTitleBarStyle_Tabs" />
<ComboBoxItem x:Uid="FancyZones_ZoneTitleBarStyle_Labels" />
<ComboBoxItem x:Uid="FancyZones_ZoneTitleBarStyle_Pager" />
<ComboBoxItem x:Uid="FancyZones_ZoneTitleBarStyle_Buttons" />
</ComboBox>
</controls:Setting.ActionContent>
</controls:Setting>