some cleanup. Try only hovering the actually hovered button

This commit is contained in:
Mike Griese 2021-11-03 09:11:55 -05:00
parent 5fdef429a8
commit 6c9b399048
8 changed files with 137 additions and 25 deletions

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// MinMaxCloseControl.xaml.cpp
@ -95,4 +95,60 @@ namespace winrt::TerminalApp::implementation
break;
}
}
void MinMaxCloseControl::HoverButton(CaptionButton button)
{
switch (button)
{
case CaptionButton::Minimize:
VisualStateManager::GoToState(MinimizeButton(), L"PointerOver", false);
VisualStateManager::GoToState(MaximizeButton(), L"Normal", false);
VisualStateManager::GoToState(CloseButton(), L"Normal", false);
break;
case CaptionButton::Maximize:
VisualStateManager::GoToState(MinimizeButton(), L"Normal", false);
VisualStateManager::GoToState(MaximizeButton(), L"PointerOver", false);
VisualStateManager::GoToState(CloseButton(), L"Normal", false);
break;
case CaptionButton::Close:
VisualStateManager::GoToState(MinimizeButton(), L"Normal", false);
VisualStateManager::GoToState(MaximizeButton(), L"Normal", false);
VisualStateManager::GoToState(CloseButton(), L"PointerOver", false);
break;
}
}
void MinMaxCloseControl::PressButton(CaptionButton button)
{
switch (button)
{
case CaptionButton::Minimize:
VisualStateManager::GoToState(MinimizeButton(), L"Pressed", false);
VisualStateManager::GoToState(MaximizeButton(), L"Normal", false);
VisualStateManager::GoToState(CloseButton(), L"Normal", false);
break;
case CaptionButton::Maximize:
VisualStateManager::GoToState(MinimizeButton(), L"Normal", false);
VisualStateManager::GoToState(MaximizeButton(), L"Pressed", false);
VisualStateManager::GoToState(CloseButton(), L"Normal", false);
break;
case CaptionButton::Close:
VisualStateManager::GoToState(MinimizeButton(), L"Normal", false);
VisualStateManager::GoToState(MaximizeButton(), L"Normal", false);
VisualStateManager::GoToState(CloseButton(), L"Pressed", false);
break;
}
}
void MinMaxCloseControl::ReleaseButton(CaptionButton button)
{
switch (button)
{
case CaptionButton::Minimize:
case CaptionButton::Maximize:
case CaptionButton::Close:
VisualStateManager::GoToState(MinimizeButton(), L"Normal", false);
VisualStateManager::GoToState(MaximizeButton(), L"Normal", false);
VisualStateManager::GoToState(CloseButton(), L"Normal", false);
break;
}
}
}

View file

@ -20,6 +20,10 @@ namespace winrt::TerminalApp::implementation
void SetWindowVisualState(WindowVisualState visualState);
void HoverButton(CaptionButton button);
void PressButton(CaptionButton button);
void ReleaseButton(CaptionButton button);
void _MinimizeClick(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void _MaximizeClick(winrt::Windows::Foundation::IInspectable const& sender,

View file

@ -11,6 +11,10 @@ namespace TerminalApp
void SetWindowVisualState(WindowVisualState visualState);
void HoverButton(CaptionButton button);
void PressButton(CaptionButton button);
void ReleaseButton(CaptionButton button);
event Windows.Foundation.TypedEventHandler<MinMaxCloseControl, Windows.UI.Xaml.RoutedEventArgs> MinimizeClick;
event Windows.Foundation.TypedEventHandler<MinMaxCloseControl, Windows.UI.Xaml.RoutedEventArgs> MaximizeClick;
event Windows.Foundation.TypedEventHandler<MinMaxCloseControl, Windows.UI.Xaml.RoutedEventArgs> CloseClick;

View file

@ -103,4 +103,18 @@ namespace winrt::TerminalApp::implementation
{
MinMaxCloseControl().SetWindowVisualState(visualState);
}
void TitlebarControl::HoverButton(CaptionButton button)
{
MinMaxCloseControl().HoverButton(button);
}
void TitlebarControl::PressButton(CaptionButton button)
{
MinMaxCloseControl().PressButton(button);
}
void TitlebarControl::ReleaseButton(CaptionButton button)
{
MinMaxCloseControl().ReleaseButton(button);
}
}

View file

@ -6,9 +6,6 @@
#pragma once
#include "winrt/Windows.UI.Xaml.h"
#include "winrt/Windows.UI.Xaml.Markup.h"
#include "winrt/Windows.UI.Xaml.Interop.h"
#include "TitlebarControl.g.h"
namespace winrt::TerminalApp::implementation
@ -19,6 +16,9 @@ namespace winrt::TerminalApp::implementation
void MaxButtonEntered();
void MaxButtonExited();
void HoverButton(CaptionButton button);
void PressButton(CaptionButton button);
void ReleaseButton(CaptionButton button);
IInspectable Content();
void Content(IInspectable content);

View file

@ -10,10 +10,21 @@ namespace TerminalApp
WindowVisualStateIconified
};
enum CaptionButton {
Minimize,
Maximize,
Close
};
[default_interface] runtimeclass TitlebarControl : Windows.UI.Xaml.Controls.Grid
{
TitlebarControl(UInt64 parentWindowHandle);
void SetWindowVisualState(WindowVisualState visualState);
void HoverButton(CaptionButton button);
void PressButton(CaptionButton button);
void ReleaseButton(CaptionButton button);
void MaxButtonEntered();
void MaxButtonExited();

View file

@ -87,6 +87,30 @@ void NonClientIslandWindow::MakeWindow() noexcept
THROW_HR_IF_NULL(E_UNEXPECTED, _dragBarWindow);
}
LRESULT NonClientIslandWindow::_dragBarNcHitTest(const til::point& pointer)
{
RECT rcParent = GetWindowRect();
// Consider the entire caption control area (rough estimate) to be the maximize button
// TODO: Should consider drag distance also. This is considered in the parent window's nc hittest handler,
// I just didn't duplicate it here.
// TODO! this 130 shouldn't be hardcoded
// TODO! other buttons too
if ((rcParent.right - pointer.x()) < 130)
{
return HTMAXBUTTON;
}
else
{
// If we're not on a caption button, then check if we're on the top
// border. If we're not on the top border, then we're just generally in
// the caption area.
const auto resizeBorderHeight = _GetResizeHandleHeight();
const auto isOnResizeBorder = pointer.y() < rcParent.top + resizeBorderHeight;
return isOnResizeBorder ? HTTOP : HTCAPTION;
}
}
// Function Description:
// - The window procedure for the drag bar forwards clicks on its client area to its parent as non-client clicks.
LRESULT NonClientIslandWindow::_InputSinkMessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept
@ -95,47 +119,44 @@ LRESULT NonClientIslandWindow::_InputSinkMessageHandler(UINT const message, WPAR
{
case WM_NCHITTEST:
{
RECT rcParent = GetWindowRect();
// Consider the entire caption control area (rough estimate) to be the maximize button
// TODO: Should consider drag distance also. This is considered in the parent window's nc hittest handler,
// I just didn't duplicate it here.
if ((rcParent.right - GET_X_LPARAM(lparam)) < 130)
{
return HTMAXBUTTON;
}
else
{
RECT rcWindow;
winrt::check_bool(::GetWindowRect(_window.get(), &rcWindow));
til::point pointer{ GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam) };
const auto resizeBorderHeight = _GetResizeHandleHeight();
const auto isOnResizeBorder = GET_Y_LPARAM(lparam) < rcWindow.top + resizeBorderHeight;
return isOnResizeBorder ? HTTOP : HTCAPTION;
}
return _dragBarNcHitTest(pointer);
}
break;
case WM_NCMOUSEMOVE:
// Communicate state to the title bar control so that it can update its visuals.
// TODO! other buttons too
if (wparam == HTMAXBUTTON)
{
_titlebar.MaxButtonEntered();
_titlebar.HoverButton(winrt::TerminalApp::CaptionButton::Maximize);
// _titlebar.MaxButtonEntered();
}
else
{
_titlebar.MaxButtonExited();
_titlebar.ReleaseButton(winrt::TerminalApp::CaptionButton::Maximize);
// _titlebar.MaxButtonExited();
}
break;
case WM_NCMOUSELEAVE:
case WM_MOUSELEAVE:
_titlebar.MaxButtonExited();
// _titlebar.MaxButtonExited();
_titlebar.ReleaseButton(winrt::TerminalApp::CaptionButton::Maximize);
break;
// NB: *Shouldn't be forwarding these* when they're not over the caption because they can inadvertently take action using the system's default metrics instead of our own.
case WM_NCLBUTTONDOWN:
case WM_NCLBUTTONDBLCLK:
switch (wparam)
{
case HTMAXBUTTON:
_titlebar.PressButton(winrt::TerminalApp::CaptionButton::Maximize);
break;
}
return 0;
// TODO!: I think we only want WM_NCLBUTTONUP
case WM_NCLBUTTONUP:
switch (wparam)
{
@ -153,6 +174,7 @@ LRESULT NonClientIslandWindow::_InputSinkMessageHandler(UINT const message, WPAR
case HTCLOSE:
// Forward along to the button state machine.
// As a proof of concept just locally handle the maximize button.
// TODO!
if ((wparam == HTMAXBUTTON) && (message == WM_NCLBUTTONUP))
{
ShowWindow(GetHandle(), SW_MAXIMIZE);
@ -310,7 +332,7 @@ RECT NonClientIslandWindow::_GetDragAreaRect() const noexcept
const auto logicalDragBarRect = winrt::Windows::Foundation::Rect{
0.0f,
0.0f,
static_cast<float>(/*_dragBar*/_rootGrid.ActualWidth()),
static_cast<float>(/*_dragBar*/ _rootGrid.ActualWidth()),
static_cast<float>(_dragBar.ActualHeight())
};
const auto clientDragBarRect = transform.TransformBounds(logicalDragBarRect);

View file

@ -71,6 +71,7 @@ private:
int _GetResizeHandleHeight() const noexcept;
RECT _GetDragAreaRect() const noexcept;
int _GetTopBorderHeight() const noexcept;
LRESULT _dragBarNcHitTest(const til::point& pointer);
[[nodiscard]] LRESULT _OnNcCreate(WPARAM wParam, LPARAM lParam) noexcept override;
[[nodiscard]] LRESULT _OnNcCalcSize(const WPARAM wParam, const LPARAM lParam) noexcept;