Compare commits

...

15 commits

Author SHA1 Message Date
Mike Griese ff8eb619ea Get the thumbnail working
For whatever reason, the symbols are fucked though. that _needs_ to be fixed, whatever happened.
2019-07-22 11:06:50 -05:00
Mike Griese 3f895d93e7 Hook up the buttons 2019-07-22 09:09:55 -05:00
Mike Griese e286eb66f3 Realtime updating for title&artist, play/pause status 2019-07-22 08:30:48 -05:00
Mike Griese 1feb2bddca HOLY SHIT THIS WORKS 2019-07-19 16:59:56 -05:00
Mike Griese c87ffa62da Think about doing a Settings Page for the hackathon 2019-07-19 16:59:43 -05:00
Mike Griese 2e3c61fcee Remove GetControl() for IControlHost
I didn't like it there. What if an element has lots of controls? It's just not a sustainable model.
2019-07-19 16:10:27 -05:00
Mike Griese d298ff025d Well this is a dead end too. 2019-07-19 09:01:04 -05:00
Mike Griese 141d0d4d1c Merge remote-tracking branch 'origin/master' into dev/migrie/f/non-terminal-panes
# Conflicts:
#	src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj
2019-07-19 07:58:16 -05:00
Mike Griese fe48a9a85d Oh no this might not be possible 2019-07-18 15:00:24 -05:00
Mike Griese 27c4b8df09 This is a hacky RichTextBoxHost in XAML
Just to prove it can be done this way
2019-07-18 12:31:14 -05:00
Mike Griese dd212dde74 Enable embedding non-terminal controls in panes
This adds a _super_ simple dummy RichTextBox as a control in a pane adjacent to a terminal pane
2019-07-18 10:36:49 -05:00
Mike Griese e5d88c3909 Merge remote-tracking branch 'origin/dev/duhowett/rollup_harder' into dev/migrie/f/non-terminal-panes 2019-07-18 07:23:29 -05:00
Dustin L. Howett 9b159904b0 Add a safety net to make sure the MSIX doesn't continue to regress 2019-07-18 00:33:30 -07:00
Dustin Howett bfffb76f3f Well, reintroduce part of it 2019-07-17 16:59:25 -07:00
Dustin Howett d982e1be58 Roll up dependencies properly throguh TerminalApp->WindowsTerminal->WAP 2019-07-17 16:40:24 -07:00
34 changed files with 1425 additions and 39 deletions

View file

@ -500,6 +500,7 @@ namespace winrt::TerminalApp::implementation
bindings.MoveFocus([this](const auto direction) { _MoveFocus(direction); });
bindings.CopyText([this](const auto trimWhitespace) { _CopyText(trimWhitespace); });
bindings.PasteText([this]() { _PasteText(); });
bindings.OpenTestPane([this]() { _OpenTestPane(); });
}
// Method Description:
@ -919,13 +920,15 @@ namespace winrt::TerminalApp::implementation
winrt::guid());
TermControl term{ settings, connection };
TermControlHost controlHost{ term };
// Add the new tab to the list of our tabs.
auto newTab = _tabs.emplace_back(std::make_shared<Tab>(profileGuid, term));
auto newTab = _tabs.emplace_back(std::make_shared<Tab>(profileGuid, controlHost));
const auto* const profile = _settings->FindProfile(profileGuid);
// Hookup our event handlers to the new terminal
// TODO: non-terminal tabs? what do for these events?
_RegisterTerminalEvents(term, newTab);
auto tabViewItem = newTab->GetTabViewItem();
@ -1317,6 +1320,7 @@ namespace winrt::TerminalApp::implementation
// this is nullopt, use the default profile.
void App::_SplitPane(const Pane::SplitState splitType, const std::optional<GUID>& profileGuid)
{
// TODO: how do we split for non-terminal controls?
// Do nothing if we're requesting no split.
if (splitType == Pane::SplitState::None)
{
@ -1335,15 +1339,43 @@ namespace winrt::TerminalApp::implementation
winrt::guid());
TermControl newControl{ controlSettings, controlConnection };
TermControlHost controlHost{ newControl };
const int focusedTabIndex = _GetFocusedTabIndex();
auto focusedTab = _tabs[focusedTabIndex];
// TODO: what do we do about these events that might not make sense for non-terminal controls
// Hookup our event handlers to the new terminal
_RegisterTerminalEvents(newControl, focusedTab);
return splitType == Pane::SplitState::Horizontal ? focusedTab->AddHorizontalSplit(realGuid, newControl) :
focusedTab->AddVerticalSplit(realGuid, newControl);
return splitType == Pane::SplitState::Horizontal ? focusedTab->AddHorizontalSplit(realGuid, controlHost) :
focusedTab->AddVerticalSplit(realGuid, controlHost);
}
void App::_OpenTestPane()
{
const auto splitType = Pane::SplitState::Vertical;
// TODO: how do we split for non-terminal controls?
// Do nothing if we're requesting no split.
GUID realGuid = { 0 };
// TextBlockControlHost controlHost{};
// RichTextBoxControlHost controlHost{};
MediaControlHost controlHost{};
// WebViewHost controlHost{};
// SettingsHost controlHost{};
const int focusedTabIndex = _GetFocusedTabIndex();
auto focusedTab = _tabs[focusedTabIndex];
// // TODO: what do we do about these events that might not make sense for non-terminal controls
// // Hookup our event handlers to the new terminal
// _RegisterTerminalEvents(newControl, focusedTab);
return splitType == Pane::SplitState::Horizontal ? focusedTab->AddHorizontalSplit(realGuid, controlHost) :
focusedTab->AddVerticalSplit(realGuid, controlHost);
}
// Method Description:

View file

@ -115,6 +115,7 @@ namespace winrt::TerminalApp::implementation
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);
void _OpenTestPane();
// Todo: add more event implementations here
// MSFT:20641986: Add keybindings for New Window

View file

@ -184,6 +184,11 @@ namespace winrt::TerminalApp::implementation
case ShortcutAction::MoveFocusDown:
_MoveFocusHandlers(Direction::Down);
return true;
case ShortcutAction::OpenTestPane:
_OpenTestPaneHandlers();
return true;
default:
return false;
}
@ -267,5 +272,6 @@ namespace winrt::TerminalApp::implementation
DEFINE_EVENT(AppKeyBindings, OpenSettings, _OpenSettingsHandlers, TerminalApp::OpenSettingsEventArgs);
DEFINE_EVENT(AppKeyBindings, ResizePane, _ResizePaneHandlers, TerminalApp::ResizePaneEventArgs);
DEFINE_EVENT(AppKeyBindings, MoveFocus, _MoveFocusHandlers, TerminalApp::MoveFocusEventArgs);
DEFINE_EVENT(AppKeyBindings, OpenTestPane, _OpenTestPaneHandlers, TerminalApp::OpenTestPaneEventArgs);
// clang-format on
}

View file

@ -63,6 +63,7 @@ namespace winrt::TerminalApp::implementation
DECLARE_EVENT(OpenSettings, _OpenSettingsHandlers, TerminalApp::OpenSettingsEventArgs);
DECLARE_EVENT(ResizePane, _ResizePaneHandlers, TerminalApp::ResizePaneEventArgs);
DECLARE_EVENT(MoveFocus, _MoveFocusHandlers, TerminalApp::MoveFocusEventArgs);
DECLARE_EVENT(OpenTestPane, _OpenTestPaneHandlers, TerminalApp::OpenTestPaneEventArgs);
// clang-format on
private:

View file

@ -58,7 +58,8 @@ namespace TerminalApp
MoveFocusRight,
MoveFocusUp,
MoveFocusDown,
OpenSettings
OpenSettings,
OpenTestPane
};
delegate void CopyTextEventArgs(Boolean trimWhitespace);
@ -84,6 +85,7 @@ namespace TerminalApp
delegate void OpenSettingsEventArgs();
delegate void ResizePaneEventArgs(Direction direction);
delegate void MoveFocusEventArgs(Direction direction);
delegate void OpenTestPaneEventArgs();
[default_interface] runtimeclass AppKeyBindings : Microsoft.Terminal.Settings.IKeyBindings
{
@ -115,5 +117,6 @@ namespace TerminalApp
event OpenSettingsEventArgs OpenSettings;
event ResizePaneEventArgs ResizePane;
event MoveFocusEventArgs MoveFocus;
event OpenTestPaneEventArgs OpenTestPane;
}
}

View file

@ -60,6 +60,7 @@ static constexpr std::string_view MoveFocusLeftKey{ "moveFocusLeft" };
static constexpr std::string_view MoveFocusRightKey{ "moveFocusRight" };
static constexpr std::string_view MoveFocusUpKey{ "moveFocusUp" };
static constexpr std::string_view MoveFocusDownKey{ "moveFocusDown" };
static constexpr std::string_view OpenTestPaneKey{ "openTestPane" };
// Specifically use a map here over an unordered_map. We want to be able to
// iterate over these entries in-order when we're serializing the keybindings.
@ -116,6 +117,7 @@ static const std::map<std::string_view, ShortcutAction, std::less<>> commandName
{ MoveFocusUpKey, ShortcutAction::MoveFocusUp },
{ MoveFocusDownKey, ShortcutAction::MoveFocusDown },
{ OpenSettingsKey, ShortcutAction::OpenSettings },
{ OpenTestPaneKey, ShortcutAction::OpenTestPane },
};
// Function Description:

View file

@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace TerminalApp
{
delegate void ClosedEventArgs();
interface IControlHost
{
// Windows.UI.Xaml.Controls.Control GetControl();
Windows.UI.Xaml.UIElement GetRoot();
event Windows.Foundation.TypedEventHandler<IControlHost, ClosedEventArgs> CloseRequested;
void Close();
event Windows.Foundation.TypedEventHandler<IControlHost, Microsoft.Terminal.TerminalControl.TitleChangedEventArgs> TitleChanged;
String GetTitle();
Windows.Foundation.Size MinimumSize { get; };
// Other things we'll need:
Boolean IsFocused();
void Focus();
}
}

View file

@ -0,0 +1,184 @@
#include "pch.h"
#include "MediaControlHost.h"
#include "MediaControlHost.g.cpp"
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Windows::Media;
namespace winrt::TerminalApp::implementation
{
void MediaControlHost::_UpdateMediaInfo(Control::GlobalSystemMediaTransportControlsSession session)
{
auto mediaAsync = session.TryGetMediaPropertiesAsync();
auto media = mediaAsync.get();
auto artist = media.AlbumArtist();
auto title = media.Title();
auto info = session.GetPlaybackInfo();
_playbackState = info.PlaybackStatus();
Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [this, artist, title, info]() {
_Title().Text(title);
_Band().Text(artist);
auto status = info.PlaybackStatus();
if (status == Control::GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing)
{
_PlayPauseIcon().Glyph(L"\xE769");
}
else if (status == Control::GlobalSystemMediaTransportControlsSessionPlaybackStatus::Paused)
{
_PlayPauseIcon().Glyph(L"\xE768");
}
});
auto thumb = media.Thumbnail();
auto streamAsync = thumb.OpenReadAsync();
auto stream = streamAsync.get();
Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [this, stream]() {
Media::Imaging::BitmapImage bitmapImage{};
bitmapImage.SetSourceAsync(stream);
_Thumbnail().Source(bitmapImage);
});
}
void MediaControlHost::_MediaPropertiesChanged(Control::GlobalSystemMediaTransportControlsSession session,
Control::MediaPropertiesChangedEventArgs args)
{
_UpdateMediaInfo(session);
}
void MediaControlHost::_PlaybackInfoChanged(Control::GlobalSystemMediaTransportControlsSession session,
Control::PlaybackInfoChangedEventArgs args)
{
_UpdateMediaInfo(session);
}
fire_and_forget MediaControlHost::_SetupMediaManager()
{
co_await winrt::resume_background();
auto request = winrt::Windows::Media::Control::GlobalSystemMediaTransportControlsSessionManager::RequestAsync();
auto mgr = request.get();
_session = mgr.GetCurrentSession();
_session.MediaPropertiesChanged({ this, &MediaControlHost::_MediaPropertiesChanged });
mgr.CurrentSessionChanged([this](auto&&, auto&&) {
auto a = 0;
a++;
a;
});
_session.PlaybackInfoChanged({ this, &MediaControlHost::_PlaybackInfoChanged });
// _session.TimelinePropertiesChanged([this](auto&&, auto&&) {
// auto a = 0;
// a++;
// a;
// });
_UpdateMediaInfo(_session);
}
MediaControlHost::MediaControlHost()
{
InitializeComponent();
_PreviousButton().Click({ this, &MediaControlHost::_PreviousClick });
_PlayPauseButton().Click({ this, &MediaControlHost::_PlayPauseClick });
_NextButton().Click({ this, &MediaControlHost::_NextClick });
Loaded([this](auto&&, auto&&) {
_SetupMediaManager();
});
}
Windows::UI::Xaml::UIElement MediaControlHost::GetRoot()
{
return *this;
}
void MediaControlHost::Close()
{
throw hresult_not_implemented();
}
hstring MediaControlHost::GetTitle()
{
return L"foo";
}
winrt::Windows::Foundation::Size MediaControlHost::MinimumSize() const
{
return { 32, 32 };
}
bool MediaControlHost::IsFocused()
{
// TODO: Return if focus is anywhere in our tree
return false;
// return _Editor().FocusState() != FocusState::Unfocused;
}
void MediaControlHost::Focus()
{
_PlayPauseButton().Focus(FocusState::Programmatic);
}
void MediaControlHost::_PreviousClick(IInspectable const& sender,
RoutedEventArgs const& e)
{
_DispatchPreviousClick();
}
void MediaControlHost::_NextClick(IInspectable const& sender,
RoutedEventArgs const& e)
{
_DispatchNextClick();
}
void MediaControlHost::_PlayPauseClick(IInspectable const& sender,
RoutedEventArgs const& e)
{
_DispatchPlayPauseClick();
}
fire_and_forget MediaControlHost::_DispatchPreviousClick()
{
co_await winrt::resume_background();
if (_session)
{
if (_playbackState == Control::GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing)
{
_session.TrySkipPreviousAsync();
}
}
}
fire_and_forget MediaControlHost::_DispatchNextClick()
{
co_await winrt::resume_background();
if (_session)
{
if (_playbackState == Control::GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing)
{
_session.TrySkipNextAsync();
}
}
}
fire_and_forget MediaControlHost::_DispatchPlayPauseClick()
{
co_await winrt::resume_background();
if (_session)
{
auto foo = _playbackState;
if (_playbackState == Control::GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing)
{
_session.TryPauseAsync();
}
else if (_playbackState == Control::GlobalSystemMediaTransportControlsSessionPlaybackStatus::Paused)
{
_session.TryPlayAsync();
}
}
}
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(MediaControlHost, CloseRequested, _closeRequestedHandlers, TerminalApp::IControlHost, TerminalApp::ClosedEventArgs);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(MediaControlHost, TitleChanged, _titleChangedHandlers, TerminalApp::IControlHost, Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
}

View file

@ -0,0 +1,60 @@
#pragma once
#include "MediaControlHost.g.h"
#include "../../cascadia/inc/cppwinrt_utils.h"
#include <winrt/Windows.Media.h>
#include <winrt/Windows.Media.Control.h>
#include <winrt/Windows.ui.xaml.media.h>
#include <winrt/Windows.ui.xaml.media.imaging.h>
#include <winrt/Windows.storage.streams.h>
namespace winrt::TerminalApp::implementation
{
struct MediaControlHost : MediaControlHostT<MediaControlHost>
{
MediaControlHost();
// Windows::UI::Xaml::Controls::Control GetControl();
Windows::UI::Xaml::UIElement GetRoot();
void Close();
hstring GetTitle();
Windows::Foundation::Size MinimumSize() const;
bool IsFocused();
void Focus();
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CloseRequested, _closeRequestedHandlers, TerminalApp::IControlHost, TerminalApp::ClosedEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(TitleChanged, _titleChangedHandlers, TerminalApp::IControlHost, Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
void _PreviousClick(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void _NextClick(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void _PlayPauseClick(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
private:
winrt::Windows::Media::Control::GlobalSystemMediaTransportControlsSession _session{ nullptr };
Windows::Media::Control::GlobalSystemMediaTransportControlsSessionPlaybackStatus _playbackState{ Windows::Media::Control::GlobalSystemMediaTransportControlsSessionPlaybackStatus::Closed };
fire_and_forget _SetupMediaManager();
void _MediaPropertiesChanged(winrt::Windows::Media::Control::GlobalSystemMediaTransportControlsSession session,
winrt::Windows::Media::Control::MediaPropertiesChangedEventArgs args);
void _PlaybackInfoChanged(winrt::Windows::Media::Control::GlobalSystemMediaTransportControlsSession session,
winrt::Windows::Media::Control::PlaybackInfoChangedEventArgs args);
// void _TimelinePropertiesChanged(winrt::Windows::Media::Control::GlobalSystemMediaTransportControlsSession session,
// winrt::Windows::Media::Control::MediaPropertiesChangedEventArgs args);
void _UpdateMediaInfo(winrt::Windows::Media::Control::GlobalSystemMediaTransportControlsSession session);
fire_and_forget _DispatchPreviousClick();
fire_and_forget _DispatchNextClick();
fire_and_forget _DispatchPlayPauseClick();
};
}
namespace winrt::TerminalApp::factory_implementation
{
struct MediaControlHost : MediaControlHostT<MediaControlHost, implementation::MediaControlHost>
{
};
}

View file

@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Even though this is in the same directory, we're building from a child
// directory, so the midl compiler gets confused. TODO: This shouldn't need the
// "../". Maybe there's a build rule we can add (gross) or we can just live with
// it.
import "../IControlHost.idl";
namespace TerminalApp
{
// I can't tell you how important it is that the base class of your custom
// element is the UIElement that's at the root of the xaml file.
[default_interface] runtimeclass MediaControlHost : Windows.UI.Xaml.Controls.Grid, IControlHost
{
MediaControlHost();
};
}

View file

@ -0,0 +1,104 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<Grid
x:Class="TerminalApp.MediaControlHost"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TerminalApp"
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Name="_Root"
Background="{ThemeResource SystemChromeLowColor}"
VerticalAlignment="Stretch"
mc:Ignorable="d">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<RelativePanel
Margin="8,0,0,8"
Grid.Row="0"
HorizontalAlignment="Stretch">
<TextBlock
FontWeight="Bold"
RelativePanel.AlignLeftWithPanel="True"
TextWrapping="WrapWholeWords"
FontSize="16"
x:Name="_CurrentlyPlayingText">
Currently Playing:
</TextBlock>
<Button
x:Name="_CloseButton"
Background="Transparent"
AutomationProperties.Name="Close"
ToolTipService.ToolTip="Close"
RelativePanel.AlignRightWithPanel="True">
<Button.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8BB;"/>
</Button.Content>
</Button>
</RelativePanel>
<Grid Grid.Row="1" Margin="8,2,8,8">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image
x:Name="_Thumbnail"
Grid.Row="0"
Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center"></Image>
<StackPanel
Grid.Row="1"
Orientation="Vertical">
<StackPanel
x:Name="_Buttons"
Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<StackPanel.Resources>
<Style TargetType="Button">
<Setter Property="Background" Value="Transparent"></Setter>
</Style>
</StackPanel.Resources>
<Button x:Name="_PreviousButton">
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE892;"/>
</Button>
<Button x:Name="_PlayPauseButton">
<!-- Pause is xE769 -->
<FontIcon x:Name="_PlayPauseIcon" FontFamily="Segoe MDL2 Assets" Glyph="&#xE768;"/>
</Button>
<Button x:Name="_NextButton">
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE893;"/>
</Button>
</StackPanel>
<TextBlock
TextWrapping="WrapWholeWords"
HorizontalAlignment="Center" x:Name="_Title" FontSize="20">
</TextBlock>
<TextBlock
TextWrapping="WrapWholeWords"
HorizontalAlignment="Center" x:Name="_Band">
</TextBlock>
</StackPanel>
</Grid>
</Grid>

View file

@ -14,13 +14,38 @@ using namespace winrt::TerminalApp;
static const int PaneSeparatorSize = 4;
static const float Half = 0.50f;
Pane::Pane(const GUID& profile, const TermControl& control, const bool lastFocused) :
// Pane::Pane(const GUID& profile, const TermControl& control, const bool lastFocused) :
// _control{ control },
// _lastFocused{ lastFocused },
// _profile{ profile }
// {
// _root.Children().Append(_control.GetControl());
// _connectionClosedToken = _control.ConnectionClosed({ this, &Pane::_ControlClosedHandler });
// // Set the background of the pane to match that of the theme's default grid
// // background. This way, we'll match the small underline under the tabs, and
// // the UI will be consistent on bot light and dark modes.
// const auto res = Application::Current().Resources();
// const auto key = winrt::box_value(L"BackgroundGridThemeStyle");
// if (res.HasKey(key))
// {
// const auto g = res.Lookup(key);
// const auto style = g.try_as<winrt::Windows::UI::Xaml::Style>();
// // try_as fails by returning nullptr
// if (style)
// {
// _root.Style(style);
// }
// }
// }
Pane::Pane(const GUID& profile, const IControlHost& control, const bool lastFocused) :
_control{ control },
_lastFocused{ lastFocused },
_profile{ profile }
{
_root.Children().Append(_control.GetControl());
_connectionClosedToken = _control.ConnectionClosed({ this, &Pane::_ControlClosedHandler });
_root.Children().Append(_control.GetRoot());
_connectionClosedToken = _control.CloseRequested({ this, &Pane::_ControlClosedHandler2 });
// Set the background of the pane to match that of the theme's default grid
// background. This way, we'll match the small underline under the tabs, and
@ -39,6 +64,11 @@ Pane::Pane(const GUID& profile, const TermControl& control, const bool lastFocus
}
}
void Pane::_ControlClosedHandler2(const winrt::Windows::Foundation::IInspectable& sender, const winrt::TerminalApp::ClosedEventArgs& args)
{
_ControlClosedHandler();
}
// Method Description:
// - Update the size of this pane. Resizes each of our columns so they have the
// same relative sizes, given the newSize.
@ -301,11 +331,12 @@ void Pane::_ControlClosedHandler()
return;
}
if (_control.ShouldCloseOnExit())
{
// Fire our Closed event to tell our parent that we should be removed.
_closedHandlers();
}
// TODO: move this to the TerminalControlHost
// if (_control.ShouldCloseOnExit())
// {
// // Fire our Closed event to tell our parent that we should be removed.
// _closedHandlers();
// }
}
// Method Description:
@ -373,7 +404,13 @@ std::shared_ptr<Pane> Pane::GetFocusedPane()
TermControl Pane::GetFocusedTerminalControl()
{
auto lastFocused = GetFocusedPane();
return lastFocused ? lastFocused->_control : nullptr;
// return lastFocused ? lastFocused->_control : nullptr;
if (lastFocused)
{
auto termControlHost = lastFocused->_control.try_as<TermControlHost>();
return termControlHost ? termControlHost.Terminal() : nullptr;
}
return nullptr;
}
// Method Description:
@ -426,7 +463,7 @@ bool Pane::_HasFocusedChild() const noexcept
// We're intentionally making this one giant expression, so the compiler
// will skip the following lookups if one of the lookups before it returns
// true
return (_control && _control.GetControl().FocusState() != FocusState::Unfocused) ||
return (_control && _control.IsFocused()) ||
(_firstChild && _firstChild->_HasFocusedChild()) ||
(_secondChild && _secondChild->_HasFocusedChild());
}
@ -445,7 +482,7 @@ void Pane::UpdateFocus()
if (_IsLeaf())
{
const auto controlFocused = _control &&
_control.GetControl().FocusState() != FocusState::Unfocused;
_control.IsFocused();
_lastFocused = controlFocused;
}
@ -468,7 +505,8 @@ void Pane::_FocusFirstChild()
{
if (_IsLeaf())
{
_control.GetControl().Focus(FocusState::Programmatic);
_control.Focus();
// _control.GetControl().Focus(FocusState::Programmatic);
}
else
{
@ -495,9 +533,13 @@ void Pane::UpdateSettings(const TerminalSettings& settings, const GUID& profile)
}
else
{
// TODO check if out profile is nullopt. If it is, then we don't have a terminal
if (profile == _profile)
{
_control.UpdateSettings(settings);
if (auto termControlHost = _control.try_as<TermControlHost>())
{
termControlHost.Terminal().UpdateSettings(settings);
}
}
}
}
@ -537,7 +579,8 @@ void Pane::_CloseChild(const bool closeFirst)
_profile = remainingChild->_profile;
// Add our new event handler before revoking the old one.
_connectionClosedToken = _control.ConnectionClosed({ this, &Pane::_ControlClosedHandler });
// _connectionClosedToken = _control.ConnectionClosed({ this, &Pane::_ControlClosedHandler });
_connectionClosedToken = _control.CloseRequested({ this, &Pane::_ControlClosedHandler2 });
// Revoke the old event handlers. Remove both the handlers for the panes
// themselves closing, and remove their handlers for their controls
@ -545,8 +588,10 @@ void Pane::_CloseChild(const bool closeFirst)
// they'll trigger only our event handler for the control's close.
_firstChild->Closed(_firstClosedToken);
_secondChild->Closed(_secondClosedToken);
closedChild->_control.ConnectionClosed(closedChild->_connectionClosedToken);
remainingChild->_control.ConnectionClosed(remainingChild->_connectionClosedToken);
// closedChild->_control.ConnectionClosed(closedChild->_connectionClosedToken);
// remainingChild->_control.ConnectionClosed(remainingChild->_connectionClosedToken);
closedChild->_control.CloseRequested(closedChild->_connectionClosedToken);
remainingChild->_control.CloseRequested(remainingChild->_connectionClosedToken);
// If either of our children was focused, we want to take that focus from
// them.
@ -564,11 +609,12 @@ void Pane::_CloseChild(const bool closeFirst)
_separatorRoot = { nullptr };
// Reattach the TermControl to our grid.
_root.Children().Append(_control.GetControl());
_root.Children().Append(_control.GetRoot());
if (_lastFocused)
{
_control.GetControl().Focus(FocusState::Programmatic);
_control.Focus();
// _control.GetControl().Focus(FocusState::Programmatic);
}
_splitState = SplitState::None;
@ -601,7 +647,8 @@ void Pane::_CloseChild(const bool closeFirst)
// Revoke event handlers on old panes and controls
oldFirst->Closed(oldFirstToken);
oldSecond->Closed(oldSecondToken);
closedChild->_control.ConnectionClosed(closedChild->_connectionClosedToken);
// closedChild->_control.ConnectionClosed(closedChild->_connectionClosedToken);
closedChild->_control.CloseRequested(closedChild->_connectionClosedToken);
// Reset our UI:
_root.Children().Clear();
@ -786,7 +833,8 @@ void Pane::_ApplySplitDefinitions()
// - control: A TermControl to use in the new pane.
// Return Value:
// - <none>
void Pane::SplitVertical(const GUID& profile, const TermControl& control)
// void Pane::SplitVertical(const GUID& profile, const TermControl& control)
void Pane::SplitVertical(const GUID& profile, const IControlHost& control)
{
// If we're not the leaf, recurse into our children to split them.
if (!_IsLeaf())
@ -815,7 +863,8 @@ void Pane::SplitVertical(const GUID& profile, const TermControl& control)
// - control: A TermControl to use in the new pane.
// Return Value:
// - <none>
void Pane::SplitHorizontal(const GUID& profile, const TermControl& control)
// void Pane::SplitHorizontal(const GUID& profile, const TermControl& control)
void Pane::SplitHorizontal(const GUID& profile, const IControlHost& control)
{
if (!_IsLeaf())
{
@ -843,14 +892,16 @@ void Pane::SplitHorizontal(const GUID& profile, const TermControl& control)
// - control: A TermControl to use in the new pane.
// Return Value:
// - <none>
void Pane::_Split(SplitState splitType, const GUID& profile, const TermControl& control)
// void Pane::_Split(SplitState splitType, const GUID& profile, const TermControl& control)
void Pane::_Split(SplitState splitType, const GUID& profile, const IControlHost& control)
{
// Lock the create/close lock so that another operation won't concurrently
// modify our tree
std::unique_lock lock{ _createCloseLock };
// revoke our handler - the child will take care of the control now.
_control.ConnectionClosed(_connectionClosedToken);
// _control.ConnectionClosed(_connectionClosedToken);
_control.CloseRequested(_connectionClosedToken);
_connectionClosedToken.value = 0;
_splitState = splitType;

View file

@ -33,7 +33,8 @@ public:
Horizontal = 2
};
Pane(const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control, const bool lastFocused = false);
// Pane(const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control, const bool lastFocused = false);
Pane(const GUID& profile, const winrt::TerminalApp::IControlHost& control, const bool lastFocused = false);
std::shared_ptr<Pane> GetFocusedPane();
winrt::Microsoft::Terminal::TerminalControl::TermControl GetFocusedTerminalControl();
@ -49,8 +50,10 @@ public:
bool ResizePane(const winrt::TerminalApp::Direction& direction);
bool NavigateFocus(const winrt::TerminalApp::Direction& direction);
void SplitHorizontal(const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
void SplitVertical(const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
// void SplitHorizontal(const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
// void SplitVertical(const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
void SplitHorizontal(const GUID& profile, const winrt::TerminalApp::IControlHost& control);
void SplitVertical(const GUID& profile, const winrt::TerminalApp::IControlHost& control);
void Close();
@ -59,7 +62,8 @@ public:
private:
winrt::Windows::UI::Xaml::Controls::Grid _root{};
winrt::Windows::UI::Xaml::Controls::Grid _separatorRoot{ nullptr };
winrt::Microsoft::Terminal::TerminalControl::TermControl _control{ nullptr };
// winrt::Microsoft::Terminal::TerminalControl::TermControl _control{ nullptr };
winrt::TerminalApp::IControlHost _control{ nullptr };
std::shared_ptr<Pane> _firstChild{ nullptr };
std::shared_ptr<Pane> _secondChild{ nullptr };
@ -79,7 +83,8 @@ private:
bool _HasFocusedChild() const noexcept;
void _SetupChildCloseHandlers();
void _Split(SplitState splitType, const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
// void _Split(SplitState splitType, const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
void _Split(SplitState splitType, const GUID& profile, const winrt::TerminalApp::IControlHost& control);
void _CreateRowColDefinitions(const winrt::Windows::Foundation::Size& rootSize);
void _CreateSplitContent();
void _ApplySplitDefinitions();
@ -91,6 +96,7 @@ private:
void _FocusFirstChild();
void _ControlClosedHandler();
void _ControlClosedHandler2(const winrt::Windows::Foundation::IInspectable& sender, const winrt::TerminalApp::ClosedEventArgs& args);
std::pair<float, float> _GetPaneSizes(const float& fullSize);

View file

@ -0,0 +1,51 @@
#include "pch.h"
#include "RichTextBoxControlHost.h"
#include "RichTextBoxControlHost.g.cpp"
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Core;
namespace winrt::TerminalApp::implementation
{
RichTextBoxControlHost::RichTextBoxControlHost()
{
InitializeComponent();
}
// Windows::UI::Xaml::Controls::Control RichTextBoxControlHost::GetControl()
// {
// return _Editor();
// }
Windows::UI::Xaml::UIElement RichTextBoxControlHost::GetRoot()
{
return *this;
}
void RichTextBoxControlHost::Close()
{
throw hresult_not_implemented();
}
hstring RichTextBoxControlHost::GetTitle()
{
return L"foo";
}
winrt::Windows::Foundation::Size RichTextBoxControlHost::MinimumSize() const
{
return { 32, 32 };
}
bool RichTextBoxControlHost::IsFocused()
{
return _Editor().FocusState() != winrt::Windows::UI::Xaml::FocusState::Unfocused;
}
void RichTextBoxControlHost::Focus()
{
_Editor().Focus(winrt::Windows::UI::Xaml::FocusState::Programmatic);
}
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(RichTextBoxControlHost, CloseRequested, _closeRequestedHandlers, TerminalApp::IControlHost, TerminalApp::ClosedEventArgs);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(RichTextBoxControlHost, TitleChanged, _titleChangedHandlers, TerminalApp::IControlHost, Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
}

View file

@ -0,0 +1,32 @@
#pragma once
#include "RichTextBoxControlHost.g.h"
#include "../../cascadia/inc/cppwinrt_utils.h"
namespace winrt::TerminalApp::implementation
{
struct RichTextBoxControlHost : RichTextBoxControlHostT<RichTextBoxControlHost>
{
RichTextBoxControlHost();
// Windows::UI::Xaml::Controls::Control GetControl();
Windows::UI::Xaml::UIElement GetRoot();
void Close();
hstring GetTitle();
Windows::Foundation::Size MinimumSize() const;
bool IsFocused();
void Focus();
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CloseRequested, _closeRequestedHandlers, TerminalApp::IControlHost, TerminalApp::ClosedEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(TitleChanged, _titleChangedHandlers, TerminalApp::IControlHost, Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
// private:
// winrt::Windows::UI::Xaml::Controls::RichEditBox _textBox{ nullptr };
};
}
namespace winrt::TerminalApp::factory_implementation
{
struct RichTextBoxControlHost : RichTextBoxControlHostT<RichTextBoxControlHost, implementation::RichTextBoxControlHost>
{
};
}

View file

@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Even though this is in the same directory, we're building from a child
// directory, so the midl compiler gets confused. TODO: This shouldn't need the
// "../". Maybe there's a build rule we can add (gross) or we can just live with
// it.
import "../IControlHost.idl";
namespace TerminalApp
{
// I can't tell you how important it is that the base class of your custom
// element is the UIElement that's at the root of the xaml file.
[default_interface] runtimeclass RichTextBoxControlHost : Windows.UI.Xaml.Controls.Grid, IControlHost
{
RichTextBoxControlHost();
};
}

View file

@ -0,0 +1,118 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<Grid
x:Class="TerminalApp.RichTextBoxControlHost"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TerminalApp"
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Name="_Root"
Background="{ThemeResource SystemChromeLowColor}"
mc:Ignorable="d">
<!-- <Grid.Resources>
<Style TargetType="AppBarButton">
<Setter Property="IsCompact" Value="True"/>
</Style>
</Grid.Resources> -->
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<RelativePanel
Grid.Row="0"
HorizontalAlignment="Stretch">
<!-- <RelativePanel.Resources>
<Style TargetType="Button">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Margin" Value="0,0,8,0" />
</Style>
</RelativePanel.Resources> -->
<!-- <Button
x:Name="openFileButton"
AutomationProperties.Name="Open file"
ToolTipService.ToolTip="Open file">
<Button.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8E5;"/>
</Button.Content>
</Button> -->
<!-- <Button
x:Name="saveFileButton"
AutomationProperties.Name="Save file"
ToolTipService.ToolTip="Save file"
RelativePanel.RightOf="openFileButton">
<Button.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE74E;"/>
</Button.Content>
</Button> -->
<Button
x:Name="_CloseButton"
Background="Transparent"
AutomationProperties.Name="Close"
ToolTipService.ToolTip="Close"
RelativePanel.AlignRightWithPanel="True">
<Button.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8BB;"/>
</Button.Content>
</Button>
</RelativePanel>
<!-- <StackPanel
Grid.Row="0"
Orientation="Horizontal">
<AppBarButton x:Name="_OpenFileButton"
Icon="OpenFile"/>
<AppBarButton Icon="Save"
Margin="8,0,0,0"/>
<AppBarButton Icon="Bold"
Margin="0,0,8,0"/>
<AppBarButton x:Name="_ItalicButton"
Icon="Italic"
Margin="0,0,8,0"/>
<AppBarButton x:Name="_UnderlineButton"
Icon="Underline"/>
</StackPanel> -->
<!-- <StackPanel
Grid.Row="0"
Orientation="Horizontal">
<Button>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8E5;"/>
</Button>
<Button>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE74E;"/>
</Button>
<Button>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8DD;"/>
</Button>
<Button>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8DB;"/>
</Button>
</StackPanel> -->
<!-- <Button
Grid.Row="0">
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8E5;"/>
Foo
</Button> -->
<!-- <TextBlock>Foo</TextBlock> -->
<RichEditBox x:Name="_Editor"
Grid.Row="1"
VerticalAlignment="Stretch"
/>
</Grid>

View file

@ -0,0 +1,46 @@
#include "pch.h"
#include "SettingsHost.h"
#include "SettingsHost.g.cpp"
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Windows::Media;
namespace winrt::TerminalApp::implementation
{
SettingsHost::SettingsHost()
{
InitializeComponent();
}
Windows::UI::Xaml::UIElement SettingsHost::GetRoot()
{
return *this;
}
void SettingsHost::Close()
{
throw hresult_not_implemented();
}
hstring SettingsHost::GetTitle()
{
return L"Settings";
}
winrt::Windows::Foundation::Size SettingsHost::MinimumSize() const
{
return { 32, 32 };
}
bool SettingsHost::IsFocused()
{
return _Editor().FocusState() != FocusState::Unfocused;
}
void SettingsHost::Focus()
{
_Editor().Focus(FocusState::Programmatic);
}
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(SettingsHost, CloseRequested, _closeRequestedHandlers, TerminalApp::IControlHost, TerminalApp::ClosedEventArgs);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(SettingsHost, TitleChanged, _titleChangedHandlers, TerminalApp::IControlHost, Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
}

View file

@ -0,0 +1,32 @@
#pragma once
#include "SettingsHost.g.h"
#include "../../cascadia/inc/cppwinrt_utils.h"
#include <winrt/Windows.Media.h>
namespace winrt::TerminalApp::implementation
{
struct SettingsHost : SettingsHostT<SettingsHost>
{
SettingsHost();
Windows::UI::Xaml::UIElement GetRoot();
void Close();
hstring GetTitle();
Windows::Foundation::Size MinimumSize() const;
bool IsFocused();
void Focus();
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CloseRequested, _closeRequestedHandlers, TerminalApp::IControlHost, TerminalApp::ClosedEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(TitleChanged, _titleChangedHandlers, TerminalApp::IControlHost, Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
// private:
// Windows::UI::Xaml::Controls::WebView _webView{ nullptr };
};
}
namespace winrt::TerminalApp::factory_implementation
{
struct SettingsHost : SettingsHostT<SettingsHost, implementation::SettingsHost>
{
};
}

View file

@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Even though this is in the same directory, we're building from a child
// directory, so the midl compiler gets confused. TODO: This shouldn't need the
// "../". Maybe there's a build rule we can add (gross) or we can just live with
// it.
import "../IControlHost.idl";
namespace TerminalApp
{
// I can't tell you how important it is that the base class of your custom
// element is the UIElement that's at the root of the xaml file.
[default_interface] runtimeclass SettingsHost : Windows.UI.Xaml.Controls.Grid, IControlHost
{
SettingsHost();
};
}

View file

@ -0,0 +1,78 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<Grid
x:Class="TerminalApp.SettingsHost"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TerminalApp"
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Name="_Root"
Background="{ThemeResource SystemChromeLowColor}"
mc:Ignorable="d">
<!-- <Grid.Resources>
<Style TargetType="AppBarButton">
<Setter Property="IsCompact" Value="True"/>
</Style>
</Grid.Resources> -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<RelativePanel
Grid.Column="0"
HorizontalAlignment="Stretch">
<!-- <RelativePanel.Resources>
<Style TargetType="Button">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Margin" Value="0,0,8,0" />
</Style>
</RelativePanel.Resources> -->
<!-- <Button
x:Name="openFileButton"
AutomationProperties.Name="Open file"
ToolTipService.ToolTip="Open file">
<Button.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8E5;"/>
</Button.Content>
</Button> -->
<!-- <Button
x:Name="saveFileButton"
AutomationProperties.Name="Save file"
ToolTipService.ToolTip="Save file"
RelativePanel.RightOf="openFileButton">
<Button.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE74E;"/>
</Button.Content>
</Button> -->
<Button
x:Name="_CloseButton"
Background="Transparent"
AutomationProperties.Name="Close"
ToolTipService.ToolTip="Close"
RelativePanel.AlignRightWithPanel="True">
<Button.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8BB;"/>
</Button.Content>
</Button>
</RelativePanel>
<RichEditBox x:Name="_Editor"
Grid.Column="1"
Height="100"
/>
<!-- <WebView x:Name="_WebView" Grid.Row="2"/> -->
<!--<StackPanel Grid.Row="2">-->
<!-- <WebView x:Name="_WebView" Source="http://www.github.com/microsoft/terminal"/> -->
<!--<WebView x:Name="_WebView"/>-->
<!--</StackPanel>-->
</Grid>

View file

@ -8,10 +8,11 @@ using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Microsoft::Terminal::Settings;
using namespace winrt::Microsoft::Terminal::TerminalControl;
using namespace winrt::TerminalApp;
static const int TabViewFontSize = 12;
Tab::Tab(const GUID& profile, const TermControl& control)
Tab::Tab(const GUID& profile, const IControlHost& control)
{
_rootPane = std::make_shared<Pane>(profile, control, true);
@ -195,7 +196,7 @@ void Tab::Scroll(const int delta)
// - control: A TermControl to use in the new pane.
// Return Value:
// - <none>
void Tab::AddVerticalSplit(const GUID& profile, TermControl& control)
void Tab::AddVerticalSplit(const GUID& profile, const IControlHost& control)
{
_rootPane->SplitVertical(profile, control);
}
@ -208,7 +209,7 @@ void Tab::AddVerticalSplit(const GUID& profile, TermControl& control)
// - control: A TermControl to use in the new pane.
// Return Value:
// - <none>
void Tab::AddHorizontalSplit(const GUID& profile, TermControl& control)
void Tab::AddHorizontalSplit(const GUID& profile, const IControlHost& control)
{
_rootPane->SplitHorizontal(profile, control);
}

View file

@ -8,7 +8,7 @@
class Tab
{
public:
Tab(const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
Tab(const GUID& profile, const winrt::TerminalApp::IControlHost& control);
winrt::Microsoft::UI::Xaml::Controls::TabViewItem GetTabViewItem();
winrt::Windows::UI::Xaml::UIElement GetRootElement();
@ -19,8 +19,8 @@ public:
void SetFocused(const bool focused);
void Scroll(const int delta);
void AddVerticalSplit(const GUID& profile, winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
void AddHorizontalSplit(const GUID& profile, winrt::Microsoft::Terminal::TerminalControl::TermControl& control);
void AddVerticalSplit(const GUID& profile, const winrt::TerminalApp::IControlHost& control);
void AddHorizontalSplit(const GUID& profile, const winrt::TerminalApp::IControlHost& control);
void UpdateFocus();
void ResizeContent(const winrt::Windows::Foundation::Size& newSize);

View file

@ -0,0 +1,54 @@
#include "pch.h"
#include "TermControlHost.h"
#include "TermControlHost.g.cpp"
namespace winrt::TerminalApp::implementation
{
TermControlHost::TermControlHost(Microsoft::Terminal::TerminalControl::TermControl control) :
_control{ control }
{
// TODO: Hookup the control's titlechanged event, closed event
}
// Windows::UI::Xaml::Controls::Control TermControlHost::GetControl()
// {
// return _control.GetControl();
// }
Windows::UI::Xaml::UIElement TermControlHost::GetRoot()
{
return _control.GetControl();
}
void TermControlHost::Close()
{
_control.Close();
}
hstring TermControlHost::GetTitle()
{
return _control.Title();
}
Microsoft::Terminal::TerminalControl::TermControl TermControlHost::Terminal()
{
return _control;
}
winrt::Windows::Foundation::Size TermControlHost::MinimumSize() const
{
return _control.MinimumSize();
}
bool TermControlHost::IsFocused()
{
return _control.GetControl().FocusState() != winrt::Windows::UI::Xaml::FocusState::Unfocused;
}
void TermControlHost::Focus()
{
_control.GetControl().Focus(winrt::Windows::UI::Xaml::FocusState::Programmatic);
}
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControlHost, CloseRequested, _closeRequestedHandlers, TerminalApp::IControlHost, TerminalApp::ClosedEventArgs);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TermControlHost, TitleChanged, _titleChangedHandlers, TerminalApp::IControlHost, Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
}

View file

@ -0,0 +1,35 @@
#pragma once
#include "TermControlHost.g.h"
#include "../../cascadia/inc/cppwinrt_utils.h"
#include <winrt/Microsoft.Terminal.TerminalControl.h>
namespace winrt::TerminalApp::implementation
{
struct TermControlHost : TermControlHostT<TermControlHost>
{
TermControlHost(Microsoft::Terminal::TerminalControl::TermControl control);
// Windows::UI::Xaml::Controls::Control GetControl();
Windows::UI::Xaml::UIElement GetRoot();
void Close();
hstring GetTitle();
Microsoft::Terminal::TerminalControl::TermControl Terminal();
Windows::Foundation::Size MinimumSize() const;
bool IsFocused();
void Focus();
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CloseRequested, _closeRequestedHandlers, TerminalApp::IControlHost, TerminalApp::ClosedEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(TitleChanged, _titleChangedHandlers, TerminalApp::IControlHost, Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
private:
Microsoft::Terminal::TerminalControl::TermControl _control{ nullptr };
};
}
namespace winrt::TerminalApp::factory_implementation
{
struct TermControlHost : TermControlHostT<TermControlHost, implementation::TermControlHost>
{
};
}

View file

@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Even though this is in the same directory, we're building from a child
// directory, so the midl compiler gets confused. TODO: This shouldn't need the
// "../". Maybe there's a build rule we can add (gross) or we can just live with
// it.
import "../IControlHost.idl";
namespace TerminalApp
{
[default_interface] runtimeclass TermControlHost : IControlHost
{
TermControlHost(Microsoft.Terminal.TerminalControl.TermControl control);
Microsoft.Terminal.TerminalControl.TermControl Terminal { get; };
};
}

View file

@ -0,0 +1,55 @@
#include "pch.h"
#include "TextBlockControlHost.h"
#include "TextBlockControlHost.g.cpp"
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Core;
namespace winrt::TerminalApp::implementation
{
TextBlockControlHost::TextBlockControlHost() :
_textBox{}
{
_textBox.HorizontalAlignment(HorizontalAlignment::Stretch);
_textBox.VerticalAlignment(VerticalAlignment::Stretch);
// _textBox.IsEnabled(true);
// _textBox.Text(L"I am a TextBox");
}
// Windows::UI::Xaml::Controls::Control TextBlockControlHost::GetControl()
// {
// return _textBox;
// }
Windows::UI::Xaml::UIElement TextBlockControlHost::GetRoot()
{
return _textBox;
}
void TextBlockControlHost::Close()
{
throw hresult_not_implemented();
}
hstring TextBlockControlHost::GetTitle()
{
return L"foo";
}
winrt::Windows::Foundation::Size TextBlockControlHost::MinimumSize() const
{
return { 32, 32 };
}
bool TextBlockControlHost::IsFocused() const
{
return _textBox.FocusState() != FocusState::Unfocused;
}
void TextBlockControlHost::Focus()
{
_textBox.Focus(FocusState::Programmatic);
}
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TextBlockControlHost, CloseRequested, _closeRequestedHandlers, TerminalApp::IControlHost, TerminalApp::ClosedEventArgs);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(TextBlockControlHost, TitleChanged, _titleChangedHandlers, TerminalApp::IControlHost, Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
}

View file

@ -0,0 +1,32 @@
#pragma once
#include "TextBlockControlHost.g.h"
#include "../../cascadia/inc/cppwinrt_utils.h"
namespace winrt::TerminalApp::implementation
{
struct TextBlockControlHost : TextBlockControlHostT<TextBlockControlHost>
{
TextBlockControlHost();
// Windows::UI::Xaml::Controls::Control GetControl();
Windows::UI::Xaml::UIElement GetRoot();
void Close();
hstring GetTitle();
Windows::Foundation::Size MinimumSize() const;
bool IsFocused() const;
void Focus();
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CloseRequested, _closeRequestedHandlers, TerminalApp::IControlHost, TerminalApp::ClosedEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(TitleChanged, _titleChangedHandlers, TerminalApp::IControlHost, Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
private:
winrt::Windows::UI::Xaml::Controls::RichEditBox _textBox{ nullptr };
};
}
namespace winrt::TerminalApp::factory_implementation
{
struct TextBlockControlHost : TextBlockControlHostT<TextBlockControlHost, implementation::TextBlockControlHost>
{
};
}

View file

@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Even though this is in the same directory, we're building from a child
// directory, so the midl compiler gets confused. TODO: This shouldn't need the
// "../". Maybe there's a build rule we can add (gross) or we can just live with
// it.
import "../IControlHost.idl";
namespace TerminalApp
{
[default_interface] runtimeclass TextBlockControlHost : IControlHost
{
TextBlockControlHost();
};
}

View file

@ -0,0 +1,78 @@
#include "pch.h"
#include "WebViewHost.h"
#include "WebViewHost.g.cpp"
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Windows::Media;
namespace winrt::TerminalApp::implementation
{
WebViewHost::WebViewHost()
{
InitializeComponent();
_webView = Controls::WebView{};
Children().Append(_webView);
// Controls::Grid::SetRow(_webView, 2);
_webView.Loaded([this](auto&&, auto&&) {
auto w = _webView.ActualWidth();
auto h = _webView.ActualHeight();
try
{
_webView.Navigate(winrt::Windows::Foundation::Uri(L"https://www.github.com/microsoft/terminal"));
// _webView.NavigateToString(L"<html><body><h2>This is an HTML fragment</h2></body></html>");
}
CATCH_LOG();
/*catch (...)
{
auto b = 0;
b++;
b;
}*/
});
_webView.NavigationStarting([this](auto&&, auto&&) {
auto a = 0;
a++;
a;
});
}
// Windows::UI::Xaml::Controls::Control WebViewHost::GetControl()
// {
// return _Editor();
// }
Windows::UI::Xaml::UIElement WebViewHost::GetRoot()
{
return *this;
}
void WebViewHost::Close()
{
throw hresult_not_implemented();
}
hstring WebViewHost::GetTitle()
{
return L"foo";
}
winrt::Windows::Foundation::Size WebViewHost::MinimumSize() const
{
return { 32, 32 };
}
bool WebViewHost::IsFocused()
{
return _Editor().FocusState() != FocusState::Unfocused;
}
void WebViewHost::Focus()
{
_Editor().Focus(FocusState::Programmatic);
}
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(WebViewHost, CloseRequested, _closeRequestedHandlers, TerminalApp::IControlHost, TerminalApp::ClosedEventArgs);
DEFINE_EVENT_WITH_TYPED_EVENT_HANDLER(WebViewHost, TitleChanged, _titleChangedHandlers, TerminalApp::IControlHost, Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
}

View file

@ -0,0 +1,33 @@
#pragma once
#include "WebViewHost.g.h"
#include "../../cascadia/inc/cppwinrt_utils.h"
#include <winrt/Windows.Media.h>
namespace winrt::TerminalApp::implementation
{
struct WebViewHost : WebViewHostT<WebViewHost>
{
WebViewHost();
// Windows::UI::Xaml::Controls::Control GetControl();
Windows::UI::Xaml::UIElement GetRoot();
void Close();
hstring GetTitle();
Windows::Foundation::Size MinimumSize() const;
bool IsFocused();
void Focus();
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CloseRequested, _closeRequestedHandlers, TerminalApp::IControlHost, TerminalApp::ClosedEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(TitleChanged, _titleChangedHandlers, TerminalApp::IControlHost, Microsoft::Terminal::TerminalControl::TitleChangedEventArgs);
private:
Windows::UI::Xaml::Controls::WebView _webView{ nullptr };
};
}
namespace winrt::TerminalApp::factory_implementation
{
struct WebViewHost : WebViewHostT<WebViewHost, implementation::WebViewHost>
{
};
}

View file

@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Even though this is in the same directory, we're building from a child
// directory, so the midl compiler gets confused. TODO: This shouldn't need the
// "../". Maybe there's a build rule we can add (gross) or we can just live with
// it.
import "../IControlHost.idl";
namespace TerminalApp
{
// I can't tell you how important it is that the base class of your custom
// element is the UIElement that's at the root of the xaml file.
[default_interface] runtimeclass WebViewHost : Windows.UI.Xaml.Controls.Grid, IControlHost
{
WebViewHost();
};
}

View file

@ -0,0 +1,79 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<Grid
x:Class="TerminalApp.WebViewHost"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TerminalApp"
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Name="_Root"
Background="{ThemeResource SystemChromeLowColor}"
mc:Ignorable="d">
<!-- <Grid.Resources>
<Style TargetType="AppBarButton">
<Setter Property="IsCompact" Value="True"/>
</Style>
</Grid.Resources> -->
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<RelativePanel
Grid.Row="0"
HorizontalAlignment="Stretch">
<!-- <RelativePanel.Resources>
<Style TargetType="Button">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Margin" Value="0,0,8,0" />
</Style>
</RelativePanel.Resources> -->
<!-- <Button
x:Name="openFileButton"
AutomationProperties.Name="Open file"
ToolTipService.ToolTip="Open file">
<Button.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8E5;"/>
</Button.Content>
</Button> -->
<!-- <Button
x:Name="saveFileButton"
AutomationProperties.Name="Save file"
ToolTipService.ToolTip="Save file"
RelativePanel.RightOf="openFileButton">
<Button.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE74E;"/>
</Button.Content>
</Button> -->
<Button
x:Name="_CloseButton"
Background="Transparent"
AutomationProperties.Name="Close"
ToolTipService.ToolTip="Close"
RelativePanel.AlignRightWithPanel="True">
<Button.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8BB;"/>
</Button.Content>
</Button>
</RelativePanel>
<RichEditBox x:Name="_Editor"
Grid.Row="1"
Height="100"
/>
<!-- <WebView x:Name="_WebView" Grid.Row="2"/> -->
<!--<StackPanel Grid.Row="2">-->
<!-- <WebView x:Name="_WebView" Source="http://www.github.com/microsoft/terminal"/> -->
<!--<WebView x:Name="_WebView"/>-->
<!--</StackPanel>-->
</Grid>

View file

@ -41,6 +41,18 @@
<Page Include="../TabRowControl.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="../RichTextBoxControlHost.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="../MediaControlHost.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="../WebViewHost.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="../SettingsHost.xaml">
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<!-- ========================= Headers ======================== -->
@ -59,6 +71,22 @@
<ClInclude Include="../TabRowControl.h">
<DependentUpon>../TabRowControl.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="../RichTextBoxControlHost.h">
<DependentUpon>../RichTextBoxControlHost.xaml</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="../MediaControlHost.h">
<DependentUpon>../MediaControlHost.xaml</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="../WebViewHost.h">
<DependentUpon>../WebViewHost.xaml</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="../SettingsHost.h">
<DependentUpon>../SettingsHost.xaml</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="../Tab.h" />
<ClInclude Include="../Pane.h" />
<ClInclude Include="../ColorScheme.h" />
@ -69,10 +97,18 @@
<ClInclude Include="../KeyChordSerialization.h" />
<ClInclude Include="../Utils.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="../AppKeyBindings.h" />
<ClInclude Include="../AppKeyBindings.h" >
<DependentUpon>../AppKeyBindings.idl</DependentUpon>
</ClInclude>
<ClInclude Include="../App.h" >
<DependentUpon>../App.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="../TermControlHost.h" >
<DependentUpon>../TermControlHost.idl</DependentUpon>
</ClInclude>
<ClInclude Include="../TextBlockControlHost.h" >
<DependentUpon>../TextBlockControlHost.idl</DependentUpon>
</ClInclude>
</ItemGroup>
<!-- ========================= Cpp Files ======================== -->
@ -90,6 +126,22 @@
<ClCompile Include="../TabRowControl.cpp">
<DependentUpon>../TabRowControl.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="../RichTextBoxControlHost.cpp">
<DependentUpon>../RichTextBoxControlHost.xaml</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="../MediaControlHost.cpp">
<DependentUpon>../MediaControlHost.xaml</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="../WebViewHost.cpp">
<DependentUpon>../WebViewHost.xaml</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="../SettingsHost.cpp">
<DependentUpon>../SettingsHost.xaml</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="../Tab.cpp" />
<ClCompile Include="../Pane.cpp" />
<ClCompile Include="../ColorScheme.cpp" />
@ -109,6 +161,12 @@
<ClCompile Include="../App.cpp" >
<DependentUpon>../App.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="../TermControlHost.cpp" >
<DependentUpon>../TermControlHost.idl</DependentUpon>
</ClCompile>
<ClCompile Include="../TextBlockControlHost.cpp" >
<DependentUpon>../TextBlockControlHost.idl</DependentUpon>
</ClCompile>
<!-- You _NEED_ to include this file and the jsoncpp IncludePath (below) if
you want to use jsoncpp -->
@ -142,6 +200,25 @@
<DependentUpon>../TabRowControl.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="../RichTextBoxControlHost.idl">
<DependentUpon>../RichTextBoxControlHost.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="../MediaControlHost.idl">
<DependentUpon>../MediaControlHost.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="../WebViewHost.idl">
<DependentUpon>../SettingsHost.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="../SettingsHost.idl">
<DependentUpon>../SettingsHost.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="../IControlHost.idl" />
<Midl Include="../TermControlHost.idl" />
<Midl Include="../TextBlockControlHost.idl" />
</ItemGroup>
<!-- ========================= Misc Files ======================== -->