terminal/src/cascadia/TerminalApp/App.h
Mike Griese 8ffff8ea37
Enable dragging with the entire titlebar (#1948)
* This definitely works for getting shadow, pointy corners back

  Don't do anything in NCPAINT. If you do, you have to do everything. But the
  whole point of DwmExtendFrameIntoClientArea is to let you paint the NC area in
  your normal paint. So just do that dummy.

  * This doesn't transition across monitors.
  * This has a window style change I think is wrong.
  * I'm not sure the margins change is important.

* The window style was _not_ important

* Still getting a black xaml islands area (the HRGN) when we switch to high DPI

* I don't know if this affects anything.

* heyo this works.

  I'm not entirely sure why. But if we only update the titlebar drag region when
  that actually changes, it's a _lot_ smoother. I'm not super happy with the
  duplicated work in _UpdateDragRegion and OnSize, but checking this in in case
  I can't figure that out.

* Add more comments and cleanup

* Try making the button RightCustomContent

* * Make the MinMaxClose's drag bar's min size the same as a caption button
* Make the new tab button transparent, to see how that looks
* Make sure the TabView doesn't push the MMC off the window

* Create a TitlebarControl

  * The TitlebarControl is owned by the NCIW. It consists of a Content, DragBar,
    and MMCControl.
  * The App instatntiates a TabRowControl at runtime, and either places it in
    the UI (for tabs below titlebar) or hangs on to it, and gives it to the NCIW
    when the NCIW creates its UI.
  * When the NCIW is created, it creates a grid with two rows, one for the
    titlebar and one for the app content.
  * The MMCControl is only responsible for Min Max Close now, and is closer to
    the window implementation.
  * The drag bar takes up all the space from the right of the TabRow to the left
    of the MMC
  * Things that **DON'T** work:
    - When you add tabs, the drag bar doesn't update it's size. It only updates
      OnSize
    - The MMCControl's Min and Max buttons don't seem to work anymore.
      - They should probably just expose their OnMinimizeClick and
        OnMaximizeClick events for the Titlebar to handle minimizing and
        maximizing.
    - The drag bar is Magenta (#ff00ff) currently.
    - I'm not _sure_ we need a TabRowControl. We could probably get away with
      removing it from the UI tree, I was just being dumb before.

* Fix the MMC buttons not working

  I forgot to plumb the window handle through

* Make the titlebar less magenta

* Resize the drag region as we add/remove tabs

* Move the actual MMC handling to the TitlebarControl

* Some PR nits, fix the titlebar painting on maximize

* Put the TabRow in our XAML

* Remove dead code in preparation for review

* Horrifyingly try Gdi Plus as a solution, that is _wrong_ though

* Revert "Horrifyingly try Gdi Plus as a solution, that is _wrong_ though"

This reverts commit e038b5d921.

* This fixes the bottom border but breaks the titlebar painting

* Fix the NC bottom border

* A bunch of the more minor PR nits

* Add a MinimizeClick event to the MMCControl

  This works for Minimize. This is what I wanted to do originally.

* Add events for _all_ of the buttons, not just the Minimize btn

* Change hoe setting the titlebar content works

  Now the app triggers a callcack on the host to set the content, instead of the host querying the app.

* Move the tab row to the bottom of it's available space

* Fix the theme reloading

* PR nits from @miniksa

* Update src/cascadia/WindowsTerminal/NonClientIslandWindow.cpp

Co-Authored-By: Michael Niksa <miniksa@microsoft.com>

* This needed to be fixed, was missed in other PR nits

* runformat

  wait _what_

* Does this fix the CI build?
2019-07-18 17:21:33 -05:00

152 lines
6.7 KiB
C++

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "Tab.h"
#include "CascadiaSettings.h"
#include "App.g.h"
#include "App.base.h"
#include "../../cascadia/inc/cppwinrt_utils.h"
#include <winrt/Microsoft.Terminal.TerminalControl.h>
#include <winrt/Microsoft.Terminal.TerminalConnection.h>
#include <winrt/Microsoft.UI.Xaml.Controls.h>
#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h>
#include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
#include <winrt/Windows.ApplicationModel.DataTransfer.h>
namespace winrt::TerminalApp::implementation
{
struct App : AppT2<App>
{
public:
App();
Windows::UI::Xaml::UIElement GetRoot() noexcept;
void Create();
void LoadSettings();
Windows::Foundation::Point GetLaunchDimensions(uint32_t dpi);
bool GetShowTabsInTitlebar();
~App();
hstring GetTitle();
// -------------------------------- WinRT Events ---------------------------------
DECLARE_EVENT(TitleChanged, _titleChangeHandlers, winrt::Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
DECLARE_EVENT(LastTabClosed, _lastTabClosedHandlers, winrt::TerminalApp::LastTabClosedEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(SetTitleBarContent, _setTitleBarContentHandlers, TerminalApp::App, winrt::Windows::UI::Xaml::UIElement);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(RequestedThemeChanged, _requestedThemeChangedHandlers, TerminalApp::App, winrt::Windows::UI::Xaml::ElementTheme);
private:
// If you add controls here, but forget to null them either here or in
// the ctor, you're going to have a bad time. It'll mysteriously fail to
// activate the app.
// ALSO: If you add any UIElements as roots here, make sure they're
// updated in _ApplyTheme. The two roots currently are _root and _tabRow
// (which is a root when the tabs are in the titlebar.)
Windows::UI::Xaml::Controls::Control _root{ nullptr };
Microsoft::UI::Xaml::Controls::TabView _tabView{ nullptr };
TerminalApp::TabRowControl _tabRow{ nullptr };
Windows::UI::Xaml::Controls::Grid _tabContent{ nullptr };
Windows::UI::Xaml::Controls::SplitButton _newTabButton{ nullptr };
std::vector<std::shared_ptr<Tab>> _tabs;
std::unique_ptr<::TerminalApp::CascadiaSettings> _settings;
HRESULT _settingsLoadedResult;
bool _loadedInitialSettings;
std::shared_mutex _dialogLock;
wil::unique_folder_change_reader_nothrow _reader;
std::atomic<bool> _settingsReloadQueued{ false };
void _CreateNewTabFlyout();
fire_and_forget _ShowDialog(const winrt::Windows::Foundation::IInspectable& titleElement,
const winrt::Windows::Foundation::IInspectable& contentElement,
const winrt::hstring& closeButtonText);
void _ShowOkDialog(const winrt::hstring& titleKey, const winrt::hstring& contentKey);
void _ShowAboutDialog();
[[nodiscard]] HRESULT _TryLoadSettings(const bool saveOnLoad) noexcept;
void _LoadSettings();
void _OpenSettings();
void _HookupKeyBindings(TerminalApp::AppKeyBindings bindings) noexcept;
void _RegisterSettingsChange();
fire_and_forget _DispatchReloadSettings();
void _ReloadSettings();
void _SettingsButtonOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
void _FeedbackButtonOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
void _AboutButtonOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
void _UpdateTabView();
void _UpdateTabIcon(std::shared_ptr<Tab> tab);
void _UpdateTitle(std::shared_ptr<Tab> tab);
void _RegisterTerminalEvents(Microsoft::Terminal::TerminalControl::TermControl term, std::shared_ptr<Tab> hostingTab);
void _CreateNewTabFromSettings(GUID profileGuid, winrt::Microsoft::Terminal::Settings::TerminalSettings settings);
void _OpenNewTab(std::optional<int> profileIndex);
void _DuplicateTabViewItem();
void _CloseFocusedTab();
void _SelectNextTab(const bool bMoveRight);
void _SelectTab(const int tabIndex);
void _SetFocusedTabIndex(int tabIndex);
int _GetFocusedTabIndex() const;
void _Scroll(int delta);
void _CopyText(const bool trimTrailingWhitespace);
void _PasteText();
void _SplitVertical(const std::optional<GUID>& profileGuid);
void _SplitHorizontal(const std::optional<GUID>& profileGuid);
void _SplitPane(const Pane::SplitState splitType, const std::optional<GUID>& profileGuid);
// Todo: add more event implementations here
// MSFT:20641986: Add keybindings for New Window
void _ScrollPage(int delta);
void _ResizePane(const Direction& direction);
void _MoveFocus(const Direction& direction);
void _OnLoaded(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs);
void _OnTabSelectionChanged(const IInspectable& sender, const Windows::UI::Xaml::Controls::SelectionChangedEventArgs& eventArgs);
void _OnTabClosing(const IInspectable& sender, const Microsoft::UI::Xaml::Controls::TabViewTabClosingEventArgs& eventArgs);
void _OnTabItemsChanged(const IInspectable& sender, const Windows::Foundation::Collections::IVectorChangedEventArgs& eventArgs);
void _OnTabClick(const IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& eventArgs);
void _OnContentSizeChanged(const IInspectable& sender, Windows::UI::Xaml::SizeChangedEventArgs const& e);
void _RemoveTabViewItem(const IInspectable& tabViewItem);
void _ApplyTheme(const Windows::UI::Xaml::ElementTheme& newTheme);
static Windows::UI::Xaml::Controls::IconElement _GetIconFromProfile(const ::TerminalApp::Profile& profile);
winrt::Microsoft::Terminal::TerminalControl::TermControl _GetFocusedControl();
void _CopyToClipboardHandler(const winrt::hstring& copiedData);
void _PasteFromClipboardHandler(const IInspectable& sender, const Microsoft::Terminal::TerminalControl::PasteFromClipboardEventArgs& eventArgs);
static void _SetAcceleratorForMenuItem(Windows::UI::Xaml::Controls::MenuFlyoutItem& menuItem, const winrt::Microsoft::Terminal::Settings::KeyChord& keyChord);
};
}
namespace winrt::TerminalApp::factory_implementation
{
struct App : AppT<App, implementation::App>
{
};
}