Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TwoPaneRight Layout #1685

Open
wants to merge 3 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Amethyst.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@
4493EAA22139D9F000AA9623 /* ThreeColumnLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4493EAA12139D9EF00AA9623 /* ThreeColumnLayout.swift */; };
AA4AF40D26717DA900D2AE1B /* TwoPaneLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4AF40C26717DA900D2AE1B /* TwoPaneLayout.swift */; };
AAAC6BAC2677DF7B00BEC1B0 /* TwoPaneLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAAC6BAB2677DF7B00BEC1B0 /* TwoPaneLayoutTests.swift */; };
ED989E6BAE0E8D035277478A /* Pods_Amethyst.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6611384054CC1D59E32FC049 /* Pods_Amethyst.framework */; };
F0B42E352A3CA45E00298E30 /* TwoPaneRightLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0B42E342A3CA45E00298E30 /* TwoPaneRightLayout.swift */; };
F46629C4272AD7A30040C275 /* FourColumnLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46629C3272AD7A30040C275 /* FourColumnLayout.swift */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -251,6 +253,7 @@
4493EAA12139D9EF00AA9623 /* ThreeColumnLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThreeColumnLayout.swift; sourceTree = "<group>"; };
AA4AF40C26717DA900D2AE1B /* TwoPaneLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoPaneLayout.swift; sourceTree = "<group>"; };
AAAC6BAB2677DF7B00BEC1B0 /* TwoPaneLayoutTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoPaneLayoutTests.swift; sourceTree = "<group>"; };
F0B42E342A3CA45E00298E30 /* TwoPaneRightLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoPaneRightLayout.swift; sourceTree = "<group>"; };
F46629C3272AD7A30040C275 /* FourColumnLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FourColumnLayout.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -367,6 +370,7 @@
4062AD341C1FA62500DB612B /* WideLayout.swift */,
4062AD3A1C206EA900DB612B /* WidescreenTallLayout.swift */,
4045416E268FFDA000861BE8 /* CustomLayout.swift */,
F0B42E342A3CA45E00298E30 /* TwoPaneRightLayout.swift */,
);
path = Layouts;
sourceTree = "<group>";
Expand Down Expand Up @@ -794,6 +798,7 @@
40A87FFD2404B1B4005EE9C6 /* DebugInfo.swift in Sources */,
4493EAA22139D9F000AA9623 /* ThreeColumnLayout.swift in Sources */,
40A7AEA7232ECF3000E79964 /* Windows.swift in Sources */,
F0B42E352A3CA45E00298E30 /* TwoPaneRightLayout.swift in Sources */,
404BE9CE1CFBB6E900D6C537 /* BinarySpacePartitioningLayout.swift in Sources */,
4062AD3B1C206EA900DB612B /* WidescreenTallLayout.swift in Sources */,
4058C46F1C4B119500B19D26 /* LayoutNameWindowController.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
{
"originHash" : "43f1b1e9bfd866a37b073557f24d496c85ab3a7508ae523528cda0c3afb30aa9",
"pins" : [
{
"identity" : "cartography",
"kind" : "remoteSourceControl",
"location" : "https://github.com/robb/Cartography",
"state" : {
"revision" : "b75197ea134f42b5feafb04b526b37eb1a41034b",
"version" : "4.0.0"
}
},
{
"identity" : "cwlcatchexception",
"kind" : "remoteSourceControl",
"location" : "https://github.com/mattgallagher/CwlCatchException.git",
"state" : {
"revision" : "07b2ba21d361c223e25e3c1e924288742923f08c",
"version" : "2.2.1"
}
},
{
"identity" : "cwlpreconditiontesting",
"kind" : "remoteSourceControl",
"location" : "https://github.com/mattgallagher/CwlPreconditionTesting.git",
"state" : {
"revision" : "0139c665ebb45e6a9fbdb68aabfd7c39f3fe0071",
"version" : "2.2.2"
}
},
{
"identity" : "loginservicekit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Clipy/LoginServiceKit",
"state" : {
"branch" : "master",
"revision" : "56dce9dbf4367c1445ef2343a2a912bbe5019a6c"
}
},
{
"identity" : "masshortcut",
"kind" : "remoteSourceControl",
"location" : "https://github.com/shpakovski/MASShortcut",
"state" : {
"branch" : "master",
"revision" : "6f2603c6b6cc18f64a799e5d2c9d3bbc467c413a"
}
},
{
"identity" : "nimble",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Quick/Nimble",
"state" : {
"revision" : "eb5e3d717224fa0d1f6aff3fc2c5e8e81fa1f728",
"version" : "11.2.2"
}
},
{
"identity" : "quick",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Quick/Quick",
"state" : {
"revision" : "16910e406be96e08923918315388c3e989deac9e",
"version" : "6.1.0"
}
},
{
"identity" : "rxswift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ReactiveX/RxSwift",
"state" : {
"revision" : "c7c7d2cf50a3211fe2843f76869c698e4e417930",
"version" : "6.8.0"
}
},
{
"identity" : "silica",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ianyh/silica",
"state" : {
"branch" : "master",
"revision" : "4b0e9f62c1ea97a2b97dbcf214be4209dc9d7a71"
}
},
{
"identity" : "sparkle",
"kind" : "remoteSourceControl",
"location" : "https://github.com/sparkle-project/Sparkle",
"state" : {
"revision" : "0ef1ee0220239b3776f433314515fd849025673f",
"version" : "2.6.4"
}
},
{
"identity" : "swift-argument-parser",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-argument-parser.git",
"state" : {
"revision" : "fee6933f37fde9a5e12a1e4aeaa93fe60116ff2a",
"version" : "1.2.2"
}
},
{
"identity" : "swiftybeaver",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SwiftyBeaver/SwiftyBeaver",
"state" : {
"revision" : "12b5acf96d98f91d50de447369bd18df74600f1a",
"version" : "1.9.6"
}
},
{
"identity" : "swiftyjson",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SwiftyJSON/SwiftyJSON",
"state" : {
"revision" : "af76cf3ef710b6ca5f8c05f3a31307d44a3c5828",
"version" : "5.0.2"
}
},
{
"identity" : "yams",
"kind" : "remoteSourceControl",
"location" : "https://github.com/jpsim/Yams",
"state" : {
"revision" : "3036ba9d69cf1fd04d433527bc339dc0dc75433d",
"version" : "5.1.3"
}
}
],
"version" : 3
}
103 changes: 103 additions & 0 deletions Amethyst/Layout/Layouts/TwoPaneRightLayout.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
//
// TwoPaneRightLayout.swift
// Amethyst
//
// Created by Anja on 16.06.23.
// Copyright © 2023 Ian Ynda-Hummel. All rights reserved.
//

import Silica

class TwoPaneRightLayout<Window: WindowType>: Layout<Window>, PanedLayout {
override static var layoutName: String { return "Two Pane Right" }
override static var layoutKey: String { return "two-pane-right" }

enum CodingKeys: String, CodingKey {
case mainPaneCount
case mainPaneRatio
}

override var layoutDescription: String { return "" }

private(set) var mainPaneCount: Int = 1
private(set) var mainPaneRatio: CGFloat = 0.5

required init() {
super.init()
}

required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
self.mainPaneCount = try values.decode(Int.self, forKey: .mainPaneCount)
self.mainPaneRatio = try values.decode(CGFloat.self, forKey: .mainPaneRatio)
super.init()
}

override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(mainPaneCount, forKey: .mainPaneCount)
try container.encode(mainPaneRatio, forKey: .mainPaneRatio)
}

func recommendMainPaneRawRatio(rawRatio: CGFloat) {
mainPaneRatio = rawRatio
}

func increaseMainPaneCount() {}

func decreaseMainPaneCount() {}

override func frameAssignments(_ windowSet: WindowSet<Window>, on screen: Screen) -> [FrameAssignmentOperation<Window>]? {
let windows = windowSet.windows

guard !windows.isEmpty else {
return []
}

let mainPaneCount = min(windows.count, self.mainPaneCount)
let secondaryPaneCount = windows.count > 1 ? 1 : 0
let hasSecondaryPane = secondaryPaneCount > 0

let screenFrame = screen.adjustedFrame()
let isHorizontal = (screenFrame.size.width / screenFrame.size.height) >= 1

let mainPaneWindowHeight = screenFrame.size.height * (!isHorizontal && hasSecondaryPane ? mainPaneRatio : 1)
let secondaryPaneWindowHeight = isHorizontal ? mainPaneWindowHeight : screenFrame.size.height - mainPaneWindowHeight

let mainPaneWindowWidth = screenFrame.size.width * (isHorizontal && hasSecondaryPane ? mainPaneRatio : 1)
let secondaryPaneWindowWidth = !isHorizontal ? mainPaneWindowWidth : screenFrame.size.width - mainPaneWindowWidth

return windows.reduce([]) { acc, window -> [FrameAssignmentOperation<Window>] in
var assignments = acc
var windowFrame = CGRect.zero
let isMain = acc.count < mainPaneCount
var scaleFactor: CGFloat

if isMain {
scaleFactor = screenFrame.size.width / mainPaneWindowWidth
windowFrame.origin.x = screenFrame.origin.x + (isHorizontal ? secondaryPaneWindowWidth : 0)
windowFrame.origin.y = screenFrame.origin.y
windowFrame.size.width = mainPaneWindowWidth
windowFrame.size.height = mainPaneWindowHeight
} else {
scaleFactor = screenFrame.size.width / secondaryPaneWindowWidth
windowFrame.origin.x = screenFrame.origin.x
windowFrame.origin.y = screenFrame.origin.y + (isHorizontal ? 0 : mainPaneWindowHeight)
windowFrame.size.width = secondaryPaneWindowWidth
windowFrame.size.height = secondaryPaneWindowHeight
}

let resizeRules = ResizeRules(isMain: isMain, unconstrainedDimension: .horizontal, scaleFactor: scaleFactor)
let frameAssignment = FrameAssignment<Window>(
frame: windowFrame,
window: window,
screenFrame: screenFrame,
resizeRules: resizeRules
)

assignments.append(FrameAssignmentOperation(frameAssignment: frameAssignment, windowSet: windowSet))

return assignments
}
}
}
8 changes: 8 additions & 0 deletions Amethyst/Managers/LayoutType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ enum LayoutType<Window: WindowType> {
case tallRight
case wide
case twoPane
case twoPaneRight
case threeColumnLeft
case threeColumnMiddle
case threeColumnRight
Expand All @@ -67,6 +68,7 @@ enum LayoutType<Window: WindowType> {
.tallRight,
.wide,
.twoPane,
.twoPaneRight,
.threeColumnLeft,
.threeColumnMiddle,
.threeColumnRight,
Expand All @@ -92,6 +94,8 @@ enum LayoutType<Window: WindowType> {
return "wide"
case .twoPane:
return "two-pane"
case .twoPaneRight:
return "two-pane-right"
case .threeColumnLeft:
return "3column-left"
case .threeColumnMiddle:
Expand Down Expand Up @@ -131,6 +135,8 @@ enum LayoutType<Window: WindowType> {
return WideLayout<Window>.self
case .twoPane:
return TwoPaneLayout<Window>.self
case .twoPaneRight:
return TwoPaneRightLayout<Window>.self
case .threeColumnLeft:
return ThreeColumnLeftLayout<Window>.self
case .threeColumnMiddle:
Expand Down Expand Up @@ -170,6 +176,8 @@ enum LayoutType<Window: WindowType> {
return .wide
case "two-pane":
return .twoPane
case "two-pane-right":
return .twoPaneRight
case "3column-left":
return .threeColumnLeft
case "middle-wide":
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ automatically adapts to horizontal/vertical tiling depending on your screen
orientation. The main pane is on the left in the horizontal orientation and it's
on the top in the vertical orientation.

#### Two Pane Right

Exactly the same as *Two Pane*, but the main pane is on the right, with the other pane on the left.

#### 3Column-Left

A three-column version of *Tall*, with one main pane on the left (extending the full height of the screen) and two other panes, one in the middle and one on the right. Like *Tall*, if any pane has more than one window, that pane will be split into rows. You can control how many windows are in the main pane as usual; other windows will be assigned as evenly as possible between the other two panes.
Expand Down