[ScreenRuler]Add setting to show the measurement in an extra unit (#35887)

* display ruler: supporting millimeter and other units

* Measurement Tool: UI Setting for an extra unit

* Update images

* spelling

* spelling

* suit code style

* Fix for code review

* remove weird file

* rename field
This commit is contained in:
Wenjian Chern 2024-12-06 06:02:17 +08:00 коммит произвёл GitHub
Родитель 076461e460
Коммит 09ce610dbb
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
26 изменённых файлов: 333 добавлений и 101 удалений

5
.github/actions/spell-check/expect.txt поставляемый
Просмотреть файл

@ -341,6 +341,7 @@ devblogs
devdocs
devenum
devmgmt
DEVMODE
DEVMODEW
DEVMON
devpkey
@ -607,6 +608,7 @@ hmenu
hmodule
hmonitor
homljgmgpmcbpjbnjpfijnhipfkiclkd
HORZSIZE
Hostbackdropbrush
hotkeycontrol
hotkeys
@ -1129,6 +1131,7 @@ pcelt
pch
pchast
PCIDLIST
PCTSTR
PCWSTR
pdbs
pdisp
@ -1272,6 +1275,7 @@ RAlt
Rasterize
RAWINPUTDEVICE
RAWINPUTHEADER
RAWMODE
RAWPATH
rbhid
rclsid
@ -1723,6 +1727,7 @@ VERBW
VERIFYCONTEXT
verrsrc
VERSIONINFO
VERTSIZE
VFT
vget
vgetq

Двоичные данные
doc/images/overview/MeasureTool_large.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 36 KiB

После

Ширина:  |  Высота:  |  Размер: 59 KiB

Двоичные данные
doc/images/overview/MeasureTool_small.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 18 KiB

После

Ширина:  |  Высота:  |  Размер: 19 KiB

Просмотреть файл

@ -52,3 +52,55 @@ MonitorInfo MonitorInfo::GetPrimaryMonitor()
}
return monitors[0];
}
MonitorInfo MonitorInfo::GetFromWindow(const HWND window)
{
auto monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONULL);
return MonitorInfo::MonitorInfo(monitor);
}
MonitorInfo MonitorInfo::GetFromPoint(int32_t x, int32_t y)
{
auto monitor = MonitorFromPoint(POINT{ x, y }, MONITOR_DEFAULTTONULL);
return MonitorInfo::MonitorInfo(monitor);
}
MonitorInfo::Size MonitorInfo::GetSize(const MONITORINFOEX& monitorInfoEx)
{
Size size = {};
auto device_name = PCTSTR(monitorInfoEx.szDevice);
auto hdc = CreateDC(device_name, nullptr, nullptr, nullptr);
size.width_mm = static_cast<float>(GetDeviceCaps(hdc, HORZSIZE));
size.height_mm = static_cast<float>(GetDeviceCaps(hdc, VERTSIZE));
if (hdc != nullptr)
{
ReleaseDC(nullptr, hdc);
}
auto monitor = &monitorInfoEx.rcMonitor;
size.width_logical = static_cast<uint32_t>(monitor->right - monitor->left);
size.height_logical = static_cast<uint32_t>(monitor->bottom - monitor->top);
DEVMODE dev_mode = { .dmSize = sizeof DEVMODE };
if (EnumDisplaySettingsEx(device_name, ENUM_CURRENT_SETTINGS, &dev_mode, EDS_RAWMODE))
{
size.width_physical = dev_mode.dmPelsWidth;
size.height_physical = dev_mode.dmPelsHeight;
}
return size;
}
MonitorInfo::Size MonitorInfo::GetSize() const
{
if (this->handle)
{
return MonitorInfo::GetSize(this->info);
}
else
{
return MonitorInfo::Size{};
}
}

Просмотреть файл

@ -1,4 +1,5 @@
#pragma once
#pragma comment(lib, "Gdi32.lib")
#include <Windows.h>
#include <compare>
@ -42,6 +43,15 @@ struct Box
class MonitorInfo
{
public:
typedef struct Size
{
uint32_t width_logical, height_logical;
uint32_t width_physical, height_physical;
float width_mm, height_mm;
} Size;
private:
HMONITOR handle;
MONITORINFOEX info = {};
@ -53,8 +63,14 @@ public:
}
Box GetScreenSize(const bool includeNonWorkingArea) const;
bool IsPrimary() const;
Size GetSize() const;
// Returns monitor rects ordered from left to right
static std::vector<MonitorInfo> GetMonitors(bool includeNonWorkingArea);
static MonitorInfo GetPrimaryMonitor();
static MonitorInfo GetFromWindow(HWND);
static MonitorInfo GetFromPoint(int32_t, int32_t);
private:
static Size GetSize(const MONITORINFOEX&);
};

Просмотреть файл

@ -9,7 +9,7 @@
namespace
{
Measurement GetMeasurement(const CursorDrag& currentBounds, POINT cursorPos)
Measurement GetMeasurement(const CursorDrag& currentBounds, POINT cursorPos, float px2mmRatio)
{
D2D1_RECT_F rect;
std::tie(rect.left, rect.right) =
@ -17,7 +17,7 @@ namespace
std::tie(rect.top, rect.bottom) =
std::minmax(static_cast<float>(cursorPos.y), currentBounds.startPos.y);
return Measurement(rect);
return Measurement(rect, px2mmRatio);
}
void CopyToClipboard(HWND window, const BoundsToolState& toolState, POINT cursorPos)
@ -29,7 +29,8 @@ namespace
if (handle == window && perScreen.currentBounds)
{
allMeasurements.push_back(GetMeasurement(*perScreen.currentBounds, cursorPos));
auto px2mmRatio = toolState.commonState->GetPhysicalPx2MmRatio(window);
allMeasurements.push_back(GetMeasurement(*perScreen.currentBounds, cursorPos, px2mmRatio));
}
}
@ -85,7 +86,8 @@ namespace
if (const bool shiftPress = GetKeyState(VK_SHIFT) & 0x80000; shiftPress && perScreen.currentBounds)
{
perScreen.measurements.push_back(GetMeasurement(*perScreen.currentBounds, cursorPos));
auto px2mmRatio = toolState->commonState->GetPhysicalPx2MmRatio(window);
perScreen.measurements.push_back(GetMeasurement(*perScreen.currentBounds, cursorPos, px2mmRatio));
}
perScreen.currentBounds = std::nullopt;
@ -274,7 +276,7 @@ namespace
text.buffer.size(),
true,
true,
commonState.units);
commonState.units | Measurement::Unit::Pixel); // Always show pixels.
D2D_POINT_2F textBoxPos;
if (textBoxCenter)
@ -314,6 +316,7 @@ void DrawBoundsToolTick(const CommonState& commonState,
D2D1_RECT_F rect;
std::tie(rect.left, rect.right) = std::minmax(perScreen.currentBounds->startPos.x, perScreen.currentBounds->currentPos.x);
std::tie(rect.top, rect.bottom) = std::minmax(perScreen.currentBounds->startPos.y, perScreen.currentBounds->currentPos.y);
DrawMeasurement(Measurement{ rect }, commonState, window, d2dState, perScreen.currentBounds->currentPos);
auto px2mmRatio = toolState.commonState->GetPhysicalPx2MmRatio(window);
DrawMeasurement(Measurement{ rect, px2mmRatio }, commonState, window, d2dState, perScreen.currentBounds->currentPos);
}
}

Просмотреть файл

@ -65,7 +65,7 @@ D2DState::D2DState(const DxgiAPI* dxgi,
void D2DState::DrawTextBox(const wchar_t* text,
const size_t textLen,
const std::optional<size_t> halfOpaqueSymbolPos,
const size_t halfOpaqueSymbolPos[2],
const D2D_POINT_2F center,
const bool screenQuadrantAware,
const HWND window) const
@ -80,8 +80,7 @@ void D2DState::DrawTextBox(const wchar_t* text,
&textLayout));
DWRITE_TEXT_METRICS textMetrics = {};
winrt::check_hresult(textLayout->GetMetrics(&textMetrics));
// Assumes text doesn't contain new lines
const float lineHeight = textMetrics.height;
const float lineHeight = textMetrics.height / (textMetrics.lineCount ? textMetrics.lineCount : 1);
textMetrics.width += lineHeight;
textMetrics.height += lineHeight * .5f;
winrt::check_hresult(textLayout->SetMaxWidth(textMetrics.width));
@ -147,12 +146,17 @@ void D2DState::DrawTextBox(const wchar_t* text,
// Draw text & its box
dxgiWindowState.rt->FillRoundedRectangle(textBoxRect, solidBrushes[Brush::background].get());
if (halfOpaqueSymbolPos.has_value())
if (halfOpaqueSymbolPos[0] > 0)
{
DWRITE_TEXT_RANGE textRange = { static_cast<uint32_t>(*halfOpaqueSymbolPos), 2 };
auto opacityEffect = winrt::make_self<OpacityEffect>();
opacityEffect->alpha = consts::CROSS_OPACITY;
winrt::check_hresult(textLayout->SetDrawingEffect(opacityEffect.get(), textRange));
if (halfOpaqueSymbolPos[1] > halfOpaqueSymbolPos[0])
{
textRange = { static_cast<uint32_t>(halfOpaqueSymbolPos[1]), 2 };
winrt::check_hresult(textLayout->SetDrawingEffect(opacityEffect.get(), textRange));
}
}
winrt::check_hresult(textLayout->Draw(nullptr, textRenderer.get(), textRect.left, textRect.top));
}

Просмотреть файл

@ -35,7 +35,7 @@ struct D2DState
std::vector<D2D1::ColorF> solidBrushesColors);
void DrawTextBox(const wchar_t* text,
const size_t textLen,
const std::optional<size_t> halfOpaqueSymbolPos,
const size_t halfOpaqueSymbolPos[2],
const D2D_POINT_2F center,
const bool screenQuadrantAware,
const HWND window) const;

Просмотреть файл

@ -19,17 +19,17 @@ namespace
{
switch (mode)
{
case MeasureToolState::Mode::Cross:
return { true, true };
case MeasureToolState::Mode::Cross:
return { true, true };
case MeasureToolState::Mode::Vertical:
return { false, true };
case MeasureToolState::Mode::Vertical:
return { false, true };
case MeasureToolState::Mode::Horizontal:
return { true, false };
case MeasureToolState::Mode::Horizontal:
return { true, false };
default:
throw std::runtime_error("Unknown MeasureToolState Mode");
default:
throw std::runtime_error("Unknown MeasureToolState Mode");
}
}
@ -77,7 +77,7 @@ namespace
CopyToClipboard(window, *toolState);
auto& perScreen = toolState->perScreen[window];
const bool shiftPress = GetKeyState(VK_SHIFT) & 0x8000;
if (shiftPress && perScreen.measuredEdges)
{
@ -144,10 +144,10 @@ namespace
const auto [crossSymbolPos, measureStringBufLen] =
measurement.Print(text.buffer.data(),
text.buffer.size(),
drawHorizontalCrossLine,
drawVerticalCrossLine,
commonState.units);
text.buffer.size(),
drawHorizontalCrossLine,
drawVerticalCrossLine,
commonState.units | Measurement::Unit::Pixel); // Always show pixels.
d2dState.DrawTextBox(text.buffer.data(),
measureStringBufLen,

Просмотреть файл

@ -4,7 +4,8 @@
#include <iostream>
Measurement::Measurement(RECT winRect)
Measurement::Measurement(RECT winRect, float px2mmRatio) :
px2mmRatio{ px2mmRatio }
{
rect.left = static_cast<float>(winRect.left);
rect.right = static_cast<float>(winRect.right);
@ -12,81 +13,192 @@ Measurement::Measurement(RECT winRect)
rect.bottom = static_cast<float>(winRect.bottom);
}
Measurement::Measurement(D2D1_RECT_F d2dRect) :
rect{ d2dRect }
Measurement::Measurement(D2D1_RECT_F d2dRect, float px2mmRatio) :
rect{ d2dRect }, px2mmRatio{ px2mmRatio }
{
}
namespace
{
inline float Convert(const float pixels, const Measurement::Unit units)
inline float Convert(const float pixels, const Measurement::Unit units, float px2mmRatio)
{
switch (units)
if (px2mmRatio > 0)
{
case Measurement::Unit::Pixel:
return pixels;
case Measurement::Unit::Inch:
return pixels / 96.f;
case Measurement::Unit::Centimetre:
return pixels / 96.f * 2.54f;
default:
return pixels;
switch (units)
{
case Measurement::Unit::Pixel:
return pixels;
case Measurement::Unit::Inch:
return pixels * px2mmRatio / 10.0f / 2.54f;
case Measurement::Unit::Centimetre:
return pixels * px2mmRatio / 10.0f;
case Measurement::Unit::Millimetre:
return pixels * px2mmRatio;
default:
return pixels;
}
}
else
{
switch (units)
{
case Measurement::Unit::Pixel:
return pixels;
case Measurement::Unit::Inch:
return pixels / 96.0f;
case Measurement::Unit::Centimetre:
return pixels / 96.0f * 2.54f;
case Measurement::Unit::Millimetre:
return pixels / 96.0f / 10.0f * 2.54f;
default:
return pixels;
}
}
}
}
winrt::hstring Measurement::abbreviations[4]{};
inline float Measurement::Width(const Unit units) const
{
return Convert(rect.right - rect.left + 1.f, units);
return Convert(rect.right - rect.left + 1.f, units, px2mmRatio);
}
inline float Measurement::Height(const Unit units) const
{
return Convert(rect.bottom - rect.top + 1.f, units);
return Convert(rect.bottom - rect.top + 1.f, units, px2mmRatio);
}
Measurement::Unit Measurement::GetUnitFromIndex(int index)
{
switch (index)
{
case 0:
return Measurement::Unit::Pixel;
case 1:
return Measurement::Unit::Inch;
case 2:
return Measurement::Unit::Centimetre;
case 3:
return Measurement::Unit::Millimetre;
default:
return Measurement::Unit::Pixel;
}
}
void Measurement::InitResources()
{
auto rm = winrt::ResourceManager{};
auto mm = rm.MainResourceMap();
abbreviations[0] = mm.GetValue(L"Resources/MeasurementUnitAbbrPixel").ValueAsString();
abbreviations[1] = mm.GetValue(L"Resources/MeasurementUnitAbbrInch").ValueAsString();
abbreviations[2] = mm.GetValue(L"Resources/MeasurementUnitAbbrCentimetre").ValueAsString();
abbreviations[3] = mm.GetValue(L"Resources/MeasurementUnitAbbrMillimetre").ValueAsString();
}
const wchar_t* Measurement::GetUnitAbbreviation(Measurement::Unit units)
{
switch (units)
{
case Unit::Pixel:
return abbreviations[0].c_str();
case Unit::Inch:
return abbreviations[1].c_str();
case Unit::Centimetre:
return abbreviations[2].c_str();
case Unit::Millimetre:
return abbreviations[3].c_str();
default:
return L"??";
}
}
Measurement::PrintResult Measurement::Print(wchar_t* buf,
const size_t bufSize,
const bool printWidth,
const bool printHeight,
const Unit units) const
const int units) const
{
PrintResult result;
if (printWidth)
{
result.strLen += swprintf_s(buf,
bufSize,
L"%g",
Width(units));
if (printHeight)
auto print = [=, &result](Measurement::Unit unit, const bool paren) {
if (paren)
{
result.strLen += swprintf_s(buf + result.strLen, bufSize - result.strLen, printWidth && printHeight ? L"\n(" : L" (");
}
if (printWidth)
{
result.crossSymbolPos = result.strLen + 1;
result.strLen += swprintf_s(buf + result.strLen,
bufSize - result.strLen,
L" \x00D7 ");
L"%.4g",
Width(unit));
if (printHeight)
{
result.crossSymbolPos[paren] = result.strLen + 1;
result.strLen += swprintf_s(buf + result.strLen,
bufSize - result.strLen,
L" \x00D7 ");
}
}
}
if (printHeight)
{
result.strLen += swprintf_s(buf + result.strLen,
bufSize - result.strLen,
L"%.4g",
Height(unit));
}
switch (unit)
{
case Measurement::Unit::Pixel:
result.strLen += swprintf_s(buf + result.strLen,
bufSize - result.strLen,
L" %s",
Measurement::GetUnitAbbreviation(unit));
break;
case Measurement::Unit::Inch:
result.strLen += swprintf_s(buf + result.strLen,
bufSize - result.strLen,
L" %s",
Measurement::GetUnitAbbreviation(unit));
break;
case Measurement::Unit::Centimetre:
result.strLen += swprintf_s(buf + result.strLen,
bufSize - result.strLen,
L" %s",
Measurement::GetUnitAbbreviation(unit));
if (printHeight)
{
result.strLen += swprintf_s(buf + result.strLen,
bufSize - result.strLen,
L"%g",
Height(units));
}
break;
case Measurement::Unit::Millimetre:
result.strLen += swprintf_s(buf + result.strLen,
bufSize - result.strLen,
L" %s",
Measurement::GetUnitAbbreviation(unit));
switch (units)
break;
}
if (paren)
{
result.strLen += swprintf_s(buf + result.strLen, bufSize - result.strLen, L")");
}
};
int count = 0;
const Measurement::Unit allUnits[] = {
Measurement::Unit::Pixel,
Measurement::Unit::Millimetre,
Measurement::Unit::Inch,
Measurement::Unit::Centimetre,
};
// We only use two units at most, it would be to long otherwise.
for each (Measurement::Unit unit in allUnits)
{
case Measurement::Unit::Inch:
result.strLen += swprintf_s(buf + result.strLen,
bufSize - result.strLen,
L" in");
break;
case Measurement::Unit::Centimetre:
result.strLen += swprintf_s(buf + result.strLen,
bufSize - result.strLen,
L" cm");
break;
if ((unit & units) == unit)
{
count += 1;
if (count > 2)
break;
print(unit, count != 1);
}
}
return result;
@ -117,15 +229,9 @@ void Measurement::PrintToStream(std::wostream& stream,
stream << Height(units);
}
switch (units)
// If the unit is pixels, then the abbreviation will not be saved as it used to be.
if (units != Measurement::Unit::Pixel)
{
case Measurement::Unit::Inch:
stream << L" in";
break;
case Measurement::Unit::Centimetre:
stream << L" cm";
break;
stream << L" " << Measurement::GetUnitAbbreviation(units);
}
}

Просмотреть файл

@ -1,4 +1,5 @@
#pragma once
#include "pch.h"
#include <dcommon.h>
#include <windef.h>
@ -8,38 +9,45 @@ struct Measurement
{
enum Unit
{
Pixel,
Inch,
Centimetre
Pixel = 1,
Inch = 2,
Centimetre = 4,
Millimetre = 8,
};
D2D1_RECT_F rect = {}; // corners are inclusive
Measurement() = default;
float px2mmRatio = 0;
static winrt::hstring abbreviations[4]; // Abbreviations of units.
Measurement(const Measurement&) = default;
Measurement& operator=(const Measurement&) = default;
explicit Measurement(D2D1_RECT_F d2dRect);
explicit Measurement(RECT winRect);
explicit Measurement(D2D1_RECT_F d2dRect, float px2mmRatio);
explicit Measurement(RECT winRect, float px2mmRatio);
float Width(const Unit units) const;
float Height(const Unit units) const;
struct PrintResult
{
std::optional<size_t> crossSymbolPos;
size_t crossSymbolPos[2] = {};
size_t strLen = {};
};
static void InitResources();
static Unit GetUnitFromIndex(int index);
static const wchar_t* GetUnitAbbreviation(const Unit units);
PrintResult Print(wchar_t* buf,
const size_t bufSize,
const bool printWidth,
const bool printHeight,
const Unit units) const;
const int units) const;
void PrintToStream(std::wostream& stream,
const bool prependNewLine,
const bool printWidth,
const bool printHeight,
const Unit units) const;
const bool prependNewLine,
const bool printWidth,
const bool printHeight,
const Unit units) const;
};

Просмотреть файл

@ -62,6 +62,11 @@ namespace winrt::PowerToys::MeasureToolCore::implementation
_mouseCaptureThread.join();
}
void Core::InitResources()
{
Measurement::InitResources();
}
void Core::ResetState()
{
_commonState.closeOnOtherMonitors = true;

Просмотреть файл

@ -32,6 +32,7 @@ namespace winrt::PowerToys::MeasureToolCore::implementation
~Core();
void Close();
void InitResources();
void StartBoundsTool();
void StartMeasureTool(const bool horizontal, const bool vertical);
void SetToolCompletionEvent(ToolSessionCompleted sessionCompletedTrigger);
@ -45,7 +46,7 @@ namespace winrt::PowerToys::MeasureToolCore::implementation
wil::shared_event _stopMouseCaptureThreadSignal;
std::thread _mouseCaptureThread;
std::vector<std::thread> _screenCaptureThreads;
std::vector<std::unique_ptr<OverlayUIState>> _overlayUIStates;
Serialized<MeasureToolState> _measureToolState;
BoundsToolState _boundsToolState;

Просмотреть файл

@ -19,6 +19,7 @@ namespace PowerToys
void StartBoundsTool();
void ResetState();
void InitResources();
void SetToolbarBoundingBox(Int32 fromX, Int32 fromY, Int32 toX, Int32 toY);
Single GetDPIScaleForWindow(Int64 windowHandle);
}

Просмотреть файл

@ -294,11 +294,12 @@ void UpdateCaptureState(const CommonState& commonState,
cursorPos,
perColorChannelEdgeDetection,
pixelTolerance);
auto px2mmRatio = commonState.GetPhysicalPx2MmRatio(window);
#if defined(DEBUG_EDGES)
char buffer[256];
sprintf_s(buffer,
"Cursor: [%ld,%ld] Bounds: [%ld,%ld]-[%ld,%ld] Screen size: [%zu, %zu]\n",
"Cursor: [%ld,%ld] Bounds: [%ld,%ld]-[%ld,%ld] Screen size: [%zu, %zu] Ratio: %g\n",
cursorPos.x,
cursorPos.y,
bounds.left,
@ -306,11 +307,12 @@ void UpdateCaptureState(const CommonState& commonState,
bounds.right,
bounds.bottom,
textureView.view.width,
textureView.view.height);
textureView.view.height,
px2mmRatio);
OutputDebugStringA(buffer);
#endif
state.Access([&](MeasureToolState& state) {
state.perScreen[window].measuredEdges = Measurement{ bounds };
state.perScreen[window].measuredEdges = Measurement{ bounds, px2mmRatio };
});
}

Просмотреть файл

@ -69,7 +69,8 @@ Settings Settings::LoadFromFile()
try
{
result.units = static_cast<Measurement::Unit>(props.GetNamedObject(JSON_KEY_UNITS_OF_MEASURE).GetNamedNumber(JSON_KEY_VALUE));
auto index = static_cast<int>(props.GetNamedObject(JSON_KEY_UNITS_OF_MEASURE).GetNamedNumber(JSON_KEY_VALUE));
result.units = Measurement::GetUnitFromIndex(index);
}
catch (...)
{

Просмотреть файл

@ -33,6 +33,17 @@ struct CommonState
POINT cursorPosSystemSpace = {}; // updated atomically
std::atomic_bool closeOnOtherMonitors = false;
float GetPhysicalPx2MmRatio(HWND window) const
{
auto ratio = -1.0f;
auto size = MonitorInfo::GetFromWindow(window).GetSize();
if (size.width_physical > 0u)
{
ratio = size.width_mm / static_cast<float>(size.width_physical);
}
return ratio;
}
};
struct CursorDrag

Просмотреть файл

@ -49,6 +49,7 @@
#include <winrt/Microsoft.UI.Xaml.Navigation.h>
#include <winrt/Microsoft.UI.Xaml.Shapes.h>
#include <winrt/Microsoft.UI.Dispatching.h>
#include <winrt/Microsoft.Windows.ApplicationModel.Resources.h>
#include <winrt/Windows.Graphics.DirectX.h>
#include <winrt/Windows.Graphics.DirectX.Direct3d11.h>
#include <winrt/Windows.Graphics.Capture.h>
@ -73,6 +74,7 @@ namespace winrt
using namespace Microsoft::UI::Xaml;
using namespace Microsoft::UI::Xaml::Controls;
using namespace Microsoft::UI::Xaml::Navigation;
using namespace Microsoft::Windows::ApplicationModel::Resources;
}
template<typename Func>

Просмотреть файл

@ -4,7 +4,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:p="using:PowerToys.MeasureToolUI.Properties"
xmlns:winuiex="using:WinUIEx"
IsAlwaysOnTop="True"
IsMaximizable="False"

Просмотреть файл

@ -64,6 +64,7 @@ namespace MeasureToolUI
_ = SetWindowLong(hwnd, GWL_STYLE, windowStyle);
_coreLogic = core;
_coreLogic.InitResources();
Closed += MainWindow_Closed;
DisplayArea displayArea = DisplayArea.GetFromWindowId(windowId, DisplayAreaFallback.Nearest);
float dpiScale = _coreLogic.GetDPIScaleForWindow((int)hwnd);

Просмотреть файл

@ -66,4 +66,16 @@
<data name="BtnClosePanelTooltip.Text" xml:space="preserve">
<value>Close (Esc)</value>
</data>
<data name="MeasurementUnitAbbrPixel" xml:space="preserve">
<value>px</value>
</data>
<data name="MeasurementUnitAbbrInch" xml:space="preserve">
<value>in</value>
</data>
<data name="MeasurementUnitAbbrCentimetre" xml:space="preserve">
<value>cm</value>
</data>
<data name="MeasurementUnitAbbrMillimetre" xml:space="preserve">
<value>mm</value>
</data>
</root>

Просмотреть файл

@ -38,7 +38,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonConverter(typeof(BoolPropertyJsonConverter))]
public bool PerColorChannelEdgeDetection { get; set; }
[CmdConfigureIgnore]
public IntProperty UnitsOfMeasure { get; set; }
public IntProperty PixelTolerance { get; set; }

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 403 KiB

После

Ширина:  |  Высота:  |  Размер: 599 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 29 KiB

После

Ширина:  |  Высота:  |  Размер: 59 KiB

Просмотреть файл

@ -64,13 +64,14 @@
Value="{x:Bind ViewModel.PixelTolerance, Mode=TwoWay}" />
</tkcontrols:SettingsCard>
<!--<tkcontrols:SettingsCard x:Uid="MeasureTool_UnitsOfMeasure" HeaderIcon="{ui:FontIcon Glyph=&#xECC6;}">
<ComboBox SelectedIndex="{x:Bind Path=ViewModel.UnitsOfMeasure, Mode=TwoWay}" MinWidth="{StaticResource SettingActionControlMinWidth}">
<tkcontrols:SettingsCard x:Uid="MeasureTool_UnitsOfMeasure" HeaderIcon="{ui:FontIcon Glyph=&#xECC6;}">
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind Path=ViewModel.UnitsOfMeasure, Mode=TwoWay}">
<ComboBoxItem x:Uid="MeasureTool_UnitsOfMeasure_Pixels" />
<ComboBoxItem x:Uid="MeasureTool_UnitsOfMeasure_Inches" />
<ComboBoxItem x:Uid="MeasureTool_UnitsOfMeasure_Centimeters" />
<ComboBoxItem x:Uid="MeasureTool_UnitsOfMeasure_Millimeters" />
</ComboBox>
</tkcontrols:SettingsCard>-->
</tkcontrols:SettingsCard>
<tkcontrols:SettingsCard x:Uid="MeasureTool_DrawFeetOnCross">
<ToggleSwitch x:Uid="MeasureTool_DrawFeetOnCross_ToggleSwitch" IsOn="{x:Bind ViewModel.DrawFeetOnCross, Mode=TwoWay}" />

Просмотреть файл

@ -177,10 +177,10 @@
<value>Vertical spacing</value>
</data>
<data name="MeasureTool_UnitsOfMeasure.Header" xml:space="preserve">
<value>Units of measurement</value>
<value>Extra units of measurement</value>
</data>
<data name="MeasureTool_UnitsOfMeasure_Pixels.Content" xml:space="preserve">
<value>Pixels</value>
<value>Show only pixels</value>
</data>
<data name="MeasureTool_UnitsOfMeasure_Inches.Content" xml:space="preserve">
<value>Inches</value>
@ -188,6 +188,9 @@
<data name="MeasureTool_UnitsOfMeasure_Centimeters.Content" xml:space="preserve">
<value>Centimeters</value>
</data>
<data name="MeasureTool_UnitsOfMeasure_Millimeters.Content" xml:space="preserve">
<value>Millimeters</value>
</data>
<data name="MeasureTool_PixelTolerance.Header" xml:space="preserve">
<value>Pixel tolerance for edge detection</value>
</data>