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

Commit

Permalink
Add support for AdwViewSwitcher
Browse files Browse the repository at this point in the history
  • Loading branch information
david-swift committed Dec 25, 2023
1 parent 6044ab6 commit 11d0bf5
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Documentation/Reference/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
- [ToastOverlay](classes/ToastOverlay.md)
- [ToggleButton](classes/ToggleButton.md)
- [ToolbarView](classes/ToolbarView.md)
- [ViewSwitcher](classes/ViewSwitcher.md)
- [Window](classes/Window.md)

## Enums
Expand Down Expand Up @@ -99,6 +100,7 @@
- [tabbutton_on_click_cb(ptr_userData_)](methods/tabbutton_on_click_cb(ptr_userData_).md)
- [taboverview_on_create_tab_cb(ptr_userData_)](methods/taboverview_on_create_tab_cb(ptr_userData_).md)
- [toast_on_click_cb(ptr_userData_)](methods/toast_on_click_cb(ptr_userData_).md)
- [viewswitcher_on_select_cb(ptr_parameter_userData_)](methods/viewswitcher_on_select_cb(ptr_parameter_userData_).md)
- [window_close_cb(ptr_userData_)](methods/window_close_cb(ptr_userData_).md)

This file was generated by [SourceDocs](https://github.com/eneko/SourceDocs)
51 changes: 51 additions & 0 deletions Documentation/Reference/classes/ViewSwitcher.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
**CLASS**

# `ViewSwitcher`

Adw.ViewSwitcher

## Properties
### `onSelect`

The closure that is executed when the selection changes.

## Methods
### `init()`

Initialize a view switcher.

### `addOption(title:icon:)`

Add a view.
- Parameters:
- title: The view's title and identifier.
- icon: The view's icon.
- Returns: The view switcher.

### `removeOption(title:)`

Remove a view.
- Parameter title: The view's title.
- Returns: The view switcher.

### `getSelection()`

Get the selected view's title.
- Returns: The title.

### `select(title:)`

Select the view with a specific title.
- Parameter title: The title.

### `onSelect(closure:)`

Set the closure that gets called when the selection changes.
- Parameter closure: The closure.
- Returns: The view switcher.

### `wideDesign(_:)`

Set the wide or narrow design.
- Parameter wide: Whether the design is wide.
- Returns: The view switcher.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
### `viewswitcher_on_select_cb(ptr:parameter:userData:)`

Run when the seleciton changes.
- Parameters:
- ptr: The pointer.
- parameter: Additional data.
- userData: The switcher data.
88 changes: 88 additions & 0 deletions Sources/CGTUI/shim.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ static void
tabbutton_on_click_cb (void *, void *);
static void
toast_on_click_cb (void *, void *);
static void
viewswitcher_on_select_cb (void *, void *, void *);
static gboolean
window_close_cb (void *, void *);
static void
Expand Down Expand Up @@ -1356,6 +1358,92 @@ gtui_editable_set_contents (uint64_t editable, const char *contents)
return gtk_editable_set_text (editable, contents);
}

static uint64_t
gtui_create_viewswitcher ()
{
AdwViewSwitcher *switcher = adw_view_switcher_new ();
adw_view_switcher_set_stack (switcher, adw_view_stack_new ());
return (uint64_t)switcher;
}

static void
gtui_viewswitcher_init_signals (uint64_t swtchr, uint64_t data)
{
AdwViewSwitcher *switcher;

g_assert_nonnull (swtchr);
g_assert_nonnull (data);
g_assert (ADW_IS_VIEW_SWITCHER (ADW_VIEW_SWITCHER ((void *)swtchr)));

switcher = ADW_VIEW_SWITCHER (swtchr);
AdwViewStack *stack = adw_view_switcher_get_stack (switcher);
swift_retain (data);
g_signal_connect (stack, "notify::visible-child", G_CALLBACK (viewswitcher_on_select_cb), (void *)data);
}

static void
gtui_viewswitcher_add_view (uint64_t switcher, uint64_t child, const char *title, const char *icon)
{
g_assert_nonnull (switcher);
g_assert_nonnull (child);
g_assert_nonnull (title);
g_assert_nonnull (icon);
g_assert (ADW_IS_VIEW_SWITCHER (ADW_VIEW_SWITCHER ((void *)switcher)));
g_assert (GTK_IS_WIDGET (GTK_WIDGET ((void *)child)));

AdwViewStack *stack = adw_view_switcher_get_stack (switcher);
adw_view_stack_add_titled_with_icon (stack, child, title, title, icon);
}

static void
gtui_viewswitcher_remove_view (uint64_t switcher, const char *title)
{
g_assert_nonnull (switcher);
g_assert_nonnull (title);
g_assert (ADW_IS_VIEW_SWITCHER (ADW_VIEW_SWITCHER ((void *)switcher)));

AdwViewStack *stack = adw_view_switcher_get_stack (switcher);
GtkWidget *widget = adw_view_stack_get_child_by_name (stack, title);
adw_view_stack_remove (stack, widget);
}

static void
gtui_viewswitcher_set_wide_design (uint64_t switcher, gboolean wide)
{
g_assert_nonnull (switcher);
g_assert (ADW_IS_VIEW_SWITCHER (ADW_VIEW_SWITCHER ((void *)switcher)));

if (wide)
{
adw_view_switcher_set_policy (switcher, ADW_VIEW_SWITCHER_POLICY_WIDE);
}
else
{
adw_view_switcher_set_policy (switcher, ADW_VIEW_SWITCHER_POLICY_NARROW);
}
}

static const char *
gtui_viewswitcher_get_selection (uint64_t switcher)
{
g_assert_nonnull (switcher);
g_assert (ADW_IS_VIEW_SWITCHER (ADW_VIEW_SWITCHER ((void *)switcher)));

AdwViewStack *stack = adw_view_switcher_get_stack (switcher);
return adw_view_stack_get_visible_child_name (stack);
}

static void
gtui_viewswitcher_select (uint64_t switcher, const char *title)
{
g_assert_nonnull (switcher);
g_assert_nonnull (title);
g_assert (ADW_IS_VIEW_SWITCHER (ADW_VIEW_SWITCHER ((void *)switcher)));

AdwViewStack *stack = adw_view_switcher_get_stack (switcher);
adw_view_stack_set_visible_child_name (stack, title);
}

static uint64_t
gtui_create_aboutwindow ()
{
Expand Down
85 changes: 85 additions & 0 deletions Sources/Libadwaita/Adwaita/ViewSwitcher.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//
// ViewSwitcher.swift
// Libadwaita
//
// Created by david-swift on 25.12.23.
//

import CGTUI

/// Adw.ViewSwitcher
public class ViewSwitcher: NativeWidgetPeer {

/// The closure that is executed when the selection changes.
var onSelect: () -> Void = { }

/// Initialize a view switcher.
override public init() {
super.init()
self.nativePtr = gtui_create_viewswitcher()
let selfAddr = unsafeBitCast(self, to: UInt64.self)
gtui_viewswitcher_init_signals(self.nativePtr, selfAddr)
}

/// Add a view.
/// - Parameters:
/// - title: The view's title and identifier.
/// - icon: The view's icon.
/// - Returns: The view switcher.
public func addOption(title: String, icon: Icon) -> ViewSwitcher {
gtui_viewswitcher_add_view(self.nativePtr, Label("").nativePtr, title.cString, icon.string.cString)
return self
}

/// Remove a view.
/// - Parameter title: The view's title.
/// - Returns: The view switcher.
public func removeOption(title: String) -> ViewSwitcher {
gtui_viewswitcher_remove_view(self.nativePtr, title.cString)
return self
}

/// Get the selected view's title.
/// - Returns: The title.
public func getSelection() -> String {
.init(cString: gtui_viewswitcher_get_selection(self.nativePtr))
}

/// Select the view with a specific title.
/// - Parameter title: The title.
public func select(title: String) {
gtui_viewswitcher_select(self.nativePtr, title.cString)
}

/// Set the closure that gets called when the selection changes.
/// - Parameter closure: The closure.
/// - Returns: The view switcher.
public func onSelect(closure: @escaping () -> Void) -> ViewSwitcher {
self.onSelect = closure
return self
}

/// Set the wide or narrow design.
/// - Parameter wide: Whether the design is wide.
/// - Returns: The view switcher.
public func wideDesign(_ wide: Bool = true) -> ViewSwitcher {
gtui_viewswitcher_set_wide_design(self.nativePtr, wide.cBool)
return self
}

}

/// Run when the seleciton changes.
/// - Parameters:
/// - ptr: The pointer.
/// - parameter: Additional data.
/// - userData: The switcher data.
@_cdecl("viewswitcher_on_select_cb")
func viewswitcher_on_select_cb(
ptr: UnsafeMutableRawPointer,
parameter: UnsafeMutableRawPointer,
userData: UnsafeMutableRawPointer
) {
let switcher = Unmanaged<ViewSwitcher>.fromOpaque(userData).takeUnretainedValue()
switcher.onSelect()
}
11 changes: 10 additions & 1 deletion Tests/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,21 @@ public class MyApplication: Application {
}
let contentView = TabOverview().createTabHandler { createTab() }
let box = Box(horizontal: false)
let switcher = ViewSwitcher()
_ = contentView.add(
ToolbarView(box.append(tabView.append(title: "Initial View", self.toastOverlay(win: win))))
.addTopBar(
HeaderBar()
.packStart(helloButton())
.titleWidget(TitleBarWidget("Title", "Subtitle"))
.titleWidget(
switcher
.addOption(title: "Test", icon: .default(icon: .actionUnavailable))
.addOption(title: "Case", icon: .default(icon: .addressBookNew))
.wideDesign()
.onSelect {
print(switcher.getSelection())
}
)
.packEnd(Button(icon: .default(icon: .tabNew)).handler { _ = createTab() })
.packEnd(TabButton(view: tabView).handler { contentView.showOverview() })
)
Expand Down

0 comments on commit 11d0bf5

Please sign in to comment.