update issue template + refactor text box drawing

This commit is contained in:
Andrey Nekrasov
2022-08-23 20:45:25 +02:00
parent 48a79819f3
commit 78d4f66669
7 changed files with 52 additions and 38 deletions

View File

@@ -48,6 +48,7 @@ body:
- G-code Thumbnail
- PowerRename
- PowerToys Run
- Screen ruler
- Shortcut Guide
- STL Thumbnail
- SVG Preview

View File

@@ -39,6 +39,7 @@ body:
- G-code Thumbnail
- PowerRename
- PowerToys Run
- Screen Ruler
- Shortcut Guide
- SVG Preview
- SVG Thumbnail

View File

@@ -101,7 +101,10 @@ namespace
const D2DState& d2dState)
{
const bool screenQuadrantAware = !alignTextBoxToCenter;
const auto prevMode = d2dState.rt->GetAntialiasMode();
d2dState.rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
d2dState.rt->DrawRectangle(rect, d2dState.solidBrushes[Brush::line].get());
d2dState.rt->SetAntialiasMode(prevMode);
OverlayBoxText text;
const auto width = std::abs(rect.right - rect.left + 1);

View File

@@ -72,45 +72,51 @@ D2DState::D2DState(HWND overlayWindow, std::vector<D2D1::ColorF> solidBrushesCol
void D2DState::DrawTextBox(const wchar_t* text,
const uint32_t textLen,
const float cornerX,
const float cornerY,
const float centerX,
const float centerY,
const bool screenQuadrantAware,
HWND window) const
{
wil::com_ptr<IDWriteTextLayout> textLayout;
winrt::check_hresult(writeFactory->CreateTextLayout(text, textLen, textFormat.get(), 1000.f, 1000.f, &textLayout));
DWRITE_TEXT_METRICS metrics = {};
textLayout->GetMetrics(&metrics);
winrt::check_hresult(writeFactory->CreateTextLayout(text,
textLen,
textFormat.get(),
std::numeric_limits<float>::max(),
std::numeric_limits<float>::max(),
&textLayout));
DWRITE_TEXT_METRICS textMetrics = {};
winrt::check_hresult(textLayout->GetMetrics(&textMetrics));
textMetrics.width *= consts::TEXT_BOX_MARGIN_COEFF;
textMetrics.height *= consts::TEXT_BOX_MARGIN_COEFF;
winrt::check_hresult(textLayout->SetMaxWidth(textMetrics.width));
winrt::check_hresult(textLayout->SetMaxHeight(textMetrics.height));
bool cursorInLeftScreenHalf = false;
bool cursorInTopScreenHalf = false;
DetermineScreenQuadrant(window,
static_cast<long>(cornerX),
static_cast<long>(cornerY),
cursorInLeftScreenHalf,
cursorInTopScreenHalf);
const float TEXT_BOX_MARGIN = 1.25f;
const float textBoxWidth = metrics.width * TEXT_BOX_MARGIN;
const float textBoxHeight = metrics.height * TEXT_BOX_MARGIN;
const float TEXT_BOX_PADDING = 1.f * dpiScale;
const float TEXT_BOX_OFFSET_AMOUNT_X = textBoxWidth * dpiScale;
const float TEXT_BOX_OFFSET_AMOUNT_Y = textBoxWidth * dpiScale;
const float TEXT_BOX_OFFSET_X = cursorInLeftScreenHalf ? TEXT_BOX_OFFSET_AMOUNT_X : -TEXT_BOX_OFFSET_AMOUNT_X;
const float TEXT_BOX_OFFSET_Y = cursorInTopScreenHalf ? TEXT_BOX_OFFSET_AMOUNT_Y : -TEXT_BOX_OFFSET_AMOUNT_Y;
D2D1_RECT_F textRect{ .left = cornerX - textBoxWidth / 2.f,
.top = cornerY - textBoxHeight / 2.f,
.right = cornerX + textBoxWidth / 2.f,
.bottom = cornerY + textBoxHeight / 2.f };
D2D1_RECT_F textRect{ .left = centerX - textMetrics.width / 2.f,
.top = centerY - textMetrics.height / 2.f,
.right = centerX + textMetrics.width / 2.f,
.bottom = centerY + textMetrics.height / 2.f };
if (screenQuadrantAware)
{
textRect.left += TEXT_BOX_OFFSET_X;
textRect.right += TEXT_BOX_OFFSET_X;
textRect.top += TEXT_BOX_OFFSET_Y;
textRect.bottom += TEXT_BOX_OFFSET_Y;
bool cursorInLeftScreenHalf = false;
bool cursorInTopScreenHalf = false;
DetermineScreenQuadrant(window,
static_cast<long>(centerX),
static_cast<long>(centerY),
cursorInLeftScreenHalf,
cursorInTopScreenHalf);
float textQuadrantOffsetX = textMetrics.width * dpiScale;
float textQuadrantOffsetY = textMetrics.height * dpiScale;
if (!cursorInLeftScreenHalf)
textQuadrantOffsetX *= -1.f;
if (!cursorInTopScreenHalf)
textQuadrantOffsetY *= -1.f;
textRect.left += textQuadrantOffsetX;
textRect.right += textQuadrantOffsetX;
textRect.top += textQuadrantOffsetY;
textRect.bottom += textQuadrantOffsetY;
}
// Draw shadow
bitmapRt->BeginDraw();
bitmapRt->Clear(D2D1::ColorF(0.f, 0.f, 0.f, 0.f));
D2D1_ROUNDED_RECT textBoxRect;
@@ -126,19 +132,20 @@ void D2DState::DrawTextBox(const wchar_t* text,
bitmapRt->GetBitmap(&rtBitmap);
shadowEffect->SetInput(0, rtBitmap.get());
affineTransformEffect->SetValue(D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX,
D2D1::Matrix3x2F::Translation(consts::SHADOW_OFFSET * dpiScale, consts::SHADOW_OFFSET * dpiScale));
winrt::check_hresult(affineTransformEffect->SetValue(D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX,
D2D1::Matrix3x2F::Translation(consts::SHADOW_OFFSET * dpiScale,
consts::SHADOW_OFFSET * dpiScale)));
auto deviceContext = rt.query<ID2D1DeviceContext>();
deviceContext->DrawImage(affineTransformEffect.get(), D2D1_INTERPOLATION_MODE_LINEAR);
// Draw text box border rectangle
rt->DrawRoundedRectangle(textBoxRect, solidBrushes[Brush::border].get());
const float TEXT_BOX_PADDING = 1.f * dpiScale;
textBoxRect.rect.bottom -= TEXT_BOX_PADDING;
textBoxRect.rect.top += TEXT_BOX_PADDING;
textBoxRect.rect.left += TEXT_BOX_PADDING;
textBoxRect.rect.right -= TEXT_BOX_PADDING;
// Draw text & its box
rt->FillRoundedRectangle(textBoxRect, solidBrushes[Brush::background].get());
rt->DrawTextW(text, textLen, textFormat.get(), textRect, solidBrushes[Brush::foreground].get(), D2D1_DRAW_TEXT_OPTIONS_NONE);
rt->DrawTextLayout(D2D1_POINT_2F{ .x = textRect.left, .y = textRect.top }, textLayout.get(), solidBrushes[Brush::foreground].get());
}

View File

@@ -29,8 +29,8 @@ struct D2DState
D2DState(HWND window, std::vector<D2D1::ColorF> solidBrushesColors);
void DrawTextBox(const wchar_t* text,
const uint32_t textLen,
const float cornerX,
const float cornerY,
const float centerX,
const float centerY,
const bool screenQuadrantAware,
HWND window) const;
};

View File

@@ -9,6 +9,7 @@ namespace consts
constexpr inline float FONT_SIZE = 14.f;
constexpr inline float TEXT_BOX_CORNER_RADIUS = 4.f;
constexpr inline float TEXT_BOX_MARGIN_COEFF = 1.25f;
constexpr inline float FEET_HALF_LENGTH = 2.f;
constexpr inline float SHADOW_OPACITY = .4f;
constexpr inline float SHADOW_RADIUS = 6.f;

View File

@@ -22,6 +22,7 @@
#include <functional>
#include <cassert>
#include <iomanip>
#include <limits>
#include <sstream>
#include <string_view>
#include <chrono>