Skip to content

Commit

Permalink
Lights
Browse files Browse the repository at this point in the history
  • Loading branch information
niels9001 committed Dec 17, 2024
1 parent 6fdff69 commit 8b4e646
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 2 deletions.
12 changes: 11 additions & 1 deletion src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/ActionBar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@
</UserControl.Resources>

<Grid Padding="8" ColumnSpacing="8">
<Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<!-- Inner core -->
<GradientStop Offset="0" Color="#40ff6600" />
<!-- Outer fade -->
<GradientStop Offset="1" Color="#00ff6600" />
</LinearGradientBrush>
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
Expand All @@ -56,7 +64,9 @@
Width="20"
Height="20"
Margin="12,0,0,0"
Background="{ThemeResource AccentFillColorDefaultBrush}"
Background="#ff6600"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="{StaticResource ControlCornerRadius}" />

<TextBlock
Expand Down
39 changes: 39 additions & 0 deletions src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/Lights/AmbLight.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.UI;
using Microsoft.UI.Composition;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media;

namespace Microsoft.CmdPal.UI.Controls;

internal sealed partial class AmbLight : XamlLight
{
private static readonly string Id = typeof(AmbLight).FullName!;

protected override void OnConnected(UIElement newElement)
{
var compositor = CompositionTarget.GetCompositorForCurrentThread();

// Create AmbientLight and set its properties
var ambientLight = compositor.CreateAmbientLight();
ambientLight.Color = Colors.White;

// Associate CompositionLight with XamlLight
CompositionLight = ambientLight;

// Add UIElement to the Light's Targets
AddTargetElement(GetId(), newElement);
}

protected override void OnDisconnected(UIElement oldElement)
{
// Dispose Light when it is removed from the tree
RemoveTargetElement(GetId(), oldElement);
CompositionLight.Dispose();
}

protected override string GetId() => Id;
}
104 changes: 104 additions & 0 deletions src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/Lights/HoverLight.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Numerics;
using Microsoft.UI;
using Microsoft.UI.Composition;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Hosting;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;

namespace Microsoft.CmdPal.UI.Controls;

internal sealed partial class HoverLight : XamlLight
{
private ExpressionAnimation? _lightPositionExpression;
private Vector3KeyFrameAnimation? _offsetAnimation;
private static readonly string Id = typeof(HoverLight).FullName!;

protected override void OnConnected(UIElement targetElement)
{
var compositor = CompositionTarget.GetCompositorForCurrentThread();

// Create SpotLight and set its properties
var spotLight = compositor.CreateSpotLight();
spotLight.InnerConeAngleInDegrees = 50f;
spotLight.InnerConeColor = Colors.FloralWhite;
spotLight.OuterConeColor = Colors.FloralWhite;
spotLight.OuterConeAngleInDegrees = 20f;
spotLight.ConstantAttenuation = 1f;
spotLight.LinearAttenuation = 0.253f;
spotLight.QuadraticAttenuation = 0.58f;

// Associate CompositionLight with XamlLight
CompositionLight = spotLight;

// Define resting position Animation
Vector3 restingPosition = new(200, 200, 400);
var cbEasing = compositor.CreateCubicBezierEasingFunction(new Vector2(0.3f, 0.7f), new Vector2(0.9f, 0.5f));
_offsetAnimation = compositor.CreateVector3KeyFrameAnimation();
_offsetAnimation.InsertKeyFrame(1, restingPosition, cbEasing);
_offsetAnimation.Duration = TimeSpan.FromSeconds(0.5f);

spotLight.Offset = restingPosition;

// Define expression animation that relates light's offset to pointer position
var hoverPosition = ElementCompositionPreview.GetPointerPositionPropertySet(targetElement);
_lightPositionExpression = compositor.CreateExpressionAnimation("Vector3(hover.Position.X, hover.Position.Y, height)");
_lightPositionExpression.SetReferenceParameter("hover", hoverPosition);
_lightPositionExpression.SetScalarParameter("height", 100.0f);

// Configure pointer entered/ exited events
targetElement.PointerMoved += TargetElement_PointerMoved;
targetElement.PointerExited += TargetElement_PointerExited;

// Add UIElement to the Light's Targets
AddTargetElement(GetId(), targetElement);
}

private void MoveToRestingPosition() =>

// Start animation on SpotLight's Offset
CompositionLight?.StartAnimation("Offset", _offsetAnimation);

private void TargetElement_PointerMoved(object sender, PointerRoutedEventArgs e)
{
if (CompositionLight != null)
{
// touch input is still UI thread-bound as of the Creator's Update
if (e.Pointer.PointerDeviceType == Microsoft.UI.Input.PointerDeviceType.Touch)
{
var offset = e.GetCurrentPoint((UIElement)sender).Position.ToVector2();

if (CompositionLight is SpotLight light)
{
light.Offset = new Vector3(offset.X, offset.Y, 15);
}
}
else
{
// Get the pointer's current position from the property and bind the SpotLight's X-Y Offset
CompositionLight.StartAnimation("Offset", _lightPositionExpression);
}
}
}

private void TargetElement_PointerExited(object sender, PointerRoutedEventArgs e) =>

// Move to resting state when pointer leaves targeted UIElement
MoveToRestingPosition();

protected override void OnDisconnected(UIElement oldElement)
{
// Dispose Light and Composition resources when it is removed from the tree
RemoveTargetElement(GetId(), oldElement);
CompositionLight.Dispose();

_lightPositionExpression?.Dispose();
_offsetAnimation?.Dispose();
}

protected override string GetId() => Id;
}
9 changes: 8 additions & 1 deletion src/modules/cmdpal/Microsoft.CmdPal.UI/ShellPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
mc:Ignorable="d">

<Grid>

<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
Expand All @@ -28,9 +29,15 @@
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="0,1,0,1">
<Frame Name="RootFrame" IsNavigationStackEnabled="True" />

</Grid>


<controls:ActionBar Grid.Row="2" VerticalAlignment="Top" />
<controls:ActionBar Grid.Row="2" VerticalAlignment="Top">
<controls:ActionBar.Lights>
<controls:HoverLight />
<controls:AmbLight />
</controls:ActionBar.Lights>
</controls:ActionBar>
</Grid>
</Page>

1 comment on commit 8b4e646

@github-actions
Copy link

Choose a reason for hiding this comment

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

@check-spelling-bot Report

🔴 Please review

See the 📜action log or 📝 job summary for details.

Unrecognized words (160)
adaptivecards
affordances
Aliias
Allman
Aot
apicontract
APPICONREFERENCE
APPMODEL
APPPUBLISHER
asynchonously
AVery
bodgy
Bools
builttoroam
BYEXENAME
Cantarell
cdn
channelurl
CLSIDs
cmdpal
commandpalette
contextitems
contractversion
CREATETHREAD
CREATEWINDOW
cswin
Ctl
CVS
datas
DDEAPPLICATION
DDECOMMAND
DDEIFEXEC
DDETOPIC
defaultlib
DEFAULTTOFOLDER
DEFAULTTOSTAR
DELEGATEEXECUTE
devpal
dic
dragable
Droid
DROPTARGET
emoji
ESPN
extensionsdk
favourites
filterbox
Fira
flaticon
FRIENDLYAPPNAME
FRIENDLYDOCNAME
getcommand
gifv
gitroot
googleapis
Griese
gsl
Hande
harcoded
HKC
homies
HSSH
icf
icommanditems
icommandprovider
icondatatype
iextn
IGNOREBASECLASS
IGo
imgflip
imgur
implementaions
implmenting
inbox
infotip
INLINEPREFIX
inotifypropchanged
intederminate
INVALIDCALL
INVALIDINDEX
isection
keyboardtester
Keychain
kinda
libraryincludes
libucrt
libucrtd
listpage
localappdata
LUQ
lvm
MBM
meme
memicmp
microwaved
minwindef
mobileredirect
mtu
murmurhash
MVVMTK
nicksnettravels
NOFIXUPS
nonspace
NOOPEN
NOREMAPCLSID
NOTRUNCATE
NOUSERSETTINGS
nullness
paintin
Playbadge
Poc
Podcasts
Pokedex
Puser
QUICKTIP
Rasterization
realease
reblogs
refelct
refering
REGISTERCLASSEX
REMAPRUNDLL
renamve
rsdk
searchtext
seearch
seperators
SFBS
sharepoint
SHELLEXTENSION
SHELLNEWVALUE
shich
sooon
sourced
sourcedoc
Spongebob
spongebot
stdcpp
throughs
TIcon
TILEINFO
tlc
TLDR
Tralalal
ucrt
ucrtd
unistalls
videourl
vkey
vulnerbilities
wasdk
Wholegrain
wic
WUX
xclip
xdoc
XJSNh
ycombinator
youtube
zadjii
Previously acknowledged words that are now absent BODGY Emoji Infotip pef SYSTEMWOW VKey Wbemidl WIC 🫥
Some files were automatically ignored 🙈

These sample patterns would exclude them:

^\Qsrc/modules/cmdpal/doc/initial-sdk-spec/list-elements-mock-002.pdn\E$
^\Qsrc/modules/cmdpal/Exts/PokedexExtension/Pages/PokedexExtensionPage.cs\E$

You should consider adding them to:

.github/actions/spell-check/excludes.txt

File matching is via Perl regular expressions.

To check these files, more of their words need to be in the dictionary than not. You can use patterns.txt to exclude portions, add items to the dictionary (e.g. by adding them to allow.txt), or fix typos.

To accept these unrecognized words as correct and remove the previously acknowledged and now absent words and update file exclusions, you could run the following commands

... in a clone of the [email protected]:zadjii-msft/PowerToys.git repository
on the niels9001/lights branch (ℹ️ how do I use this?):

curl -s -S -L 'https://raw.githubusercontent.com/check-spelling/check-spelling/v0.0.22/apply.pl' |
perl - 'https://github.com/zadjii-msft/PowerToys/actions/runs/12376741341/attempts/1'
Available 📚 dictionaries could cover words (expected and unrecognized) not in the 📘 dictionary

This includes both expected items (1910) from .github/actions/spell-check/expect.txt and unrecognized words (160)

Dictionary Entries Covers Uniquely
cspell:npm/dict/npm.txt 302 1 1
cspell:r/src/r.txt 543 1 1
cspell:cpp/src/people.txt 23 1
cspell:cpp/src/ecosystem.txt 51 1

Consider adding them (in .github/workflows/spelling2.yml) for uses: check-spelling/[email protected] in its with:

      with:
        extra_dictionaries:
          cspell:npm/dict/npm.txt
          cspell:r/src/r.txt
          cspell:cpp/src/people.txt
          cspell:cpp/src/ecosystem.txt

To stop checking additional dictionaries, add (in .github/workflows/spelling2.yml) for uses: check-spelling/[email protected] in its with:

check_extra_dictionaries: ''
Pattern suggestions ✂️ (1)

You could add these patterns to .github/actions/spell-check/patterns.txt:

# Automatically suggested patterns
# hit-count: 1 file-count: 1
# imgur
\bimgur\.com/[^.]+

Errors (5)

See the 📜action log or 📝 job summary for details.

❌ Errors Count
ℹ️ binary-file 1
ℹ️ candidate-pattern 1
❌ check-file-path 593
❌ forbidden-pattern 3
ℹ️ noisy-file 1

See ❌ Event descriptions for more information.

If the flagged items are 🤯 false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it,
    try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

Please sign in to comment.