Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Windows] Add TitleBar Control #23019

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open

[Windows] Add TitleBar Control #23019

wants to merge 30 commits into from

Conversation

Foda
Copy link
Member

@Foda Foda commented Jun 12, 2024

This PR is a draft and seeking API feedback for an initial release

Description of Change

This PR adds a new TitleBar control and API to set the TitleBar on a Window. It currently only applies to the Windows platform, but it's built entirely as a MAUI control to allow macOS support later.

Please read the full API description here: #13023

Feature demo (PlatformSpecifics page in Maui.Controls.Sample):

titlebar.mp4

API/Usage

The primary API is the Window.SetTitleBar function -- which removes the TitleBar control from the visual tree and inserts it as the native TitleBar (this approach was shamelessly copied from the WinAppSDK). This was used vs an attached property (ex: <Window.TitleBar>) because it was difficult to get a valid Window object when the property was first set.

Example using XAML:

MainWindow.xaml

<Window.TitleBar>
  <TitleBar
    x:Name="TeamsTitleBar"
    HeightRequest="46"
    Title="Hello World">
    <TitleBar.Content>
      <Entry
        x:Name="SearchTitleBar"
        Placeholder="Search"
        VerticalOptions="Center"
        MinimumWidthRequest="300"
        MaximumWidthRequest="450"
        HeightRequest="32"/>
    </TitleBar.Content>
  </TitleBar>
</Window.TitleBar>

Example using code

MainPage.xaml.cs

protected override void OnAppearing()
{
    base.OnAppearing();
    
    Window.TitleBar = new TitleBar()
    {
        Title = "MAUI App",
        Icon = "appicon.png",
        LeadingContent = new AvatarButton()
    };
}

Issues Fixed

Fixes #13023

@Foda Foda added this to the .NET 9 Planning milestone Jun 12, 2024
@Foda Foda requested review from rmarinho and PureWeen June 12, 2024 22:13
Copy link
Contributor

@tj-devel709 tj-devel709 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow this is super cool! Few questions from me!

src/Controls/src/Core/TitleBar/TitleBar.cs Outdated Show resolved Hide resolved
src/Controls/src/Core/TitleBar/TitleBar.cs Show resolved Hide resolved
src/Controls/src/Core/TitleBar/TitleBar.cs Show resolved Hide resolved
src/Controls/src/Core/Window/Window.cs Show resolved Hide resolved
src/Controls/src/Core/Window/Window.cs Outdated Show resolved Hide resolved
src/Core/src/Core/IWindow.cs Show resolved Hide resolved
Mike Corsaro added 2 commits June 20, 2024 11:10
@drasticactions
Copy link
Contributor

drasticactions commented Jun 23, 2024

This PR adds a new TitleBar control and API to set the TitleBar on a Window. It currently only applies to the Windows platform, but it's built entirely as a MAUI control to allow macOS support later.

How do we plan to add support for this with Catalyst?

If you want to use something like NSToolbarDelegate to build a title bar like this:

Screenshot from 2024-06-23 16-48-49

That uses specific NSToolBar items and a layout system where you set identifiers and set the flexibility of where items should appear. The TitleBar API allows for arbitrary existing controls and layout which AFAIK wouldn't work with that delegate.

So if you want arbitrary controls, you would probably need to do something special with the UIWindow, merge the title bar into the inner content, and handle the managing the layout yourself. Or there could be other ways to create a more "native" looking titlebar on Catalyst that uses arbitrary controls. Making sure we have a plan for that now before deciding on this approach only to see it won't work on MacOS wouldn't be ideal.

@Foda
Copy link
Member Author

Foda commented Jun 24, 2024

This PR adds a new TitleBar control and API to set the TitleBar on a Window. It currently only applies to the Windows platform, but it's built entirely as a MAUI control to allow macOS support later.

How do we plan to add support for this with Catalyst?

If you want to use something like NSToolbarDelegate to build a title bar like this:

Screenshot from 2024-06-23 16-48-49

That uses specific NSToolBar items and a layout system where you set identifiers and set the flexibility of where items should appear. The TitleBar API allows for arbitrary existing controls and layout which AFAIK wouldn't work with that delegate.

So if you want arbitrary controls, you would probably need to do something special with the UIWindow, merge the title bar into the inner content, and handle the managing the layout yourself. Or there could be other ways to create a more "native" looking titlebar on Catalyst that uses arbitrary controls. Making sure we have a plan for that now before deciding on this approach only to see it won't work on MacOS wouldn't be ideal.

Yeah, we did talk briefly about this. One of the reasons why I made it a native MAUI control was so that we could just plop it into the "titlebar area" on both Win and Mac. I know it's possible to draw whatever custom control you want in the TitleBar (see: Edge w/ tabs) but I'm not sure what API does that, or what exactly the behavior is (maybe https://developer.apple.com/documentation/uikit/mac_catalyst/removing_the_title_bar_in_your_mac_app_built_with_mac_catalyst ??).

I'm going to play around today to see how that API works

@Foda
Copy link
Member Author

Foda commented Jun 24, 2024

@drasticactions here's what it looks like using that API + NavigationPage.TitleView:
image

I couldn't quite figure out how to get the NavigationBar to not have that top padding -- someone more familiar w/ macOS layout constraints would be able to figure it out. But other than the top margin, it works as expected: controls in that are can be clicked, etc, without breaking the drag behavior.

@Foda
Copy link
Member Author

Foda commented Jun 27, 2024

/rebase

@Foda Foda marked this pull request as ready for review July 8, 2024 22:05
@Foda Foda requested a review from a team as a code owner July 8, 2024 22:05
@Foda Foda requested a review from jsuarezruiz July 8, 2024 22:05
@Foda
Copy link
Member Author

Foda commented Jul 10, 2024

/rebase

using System.Threading.Tasks;
using Maui.Controls.Sample.ViewModels.Base;

namespace Maui.Controls.Sample.ViewModels
Copy link
Collaborator

@MartyIX MartyIX Jul 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to use file-scope namespaces in new files?

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change does not look like it is needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Provide a cross platform API for customizing the TitleBar of desktop apps
9 participants