Skip to content

Commit 6ee5bf5

Browse files
authored
Merge pull request #473 from CoolCoderSuper/native_menu
Add native menu and tray icon bindings
2 parents bc148de + 2851e71 commit 6ee5bf5

File tree

6 files changed

+108
-2
lines changed

6 files changed

+108
-2
lines changed

src/Avalonia.FuncUI.ControlCatalog/Avalonia.FuncUI.ControlCatalog/ControlCatalog.fs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ open Avalonia.FuncUI.Elmish
88
open Avalonia.FuncUI.ControlCatalog.Views
99
open Avalonia.Themes.Fluent
1010
open Avalonia.FuncUI
11+
open Avalonia.FuncUI.DSL
1112
open Avalonia.Controls
1213

1314
type MainWindow() as this =
@@ -26,6 +27,24 @@ type App() =
2627
inherit Application()
2728

2829
override this.Initialize() =
30+
let menu = NativeMenu.create [
31+
NativeMenu.items [
32+
NativeMenuItem.create [
33+
NativeMenuItem.header "File"
34+
NativeMenuItem.isChecked true
35+
NativeMenuItem.isEnabled false
36+
]
37+
]
38+
]
39+
let tray =
40+
TrayIcon.create [
41+
TrayIcon.toolTipText "Control Catalog"
42+
TrayIcon.menu menu
43+
]
44+
let icon = Avalonia.FuncUI.VirtualDom.VirtualDom.createObject tray :?> TrayIcon
45+
let icons = TrayIcons()
46+
icons.Add(icon)
47+
TrayIcon.SetIcons(this, icons)
2948
this.Styles.Add (FluentTheme())
3049
this.Styles.Load "avares://Avalonia.FuncUI.ControlCatalog/Styles/TabControl.xaml"
3150

src/Avalonia.FuncUI/Avalonia.FuncUI.fsproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,11 @@
154154
<Compile Include="DSL\ListBoxItem.fs" />
155155
<Compile Include="DSL\MenuBase.fs" />
156156
<Compile Include="DSL\Menu.fs" />
157+
<Compile Include="DSL\NativeMenu.fs" />
157158
<Compile Include="DSL\ContextMenu.fs" />
158159
<Compile Include="DSL\MenuItem.fs" />
160+
<Compile Include="DSL\NativeMenuItem.fs" />
161+
<Compile Include="DSL\TrayIcon.fs" />
159162
<Compile Include="DSL\GridSplitter.fs" />
160163
<Compile Include="DSL\DatePickerPresenter.fs" />
161164
<Compile Include="DSL\TimePickerPresenter.fs" />
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
namespace Avalonia.FuncUI.DSL
2+
3+
[<AutoOpen>]
4+
module NativeMenu =
5+
open Avalonia.Controls
6+
open Avalonia.FuncUI.Builder
7+
open Avalonia.FuncUI.Types
8+
9+
let create (attrs: IAttr<NativeMenu> list): IView<NativeMenu> =
10+
ViewBuilder.Create<NativeMenu>(attrs)
11+
12+
type NativeMenu with
13+
static member items<'t when 't :> NativeMenu>(value: IView list) : IAttr<'t> =
14+
let getter : ('t -> obj) = (fun control -> control.Items :> obj)
15+
16+
AttrBuilder<'t>.CreateContentMultiple("Items", ValueSome getter, ValueNone, value)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
namespace Avalonia.FuncUI.DSL
2+
open Avalonia.Input
3+
open Avalonia.Interactivity
4+
open System.Windows.Input
5+
6+
[<AutoOpen>]
7+
module NativeMenuItem =
8+
open Avalonia.Controls
9+
open Avalonia.FuncUI.Types
10+
open Avalonia.FuncUI.Builder
11+
12+
let create (attrs: IAttr<NativeMenuItem> list): IView<NativeMenuItem> =
13+
ViewBuilder.Create<NativeMenuItem>(attrs)
14+
15+
type NativeMenuItem with
16+
17+
static member command<'t when 't :> NativeMenuItem>(command: ICommand) : IAttr<'t> =
18+
AttrBuilder<'t>.CreateProperty<ICommand>(NativeMenuItem.CommandProperty, command, ValueNone)
19+
20+
static member commandParameter<'t when 't :> NativeMenuItem>(parameter: obj) : IAttr<'t> =
21+
AttrBuilder<'t>.CreateProperty<obj>(NativeMenuItem.CommandParameterProperty, parameter, ValueNone)
22+
23+
static member header<'t when 't :> NativeMenuItem>(header: string) : IAttr<'t> =
24+
AttrBuilder<'t>.CreateProperty<string>(NativeMenuItem.HeaderProperty, header, ValueNone)
25+
26+
static member isChecked<'t when 't :> NativeMenuItem>(value: bool) : IAttr<'t> =
27+
AttrBuilder<'t>.CreateProperty<bool>(NativeMenuItem.IsCheckedProperty, value, ValueNone)
28+
29+
static member isEnabled<'t when 't :> NativeMenuItem>(value: bool) : IAttr<'t> =
30+
AttrBuilder<'t>.CreateProperty<bool>(NativeMenuItem.IsEnabledProperty, value, ValueNone)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
namespace Avalonia.FuncUI.DSL
2+
open Avalonia.Input
3+
open Avalonia.Interactivity
4+
open System.Windows.Input
5+
6+
[<AutoOpen>]
7+
module TrayIcon =
8+
open Avalonia.Controls
9+
open Avalonia.FuncUI.Builder
10+
open Avalonia.FuncUI.Types
11+
12+
let create (attrs: IAttr<TrayIcon> list): IView<TrayIcon> =
13+
ViewBuilder.Create<TrayIcon>(attrs)
14+
15+
type TrayIcon with
16+
static member command<'t when 't :> TrayIcon>(command: ICommand) : IAttr<'t> =
17+
AttrBuilder<'t>.CreateProperty<ICommand>(TrayIcon.CommandProperty, command, ValueNone)
18+
19+
static member commandParameter<'t when 't :> TrayIcon>(parameter: obj) : IAttr<'t> =
20+
AttrBuilder<'t>.CreateProperty<obj>(TrayIcon.CommandParameterProperty, parameter, ValueNone)
21+
22+
static member isVisible<'t when 't :> TrayIcon>(isVisible: bool) : IAttr<'t> =
23+
AttrBuilder<'t>.CreateProperty<bool>(TrayIcon.IsVisibleProperty, isVisible, ValueNone)
24+
25+
static member toolTipText<'t when 't :> TrayIcon>(toolTipText: string) : IAttr<'t> =
26+
AttrBuilder<'t>.CreateProperty<string>(TrayIcon.ToolTipTextProperty, toolTipText, ValueNone)
27+
28+
static member menu<'t when 't :> TrayIcon>(menu: IView option) : IAttr<'t> =
29+
AttrBuilder<'t>.CreateContentSingle(TrayIcon.MenuProperty, menu)
30+
31+
static member menu<'t when 't :> TrayIcon>(value: IView) : IAttr<'t> =
32+
value
33+
|> Some
34+
|> TrayIcon.menu

src/Avalonia.FuncUI/VirtualDom/VirtualDom.fs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@ open Avalonia.Controls
44

55
open Avalonia.FuncUI.Types
66
open Avalonia.FuncUI.VirtualDom.Delta
7+
open Avalonia
78

89
module rec VirtualDom =
10+
let createObject (view: IView) : AvaloniaObject =
11+
view
12+
|> ViewDelta.From
13+
|> Patcher.create
914

1015
let create (view: IView) : Control =
1116
view
12-
|> ViewDelta.From
13-
|> Patcher.create :?> Control
17+
|> createObject :?> Control
1418

1519
let update (root: Control, last: IView, next: IView) : unit =
1620
let delta = Differ.diff(last, next)

0 commit comments

Comments
 (0)