Skip to content
This repository has been archived by the owner on Oct 17, 2024. It is now read-only.

Commit

Permalink
Merge pull request #46 from AparokshaUI/1.0.0
Browse files Browse the repository at this point in the history
Migrate to Meta backend
  • Loading branch information
david-swift authored Oct 3, 2024
2 parents c6d0fa5 + 62661fd commit ec319a6
Show file tree
Hide file tree
Showing 167 changed files with 3,901 additions and 5,186 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: macos-14
runs-on: macos-15
steps:
- uses: actions/checkout@v4
- name: Install Libadwaita
Expand Down
5 changes: 1 addition & 4 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ opt_in_rules:
- convenience_type
- discouraged_none_name
- discouraged_object_literal
- discouraged_optional_boolean
- discouraged_optional_collection
- empty_collection_literal
- empty_count
- empty_string
Expand Down Expand Up @@ -51,7 +49,6 @@ opt_in_rules:
- multiline_parameters_brackets
- no_extension_access_modifier
- no_grouping_extension
- no_magic_numbers
- number_separator
- operator_usage_whitespace
- optional_enum_case_matching
Expand Down Expand Up @@ -141,7 +138,7 @@ file_header:
missing_docs:
warning: [internal, private]
error: [open, public]
excludes_extensions: false
excludes_extensions: true
excludes_inherited_types: false
type_contents_order:
order:
Expand Down
8 changes: 0 additions & 8 deletions Contributors.md

This file was deleted.

18 changes: 10 additions & 8 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 5.8
// swift-tools-version: 6.0
//
// Package.swift
// Adwaita
Expand All @@ -11,9 +11,7 @@ import PackageDescription
/// The Adwaita package.
let package = Package(
name: "Adwaita",
platforms: [
.macOS(.v10_15)
],
platforms: [.macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v6), .macCatalyst(.v13)],
products: [
.library(
name: "Adwaita",
Expand All @@ -25,6 +23,8 @@ let package = Package(
)
],
dependencies: [
.package(url: "https://github.com/AparokshaUI/Meta", branch: "main"),
.package(url: "https://github.com/AparokshaUI/meta-sqlite", branch: "main"),
.package(
url: "https://github.com/david-swift/LevenshteinTransformations",
from: "0.1.1"
Expand All @@ -40,7 +40,9 @@ let package = Package(
name: "Adwaita",
dependencies: [
"CAdw",
.product(name: "LevenshteinTransformations", package: "LevenshteinTransformations")
.product(name: "LevenshteinTransformations", package: "LevenshteinTransformations"),
.product(name: "Meta", package: "Meta"),
.product(name: "MetaSQLite", package: "meta-sqlite")
]
),
.executableTarget(
Expand All @@ -51,8 +53,8 @@ let package = Package(
),
.executableTarget(
name: "Demo",
dependencies: ["Adwaita"],
path: "Tests"
dependencies: ["Adwaita"]
)
]
],
swiftLanguageModes: [.v5]
)
68 changes: 47 additions & 21 deletions Sources/Adwaita/Menu/MenuButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@
import CAdw

/// A button widget for menus.
public struct MenuButton: MenuItem {
public struct MenuButton: MenuWidget {

/// The button's label.
var label: String
/// The button's action handler.
var handler: () -> Void
/// The keyboard shortcut.
var shortcut = ""
/// Whether the keyboard shortcut is currently available.
var active = true
/// Whether to prefer adding the action to the application window.
var preferApplicationWindow: Bool

Expand All @@ -35,33 +33,61 @@ public struct MenuButton: MenuItem {
self.handler = handler
}

/// Add the button to a menu.
/// The view storage.
/// - Parameters:
/// - menu: The menu.
/// - app: The application containing the menu.
/// - window: The application window containing the menu.
public func addMenuItem(menu: OpaquePointer?, app: GTUIApp, window: GTUIApplicationWindow?) {
if let window, preferApplicationWindow {
window.addKeyboardShortcut(active ? shortcut : "", id: filteredLabel, handler: handler)
g_menu_append(menu, label, "win." + filteredLabel)
/// - modifiers: Modify the views before updating.
/// - type: The type of the views.
/// - Returns: The view storage.
public func container<Data>(
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let storage = ViewStorage(nil)
var label = filteredLabel
guard let app = data.appStorage as? AdwaitaApp else {
return .init(nil)
}
if let window = data.sceneStorage.pointer as? AdwaitaWindow, preferApplicationWindow {
app.addKeyboardShortcut(shortcut, id: filteredLabel, window: window, handler: handler)
label = "win." + label
} else {
app.addKeyboardShortcut(shortcut, id: filteredLabel, handler: handler)
label = "app." + label
}
let pointer = g_menu_item_new(self.label, label)
storage.pointer = pointer
return storage
}

/// Update the stored content.
/// - Parameters:
/// - storage: The storage to update.
/// - modifiers: Modify the views before updating.
/// - updateProperties: Whether to update the properties.
/// - type: The type of the views.
public func update<Data>(
_ storage: ViewStorage,
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
guard let app = data.appStorage as? AdwaitaApp else {
return
}
if let window = data.sceneStorage.pointer as? AdwaitaWindow, preferApplicationWindow {
app.addKeyboardShortcut(shortcut, id: filteredLabel, window: window, handler: handler)
} else {
app.addKeyboardShortcut(active ? shortcut : "", id: filteredLabel, handler: handler)
g_menu_append(menu, label, "app." + filteredLabel)
app.addKeyboardShortcut(shortcut, id: filteredLabel, 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.
/// - active: Whether the keyboard shortcut is currently available.
/// - Parameter shortcut: The keyboard shortcut.
/// - Returns: The button.
public func keyboardShortcut(_ shortcut: String, active: Bool = true) -> Self {
var newSelf = self
newSelf.shortcut = shortcut
newSelf.active = active
return newSelf
public func keyboardShortcut(_ shortcut: String) -> Self {
modify { $0.shortcut = shortcut }
}

}
84 changes: 84 additions & 0 deletions Sources/Adwaita/Menu/MenuCollection.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//
// MenuCollection.swift
// Adwaita
//
// Created by david-swift on 02.08.2024.
//

import CAdw
import Foundation

/// A collection of menus.
public struct MenuCollection: MenuWidget, Wrapper {

/// The content of the collection.
var content: Body

/// Initialize a menu.
/// - Parameter content: The content of the collection.
public init(@ViewBuilder content: @escaping () -> Body) {
self.content = content()
}

/// The view storage.
/// - Parameters:
/// - modifiers: Modify the views before updating.
/// - type: The type of the views.
/// - Returns: The view storage.
public func container<Data>(
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let storages = content.storages(data: data, type: type)
return .init(nil, content: [.mainContent: storages])
}

/// Update the stored content.
/// - Parameters:
/// - storage: The storage to update.
/// - modifiers: Modify the views before updating.
/// - updateProperties: Whether to update the properties.
/// - type: The type of the views.
public func update<Data>(
_ storage: ViewStorage,
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
guard let storages = storage.content[.mainContent] else {
return
}
content.update(storages, data: data, updateProperties: updateProperties, type: type)
}

/// Render the collection as a menu.
/// - Parameter data: The widget data.
/// - Returns: The view storage with the GMenu as the pointer.
public func getMenu(data: WidgetData) -> ViewStorage {
let menu = g_menu_new()
let storage = container(data: data.noModifiers, type: MenuContext.self)
if let app = data.appStorage as? AdwaitaApp, let window = data.sceneStorage.pointer as? AdwaitaWindow {
initializeMenu(menu: menu, storage: storage, app: app, window: window)
}
storage.pointer = menu
return storage
}

/// Initialize a menu.
/// - Parameters:
/// - menu: The pointer to the GMenu.
/// - storage: The storage for the menu's content.
/// - app: The app object.
/// - window: The window object.
func initializeMenu(menu: OpaquePointer?, storage: ViewStorage, app: AdwaitaApp, window: AdwaitaWindow?) {
if let item = storage.opaquePointer {
g_menu_append_item(menu, item)
storage.pointer = item
} else {
for element in storage.content[.mainContent] ?? [] {
initializeMenu(menu: menu, storage: element, app: app, window: window)
}
}
}

}
21 changes: 21 additions & 0 deletions Sources/Adwaita/Menu/MenuContext.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// MenuContext.swift
// Adwaita
//
// Created by david-swift on 01.08.24.
//

/// The menu items view context.
public enum MenuContext: ViewRenderData {

/// The type of the widgets.
public typealias WidgetType = MenuWidget
/// The wrapper type.
public typealias WrapperType = MenuCollection
/// The either view type.
public typealias EitherViewType = MenuEitherView

}

/// The type of the widgets.
public protocol MenuWidget: Meta.Widget { }
23 changes: 23 additions & 0 deletions Sources/Adwaita/Menu/MenuEitherView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// MenuEitherView.swift
// Adwaita
//
// Created by david-swift on 06.08.2024.
//

/// Show one of two views depending on a condition.
public struct MenuEitherView: Meta.EitherView, SimpleView {

/// The view.
public var view: Body

/// Initialize an either view.
/// - Parameters:
/// - condition: The condition.
/// - view1: The first view.
/// - view2: The second view.
public init(_ condition: Bool, view1: () -> Body, else view2: () -> Body) {
self.view = condition ? view1() : view2()
}

}
51 changes: 37 additions & 14 deletions Sources/Adwaita/Menu/MenuSection.swift
Original file line number Diff line number Diff line change
@@ -1,35 +1,58 @@
//
// Submenu.swift
// MenuButton.swift
// Adwaita
//
// Created by david-swift on 22.10.23.
//

import CAdw

/// A section for menus.
public struct MenuSection: MenuItem {
/// A button widget for menus.
public struct MenuSection: MenuWidget {

/// The content of the section.
var sectionContent: MenuContent
var sectionContent: Body

/// Initialize a section for menus.
/// - Parameter content: The content of the section.
public init(@MenuBuilder content: () -> MenuContent) {
public init(@ViewBuilder content: () -> Body) {
self.sectionContent = content()
}

/// Add the section to a menu.
/// The view storage.
/// - Parameters:
/// - menu: The menu.
/// - app: The application containing the menu.
/// - window: The application window containing the menu.
public func addMenuItem(menu: OpaquePointer?, app: GTUIApp, window: GTUIApplicationWindow?) {
let section = g_menu_new()
g_menu_append_section(menu, nil, section?.cast())
for element in sectionContent {
element.addMenuItems(menu: section, app: app, window: window)
/// - modifiers: Modify the views before updating.
/// - type: The type of the views.
/// - Returns: The view storage.
public func container<Data>(
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let storage = ViewStorage(nil)
let childStorage = MenuCollection { sectionContent }.getMenu(data: data)
storage.content[.mainContent] = [childStorage]
let pointer = g_menu_item_new_section(nil, childStorage.opaquePointer?.cast())
storage.pointer = pointer
return storage
}

/// Update the stored content.
/// - Parameters:
/// - storage: The storage to update.
/// - modifiers: Modify the views before updating.
/// - updateProperties: Whether to update the properties.
/// - type: The type of the views.
public func update<Data>(
_ storage: ViewStorage,
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
guard let content = storage.content[.mainContent]?.first else {
return
}
MenuCollection { sectionContent }
.updateStorage(content, data: data, updateProperties: updateProperties, type: MenuContext.self)
}

}
Loading

0 comments on commit ec319a6

Please sign in to comment.