forked from aparoksha/adwaita-swift
Add support for menus
This commit is contained in:
parent
af59675089
commit
ac0c775985
@ -3,6 +3,8 @@
|
|||||||
## Protocols
|
## Protocols
|
||||||
|
|
||||||
- [App](protocols/App.md)
|
- [App](protocols/App.md)
|
||||||
|
- [MenuItem](protocols/MenuItem.md)
|
||||||
|
- [MenuItemGroup](protocols/MenuItemGroup.md)
|
||||||
- [StateProtocol](protocols/StateProtocol.md)
|
- [StateProtocol](protocols/StateProtocol.md)
|
||||||
- [View](protocols/View.md)
|
- [View](protocols/View.md)
|
||||||
- [Widget](protocols/Widget.md)
|
- [Widget](protocols/Widget.md)
|
||||||
@ -11,7 +13,6 @@
|
|||||||
|
|
||||||
## Structs
|
## Structs
|
||||||
|
|
||||||
- [ApplicationWindow](structs/ApplicationWindow.md)
|
|
||||||
- [Binding](structs/Binding.md)
|
- [Binding](structs/Binding.md)
|
||||||
- [Button](structs/Button.md)
|
- [Button](structs/Button.md)
|
||||||
- [Clamp](structs/Clamp.md)
|
- [Clamp](structs/Clamp.md)
|
||||||
@ -20,11 +21,15 @@
|
|||||||
- [HeaderBar](structs/HeaderBar.md)
|
- [HeaderBar](structs/HeaderBar.md)
|
||||||
- [InspectorWrapper](structs/InspectorWrapper.md)
|
- [InspectorWrapper](structs/InspectorWrapper.md)
|
||||||
- [List](structs/List.md)
|
- [List](structs/List.md)
|
||||||
|
- [Menu](structs/Menu.md)
|
||||||
|
- [MenuButton](structs/MenuButton.md)
|
||||||
|
- [MenuSection](structs/MenuSection.md)
|
||||||
- [NavigationSplitView](structs/NavigationSplitView.md)
|
- [NavigationSplitView](structs/NavigationSplitView.md)
|
||||||
- [ScrollView](structs/ScrollView.md)
|
- [ScrollView](structs/ScrollView.md)
|
||||||
- [State](structs/State.md)
|
- [State](structs/State.md)
|
||||||
- [StateWrapper](structs/StateWrapper.md)
|
- [StateWrapper](structs/StateWrapper.md)
|
||||||
- [StatusPage](structs/StatusPage.md)
|
- [StatusPage](structs/StatusPage.md)
|
||||||
|
- [Submenu](structs/Submenu.md)
|
||||||
- [Text](structs/Text.md)
|
- [Text](structs/Text.md)
|
||||||
- [ToolbarView](structs/ToolbarView.md)
|
- [ToolbarView](structs/ToolbarView.md)
|
||||||
- [UpdateObserver](structs/UpdateObserver.md)
|
- [UpdateObserver](structs/UpdateObserver.md)
|
||||||
@ -49,6 +54,8 @@
|
|||||||
|
|
||||||
- [App](extensions/App.md)
|
- [App](extensions/App.md)
|
||||||
- [Array](extensions/Array.md)
|
- [Array](extensions/Array.md)
|
||||||
|
- [MenuItem](extensions/MenuItem.md)
|
||||||
|
- [MenuItemGroup](extensions/MenuItemGroup.md)
|
||||||
- [NativeWidgetPeer](extensions/NativeWidgetPeer.md)
|
- [NativeWidgetPeer](extensions/NativeWidgetPeer.md)
|
||||||
- [String](extensions/String.md)
|
- [String](extensions/String.md)
|
||||||
- [View](extensions/View.md)
|
- [View](extensions/View.md)
|
||||||
@ -61,6 +68,8 @@
|
|||||||
- [Body](typealiases/Body.md)
|
- [Body](typealiases/Body.md)
|
||||||
- [GTUIApplicationWindow](typealiases/GTUIApplicationWindow.md)
|
- [GTUIApplicationWindow](typealiases/GTUIApplicationWindow.md)
|
||||||
- [GTUIWindow](typealiases/GTUIWindow.md)
|
- [GTUIWindow](typealiases/GTUIWindow.md)
|
||||||
|
- [MenuBuilder](typealiases/MenuBuilder.md)
|
||||||
|
- [MenuContent](typealiases/MenuContent.md)
|
||||||
- [Scene](typealiases/Scene.md)
|
- [Scene](typealiases/Scene.md)
|
||||||
- [SceneBuilder](typealiases/SceneBuilder.md)
|
- [SceneBuilder](typealiases/SceneBuilder.md)
|
||||||
|
|
||||||
|
|||||||
8
Documentation/Reference/extensions/MenuItem.md
Normal file
8
Documentation/Reference/extensions/MenuItem.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
**EXTENSION**
|
||||||
|
|
||||||
|
# `MenuItem`
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
### `content`
|
||||||
|
|
||||||
|
The menu item's content is itself.
|
||||||
9
Documentation/Reference/extensions/MenuItemGroup.md
Normal file
9
Documentation/Reference/extensions/MenuItemGroup.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
**EXTENSION**
|
||||||
|
|
||||||
|
# `MenuItemGroup`
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
### `addMenuItems(menu:app:window:)`
|
||||||
|
|
||||||
|
Add the menu items described by the group to a menu.
|
||||||
|
- Parameter menu: The menu.
|
||||||
14
Documentation/Reference/protocols/MenuItem.md
Normal file
14
Documentation/Reference/protocols/MenuItem.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
**PROTOCOL**
|
||||||
|
|
||||||
|
# `MenuItem`
|
||||||
|
|
||||||
|
A structure representing the content for a certain menu item type.
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
### `addMenuItem(menu:app:window:)`
|
||||||
|
|
||||||
|
Add the menu item to a certain menu.
|
||||||
|
- Parameters:
|
||||||
|
- menu: The menu.
|
||||||
|
- app: The application containing the menu.
|
||||||
|
- window: The application window containing the menu.
|
||||||
10
Documentation/Reference/protocols/MenuItemGroup.md
Normal file
10
Documentation/Reference/protocols/MenuItemGroup.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
**PROTOCOL**
|
||||||
|
|
||||||
|
# `MenuItemGroup`
|
||||||
|
|
||||||
|
A structure conforming to `MenuItemGroup` can be added to the content accepting a menu.
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
### `content`
|
||||||
|
|
||||||
|
The menu's content.
|
||||||
56
Documentation/Reference/structs/Menu.md
Normal file
56
Documentation/Reference/structs/Menu.md
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
**STRUCT**
|
||||||
|
|
||||||
|
# `Menu`
|
||||||
|
|
||||||
|
A menu button widget.
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
### `label`
|
||||||
|
|
||||||
|
The button's label.
|
||||||
|
|
||||||
|
### `icon`
|
||||||
|
|
||||||
|
The button's icon.
|
||||||
|
|
||||||
|
### `content`
|
||||||
|
|
||||||
|
The menu's content.
|
||||||
|
|
||||||
|
### `app`
|
||||||
|
|
||||||
|
The application.
|
||||||
|
|
||||||
|
### `window`
|
||||||
|
|
||||||
|
The window.
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
### `init(_:icon:app:window:content:)`
|
||||||
|
|
||||||
|
Initialize a menu button.
|
||||||
|
- Parameters:
|
||||||
|
- label: The button's label.
|
||||||
|
- icon: The button's icon.
|
||||||
|
- app: The application.
|
||||||
|
- window: The application window.
|
||||||
|
- content: The menu's content.
|
||||||
|
|
||||||
|
### `init(_:app:window:content:)`
|
||||||
|
|
||||||
|
Initialize a menu button.
|
||||||
|
- Parameters:
|
||||||
|
- label: The buttons label.
|
||||||
|
- app: The application.
|
||||||
|
- window: The application window.
|
||||||
|
- content: The menu's content.
|
||||||
|
|
||||||
|
### `update(_:)`
|
||||||
|
|
||||||
|
Update a button's view storage.
|
||||||
|
- Parameter storage: The view storage.
|
||||||
|
|
||||||
|
### `container()`
|
||||||
|
|
||||||
|
Get a button's view storage.
|
||||||
|
- Returns: The button's view storage.
|
||||||
48
Documentation/Reference/structs/MenuButton.md
Normal file
48
Documentation/Reference/structs/MenuButton.md
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
**STRUCT**
|
||||||
|
|
||||||
|
# `MenuButton`
|
||||||
|
|
||||||
|
A button widget for menus.
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
### `label`
|
||||||
|
|
||||||
|
The button's label.
|
||||||
|
|
||||||
|
### `handler`
|
||||||
|
|
||||||
|
The button's action handler.
|
||||||
|
|
||||||
|
### `shortcut`
|
||||||
|
|
||||||
|
The keyboard shortcut.
|
||||||
|
|
||||||
|
### `preferApplicationWindow`
|
||||||
|
|
||||||
|
Whether to prefer adding the action to the application window.
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
### `init(_:window:handler:)`
|
||||||
|
|
||||||
|
Initialize a menu button.
|
||||||
|
- Parameters:
|
||||||
|
- label: The buttons label.
|
||||||
|
- window: Whether to prefer adding the action to the application window.
|
||||||
|
- handler: The button's action handler.
|
||||||
|
|
||||||
|
### `addMenuItem(menu:app:window:)`
|
||||||
|
|
||||||
|
Add the button to a menu.
|
||||||
|
- Parameters:
|
||||||
|
- menu: The menu.
|
||||||
|
- app: The application containing the menu.
|
||||||
|
- window: The application window containing the menu.
|
||||||
|
|
||||||
|
### `keyboardShortcut(_:)`
|
||||||
|
|
||||||
|
Create a keyboard shortcut for an application from a button.
|
||||||
|
|
||||||
|
Note that the keyboard shortcut is available after the view has been visible for the first time.
|
||||||
|
- Parameters:
|
||||||
|
- shortcut: The keyboard shortcut.
|
||||||
|
- Returns: The button.
|
||||||
24
Documentation/Reference/structs/MenuSection.md
Normal file
24
Documentation/Reference/structs/MenuSection.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
**STRUCT**
|
||||||
|
|
||||||
|
# `MenuSection`
|
||||||
|
|
||||||
|
A section for menus.
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
### `sectionContent`
|
||||||
|
|
||||||
|
The content of the section.
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
### `init(content:)`
|
||||||
|
|
||||||
|
Initialize a section for menus.
|
||||||
|
- Parameter content: The content of the section.
|
||||||
|
|
||||||
|
### `addMenuItem(menu:app:window:)`
|
||||||
|
|
||||||
|
Add the section to a menu.
|
||||||
|
- Parameters:
|
||||||
|
- menu: The menu.
|
||||||
|
- app: The application containing the menu.
|
||||||
|
- window: The application window containing the menu.
|
||||||
30
Documentation/Reference/structs/Submenu.md
Normal file
30
Documentation/Reference/structs/Submenu.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
**STRUCT**
|
||||||
|
|
||||||
|
# `Submenu`
|
||||||
|
|
||||||
|
A submenu widget.
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
### `label`
|
||||||
|
|
||||||
|
The submenu's label.
|
||||||
|
|
||||||
|
### `submenuContent`
|
||||||
|
|
||||||
|
The content of the submenu.
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
### `init(_:content:)`
|
||||||
|
|
||||||
|
Initialize a submenu.
|
||||||
|
- Parameters:
|
||||||
|
- label: The submenu's label.
|
||||||
|
- content: The content of the submenu.
|
||||||
|
|
||||||
|
### `addMenuItem(menu:app:window:)`
|
||||||
|
|
||||||
|
Add the submenu to a menu.
|
||||||
|
- Parameters:
|
||||||
|
- menu: The menu.
|
||||||
|
- app: The application containing the menu.
|
||||||
|
- window: The application window containing the menu.
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# `Window`
|
# `Window`
|
||||||
|
|
||||||
A structure representing a simple window type.
|
A structure representing an application window type.
|
||||||
|
|
||||||
Note that multiple instances of a window can be opened at the same time.
|
Note that multiple instances of a window can be opened at the same time.
|
||||||
|
|
||||||
@ -19,6 +19,10 @@ The window's content.
|
|||||||
|
|
||||||
Whether an instance of the window type should be opened when the app is starting up.
|
Whether an instance of the window type should be opened when the app is starting up.
|
||||||
|
|
||||||
|
### `shortcuts`
|
||||||
|
|
||||||
|
The keyboard shortcuts.
|
||||||
|
|
||||||
### `appShortcuts`
|
### `appShortcuts`
|
||||||
|
|
||||||
The keyboard shortcuts on the app level.
|
The keyboard shortcuts on the app level.
|
||||||
@ -53,6 +57,22 @@ Get the storage of the content view.
|
|||||||
### `update(_:app:)`
|
### `update(_:app:)`
|
||||||
|
|
||||||
Update a window storage's content.
|
Update a window storage's content.
|
||||||
|
- Parameter storage: The storage to update.
|
||||||
|
|
||||||
|
### `keyboardShortcut(_:action:)`
|
||||||
|
|
||||||
|
Add a keyboard shortcut.
|
||||||
- Parameters:
|
- Parameters:
|
||||||
- storage: The storage to update.
|
- shortcut: The keyboard shortcut.
|
||||||
- app: The application.
|
- action: The closure to execute when the keyboard shortcut is pressed.
|
||||||
|
- Returns: The window.
|
||||||
|
|
||||||
|
### `updateShortcuts(window:)`
|
||||||
|
|
||||||
|
Update the keyboard shortcuts.
|
||||||
|
- Parameter window: The application window.
|
||||||
|
|
||||||
|
### `closeShortcut()`
|
||||||
|
|
||||||
|
Add the shortcut "<Ctrl>w" which closes the window.
|
||||||
|
- Returns: The window.
|
||||||
|
|||||||
5
Documentation/Reference/typealiases/MenuBuilder.md
Normal file
5
Documentation/Reference/typealiases/MenuBuilder.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
**TYPEALIAS**
|
||||||
|
|
||||||
|
# `MenuBuilder`
|
||||||
|
|
||||||
|
A builder for the `MenuContent`
|
||||||
5
Documentation/Reference/typealiases/MenuContent.md
Normal file
5
Documentation/Reference/typealiases/MenuContent.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
**TYPEALIAS**
|
||||||
|
|
||||||
|
# `MenuContent`
|
||||||
|
|
||||||
|
`MenuContent` is an array of menu item groups.
|
||||||
BIN
Icons/Demo.png
BIN
Icons/Demo.png
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
15
README.md
15
README.md
@ -78,6 +78,7 @@ If you want to use _Adwaita_ in a project, but there are widgets missing, open a
|
|||||||
| VStack | A widget which arranges child widgets into a single column. | GtkBox |
|
| VStack | A widget which arranges child widgets into a single column. | GtkBox |
|
||||||
| HStack | A widget which arranges child widgets into a single row. | GtkBox |
|
| HStack | A widget which arranges child widgets into a single row. | GtkBox |
|
||||||
| List | A widget which arranges child widgets vertically into rows. | GtkListBox |
|
| List | A widget which arranges child widgets vertically into rows. | GtkListBox |
|
||||||
|
| Menu | A widget showing a button that toggles the appearance of a menu. | GtkMenuButton |
|
||||||
| NavigationSplitView | A widget presenting sidebar and content side by side. | AdwNavigationSplitView |
|
| NavigationSplitView | A widget presenting sidebar and content side by side. | AdwNavigationSplitView |
|
||||||
| ScrollView | A container that makes its child scrollable. | GtkScrolledWindow |
|
| ScrollView | A container that makes its child scrollable. | GtkScrolledWindow |
|
||||||
| StatusPage | A page with an icon, title, and optionally description and widget.| AdwStatusPage |
|
| StatusPage | A page with an icon, title, and optionally description and widget.| AdwStatusPage |
|
||||||
@ -134,7 +135,19 @@ If you want to use _Adwaita_ in a project, but there are widgets missing, open a
|
|||||||
| Syntax | Description |
|
| Syntax | Description |
|
||||||
| ------------------------------- | --------------------------------------------------------------------------------------- |
|
| ------------------------------- | --------------------------------------------------------------------------------------- |
|
||||||
| `keyboardShortcut(_:action:)` | Create a keyboard shortcut available in one window. |
|
| `keyboardShortcut(_:action:)` | Create a keyboard shortcut available in one window. |
|
||||||
| `closeShortcut()` | Create a keyboard shortcut for closing the window with "Ctrl + w". |
|
| `closeShortcut()` | Create a keyboard shortcut for closing the window with "Ctrl + w".
|
||||||
|
|
||||||
|
### Menu Widgets
|
||||||
|
| Name | Description | Widget |
|
||||||
|
| -------------------- | ----------------------------------------------------------------- | ---------------------- |
|
||||||
|
| MenuButton | A button in a menu. | GMenuItem |
|
||||||
|
| MenuSection | A collection of menu widgets grouped with lines. | GMenuItem |
|
||||||
|
| Submenu | A collection of menu widgets grouped by navigation. | GMenuItem |
|
||||||
|
|
||||||
|
### `MenuButton` Modifiers
|
||||||
|
| Syntax | Description |
|
||||||
|
| ------------------------------- | --------------------------------------------------------------------------------------- |
|
||||||
|
| `keyboardShortcut(_:)` | Assign a keyboard shortcut to the button's action. |
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|||||||
58
Sources/Adwaita/Menu/MenuButton.swift
Normal file
58
Sources/Adwaita/Menu/MenuButton.swift
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
//
|
||||||
|
// MenuButton.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 22.10.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import GTUI
|
||||||
|
|
||||||
|
/// A button widget for menus.
|
||||||
|
public struct MenuButton: MenuItem {
|
||||||
|
|
||||||
|
/// The button's label.
|
||||||
|
var label: String
|
||||||
|
/// The button's action handler.
|
||||||
|
var handler: () -> Void
|
||||||
|
/// The keyboard shortcut.
|
||||||
|
var shortcut = ""
|
||||||
|
/// Whether to prefer adding the action to the application window.
|
||||||
|
var preferApplicationWindow: Bool
|
||||||
|
|
||||||
|
/// Initialize a menu button.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - label: The buttons label.
|
||||||
|
/// - window: Whether to prefer adding the action to the application window.
|
||||||
|
/// - handler: The button's action handler.
|
||||||
|
public init(_ label: String, window: Bool = true, handler: @escaping () -> Void) {
|
||||||
|
self.label = label
|
||||||
|
preferApplicationWindow = window
|
||||||
|
self.handler = handler
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add the button to a menu.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - menu: The menu.
|
||||||
|
/// - app: The application containing the menu.
|
||||||
|
/// - window: The application window containing the menu.
|
||||||
|
public func addMenuItem(menu: GTUI.Menu, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||||
|
if let window, preferApplicationWindow {
|
||||||
|
_ = menu.append(label, window: window, shortcut: shortcut, handler: handler)
|
||||||
|
} else {
|
||||||
|
_ = menu.append(label, app: app, shortcut: shortcut, handler: handler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a keyboard shortcut for an application from a button.
|
||||||
|
///
|
||||||
|
/// Note that the keyboard shortcut is available after the view has been visible for the first time.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - shortcut: The keyboard shortcut.
|
||||||
|
/// - Returns: The button.
|
||||||
|
public func keyboardShortcut(_ shortcut: String) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.shortcut = shortcut
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
35
Sources/Adwaita/Menu/MenuSection.swift
Normal file
35
Sources/Adwaita/Menu/MenuSection.swift
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// Submenu.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 22.10.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import GTUI
|
||||||
|
|
||||||
|
/// A section for menus.
|
||||||
|
public struct MenuSection: MenuItem {
|
||||||
|
|
||||||
|
/// The content of the section.
|
||||||
|
var sectionContent: MenuContent
|
||||||
|
|
||||||
|
/// Initialize a section for menus.
|
||||||
|
/// - Parameter content: The content of the section.
|
||||||
|
public init(@MenuBuilder content: () -> MenuContent) {
|
||||||
|
self.sectionContent = content()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add the section to a menu.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - menu: The menu.
|
||||||
|
/// - app: The application containing the menu.
|
||||||
|
/// - window: The application window containing the menu.
|
||||||
|
public func addMenuItem(menu: GTUI.Menu, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||||
|
let section = GTUI.Menu()
|
||||||
|
_ = menu.append("", section: section)
|
||||||
|
for element in sectionContent {
|
||||||
|
element.addMenuItems(menu: section, app: app, window: window)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
40
Sources/Adwaita/Menu/Submenu.swift
Normal file
40
Sources/Adwaita/Menu/Submenu.swift
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
// Submenu.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 22.10.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import GTUI
|
||||||
|
|
||||||
|
/// A submenu widget.
|
||||||
|
public struct Submenu: MenuItem {
|
||||||
|
|
||||||
|
/// The submenu's label.
|
||||||
|
var label: String
|
||||||
|
/// The content of the submenu.
|
||||||
|
var submenuContent: MenuContent
|
||||||
|
|
||||||
|
/// Initialize a submenu.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - label: The submenu's label.
|
||||||
|
/// - content: The content of the submenu.
|
||||||
|
public init(_ label: String, @MenuBuilder content: () -> MenuContent) {
|
||||||
|
self.label = label
|
||||||
|
self.submenuContent = content()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add the submenu to a menu.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - menu: The menu.
|
||||||
|
/// - app: The application containing the menu.
|
||||||
|
/// - window: The application window containing the menu.
|
||||||
|
public func addMenuItem(menu: GTUI.Menu, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||||
|
let submenu = GTUI.Menu()
|
||||||
|
_ = menu.append(label, submenu: submenu)
|
||||||
|
for element in submenuContent {
|
||||||
|
element.addMenuItems(menu: submenu, app: app, window: window)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
27
Sources/Adwaita/Model/User Interface/Menu/MenuItem.swift
Normal file
27
Sources/Adwaita/Model/User Interface/Menu/MenuItem.swift
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// MenuItem.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 22.10.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import GTUI
|
||||||
|
|
||||||
|
/// A structure representing the content for a certain menu item type.
|
||||||
|
public protocol MenuItem: MenuItemGroup {
|
||||||
|
|
||||||
|
/// Add the menu item to a certain menu.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - menu: The menu.
|
||||||
|
/// - app: The application containing the menu.
|
||||||
|
/// - window: The application window containing the menu.
|
||||||
|
func addMenuItem(menu: GTUI.Menu, app: GTUIApp, window: GTUIApplicationWindow?)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension MenuItem {
|
||||||
|
|
||||||
|
/// The menu item's content is itself.
|
||||||
|
@MenuBuilder public var content: MenuContent { self }
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// MenuItemGroup.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 22.10.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import GTUI
|
||||||
|
|
||||||
|
/// A structure conforming to `MenuItemGroup` can be added to the content accepting a menu.
|
||||||
|
public protocol MenuItemGroup {
|
||||||
|
|
||||||
|
/// The menu's content.
|
||||||
|
@MenuBuilder var content: MenuContent { get }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension MenuItemGroup {
|
||||||
|
|
||||||
|
/// Add the menu items described by the group to a menu.
|
||||||
|
/// - Parameter menu: The menu.
|
||||||
|
func addMenuItems(menu: GTUI.Menu, app: GTUIApp, window: GTUIApplicationWindow?) {
|
||||||
|
for element in content {
|
||||||
|
if let item = element as? MenuItem {
|
||||||
|
item.addMenuItem(menu: menu, app: app, window: window)
|
||||||
|
} else {
|
||||||
|
element.addMenuItems(menu: menu, app: app, window: window)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `MenuContent` is an array of menu item groups.
|
||||||
|
public typealias MenuContent = [MenuItemGroup]
|
||||||
|
/// A builder for the `MenuContent`
|
||||||
|
public typealias MenuBuilder = ArrayBuilder<MenuItemGroup>
|
||||||
98
Sources/Adwaita/View/Menu.swift
Normal file
98
Sources/Adwaita/View/Menu.swift
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
//
|
||||||
|
// Menu.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 21.10.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import GTUI
|
||||||
|
|
||||||
|
/// A menu button widget.
|
||||||
|
public struct Menu: Widget {
|
||||||
|
|
||||||
|
/// The button's label.
|
||||||
|
var label: String?
|
||||||
|
/// The button's icon.
|
||||||
|
var icon: Icon?
|
||||||
|
/// The menu's content.
|
||||||
|
var content: MenuContent
|
||||||
|
/// The application.
|
||||||
|
var app: GTUIApp
|
||||||
|
/// The window.
|
||||||
|
var window: GTUIApplicationWindow?
|
||||||
|
|
||||||
|
// swiftlint:disable function_default_parameter_at_end
|
||||||
|
/// Initialize a menu button.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - label: The button's label.
|
||||||
|
/// - icon: The button's icon.
|
||||||
|
/// - app: The application.
|
||||||
|
/// - window: The application window.
|
||||||
|
/// - content: The menu's content.
|
||||||
|
public init(
|
||||||
|
_ label: String? = nil,
|
||||||
|
icon: Icon,
|
||||||
|
app: GTUIApp,
|
||||||
|
window: GTUIApplicationWindow?,
|
||||||
|
@MenuBuilder content: () -> MenuContent
|
||||||
|
) {
|
||||||
|
self.label = label
|
||||||
|
self.icon = icon
|
||||||
|
self.app = app
|
||||||
|
self.window = window
|
||||||
|
self.content = content()
|
||||||
|
}
|
||||||
|
// swiftlint:enable function_default_parameter_at_end
|
||||||
|
|
||||||
|
/// Initialize a menu button.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - label: The buttons label.
|
||||||
|
/// - app: The application.
|
||||||
|
/// - window: The application window.
|
||||||
|
/// - content: The menu's content.
|
||||||
|
public init(
|
||||||
|
_ label: String,
|
||||||
|
app: GTUIApp,
|
||||||
|
window: GTUIApplicationWindow?,
|
||||||
|
@MenuBuilder content: () -> MenuContent
|
||||||
|
) {
|
||||||
|
self.label = label
|
||||||
|
self.app = app
|
||||||
|
self.window = window
|
||||||
|
self.content = content()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update a button's view storage.
|
||||||
|
/// - Parameter storage: The view storage.
|
||||||
|
public func update(_ storage: ViewStorage) {
|
||||||
|
if let button = storage.view as? GTUI.MenuButton {
|
||||||
|
let content = button.getContent()
|
||||||
|
if let label {
|
||||||
|
if icon == nil {
|
||||||
|
button.setLabel(label)
|
||||||
|
} else {
|
||||||
|
content?.setLabel(label)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let icon {
|
||||||
|
content?.setIcon(icon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a button's view storage.
|
||||||
|
/// - Returns: The button's view storage.
|
||||||
|
public func container() -> ViewStorage {
|
||||||
|
let button: GTUI.MenuButton
|
||||||
|
if let icon {
|
||||||
|
button = .init(label, icon: icon)
|
||||||
|
} else {
|
||||||
|
button = .init(label ?? .init())
|
||||||
|
}
|
||||||
|
for element in content {
|
||||||
|
element.addMenuItems(menu: button.getMenu(), app: app, window: window)
|
||||||
|
}
|
||||||
|
return .init(button)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -20,9 +20,6 @@ struct Demo: App {
|
|||||||
Window(id: "main") { window in
|
Window(id: "main") { window in
|
||||||
DemoContent(window: window, app: app)
|
DemoContent(window: window, app: app)
|
||||||
}
|
}
|
||||||
.appKeyboardShortcut("n".ctrl()) { $0.addWindow("main") }
|
|
||||||
.closeShortcut()
|
|
||||||
.quitShortcut()
|
|
||||||
HelperWindows()
|
HelperWindows()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +41,7 @@ struct Demo: App {
|
|||||||
struct DemoContent: View {
|
struct DemoContent: View {
|
||||||
|
|
||||||
@State private var selection: Page = .welcome
|
@State private var selection: Page = .welcome
|
||||||
var window: GTUIWindow
|
var window: GTUIApplicationWindow
|
||||||
var app: GTUIApp!
|
var app: GTUIApp!
|
||||||
|
|
||||||
var view: Body {
|
var view: Body {
|
||||||
@ -58,7 +55,24 @@ struct Demo: App {
|
|||||||
.sidebarStyle()
|
.sidebarStyle()
|
||||||
}
|
}
|
||||||
.topToolbar {
|
.topToolbar {
|
||||||
HeaderBar.empty()
|
HeaderBar.end {
|
||||||
|
Menu(icon: .default(icon: .openMenu), app: app, window: window) {
|
||||||
|
MenuButton("New Window", window: false) {
|
||||||
|
app.addWindow("main")
|
||||||
|
}
|
||||||
|
.keyboardShortcut("n".ctrl())
|
||||||
|
MenuButton("Close Window") {
|
||||||
|
window.close()
|
||||||
|
}
|
||||||
|
.keyboardShortcut("w".ctrl())
|
||||||
|
MenuSection {
|
||||||
|
MenuButton("Quit", window: false) {
|
||||||
|
app.quit()
|
||||||
|
}
|
||||||
|
.keyboardShortcut("q".ctrl())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.navigationTitle("Demo")
|
.navigationTitle("Demo")
|
||||||
} content: {
|
} content: {
|
||||||
|
|||||||
@ -70,6 +70,29 @@ struct HelloWorld: App {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Create Shortcuts from a Menu
|
||||||
|
The most elegant way for adding keyboard shortcuts is in many cases adding them via menus.
|
||||||
|
Here is an example using a menu button:
|
||||||
|
```swift
|
||||||
|
struct TestView: View {
|
||||||
|
|
||||||
|
var app: GTUIApp
|
||||||
|
|
||||||
|
var view: Body {
|
||||||
|
Menu(icon: .default(icon: .openMenu), app: app) {
|
||||||
|
MenuButton("New Window", window: false) {
|
||||||
|
app.addWindow("main")
|
||||||
|
}
|
||||||
|
// Add a keyboard shortcut to the app.
|
||||||
|
.keyboardShortcut("n".ctrl())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Add the keyboard shortcut to a single window by specifying the `window` parameter in the initializer of `Menu`,
|
||||||
|
and removing `window: false` in the initializer of `MenuButton`.
|
||||||
|
|
||||||
## Create Shortcuts from a Button
|
## Create Shortcuts from a Button
|
||||||
It's possible to easily create a keyboard shortcut from a button.
|
It's possible to easily create a keyboard shortcut from a button.
|
||||||
Use `appKeyboardShortcut` instead of `keyboardShortcut` for shortcuts on an application level.
|
Use `appKeyboardShortcut` instead of `keyboardShortcut` for shortcuts on an application level.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user